From a8a1c14580ee735672de5235ce4a9e27b79d0703 Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 13 Nov 2023 00:56:19 -0800 Subject: [PATCH] mobj_t: add reappear and punt_ref members, add to savegame and Lua --- src/lua_mobjlib.c | 29 ++++++++++++++++++- src/p_mobj.c | 3 ++ src/p_mobj.h | 3 ++ src/p_saveg.c | 72 +++++++++++++++++++++++++++++++++++++++-------- 4 files changed, 95 insertions(+), 12 deletions(-) diff --git a/src/lua_mobjlib.c b/src/lua_mobjlib.c index ce4668038..51751f996 100644 --- a/src/lua_mobjlib.c +++ b/src/lua_mobjlib.c @@ -106,7 +106,9 @@ enum mobj_e { mobj_tid, mobj_special, mobj_args, - mobj_stringargs + mobj_stringargs, + mobj_reappear, + mobj_punt_ref, }; static const char *const mobj_opt[] = { @@ -194,6 +196,8 @@ static const char *const mobj_opt[] = { "special", "args", "stringargs", + "reappear", + "punt_ref", NULL}; #define UNIMPLEMENTED luaL_error(L, LUA_QL("mobj_t") " field " LUA_QS " is not implemented for Lua and cannot be accessed.", mobj_opt[field]) @@ -493,6 +497,17 @@ static int mobj_get(lua_State *L) case mobj_stringargs: LUA_PushUserdata(L, mo->thing_stringargs, META_THINGSTRINGARGS); break; + case mobj_reappear: + lua_pushinteger(L, mo->reappear); + break; + case mobj_punt_ref: + if (mo->punt_ref && P_MobjWasRemoved(mo->punt_ref)) + { // don't put invalid mobj back into Lua. + P_SetTarget(&mo->punt_ref, NULL); + return 0; + } + LUA_PushUserdata(L, mo->punt_ref, META_MOBJ); + break; default: // extra custom variables in Lua memory lua_getfield(L, LUA_REGISTRYINDEX, LREG_EXTVARS); I_Assert(lua_istable(L, -1)); @@ -883,6 +898,18 @@ static int mobj_set(lua_State *L) return NOSET; case mobj_stringargs: return NOSET; + case mobj_reappear: + mo->reappear = luaL_checkinteger(L, 3); + break; + case mobj_punt_ref: + if (lua_isnil(L, 3)) + P_SetTarget(&mo->punt_ref, NULL); + else + { + mobj_t *punt_ref = *((mobj_t **)luaL_checkudata(L, 3, META_MOBJ)); + P_SetTarget(&mo->punt_ref, punt_ref); + } + break; default: lua_getfield(L, LUA_REGISTRYINDEX, LREG_EXTVARS); I_Assert(lua_istable(L, -1)); diff --git a/src/p_mobj.c b/src/p_mobj.c index 0bdba2deb..e781107f0 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -10250,6 +10250,8 @@ void P_MobjThinker(mobj_t *mobj) P_SetTarget(&mobj->hprev, NULL); if (mobj->itnext && P_MobjWasRemoved(mobj->itnext)) P_SetTarget(&mobj->itnext, NULL); + if (mobj->punt_ref && P_MobjWasRemoved(mobj->punt_ref)) + P_SetTarget(&mobj->punt_ref, NULL); if (mobj->flags & MF_NOTHINK) return; @@ -11803,6 +11805,7 @@ void P_RemoveMobj(mobj_t *mobj) } P_SetTarget(&mobj->itnext, NULL); + P_SetTarget(&mobj->punt_ref, NULL); P_RemoveThingTID(mobj); P_DeleteMobjStringArgs(mobj); diff --git a/src/p_mobj.h b/src/p_mobj.h index 61780c004..96f6aa5bb 100644 --- a/src/p_mobj.h +++ b/src/p_mobj.h @@ -437,6 +437,9 @@ struct mobj_t boolean frozen; + tic_t reappear; + mobj_t *punt_ref; + // WARNING: New fields must be added separately to savegame and Lua. }; diff --git a/src/p_saveg.c b/src/p_saveg.c index fad0ce24c..ef09120d7 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -2668,9 +2668,16 @@ typedef enum MD2_FROZEN = 1<<28, MD2_TERRAIN = 1<<29, MD2_WATERSKIP = 1<<30, - MD2_LIGHTLEVEL = (INT32)(1U<<31), + MD2_MORE = (INT32)(1U<<31), } mobj_diff2_t; +typedef enum +{ + MD3_LIGHTLEVEL = 1, + MD3_REAPPEAR = 1<<1, + MD3_PUNT_REF = 1<<2, +} mobj_diff3_t; + typedef enum { tc_mobj, @@ -2781,12 +2788,14 @@ static void SaveMobjThinker(savebuffer_t *save, const thinker_t *th, const UINT8 const mobj_t *mobj = (const mobj_t *)th; UINT32 diff; UINT32 diff2; + UINT32 diff3; size_t j; if (TypeIsNetSynced(mobj->type) == false) return; diff2 = 0; + diff3 = 0; if (mobj->spawnpoint) { @@ -2968,8 +2977,6 @@ static void SaveMobjThinker(savebuffer_t *save, const thinker_t *th, const UINT8 || (slope->normal.z != FRACUNIT)) diff2 |= MD2_FLOORSPRITESLOPE; } - if (mobj->lightlevel) - diff2 |= MD2_LIGHTLEVEL; if (mobj->hitlag) diff2 |= MD2_HITLAG; if (mobj->waterskip) @@ -2987,6 +2994,16 @@ static void SaveMobjThinker(savebuffer_t *save, const thinker_t *th, const UINT8 if (mobj->terrain != NULL || mobj->terrainOverlay != NULL) diff2 |= MD2_TERRAIN; + if (mobj->lightlevel) + diff3 |= MD3_LIGHTLEVEL; + if (mobj->reappear) + diff3 |= MD3_REAPPEAR; + if (mobj->punt_ref) + diff3 |= MD3_PUNT_REF; + + if (diff3 != 0) + diff2 |= MD2_MORE; + if (diff2 != 0) diff |= MD_MORE; @@ -2998,6 +3015,8 @@ static void SaveMobjThinker(savebuffer_t *save, const thinker_t *th, const UINT8 WRITEUINT32(save->p, diff); if (diff & MD_MORE) WRITEUINT32(save->p, diff2); + if (diff2 & MD2_MORE) + WRITEUINT32(save->p, diff3); WRITEFIXED(save->p, mobj->z); // Force this so 3dfloor problems don't arise. WRITEFIXED(save->p, mobj->floorz); @@ -3235,10 +3254,6 @@ static void SaveMobjThinker(savebuffer_t *save, const thinker_t *th, const UINT8 WRITEFIXED(save->p, slope->normal.y); WRITEFIXED(save->p, slope->normal.z); } - if (diff2 & MD2_LIGHTLEVEL) - { - WRITEINT16(save->p, mobj->lightlevel); - } if (diff2 & MD2_HITLAG) { WRITEINT32(save->p, mobj->hitlag); @@ -3261,6 +3276,19 @@ static void SaveMobjThinker(savebuffer_t *save, const thinker_t *th, const UINT8 WRITEUINT32(save->p, SaveMobjnum(mobj->terrainOverlay)); } + if (diff3 & MD3_LIGHTLEVEL) + { + WRITEINT16(save->p, mobj->lightlevel); + } + if (diff3 & MD3_REAPPEAR) + { + WRITEUINT32(save->p, mobj->reappear); + } + if (diff3 & MD3_PUNT_REF) + { + WRITEUINT32(save->p, mobj->punt_ref->mobjnum); + } + WRITEUINT32(save->p, mobj->mobjnum); } @@ -4134,6 +4162,7 @@ static thinker_t* LoadMobjThinker(savebuffer_t *save, actionf_p1 thinker) mobj_t *mobj; UINT32 diff; UINT32 diff2; + UINT32 diff3; INT32 i; fixed_t z, floorz, ceilingz; ffloor_t *floorrover = NULL, *ceilingrover = NULL; @@ -4145,6 +4174,11 @@ static thinker_t* LoadMobjThinker(savebuffer_t *save, actionf_p1 thinker) else diff2 = 0; + if (diff2 & MD2_MORE) + diff3 = READUINT32(save->p); + else + diff3 = 0; + z = READFIXED(save->p); // Force this so 3dfloor problems don't arise. floorz = READFIXED(save->p); ceilingz = READFIXED(save->p); @@ -4470,10 +4504,6 @@ static thinker_t* LoadMobjThinker(savebuffer_t *save, actionf_p1 thinker) P_UpdateSlopeLightOffset(slope); } - if (diff2 & MD2_LIGHTLEVEL) - { - mobj->lightlevel = READINT16(save->p); - } if (diff2 & MD2_HITLAG) { mobj->hitlag = READINT32(save->p); @@ -4500,6 +4530,19 @@ static thinker_t* LoadMobjThinker(savebuffer_t *save, actionf_p1 thinker) mobj->terrain = NULL; } + if (diff3 & MD3_LIGHTLEVEL) + { + mobj->lightlevel = READINT16(save->p); + } + if (diff3 & MD3_REAPPEAR) + { + mobj->reappear = READUINT32(save->p); + } + if (diff3 & MD3_PUNT_REF) + { + mobj->punt_ref = (mobj_t *)(size_t)READUINT32(save->p); + } + // set sprev, snext, bprev, bnext, subsector P_SetThingPosition(mobj); @@ -5539,6 +5582,13 @@ static void P_RelinkPointers(void) if (!P_SetTarget(&mobj->terrainOverlay, P_FindNewPosition(temp))) CONS_Debug(DBG_GAMELOGIC, "terrainOverlay not found on %d\n", mobj->type); } + if (mobj->punt_ref) + { + temp = (UINT32)(size_t)mobj->punt_ref; + mobj->punt_ref = NULL; + if (!P_SetTarget(&mobj->punt_ref, P_FindNewPosition(temp))) + CONS_Debug(DBG_GAMELOGIC, "punt_ref not found on %d\n", mobj->type); + } } for (i = 0; i < MAXPLAYERS; i++)