- 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)
{
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)
@ -266,7 +267,7 @@ DPSprite *player_t::GetPSprite(PSPLayers layer)
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);
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.
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;
player.SetSafeFlash(weap, flash, theflash);
}

View file

@ -56,7 +56,11 @@ class Beak : Weapon
{
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());
}
@ -85,7 +89,11 @@ class Beak : Weapon
}
A_StartSound ("chicken/peck", CHAN_VOICE);
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);
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))
return;
player.GetPSprite(PSP_WEAPON).x = ((random[GauntletAtk](0, 3)) - 2);
player.GetPSprite(PSP_WEAPON).y = WEAPONTOP + (random[GauntletAtk](0, 3));
let psp = player.GetPSprite(PSP_WEAPON);
if (psp)
{
psp.x = ((random[GauntletAtk](0, 3)) - 2);
psp.y = WEAPONTOP + (random[GauntletAtk](0, 3));
}
}
double ang = angle;
if (power)

View file

@ -74,8 +74,12 @@ class Mace : HereticWeapon
}
else
{
player.GetPSprite(PSP_WEAPON).x = random[MaceAtk](-2, 1);
player.GetPSprite(PSP_WEAPON).y = WEAPONTOP + random[MaceAtk](0, 3);
let psp = player.GetPSprite(PSP_WEAPON);
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)));
if (ball)
{

View file

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

View file

@ -227,6 +227,7 @@ class Weapon : StateProvider
return;
}
let psp = player.GetPSprite(PSP_WEAPON);
if (!psp) return;
if (player.morphTics || player.cheats & CF_INSTANTWEAPSWITCH)
{
psp.y = WEAPONBOTTOM;
@ -276,6 +277,7 @@ class Weapon : StateProvider
return;
}
let psp = player.GetPSprite(PSP_WEAPON);
if (!psp) return;
psp.y -= raisespeed;
if (psp.y > WEAPONTOP)
{ // Not raised all the way yet
@ -341,7 +343,8 @@ class Weapon : StateProvider
}
// 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)
{
@ -361,8 +364,11 @@ class Weapon : StateProvider
// Prepare for bobbing action.
player.WeaponState |= WF_WEAPONBOBBING;
let pspr = player.GetPSprite(PSP_WEAPON);
pspr.x = 0;
pspr.y = WEAPONTOP;
if (pspr)
{
pspr.x = 0;
pspr.y = WEAPONTOP;
}
}
}
@ -865,9 +871,12 @@ class Weapon : StateProvider
p.refire = 0;
let pspr = p.GetPSprite(PSP_WEAPON);
pspr.y = WEAPONBOTTOM;
pspr.ResetInterpolation();
pspr.SetState(GetUpState());
if (pspr)
{
pspr.y = WEAPONBOTTOM;
pspr.ResetInterpolation();
pspr.SetState(GetUpState());
}
}
//===========================================================================

View file

@ -1659,7 +1659,8 @@ class PlayerPawn : Actor
{
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());
}
return;
@ -1686,7 +1687,8 @@ class PlayerPawn : Actor
weapon.PlayUpSound(self);
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.
// When coming here from a weapon drop it may still be active.
player.SetPsprite(PSP_FLASH, null);

View file

@ -57,7 +57,8 @@ extend class PlayerPawn
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'))

View file

@ -202,7 +202,7 @@ class Sigil : Weapon
return;
}
PSprite pspr = player.GetPSprite(PSP_WEAPON);
pspr.SetState(pspr.CurState + invoker.health);
if (pspr) pspr.SetState(pspr.CurState + invoker.health);
invoker.downpieces = 0;
}
@ -225,7 +225,7 @@ class Sigil : Weapon
PSprite pspr = player.GetPSprite(PSP_WEAPON);
int pieces = invoker.downpieces;
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;
}
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 firehands = FindState("FireHands");
if (psp.CurState != null && firehandslower != null && firehands != null)
if (psp)
{
// Calculate state to go to.
int dist = firehands.DistanceTo(psp.curState);
if (dist > 0)
if (psp.CurState != null && firehandslower != null && firehands != null)
{
player.playerstate = PST_DEAD;
psp.SetState(firehandslower + dist);
return;
// Calculate state to go to.
int dist = firehands.DistanceTo(psp.curState);
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)
{
PSprite psp = player.GetPSprite(PSP_STRIFEHANDS);
if (psp.CurState == null)
if (psp)
{
psp.SetState(null);
return;
}
if (psp.CurState == null)
{
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--;
}
return;

View file

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