mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2024-11-22 04:21:23 +00:00
Backport the Blockmap library I made two years ago
This commit is contained in:
parent
e0a1c43813
commit
11cb163435
10 changed files with 281 additions and 0 deletions
3
SRB2.cbp
3
SRB2.cbp
|
@ -1549,6 +1549,9 @@ HW3SOUND for 3D hardware sound support
|
||||||
<Unit filename="src/lua_baselib.c">
|
<Unit filename="src/lua_baselib.c">
|
||||||
<Option compilerVar="CC" />
|
<Option compilerVar="CC" />
|
||||||
</Unit>
|
</Unit>
|
||||||
|
<Unit filename="src/lua_blockmaplib.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
<Unit filename="src/lua_consolelib.c">
|
<Unit filename="src/lua_consolelib.c">
|
||||||
<Option compilerVar="CC" />
|
<Option compilerVar="CC" />
|
||||||
</Unit>
|
</Unit>
|
||||||
|
|
|
@ -237,6 +237,7 @@ if(${SRB2_CONFIG_HAVE_BLUA})
|
||||||
add_definitions(-DHAVE_BLUA)
|
add_definitions(-DHAVE_BLUA)
|
||||||
set(SRB2_LUA_SOURCES
|
set(SRB2_LUA_SOURCES
|
||||||
lua_baselib.c
|
lua_baselib.c
|
||||||
|
lua_blockmaplib.c
|
||||||
lua_consolelib.c
|
lua_consolelib.c
|
||||||
lua_hooklib.c
|
lua_hooklib.c
|
||||||
lua_hudlib.c
|
lua_hudlib.c
|
||||||
|
|
|
@ -39,6 +39,7 @@ OBJS:=$(OBJS) \
|
||||||
$(OBJDIR)/lvm.o \
|
$(OBJDIR)/lvm.o \
|
||||||
$(OBJDIR)/lua_script.o \
|
$(OBJDIR)/lua_script.o \
|
||||||
$(OBJDIR)/lua_baselib.o \
|
$(OBJDIR)/lua_baselib.o \
|
||||||
|
$(OBJDIR)/lua_blockmaplib.o \
|
||||||
$(OBJDIR)/lua_mathlib.o \
|
$(OBJDIR)/lua_mathlib.o \
|
||||||
$(OBJDIR)/lua_hooklib.o \
|
$(OBJDIR)/lua_hooklib.o \
|
||||||
$(OBJDIR)/lua_consolelib.o \
|
$(OBJDIR)/lua_consolelib.o \
|
||||||
|
|
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
|
|
@ -69,6 +69,7 @@ int LUA_PlayerLib(lua_State *L);
|
||||||
int LUA_SkinLib(lua_State *L);
|
int LUA_SkinLib(lua_State *L);
|
||||||
int LUA_ThinkerLib(lua_State *L);
|
int LUA_ThinkerLib(lua_State *L);
|
||||||
int LUA_MapLib(lua_State *L);
|
int LUA_MapLib(lua_State *L);
|
||||||
|
int LUA_BlockmapLib(lua_State *L);
|
||||||
int LUA_HudLib(lua_State *L);
|
int LUA_HudLib(lua_State *L);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -51,6 +51,7 @@ static lua_CFunction liblist[] = {
|
||||||
LUA_SkinLib, // skin_t, skins[]
|
LUA_SkinLib, // skin_t, skins[]
|
||||||
LUA_ThinkerLib, // thinker_t
|
LUA_ThinkerLib, // thinker_t
|
||||||
LUA_MapLib, // line_t, side_t, sector_t, subsector_t
|
LUA_MapLib, // line_t, side_t, sector_t, subsector_t
|
||||||
|
LUA_BlockmapLib, // blockmap stuff
|
||||||
LUA_HudLib, // HUD stuff
|
LUA_HudLib, // HUD stuff
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
|
@ -297,6 +297,7 @@
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="..\i_tcp.c" />
|
<ClCompile Include="..\i_tcp.c" />
|
||||||
<ClCompile Include="..\lua_baselib.c" />
|
<ClCompile Include="..\lua_baselib.c" />
|
||||||
|
<ClCompile Include="..\lua_blockmaplib.c" />
|
||||||
<ClCompile Include="..\lua_consolelib.c" />
|
<ClCompile Include="..\lua_consolelib.c" />
|
||||||
<ClCompile Include="..\lua_hooklib.c" />
|
<ClCompile Include="..\lua_hooklib.c" />
|
||||||
<ClCompile Include="..\lua_hudlib.c" />
|
<ClCompile Include="..\lua_hudlib.c" />
|
||||||
|
|
|
@ -639,6 +639,9 @@
|
||||||
<ClCompile Include="..\lua_baselib.c">
|
<ClCompile Include="..\lua_baselib.c">
|
||||||
<Filter>LUA</Filter>
|
<Filter>LUA</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\lua_blockmaplib.c">
|
||||||
|
<Filter>LUA</Filter>
|
||||||
|
</ClCompile>
|
||||||
<ClCompile Include="..\lua_consolelib.c">
|
<ClCompile Include="..\lua_consolelib.c">
|
||||||
<Filter>LUA</Filter>
|
<Filter>LUA</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
|
|
@ -132,6 +132,7 @@
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="..\i_tcp.c" />
|
<ClCompile Include="..\i_tcp.c" />
|
||||||
<ClCompile Include="..\lua_baselib.c" />
|
<ClCompile Include="..\lua_baselib.c" />
|
||||||
|
<ClCompile Include="..\lua_blockmaplib.c" />
|
||||||
<ClCompile Include="..\lua_consolelib.c" />
|
<ClCompile Include="..\lua_consolelib.c" />
|
||||||
<ClCompile Include="..\lua_hooklib.c" />
|
<ClCompile Include="..\lua_hooklib.c" />
|
||||||
<ClCompile Include="..\lua_hudlib.c" />
|
<ClCompile Include="..\lua_hudlib.c" />
|
||||||
|
|
|
@ -228,6 +228,9 @@
|
||||||
<ClCompile Include="..\lua_baselib.c">
|
<ClCompile Include="..\lua_baselib.c">
|
||||||
<Filter>LUA</Filter>
|
<Filter>LUA</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\lua_blockmaplib.c">
|
||||||
|
<Filter>LUA</Filter>
|
||||||
|
</ClCompile>
|
||||||
<ClCompile Include="..\lua_consolelib.c">
|
<ClCompile Include="..\lua_consolelib.c">
|
||||||
<Filter>LUA</Filter>
|
<Filter>LUA</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
|
Loading…
Reference in a new issue