mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2025-03-20 18:01:16 +00:00
Merge branch 'lua-polyobjects' into 'next'
Lua polyobjects Closes #19 See merge request STJr/SRB2!1140
This commit is contained in:
commit
bd9fda8ceb
13 changed files with 660 additions and 6 deletions
|
@ -263,6 +263,7 @@ set(SRB2_LUA_SOURCES
|
|||
lua_mathlib.c
|
||||
lua_mobjlib.c
|
||||
lua_playerlib.c
|
||||
lua_polyobjlib.c
|
||||
lua_script.c
|
||||
lua_skinlib.c
|
||||
lua_thinkerlib.c
|
||||
|
|
|
@ -47,5 +47,6 @@ OBJS:=$(OBJS) \
|
|||
$(OBJDIR)/lua_skinlib.o \
|
||||
$(OBJDIR)/lua_thinkerlib.o \
|
||||
$(OBJDIR)/lua_maplib.o \
|
||||
$(OBJDIR)/lua_polyobjlib.o \
|
||||
$(OBJDIR)/lua_blockmaplib.o \
|
||||
$(OBJDIR)/lua_hudlib.o
|
||||
|
|
|
@ -9908,6 +9908,25 @@ struct {
|
|||
{"FF_COLORMAPONLY",FF_COLORMAPONLY}, ///< Only copy the colormap, not the lightlevel
|
||||
{"FF_GOOWATER",FF_GOOWATER}, ///< Used with ::FF_SWIMMABLE. Makes thick bouncey goop.
|
||||
|
||||
// PolyObject flags
|
||||
{"POF_CLIPLINES",POF_CLIPLINES}, ///< Test against lines for collision
|
||||
{"POF_CLIPPLANES",POF_CLIPPLANES}, ///< Test against tops and bottoms for collision
|
||||
{"POF_SOLID",POF_SOLID}, ///< Clips things.
|
||||
{"POF_TESTHEIGHT",POF_TESTHEIGHT}, ///< Test line collision with heights
|
||||
{"POF_RENDERSIDES",POF_RENDERSIDES}, ///< Renders the sides.
|
||||
{"POF_RENDERTOP",POF_RENDERTOP}, ///< Renders the top.
|
||||
{"POF_RENDERBOTTOM",POF_RENDERBOTTOM}, ///< Renders the bottom.
|
||||
{"POF_RENDERPLANES",POF_RENDERPLANES}, ///< Renders top and bottom.
|
||||
{"POF_RENDERALL",POF_RENDERALL}, ///< Renders everything.
|
||||
{"POF_INVERT",POF_INVERT}, ///< Inverts collision (like a cage).
|
||||
{"POF_INVERTPLANES",POF_INVERTPLANES}, ///< Render inside planes.
|
||||
{"POF_INVERTPLANESONLY",POF_INVERTPLANESONLY}, ///< Only render inside planes.
|
||||
{"POF_PUSHABLESTOP",POF_PUSHABLESTOP}, ///< Pushables will stop movement.
|
||||
{"POF_LDEXEC",POF_LDEXEC}, ///< This PO triggers a linedef executor.
|
||||
{"POF_ONESIDE",POF_ONESIDE}, ///< Only use the first side of the linedef.
|
||||
{"POF_NOSPECIALS",POF_NOSPECIALS}, ///< Don't apply sector specials.
|
||||
{"POF_SPLAT",POF_SPLAT}, ///< Use splat flat renderer (treat cyan pixels as invisible).
|
||||
|
||||
#ifdef HAVE_LUA_SEGS
|
||||
// Node flags
|
||||
{"NF_SUBSECTOR",NF_SUBSECTOR}, // Indicate a leaf.
|
||||
|
|
|
@ -173,8 +173,13 @@ static const struct {
|
|||
{META_SEG, "seg_t"},
|
||||
{META_NODE, "node_t"},
|
||||
#endif
|
||||
{META_SLOPE, "slope_t"},
|
||||
{META_VECTOR2, "vector2_t"},
|
||||
{META_VECTOR3, "vector3_t"},
|
||||
{META_MAPHEADER, "mapheader_t"},
|
||||
|
||||
{META_POLYOBJ, "polyobj_t"},
|
||||
|
||||
{META_CVAR, "consvar_t"},
|
||||
|
||||
{META_SECTORLINES, "sector_t.lines"},
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2016 by Iestyn "Monster Iestyn" Jealous.
|
||||
// Copyright (C) 2016-2020 by Iestyn "Monster Iestyn" Jealous.
|
||||
// Copyright (C) 2016-2020 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
|
@ -13,6 +13,7 @@
|
|||
#include "doomdef.h"
|
||||
#include "p_local.h"
|
||||
#include "r_main.h" // validcount
|
||||
#include "p_polyobj.h"
|
||||
#include "lua_script.h"
|
||||
#include "lua_libs.h"
|
||||
//#include "lua_hud.h" // hud_running errors
|
||||
|
@ -20,6 +21,7 @@
|
|||
static const char *const search_opt[] = {
|
||||
"objects",
|
||||
"lines",
|
||||
"polyobjs",
|
||||
NULL};
|
||||
|
||||
// a quickly-made function pointer typedef used by lib_searchBlockmap...
|
||||
|
@ -167,6 +169,55 @@ static UINT8 lib_searchBlockmap_Lines(lua_State *L, INT32 x, INT32 y, mobj_t *th
|
|||
return 0; // Everything was checked.
|
||||
}
|
||||
|
||||
// Helper function for "polyobjs" search
|
||||
static UINT8 lib_searchBlockmap_PolyObjs(lua_State *L, INT32 x, INT32 y, mobj_t *thing)
|
||||
{
|
||||
INT32 offset;
|
||||
polymaplink_t *plink; // haleyjd 02/22/06
|
||||
|
||||
if (x < 0 || y < 0 || x >= bmapwidth || y >= bmapheight)
|
||||
return 0;
|
||||
|
||||
offset = y*bmapwidth + x;
|
||||
|
||||
// haleyjd 02/22/06: consider polyobject lines
|
||||
plink = polyblocklinks[offset];
|
||||
|
||||
while (plink)
|
||||
{
|
||||
polyobj_t *po = plink->po;
|
||||
|
||||
if (po->validcount != validcount) // if polyobj hasn't been checked
|
||||
{
|
||||
po->validcount = validcount;
|
||||
|
||||
lua_pushvalue(L, 1);
|
||||
LUA_PushUserdata(L, thing, META_MOBJ);
|
||||
LUA_PushUserdata(L, po, META_POLYOBJ);
|
||||
if (lua_pcall(gL, 2, 1, 0)) {
|
||||
if (!blockfuncerror || cv_debug & DBG_LUA)
|
||||
CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1));
|
||||
lua_pop(gL, 1);
|
||||
blockfuncerror = true;
|
||||
return 0; // *shrugs*
|
||||
}
|
||||
if (!lua_isnil(gL, -1))
|
||||
{ // if nil, continue
|
||||
if (lua_toboolean(gL, -1))
|
||||
return 2; // stop whole search
|
||||
else
|
||||
return 1; // stop block search
|
||||
}
|
||||
lua_pop(gL, 1);
|
||||
if (P_MobjWasRemoved(thing))
|
||||
return 2;
|
||||
}
|
||||
plink = (polymaplink_t *)(plink->link.next);
|
||||
}
|
||||
|
||||
return 0; // Everything was checked.
|
||||
}
|
||||
|
||||
// The searchBlockmap function
|
||||
// arguments: searchBlockmap(searchtype, function, mobj, [x1, x2, y1, y2])
|
||||
// return value:
|
||||
|
@ -195,6 +246,9 @@ static int lib_searchBlockmap(lua_State *L)
|
|||
case 1: // "lines"
|
||||
searchFunc = lib_searchBlockmap_Lines;
|
||||
break;
|
||||
case 2: // "polyobjs"
|
||||
searchFunc = lib_searchBlockmap_PolyObjs;
|
||||
break;
|
||||
}
|
||||
|
||||
// the mobj we are searching around, the "calling" mobj we could say
|
||||
|
|
|
@ -50,6 +50,8 @@ extern lua_State *gL;
|
|||
#define META_VECTOR3 "VECTOR3_T"
|
||||
#define META_MAPHEADER "MAPHEADER_T*"
|
||||
|
||||
#define META_POLYOBJ "POLYOBJ_T*"
|
||||
|
||||
#define META_CVAR "CONSVAR_T*"
|
||||
|
||||
#define META_SECTORLINES "SECTOR_T*LINES"
|
||||
|
@ -58,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"
|
||||
|
@ -88,5 +92,6 @@ int LUA_PlayerLib(lua_State *L);
|
|||
int LUA_SkinLib(lua_State *L);
|
||||
int LUA_ThinkerLib(lua_State *L);
|
||||
int LUA_MapLib(lua_State *L);
|
||||
int LUA_PolyObjLib(lua_State *L);
|
||||
int LUA_BlockmapLib(lua_State *L);
|
||||
int LUA_HudLib(lua_State *L);
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "p_setup.h"
|
||||
#include "z_zone.h"
|
||||
#include "p_slopes.h"
|
||||
#include "p_polyobj.h"
|
||||
#include "r_main.h"
|
||||
|
||||
#include "lua_script.h"
|
||||
|
@ -68,6 +69,7 @@ enum subsector_e {
|
|||
subsector_sector,
|
||||
subsector_numlines,
|
||||
subsector_firstline,
|
||||
subsector_polyList
|
||||
};
|
||||
|
||||
static const char *const subsector_opt[] = {
|
||||
|
@ -75,6 +77,7 @@ static const char *const subsector_opt[] = {
|
|||
"sector",
|
||||
"numlines",
|
||||
"firstline",
|
||||
"polyList",
|
||||
NULL};
|
||||
|
||||
enum line_e {
|
||||
|
@ -98,6 +101,7 @@ enum line_e {
|
|||
line_backsector,
|
||||
line_firsttag,
|
||||
line_nexttag,
|
||||
line_polyobj,
|
||||
line_text,
|
||||
line_callcount
|
||||
};
|
||||
|
@ -123,6 +127,7 @@ static const char *const line_opt[] = {
|
|||
"backsector",
|
||||
"firsttag",
|
||||
"nexttag",
|
||||
"polyobj",
|
||||
"text",
|
||||
"callcount",
|
||||
NULL};
|
||||
|
@ -223,6 +228,7 @@ enum seg_e {
|
|||
seg_linedef,
|
||||
seg_frontsector,
|
||||
seg_backsector,
|
||||
seg_polyseg
|
||||
};
|
||||
|
||||
static const char *const seg_opt[] = {
|
||||
|
@ -236,6 +242,7 @@ static const char *const seg_opt[] = {
|
|||
"linedef",
|
||||
"frontsector",
|
||||
"backsector",
|
||||
"polyseg",
|
||||
NULL};
|
||||
|
||||
enum node_e {
|
||||
|
@ -325,9 +332,9 @@ static const char *const vector_opt[] = {
|
|||
static const char *const array_opt[] ={"iterate",NULL};
|
||||
static const char *const valid_opt[] ={"valid",NULL};
|
||||
|
||||
///////////////////////////////////
|
||||
// sector list iterate functions //
|
||||
///////////////////////////////////
|
||||
/////////////////////////////////////////////
|
||||
// sector/subsector list iterate functions //
|
||||
/////////////////////////////////////////////
|
||||
|
||||
// iterates through a sector's thinglist!
|
||||
static int lib_iterateSectorThinglist(lua_State *L)
|
||||
|
@ -399,6 +406,41 @@ static int lib_iterateSectorFFloors(lua_State *L)
|
|||
return 0;
|
||||
}
|
||||
|
||||
// iterates through a subsector's polyList! (for polyobj_t)
|
||||
static int lib_iterateSubSectorPolylist(lua_State *L)
|
||||
{
|
||||
polyobj_t *state = NULL;
|
||||
polyobj_t *po = NULL;
|
||||
|
||||
INLEVEL
|
||||
|
||||
if (lua_gettop(L) < 2)
|
||||
return luaL_error(L, "Don't call subsector.polyList() directly, use it as 'for polyobj in subsector.polyList do <block> end'.");
|
||||
|
||||
if (!lua_isnil(L, 1))
|
||||
state = *((polyobj_t **)luaL_checkudata(L, 1, META_POLYOBJ));
|
||||
else
|
||||
return 0; // no polylist to iterate through sorry!
|
||||
|
||||
lua_settop(L, 2);
|
||||
lua_remove(L, 1); // remove state now.
|
||||
|
||||
if (!lua_isnil(L, 1))
|
||||
{
|
||||
po = *((polyobj_t **)luaL_checkudata(L, 1, META_POLYOBJ));
|
||||
po = (polyobj_t *)(po->link.next);
|
||||
}
|
||||
else
|
||||
po = state; // state is used as the "start" of the polylist
|
||||
|
||||
if (po)
|
||||
{
|
||||
LUA_PushUserdata(L, po, META_POLYOBJ);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sector_iterate(lua_State *L)
|
||||
{
|
||||
lua_pushvalue(L, lua_upvalueindex(1)); // iterator function, or the "generator"
|
||||
|
@ -687,6 +729,11 @@ static int subsector_get(lua_State *L)
|
|||
case subsector_firstline:
|
||||
lua_pushinteger(L, subsector->firstline);
|
||||
return 1;
|
||||
case subsector_polyList: // polyList
|
||||
lua_pushcfunction(L, lib_iterateSubSectorPolylist);
|
||||
LUA_PushUserdata(L, subsector->polyList, META_POLYOBJ);
|
||||
lua_pushcclosure(L, sector_iterate, 2); // push lib_iterateSubSectorPolylist and subsector->polyList as upvalues for the function
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -830,6 +877,9 @@ static int line_get(lua_State *L)
|
|||
case line_nexttag:
|
||||
lua_pushinteger(L, line->nexttag);
|
||||
return 1;
|
||||
case line_polyobj:
|
||||
LUA_PushUserdata(L, line->polyobj, META_POLYOBJ);
|
||||
return 1;
|
||||
case line_text:
|
||||
lua_pushstring(L, line->text);
|
||||
return 1;
|
||||
|
@ -1092,6 +1142,9 @@ static int seg_get(lua_State *L)
|
|||
case seg_backsector:
|
||||
LUA_PushUserdata(L, seg->backsector, META_SECTOR);
|
||||
return 1;
|
||||
case seg_polyseg:
|
||||
LUA_PushUserdata(L, seg->polyseg, META_POLYOBJ);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
486
src/lua_polyobjlib.c
Normal file
486
src/lua_polyobjlib.c
Normal file
|
@ -0,0 +1,486 @@
|
|||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2020 by Iestyn "Monster Iestyn" Jealous.
|
||||
// Copyright (C) 2020 by Sonic Team Junior.
|
||||
//
|
||||
// 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"
|
||||
#include "fastcmp.h"
|
||||
#include "p_local.h"
|
||||
#include "p_polyobj.h"
|
||||
#include "lua_script.h"
|
||||
#include "lua_libs.h"
|
||||
#include "lua_hud.h" // hud_running errors
|
||||
|
||||
#define NOHUD if (hud_running)\
|
||||
return luaL_error(L, "HUD rendering code should not call this function!");
|
||||
|
||||
enum polyobj_e {
|
||||
// properties
|
||||
polyobj_valid = 0,
|
||||
polyobj_id,
|
||||
polyobj_parent,
|
||||
polyobj_vertices,
|
||||
polyobj_lines,
|
||||
polyobj_sector,
|
||||
polyobj_angle,
|
||||
polyobj_damage,
|
||||
polyobj_thrust,
|
||||
polyobj_flags,
|
||||
polyobj_translucency,
|
||||
polyobj_triggertag,
|
||||
// special functions - utility
|
||||
polyobj_pointInside,
|
||||
polyobj_mobjTouching,
|
||||
polyobj_mobjInside,
|
||||
// special functions - manipulation
|
||||
polyobj_moveXY,
|
||||
polyobj_rotate
|
||||
};
|
||||
static const char *const polyobj_opt[] = {
|
||||
// properties
|
||||
"valid",
|
||||
"id",
|
||||
"parent",
|
||||
"vertices",
|
||||
"lines",
|
||||
"sector",
|
||||
"angle",
|
||||
"damage",
|
||||
"thrust",
|
||||
"flags",
|
||||
"translucency",
|
||||
"triggertag",
|
||||
// special functions - utility
|
||||
"pointInside",
|
||||
"mobjTouching",
|
||||
"mobjInside",
|
||||
// special functions - manipulation
|
||||
"moveXY",
|
||||
"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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
// special functions - manipulation
|
||||
static int lib_polyobj_moveXY(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);
|
||||
boolean checkmobjs = lua_opttrueboolean(L, 4);
|
||||
NOHUD
|
||||
INLEVEL
|
||||
if (!po)
|
||||
return LUA_ErrInvalid(L, "polyobj_t");
|
||||
lua_pushboolean(L, Polyobj_moveXY(po, x, y, checkmobjs));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int lib_polyobj_rotate(lua_State *L)
|
||||
{
|
||||
polyobj_t *po = *((polyobj_t **)luaL_checkudata(L, 1, META_POLYOBJ));
|
||||
angle_t delta = luaL_checkangle(L, 2);
|
||||
UINT8 turnthings = (UINT8)luaL_optinteger(L, 3, 0); // don't turn anything by default? (could change this if not desired)
|
||||
boolean checkmobjs = lua_opttrueboolean(L, 4);
|
||||
NOHUD
|
||||
INLEVEL
|
||||
if (!po)
|
||||
return LUA_ErrInvalid(L, "polyobj_t");
|
||||
lua_pushboolean(L, Polyobj_rotate(po, delta, turnthings, checkmobjs));
|
||||
return 1;
|
||||
}
|
||||
|
||||
///////////////
|
||||
// polyobj_t //
|
||||
///////////////
|
||||
|
||||
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)
|
||||
{
|
||||
// properties
|
||||
case polyobj_valid:
|
||||
lua_pushboolean(L, true);
|
||||
break;
|
||||
case polyobj_id:
|
||||
lua_pushinteger(L, polyobj->id);
|
||||
break;
|
||||
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;
|
||||
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;
|
||||
case polyobj_translucency:
|
||||
lua_pushinteger(L, polyobj->translucency);
|
||||
break;
|
||||
case polyobj_triggertag:
|
||||
lua_pushinteger(L, polyobj->triggertag);
|
||||
break;
|
||||
// special functions - utility
|
||||
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;
|
||||
// special functions - manipulation
|
||||
case polyobj_moveXY:
|
||||
lua_pushcfunction(L, lib_polyobj_moveXY);
|
||||
break;
|
||||
case polyobj_rotate:
|
||||
lua_pushcfunction(L, lib_polyobj_rotate);
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int polyobj_set(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)
|
||||
return LUA_ErrInvalid(L, "polyobj_t");
|
||||
|
||||
if (hud_running)
|
||||
return luaL_error(L, "Do not alter polyobj_t in HUD rendering code!");
|
||||
|
||||
switch (field)
|
||||
{
|
||||
default:
|
||||
return luaL_error(L, LUA_QL("polyobj_t") " field " LUA_QS " cannot be modified.", polyobj_opt[field]);
|
||||
case polyobj_angle:
|
||||
return luaL_error(L, LUA_QL("polyobj_t") " field " LUA_QS " should not be set directly. Use the function " LUA_QL("polyobj:rotate(angle)") " instead.", polyobj_opt[field]);
|
||||
case polyobj_parent:
|
||||
polyobj->parent = luaL_checkinteger(L, 3);
|
||||
break;
|
||||
case polyobj_flags:
|
||||
polyobj->flags = luaL_checkinteger(L, 3);
|
||||
break;
|
||||
case polyobj_translucency:
|
||||
polyobj->translucency = luaL_checkinteger(L, 3);
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
///////////////////
|
||||
// PolyObjects[] //
|
||||
///////////////////
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
// find PolyObject by ID
|
||||
else if (fastcmp(field,"GetForNum")) // name could probably be better
|
||||
{
|
||||
lua_pushcfunction(L, lib_PolyObject_getfornum);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lib_numPolyObjects(lua_State *L)
|
||||
{
|
||||
lua_pushinteger(L, numPolyObjects);
|
||||
return 1;
|
||||
}
|
||||
|
||||
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");
|
||||
|
||||
lua_pushcfunction(L, polyobj_set);
|
||||
lua_setfield(L, -2, "__newindex");
|
||||
|
||||
lua_pushcfunction(L, polyobj_num);
|
||||
lua_setfield(L, -2, "__len");
|
||||
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");
|
||||
return 0;
|
||||
}
|
|
@ -24,6 +24,7 @@
|
|||
#include "p_saveg.h"
|
||||
#include "p_local.h"
|
||||
#include "p_slopes.h" // for P_SlopeById
|
||||
#include "p_polyobj.h" // polyobj_t, PolyObjects
|
||||
#ifdef LUA_ALLOW_BYTECODE
|
||||
#include "d_netfil.h" // for LUA_DumpFile
|
||||
#endif
|
||||
|
@ -50,6 +51,7 @@ static lua_CFunction liblist[] = {
|
|||
LUA_SkinLib, // skin_t, skins[]
|
||||
LUA_ThinkerLib, // thinker_t
|
||||
LUA_MapLib, // line_t, side_t, sector_t, subsector_t
|
||||
LUA_PolyObjLib, // polyobj_t
|
||||
LUA_BlockmapLib, // blockmap stuff
|
||||
LUA_HudLib, // HUD stuff
|
||||
NULL
|
||||
|
@ -774,6 +776,12 @@ void LUA_InvalidateLevel(void)
|
|||
LUA_InvalidateUserdata(&sides[i]);
|
||||
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]);
|
||||
|
@ -832,6 +840,7 @@ enum
|
|||
ARCH_NODE,
|
||||
#endif
|
||||
ARCH_FFLOOR,
|
||||
ARCH_POLYOBJ,
|
||||
ARCH_SLOPE,
|
||||
ARCH_MAPHEADER,
|
||||
ARCH_SKINCOLOR,
|
||||
|
@ -858,6 +867,7 @@ static const struct {
|
|||
{META_NODE, ARCH_NODE},
|
||||
#endif
|
||||
{META_FFLOOR, ARCH_FFLOOR},
|
||||
{META_POLYOBJ, ARCH_POLYOBJ},
|
||||
{META_SLOPE, ARCH_SLOPE},
|
||||
{META_MAPHEADER, ARCH_MAPHEADER},
|
||||
{META_SKINCOLOR, ARCH_SKINCOLOR},
|
||||
|
@ -1126,6 +1136,17 @@ static UINT8 ArchiveValue(int TABLESINDEX, int myindex)
|
|||
}
|
||||
break;
|
||||
}
|
||||
case ARCH_POLYOBJ:
|
||||
{
|
||||
polyobj_t *polyobj = *((polyobj_t **)lua_touserdata(gL, myindex));
|
||||
if (!polyobj)
|
||||
WRITEUINT8(save_p, ARCH_NULL);
|
||||
else {
|
||||
WRITEUINT8(save_p, ARCH_POLYOBJ);
|
||||
WRITEUINT16(save_p, polyobj-PolyObjects);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ARCH_SLOPE:
|
||||
{
|
||||
pslope_t *slope = *((pslope_t **)lua_touserdata(gL, myindex));
|
||||
|
@ -1381,6 +1402,9 @@ static UINT8 UnArchiveValue(int TABLESINDEX)
|
|||
LUA_PushUserdata(gL, rover, META_FFLOOR);
|
||||
break;
|
||||
}
|
||||
case ARCH_POLYOBJ:
|
||||
LUA_PushUserdata(gL, &PolyObjects[READUINT16(save_p)], META_POLYOBJ);
|
||||
break;
|
||||
case ARCH_SLOPE:
|
||||
LUA_PushUserdata(gL, P_SlopeById(READUINT16(save_p)), META_SLOPE);
|
||||
break;
|
||||
|
|
|
@ -976,7 +976,7 @@ static INT32 Polyobj_clipThings(polyobj_t *po, line_t *line)
|
|||
|
||||
|
||||
// Moves a polyobject on the x-y plane.
|
||||
static boolean Polyobj_moveXY(polyobj_t *po, fixed_t x, fixed_t y, boolean checkmobjs)
|
||||
boolean Polyobj_moveXY(polyobj_t *po, fixed_t x, fixed_t y, boolean checkmobjs)
|
||||
{
|
||||
size_t i;
|
||||
vertex_t vec;
|
||||
|
@ -1162,7 +1162,7 @@ static void Polyobj_rotateThings(polyobj_t *po, vector2_t origin, angle_t delta,
|
|||
}
|
||||
|
||||
// Rotates a polyobject around its start point.
|
||||
static boolean Polyobj_rotate(polyobj_t *po, angle_t delta, UINT8 turnthings, boolean checkmobjs)
|
||||
boolean Polyobj_rotate(polyobj_t *po, angle_t delta, UINT8 turnthings, boolean checkmobjs)
|
||||
{
|
||||
size_t i;
|
||||
angle_t angle;
|
||||
|
|
|
@ -336,6 +336,8 @@ typedef struct polyfadedata_s
|
|||
// Functions
|
||||
//
|
||||
|
||||
boolean Polyobj_moveXY(polyobj_t *po, fixed_t x, fixed_t y, boolean checkmobjs);
|
||||
boolean Polyobj_rotate(polyobj_t *po, angle_t delta, UINT8 turnthings, boolean checkmobjs);
|
||||
polyobj_t *Polyobj_GetForNum(INT32 id);
|
||||
void Polyobj_InitLevel(void);
|
||||
void Polyobj_MoveOnLoad(polyobj_t *po, angle_t angle, fixed_t x, fixed_t y);
|
||||
|
|
|
@ -401,6 +401,7 @@
|
|||
<ClCompile Include="..\lua_mathlib.c" />
|
||||
<ClCompile Include="..\lua_mobjlib.c" />
|
||||
<ClCompile Include="..\lua_playerlib.c" />
|
||||
<ClCompile Include="..\lua_polyobjlib.c" />
|
||||
<ClCompile Include="..\lua_script.c" />
|
||||
<ClCompile Include="..\lua_skinlib.c" />
|
||||
<ClCompile Include="..\lua_thinkerlib.c" />
|
||||
|
|
|
@ -723,6 +723,9 @@
|
|||
<ClCompile Include="..\lua_playerlib.c">
|
||||
<Filter>LUA</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lua_polyobjlib.c">
|
||||
<Filter>LUA</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lua_script.c">
|
||||
<Filter>LUA</Filter>
|
||||
</ClCompile>
|
||||
|
|
Loading…
Reference in a new issue