2020-09-08 17:08:08 +00:00
|
|
|
// SONIC ROBO BLAST 2
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Copyright (C) 2020 by Iestyn "Monster Iestyn" Jealous.
|
2020-09-08 17:56:00 +00:00
|
|
|
// Copyright (C) 2020 by Sonic Team Junior.
|
2020-09-08 17:08:08 +00:00
|
|
|
//
|
|
|
|
// This program is free software distributed under the
|
|
|
|
// terms of the GNU General Public License, version 2.
|
|
|
|
// See the 'LICENSE' file for more details.
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
/// \file lua_polyobjlib.c
|
|
|
|
/// \brief polyobject library for Lua scripting
|
|
|
|
|
|
|
|
#include "doomdef.h"
|
2020-09-08 17:55:16 +00:00
|
|
|
#include "fastcmp.h"
|
2020-09-08 17:08:08 +00:00
|
|
|
#include "p_local.h"
|
|
|
|
#include "p_polyobj.h"
|
|
|
|
#include "lua_script.h"
|
|
|
|
#include "lua_libs.h"
|
|
|
|
|
2020-09-08 17:29:10 +00:00
|
|
|
enum polyobj_e {
|
2020-09-09 17:09:32 +00:00
|
|
|
// properties
|
2020-09-08 17:29:10 +00:00
|
|
|
polyobj_valid = 0,
|
2020-09-08 20:42:51 +00:00
|
|
|
polyobj_id,
|
|
|
|
polyobj_parent,
|
2020-09-09 16:06:36 +00:00
|
|
|
polyobj_sector,
|
2020-09-08 20:42:51 +00:00
|
|
|
polyobj_angle,
|
|
|
|
polyobj_damage,
|
|
|
|
polyobj_thrust,
|
2020-09-08 21:10:11 +00:00
|
|
|
polyobj_flags,
|
|
|
|
polyobj_translucency,
|
2020-09-09 17:09:32 +00:00
|
|
|
polyobj_triggertag,
|
|
|
|
// special functions
|
|
|
|
polyobj_pointInside,
|
|
|
|
polyobj_mobjTouching,
|
|
|
|
polyobj_mobjInside
|
2020-09-08 17:29:10 +00:00
|
|
|
};
|
|
|
|
static const char *const polyobj_opt[] = {
|
2020-09-09 17:09:32 +00:00
|
|
|
// properties
|
2020-09-08 17:29:10 +00:00
|
|
|
"valid",
|
2020-09-08 20:42:51 +00:00
|
|
|
"id",
|
|
|
|
"parent",
|
2020-09-09 16:06:36 +00:00
|
|
|
"sector",
|
2020-09-08 20:42:51 +00:00
|
|
|
"angle",
|
|
|
|
"damage",
|
|
|
|
"thrust",
|
|
|
|
"flags",
|
2020-09-08 21:10:11 +00:00
|
|
|
"translucency",
|
|
|
|
"triggertag",
|
2020-09-09 17:09:32 +00:00
|
|
|
// special functions
|
|
|
|
"pointInside",
|
|
|
|
"mobjTouching",
|
|
|
|
"mobjInside",
|
2020-09-08 17:29:10 +00:00
|
|
|
NULL};
|
|
|
|
|
2020-09-09 17:09:32 +00:00
|
|
|
static int lib_polyobj_PointInside(lua_State *L)
|
|
|
|
{
|
|
|
|
polyobj_t *po = *((polyobj_t **)luaL_checkudata(L, 1, META_POLYOBJ));
|
|
|
|
fixed_t x = luaL_checkfixed(L, 2);
|
|
|
|
fixed_t y = luaL_checkfixed(L, 3);
|
|
|
|
INLEVEL
|
|
|
|
if (!po)
|
|
|
|
return LUA_ErrInvalid(L, "polyobj_t");
|
|
|
|
lua_pushboolean(L, P_PointInsidePolyobj(po, x, y));
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int lib_polyobj_MobjTouching(lua_State *L)
|
|
|
|
{
|
|
|
|
polyobj_t *po = *((polyobj_t **)luaL_checkudata(L, 1, META_POLYOBJ));
|
|
|
|
mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 2, META_MOBJ));
|
|
|
|
INLEVEL
|
|
|
|
if (!po)
|
|
|
|
return LUA_ErrInvalid(L, "polyobj_t");
|
|
|
|
if (!mo)
|
|
|
|
return LUA_ErrInvalid(L, "mobj_t");
|
|
|
|
lua_pushboolean(L, P_MobjTouchingPolyobj(po, mo));
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int lib_polyobj_MobjInside(lua_State *L)
|
|
|
|
{
|
|
|
|
polyobj_t *po = *((polyobj_t **)luaL_checkudata(L, 1, META_POLYOBJ));
|
|
|
|
mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 2, META_MOBJ));
|
|
|
|
INLEVEL
|
|
|
|
if (!po)
|
|
|
|
return LUA_ErrInvalid(L, "polyobj_t");
|
|
|
|
if (!mo)
|
|
|
|
return LUA_ErrInvalid(L, "mobj_t");
|
|
|
|
lua_pushboolean(L, P_MobjInsidePolyobj(po, mo));
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2020-09-08 17:29:10 +00:00
|
|
|
static int polyobj_get(lua_State *L)
|
|
|
|
{
|
|
|
|
polyobj_t *polyobj = *((polyobj_t **)luaL_checkudata(L, 1, META_POLYOBJ));
|
|
|
|
enum polyobj_e field = luaL_checkoption(L, 2, NULL, polyobj_opt);
|
|
|
|
|
|
|
|
if (!polyobj) {
|
|
|
|
if (field == polyobj_valid) {
|
|
|
|
lua_pushboolean(L, false);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
return LUA_ErrInvalid(L, "polyobj_t");
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (field)
|
|
|
|
{
|
2020-09-09 17:09:32 +00:00
|
|
|
// properties
|
2020-09-08 17:29:10 +00:00
|
|
|
case polyobj_valid:
|
|
|
|
lua_pushboolean(L, true);
|
|
|
|
break;
|
2020-09-08 20:42:51 +00:00
|
|
|
case polyobj_id:
|
|
|
|
lua_pushinteger(L, polyobj->id);
|
|
|
|
break;
|
|
|
|
case polyobj_parent:
|
|
|
|
lua_pushinteger(L, polyobj->parent);
|
|
|
|
break;
|
2020-09-09 16:06:36 +00:00
|
|
|
case polyobj_sector: // shortcut that exists only in Lua!
|
|
|
|
LUA_PushUserdata(L, polyobj->lines[0]->backsector, META_SECTOR);
|
|
|
|
break;
|
2020-09-08 20:42:51 +00:00
|
|
|
case polyobj_angle:
|
|
|
|
lua_pushangle(L, polyobj->angle);
|
|
|
|
break;
|
|
|
|
case polyobj_damage:
|
|
|
|
lua_pushinteger(L, polyobj->damage);
|
|
|
|
break;
|
|
|
|
case polyobj_thrust:
|
|
|
|
lua_pushfixed(L, polyobj->thrust);
|
|
|
|
break;
|
|
|
|
case polyobj_flags:
|
|
|
|
lua_pushinteger(L, polyobj->flags);
|
|
|
|
break;
|
2020-09-08 21:10:11 +00:00
|
|
|
case polyobj_translucency:
|
|
|
|
lua_pushinteger(L, polyobj->translucency);
|
|
|
|
break;
|
|
|
|
case polyobj_triggertag:
|
|
|
|
lua_pushinteger(L, polyobj->triggertag);
|
|
|
|
break;
|
2020-09-09 17:09:32 +00:00
|
|
|
// special functions
|
|
|
|
case polyobj_pointInside:
|
|
|
|
lua_pushcfunction(L, lib_polyobj_PointInside);
|
|
|
|
break;
|
|
|
|
case polyobj_mobjTouching:
|
|
|
|
lua_pushcfunction(L, lib_polyobj_MobjTouching);
|
|
|
|
break;
|
|
|
|
case polyobj_mobjInside:
|
|
|
|
lua_pushcfunction(L, lib_polyobj_MobjInside);
|
|
|
|
break;
|
2020-09-08 17:29:10 +00:00
|
|
|
}
|
|
|
|
return 1;
|
2020-09-08 20:42:51 +00:00
|
|
|
}
|
2020-09-08 17:29:10 +00:00
|
|
|
|
|
|
|
static int polyobj_set(lua_State *L)
|
|
|
|
{
|
|
|
|
return luaL_error(L, LUA_QL("polyobj_t") " struct cannot be edited by Lua."); // this is just temporary
|
|
|
|
}
|
|
|
|
|
2020-09-08 20:42:51 +00:00
|
|
|
static int polyobj_num(lua_State *L)
|
|
|
|
{
|
|
|
|
polyobj_t *polyobj = *((polyobj_t **)luaL_checkudata(L, 1, META_POLYOBJ));
|
|
|
|
if (!polyobj)
|
|
|
|
return luaL_error(L, "accessed polyobj_t doesn't exist anymore.");
|
|
|
|
lua_pushinteger(L, polyobj-PolyObjects);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2020-09-08 17:29:10 +00:00
|
|
|
static int lib_iteratePolyObjects(lua_State *L)
|
|
|
|
{
|
|
|
|
INT32 i = -1;
|
|
|
|
if (lua_gettop(L) < 2)
|
|
|
|
{
|
|
|
|
//return luaL_error(L, "Don't call PolyObjects.iterate() directly, use it as 'for polyobj in PolyObjects.iterate do <block> end'.");
|
|
|
|
lua_pushcfunction(L, lib_iteratePolyObjects);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
lua_settop(L, 2);
|
|
|
|
lua_remove(L, 1); // state is unused.
|
|
|
|
if (!lua_isnil(L, 1))
|
|
|
|
i = (INT32)(*((polyobj_t **)luaL_checkudata(L, 1, META_POLYOBJ)) - PolyObjects);
|
|
|
|
for (i++; i < numPolyObjects; i++)
|
|
|
|
{
|
|
|
|
LUA_PushUserdata(L, &PolyObjects[i], META_POLYOBJ);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2020-09-08 20:42:51 +00:00
|
|
|
static int lib_PolyObject_getfornum(lua_State *L)
|
|
|
|
{
|
|
|
|
INT32 id = (INT32)luaL_checkinteger(L, 1);
|
|
|
|
|
|
|
|
if (!numPolyObjects)
|
|
|
|
return 0; // if there's no PolyObjects then bail out here
|
|
|
|
|
|
|
|
LUA_PushUserdata(L, Polyobj_GetForNum(id), META_POLYOBJ);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2020-09-08 17:29:10 +00:00
|
|
|
static int lib_getPolyObject(lua_State *L)
|
|
|
|
{
|
|
|
|
const char *field;
|
|
|
|
INT32 i;
|
|
|
|
|
|
|
|
// find PolyObject by number
|
|
|
|
if (lua_type(L, 2) == LUA_TNUMBER)
|
|
|
|
{
|
|
|
|
i = luaL_checkinteger(L, 2);
|
|
|
|
if (i < 0 || i >= numPolyObjects)
|
|
|
|
return luaL_error(L, "PolyObjects[] index %d out of range (0 - %d)", i, numPolyObjects-1);
|
|
|
|
LUA_PushUserdata(L, &PolyObjects[i], META_POLYOBJ);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
field = luaL_checkstring(L, 2);
|
|
|
|
// special function iterate
|
|
|
|
if (fastcmp(field,"iterate"))
|
|
|
|
{
|
|
|
|
lua_pushcfunction(L, lib_iteratePolyObjects);
|
|
|
|
return 1;
|
|
|
|
}
|
2020-09-08 20:42:51 +00:00
|
|
|
// find PolyObject by ID
|
|
|
|
else if (fastcmp(field,"GetForNum")) // name could probably be better
|
|
|
|
{
|
|
|
|
lua_pushcfunction(L, lib_PolyObject_getfornum);
|
|
|
|
return 1;
|
|
|
|
}
|
2020-09-08 17:29:10 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int lib_numPolyObjects(lua_State *L)
|
|
|
|
{
|
|
|
|
lua_pushinteger(L, numPolyObjects);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2020-09-08 17:08:08 +00:00
|
|
|
int LUA_PolyObjLib(lua_State *L)
|
|
|
|
{
|
2020-09-08 17:29:10 +00:00
|
|
|
luaL_newmetatable(L, META_POLYOBJ);
|
|
|
|
lua_pushcfunction(L, polyobj_get);
|
|
|
|
lua_setfield(L, -2, "__index");
|
|
|
|
|
|
|
|
lua_pushcfunction(L, polyobj_set);
|
|
|
|
lua_setfield(L, -2, "__newindex");
|
|
|
|
|
2020-09-08 20:42:51 +00:00
|
|
|
lua_pushcfunction(L, polyobj_num);
|
|
|
|
lua_setfield(L, -2, "__len");
|
2020-09-08 17:29:10 +00:00
|
|
|
lua_pop(L,1);
|
|
|
|
|
|
|
|
lua_newuserdata(L, 0);
|
|
|
|
lua_createtable(L, 0, 2);
|
|
|
|
lua_pushcfunction(L, lib_getPolyObject);
|
|
|
|
lua_setfield(L, -2, "__index");
|
|
|
|
|
|
|
|
lua_pushcfunction(L, lib_numPolyObjects);
|
|
|
|
lua_setfield(L, -2, "__len");
|
|
|
|
lua_setmetatable(L, -2);
|
|
|
|
lua_setglobal(L, "PolyObjects");
|
2020-09-08 17:08:08 +00:00
|
|
|
return 0;
|
|
|
|
}
|