- 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,7 +267,7 @@ 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);
if (center)
{
center.x = POS_X; center.x = POS_X;
center.y = POS_Y; center.y = POS_Y;
}
PositionAccuracy (); PositionAccuracy ();
} }
@ -1402,14 +1404,20 @@ class PowerTargeter : Powerup
if (player != null) if (player != null)
{ {
PSprite left = player.GetPSprite(PSprite.TARGETLEFT); PSprite left = player.GetPSprite(PSprite.TARGETLEFT);
if (left)
{
left.x = POS_X - (100 - player.mo.accuracy); left.x = POS_X - (100 - player.mo.accuracy);
left.y = POS_Y; left.y = POS_Y;
}
PSprite right = player.GetPSprite(PSprite.TARGETRIGHT); PSprite right = player.GetPSprite(PSprite.TARGETRIGHT);
if (right)
{
right.x = POS_X + (100 - player.mo.accuracy); right.x = POS_X + (100 - player.mo.accuracy);
right.y = POS_Y; 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,10 +364,13 @@ 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);
if (pspr)
{
pspr.x = 0; pspr.x = 0;
pspr.y = WEAPONTOP; pspr.y = WEAPONTOP;
} }
} }
}
static int GetButtonStateFlags(int flags) static int GetButtonStateFlags(int flags)
{ {
@ -865,10 +871,13 @@ class Weapon : StateProvider
p.refire = 0; p.refire = 0;
let pspr = p.GetPSprite(PSP_WEAPON); let pspr = p.GetPSprite(PSP_WEAPON);
if (pspr)
{
pspr.y = WEAPONBOTTOM; pspr.y = WEAPONBOTTOM;
pspr.ResetInterpolation(); pspr.ResetInterpolation();
pspr.SetState(GetUpState()); 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,6 +121,8 @@ class StrifePlayer : PlayerPawn
State firehandslower = FindState("FireHandsLower"); State firehandslower = FindState("FireHandsLower");
State firehands = FindState("FireHands"); State firehands = FindState("FireHands");
if (psp)
{
if (psp.CurState != null && firehandslower != null && firehands != null) if (psp.CurState != null && firehandslower != null && firehands != null)
{ {
// Calculate state to go to. // Calculate state to go to.
@ -136,13 +138,15 @@ class StrifePlayer : PlayerPawn
psp.SetState(null); psp.SetState(null);
} }
} }
}
void A_HandLower() void A_HandLower()
{ {
if (player != null) if (player != null)
{ {
PSprite psp = player.GetPSprite(PSP_STRIFEHANDS); PSprite psp = player.GetPSprite(PSP_STRIFEHANDS);
if (psp)
{
if (psp.CurState == null) if (psp.CurState == null)
{ {
psp.SetState(null); psp.SetState(null);
@ -154,7 +158,7 @@ class StrifePlayer : PlayerPawn
{ {
psp.SetState(null); psp.SetState(null);
} }
}
if (player.extralight > 0) player.extralight--; if (player.extralight > 0) player.extralight--;
} }
return; return;

View file

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