From 34c4a207c7ccf46f5edd0596d600603d058aa58a 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 | 50 ++++------------ src/doomdata.h | 17 ++++-- src/lua_maplib.c | 26 ++++----- src/lua_mobjlib.c | 12 ++-- src/m_cheat.c | 7 ++- src/p_enemy.c | 4 +- src/p_mobj.c | 45 ++++++++++++++- src/p_mobj.h | 9 ++- src/p_saveg.c | 125 +++++++++++++++++++++++++++++++++------- src/p_setup.c | 88 +++++++++++++++------------- src/p_spec.c | 18 +++--- src/r_defs.h | 16 ++--- 13 files changed, 267 insertions(+), 152 deletions(-) diff --git a/src/acs/call-funcs.cpp b/src/acs/call-funcs.cpp index d6f50e811..4cce79309 100644 --- a/src/acs/call-funcs.cpp +++ b/src/acs/call-funcs.cpp @@ -1081,7 +1081,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 e47eb6f7c..af8d2fab0 100644 --- a/src/acs/environment.cpp +++ b/src/acs/environment.cpp @@ -324,16 +324,13 @@ ACSVM::Word Environment::callSpecImpl auto info = &static_cast(thread)->info; ACSVM::MapScope *const map = thread->scopeMap; - int arg = 0; - int numStringArgs = 0; + INT32 args[NUM_SCRIPT_ARGS] = {0}; - INT32 args[NUMLINEARGS] = {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]); } @@ -352,42 +349,19 @@ ACSVM::Word Environment::callSpecImpl } ); - // This needs manually set, as ACS just uses indicies in the - // compiled string table and not actual strings, and SRB2 has - // separate args and stringargs, so there's no way to - // properly distinguish them. - switch (spec) + int i = 0; + + for (i = 0; i < std::min((signed)(argC), NUM_SCRIPT_STRINGARGS); i++) { - case 442: - numStringArgs = 2; - break; - case 413: - case 414: - case 415: - case 423: - case 425: - case 443: - case 459: - case 461: - case 463: - case 469: - numStringArgs = 1; - break; - default: - break; + ACSVM::String *strPtr = map->getString(argV[i]); + + stringargs[i] = static_cast(Z_Malloc(strPtr->len + 1, PU_STATIC, nullptr)); + M_Memcpy(stringargs[i], strPtr->str, strPtr->len + 1); } - for (; arg < numStringArgs; arg++) + for (i = 0; i < std::min((signed)(argC), NUM_SCRIPT_ARGS); i++) { - ACSVM::String *strPtr = map->getString(argV[arg]); - - stringargs[arg] = static_cast(Z_Malloc(strPtr->len + 1, PU_STATIC, nullptr)); - M_Memcpy(stringargs[arg], strPtr->str, strPtr->len + 1); - } - - for (; arg < std::min((signed)argC, NUMLINEARGS); arg++) - { - args[arg - numStringArgs] = argV[arg]; + args[i] = argV[i]; } P_SetTarget(&activator->mo, info->mo); diff --git a/src/doomdata.h b/src/doomdata.h index 429063de0..255a93e04 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 @@ -249,8 +254,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. @@ -266,8 +273,10 @@ struct mapthing_t fixed_t scale; fixed_t spritexscale, spriteyscale; 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 75d64ab93..744a6d6a4 100644 --- a/src/lua_maplib.c +++ b/src/lua_maplib.c @@ -605,16 +605,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; } @@ -623,16 +623,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; } @@ -948,16 +948,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; } @@ -966,16 +966,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 2f5b65bea..179e1cb71 100644 --- a/src/lua_mobjlib.c +++ b/src/lua_mobjlib.c @@ -901,16 +901,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; } @@ -919,16 +919,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 d2f351596..7db86b13f 100644 --- a/src/m_cheat.c +++ b/src/m_cheat.c @@ -981,8 +981,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 d55a2a65e..7d7c56277 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -6924,8 +6924,8 @@ 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 db8f9ebe9..4365e89f1 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -12491,12 +12491,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; @@ -12516,6 +12516,39 @@ 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, &doangle)) + { + if (P_MobjWasRemoved(mobj)) + return NULL; + + return mobj; + } + mthing->mobj = mobj; // Generic reverse gravity for individual objects flag. @@ -13605,9 +13638,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 af4fb8112..11cc036d9 100644 --- a/src/p_mobj.h +++ b/src/p_mobj.h @@ -418,10 +418,13 @@ struct mobj_t mobj_t *terrainOverlay; // Overlay sprite object for terrain 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 4ec3afc81..80e638240 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -953,7 +953,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; @@ -963,7 +963,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]; @@ -1000,7 +1000,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; @@ -1010,7 +1010,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]; @@ -1273,12 +1273,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; @@ -1427,12 +1427,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; @@ -1563,13 +1563,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; @@ -1652,13 +1652,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; @@ -1725,7 +1725,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; @@ -1735,7 +1735,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]; @@ -1747,6 +1747,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, @@ -1938,7 +1960,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 @@ -1946,7 +1968,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) { @@ -1955,7 +1977,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) { @@ -1968,6 +1990,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; + } + } } @@ -2224,12 +2264,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; @@ -2309,8 +2349,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; @@ -3423,12 +3483,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; @@ -3512,6 +3572,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 a5f217c41..9eedbf605 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1116,8 +1116,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); @@ -1226,8 +1226,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; @@ -1504,9 +1504,11 @@ static void P_LoadThings(UINT8 *data) mt->tid = 0; mt->scale = FRACUNIT; mt->spritexscale = mt->spriteyscale = FRACUNIT; - memset(mt->args, 0, NUMMAPTHINGARGS*sizeof(*mt->args)); - memset(mt->stringargs, 0x00, NUMMAPTHINGSTRINGARGS*sizeof(*mt->stringargs)); - //mt->special = 0; + 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; @@ -1917,7 +1919,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); @@ -1925,7 +1927,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); } @@ -1998,7 +2000,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); @@ -2006,7 +2008,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); } @@ -2122,7 +2124,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); @@ -2132,26 +2134,26 @@ 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, "thingarg", 8) && strlen(param) > 8) + else if (fastncmp(param, "scriptstringarg", 15) && strlen(param) > 15) { - size_t argnum = atol(param + 8); - if (argnum >= NUMMAPTHINGARGS) - return; - mapthings[i].args[argnum] = atol(val); - } - else if (fastncmp(param, "thingstringarg", 14) && strlen(param) > 14) - { - size_t argnum = atol(param + 14); - if (argnum >= NUMMAPTHINGSTRINGARGS) + size_t argnum = atol(param + 15); + if (argnum >= NUM_SCRIPT_STRINGARGS) return; size_t len = strlen(val); - mapthings[i].stringargs[argnum] = Z_Malloc(len + 1, PU_LEVEL, NULL); - M_Memcpy(mapthings[i].stringargs[argnum], val, len); - mapthings[i].stringargs[argnum][len] = '\0'; + 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); @@ -2321,10 +2323,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) @@ -2725,10 +2733,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) @@ -3024,10 +3032,10 @@ static void P_WriteTextmap(void) fprintf(f, "triggerer = %d;\n", wsectors[i].triggerer); 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) @@ -3221,8 +3229,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); @@ -3272,8 +3280,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; @@ -3327,9 +3335,11 @@ static void P_LoadTextmap(void) mt->tid = 0; mt->scale = FRACUNIT; mt->spritexscale = mt->spriteyscale = FRACUNIT; - memset(mt->args, 0, NUMMAPTHINGARGS*sizeof(*mt->args)); - memset(mt->stringargs, 0x00, NUMMAPTHINGSTRINGARGS*sizeof(*mt->stringargs)); - //mt->special = 0; + 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 5996c8b6f..8cd78b24b 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -2336,7 +2336,9 @@ void P_ActivateThingSpecial(mobj_t *mo, mobj_t *source) activator->sector = source->subsector->sector; } - P_ProcessSpecial(activator, mt->special, mt->args, mt->stringargs); + P_ProcessSpecial(activator, mo->special, mo->script_args, mo->script_stringargs); + + P_SetTarget(&activator->mo, NULL); Z_Free(activator); } @@ -4171,7 +4173,7 @@ boolean P_ProcessSpecial(activator_t *activator, INT16 special, INT32 *args, cha if (!udmf) 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; @@ -4216,7 +4218,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]) @@ -4225,17 +4227,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]) @@ -4244,12 +4246,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 6c3b66b75..d831aff34 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -447,9 +447,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. @@ -556,8 +553,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. @@ -575,10 +572,7 @@ typedef enum ST_NEGATIVE } slopetype_t; -#define HORIZONSPECIAL 41 - -#define NUMLINEARGS 10 -#define NUMLINESTRINGARGS 2 +#define HORIZONSPECIAL (41) struct line_t { @@ -594,8 +588,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