diff --git a/src/dehacked.c b/src/dehacked.c index 82ce0a4b4..a975d76e1 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -8131,10 +8131,13 @@ void FUNCMATH DEH_Check(void) static inline int lib_freeslot(lua_State *L) { int n = lua_gettop(L); - int r = 0; // args returned + int r = 0; // args returned char *s, *type,*word; - while (n-- > 0) + if (!lua_lumploading) + return luaL_error(L, "This function cannot be called from within a hook or coroutine!"); + + while (n-- > 0) { s = Z_StrDup(luaL_checkstring(L,1)); type = strtok(s, "_"); diff --git a/src/lua_consolelib.c b/src/lua_consolelib.c index 322fecb64..b688155fb 100644 --- a/src/lua_consolelib.c +++ b/src/lua_consolelib.c @@ -22,8 +22,13 @@ #include "lua_libs.h" #include "lua_hud.h" // hud_running errors +// for functions not allowed in hud.add hooks #define NOHUD if (hud_running)\ return luaL_error(L, "HUD rendering code should not call this function!"); +// for functions not allowed in hooks or coroutines (supercedes above) +#define NOHOOK if (!lua_lumploading)\ + return luaL_error(L, "This function cannot be called from within a hook or coroutine!"); +// for functions only allowed within a level #define INLEVEL if (gamestate != GS_LEVEL)\ return luaL_error(L, "This function can only be used in a level!"); @@ -184,7 +189,7 @@ static int lib_comAddCommand(lua_State *L) strlwr(name); luaL_checktype(L, 2, LUA_TFUNCTION); - NOHUD + NOHOOK if (lua_gettop(L) >= 3) { // For the third argument, only take a boolean or a number. lua_settop(L, 3); @@ -296,7 +301,7 @@ static int lib_cvRegisterVar(lua_State *L) consvar_t *cvar; luaL_checktype(L, 1, LUA_TTABLE); lua_settop(L, 1); // Clear out all other possible arguments, leaving only the first one. - NOHUD + NOHOOK cvar = lua_newuserdata(L, sizeof(consvar_t)); luaL_getmetatable(L, META_CVAR); lua_setmetatable(L, -2); diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c index dadc1861a..b5a076edf 100644 --- a/src/lua_hooklib.c +++ b/src/lua_hooklib.c @@ -108,8 +108,8 @@ static int lib_addHook(lua_State *L) luaL_checktype(L, 1, LUA_TFUNCTION); - if (hud_running) - return luaL_error(L, "HUD rendering code should not call this function!"); + if (!lua_lumploading) + return luaL_error(L, "This function cannot be called from within a hook or coroutine!"); switch(hook.type) { diff --git a/src/lua_hudlib.c b/src/lua_hudlib.c index 5b3cd46ce..29e4970c1 100644 --- a/src/lua_hudlib.c +++ b/src/lua_hudlib.c @@ -612,6 +612,9 @@ static int lib_hudadd(lua_State *L) luaL_checktype(L, 1, LUA_TFUNCTION); field = luaL_checkoption(L, 2, "game", hudhook_opt); + if (!lua_lumploading) + return luaL_error(L, "This function cannot be called from within a hook or coroutine!"); + lua_getfield(L, LUA_REGISTRYINDEX, "HUD"); I_Assert(lua_istable(L, -1)); lua_rawgeti(L, -1, field+2); // HUD[2+] diff --git a/src/lua_script.c b/src/lua_script.c index d30790be1..75efb8620 100644 --- a/src/lua_script.c +++ b/src/lua_script.c @@ -161,6 +161,11 @@ void LUA_ClearExtVars(void) } #endif +// Use this variable to prevent certain functions from running +// if they were not called on lump load +// (i.e. they were called in hooks or coroutines etc) +boolean lua_lumploading = false; + // Load a script from a MYFILE static inline void LUA_LoadFile(MYFILE *f, char *name) { @@ -198,7 +203,9 @@ void LUA_LoadLump(UINT16 wad, UINT16 lump) name[strlen(wadfiles[wad]->filename)+9] = '\0'; } - LUA_LoadFile(&f, name); + lua_lumploading = true; // turn on loading flag + LUA_LoadFile(&f, name); // actually load file! + lua_lumploading = false; // turn off again free(name); Z_Free(f.data); diff --git a/src/lua_script.h b/src/lua_script.h index d143ed879..51f1eaeaa 100644 --- a/src/lua_script.h +++ b/src/lua_script.h @@ -38,6 +38,8 @@ void LUA_ClearExtVars(void); #endif +extern boolean lua_lumploading; // is LUA_LoadLump being called? + void LUA_LoadLump(UINT16 wad, UINT16 lump); #ifdef LUA_ALLOW_BYTECODE void LUA_DumpFile(const char *filename);