Merge branch 'mobjcrashfixes' into 'master'

Prevent many Mobj related segfaults

See merge request KartKrew/Kart-Public!345
This commit is contained in:
Sal 2024-03-31 20:25:37 +00:00
commit 01d828b1cb
5 changed files with 68 additions and 23 deletions

View file

@ -4021,6 +4021,7 @@ void K_RepairOrbitChain(mobj_t *orbit)
// Then recount to make sure item amount is correct // Then recount to make sure item amount is correct
if (orbit->target && orbit->target->player) if (orbit->target && orbit->target->player)
{ {
player_t *player = orbit->target->player;
INT32 num = 0; INT32 num = 0;
mobj_t *cur = orbit->target->hnext; mobj_t *cur = orbit->target->hnext;
@ -4030,14 +4031,14 @@ void K_RepairOrbitChain(mobj_t *orbit)
{ {
prev = cur; prev = cur;
cur = cur->hnext; cur = cur->hnext;
if (++num > orbit->target->player->kartstuff[k_itemamount]) if (++num > player->kartstuff[k_itemamount])
P_RemoveMobj(prev); P_RemoveMobj(prev);
else else
prev->movedir = num; prev->movedir = num;
} }
if (orbit->target->player->kartstuff[k_itemamount] != num) if (player->kartstuff[k_itemamount] != num)
orbit->target->player->kartstuff[k_itemamount] = num; player->kartstuff[k_itemamount] = num;
} }
} }

View file

@ -258,6 +258,8 @@ static int lib_iterateSectorThinglist(lua_State *L)
if (!lua_isnil(L, 1)) if (!lua_isnil(L, 1))
{ {
thing = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); thing = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
if (P_MobjWasRemoved(thing))
return luaL_error(L, "current entry in thinglist was removed; avoid calling P_RemoveMobj on entries!");
thing = thing->snext; thing = thing->snext;
} }
else else

View file

@ -3142,6 +3142,8 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
UINT8 shouldForce = LUAh_ShouldDamage(target, inflictor, source, damage); UINT8 shouldForce = LUAh_ShouldDamage(target, inflictor, source, damage);
if (P_MobjWasRemoved(target)) if (P_MobjWasRemoved(target))
return (shouldForce == 1); // mobj was removed return (shouldForce == 1); // mobj was removed
if (P_MobjWasRemoved(source))
source = NULL;
if (shouldForce == 1) if (shouldForce == 1)
force = true; force = true;
else if (shouldForce == 2) else if (shouldForce == 2)
@ -3468,6 +3470,9 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
break; break;
} }
if (P_MobjWasRemoved(target))
return false;
if (!P_MobjWasRemoved(target)) if (!P_MobjWasRemoved(target))
{ {
target->reactiontime = 0; // we're awake now... target->reactiontime = 0; // we're awake now...

View file

@ -263,6 +263,9 @@ boolean P_SetMobjState(mobj_t *mobj, statenum_t state)
I_Error("P_SetMobjState used for player mobj. Use P_SetPlayerMobjState instead!\n(State called: %d)", state); I_Error("P_SetMobjState used for player mobj. Use P_SetPlayerMobjState instead!\n(State called: %d)", state);
#endif #endif
if (mobj->player != NULL)
return P_SetPlayerMobjState(mobj, state);
if (recursion++) // if recursion detected, if (recursion++) // if recursion detected,
memset(seenstate = tempstate, 0, sizeof tempstate); // clear state table memset(seenstate = tempstate, 0, sizeof tempstate); // clear state table
@ -590,29 +593,41 @@ void P_ExplodeMissile(mobj_t *mo)
P_RadiusAttack(mo, mo, 96*FRACUNIT); P_RadiusAttack(mo, mo, 96*FRACUNIT);
explodemo = P_SpawnMobj(mo->x, mo->y, mo->z, MT_EXPLODE); explodemo = P_SpawnMobj(mo->x, mo->y, mo->z, MT_EXPLODE);
if (!P_MobjWasRemoved(explodemo))
{
P_SetScale(explodemo, mo->scale); P_SetScale(explodemo, mo->scale);
explodemo->destscale = mo->destscale; explodemo->destscale = mo->destscale;
explodemo->momx += (P_RandomByte() % 32) * FixedMul(FRACUNIT/8, explodemo->scale); explodemo->momx += (P_RandomByte() % 32) * FixedMul(FRACUNIT/8, explodemo->scale);
explodemo->momy += (P_RandomByte() % 32) * FixedMul(FRACUNIT/8, explodemo->scale); explodemo->momy += (P_RandomByte() % 32) * FixedMul(FRACUNIT/8, explodemo->scale);
S_StartSound(explodemo, sfx_pop); S_StartSound(explodemo, sfx_pop);
}
explodemo = P_SpawnMobj(mo->x, mo->y, mo->z, MT_EXPLODE); explodemo = P_SpawnMobj(mo->x, mo->y, mo->z, MT_EXPLODE);
if (!P_MobjWasRemoved(explodemo))
{
P_SetScale(explodemo, mo->scale); P_SetScale(explodemo, mo->scale);
explodemo->destscale = mo->destscale; explodemo->destscale = mo->destscale;
explodemo->momx += (P_RandomByte() % 64) * FixedMul(FRACUNIT/8, explodemo->scale); explodemo->momx += (P_RandomByte() % 64) * FixedMul(FRACUNIT/8, explodemo->scale);
explodemo->momy -= (P_RandomByte() % 64) * FixedMul(FRACUNIT/8, explodemo->scale); explodemo->momy -= (P_RandomByte() % 64) * FixedMul(FRACUNIT/8, explodemo->scale);
S_StartSound(explodemo, sfx_dmpain); S_StartSound(explodemo, sfx_dmpain);
}
explodemo = P_SpawnMobj(mo->x, mo->y, mo->z, MT_EXPLODE); explodemo = P_SpawnMobj(mo->x, mo->y, mo->z, MT_EXPLODE);
if (!P_MobjWasRemoved(explodemo))
{
P_SetScale(explodemo, mo->scale); P_SetScale(explodemo, mo->scale);
explodemo->destscale = mo->destscale; explodemo->destscale = mo->destscale;
explodemo->momx -= (P_RandomByte() % 128) * FixedMul(FRACUNIT/8, explodemo->scale); explodemo->momx -= (P_RandomByte() % 128) * FixedMul(FRACUNIT/8, explodemo->scale);
explodemo->momy += (P_RandomByte() % 128) * FixedMul(FRACUNIT/8, explodemo->scale); explodemo->momy += (P_RandomByte() % 128) * FixedMul(FRACUNIT/8, explodemo->scale);
S_StartSound(explodemo, sfx_pop); S_StartSound(explodemo, sfx_pop);
}
explodemo = P_SpawnMobj(mo->x, mo->y, mo->z, MT_EXPLODE); explodemo = P_SpawnMobj(mo->x, mo->y, mo->z, MT_EXPLODE);
if (!P_MobjWasRemoved(explodemo))
{
P_SetScale(explodemo, mo->scale); P_SetScale(explodemo, mo->scale);
explodemo->destscale = mo->destscale; explodemo->destscale = mo->destscale;
explodemo->momx -= (P_RandomByte() % 96) * FixedMul(FRACUNIT/8, explodemo->scale); explodemo->momx -= (P_RandomByte() % 96) * FixedMul(FRACUNIT/8, explodemo->scale);
explodemo->momy -= (P_RandomByte() % 96) * FixedMul(FRACUNIT/8, explodemo->scale); explodemo->momy -= (P_RandomByte() % 96) * FixedMul(FRACUNIT/8, explodemo->scale);
S_StartSound(explodemo, sfx_cybdth); S_StartSound(explodemo, sfx_cybdth);
}
// Hack: Release an animal. // Hack: Release an animal.
P_DamageMobj(mo, NULL, NULL, 10000); P_DamageMobj(mo, NULL, NULL, 10000);
@ -3584,6 +3599,9 @@ static void P_PlayerMobjThinker(mobj_t *mobj)
I_Assert(mobj->player != NULL); I_Assert(mobj->player != NULL);
I_Assert(!P_MobjWasRemoved(mobj)); I_Assert(!P_MobjWasRemoved(mobj));
if (P_MobjWasRemoved(mobj))
return;
P_MobjCheckWater(mobj); P_MobjCheckWater(mobj);
P_ButteredSlope(mobj); P_ButteredSlope(mobj);
@ -7051,6 +7069,9 @@ void P_MobjThinker(mobj_t *mobj)
// separate thinker // separate thinker
if (mobj->flags & MF_PUSHABLE || (mobj->info->flags & MF_PUSHABLE && mobj->fuse)) if (mobj->flags & MF_PUSHABLE || (mobj->info->flags & MF_PUSHABLE && mobj->fuse))
{ {
if (P_MobjWasRemoved(mobj))
return;
P_MobjCheckWater(mobj); P_MobjCheckWater(mobj);
P_PushableThinker(mobj); P_PushableThinker(mobj);
@ -10235,6 +10256,10 @@ void P_RemoveMobj(mobj_t *mobj)
} }
} }
// clear the reference from the mapthing
if (mobj->spawnpoint)
mobj->spawnpoint->mobj = NULL;
// free block // free block
// DBG: set everything in mobj_t to 0xFF instead of leaving it. debug memory error. // DBG: set everything in mobj_t to 0xFF instead of leaving it. debug memory error.
if (mobj->flags & MF_NOTHINK && !mobj->thinker.next) if (mobj->flags & MF_NOTHINK && !mobj->thinker.next)
@ -10751,6 +10776,7 @@ void P_SpawnPlayer(INT32 playernum)
} }
mobj = P_SpawnMobj(0, 0, 0, MT_PLAYER); mobj = P_SpawnMobj(0, 0, 0, MT_PLAYER);
I_Assert(mobj != NULL);
(mobj->player = p)->mo = mobj; (mobj->player = p)->mo = mobj;
mobj->angle = 0; mobj->angle = 0;
@ -11363,6 +11389,13 @@ void P_SpawnMapThing(mapthing_t *mthing)
} }
mobj = P_SpawnMobj(x, y, z, i); mobj = P_SpawnMobj(x, y, z, i);
if (!mobj || P_MobjWasRemoved(mobj))
{
CONS_Alert(CONS_WARNING, "Failed to spawn map thing #%d at %d, %d\n", mthing->type, x>>FRACBITS, y>>FRACBITS);
return;
}
mobj->spawnpoint = mthing; mobj->spawnpoint = mthing;
switch(mobj->type) switch(mobj->type)

View file

@ -829,6 +829,10 @@ void P_NightserizePlayer(player_t *player, INT32 nighttime)
// //
boolean P_PlayerInPain(player_t *player) boolean P_PlayerInPain(player_t *player)
{ {
// If the player doesn't have a mobj, it can't be in pain.
if (!player->mo)
return false;
// no silly, sliding isn't pain // no silly, sliding isn't pain
if (!(player->pflags & PF_SLIDING) && player->mo->state == &states[player->mo->info->painstate] && player->powers[pw_flashing]) if (!(player->pflags & PF_SLIDING) && player->mo->state == &states[player->mo->info->painstate] && player->powers[pw_flashing])
return true; return true;