From e8140ae3883f3618aa423407d2d8492b2fb78749 Mon Sep 17 00:00:00 2001 From: Antonio Martinez Date: Mon, 2 Jun 2025 12:02:58 -0400 Subject: [PATCH] Relink player to kartitems --- src/lua_mobjlib.c | 8 ++++++++ src/p_mobj.c | 15 +++++++++++++++ src/p_mobj.h | 2 ++ src/p_saveg.cpp | 11 +++++++++++ 4 files changed, 36 insertions(+) diff --git a/src/lua_mobjlib.c b/src/lua_mobjlib.c index 158909815..dd80daf66 100644 --- a/src/lua_mobjlib.c +++ b/src/lua_mobjlib.c @@ -111,6 +111,7 @@ enum mobj_e { mobj_reappear, mobj_punt_ref, mobj_owner, + mobj_relinkplayer, }; static const char *const mobj_opt[] = { @@ -201,6 +202,7 @@ static const char *const mobj_opt[] = { "reappear", "punt_ref", "owner", + "relinkplayer", 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]) @@ -519,6 +521,9 @@ static int mobj_get(lua_State *L) } LUA_PushUserdata(L, mo->owner, META_MOBJ); break; + case mobj_relinkplayer: + lua_pushinteger(L, mo->relinkplayer); + break; default: // extra custom variables in Lua memory lua_getfield(L, LUA_REGISTRYINDEX, LREG_EXTVARS); I_Assert(lua_istable(L, -1)); @@ -934,6 +939,9 @@ static int mobj_set(lua_State *L) P_SetTarget(&mo->owner, owner); } break; + case mobj_relinkplayer: + mo->relinkplayer = luaL_checkinteger(L, 3); + 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 98d377637..0040ccad9 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -10353,9 +10353,24 @@ void P_MobjThinker(mobj_t *mobj) I_Assert(mobj != NULL); I_Assert(!P_MobjWasRemoved(mobj)); + if (P_IsKartItem(mobj->type) && mobj->target && !P_MobjWasRemoved(mobj->target)) + { + player_t *link = mobj->target->player; + if (link && playeringame[link-players] && !link->spectator) + mobj->relinkplayer = (link-players) + 1; + } + // Remove dead target/tracer. if (mobj->target && P_MobjWasRemoved(mobj->target)) + { P_SetTarget(&mobj->target, NULL); + if (P_IsKartItem(mobj->type) && mobj->relinkplayer && mobj->relinkplayer <= MAXPLAYERS) + { + player_t *relink = &players[mobj->relinkplayer-1]; + if (playeringame[relink-players] && !relink->spectator && relink->mo && !P_MobjWasRemoved(relink->mo)) + P_SetTarget(&mobj->target, relink->mo); + } + } if (mobj->tracer && P_MobjWasRemoved(mobj->tracer)) P_SetTarget(&mobj->tracer, NULL); if (mobj->hnext && P_MobjWasRemoved(mobj->hnext)) diff --git a/src/p_mobj.h b/src/p_mobj.h index 08b41922e..353011ddf 100644 --- a/src/p_mobj.h +++ b/src/p_mobj.h @@ -450,6 +450,8 @@ struct mobj_t INT32 po_movecount; // Polyobject carrying (NOT savegame, NOT Lua) + UINT8 relinkplayer; // reassociate kartitem target when it dies. ACHTUNG 1-INDEXED + // WARNING: New fields must be added separately to savegame and Lua. }; diff --git a/src/p_saveg.cpp b/src/p_saveg.cpp index 7fc84d0f8..6e39c8174 100644 --- a/src/p_saveg.cpp +++ b/src/p_saveg.cpp @@ -2999,6 +2999,7 @@ typedef enum MD3_REAPPEAR = 1<<1, MD3_PUNT_REF = 1<<2, MD3_OWNER = 1<<3, + MD3_RELINK_PLAYER = 1<<4, } mobj_diff3_t; typedef enum @@ -3322,6 +3323,8 @@ static void SaveMobjThinker(savebuffer_t *save, const thinker_t *th, const UINT8 diff3 |= MD3_PUNT_REF; if (mobj->owner) diff3 |= MD3_OWNER; + if (mobj->relinkplayer) + diff3 |= MD3_RELINK_PLAYER; if (diff3 != 0) diff2 |= MD2_MORE; @@ -3612,6 +3615,10 @@ static void SaveMobjThinker(savebuffer_t *save, const thinker_t *th, const UINT8 { WRITEUINT32(save->p, mobj->owner->mobjnum); } + if (diff3 & MD3_RELINK_PLAYER) + { + WRITEUINT8(save->p, mobj->relinkplayer); + } WRITEUINT32(save->p, mobj->mobjnum); } @@ -4925,6 +4932,10 @@ static thinker_t* LoadMobjThinker(savebuffer_t *save, actionf_p1 thinker) { mobj->owner = (mobj_t *)(size_t)READUINT32(save->p); } + if (diff3 & MD3_OWNER) + { + mobj->relinkplayer = READUINT8(save->p); + } // link tid set earlier P_AddThingTID(mobj);