mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-26 05:51:20 +00:00
- 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:
parent
2acdf5cfab
commit
a638cfbd6e
12 changed files with 101 additions and 52 deletions
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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'))
|
||||||
|
|
|
@ -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));
|
||||||
}
|
}
|
||||||
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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.;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue