mirror of
https://github.com/ZDoom/Raze.git
synced 2024-11-15 08:51:24 +00:00
- clean out stale sprite pointers in User when a sprite gets removed.
This was the main reason for those constant crashes, the game was accessing an invalid sprite, treating its data as valid. Also added a few checks for valid targets in two places where it still crashed.
This commit is contained in:
parent
4323632ed2
commit
410f5a4545
3 changed files with 22 additions and 5 deletions
|
@ -451,8 +451,8 @@ void UnindexAIState(AISTATE*& state)
|
|||
auto index = intptr_t(state);
|
||||
if (index >= 0 && index < countof(allAIStates))
|
||||
{
|
||||
Printf("Unindexing %i to state %p\n", int(index), state);
|
||||
state = allAIStates[index];
|
||||
Printf("Unindexing %i to state %p\n", int(index), state);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -305,12 +305,10 @@ CanSeePlayer(short SpriteNum)
|
|||
// if actor can still see the player
|
||||
int look_height = SPRITEp_TOS(sp);
|
||||
|
||||
ASSERT(u->tgt_sp);
|
||||
|
||||
//if (FAF_Sector(sp->sectnum))
|
||||
// return(TRUE);
|
||||
|
||||
if (FAFcansee(sp->x, sp->y, look_height, sp->sectnum, u->tgt_sp->x, u->tgt_sp->y, SPRITEp_UPPER(u->tgt_sp), u->tgt_sp->sectnum))
|
||||
if (u->tgt_sp && FAFcansee(sp->x, sp->y, look_height, sp->sectnum, u->tgt_sp->x, u->tgt_sp->y, SPRITEp_UPPER(u->tgt_sp), u->tgt_sp->sectnum))
|
||||
return TRUE;
|
||||
else
|
||||
return FALSE;
|
||||
|
@ -644,6 +642,12 @@ DoActorActionDecide(short SpriteNum)
|
|||
u->Dist = 0;
|
||||
action = InitActorDecide;
|
||||
|
||||
// target is gone.
|
||||
if (u->tgt_sp == nullptr)
|
||||
{
|
||||
return action;
|
||||
}
|
||||
|
||||
if (TEST(u->Flags, SPR_JUMPING | SPR_FALLING))
|
||||
{
|
||||
//CON_Message("Jumping or falling");
|
||||
|
@ -658,7 +662,6 @@ DoActorActionDecide(short SpriteNum)
|
|||
return action;
|
||||
}
|
||||
|
||||
|
||||
ICanSee = CanSeePlayer(SpriteNum); // Only need to call once
|
||||
// But need the result multiple times
|
||||
|
||||
|
@ -845,6 +848,9 @@ DoActorDecide(short SpriteNum)
|
|||
if (actor_action == InitActorAttack && u->WeaponNum == 0)
|
||||
return 0; // Just let the actor do as it was doing before in this case
|
||||
|
||||
// Target is gone.
|
||||
if (u->tgt_sp == nullptr)
|
||||
return 0;
|
||||
|
||||
// zombie is attacking a player
|
||||
if (actor_action == InitActorAttack && u->ID == ZOMBIE_RUN_R0 && User[u->tgt_sp-sprite]->PlayerP)
|
||||
|
|
|
@ -812,6 +812,17 @@ KillSprite(int16_t SpriteNum)
|
|||
memset(sp, 0xCC, sizeof(SPRITE));
|
||||
sp->statnum = statnum;
|
||||
sp->sectnum = sectnum;
|
||||
|
||||
// Kill references in all users - slow but unavoidable if we don't want the game to crash on stale pointers.
|
||||
for (auto u : User)
|
||||
{
|
||||
if (u)
|
||||
{
|
||||
if (u->hi_sp == sp) u->hi_sp = nullptr;
|
||||
if (u->lo_sp == sp) u->lo_sp = nullptr;
|
||||
if (u->tgt_sp == sp) u->tgt_sp = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ChangeState(short SpriteNum, STATEp statep)
|
||||
|
|
Loading…
Reference in a new issue