diff --git a/src/k_kart.c b/src/k_kart.c index 7cafa491..146120f7 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -4021,6 +4021,7 @@ void K_RepairOrbitChain(mobj_t *orbit) // Then recount to make sure item amount is correct if (orbit->target && orbit->target->player) { + player_t *player = orbit->target->player; INT32 num = 0; mobj_t *cur = orbit->target->hnext; @@ -4030,14 +4031,14 @@ void K_RepairOrbitChain(mobj_t *orbit) { prev = cur; cur = cur->hnext; - if (++num > orbit->target->player->kartstuff[k_itemamount]) + if (++num > player->kartstuff[k_itemamount]) P_RemoveMobj(prev); else prev->movedir = num; } - if (orbit->target->player->kartstuff[k_itemamount] != num) - orbit->target->player->kartstuff[k_itemamount] = num; + if (player->kartstuff[k_itemamount] != num) + player->kartstuff[k_itemamount] = num; } } diff --git a/src/lua_maplib.c b/src/lua_maplib.c index 41875ea9..ae9dd4e9 100644 --- a/src/lua_maplib.c +++ b/src/lua_maplib.c @@ -258,6 +258,8 @@ static int lib_iterateSectorThinglist(lua_State *L) if (!lua_isnil(L, 1)) { 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; } else diff --git a/src/p_inter.c b/src/p_inter.c index db321541..d4dca95f 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -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); if (P_MobjWasRemoved(target)) return (shouldForce == 1); // mobj was removed + if (P_MobjWasRemoved(source)) + source = NULL; if (shouldForce == 1) force = true; else if (shouldForce == 2) @@ -3468,6 +3470,9 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da break; } + if (P_MobjWasRemoved(target)) + return false; + if (!P_MobjWasRemoved(target)) { target->reactiontime = 0; // we're awake now... diff --git a/src/p_mobj.c b/src/p_mobj.c index 7978d0f3..f0ca3ed6 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -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); #endif + if (mobj->player != NULL) + return P_SetPlayerMobjState(mobj, state); + if (recursion++) // if recursion detected, 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); explodemo = P_SpawnMobj(mo->x, mo->y, mo->z, MT_EXPLODE); - P_SetScale(explodemo, mo->scale); - explodemo->destscale = mo->destscale; - explodemo->momx += (P_RandomByte() % 32) * FixedMul(FRACUNIT/8, explodemo->scale); - explodemo->momy += (P_RandomByte() % 32) * FixedMul(FRACUNIT/8, explodemo->scale); - S_StartSound(explodemo, sfx_pop); + if (!P_MobjWasRemoved(explodemo)) + { + P_SetScale(explodemo, mo->scale); + explodemo->destscale = mo->destscale; + explodemo->momx += (P_RandomByte() % 32) * FixedMul(FRACUNIT/8, explodemo->scale); + explodemo->momy += (P_RandomByte() % 32) * FixedMul(FRACUNIT/8, explodemo->scale); + S_StartSound(explodemo, sfx_pop); + } explodemo = P_SpawnMobj(mo->x, mo->y, mo->z, MT_EXPLODE); - P_SetScale(explodemo, mo->scale); - explodemo->destscale = mo->destscale; - explodemo->momx += (P_RandomByte() % 64) * FixedMul(FRACUNIT/8, explodemo->scale); - explodemo->momy -= (P_RandomByte() % 64) * FixedMul(FRACUNIT/8, explodemo->scale); - S_StartSound(explodemo, sfx_dmpain); + if (!P_MobjWasRemoved(explodemo)) + { + P_SetScale(explodemo, mo->scale); + explodemo->destscale = mo->destscale; + explodemo->momx += (P_RandomByte() % 64) * FixedMul(FRACUNIT/8, explodemo->scale); + explodemo->momy -= (P_RandomByte() % 64) * FixedMul(FRACUNIT/8, explodemo->scale); + S_StartSound(explodemo, sfx_dmpain); + } explodemo = P_SpawnMobj(mo->x, mo->y, mo->z, MT_EXPLODE); - P_SetScale(explodemo, mo->scale); - explodemo->destscale = mo->destscale; - explodemo->momx -= (P_RandomByte() % 128) * FixedMul(FRACUNIT/8, explodemo->scale); - explodemo->momy += (P_RandomByte() % 128) * FixedMul(FRACUNIT/8, explodemo->scale); - S_StartSound(explodemo, sfx_pop); + if (!P_MobjWasRemoved(explodemo)) + { + P_SetScale(explodemo, mo->scale); + explodemo->destscale = mo->destscale; + explodemo->momx -= (P_RandomByte() % 128) * FixedMul(FRACUNIT/8, explodemo->scale); + explodemo->momy += (P_RandomByte() % 128) * FixedMul(FRACUNIT/8, explodemo->scale); + S_StartSound(explodemo, sfx_pop); + } explodemo = P_SpawnMobj(mo->x, mo->y, mo->z, MT_EXPLODE); - P_SetScale(explodemo, mo->scale); - explodemo->destscale = mo->destscale; - explodemo->momx -= (P_RandomByte() % 96) * FixedMul(FRACUNIT/8, explodemo->scale); - explodemo->momy -= (P_RandomByte() % 96) * FixedMul(FRACUNIT/8, explodemo->scale); - S_StartSound(explodemo, sfx_cybdth); + if (!P_MobjWasRemoved(explodemo)) + { + P_SetScale(explodemo, mo->scale); + explodemo->destscale = mo->destscale; + explodemo->momx -= (P_RandomByte() % 96) * FixedMul(FRACUNIT/8, explodemo->scale); + explodemo->momy -= (P_RandomByte() % 96) * FixedMul(FRACUNIT/8, explodemo->scale); + S_StartSound(explodemo, sfx_cybdth); + } // Hack: Release an animal. P_DamageMobj(mo, NULL, NULL, 10000); @@ -3584,6 +3599,9 @@ static void P_PlayerMobjThinker(mobj_t *mobj) I_Assert(mobj->player != NULL); I_Assert(!P_MobjWasRemoved(mobj)); + if (P_MobjWasRemoved(mobj)) + return; + P_MobjCheckWater(mobj); P_ButteredSlope(mobj); @@ -7051,6 +7069,9 @@ void P_MobjThinker(mobj_t *mobj) // separate thinker if (mobj->flags & MF_PUSHABLE || (mobj->info->flags & MF_PUSHABLE && mobj->fuse)) { + if (P_MobjWasRemoved(mobj)) + return; + P_MobjCheckWater(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 // DBG: set everything in mobj_t to 0xFF instead of leaving it. debug memory error. 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); + I_Assert(mobj != NULL); (mobj->player = p)->mo = mobj; mobj->angle = 0; @@ -11363,6 +11389,13 @@ void P_SpawnMapThing(mapthing_t *mthing) } 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; switch(mobj->type) diff --git a/src/p_user.c b/src/p_user.c index 94169754..fda7d9bb 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -829,6 +829,10 @@ void P_NightserizePlayer(player_t *player, INT32 nighttime) // 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 if (!(player->pflags & PF_SLIDING) && player->mo->state == &states[player->mo->info->painstate] && player->powers[pw_flashing]) return true;