- fixed: player_t::GetPSprite cannot guarantee success

As a consequence it must return null in the failure case instead of asserting and all calls to this function must check for the failure case.
This commit is contained in:
Christoph Oelckers 2020-03-11 00:56:29 +01:00
parent 2acdf5cfab
commit a638cfbd6e
12 changed files with 101 additions and 52 deletions

View file

@ -232,7 +232,8 @@ DEFINE_ACTION_FUNCTION(_PlayerInfo, FindPSprite) // the underscore is needed to
void P_SetPsprite(player_t *player, PSPLayers id, FState *state, bool pending) void P_SetPsprite(player_t *player, PSPLayers id, FState *state, bool pending)
{ {
if (player == nullptr) return; if (player == nullptr) return;
player->GetPSprite(id)->SetState(state, pending); auto psp = player->GetPSprite(id);
if (psp) psp->SetState(state, pending);
} }
DEFINE_ACTION_FUNCTION(_PlayerInfo, SetPSprite) // the underscore is needed to get past the name mangler which removes the first clas name character to match the class representation (needs to be fixed in a later commit) DEFINE_ACTION_FUNCTION(_PlayerInfo, SetPSprite) // the underscore is needed to get past the name mangler which removes the first clas name character to match the class representation (needs to be fixed in a later commit)
@ -266,8 +267,8 @@ DPSprite *player_t::GetPSprite(PSPLayers layer)
newcaller = ReadyWeapon; newcaller = ReadyWeapon;
} }
assert(newcaller != nullptr); if (newcaller == nullptr) return nullptr; // Error case was not handled properly. This function cannot give a guarantee to always succeed!
DPSprite *pspr = FindPSprite(layer); DPSprite *pspr = FindPSprite(layer);
if (pspr == nullptr) if (pspr == nullptr)
{ {

View file

@ -70,7 +70,8 @@ extend class StateProvider
{ {
// Removed most of the mess that was here in the C++ code because SetSafeFlash already does some thorough validation. // Removed most of the mess that was here in the C++ code because SetSafeFlash already does some thorough validation.
State atk = weap.FindState('Fire'); State atk = weap.FindState('Fire');
State cur = player.GetPSprite(PSP_WEAPON).CurState; let psp = player.GetPSprite(PSP_WEAPON);
if (psp) State cur = psp.CurState;
int theflash = atk == cur? 0:1; int theflash = atk == cur? 0:1;
player.SetSafeFlash(weap, flash, theflash); player.SetSafeFlash(weap, flash, theflash);
} }

View file

@ -56,7 +56,11 @@ class Beak : Weapon
{ {
return; return;
} }
player.GetPSprite(PSP_WEAPON).y = WEAPONTOP; let psp = player.GetPSprite(PSP_WEAPON);
if (psp)
{
psp.y = WEAPONTOP;
}
player.SetPsprite(PSP_WEAPON, player.ReadyWeapon.GetReadyState()); player.SetPsprite(PSP_WEAPON, player.ReadyWeapon.GetReadyState());
} }
@ -85,7 +89,11 @@ class Beak : Weapon
} }
A_StartSound ("chicken/peck", CHAN_VOICE); A_StartSound ("chicken/peck", CHAN_VOICE);
player.chickenPeck = 12; player.chickenPeck = 12;
player.GetPSprite(PSP_WEAPON).Tics -= random[BeakAtk](0,7); let psp = player.GetPSprite(PSP_WEAPON);
if (psp)
{
psp.Tics -= random[BeakAtk](0,7);
}
} }
} }
@ -133,7 +141,11 @@ class BeakPowered : Beak
} }
A_StartSound ("chicken/peck", CHAN_VOICE); A_StartSound ("chicken/peck", CHAN_VOICE);
player.chickenPeck = 12; player.chickenPeck = 12;
player.GetPSprite(PSP_WEAPON).Tics -= random[BeakAtk](0,3); let psp = player.GetPSprite(PSP_WEAPON);
if (psp)
{
psp.Tics -= random[BeakAtk](0,3);
}
} }
} }

View file

@ -67,8 +67,12 @@ class Gauntlets : Weapon
if (!weapon.DepleteAmmo (weapon.bAltFire)) if (!weapon.DepleteAmmo (weapon.bAltFire))
return; return;
player.GetPSprite(PSP_WEAPON).x = ((random[GauntletAtk](0, 3)) - 2); let psp = player.GetPSprite(PSP_WEAPON);
player.GetPSprite(PSP_WEAPON).y = WEAPONTOP + (random[GauntletAtk](0, 3)); if (psp)
{
psp.x = ((random[GauntletAtk](0, 3)) - 2);
psp.y = WEAPONTOP + (random[GauntletAtk](0, 3));
}
} }
double ang = angle; double ang = angle;
if (power) if (power)

View file

@ -74,8 +74,12 @@ class Mace : HereticWeapon
} }
else else
{ {
player.GetPSprite(PSP_WEAPON).x = random[MaceAtk](-2, 1); let psp = player.GetPSprite(PSP_WEAPON);
player.GetPSprite(PSP_WEAPON).y = WEAPONTOP + random[MaceAtk](0, 3); if (psp)
{
psp.x = random[MaceAtk](-2, 1);
psp.y = WEAPONTOP + random[MaceAtk](0, 3);
}
Actor ball = SpawnPlayerMissile("MaceFX1", angle + (random[MaceAtk](-4, 3) * (360. / 256))); Actor ball = SpawnPlayerMissile("MaceFX1", angle + (random[MaceAtk](-4, 3) * (360. / 256)));
if (ball) if (ball)
{ {

View file

@ -1323,9 +1323,11 @@ class PowerTargeter : Powerup
} }
PSprite center = player.GetPSprite(PSprite.TARGETCENTER); PSprite center = player.GetPSprite(PSprite.TARGETCENTER);
center.x = POS_X; if (center)
center.y = POS_Y; {
center.x = POS_X;
center.y = POS_Y;
}
PositionAccuracy (); PositionAccuracy ();
} }
@ -1402,12 +1404,18 @@ class PowerTargeter : Powerup
if (player != null) if (player != null)
{ {
PSprite left = player.GetPSprite(PSprite.TARGETLEFT); PSprite left = player.GetPSprite(PSprite.TARGETLEFT);
left.x = POS_X - (100 - player.mo.accuracy); if (left)
left.y = POS_Y; {
left.x = POS_X - (100 - player.mo.accuracy);
left.y = POS_Y;
}
PSprite right = player.GetPSprite(PSprite.TARGETRIGHT); PSprite right = player.GetPSprite(PSprite.TARGETRIGHT);
right.x = POS_X + (100 - player.mo.accuracy); if (right)
right.y = POS_Y; {
right.x = POS_X + (100 - player.mo.accuracy);
right.y = POS_Y;
}
} }
} }

View file

@ -227,6 +227,7 @@ class Weapon : StateProvider
return; return;
} }
let psp = player.GetPSprite(PSP_WEAPON); let psp = player.GetPSprite(PSP_WEAPON);
if (!psp) return;
if (player.morphTics || player.cheats & CF_INSTANTWEAPSWITCH) if (player.morphTics || player.cheats & CF_INSTANTWEAPSWITCH)
{ {
psp.y = WEAPONBOTTOM; psp.y = WEAPONBOTTOM;
@ -276,6 +277,7 @@ class Weapon : StateProvider
return; return;
} }
let psp = player.GetPSprite(PSP_WEAPON); let psp = player.GetPSprite(PSP_WEAPON);
if (!psp) return;
psp.y -= raisespeed; psp.y -= raisespeed;
if (psp.y > WEAPONTOP) if (psp.y > WEAPONTOP)
{ // Not raised all the way yet { // Not raised all the way yet
@ -341,7 +343,8 @@ class Weapon : StateProvider
} }
// Play ready sound, if any. // Play ready sound, if any.
if (weapon.ReadySound && player.GetPSprite(PSP_WEAPON).curState == weapon.FindState('Ready')) let psp = player.GetPSprite(PSP_WEAPON);
if (weapon.ReadySound && psp && psp.curState == weapon.FindState('Ready'))
{ {
if (!weapon.bReadySndHalf || random[WpnReadySnd]() < 128) if (!weapon.bReadySndHalf || random[WpnReadySnd]() < 128)
{ {
@ -361,8 +364,11 @@ class Weapon : StateProvider
// Prepare for bobbing action. // Prepare for bobbing action.
player.WeaponState |= WF_WEAPONBOBBING; player.WeaponState |= WF_WEAPONBOBBING;
let pspr = player.GetPSprite(PSP_WEAPON); let pspr = player.GetPSprite(PSP_WEAPON);
pspr.x = 0; if (pspr)
pspr.y = WEAPONTOP; {
pspr.x = 0;
pspr.y = WEAPONTOP;
}
} }
} }
@ -865,9 +871,12 @@ class Weapon : StateProvider
p.refire = 0; p.refire = 0;
let pspr = p.GetPSprite(PSP_WEAPON); let pspr = p.GetPSprite(PSP_WEAPON);
pspr.y = WEAPONBOTTOM; if (pspr)
pspr.ResetInterpolation(); {
pspr.SetState(GetUpState()); pspr.y = WEAPONBOTTOM;
pspr.ResetInterpolation();
pspr.SetState(GetUpState());
}
} }
//=========================================================================== //===========================================================================

View file

@ -1659,7 +1659,8 @@ class PlayerPawn : Actor
{ {
if (player.ReadyWeapon != null) if (player.ReadyWeapon != null)
{ {
player.GetPSprite(PSP_WEAPON).y = WEAPONTOP; let psp = player.GetPSprite(PSP_WEAPON);
if (psp) psp.y = WEAPONTOP;
player.SetPsprite(PSP_WEAPON, player.ReadyWeapon.GetReadyState()); player.SetPsprite(PSP_WEAPON, player.ReadyWeapon.GetReadyState());
} }
return; return;
@ -1686,7 +1687,8 @@ class PlayerPawn : Actor
weapon.PlayUpSound(self); weapon.PlayUpSound(self);
player.refire = 0; player.refire = 0;
player.GetPSprite(PSP_WEAPON).y = player.cheats & CF_INSTANTWEAPSWITCH? WEAPONTOP : WEAPONBOTTOM; let psp = player.GetPSprite(PSP_WEAPON);
if (psp) psp.y = player.cheats & CF_INSTANTWEAPSWITCH? WEAPONTOP : WEAPONBOTTOM;
// make sure that the previous weapon's flash state is terminated. // make sure that the previous weapon's flash state is terminated.
// When coming here from a weapon drop it may still be active. // When coming here from a weapon drop it may still be active.
player.SetPsprite(PSP_FLASH, null); player.SetPsprite(PSP_FLASH, null);

View file

@ -57,7 +57,8 @@ extend class PlayerPawn
if (player.ReadyWeapon != null) if (player.ReadyWeapon != null)
{ {
player.GetPSprite(PSP_WEAPON).y = WEAPONTOP; let psp = player.GetPSprite(PSP_WEAPON);
if (psp) psp.y = WEAPONTOP;
} }
if (morphweaponcls == null || !(morphweaponcls is 'Weapon')) if (morphweaponcls == null || !(morphweaponcls is 'Weapon'))

View file

@ -202,7 +202,7 @@ class Sigil : Weapon
return; return;
} }
PSprite pspr = player.GetPSprite(PSP_WEAPON); PSprite pspr = player.GetPSprite(PSP_WEAPON);
pspr.SetState(pspr.CurState + invoker.health); if (pspr) pspr.SetState(pspr.CurState + invoker.health);
invoker.downpieces = 0; invoker.downpieces = 0;
} }
@ -225,7 +225,7 @@ class Sigil : Weapon
PSprite pspr = player.GetPSprite(PSP_WEAPON); PSprite pspr = player.GetPSprite(PSP_WEAPON);
int pieces = invoker.downpieces; int pieces = invoker.downpieces;
if (pieces < 1 || pieces > 5) pieces = invoker.health; if (pieces < 1 || pieces > 5) pieces = invoker.health;
pspr.SetState(pspr.CurState + pieces); if (pspr) pspr.SetState(pspr.CurState + pieces);
} }
//============================================================================ //============================================================================
@ -243,7 +243,7 @@ class Sigil : Weapon
return; return;
} }
PSprite pspr = player.GetPSprite(PSP_WEAPON); PSprite pspr = player.GetPSprite(PSP_WEAPON);
pspr.SetState(pspr.CurState + (4 * invoker.health - 3)); if (pspr) pspr.SetState(pspr.CurState + (4 * invoker.health - 3));
} }
//============================================================================ //============================================================================

View file

@ -121,19 +121,22 @@ class StrifePlayer : PlayerPawn
State firehandslower = FindState("FireHandsLower"); State firehandslower = FindState("FireHandsLower");
State firehands = FindState("FireHands"); State firehands = FindState("FireHands");
if (psp.CurState != null && firehandslower != null && firehands != null) if (psp)
{ {
// Calculate state to go to. if (psp.CurState != null && firehandslower != null && firehands != null)
int dist = firehands.DistanceTo(psp.curState);
if (dist > 0)
{ {
player.playerstate = PST_DEAD; // Calculate state to go to.
psp.SetState(firehandslower + dist); int dist = firehands.DistanceTo(psp.curState);
return; if (dist > 0)
{
player.playerstate = PST_DEAD;
psp.SetState(firehandslower + dist);
return;
}
} }
player.playerstate = PST_DEAD;
psp.SetState(null);
} }
player.playerstate = PST_DEAD;
psp.SetState(null);
} }
} }
@ -142,19 +145,20 @@ class StrifePlayer : PlayerPawn
if (player != null) if (player != null)
{ {
PSprite psp = player.GetPSprite(PSP_STRIFEHANDS); PSprite psp = player.GetPSprite(PSP_STRIFEHANDS);
if (psp)
if (psp.CurState == null)
{ {
psp.SetState(null); if (psp.CurState == null)
return; {
psp.SetState(null);
return;
}
psp.y += 9;
if (psp.y > WEAPONBOTTOM*2)
{
psp.SetState(null);
}
} }
psp.y += 9;
if (psp.y > WEAPONBOTTOM*2)
{
psp.SetState(null);
}
if (player.extralight > 0) player.extralight--; if (player.extralight > 0) player.extralight--;
} }
return; return;

View file

@ -137,8 +137,11 @@ class Mauler2 : Mauler
if (player != null) if (player != null)
{ {
PSprite psp = player.GetPSprite(PSP_WEAPON); PSprite psp = player.GetPSprite(PSP_WEAPON);
psp.x += Random2[Mauler2]() / 64.; if (psp)
psp.y += Random2[Mauler2]() / 64.; {
psp.x += Random2[Mauler2]() / 64.;
psp.y += Random2[Mauler2]() / 64.;
}
} }
} }