Replace LinedefExecute hook

- It is now called the "SpecialExecute" hook, since it can be called from ACS in addition to linedef specials.
- The input arguments are completely different now. Instead of (line_t, mobj_t, sector_t), it's (activator_t, args array, stringargs array). activator_t is userdata containing valid, mo (mobj_t), line (line_t), side (side_t), sector (sector_t), and po (polyobject_t).
This commit is contained in:
Sally Coolatta 2022-12-27 09:24:59 -05:00
parent 16a7f1dd63
commit 3135d14387
6 changed files with 95 additions and 17 deletions

View file

@ -220,6 +220,8 @@ static const struct {
{META_ACTION, "action"},
{META_LUABANKS, "luabanks[]"},
{META_ACTIVATOR, "activator_t"},
{NULL, NULL}
};

View file

@ -74,7 +74,7 @@ automatically.
X (VoteThinker),/* Y_VoteTicker */\
#define STRING_HOOK_LIST(X) \
X (LinedefExecute),\
X (SpecialExecute),\
X (ShouldJingleContinue),/* should jingle of the given music continue playing */\
#define HUD_HOOK_LIST(X) \
@ -131,7 +131,7 @@ int LUA_HookShouldDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT
int LUA_HookMobjDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage, UINT8 damagetype);
int LUA_HookMobjDeath(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damagetype);
int LUA_HookMobjMoveBlocked(mobj_t *, mobj_t *, line_t *);
void LUA_HookLinedefExecute(line_t *, mobj_t *, sector_t *);
void LUA_HookSpecialExecute(activator_t *activator, INT32 *args, char **stringargs);
int LUA_HookPlayerMsg(int source, int target, int flags, char *msg, int mute);
int LUA_HookHurtMsg(player_t *, mobj_t *inflictor, mobj_t *source, UINT8 damagetype);
int LUA_HookMapThingSpawn(mobj_t *, mapthing_t *);

View file

@ -133,7 +133,7 @@ static void add_string_hook(lua_State *L, int type)
}
break;
case STRING_HOOK(LinedefExecute):
case STRING_HOOK(SpecialExecute):
string = Z_StrDup(luaL_checkstring(L, 3));
strupr(string);
break;
@ -780,16 +780,21 @@ int LUA_HookMobjMoveBlocked(mobj_t *t1, mobj_t *t2, line_t *line)
return hook.status;
}
void LUA_HookLinedefExecute(line_t *line, mobj_t *mo, sector_t *sector)
void LUA_HookSpecialExecute(activator_t *activator, INT32 *args, char **stringargs)
{
Hook_State hook;
if (prepare_string_hook
(&hook, 0, STRING_HOOK(LinedefExecute), line->stringargs[0]))
(&hook, 0, STRING_HOOK(SpecialExecute), stringargs[0]))
{
LUA_PushUserdata(gL, line, META_LINE);
LUA_PushUserdata(gL, mo, META_MOBJ);
LUA_PushUserdata(gL, sector, META_SECTOR);
LUA_PushUserdata(gL, activator, META_ACTIVATOR);
LUA_PushUserdata(gL, args, META_LINEARGS);
LUA_PushUserdata(gL, stringargs, META_LINESTRINGARGS);
#if 0
// but this isn't a mobj hook...?
ps_lua_mobjhooks += call_hooks(&hook, 0, res_none);
#else
call_hooks(&hook, 0, res_none);
#endif
}
}

View file

@ -90,6 +90,8 @@ extern lua_State *gL;
#define META_LUABANKS "LUABANKS[]*"
#define META_ACTIVATOR "ACTIVATOR_T*"
boolean luaL_checkboolean(lua_State *L, int narg);
int LUA_EnumLib(lua_State *L);

View file

@ -369,6 +369,24 @@ static const char *const vector_opt[] = {
"z",
NULL};
enum activator_e {
activator_valid = 0,
activator_mo,
activator_line,
activator_side,
activator_sector,
activator_po
};
static const char *const activator_opt[] = {
"valid",
"mo",
"line",
"side",
"sector",
"po",
NULL};
static const char *const array_opt[] ={"iterate",NULL};
static const char *const valid_opt[] ={"valid",NULL};
@ -2473,6 +2491,59 @@ static int mapheaderinfo_get(lua_State *L)
return 1;
}
/////////////////
// activator_t //
/////////////////
static int activator_get(lua_State *L)
{
activator_t *activator = *((activator_t **)luaL_checkudata(L, 1, META_ACTIVATOR));
enum activator_e field = luaL_checkoption(L, 2, activator_opt[0], activator_opt);
if (activator == NULL)
{
if (field == activator_valid)
{
lua_pushboolean(L, 0);
return 1;
}
return luaL_error(L, "accessed activator_t doesn't exist anymore.");
}
switch (field)
{
case activator_valid:
lua_pushboolean(L, 1);
return 1;
case activator_mo:
LUA_PushUserdata(L, activator->mo, META_MOBJ);
return 1;
case activator_line:
LUA_PushUserdata(L, activator->line, META_LINE);
return 1;
case activator_side:
lua_pushinteger(L, activator->side);
return 1;
case activator_sector:
LUA_PushUserdata(L, activator->sector, META_SECTOR);
return 1;
case activator_po:
LUA_PushUserdata(L, activator->po, META_POLYOBJ);
return 1;
default:
break;
}
return 0;
}
int LUA_MapLib(lua_State *L)
{
luaL_newmetatable(L, META_SECTORLINES);
@ -2619,6 +2690,11 @@ int LUA_MapLib(lua_State *L)
//lua_setfield(L, -2, "__len");
lua_pop(L, 1);
luaL_newmetatable(L, META_ACTIVATOR);
lua_pushcfunction(L, activator_get);
lua_setfield(L, -2, "__index");
lua_pop(L, 1);
LUA_PushTaggableObjectArray(L, "sectors",
lib_iterateSectors,
lib_getSector,

View file

@ -37,7 +37,7 @@
#include "v_video.h" // V_ALLOWLOWERCASE
#include "m_misc.h"
#include "m_cond.h" //unlock triggers
#include "lua_hook.h" // LUA_HookLinedefExecute
#include "lua_hook.h" // LUA_HookSpecialExecute
#include "f_finale.h" // control text prompt
#include "r_skins.h" // skins
@ -3093,16 +3093,9 @@ void P_ProcessSpecial(activator_t *activator, INT16 special, INT32 *args, char *
}
case 443: // Calls a named Lua function
if (line == NULL)
{
break;
}
if (stringargs[0])
{
// TODO: This hook needs overhauled to insert the hook name from the proper stringargs[0],
// and to give activator_t userdata instead of loose arguments.
LUA_HookLinedefExecute(line, mo, callsec);
LUA_HookSpecialExecute(activator, args, stringargs);
}
else
{