Added polyobj.vertices and polyobj.lines to Lua

This commit is contained in:
Monster Iestyn 2020-09-09 21:15:02 +01:00
parent 4ce161f9c3
commit 78f7998618
3 changed files with 160 additions and 0 deletions

View File

@ -60,6 +60,8 @@ extern lua_State *gL;
#define META_LINESTRINGARGS "LINE_T*STRINGARGS"
#define META_THINGARGS "MAPTHING_T*ARGS"
#define META_THINGSTRINGARGS "MAPTHING_T*STRINGARGS"
#define META_POLYOBJVERTICES "POLYOBJ_T*VERTICES"
#define META_POLYOBJLINES "POLYOBJ_T*LINES"
#ifdef HAVE_LUA_SEGS
#define META_NODEBBOX "NODE_T*BBOX"
#define META_NODECHILDREN "NODE_T*CHILDREN"

View File

@ -26,6 +26,8 @@ enum polyobj_e {
polyobj_valid = 0,
polyobj_id,
polyobj_parent,
polyobj_vertices,
polyobj_lines,
polyobj_sector,
polyobj_angle,
polyobj_damage,
@ -46,6 +48,8 @@ static const char *const polyobj_opt[] = {
"valid",
"id",
"parent",
"vertices",
"lines",
"sector",
"angle",
"damage",
@ -62,6 +66,126 @@ static const char *const polyobj_opt[] = {
"rotate",
NULL};
static const char *const valid_opt[] ={"valid",NULL};
////////////////////////
// polyobj.vertices[] //
////////////////////////
// polyobj.vertices, i -> polyobj.vertices[i]
// polyobj.vertices.valid, for validity checking
//
// see sectorlines_get in lua_maplib.c
//
static int polyobjvertices_get(lua_State *L)
{
vertex_t ***polyverts = *((vertex_t ****)luaL_checkudata(L, 1, META_POLYOBJVERTICES));
size_t i;
size_t numofverts = 0;
lua_settop(L, 2);
if (!lua_isnumber(L, 2))
{
int field = luaL_checkoption(L, 2, NULL, valid_opt);
if (!polyverts || !(*polyverts))
{
if (field == 0) {
lua_pushboolean(L, 0);
return 1;
}
return luaL_error(L, "accessed polyobj_t.vertices doesn't exist anymore.");
} else if (field == 0) {
lua_pushboolean(L, 1);
return 1;
}
}
numofverts = (size_t)(*(size_t *)(((size_t)polyverts) - (offsetof(polyobj_t, vertices) - offsetof(polyobj_t, numVertices))));
if (!numofverts)
return luaL_error(L, "no vertices found!");
i = (size_t)lua_tointeger(L, 2);
if (i >= numofverts)
return 0;
LUA_PushUserdata(L, (*polyverts)[i], META_VERTEX);
return 1;
}
// #(polyobj.vertices) -> polyobj.numVertices
static int polyobjvertices_num(lua_State *L)
{
vertex_t ***polyverts = *((vertex_t ****)luaL_checkudata(L, 1, META_POLYOBJVERTICES));
size_t numofverts = 0;
if (!polyverts || !(*polyverts))
return luaL_error(L, "accessed polyobj_t.vertices doesn't exist anymore.");
numofverts = (size_t)(*(size_t *)(((size_t)polyverts) - (offsetof(polyobj_t, vertices) - offsetof(polyobj_t, numVertices))));
lua_pushinteger(L, numofverts);
return 1;
}
/////////////////////
// polyobj.lines[] //
/////////////////////
// polyobj.lines, i -> polyobj.lines[i]
// polyobj.lines.valid, for validity checking
//
// see sectorlines_get in lua_maplib.c
//
static int polyobjlines_get(lua_State *L)
{
line_t ***polylines = *((line_t ****)luaL_checkudata(L, 1, META_POLYOBJLINES));
size_t i;
size_t numoflines = 0;
lua_settop(L, 2);
if (!lua_isnumber(L, 2))
{
int field = luaL_checkoption(L, 2, NULL, valid_opt);
if (!polylines || !(*polylines))
{
if (field == 0) {
lua_pushboolean(L, 0);
return 1;
}
return luaL_error(L, "accessed polyobj_t.lines doesn't exist anymore.");
} else if (field == 0) {
lua_pushboolean(L, 1);
return 1;
}
}
numoflines = (size_t)(*(size_t *)(((size_t)polylines) - (offsetof(polyobj_t, lines) - offsetof(polyobj_t, numLines))));
if (!numoflines)
return luaL_error(L, "no lines found!");
i = (size_t)lua_tointeger(L, 2);
if (i >= numoflines)
return 0;
LUA_PushUserdata(L, (*polylines)[i], META_LINE);
return 1;
}
// #(polyobj.lines) -> polyobj.numLines
static int polyobjlines_num(lua_State *L)
{
line_t ***polylines = *((line_t ****)luaL_checkudata(L, 1, META_POLYOBJLINES));
size_t numoflines = 0;
if (!polylines || !(*polylines))
return luaL_error(L, "accessed polyobj_t.lines doesn't exist anymore.");
numoflines = (size_t)(*(size_t *)(((size_t)polylines) - (offsetof(polyobj_t, lines) - offsetof(polyobj_t, numLines))));
lua_pushinteger(L, numoflines);
return 1;
}
/////////////////////////////////
// polyobj_t function wrappers //
/////////////////////////////////
// special functions - utility
static int lib_polyobj_PointInside(lua_State *L)
{
@ -130,6 +254,10 @@ static int lib_polyobj_rotate(lua_State *L)
return 1;
}
///////////////
// polyobj_t //
///////////////
static int polyobj_get(lua_State *L)
{
polyobj_t *polyobj = *((polyobj_t **)luaL_checkudata(L, 1, META_POLYOBJ));
@ -155,6 +283,12 @@ static int polyobj_get(lua_State *L)
case polyobj_parent:
lua_pushinteger(L, polyobj->parent);
break;
case polyobj_vertices: // vertices
LUA_PushUserdata(L, &polyobj->vertices, META_POLYOBJVERTICES); // push the address of the "vertices" member in the struct, to allow our hacks to work
break;
case polyobj_lines: // lines
LUA_PushUserdata(L, &polyobj->lines, META_POLYOBJLINES); // push the address of the "lines" member in the struct, to allow our hacks to work
break;
case polyobj_sector: // shortcut that exists only in Lua!
LUA_PushUserdata(L, polyobj->lines[0]->backsector, META_SECTOR);
break;
@ -211,6 +345,10 @@ static int polyobj_num(lua_State *L)
return 1;
}
///////////////////
// PolyObjects[] //
///////////////////
static int lib_iteratePolyObjects(lua_State *L)
{
INT32 i = -1;
@ -282,6 +420,22 @@ static int lib_numPolyObjects(lua_State *L)
int LUA_PolyObjLib(lua_State *L)
{
luaL_newmetatable(L, META_POLYOBJVERTICES);
lua_pushcfunction(L, polyobjvertices_get);
lua_setfield(L, -2, "__index");
lua_pushcfunction(L, polyobjvertices_num);
lua_setfield(L, -2, "__len");
lua_pop(L, 1);
luaL_newmetatable(L, META_POLYOBJLINES);
lua_pushcfunction(L, polyobjlines_get);
lua_setfield(L, -2, "__index");
lua_pushcfunction(L, polyobjlines_num);
lua_setfield(L, -2, "__len");
lua_pop(L, 1);
luaL_newmetatable(L, META_POLYOBJ);
lua_pushcfunction(L, polyobj_get);
lua_setfield(L, -2, "__index");

View File

@ -777,7 +777,11 @@ void LUA_InvalidateLevel(void)
for (i = 0; i < numvertexes; i++)
LUA_InvalidateUserdata(&vertexes[i]);
for (i = 0; i < (size_t)numPolyObjects; i++)
{
LUA_InvalidateUserdata(&PolyObjects[i]);
LUA_InvalidateUserdata(&PolyObjects[i].vertices);
LUA_InvalidateUserdata(&PolyObjects[i].lines);
}
#ifdef HAVE_LUA_SEGS
for (i = 0; i < numsegs; i++)
LUA_InvalidateUserdata(&segs[i]);