From 9d940ed654982e95c1abc7b25bd072dba682dbbf Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Wed, 16 Aug 2023 21:54:55 -0400 Subject: [PATCH] Separate script args from mapthing args SRB2 uses a LOT of mapthing args compared to Hexen (which has none) and ZDoom (which only has them on objects that will never ever activate scripts). So we really badly needed to separate the two if we want attaching scripts to things to be useful. --- src/acs/call-funcs.cpp | 2 +- src/acs/environment.cpp | 10 ++-- src/doomdata.h | 17 ++++-- src/lua_maplib.c | 26 ++++----- src/lua_mobjlib.c | 12 ++-- src/m_cheat.c | 7 ++- src/p_enemy.c | 2 +- src/p_mobj.c | 37 +++++++++++- src/p_mobj.h | 7 ++- src/p_saveg.c | 124 +++++++++++++++++++++++++++++++++------- src/p_setup.c | 75 ++++++++++++++++-------- src/p_spec.c | 16 +++--- src/r_defs.h | 16 ++---- 13 files changed, 250 insertions(+), 101 deletions(-) diff --git a/src/acs/call-funcs.cpp b/src/acs/call-funcs.cpp index 747d74144..1939c1d2d 100644 --- a/src/acs/call-funcs.cpp +++ b/src/acs/call-funcs.cpp @@ -1063,7 +1063,7 @@ bool CallFunc_SetLineSpecial(ACSVM::Thread *thread, const ACSVM::Word *argV, ACS tag = argV[0]; spec = argV[1]; - numArgs = std::min(std::max((signed)(argC - 2), 0), NUMLINEARGS); + numArgs = std::min(std::max((signed)(argC - 2), 0), NUM_SCRIPT_ARGS); TAG_ITER_LINES(tag, lineId) { diff --git a/src/acs/environment.cpp b/src/acs/environment.cpp index 78ffa2256..c886f3651 100644 --- a/src/acs/environment.cpp +++ b/src/acs/environment.cpp @@ -298,13 +298,13 @@ ACSVM::Word Environment::callSpecImpl auto info = &static_cast(thread)->info; ACSVM::MapScope *const map = thread->scopeMap; - INT32 args[NUMLINEARGS] = {0}; + INT32 args[NUM_SCRIPT_ARGS] = {0}; - char *stringargs[NUMLINESTRINGARGS] = {0}; + char *stringargs[NUM_SCRIPT_STRINGARGS] = {0}; auto _ = srb2::finally( [stringargs]() { - for (int i = 0; i < NUMLINESTRINGARGS; i++) + for (int i = 0; i < NUM_SCRIPT_STRINGARGS; i++) { Z_Free(stringargs[i]); } @@ -322,7 +322,7 @@ ACSVM::Word Environment::callSpecImpl int i = 0; - for (i = 0; i < std::min((signed)(argC), NUMLINESTRINGARGS); i++) + for (i = 0; i < std::min((signed)(argC), NUM_SCRIPT_STRINGARGS); i++) { ACSVM::String *strPtr = map->getString(argV[i]); @@ -330,7 +330,7 @@ ACSVM::Word Environment::callSpecImpl M_Memcpy(stringargs[i], strPtr->str, strPtr->len + 1); } - for (i = 0; i < std::min((signed)(argC), NUMLINEARGS); i++) + for (i = 0; i < std::min((signed)(argC), NUM_SCRIPT_ARGS); i++) { args[i] = argV[i]; } diff --git a/src/doomdata.h b/src/doomdata.h index cfed6fbcd..375635b52 100644 --- a/src/doomdata.h +++ b/src/doomdata.h @@ -36,6 +36,11 @@ extern "C" { // used in the lumps of the WAD files. // +// Number of args for ACS scripts. +// Increasing this requires you to also update the ACS compiler. +#define NUM_SCRIPT_ARGS 10 +#define NUM_SCRIPT_STRINGARGS 2 + // Lump order in a map WAD: each map needs a couple of lumps // to provide a complete scene geometry description. enum @@ -248,8 +253,10 @@ struct mapUserProperties_t size_t capacity; }; -#define NUMMAPTHINGARGS 10 -#define NUMMAPTHINGSTRINGARGS 2 +// Number of args for thing behaviors. +// These are safe to increase at any time. +#define NUM_MAPTHING_ARGS 10 +#define NUM_MAPTHING_STRINGARGS 2 // Thing definition, position, orientation and type, // plus visibility flags and attributes. @@ -264,8 +271,10 @@ struct mapthing_t mtag_t tid; fixed_t scale; INT16 special; - INT32 args[NUMMAPTHINGARGS]; - char *stringargs[NUMMAPTHINGSTRINGARGS]; + INT32 args[NUM_MAPTHING_ARGS]; + char *stringargs[NUM_MAPTHING_STRINGARGS]; + INT32 script_args[NUM_SCRIPT_ARGS]; + char *script_stringargs[NUM_SCRIPT_STRINGARGS]; UINT8 layer; // FOF layer to spawn on, see P_GetMobjSpawnHeight mapUserProperties_t user; // UDMF user-defined custom properties. mobj_t *mobj; diff --git a/src/lua_maplib.c b/src/lua_maplib.c index b7926fcca..ef9043ca0 100644 --- a/src/lua_maplib.c +++ b/src/lua_maplib.c @@ -601,16 +601,16 @@ static int sectorargs_get(lua_State *L) { INT32 *args = *((INT32**)luaL_checkudata(L, 1, META_SECTORARGS)); int i = luaL_checkinteger(L, 2); - if (i < 0 || i >= NUMSECTORARGS) + if (i < 0 || i >= NUM_SCRIPT_ARGS) return luaL_error(L, LUA_QL("sector_t.args") " index cannot be %d", i); lua_pushinteger(L, args[i]); return 1; } -// #args -> NUMSECTORARGS +// #args -> NUM_SCRIPT_ARGS static int sectorargs_len(lua_State* L) { - lua_pushinteger(L, NUMSECTORARGS); + lua_pushinteger(L, NUM_SCRIPT_ARGS); return 1; } @@ -619,16 +619,16 @@ static int sectorstringargs_get(lua_State *L) { char **stringargs = *((char***)luaL_checkudata(L, 1, META_SECTORSTRINGARGS)); int i = luaL_checkinteger(L, 2); - if (i < 0 || i >= NUMSECTORSTRINGARGS) - return luaL_error(L, LUA_QL("line_t.stringargs") " index cannot be %d", i); + if (i < 0 || i >= NUM_SCRIPT_STRINGARGS) + return luaL_error(L, LUA_QL("sector_t.stringargs") " index cannot be %d", i); lua_pushstring(L, stringargs[i]); return 1; } -// #stringargs -> NUMLINESTRINGARGS +// #stringargs -> NUM_SCRIPT_STRINGARGS static int sectorstringargs_len(lua_State *L) { - lua_pushinteger(L, NUMSECTORSTRINGARGS); + lua_pushinteger(L, NUM_SCRIPT_STRINGARGS); return 1; } @@ -944,16 +944,16 @@ static int lineargs_get(lua_State *L) { INT32 *args = *((INT32**)luaL_checkudata(L, 1, META_LINEARGS)); int i = luaL_checkinteger(L, 2); - if (i < 0 || i >= NUMLINEARGS) + if (i < 0 || i >= NUM_SCRIPT_ARGS) return luaL_error(L, LUA_QL("line_t.args") " index cannot be %d", i); lua_pushinteger(L, args[i]); return 1; } -// #args -> NUMLINEARGS +// #args -> NUM_SCRIPT_ARGS static int lineargs_len(lua_State* L) { - lua_pushinteger(L, NUMLINEARGS); + lua_pushinteger(L, NUM_SCRIPT_ARGS); return 1; } @@ -962,16 +962,16 @@ static int linestringargs_get(lua_State *L) { char **stringargs = *((char***)luaL_checkudata(L, 1, META_LINESTRINGARGS)); int i = luaL_checkinteger(L, 2); - if (i < 0 || i >= NUMLINESTRINGARGS) + if (i < 0 || i >= NUM_SCRIPT_STRINGARGS) return luaL_error(L, LUA_QL("line_t.stringargs") " index cannot be %d", i); lua_pushstring(L, stringargs[i]); return 1; } -// #stringargs -> NUMLINESTRINGARGS +// #stringargs -> NUM_SCRIPT_STRINGARGS static int linestringargs_len(lua_State *L) { - lua_pushinteger(L, NUMLINESTRINGARGS); + lua_pushinteger(L, NUM_SCRIPT_STRINGARGS); return 1; } diff --git a/src/lua_mobjlib.c b/src/lua_mobjlib.c index efcc62687..bc35e0b3a 100644 --- a/src/lua_mobjlib.c +++ b/src/lua_mobjlib.c @@ -916,16 +916,16 @@ static int thingargs_get(lua_State *L) { INT32 *args = *((INT32**)luaL_checkudata(L, 1, META_THINGARGS)); int i = luaL_checkinteger(L, 2); - if (i < 0 || i >= NUMMAPTHINGARGS) + if (i < 0 || i >= NUM_MAPTHING_ARGS) return luaL_error(L, LUA_QL("mapthing_t.args") " index cannot be %d", i); lua_pushinteger(L, args[i]); return 1; } -// #args -> NUMMAPTHINGARGS +// #args -> NUM_MAPTHING_ARGS static int thingargs_len(lua_State* L) { - lua_pushinteger(L, NUMMAPTHINGARGS); + lua_pushinteger(L, NUM_MAPTHING_ARGS); return 1; } @@ -934,16 +934,16 @@ static int thingstringargs_get(lua_State *L) { char **stringargs = *((char***)luaL_checkudata(L, 1, META_THINGSTRINGARGS)); int i = luaL_checkinteger(L, 2); - if (i < 0 || i >= NUMMAPTHINGSTRINGARGS) + if (i < 0 || i >= NUM_MAPTHING_STRINGARGS) return luaL_error(L, LUA_QL("mapthing_t.stringargs") " index cannot be %d", i); lua_pushstring(L, stringargs[i]); return 1; } -// #stringargs -> NUMMAPTHINGSTRINGARGS +// #stringargs -> NUM_MAPTHING_STRINGARGS static int thingstringargs_len(lua_State *L) { - lua_pushinteger(L, NUMMAPTHINGSTRINGARGS); + lua_pushinteger(L, NUM_MAPTHING_STRINGARGS); return 1; } diff --git a/src/m_cheat.c b/src/m_cheat.c index ecfb9a79c..d555e9b1d 100644 --- a/src/m_cheat.c +++ b/src/m_cheat.c @@ -792,8 +792,11 @@ static mapthing_t *OP_CreateNewMapThing(player_t *player, UINT16 type, boolean c mt->options = (mt->z << ZSHIFT) | (UINT16)cv_opflags.value; mt->scale = player->mo->scale; - memset(mt->args, 0, NUMMAPTHINGARGS*sizeof(*mt->args)); - memset(mt->stringargs, 0x00, NUMMAPTHINGSTRINGARGS*sizeof(*mt->stringargs)); + memset(mt->args, 0, NUM_MAPTHING_ARGS*sizeof(*mt->args)); + memset(mt->stringargs, 0x00, NUM_MAPTHING_STRINGARGS*sizeof(*mt->stringargs)); + mt->special = 0; + memset(mt->script_args, 0, NUM_SCRIPT_ARGS*sizeof(*mt->script_args)); + memset(mt->script_stringargs, 0x00, NUM_SCRIPT_STRINGARGS*sizeof(*mt->script_stringargs)); mt->pitch = mt->roll = 0; return mt; } diff --git a/src/p_enemy.c b/src/p_enemy.c index 5e82b57dd..1eec607d0 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -6902,7 +6902,7 @@ void A_LinedefExecuteFromArg(mobj_t *actor) if (LUA_CallAction(A_LINEDEFEXECUTEFROMARG, actor)) return; - if (locvar1 < 0 || locvar1 > NUMMAPTHINGARGS) + if (locvar1 < 0 || locvar1 > NUM_MAPTHING_ARGS) { CONS_Debug(DBG_GAMELOGIC, "A_LinedefExecuteFromArg: Invalid mapthing arg %d\n", locvar1); return; diff --git a/src/p_mobj.c b/src/p_mobj.c index 2402a2ed5..743482bc3 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -13633,12 +13633,12 @@ static mobj_t *P_SpawnMobjFromMapThing(mapthing_t *mthing, fixed_t x, fixed_t y, mobj->special = mthing->special; - for (arg = 0; arg < NUMMAPTHINGARGS; arg++) + for (arg = 0; arg < NUM_MAPTHING_ARGS; arg++) { mobj->args[arg] = mthing->args[arg]; } - for (arg = 0; arg < NUMMAPTHINGSTRINGARGS; arg++) + for (arg = 0; arg < NUM_MAPTHING_STRINGARGS; arg++) { size_t len = 0; @@ -13658,6 +13658,31 @@ static mobj_t *P_SpawnMobjFromMapThing(mapthing_t *mthing, fixed_t x, fixed_t y, M_Memcpy(mobj->stringargs[arg], mthing->stringargs[arg], len + 1); } + for (arg = 0; arg < NUM_SCRIPT_ARGS; arg++) + { + mobj->script_args[arg] = mthing->args[arg]; + } + + for (arg = 0; arg < NUM_SCRIPT_STRINGARGS; arg++) + { + size_t len = 0; + + if (mthing->script_stringargs[arg]) + { + len = strlen(mthing->script_stringargs[arg]); + } + + if (len == 0) + { + Z_Free(mobj->script_stringargs[arg]); + mobj->script_stringargs[arg] = NULL; + continue; + } + + mobj->script_stringargs[arg] = Z_Realloc(mobj->script_stringargs[arg], len + 1, PU_LEVEL, NULL); + M_Memcpy(mobj->script_stringargs[arg], mthing->script_stringargs[arg], len + 1); + } + if (!P_SetupSpawnedMapThing(mthing, mobj)) { if (P_MobjWasRemoved(mobj)) @@ -14709,9 +14734,15 @@ void P_DeleteMobjStringArgs(mobj_t *mobj) { size_t i = SIZE_MAX; - for (i = 0; i < NUMMAPTHINGSTRINGARGS; i++) + for (i = 0; i < NUM_MAPTHING_STRINGARGS; i++) { Z_Free(mobj->stringargs[i]); mobj->stringargs[i] = NULL; } + + for (i = 0; i < NUM_SCRIPT_STRINGARGS; i++) + { + Z_Free(mobj->script_stringargs[i]); + mobj->script_stringargs[i] = NULL; + } } diff --git a/src/p_mobj.h b/src/p_mobj.h index a531c456d..b1ac0004c 100644 --- a/src/p_mobj.h +++ b/src/p_mobj.h @@ -426,9 +426,12 @@ struct mobj_t INT32 dispoffset; + INT32 args[NUM_MAPTHING_ARGS]; + char *stringargs[NUM_MAPTHING_STRINGARGS]; + INT16 special; - INT32 args[NUMMAPTHINGARGS]; - char *stringargs[NUMMAPTHINGSTRINGARGS]; + INT32 script_args[NUM_SCRIPT_ARGS]; + char *script_stringargs[NUM_SCRIPT_STRINGARGS]; // WARNING: New fields must be added separately to savegame and Lua. }; diff --git a/src/p_saveg.c b/src/p_saveg.c index f948c7fa0..630888763 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -1547,7 +1547,7 @@ static void P_NetUnArchiveColormaps(savebuffer_t *save) static boolean P_SectorArgsEqual(const sector_t *sc, const sector_t *spawnsc) { UINT8 i; - for (i = 0; i < NUMSECTORARGS; i++) + for (i = 0; i < NUM_SCRIPT_ARGS; i++) if (sc->args[i] != spawnsc->args[i]) return false; @@ -1557,7 +1557,7 @@ static boolean P_SectorArgsEqual(const sector_t *sc, const sector_t *spawnsc) static boolean P_SectorStringArgsEqual(const sector_t *sc, const sector_t *spawnsc) { UINT8 i; - for (i = 0; i < NUMSECTORSTRINGARGS; i++) + for (i = 0; i < NUM_SCRIPT_STRINGARGS; i++) { if (!sc->stringargs[i]) return !spawnsc->stringargs[i]; @@ -1594,7 +1594,7 @@ static boolean P_SectorStringArgsEqual(const sector_t *sc, const sector_t *spawn static boolean P_LineArgsEqual(const line_t *li, const line_t *spawnli) { UINT8 i; - for (i = 0; i < NUMLINEARGS; i++) + for (i = 0; i < NUM_SCRIPT_ARGS; i++) if (li->args[i] != spawnli->args[i]) return false; @@ -1604,7 +1604,7 @@ static boolean P_LineArgsEqual(const line_t *li, const line_t *spawnli) static boolean P_LineStringArgsEqual(const line_t *li, const line_t *spawnli) { UINT8 i; - for (i = 0; i < NUMLINESTRINGARGS; i++) + for (i = 0; i < NUM_SCRIPT_STRINGARGS; i++) { if (!li->stringargs[i]) return !spawnli->stringargs[i]; @@ -1867,12 +1867,12 @@ static void ArchiveSectors(savebuffer_t *save) WRITEINT16(save->p, ss->action); if (diff4 & SD_ARGS) { - for (j = 0; j < NUMSECTORARGS; j++) + for (j = 0; j < NUM_SCRIPT_ARGS; j++) WRITEINT32(save->p, ss->args[j]); } if (diff4 & SD_STRINGARGS) { - for (j = 0; j < NUMSECTORSTRINGARGS; j++) + for (j = 0; j < NUM_SCRIPT_STRINGARGS; j++) { size_t len, k; @@ -2021,12 +2021,12 @@ static void UnArchiveSectors(savebuffer_t *save) sectors[i].action = READINT16(save->p); if (diff4 & SD_ARGS) { - for (j = 0; j < NUMSECTORARGS; j++) + for (j = 0; j < NUM_SCRIPT_ARGS; j++) sectors[i].args[j] = READINT32(save->p); } if (diff4 & SD_STRINGARGS) { - for (j = 0; j < NUMLINESTRINGARGS; j++) + for (j = 0; j < NUM_SCRIPT_STRINGARGS; j++) { size_t len = READINT32(save->p); size_t k; @@ -2157,13 +2157,13 @@ static void ArchiveLines(savebuffer_t *save) if (diff2 & LD_ARGS) { UINT8 j; - for (j = 0; j < NUMLINEARGS; j++) + for (j = 0; j < NUM_SCRIPT_ARGS; j++) WRITEINT32(save->p, li->args[j]); } if (diff2 & LD_STRINGARGS) { UINT8 j; - for (j = 0; j < NUMLINESTRINGARGS; j++) + for (j = 0; j < NUM_SCRIPT_STRINGARGS; j++) { size_t len, k; @@ -2246,13 +2246,13 @@ static void UnArchiveLines(savebuffer_t *save) if (diff2 & LD_ARGS) { UINT8 j; - for (j = 0; j < NUMLINEARGS; j++) + for (j = 0; j < NUM_SCRIPT_ARGS; j++) li->args[j] = READINT32(save->p); } if (diff2 & LD_STRINGARGS) { UINT8 j; - for (j = 0; j < NUMLINESTRINGARGS; j++) + for (j = 0; j < NUM_SCRIPT_STRINGARGS; j++) { size_t len = READINT32(save->p); size_t k; @@ -2318,7 +2318,7 @@ static void P_NetUnArchiveWorld(savebuffer_t *save) static boolean P_ThingArgsEqual(const mobj_t *mobj, const mapthing_t *mapthing) { UINT8 i; - for (i = 0; i < NUMMAPTHINGARGS; i++) + for (i = 0; i < NUM_MAPTHING_ARGS; i++) if (mobj->args[i] != mapthing->args[i]) return false; @@ -2328,7 +2328,7 @@ static boolean P_ThingArgsEqual(const mobj_t *mobj, const mapthing_t *mapthing) static boolean P_ThingStringArgsEqual(const mobj_t *mobj, const mapthing_t *mapthing) { UINT8 i; - for (i = 0; i < NUMMAPTHINGSTRINGARGS; i++) + for (i = 0; i < NUM_MAPTHING_STRINGARGS; i++) { if (!mobj->stringargs[i]) return !mapthing->stringargs[i]; @@ -2340,6 +2340,28 @@ static boolean P_ThingStringArgsEqual(const mobj_t *mobj, const mapthing_t *mapt return true; } +static boolean P_ThingScriptEqual(const mobj_t *mobj, const mapthing_t *mapthing) +{ + UINT8 i; + if (mobj->special != mapthing->special) + return false; + + for (i = 0; i < NUM_SCRIPT_ARGS; i++) + if (mobj->script_args[i] != mapthing->script_args[i]) + return false; + + for (i = 0; i < NUM_SCRIPT_STRINGARGS; i++) + { + if (!mobj->script_stringargs[i]) + return !mapthing->script_stringargs[i]; + + if (strcmp(mobj->script_stringargs[i], mapthing->script_stringargs[i])) + return false; + } + + return true; +} + typedef enum { MD_SPAWNPOINT = 1, @@ -2546,7 +2568,7 @@ static void SaveMobjThinker(savebuffer_t *save, const thinker_t *th, const UINT8 if (!P_ThingStringArgsEqual(mobj, mobj->spawnpoint)) diff |= MD_STRINGARGS; - if (mobj->special != mobj->spawnpoint->type) + if (!P_ThingScriptEqual(mobj, mobj->spawnpoint)) diff2 |= MD2_SPECIAL; } else @@ -2554,7 +2576,7 @@ static void SaveMobjThinker(savebuffer_t *save, const thinker_t *th, const UINT8 // not a map spawned thing, so make it from scratch diff = MD_POS | MD_TYPE; - for (j = 0; j < NUMMAPTHINGARGS; j++) + for (j = 0; j < NUM_MAPTHING_ARGS; j++) { if (mobj->args[j] != 0) { @@ -2563,7 +2585,7 @@ static void SaveMobjThinker(savebuffer_t *save, const thinker_t *th, const UINT8 } } - for (j = 0; j < NUMMAPTHINGSTRINGARGS; j++) + for (j = 0; j < NUM_MAPTHING_STRINGARGS; j++) { if (mobj->stringargs[j] != NULL) { @@ -2576,6 +2598,24 @@ static void SaveMobjThinker(savebuffer_t *save, const thinker_t *th, const UINT8 { diff2 |= MD2_SPECIAL; } + + for (j = 0; j < NUM_SCRIPT_ARGS; j++) + { + if (mobj->script_args[j] != 0) + { + diff2 |= MD2_SPECIAL; + break; + } + } + + for (j = 0; j < NUM_SCRIPT_STRINGARGS; j++) + { + if (mobj->stringargs[j] != NULL) + { + diff2 |= MD2_SPECIAL; + break; + } + } } // not the default but the most probable @@ -2826,12 +2866,12 @@ static void SaveMobjThinker(savebuffer_t *save, const thinker_t *th, const UINT8 WRITEFIXED(save->p, mobj->scalespeed); if (diff & MD_ARGS) { - for (j = 0; j < NUMMAPTHINGARGS; j++) + for (j = 0; j < NUM_MAPTHING_ARGS; j++) WRITEINT32(save->p, mobj->args[j]); } if (diff & MD_STRINGARGS) { - for (j = 0; j < NUMMAPTHINGSTRINGARGS; j++) + for (j = 0; j < NUM_MAPTHING_STRINGARGS; j++) { size_t len, k; @@ -2911,7 +2951,28 @@ static void SaveMobjThinker(savebuffer_t *save, const thinker_t *th, const UINT8 WRITEFIXED(save->p, mobj->sprzoff); } if (diff2 & MD2_SPECIAL) + { WRITEINT16(save->p, mobj->special); + + for (j = 0; j < NUM_SCRIPT_ARGS; j++) + WRITEINT32(save->p, mobj->script_args[j]); + + for (j = 0; j < NUM_SCRIPT_STRINGARGS; j++) + { + size_t len, k; + + if (!mobj->script_stringargs[j]) + { + WRITEINT32(save->p, 0); + continue; + } + + len = strlen(mobj->script_stringargs[j]); + WRITEINT32(save->p, len); + for (k = 0; k < len; k++) + WRITECHAR(save->p, mobj->script_stringargs[j][k]); + } + } if (diff2 & MD2_FLOORSPRITESLOPE) { pslope_t *slope = mobj->floorspriteslope; @@ -4029,12 +4090,12 @@ static thinker_t* LoadMobjThinker(savebuffer_t *save, actionf_p1 thinker) mobj->scalespeed = mapobjectscale/12; if (diff & MD_ARGS) { - for (j = 0; j < NUMMAPTHINGARGS; j++) + for (j = 0; j < NUM_MAPTHING_ARGS; j++) mobj->args[j] = READINT32(save->p); } if (diff & MD_STRINGARGS) { - for (j = 0; j < NUMMAPTHINGSTRINGARGS; j++) + for (j = 0; j < NUM_MAPTHING_STRINGARGS; j++) { size_t len = READINT32(save->p); size_t k; @@ -4121,6 +4182,27 @@ static thinker_t* LoadMobjThinker(savebuffer_t *save, actionf_p1 thinker) if (diff2 & MD2_SPECIAL) { mobj->special = READINT16(save->p); + + for (j = 0; j < NUM_SCRIPT_ARGS; j++) + mobj->script_args[j] = READINT32(save->p); + + for (j = 0; j < NUM_SCRIPT_STRINGARGS; j++) + { + size_t len = READINT32(save->p); + size_t k; + + if (!len) + { + Z_Free(mobj->script_stringargs[j]); + mobj->script_stringargs[j] = NULL; + continue; + } + + mobj->script_stringargs[j] = Z_Realloc(mobj->script_stringargs[j], len + 1, PU_LEVEL, NULL); + for (k = 0; k < len; k++) + mobj->script_stringargs[j][k] = READCHAR(save->p); + mobj->script_stringargs[j][len] = '\0'; + } } if (diff2 & MD2_FLOORSPRITESLOPE) { diff --git a/src/p_setup.c b/src/p_setup.c index 48caf293a..f734b5cc9 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -967,8 +967,8 @@ static void P_LoadSectors(UINT8 *data) ss->friction = ORIG_FRICTION; ss->action = 0; - memset(ss->args, 0, NUMLINEARGS*sizeof(*ss->args)); - memset(ss->stringargs, 0x00, NUMLINESTRINGARGS*sizeof(*ss->stringargs)); + memset(ss->args, 0, NUM_SCRIPT_ARGS*sizeof(*ss->args)); + memset(ss->stringargs, 0x00, NUM_SCRIPT_STRINGARGS*sizeof(*ss->stringargs)); ss->activation = 0; P_InitializeSector(ss); @@ -1076,8 +1076,8 @@ static void P_LoadLinedefs(UINT8 *data) ld->flags = (UINT32)(SHORT(mld->flags)); ld->special = SHORT(mld->special); Tag_FSet(&ld->tags, SHORT(mld->tag)); - memset(ld->args, 0, NUMLINEARGS*sizeof(*ld->args)); - memset(ld->stringargs, 0x00, NUMLINESTRINGARGS*sizeof(*ld->stringargs)); + memset(ld->args, 0, NUM_SCRIPT_ARGS*sizeof(*ld->args)); + memset(ld->stringargs, 0x00, NUM_SCRIPT_STRINGARGS*sizeof(*ld->stringargs)); ld->alpha = FRACUNIT; ld->executordelay = 0; ld->activation = 0; @@ -1360,9 +1360,11 @@ static void P_LoadThings(UINT8 *data) mt->extrainfo = (UINT8)(mt->type >> 12); mt->tid = 0; mt->scale = FRACUNIT; - memset(mt->args, 0, NUMMAPTHINGARGS*sizeof(*mt->args)); - memset(mt->stringargs, 0x00, NUMMAPTHINGSTRINGARGS*sizeof(*mt->stringargs)); + memset(mt->args, 0, NUM_MAPTHING_ARGS*sizeof(*mt->args)); + memset(mt->stringargs, 0x00, NUM_MAPTHING_STRINGARGS*sizeof(*mt->stringargs)); mt->special = 0; + memset(mt->script_args, 0, NUM_SCRIPT_ARGS*sizeof(*mt->script_args)); + memset(mt->script_stringargs, 0x00, NUM_SCRIPT_STRINGARGS*sizeof(*mt->script_stringargs)); mt->pitch = mt->roll = 0; mt->layer = 0; @@ -1757,7 +1759,7 @@ static void ParseTextmapSectorParameter(UINT32 i, const char *param, const char else if (fastncmp(param, "stringarg", 9) && strlen(param) > 9) { size_t argnum = atol(param + 9); - if (argnum >= NUMSECTORSTRINGARGS) + if (argnum >= NUM_SCRIPT_STRINGARGS) return; sectors[i].stringargs[argnum] = Z_Malloc(strlen(val) + 1, PU_LEVEL, NULL); M_Memcpy(sectors[i].stringargs[argnum], val, strlen(val) + 1); @@ -1765,7 +1767,7 @@ static void ParseTextmapSectorParameter(UINT32 i, const char *param, const char else if (fastncmp(param, "arg", 3) && strlen(param) > 3) { size_t argnum = atol(param + 3); - if (argnum >= NUMSECTORARGS) + if (argnum >= NUM_SCRIPT_ARGS) return; sectors[i].args[argnum] = atol(val); } @@ -1838,7 +1840,7 @@ static void ParseTextmapLinedefParameter(UINT32 i, const char *param, const char else if (fastncmp(param, "stringarg", 9) && strlen(param) > 9) { size_t argnum = atol(param + 9); - if (argnum >= NUMLINESTRINGARGS) + if (argnum >= NUM_SCRIPT_STRINGARGS) return; lines[i].stringargs[argnum] = Z_Malloc(strlen(val) + 1, PU_LEVEL, NULL); M_Memcpy(lines[i].stringargs[argnum], val, strlen(val) + 1); @@ -1846,7 +1848,7 @@ static void ParseTextmapLinedefParameter(UINT32 i, const char *param, const char else if (fastncmp(param, "arg", 3) && strlen(param) > 3) { size_t argnum = atol(param + 3); - if (argnum >= NUMLINEARGS) + if (argnum >= NUM_SCRIPT_ARGS) return; lines[i].args[argnum] = atol(val); } @@ -1955,7 +1957,7 @@ static void ParseTextmapThingParameter(UINT32 i, const char *param, const char * else if (fastncmp(param, "stringarg", 9) && strlen(param) > 9) { size_t argnum = atol(param + 9); - if (argnum >= NUMMAPTHINGSTRINGARGS) + if (argnum >= NUM_MAPTHING_STRINGARGS) return; size_t len = strlen(val); mapthings[i].stringargs[argnum] = Z_Malloc(len + 1, PU_LEVEL, NULL); @@ -1965,10 +1967,27 @@ static void ParseTextmapThingParameter(UINT32 i, const char *param, const char * else if (fastncmp(param, "arg", 3) && strlen(param) > 3) { size_t argnum = atol(param + 3); - if (argnum >= NUMMAPTHINGARGS) + if (argnum >= NUM_MAPTHING_ARGS) return; mapthings[i].args[argnum] = atol(val); } + else if (fastncmp(param, "scriptstringarg", 15) && strlen(param) > 15) + { + size_t argnum = atol(param + 15); + if (argnum >= NUM_SCRIPT_STRINGARGS) + return; + size_t len = strlen(val); + mapthings[i].script_stringargs[argnum] = Z_Malloc(len + 1, PU_LEVEL, NULL); + M_Memcpy(mapthings[i].script_stringargs[argnum], val, len); + mapthings[i].script_stringargs[argnum][len] = '\0'; + } + else if (fastncmp(param, "scriptarg", 9) && strlen(param) > 9) + { + size_t argnum = atol(param + 9); + if (argnum >= NUM_SCRIPT_ARGS) + return; + mapthings[i].script_args[argnum] = atol(val); + } else ParseUserProperty(&mapthings[i].user, param, val); } @@ -2110,10 +2129,16 @@ static void P_WriteTextmapThing(FILE *f, mapthing_t *wmapthings, size_t i, size_ fprintf(f, "flip = true;\n"); if (wmapthings[i].special != 0) fprintf(f, "special = %d;\n", wmapthings[i].special); - for (j = 0; j < NUMMAPTHINGARGS; j++) + for (j = 0; j < NUM_SCRIPT_ARGS; j++) + if (wmapthings[i].script_args[j] != 0) + fprintf(f, "scriptarg%s = %d;\n", sizeu1(j), wmapthings[i].script_args[j]); + for (j = 0; j < NUM_SCRIPT_STRINGARGS; j++) + if (mapthings[i].script_stringargs[j]) + fprintf(f, "scriptstringarg%s = \"%s\";\n", sizeu1(j), mapthings[i].script_stringargs[j]); + for (j = 0; j < NUM_MAPTHING_ARGS; j++) if (wmapthings[i].args[j] != 0) fprintf(f, "arg%s = %d;\n", sizeu1(j), wmapthings[i].args[j]); - for (j = 0; j < NUMMAPTHINGSTRINGARGS; j++) + for (j = 0; j < NUM_MAPTHING_STRINGARGS; j++) if (mapthings[i].stringargs[j]) fprintf(f, "stringarg%s = \"%s\";\n", sizeu1(j), mapthings[i].stringargs[j]); if (wmapthings[i].user.length > 0) @@ -2534,10 +2559,10 @@ static void P_WriteTextmap(void) } if (wlines[i].special != 0) fprintf(f, "special = %d;\n", wlines[i].special); - for (j = 0; j < NUMLINEARGS; j++) + for (j = 0; j < NUM_SCRIPT_ARGS; j++) if (wlines[i].args[j] != 0) fprintf(f, "arg%s = %d;\n", sizeu1(j), wlines[i].args[j]); - for (j = 0; j < NUMLINESTRINGARGS; j++) + for (j = 0; j < NUM_SCRIPT_STRINGARGS; j++) if (lines[i].stringargs[j]) fprintf(f, "stringarg%s = \"%s\";\n", sizeu1(j), lines[i].stringargs[j]); if (wlines[i].alpha != FRACUNIT) @@ -2822,10 +2847,10 @@ static void P_WriteTextmap(void) } if (wsectors[i].action != 0) fprintf(f, "action = %d;\n", wsectors[i].action); - for (j = 0; j < NUMSECTORARGS; j++) + for (j = 0; j < NUM_SCRIPT_ARGS; j++) if (wsectors[i].args[j] != 0) fprintf(f, "arg%s = %d;\n", sizeu1(j), wsectors[i].args[j]); - for (j = 0; j < NUMSECTORSTRINGARGS; j++) + for (j = 0; j < NUM_SCRIPT_STRINGARGS; j++) if (wsectors[i].stringargs[j]) fprintf(f, "stringarg%s = \"%s\";\n", sizeu1(j), wsectors[i].stringargs[j]); switch (wsectors[i].activation & SECSPAC_TRIGGERMASK) @@ -3018,8 +3043,8 @@ static void P_LoadTextmap(void) sc->friction = ORIG_FRICTION; sc->action = 0; - memset(sc->args, 0, NUMSECTORARGS*sizeof(*sc->args)); - memset(sc->stringargs, 0x00, NUMSECTORSTRINGARGS*sizeof(*sc->stringargs)); + memset(sc->args, 0, NUM_SCRIPT_ARGS*sizeof(*sc->args)); + memset(sc->stringargs, 0x00, NUM_SCRIPT_STRINGARGS*sizeof(*sc->stringargs)); sc->activation = 0; K_UserPropertiesClear(&sc->user); @@ -3069,8 +3094,8 @@ static void P_LoadTextmap(void) ld->special = 0; Tag_FSet(&ld->tags, 0); - memset(ld->args, 0, NUMLINEARGS*sizeof(*ld->args)); - memset(ld->stringargs, 0x00, NUMLINESTRINGARGS*sizeof(*ld->stringargs)); + memset(ld->args, 0, NUM_SCRIPT_ARGS*sizeof(*ld->args)); + memset(ld->stringargs, 0x00, NUM_SCRIPT_STRINGARGS*sizeof(*ld->stringargs)); ld->alpha = FRACUNIT; ld->executordelay = 0; ld->sidenum[0] = 0xffff; @@ -3123,9 +3148,11 @@ static void P_LoadTextmap(void) mt->extrainfo = 0; mt->tid = 0; mt->scale = FRACUNIT; - memset(mt->args, 0, NUMMAPTHINGARGS*sizeof(*mt->args)); - memset(mt->stringargs, 0x00, NUMMAPTHINGSTRINGARGS*sizeof(*mt->stringargs)); + memset(mt->args, 0, NUM_MAPTHING_ARGS*sizeof(*mt->args)); + memset(mt->stringargs, 0x00, NUM_MAPTHING_STRINGARGS*sizeof(*mt->stringargs)); mt->special = 0; + memset(mt->script_args, 0, NUM_SCRIPT_ARGS*sizeof(*mt->script_args)); + memset(mt->script_stringargs, 0x00, NUM_SCRIPT_STRINGARGS*sizeof(*mt->script_stringargs)); mt->layer = 0; mt->mobj = NULL; diff --git a/src/p_spec.c b/src/p_spec.c index 0d08cdcc0..9e7336a14 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -2380,7 +2380,7 @@ void P_ActivateThingSpecial(mobj_t *mo, mobj_t *source) activator->sector = source->subsector->sector; } - P_ProcessSpecial(activator, mo->special, mo->args, mo->stringargs); + P_ProcessSpecial(activator, mo->special, mo->script_args, mo->script_stringargs); P_SetTarget(&activator->mo, NULL); Z_Free(activator); @@ -4363,7 +4363,7 @@ boolean P_ProcessSpecial(activator_t *activator, INT16 special, INT32 *args, cha if (backwardsCompat) break; - if (args[1] < 0 || args[1] >= NUMLINEARGS) + if (args[1] < 0 || args[1] >= NUM_SCRIPT_ARGS) { CONS_Debug(DBG_GAMELOGIC, "Linedef type 468: Invalid linedef arg %d\n", args[1]); break; @@ -4408,7 +4408,7 @@ boolean P_ProcessSpecial(activator_t *activator, INT16 special, INT32 *args, cha case 475: // ACS_Execute { - INT32 newArgs[NUMLINEARGS-1] = {0}; + INT32 newArgs[NUM_SCRIPT_ARGS-1] = {0}; INT32 i; if (!stringargs[0]) @@ -4417,17 +4417,17 @@ boolean P_ProcessSpecial(activator_t *activator, INT16 special, INT32 *args, cha return false; } - for (i = 1; i < NUMLINEARGS; i++) + for (i = 1; i < NUM_SCRIPT_ARGS; i++) { newArgs[i - 1] = args[i]; } - ACS_Execute(stringargs[0], newArgs, NUMLINEARGS-1, activator); + ACS_Execute(stringargs[0], newArgs, NUM_SCRIPT_ARGS-1, activator); } break; case 476: // ACS_ExecuteAlways { - INT32 newArgs[NUMLINEARGS-1] = {0}; + INT32 newArgs[NUM_SCRIPT_ARGS-1] = {0}; INT32 i; if (!stringargs[0]) @@ -4436,12 +4436,12 @@ boolean P_ProcessSpecial(activator_t *activator, INT16 special, INT32 *args, cha return false; } - for (i = 1; i < NUMLINEARGS; i++) + for (i = 1; i < NUM_SCRIPT_ARGS; i++) { newArgs[i - 1] = args[i]; } - ACS_ExecuteAlways(stringargs[0], newArgs, NUMLINEARGS-1, activator); + ACS_ExecuteAlways(stringargs[0], newArgs, NUM_SCRIPT_ARGS-1, activator); } break; case 477: // ACS_Suspend diff --git a/src/r_defs.h b/src/r_defs.h index 26d0aaaaf..de7f5e499 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -445,9 +445,6 @@ typedef enum CRUMBLE_RESTORE, // Crumble thinker is about to restore to original position } crumblestate_t; -#define NUMSECTORARGS 10 -#define NUMSECTORSTRINGARGS 2 - // // The SECTORS record, at runtime. // Stores things/mobjs. @@ -554,8 +551,8 @@ struct sector_t // Action specials INT16 action; - INT32 args[NUMSECTORARGS]; - char *stringargs[NUMSECTORSTRINGARGS]; + INT32 args[NUM_SCRIPT_ARGS]; + char *stringargs[NUM_SCRIPT_STRINGARGS]; sectoractionflags_t activation; // UDMF user-defined custom properties. @@ -573,10 +570,7 @@ typedef enum ST_NEGATIVE } slopetype_t; -#define HORIZONSPECIAL 41 - -#define NUMLINEARGS 10 -#define NUMLINESTRINGARGS 2 +#define HORIZONSPECIAL (41) struct line_t { @@ -592,8 +586,8 @@ struct line_t UINT32 activation; INT16 special; taglist_t tags; - INT32 args[NUMLINEARGS]; - char *stringargs[NUMLINESTRINGARGS]; + INT32 args[NUM_SCRIPT_ARGS]; + char *stringargs[NUM_SCRIPT_STRINGARGS]; // Visual appearance: sidedefs. UINT16 sidenum[2]; // sidenum[1] will be 0xffff if one-sided