mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2024-11-15 17:22:12 +00:00
Merge branch 'lua-additions' into 'master'
Lua additions Thought I'd may as well make a merge request so I can remind people of all the various Lua-related changes here (and because it's about time some of them got in): * Added `P_PointOnLineSide(x, y, line)`. Allows you to quickly determine which side of a line faces the point. *line* can be a real line_t or a custom defined line (just like with P_ClosestPointOnLine). * Added seg_t and node_t support to Lua (note: these are disabled for now, due to complications with OpenGL that we all know something of by now. Bit of a shame really :( ) - of note is node.children and node.bbox: * node.children[] is an array that takes 0 or 1 as indexes (or "right" and "left", alternatively) * node.bbox(child,bboxcoord) is a two-arg function: child can be 0 or 1 (or "right" and "left", alternatively), bbox coord can be 0,1,2 or 3 (or "top", "bottom", "left" and "right", alternatively) * aside from the above, segs[] and nodes[] store the segs/nodes of the current map; segs.iterate and nodes.iterate iterates through segs/nodes * NF_SUBSECTOR is also available for usage with node.children * You can now get the palette indexes (i.e. colormap[n]) of colormap userdata from `v.getColormap`, where n is a palette index number between 0 and 255. Useful for finding out which palette colors turned into what, if they changed at all * ffloor_t userdata can now save to and be read from $$$.sav in netgames properly; this means custom mobj/player variables and NetVars can both send/recieve them directly if you wanted * **IMPORTANT** Blockmap search library! (with a new file: lua_blockmaplib.c) * Format of iteration function: `searchBlockmap(searchtype, function, mobj, [x1, x2, y1, y2])`. Returns true if search was uninteruppted, false if the iteration function returned true at any point * *searchtype* can be either "objects" or "lines", for looking for mobj_t and line_t stuff in the blockmap respectively * *function* is a function of your choice to iterate with: (sorry I can't get the next two bullets to be one indent further to the side) - format of function needed: `funcname(mobj, foundmobj)` or `funcname(mobj, foundline)` (for searching for objects and lines, respectively) - return value of *function* affects searching somewhat: nil doesn't change searching, false ends searching in a block (but doesn't stop searching, it just moves onto the next), and true ends the full search. Both returning true or false ultimately makes `searchBlockmap` return false. * *mobj* is the reference mobj that you're checking around (if you don't supply x/y ranges to search in, it defaults to checking within the mobj's radius in both axes). If *mobj* was removed mid-search the search stops and `searchBlockmap` returns false * (optional) *x1, x2, y1, y2* are coordinates on the map to search the blockmap between, if given See merge request !54
This commit is contained in:
commit
47e053c8f6
17 changed files with 961 additions and 2 deletions
15
SRB2.cbp
15
SRB2.cbp
|
@ -1516,6 +1516,21 @@ HW3SOUND for 3D hardware sound support
|
|||
<Unit filename="src/lua_baselib.c">
|
||||
<Option compilerVar="CC" />
|
||||
</Unit>
|
||||
<Unit filename="src/lua_blockmaplib.c">
|
||||
<Option compilerVar="CC" />
|
||||
<Option target="Debug Native/SDL" />
|
||||
<Option target="Release Native/SDL" />
|
||||
<Option target="Debug Mingw/SDL" />
|
||||
<Option target="Release Mingw/SDL" />
|
||||
<Option target="Debug Mingw/DirectX" />
|
||||
<Option target="Release Mingw/DirectX" />
|
||||
<Option target="Debug Linux/SDL" />
|
||||
<Option target="Release Linux/SDL" />
|
||||
<Option target="Debug Mingw64/SDL" />
|
||||
<Option target="Release Mingw64/SDL" />
|
||||
<Option target="Debug Mingw64/DirectX" />
|
||||
<Option target="Release Mingw64/DirectX" />
|
||||
</Unit>
|
||||
<Unit filename="src/lua_consolelib.c">
|
||||
<Option compilerVar="CC" />
|
||||
</Unit>
|
||||
|
|
|
@ -231,6 +231,7 @@ if(${SRB2_CONFIG_HAVE_BLUA})
|
|||
add_definitions(-DHAVE_BLUA)
|
||||
set(SRB2_LUA_SOURCES
|
||||
lua_baselib.c
|
||||
lua_blockmaplib.c
|
||||
lua_consolelib.c
|
||||
lua_hooklib.c
|
||||
lua_hudlib.c
|
||||
|
|
|
@ -48,4 +48,5 @@ OBJS:=$(OBJS) \
|
|||
$(OBJDIR)/lua_skinlib.o \
|
||||
$(OBJDIR)/lua_thinkerlib.o \
|
||||
$(OBJDIR)/lua_maplib.o \
|
||||
$(OBJDIR)/lua_blockmaplib.o \
|
||||
$(OBJDIR)/lua_hudlib.o
|
||||
|
|
|
@ -7578,6 +7578,11 @@ struct {
|
|||
{"FF_COLORMAPONLY",FF_COLORMAPONLY}, ///< Only copy the colormap, not the lightlevel
|
||||
{"FF_GOOWATER",FF_GOOWATER}, ///< Used with ::FF_SWIMMABLE. Makes thick bouncey goop.
|
||||
|
||||
#ifdef HAVE_LUA_SEGS
|
||||
// Node flags
|
||||
{"NF_SUBSECTOR",NF_SUBSECTOR}, // Indicate a leaf.
|
||||
#endif
|
||||
|
||||
// Angles
|
||||
{"ANG1",ANG1},
|
||||
{"ANG2",ANG2},
|
||||
|
|
|
@ -27,7 +27,6 @@
|
|||
|
||||
#define NOHUD if (hud_running) return luaL_error(L, "HUD rendering code should not call this function!");
|
||||
|
||||
|
||||
boolean luaL_checkboolean(lua_State *L, int narg) {
|
||||
luaL_checktype(L, narg, LUA_TBOOLEAN);
|
||||
return lua_toboolean(L, narg);
|
||||
|
@ -205,6 +204,41 @@ static int lib_pClosestPointOnLine(lua_State *L)
|
|||
return 2;
|
||||
}
|
||||
|
||||
static int lib_pPointOnLineSide(lua_State *L)
|
||||
{
|
||||
int n = lua_gettop(L);
|
||||
fixed_t x = luaL_checkfixed(L, 1);
|
||||
fixed_t y = luaL_checkfixed(L, 2);
|
||||
//HUDSAFE
|
||||
if (lua_isuserdata(L, 3)) // use a real linedef to get our points
|
||||
{
|
||||
line_t *line = *((line_t **)luaL_checkudata(L, 3, META_LINE));
|
||||
if (!line)
|
||||
return LUA_ErrInvalid(L, "line_t");
|
||||
lua_pushinteger(L, P_PointOnLineSide(x, y, line));
|
||||
}
|
||||
else // use custom coordinates of our own!
|
||||
{
|
||||
vertex_t v1, v2; // fake vertexes
|
||||
line_t junk; // fake linedef
|
||||
|
||||
if (n < 6)
|
||||
return luaL_error(L, "arguments 3 to 6 not all given (expected 4 fixed-point integers)");
|
||||
|
||||
v1.x = luaL_checkfixed(L, 3);
|
||||
v1.y = luaL_checkfixed(L, 4);
|
||||
v2.x = luaL_checkfixed(L, 5);
|
||||
v2.y = luaL_checkfixed(L, 6);
|
||||
|
||||
junk.v1 = &v1;
|
||||
junk.v2 = &v2;
|
||||
junk.dx = v2.x - v1.x;
|
||||
junk.dy = v2.y - v1.y;
|
||||
lua_pushinteger(L, P_PointOnLineSide(x, y, &junk));
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
// P_ENEMY
|
||||
/////////////
|
||||
|
||||
|
@ -2047,6 +2081,7 @@ static luaL_Reg lib[] = {
|
|||
// p_maputil
|
||||
{"P_AproxDistance",lib_pAproxDistance},
|
||||
{"P_ClosestPointOnLine",lib_pClosestPointOnLine},
|
||||
{"P_PointOnLineSide",lib_pPointOnLineSide},
|
||||
|
||||
// p_enemy
|
||||
{"P_CheckMeleeRange", lib_pCheckMeleeRange},
|
||||
|
|
266
src/lua_blockmaplib.c
Normal file
266
src/lua_blockmaplib.c
Normal file
|
@ -0,0 +1,266 @@
|
|||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2016 by Iestyn "Monster Iestyn" Jealous.
|
||||
// Copyright (C) 2016 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_blockmaplib.c
|
||||
/// \brief blockmap library for Lua scripting
|
||||
|
||||
#include "doomdef.h"
|
||||
#ifdef HAVE_BLUA
|
||||
#include "p_local.h"
|
||||
#include "r_main.h" // validcount
|
||||
#include "lua_script.h"
|
||||
#include "lua_libs.h"
|
||||
//#include "lua_hud.h" // hud_running errors
|
||||
|
||||
static const char *const search_opt[] = {
|
||||
"objects",
|
||||
"lines",
|
||||
NULL};
|
||||
|
||||
// a quickly-made function pointer typedef used by lib_searchBlockmap...
|
||||
// return values:
|
||||
// 0 - normal, no interruptions
|
||||
// 1 - stop search through current block
|
||||
// 2 - stop search completely
|
||||
typedef UINT8 (*blockmap_func)(lua_State *, INT32, INT32, mobj_t *);
|
||||
|
||||
static boolean blockfuncerror = false; // errors should only print once per search blockmap call
|
||||
|
||||
// Helper function for "objects" search
|
||||
static UINT8 lib_searchBlockmap_Objects(lua_State *L, INT32 x, INT32 y, mobj_t *thing)
|
||||
{
|
||||
mobj_t *mobj, *bnext = NULL;
|
||||
|
||||
if (x < 0 || y < 0 || x >= bmapwidth || y >= bmapheight)
|
||||
return 0;
|
||||
|
||||
// Check interaction with the objects in the blockmap.
|
||||
for (mobj = blocklinks[y*bmapwidth + x]; mobj; mobj = bnext)
|
||||
{
|
||||
P_SetTarget(&bnext, mobj->bnext); // We want to note our reference to bnext here incase it is MF_NOTHINK and gets removed!
|
||||
if (mobj == thing)
|
||||
continue; // our thing just found itself, so move on
|
||||
lua_pushvalue(L, 1); // push function
|
||||
LUA_PushUserdata(L, thing, META_MOBJ);
|
||||
LUA_PushUserdata(L, mobj, META_MOBJ);
|
||||
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) // func just popped our thing, cannot continue.
|
||||
|| (bnext && P_MobjWasRemoved(bnext))) // func just broke blockmap chain, cannot continue.
|
||||
{
|
||||
P_SetTarget(&bnext, NULL);
|
||||
return (P_MobjWasRemoved(thing)) ? 2 : 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Helper function for "lines" search
|
||||
static UINT8 lib_searchBlockmap_Lines(lua_State *L, INT32 x, INT32 y, mobj_t *thing)
|
||||
{
|
||||
INT32 offset;
|
||||
const INT32 *list; // Big blockmap
|
||||
#ifdef POLYOBJECTS
|
||||
polymaplink_t *plink; // haleyjd 02/22/06
|
||||
#endif
|
||||
line_t *ld;
|
||||
|
||||
if (x < 0 || y < 0 || x >= bmapwidth || y >= bmapheight)
|
||||
return 0;
|
||||
|
||||
offset = y*bmapwidth + x;
|
||||
|
||||
#ifdef POLYOBJECTS
|
||||
// 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
|
||||
{
|
||||
size_t i;
|
||||
po->validcount = validcount;
|
||||
|
||||
for (i = 0; i < po->numLines; ++i)
|
||||
{
|
||||
if (po->lines[i]->validcount == validcount) // line has been checked
|
||||
continue;
|
||||
po->lines[i]->validcount = validcount;
|
||||
|
||||
lua_pushvalue(L, 1);
|
||||
LUA_PushUserdata(L, thing, META_MOBJ);
|
||||
LUA_PushUserdata(L, po->lines[i], META_LINE);
|
||||
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);
|
||||
}
|
||||
#endif
|
||||
|
||||
offset = *(blockmap + offset); // offset = blockmap[y*bmapwidth+x];
|
||||
|
||||
// First index is really empty, so +1 it.
|
||||
for (list = blockmaplump + offset + 1; *list != -1; list++)
|
||||
{
|
||||
ld = &lines[*list];
|
||||
|
||||
if (ld->validcount == validcount)
|
||||
continue; // Line has already been checked.
|
||||
|
||||
ld->validcount = validcount;
|
||||
|
||||
lua_pushvalue(L, 1);
|
||||
LUA_PushUserdata(L, thing, META_MOBJ);
|
||||
LUA_PushUserdata(L, ld, META_LINE);
|
||||
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;
|
||||
}
|
||||
return 0; // Everything was checked.
|
||||
}
|
||||
|
||||
// The searchBlockmap function
|
||||
// arguments: searchBlockmap(searchtype, function, mobj, [x1, x2, y1, y2])
|
||||
// return value:
|
||||
// true = search completely uninteruppted,
|
||||
// false = searching of at least one block stopped mid-way (including if the whole search was stopped)
|
||||
static int lib_searchBlockmap(lua_State *L)
|
||||
{
|
||||
int searchtype = luaL_checkoption(L, 1, "objects", search_opt);
|
||||
int n;
|
||||
mobj_t *mobj;
|
||||
INT32 xl, xh, yl, yh, bx, by;
|
||||
fixed_t x1, x2, y1, y2;
|
||||
boolean retval = true;
|
||||
UINT8 funcret = 0;
|
||||
blockmap_func searchFunc;
|
||||
|
||||
lua_remove(L, 1); // remove searchtype, stack is now function, mobj, [x1, x2, y1, y2]
|
||||
luaL_checktype(L, 1, LUA_TFUNCTION);
|
||||
|
||||
switch (searchtype)
|
||||
{
|
||||
case 0: // "objects"
|
||||
default:
|
||||
searchFunc = lib_searchBlockmap_Objects;
|
||||
break;
|
||||
case 1: // "lines"
|
||||
searchFunc = lib_searchBlockmap_Lines;
|
||||
break;
|
||||
}
|
||||
|
||||
// the mobj we are searching around, the "calling" mobj we could say
|
||||
mobj = *((mobj_t **)luaL_checkudata(L, 2, META_MOBJ));
|
||||
if (!mobj)
|
||||
return LUA_ErrInvalid(L, "mobj_t");
|
||||
|
||||
n = lua_gettop(L);
|
||||
|
||||
if (n > 2) // specific x/y ranges have been supplied
|
||||
{
|
||||
if (n < 6)
|
||||
return luaL_error(L, "arguments 4 to 6 not all given (expected 4 fixed-point integers)");
|
||||
|
||||
x1 = luaL_checkfixed(L, 3);
|
||||
x2 = luaL_checkfixed(L, 4);
|
||||
y1 = luaL_checkfixed(L, 5);
|
||||
y2 = luaL_checkfixed(L, 6);
|
||||
}
|
||||
else // mobj and function only - search around mobj's radius by default
|
||||
{
|
||||
fixed_t radius = mobj->radius + MAXRADIUS;
|
||||
x1 = mobj->x - radius;
|
||||
x2 = mobj->x + radius;
|
||||
y1 = mobj->y - radius;
|
||||
y2 = mobj->y + radius;
|
||||
}
|
||||
lua_settop(L, 2); // pop everything except function, mobj
|
||||
|
||||
xl = (unsigned)(x1 - bmaporgx)>>MAPBLOCKSHIFT;
|
||||
xh = (unsigned)(x2 - bmaporgx)>>MAPBLOCKSHIFT;
|
||||
yl = (unsigned)(y1 - bmaporgy)>>MAPBLOCKSHIFT;
|
||||
yh = (unsigned)(y2 - bmaporgy)>>MAPBLOCKSHIFT;
|
||||
|
||||
BMBOUNDFIX(xl, xh, yl, yh);
|
||||
|
||||
blockfuncerror = false; // reset
|
||||
validcount++;
|
||||
for (bx = xl; bx <= xh; bx++)
|
||||
for (by = yl; by <= yh; by++)
|
||||
{
|
||||
funcret = searchFunc(L, bx, by, mobj);
|
||||
// return value of searchFunc determines searchFunc's return value and/or when to stop
|
||||
if (funcret == 2){ // stop whole search
|
||||
lua_pushboolean(L, false); // return false
|
||||
return 1;
|
||||
}
|
||||
else if (funcret == 1) // search was interrupted for this block
|
||||
retval = false; // this changes the return value, but doesn't stop the whole search
|
||||
// else don't do anything, continue as normal
|
||||
if (P_MobjWasRemoved(mobj)){ // ...unless the original object was removed
|
||||
lua_pushboolean(L, false); // in which case we have to stop now regardless
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
lua_pushboolean(L, retval);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int LUA_BlockmapLib(lua_State *L)
|
||||
{
|
||||
lua_register(L, "searchBlockmap", lib_searchBlockmap);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -226,7 +226,12 @@ static int hudinfo_num(lua_State *L)
|
|||
|
||||
static int colormap_get(lua_State *L)
|
||||
{
|
||||
return luaL_error(L, "colormap is not a struct.");
|
||||
const UINT8 *colormap = *((UINT8 **)luaL_checkudata(L, 1, META_COLORMAP));
|
||||
UINT32 i = luaL_checkinteger(L, 2);
|
||||
if (i >= 256)
|
||||
return luaL_error(L, "colormap index %d out of range (0 - %d)", i, 255);
|
||||
lua_pushinteger(L, colormap[i]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int patch_get(lua_State *L)
|
||||
|
|
|
@ -38,12 +38,22 @@ extern lua_State *gL;
|
|||
#define META_SUBSECTOR "SUBSECTOR_T*"
|
||||
#define META_SECTOR "SECTOR_T*"
|
||||
#define META_FFLOOR "FFLOOR_T*"
|
||||
#ifdef HAVE_LUA_SEGS
|
||||
#define META_SEG "SEG_T*"
|
||||
#define META_NODE "NODE_T*"
|
||||
#endif
|
||||
#define META_MAPHEADER "MAPHEADER_T*"
|
||||
|
||||
#define META_CVAR "CONSVAR_T*"
|
||||
|
||||
#define META_SECTORLINES "SECTOR_T*LINES"
|
||||
#define META_SIDENUM "LINE_T*SIDENUM"
|
||||
#ifdef HAVE_LUA_SEGS
|
||||
#define META_NODEBBOX "NODE_T*BBOX"
|
||||
#define META_NODECHILDREN "NODE_T*CHILDREN"
|
||||
#endif
|
||||
|
||||
#define META_BBOX "BOUNDING_BOX"
|
||||
|
||||
#define META_HUDINFO "HUDINFO_T*"
|
||||
#define META_PATCH "PATCH_T*"
|
||||
|
@ -64,6 +74,7 @@ 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_BlockmapLib(lua_State *L);
|
||||
int LUA_HudLib(lua_State *L);
|
||||
|
||||
#endif
|
||||
|
|
483
src/lua_maplib.c
483
src/lua_maplib.c
|
@ -185,6 +185,82 @@ static const char *const ffloor_opt[] = {
|
|||
"alpha",
|
||||
NULL};
|
||||
|
||||
#ifdef HAVE_LUA_SEGS
|
||||
enum seg_e {
|
||||
seg_valid = 0,
|
||||
seg_v1,
|
||||
seg_v2,
|
||||
seg_side,
|
||||
seg_offset,
|
||||
seg_angle,
|
||||
seg_sidedef,
|
||||
seg_linedef,
|
||||
seg_frontsector,
|
||||
seg_backsector,
|
||||
};
|
||||
|
||||
static const char *const seg_opt[] = {
|
||||
"valid",
|
||||
"v1",
|
||||
"v2",
|
||||
"side",
|
||||
"offset",
|
||||
"angle",
|
||||
"sidedef",
|
||||
"linedef",
|
||||
"frontsector",
|
||||
"backsector",
|
||||
NULL};
|
||||
|
||||
enum node_e {
|
||||
node_valid = 0,
|
||||
node_x,
|
||||
node_y,
|
||||
node_dx,
|
||||
node_dy,
|
||||
node_bbox,
|
||||
node_children,
|
||||
};
|
||||
|
||||
static const char *const node_opt[] = {
|
||||
"valid",
|
||||
"x",
|
||||
"y",
|
||||
"dx",
|
||||
"dy",
|
||||
"bbox",
|
||||
"children",
|
||||
NULL};
|
||||
|
||||
enum nodechild_e {
|
||||
nodechild_valid = 0,
|
||||
nodechild_right,
|
||||
nodechild_left,
|
||||
};
|
||||
|
||||
static const char *const nodechild_opt[] = {
|
||||
"valid",
|
||||
"right",
|
||||
"left",
|
||||
NULL};
|
||||
#endif
|
||||
|
||||
enum bbox_e {
|
||||
bbox_valid = 0,
|
||||
bbox_top,
|
||||
bbox_bottom,
|
||||
bbox_left,
|
||||
bbox_right,
|
||||
};
|
||||
|
||||
static const char *const bbox_opt[] = {
|
||||
"valid",
|
||||
"top",
|
||||
"bottom",
|
||||
"left",
|
||||
"right",
|
||||
NULL};
|
||||
|
||||
static const char *const array_opt[] ={"iterate",NULL};
|
||||
static const char *const valid_opt[] ={"valid",NULL};
|
||||
|
||||
|
@ -768,6 +844,262 @@ static int vertex_num(lua_State *L)
|
|||
return 1;
|
||||
}
|
||||
|
||||
#ifdef HAVE_LUA_SEGS
|
||||
static int seg_get(lua_State *L)
|
||||
{
|
||||
seg_t *seg = *((seg_t **)luaL_checkudata(L, 1, META_SEG));
|
||||
enum seg_e field = luaL_checkoption(L, 2, seg_opt[0], seg_opt);
|
||||
|
||||
if (!seg)
|
||||
{
|
||||
if (field == seg_valid) {
|
||||
lua_pushboolean(L, 0);
|
||||
return 1;
|
||||
}
|
||||
return luaL_error(L, "accessed seg_t doesn't exist anymore.");
|
||||
}
|
||||
|
||||
switch(field)
|
||||
{
|
||||
case seg_valid: // valid
|
||||
lua_pushboolean(L, 1);
|
||||
return 1;
|
||||
case seg_v1:
|
||||
LUA_PushUserdata(L, seg->v1, META_VERTEX);
|
||||
return 1;
|
||||
case seg_v2:
|
||||
LUA_PushUserdata(L, seg->v2, META_VERTEX);
|
||||
return 1;
|
||||
case seg_side:
|
||||
lua_pushinteger(L, seg->side);
|
||||
return 1;
|
||||
case seg_offset:
|
||||
lua_pushfixed(L, seg->offset);
|
||||
return 1;
|
||||
case seg_angle:
|
||||
lua_pushangle(L, seg->angle);
|
||||
return 1;
|
||||
case seg_sidedef:
|
||||
LUA_PushUserdata(L, seg->sidedef, META_SIDE);
|
||||
return 1;
|
||||
case seg_linedef:
|
||||
LUA_PushUserdata(L, seg->linedef, META_LINE);
|
||||
return 1;
|
||||
case seg_frontsector:
|
||||
LUA_PushUserdata(L, seg->frontsector, META_SECTOR);
|
||||
return 1;
|
||||
case seg_backsector:
|
||||
LUA_PushUserdata(L, seg->backsector, META_SECTOR);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int seg_num(lua_State *L)
|
||||
{
|
||||
seg_t *seg = *((seg_t **)luaL_checkudata(L, 1, META_SEG));
|
||||
lua_pushinteger(L, seg-segs);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int node_get(lua_State *L)
|
||||
{
|
||||
node_t *node = *((node_t **)luaL_checkudata(L, 1, META_NODE));
|
||||
enum node_e field = luaL_checkoption(L, 2, node_opt[0], node_opt);
|
||||
|
||||
if (!node)
|
||||
{
|
||||
if (field == node_valid) {
|
||||
lua_pushboolean(L, 0);
|
||||
return 1;
|
||||
}
|
||||
return luaL_error(L, "accessed node_t doesn't exist anymore.");
|
||||
}
|
||||
|
||||
switch(field)
|
||||
{
|
||||
case node_valid: // valid
|
||||
lua_pushboolean(L, 1);
|
||||
return 1;
|
||||
case node_x:
|
||||
lua_pushfixed(L, node->x);
|
||||
return 1;
|
||||
case node_y:
|
||||
lua_pushfixed(L, node->y);
|
||||
return 1;
|
||||
case node_dx:
|
||||
lua_pushfixed(L, node->x);
|
||||
return 1;
|
||||
case node_dy:
|
||||
lua_pushfixed(L, node->x);
|
||||
return 1;
|
||||
case node_bbox:
|
||||
LUA_PushUserdata(L, node->bbox, META_NODEBBOX);
|
||||
return 1;
|
||||
case node_children:
|
||||
LUA_PushUserdata(L, node->children, META_NODECHILDREN);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int node_num(lua_State *L)
|
||||
{
|
||||
node_t *node = *((node_t **)luaL_checkudata(L, 1, META_NODE));
|
||||
lua_pushinteger(L, node-nodes);
|
||||
return 1;
|
||||
}
|
||||
/*
|
||||
// node.bbox[i][j]: i = 0 or 1, j = 0 1 2 or 3
|
||||
// NOTE: 2D arrays are NOT double pointers,
|
||||
// the second bbox will be directly after the first in memory (hence the way the bbox is pushed here)
|
||||
// this function handles the [i] part, bbox_get handles the [j] part
|
||||
static int nodebbox_get(lua_State *L)
|
||||
{
|
||||
fixed_t *bbox = *((fixed_t **)luaL_checkudata(L, 1, META_NODEBBOX));
|
||||
int i;
|
||||
lua_settop(L, 2);
|
||||
if (!lua_isnumber(L, 2))
|
||||
{
|
||||
int field = luaL_checkoption(L, 2, NULL, valid_opt);
|
||||
if (!bbox)
|
||||
{
|
||||
if (field == 0) {
|
||||
lua_pushboolean(L, 0);
|
||||
return 1;
|
||||
}
|
||||
return luaL_error(L, "accessed node_t doesn't exist anymore.");
|
||||
} else if (field == 0) {
|
||||
lua_pushboolean(L, 1);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
i = lua_tointeger(L, 2);
|
||||
if (i < 0 || i > 1)
|
||||
return 0;
|
||||
LUA_PushUserdata(L, bbox + i*4*sizeof(fixed_t), META_BBOX);
|
||||
return 1;
|
||||
}
|
||||
*/
|
||||
static int nodebbox_call(lua_State *L)
|
||||
{
|
||||
fixed_t *bbox = *((fixed_t **)luaL_checkudata(L, 1, META_NODEBBOX));
|
||||
int i, j;
|
||||
int n = lua_gettop(L);
|
||||
|
||||
if (!bbox)
|
||||
return luaL_error(L, "accessed node bbox doesn't exist anymore.");
|
||||
if (n < 3)
|
||||
return luaL_error(L, "arguments 2 and/or 3 not given (expected node.bbox(child, coord))");
|
||||
// get child
|
||||
if (!lua_isnumber(L, 2)) {
|
||||
enum nodechild_e field = luaL_checkoption(L, 2, nodechild_opt[0], nodechild_opt);
|
||||
switch (field) {
|
||||
case nodechild_right: i = 0; break;
|
||||
case nodechild_left: i = 1; break;
|
||||
default:
|
||||
return luaL_error(L, "invalid node child \"%s\".", lua_tostring(L, 2));
|
||||
}
|
||||
}
|
||||
else {
|
||||
i = lua_tointeger(L, 2);
|
||||
if (i < 0 || i > 1)
|
||||
return 0;
|
||||
}
|
||||
// get bbox coord
|
||||
if (!lua_isnumber(L, 3)) {
|
||||
enum bbox_e field = luaL_checkoption(L, 3, bbox_opt[0], bbox_opt);
|
||||
switch (field) {
|
||||
case bbox_top: j = BOXTOP; break;
|
||||
case bbox_bottom: j = BOXBOTTOM; break;
|
||||
case bbox_left: j = BOXLEFT; break;
|
||||
case bbox_right: j = BOXRIGHT; break;
|
||||
default:
|
||||
return luaL_error(L, "invalid bbox coordinate \"%s\".", lua_tostring(L, 3));
|
||||
}
|
||||
}
|
||||
else {
|
||||
j = lua_tointeger(L, 3);
|
||||
if (j < 0 || j > 3)
|
||||
return 0;
|
||||
}
|
||||
lua_pushinteger(L, bbox[i*4 + j]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// node.children[i]: i = 0 or 1
|
||||
static int nodechildren_get(lua_State *L)
|
||||
{
|
||||
UINT16 *children = *((UINT16 **)luaL_checkudata(L, 1, META_NODECHILDREN));
|
||||
int i;
|
||||
lua_settop(L, 2);
|
||||
if (!lua_isnumber(L, 2))
|
||||
{
|
||||
enum nodechild_e field = luaL_checkoption(L, 2, nodechild_opt[0], nodechild_opt);
|
||||
if (!children)
|
||||
{
|
||||
if (field == nodechild_valid) {
|
||||
lua_pushboolean(L, 0);
|
||||
return 1;
|
||||
}
|
||||
return luaL_error(L, "accessed node_t doesn't exist anymore.");
|
||||
} else if (field == nodechild_valid) {
|
||||
lua_pushboolean(L, 1);
|
||||
return 1;
|
||||
} else switch (field) {
|
||||
case nodechild_right: i = 0; break;
|
||||
case nodechild_left: i = 1; break;
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
i = lua_tointeger(L, 2);
|
||||
if (i < 0 || i > 1)
|
||||
return 0;
|
||||
}
|
||||
lua_pushinteger(L, children[i]);
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
// bounding box (aka fixed_t array with four elements)
|
||||
// NOTE: may be useful for polyobjects or other things later
|
||||
static int bbox_get(lua_State *L)
|
||||
{
|
||||
fixed_t *bbox = *((fixed_t **)luaL_checkudata(L, 1, META_BBOX));
|
||||
int i;
|
||||
lua_settop(L, 2);
|
||||
if (!lua_isnumber(L, 2))
|
||||
{
|
||||
enum bbox_e field = luaL_checkoption(L, 2, bbox_opt[0], bbox_opt);
|
||||
if (!bbox)
|
||||
{
|
||||
if (field == bbox_valid) {
|
||||
lua_pushboolean(L, 0);
|
||||
return 1;
|
||||
}
|
||||
return luaL_error(L, "accessed bbox doesn't exist anymore.");
|
||||
} else if (field == bbox_valid) {
|
||||
lua_pushboolean(L, 1);
|
||||
return 1;
|
||||
} else switch (field) {
|
||||
case bbox_top: i = BOXTOP; break;
|
||||
case bbox_bottom: i = BOXBOTTOM; break;
|
||||
case bbox_left: i = BOXLEFT; break;
|
||||
case bbox_right: i = BOXRIGHT; break;
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
i = lua_tointeger(L, 2);
|
||||
if (i < 0 || i > 3)
|
||||
return 0;
|
||||
}
|
||||
lua_pushinteger(L, bbox[i]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int lib_iterateSectors(lua_State *L)
|
||||
{
|
||||
size_t i = 0;
|
||||
|
@ -998,6 +1330,100 @@ static int lib_numvertexes(lua_State *L)
|
|||
return 1;
|
||||
}
|
||||
|
||||
#ifdef HAVE_LUA_SEGS
|
||||
static int lib_iterateSegs(lua_State *L)
|
||||
{
|
||||
size_t i = 0;
|
||||
if (lua_gettop(L) < 2)
|
||||
return luaL_error(L, "Don't call segs.iterate() directly, use it as 'for seg in segs.iterate do <block> end'.");
|
||||
lua_settop(L, 2);
|
||||
lua_remove(L, 1); // state is unused.
|
||||
if (!lua_isnil(L, 1))
|
||||
i = (size_t)(*((seg_t **)luaL_checkudata(L, 1, META_SEG)) - segs)+1;
|
||||
if (i < numsegs)
|
||||
{
|
||||
LUA_PushUserdata(L, &segs[i], META_SEG);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lib_getSeg(lua_State *L)
|
||||
{
|
||||
int field;
|
||||
lua_settop(L, 2);
|
||||
lua_remove(L, 1); // dummy userdata table is unused.
|
||||
if (lua_isnumber(L, 1))
|
||||
{
|
||||
size_t i = lua_tointeger(L, 1);
|
||||
if (i >= numsegs)
|
||||
return 0;
|
||||
LUA_PushUserdata(L, &segs[i], META_SEG);
|
||||
return 1;
|
||||
}
|
||||
field = luaL_checkoption(L, 1, NULL, array_opt);
|
||||
switch(field)
|
||||
{
|
||||
case 0: // iterate
|
||||
lua_pushcfunction(L, lib_iterateSegs);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lib_numsegs(lua_State *L)
|
||||
{
|
||||
lua_pushinteger(L, numsegs);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int lib_iterateNodes(lua_State *L)
|
||||
{
|
||||
size_t i = 0;
|
||||
if (lua_gettop(L) < 2)
|
||||
return luaL_error(L, "Don't call nodes.iterate() directly, use it as 'for node in nodes.iterate do <block> end'.");
|
||||
lua_settop(L, 2);
|
||||
lua_remove(L, 1); // state is unused.
|
||||
if (!lua_isnil(L, 1))
|
||||
i = (size_t)(*((node_t **)luaL_checkudata(L, 1, META_NODE)) - nodes)+1;
|
||||
if (i < numsegs)
|
||||
{
|
||||
LUA_PushUserdata(L, &nodes[i], META_NODE);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lib_getNode(lua_State *L)
|
||||
{
|
||||
int field;
|
||||
lua_settop(L, 2);
|
||||
lua_remove(L, 1); // dummy userdata table is unused.
|
||||
if (lua_isnumber(L, 1))
|
||||
{
|
||||
size_t i = lua_tointeger(L, 1);
|
||||
if (i >= numnodes)
|
||||
return 0;
|
||||
LUA_PushUserdata(L, &nodes[i], META_NODE);
|
||||
return 1;
|
||||
}
|
||||
field = luaL_checkoption(L, 1, NULL, array_opt);
|
||||
switch(field)
|
||||
{
|
||||
case 0: // iterate
|
||||
lua_pushcfunction(L, lib_iterateNodes);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lib_numnodes(lua_State *L)
|
||||
{
|
||||
lua_pushinteger(L, numnodes);
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int ffloor_get(lua_State *L)
|
||||
{
|
||||
ffloor_t *ffloor = *((ffloor_t **)luaL_checkudata(L, 1, META_FFLOOR));
|
||||
|
@ -1317,6 +1743,41 @@ int LUA_MapLib(lua_State *L)
|
|||
lua_setfield(L, -2, "__newindex");
|
||||
lua_pop(L, 1);
|
||||
|
||||
#ifdef HAVE_LUA_SEGS
|
||||
luaL_newmetatable(L, META_SEG);
|
||||
lua_pushcfunction(L, seg_get);
|
||||
lua_setfield(L, -2, "__index");
|
||||
|
||||
lua_pushcfunction(L, seg_num);
|
||||
lua_setfield(L, -2, "__len");
|
||||
lua_pop(L, 1);
|
||||
|
||||
luaL_newmetatable(L, META_NODE);
|
||||
lua_pushcfunction(L, node_get);
|
||||
lua_setfield(L, -2, "__index");
|
||||
|
||||
lua_pushcfunction(L, node_num);
|
||||
lua_setfield(L, -2, "__len");
|
||||
lua_pop(L, 1);
|
||||
|
||||
luaL_newmetatable(L, META_NODEBBOX);
|
||||
//lua_pushcfunction(L, nodebbox_get);
|
||||
//lua_setfield(L, -2, "__index");
|
||||
lua_pushcfunction(L, nodebbox_call);
|
||||
lua_setfield(L, -2, "__call");
|
||||
lua_pop(L, 1);
|
||||
|
||||
luaL_newmetatable(L, META_NODECHILDREN);
|
||||
lua_pushcfunction(L, nodechildren_get);
|
||||
lua_setfield(L, -2, "__index");
|
||||
lua_pop(L, 1);
|
||||
#endif
|
||||
|
||||
luaL_newmetatable(L, META_BBOX);
|
||||
lua_pushcfunction(L, bbox_get);
|
||||
lua_setfield(L, -2, "__index");
|
||||
lua_pop(L, 1);
|
||||
|
||||
luaL_newmetatable(L, META_MAPHEADER);
|
||||
lua_pushcfunction(L, mapheaderinfo_get);
|
||||
lua_setfield(L, -2, "__index");
|
||||
|
@ -1375,6 +1836,28 @@ int LUA_MapLib(lua_State *L)
|
|||
lua_setmetatable(L, -2);
|
||||
lua_setglobal(L, "vertexes");
|
||||
|
||||
#ifdef HAVE_LUA_SEGS
|
||||
lua_newuserdata(L, 0);
|
||||
lua_createtable(L, 0, 2);
|
||||
lua_pushcfunction(L, lib_getSeg);
|
||||
lua_setfield(L, -2, "__index");
|
||||
|
||||
lua_pushcfunction(L, lib_numsegs);
|
||||
lua_setfield(L, -2, "__len");
|
||||
lua_setmetatable(L, -2);
|
||||
lua_setglobal(L, "segs");
|
||||
|
||||
lua_newuserdata(L, 0);
|
||||
lua_createtable(L, 0, 2);
|
||||
lua_pushcfunction(L, lib_getNode);
|
||||
lua_setfield(L, -2, "__index");
|
||||
|
||||
lua_pushcfunction(L, lib_numnodes);
|
||||
lua_setfield(L, -2, "__len");
|
||||
lua_setmetatable(L, -2);
|
||||
lua_setglobal(L, "nodes");
|
||||
#endif
|
||||
|
||||
lua_newuserdata(L, 0);
|
||||
lua_createtable(L, 0, 2);
|
||||
lua_pushcfunction(L, lib_getMapheaderinfo);
|
||||
|
|
|
@ -48,6 +48,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_BlockmapLib, // blockmap stuff
|
||||
LUA_HudLib, // HUD stuff
|
||||
NULL
|
||||
};
|
||||
|
@ -395,6 +396,7 @@ void LUA_InvalidateLevel(void)
|
|||
{
|
||||
thinker_t *th;
|
||||
size_t i;
|
||||
ffloor_t *rover = NULL;
|
||||
if (!gL)
|
||||
return;
|
||||
|
||||
|
@ -406,7 +408,15 @@ void LUA_InvalidateLevel(void)
|
|||
for (i = 0; i < numsubsectors; i++)
|
||||
LUA_InvalidateUserdata(&subsectors[i]);
|
||||
for (i = 0; i < numsectors; i++)
|
||||
{
|
||||
LUA_InvalidateUserdata(§ors[i]);
|
||||
LUA_InvalidateUserdata(sectors[i].lines);
|
||||
if (sectors[i].ffloors)
|
||||
{
|
||||
for (rover = sectors[i].ffloors; rover; rover = rover->next)
|
||||
LUA_InvalidateUserdata(rover);
|
||||
}
|
||||
}
|
||||
for (i = 0; i < numlines; i++)
|
||||
{
|
||||
LUA_InvalidateUserdata(&lines[i]);
|
||||
|
@ -416,6 +426,16 @@ void LUA_InvalidateLevel(void)
|
|||
LUA_InvalidateUserdata(&sides[i]);
|
||||
for (i = 0; i < numvertexes; i++)
|
||||
LUA_InvalidateUserdata(&vertexes[i]);
|
||||
#ifdef HAVE_LUA_SEGS
|
||||
for (i = 0; i < numsegs; i++)
|
||||
LUA_InvalidateUserdata(&segs[i]);
|
||||
for (i = 0; i < numnodes; i++)
|
||||
{
|
||||
LUA_InvalidateUserdata(&nodes[i]);
|
||||
LUA_InvalidateUserdata(nodes[i].bbox);
|
||||
LUA_InvalidateUserdata(nodes[i].children);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void LUA_InvalidateMapthings(void)
|
||||
|
@ -455,6 +475,11 @@ enum
|
|||
ARCH_SIDE,
|
||||
ARCH_SUBSECTOR,
|
||||
ARCH_SECTOR,
|
||||
#ifdef HAVE_LUA_SEGS
|
||||
ARCH_SEG,
|
||||
ARCH_NODE,
|
||||
#endif
|
||||
ARCH_FFLOOR,
|
||||
ARCH_MAPHEADER,
|
||||
|
||||
ARCH_TEND=0xFF,
|
||||
|
@ -474,6 +499,11 @@ static const struct {
|
|||
{META_SIDE, ARCH_SIDE},
|
||||
{META_SUBSECTOR,ARCH_SUBSECTOR},
|
||||
{META_SECTOR, ARCH_SECTOR},
|
||||
#ifdef HAVE_LUA_SEGS
|
||||
{META_SEG, ARCH_SEG},
|
||||
{META_NODE, ARCH_NODE},
|
||||
#endif
|
||||
{META_FFLOOR, ARCH_FFLOOR},
|
||||
{META_MAPHEADER, ARCH_MAPHEADER},
|
||||
{NULL, ARCH_NULL}
|
||||
};
|
||||
|
@ -664,6 +694,56 @@ static UINT8 ArchiveValue(int TABLESINDEX, int myindex)
|
|||
}
|
||||
break;
|
||||
}
|
||||
#ifdef HAVE_LUA_SEGS
|
||||
case ARCH_SEG:
|
||||
{
|
||||
seg_t *seg = *((seg_t **)lua_touserdata(gL, myindex));
|
||||
if (!seg)
|
||||
WRITEUINT8(save_p, ARCH_NULL);
|
||||
else {
|
||||
WRITEUINT8(save_p, ARCH_SEG);
|
||||
WRITEUINT16(save_p, seg - segs);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ARCH_NODE:
|
||||
{
|
||||
node_t *node = *((node_t **)lua_touserdata(gL, myindex));
|
||||
if (!node)
|
||||
WRITEUINT8(save_p, ARCH_NULL);
|
||||
else {
|
||||
WRITEUINT8(save_p, ARCH_NODE);
|
||||
WRITEUINT16(save_p, node - nodes);
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
case ARCH_FFLOOR:
|
||||
{
|
||||
ffloor_t *rover = *((ffloor_t **)lua_touserdata(gL, myindex));
|
||||
if (!rover)
|
||||
WRITEUINT8(save_p, ARCH_NULL);
|
||||
else {
|
||||
ffloor_t *r2;
|
||||
UINT16 i = 0;
|
||||
// search for id
|
||||
for (r2 = rover->target->ffloors; r2; r2 = r2->next)
|
||||
{
|
||||
if (r2 == rover)
|
||||
break;
|
||||
i++;
|
||||
}
|
||||
if (!r2)
|
||||
WRITEUINT8(save_p, ARCH_NULL);
|
||||
else
|
||||
{
|
||||
WRITEUINT8(save_p, ARCH_FFLOOR);
|
||||
WRITEUINT16(save_p, rover->target - sectors);
|
||||
WRITEUINT16(save_p, i);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ARCH_MAPHEADER:
|
||||
{
|
||||
mapheader_t *header = *((mapheader_t **)lua_touserdata(gL, myindex));
|
||||
|
@ -842,6 +922,23 @@ static UINT8 UnArchiveValue(int TABLESINDEX)
|
|||
case ARCH_SECTOR:
|
||||
LUA_PushUserdata(gL, §ors[READUINT16(save_p)], META_SECTOR);
|
||||
break;
|
||||
#ifdef HAVE_LUA_SEGS
|
||||
case ARCH_SEG:
|
||||
LUA_PushUserdata(gL, &segs[READUINT16(save_p)], META_SEG);
|
||||
break;
|
||||
case ARCH_NODE:
|
||||
LUA_PushUserdata(gL, &nodes[READUINT16(save_p)], META_NODE);
|
||||
break;
|
||||
#endif
|
||||
case ARCH_FFLOOR:
|
||||
{
|
||||
sector_t *sector = §ors[READUINT16(save_p)];
|
||||
UINT16 id = READUINT16(save_p);
|
||||
ffloor_t *rover = P_GetFFloorByID(sector, id);
|
||||
if (rover)
|
||||
LUA_PushUserdata(gL, rover, META_FFLOOR);
|
||||
break;
|
||||
}
|
||||
case ARCH_MAPHEADER:
|
||||
LUA_PushUserdata(gL, §ors[READUINT16(save_p)], META_MAPHEADER);
|
||||
break;
|
||||
|
|
|
@ -92,4 +92,7 @@ void COM_Lua_f(void);
|
|||
}\
|
||||
}
|
||||
|
||||
// uncomment if you want seg_t/node_t in Lua
|
||||
// #define HAVE_LUA_SEGS
|
||||
|
||||
#endif
|
||||
|
|
27
src/p_spec.c
27
src/p_spec.c
|
@ -4752,6 +4752,13 @@ void P_UpdateSpecials(void)
|
|||
}
|
||||
}
|
||||
|
||||
/** Gets a 3Dfloor by control sector.
|
||||
*
|
||||
* \param sec Target sector.
|
||||
* \param sec2 Control sector.
|
||||
* \return Pointer to found 3Dfloor, or NULL.
|
||||
* \sa P_GetFFloorByID
|
||||
*/
|
||||
static inline ffloor_t *P_GetFFloorBySec(sector_t *sec, sector_t *sec2)
|
||||
{
|
||||
ffloor_t *rover;
|
||||
|
@ -4764,6 +4771,26 @@ static inline ffloor_t *P_GetFFloorBySec(sector_t *sec, sector_t *sec2)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/** Gets a 3Dfloor by ID number.
|
||||
*
|
||||
* \param sec Target sector.
|
||||
* \param id ID of 3Dfloor in target sector. Note that the first FOF's ID is 0.
|
||||
* \return Pointer to found 3Dfloor, or NULL.
|
||||
* \sa P_GetFFloorBySec
|
||||
*/
|
||||
ffloor_t *P_GetFFloorByID(sector_t *sec, UINT16 id)
|
||||
{
|
||||
ffloor_t *rover;
|
||||
UINT16 i = 0;
|
||||
|
||||
if (!sec->ffloors)
|
||||
return NULL;
|
||||
for (rover = sec->ffloors; rover; rover = rover->next)
|
||||
if (i++ == id)
|
||||
return rover;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/** Adds a newly formed 3Dfloor structure to a sector's ffloors list.
|
||||
*
|
||||
* \param sec Target sector.
|
||||
|
|
|
@ -64,6 +64,8 @@ boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller
|
|||
void P_LinedefExecute(INT16 tag, mobj_t *actor, sector_t *caller);
|
||||
void P_ChangeSectorTag(UINT32 sector, INT16 newtag);
|
||||
|
||||
ffloor_t *P_GetFFloorByID(sector_t *sec, UINT16 id);
|
||||
|
||||
//
|
||||
// P_LIGHTS
|
||||
//
|
||||
|
|
|
@ -295,6 +295,7 @@
|
|||
</ClCompile>
|
||||
<ClCompile Include="..\i_tcp.c" />
|
||||
<ClCompile Include="..\lua_baselib.c" />
|
||||
<ClCompile Include="..\lua_blockmaplib.c" />
|
||||
<ClCompile Include="..\lua_consolelib.c" />
|
||||
<ClCompile Include="..\lua_hooklib.c" />
|
||||
<ClCompile Include="..\lua_hudlib.c" />
|
||||
|
|
|
@ -633,6 +633,9 @@
|
|||
<ClCompile Include="..\lua_baselib.c">
|
||||
<Filter>LUA</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lua_blockmaplib.c">
|
||||
<Filter>LUA</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lua_consolelib.c">
|
||||
<Filter>LUA</Filter>
|
||||
</ClCompile>
|
||||
|
|
|
@ -131,6 +131,7 @@
|
|||
</ClCompile>
|
||||
<ClCompile Include="..\i_tcp.c" />
|
||||
<ClCompile Include="..\lua_baselib.c" />
|
||||
<ClCompile Include="..\lua_blockmaplib.c" />
|
||||
<ClCompile Include="..\lua_consolelib.c" />
|
||||
<ClCompile Include="..\lua_hooklib.c" />
|
||||
<ClCompile Include="..\lua_hudlib.c" />
|
||||
|
|
|
@ -225,6 +225,9 @@
|
|||
<ClCompile Include="..\lua_baselib.c">
|
||||
<Filter>LUA</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lua_blockmaplib.c">
|
||||
<Filter>LUA</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lua_consolelib.c">
|
||||
<Filter>LUA</Filter>
|
||||
</ClCompile>
|
||||
|
|
Loading…
Reference in a new issue