Merge branch 'fix-thing-tid-scramble' into 'master'

Fix mobj TIDs in netsave

See merge request KartKrew/Kart!2380
This commit is contained in:
AJ Martinez 2024-05-21 00:49:24 +00:00
commit a1e00b8110
3 changed files with 75 additions and 29 deletions

View file

@ -597,8 +597,9 @@ fixed_t P_GetMobjZMovement(mobj_t *mo);
boolean P_MobjCanChangeFlip(mobj_t *mobj); boolean P_MobjCanChangeFlip(mobj_t *mobj);
void P_InitTIDHash(void); void P_InitTIDHash(void);
void P_SetThingTID(mobj_t *mo, mtag_t tid); void P_AddThingTID(mobj_t *mo);
void P_RemoveThingTID(mobj_t *mo); void P_RemoveThingTID(mobj_t *mo);
void P_SetThingTID(mobj_t *mo, mtag_t tid);
mobj_t *P_FindMobjFromTID(mtag_t tid, mobj_t *i, mobj_t *activator); mobj_t *P_FindMobjFromTID(mtag_t tid, mobj_t *i, mobj_t *activator);
void P_DeleteMobjStringArgs(mobj_t *mobj); void P_DeleteMobjStringArgs(mobj_t *mobj);

View file

@ -11465,6 +11465,9 @@ void P_RemoveMobj(mobj_t *mobj)
mobj->health = 0; // Just because mobj->health = 0; // Just because
// unlink from tid chains
P_RemoveThingTID(mobj);
// unlink from sector and block lists // unlink from sector and block lists
P_UnsetThingPosition(mobj); P_UnsetThingPosition(mobj);
if (sector_list) if (sector_list)
@ -11518,7 +11521,6 @@ void P_RemoveMobj(mobj_t *mobj)
P_SetTarget(&mobj->punt_ref, NULL); P_SetTarget(&mobj->punt_ref, NULL);
P_SetTarget(&mobj->owner, NULL); P_SetTarget(&mobj->owner, NULL);
P_RemoveThingTID(mobj);
P_DeleteMobjStringArgs(mobj); P_DeleteMobjStringArgs(mobj);
R_RemoveMobjInterpolator(mobj); R_RemoveMobjInterpolator(mobj);
@ -11582,9 +11584,9 @@ void P_FreePrecipMobj(precipmobj_t *mobj)
// Clearing out stuff for savegames // Clearing out stuff for savegames
void P_RemoveSavegameMobj(mobj_t *mobj) void P_RemoveSavegameMobj(mobj_t *mobj)
{ {
// unlink from sector and block lists
if (((thinker_t *)mobj)->function.acp1 == (actionf_p1)P_NullPrecipThinker) if (((thinker_t *)mobj)->function.acp1 == (actionf_p1)P_NullPrecipThinker)
{ {
// unlink from sector and block lists
P_UnsetPrecipThingPosition((precipmobj_t *)mobj); P_UnsetPrecipThingPosition((precipmobj_t *)mobj);
if (precipsector_list) if (precipsector_list)
@ -11595,6 +11597,9 @@ void P_RemoveSavegameMobj(mobj_t *mobj)
} }
else else
{ {
// unlink from tid chains
P_RemoveThingTID(mobj);
// unlink from sector and block lists // unlink from sector and block lists
P_UnsetThingPosition(mobj); P_UnsetThingPosition(mobj);
@ -11604,12 +11609,13 @@ void P_RemoveSavegameMobj(mobj_t *mobj)
P_DelSeclist(sector_list); P_DelSeclist(sector_list);
sector_list = NULL; sector_list = NULL;
} }
P_DeleteMobjStringArgs(mobj);
} }
// stop any playing sound // stop any playing sound
S_StopSound(mobj); S_StopSound(mobj);
P_DeleteMobjStringArgs(mobj);
R_RemoveMobjInterpolator(mobj); R_RemoveMobjInterpolator(mobj);
// free block // free block
@ -13976,8 +13982,6 @@ void P_CopyMapThingSpecialFieldsToMobj(const mapthing_t *mthing, mobj_t *mobj)
{ {
size_t arg = SIZE_MAX; size_t arg = SIZE_MAX;
P_SetThingTID(mobj, mthing->tid);
mobj->special = mthing->special; mobj->special = mthing->special;
for (arg = 0; arg < NUM_MAPTHING_ARGS; arg++) for (arg = 0; arg < NUM_MAPTHING_ARGS; arg++)
@ -14048,6 +14052,9 @@ static mobj_t *P_SpawnMobjFromMapThing(mapthing_t *mthing, fixed_t x, fixed_t y,
mobj->spritexscale = mthing->spritexscale; mobj->spritexscale = mthing->spritexscale;
mobj->spriteyscale = mthing->spriteyscale; mobj->spriteyscale = mthing->spriteyscale;
mobj->tid = mthing->tid;
P_AddThingTID(mobj);
P_CopyMapThingSpecialFieldsToMobj(mthing, mobj); P_CopyMapThingSpecialFieldsToMobj(mthing, mobj);
if (!P_SetupSpawnedMapThing(mthing, mobj)) if (!P_SetupSpawnedMapThing(mthing, mobj))
@ -15028,27 +15035,25 @@ void P_InitTIDHash(void)
} }
// //
// P_SetThingTID // P_AddThingTID
// Adds a mobj to the hash array // Adds a mobj to the hash array
// //
void P_SetThingTID(mobj_t *mo, mtag_t tid) void P_AddThingTID(mobj_t *mo)
{ {
INT32 key = 0; I_Assert(!P_MobjWasRemoved(mo));
if (tid == 0) if (mo->tid <= 0)
{ {
if (mo->tid != 0) // 0 is no TID, and negative
{ // values are reserved.
P_RemoveThingTID(mo); mo->tid = 0;
} mo->tid_next = NULL;
mo->tid_prev = NULL;
return; return;
} }
mo->tid = tid;
// Insert at the head of this chain // Insert at the head of this chain
key = tid % TID_HASH_CHAINS; INT32 key = mo->tid % TID_HASH_CHAINS;
mo->tid_next = TID_Hash[key]; mo->tid_next = TID_Hash[key];
mo->tid_prev = &TID_Hash[key]; mo->tid_prev = &TID_Hash[key];
@ -15076,17 +15081,40 @@ void P_RemoveThingTID(mobj_t *mo)
{ {
mo->tid_next->tid_prev = mo->tid_prev; mo->tid_next->tid_prev = mo->tid_prev;
} }
mo->tid_prev = NULL;
mo->tid_next = NULL;
} }
// Remove TID. // Remove TID.
mo->tid = 0; mo->tid = 0;
} }
//
// P_SetThingTID
// Changes a mobj's TID
//
void P_SetThingTID(mobj_t *mo, mtag_t tid)
{
P_RemoveThingTID(mo);
if (P_MobjWasRemoved(mo))
{
// Do not assign if it is going to be removed.
return;
}
mo->tid = tid;
P_AddThingTID(mo);
}
// //
// P_FindMobjFromTID // P_FindMobjFromTID
// Mobj tag search function. // Mobj tag search function.
// //
mobj_t *P_FindMobjFromTID(mtag_t tid, mobj_t *i, mobj_t *activator) mobj_t *P_FindMobjFromTID(mtag_t tid, mobj_t *i, mobj_t *activator)
{
if (tid <= 0)
{ {
if (tid == 0) if (tid == 0)
{ {
@ -15101,6 +15129,23 @@ mobj_t *P_FindMobjFromTID(mtag_t tid, mobj_t *i, mobj_t *activator)
return activator; return activator;
} }
else if (tid >= -MAXPLAYERS)
{
// -1 to -MAXPLAYERS returns an arbritrary player's object.
INT32 playerID = -tid - 1;
player_t *player = &players[ playerID ];
if (playeringame[playerID] == true && player->spectator == false)
{
return player->mo;
}
return NULL;
}
// Invalid input, return NULL.
return NULL;
}
i = (i != NULL) ? i->tid_next : TID_Hash[tid % TID_HASH_CHAINS]; i = (i != NULL) ? i->tid_next : TID_Hash[tid % TID_HASH_CHAINS];

View file

@ -4663,10 +4663,7 @@ static thinker_t* LoadMobjThinker(savebuffer_t *save, actionf_p1 thinker)
if (diff2 & MD2_RENDERFLAGS) if (diff2 & MD2_RENDERFLAGS)
mobj->renderflags = READUINT32(save->p); mobj->renderflags = READUINT32(save->p);
if (diff2 & MD2_TID) if (diff2 & MD2_TID)
{ mobj->tid = READINT16(save->p);
INT16 tid = READINT16(save->p);
P_SetThingTID(mobj, tid);
}
if (diff2 & MD2_SPRITESCALE) if (diff2 & MD2_SPRITESCALE)
{ {
mobj->spritexscale = READFIXED(save->p); mobj->spritexscale = READFIXED(save->p);
@ -4788,6 +4785,9 @@ static thinker_t* LoadMobjThinker(savebuffer_t *save, actionf_p1 thinker)
mobj->owner = (mobj_t *)(size_t)READUINT32(save->p); mobj->owner = (mobj_t *)(size_t)READUINT32(save->p);
} }
// link tid set earlier
P_AddThingTID(mobj);
// set sprev, snext, bprev, bnext, subsector // set sprev, snext, bprev, bnext, subsector
P_SetThingPosition(mobj); P_SetThingPosition(mobj);