From 1966b61b8fd83621406c62dbc7e42aa80bafec29 Mon Sep 17 00:00:00 2001 From: Leonard2 Date: Mon, 9 May 2016 20:03:47 +0200 Subject: [PATCH 01/25] Generalized the psprites implementation --- src/d_player.h | 8 +- src/g_doom/a_doomweaps.cpp | 38 +-- src/g_game.cpp | 2 + src/g_heretic/a_chicken.cpp | 14 +- src/g_heretic/a_hereticweaps.cpp | 24 +- src/g_hexen/a_clericstaff.cpp | 12 +- src/g_hexen/a_fighteraxe.cpp | 32 +- src/g_hexen/a_fighterplayer.cpp | 4 +- src/g_hexen/a_pig.cpp | 4 +- src/g_shared/a_artifacts.cpp | 52 ++-- src/g_shared/a_weapons.cpp | 9 +- src/g_strife/a_strifestuff.cpp | 27 +- src/g_strife/a_strifeweapons.cpp | 46 +-- src/m_cheat.cpp | 12 +- src/p_local.h | 1 - src/p_mobj.cpp | 8 +- src/p_pspr.cpp | 477 ++++++++++++++++++++---------- src/p_pspr.h | 75 +++-- src/p_saveg.cpp | 17 +- src/p_tick.cpp | 2 +- src/p_user.cpp | 69 ++++- src/r_things.cpp | 271 +++++++++-------- src/r_things.h | 1 - src/thingdef/thingdef_codeptr.cpp | 13 +- src/version.h | 2 +- 25 files changed, 743 insertions(+), 477 deletions(-) diff --git a/src/d_player.h b/src/d_player.h index 40178dac1..ee9e64f0c 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -380,6 +380,7 @@ class player_t { public: player_t(); + ~player_t(); player_t &operator= (const player_t &p); void Serialize (FArchive &arc); @@ -454,7 +455,6 @@ public: int extralight; // so gun flashes light up areas short fixedcolormap; // can be set to REDCOLORMAP, etc. short fixedlightlevel; - pspdef_t psprites[NUMPSPRITES]; // view sprites (gun, etc) int morphTics; // player is a chicken/pig if > 0 PClassPlayerPawn *MorphedPlayerClass; // [MH] (for SBARINFO) class # for this player instance when morphed int MorphStyle; // which effects to apply for this player instance when morphed @@ -526,6 +526,12 @@ public: } int GetSpawnClass(); + + // PSprite layers + DPSprite *psprites; // view sprites (gun, etc) + void TickPSprites(); + void DestroyPSprites(); + DPSprite *GetPSprite(psprnum_t layer); // Used ONLY for compatibility with the old hardcoded layers. }; // Bookkeeping on players - state. diff --git a/src/g_doom/a_doomweaps.cpp b/src/g_doom/a_doomweaps.cpp index 21119f8a0..a96fab8fc 100644 --- a/src/g_doom/a_doomweaps.cpp +++ b/src/g_doom/a_doomweaps.cpp @@ -73,16 +73,15 @@ DEFINE_ACTION_FUNCTION(AActor, A_FirePistol) bool accurate; - if (self->player != NULL) + if (self->player != nullptr) { AWeapon *weapon = self->player->ReadyWeapon; - if (weapon != NULL && ACTION_CALL_FROM_WEAPON()) + if (weapon != nullptr && ACTION_CALL_FROM_WEAPON()) { if (!weapon->DepleteAmmo (weapon->bAltFire, true, 1)) return 0; - P_SetPsprite (self->player, ps_flash, weapon->FindState(NAME_Flash)); - self->player->psprites[ps_flash].processPending = true; + self->player->GetPSprite(ps_flash)->SetState(weapon->FindState(NAME_Flash), true); } self->player->mo->PlayAttacking2 (); @@ -263,19 +262,18 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireShotgun) int i; player_t *player; - if (NULL == (player = self->player)) + if (nullptr == (player = self->player)) { return 0; } S_Sound (self, CHAN_WEAPON, "weapons/shotgf", 1, ATTN_NORM); AWeapon *weapon = self->player->ReadyWeapon; - if (weapon != NULL && ACTION_CALL_FROM_WEAPON()) + if (weapon != nullptr && ACTION_CALL_FROM_WEAPON()) { if (!weapon->DepleteAmmo (weapon->bAltFire, true, 1)) return 0; - P_SetPsprite (player, ps_flash, weapon->FindState(NAME_Flash)); - self->player->psprites[ps_flash].processPending = true; + player->GetPSprite(ps_flash)->SetState(weapon->FindState(NAME_Flash), true); } player->mo->PlayAttacking2 (); @@ -300,19 +298,18 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireShotgun2) int damage; player_t *player; - if (NULL == (player = self->player)) + if (nullptr == (player = self->player)) { return 0; } S_Sound (self, CHAN_WEAPON, "weapons/sshotf", 1, ATTN_NORM); AWeapon *weapon = self->player->ReadyWeapon; - if (weapon != NULL && ACTION_CALL_FROM_WEAPON()) + if (weapon != nullptr && ACTION_CALL_FROM_WEAPON()) { if (!weapon->DepleteAmmo (weapon->bAltFire, true, 2)) return 0; - P_SetPsprite (player, ps_flash, weapon->FindState(NAME_Flash)); - self->player->psprites[ps_flash].processPending = true; + player->GetPSprite(ps_flash)->SetState(weapon->FindState(NAME_Flash), true); } player->mo->PlayAttacking2 (); @@ -384,15 +381,13 @@ void P_SetSafeFlash(AWeapon *weapon, player_t *player, FState *flashstate, int i if (flashstate + index < cls->OwnedStates + cls->NumOwnedStates) { // we're ok so set the state - P_SetPsprite (player, ps_flash, flashstate + index); - player->psprites[ps_flash].processPending = true; + player->GetPSprite(ps_flash)->SetState(flashstate + index, true); return; } else { // oh, no! The state is beyond the end of the state table so use the original flash state. - P_SetPsprite (player, ps_flash, flashstate); - player->psprites[ps_flash].processPending = true; + player->GetPSprite(ps_flash)->SetState(flashstate, true); return; } } @@ -408,8 +403,7 @@ void P_SetSafeFlash(AWeapon *weapon, player_t *player, FState *flashstate, int i { // Invalid state. With no index offset, it should at least be valid. index = 0; } - P_SetPsprite (player, ps_flash, flashstate + index); - player->psprites[ps_flash].processPending = true; + player->GetPSprite(ps_flash)->SetState(flashstate + index, true); } // @@ -421,13 +415,13 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireCGun) player_t *player; - if (self == NULL || NULL == (player = self->player)) + if (self == nullptr || nullptr == (player = self->player)) { return 0; } AWeapon *weapon = player->ReadyWeapon; - if (weapon != NULL && ACTION_CALL_FROM_WEAPON()) + if (weapon != nullptr && ACTION_CALL_FROM_WEAPON()) { if (!weapon->DepleteAmmo (weapon->bAltFire, true, 1)) return 0; @@ -435,12 +429,12 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireCGun) S_Sound (self, CHAN_WEAPON, "weapons/chngun", 1, ATTN_NORM); FState *flash = weapon->FindState(NAME_Flash); - if (flash != NULL) + if (flash != nullptr) { // [RH] Fix for Sparky's messed-up Dehacked patch! Blargh! FState * atk = weapon->FindState(NAME_Fire); - int theflash = clamp (int(player->psprites[ps_weapon].state - atk), 0, 1); + int theflash = clamp (int(player->GetPSprite(ps_weapon)->GetState() - atk), 0, 1); if (flash[theflash].sprite != flash->sprite) { diff --git a/src/g_game.cpp b/src/g_game.cpp index 7c31e09c0..3c9d274c8 100644 --- a/src/g_game.cpp +++ b/src/g_game.cpp @@ -1750,6 +1750,8 @@ void G_DoPlayerPop(int playernum) players[playernum].mo = NULL; players[playernum].camera = NULL; } + + players[playernum].DestroyPSprites(); } void G_ScreenShot (char *filename) diff --git a/src/g_heretic/a_chicken.cpp b/src/g_heretic/a_chicken.cpp index 3251e3812..cb8bc7fc9 100644 --- a/src/g_heretic/a_chicken.cpp +++ b/src/g_heretic/a_chicken.cpp @@ -123,9 +123,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_Feathers) void P_UpdateBeak (AActor *self) { - if (self->player != NULL) + if (self->player != nullptr) { - self->player->psprites[ps_weapon].sy = WEAPONTOP + self->player->chickenPeck / 2; + self->player->GetPSprite(ps_weapon)->y = WEAPONTOP + self->player->chickenPeck / 2; } } @@ -141,12 +141,12 @@ DEFINE_ACTION_FUNCTION(AActor, A_BeakRaise) player_t *player; - if (NULL == (player = self->player)) + if (nullptr == (player = self->player)) { return 0; } - player->psprites[ps_weapon].sy = WEAPONTOP; - P_SetPsprite (player, ps_weapon, player->ReadyWeapon->GetReadyState()); + player->GetPSprite(ps_weapon)->y = WEAPONTOP; + player->GetPSprite(ps_weapon)->SetState(player->ReadyWeapon->GetReadyState()); return 0; } @@ -192,7 +192,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_BeakAttackPL1) } P_PlayPeck (player->mo); player->chickenPeck = 12; - player->psprites[ps_weapon].tics -= pr_beakatkpl1() & 7; + player->GetPSprite(ps_weapon)->Tics -= pr_beakatkpl1() & 7; return 0; } @@ -227,6 +227,6 @@ DEFINE_ACTION_FUNCTION(AActor, A_BeakAttackPL2) } P_PlayPeck (player->mo); player->chickenPeck = 12; - player->psprites[ps_weapon].tics -= pr_beakatkpl2()&3; + player->GetPSprite(ps_weapon)->Tics -= pr_beakatkpl2()&3; return 0; } diff --git a/src/g_heretic/a_hereticweaps.cpp b/src/g_heretic/a_hereticweaps.cpp index 504321061..8b5409f5b 100644 --- a/src/g_heretic/a_hereticweaps.cpp +++ b/src/g_heretic/a_hereticweaps.cpp @@ -259,7 +259,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_GauntletAttack) FTranslatedLineTarget t; int actualdamage = 0; - if (NULL == (player = self->player)) + if (nullptr == (player = self->player)) { return 0; } @@ -267,13 +267,13 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_GauntletAttack) PARAM_INT(power); AWeapon *weapon = player->ReadyWeapon; - if (weapon != NULL) + if (weapon != nullptr) { if (!weapon->DepleteAmmo (weapon->bAltFire)) return 0; } - player->psprites[ps_weapon].sx = ((pr_gatk()&3)-2); - player->psprites[ps_weapon].sy = WEAPONTOP + (pr_gatk()&3); + player->GetPSprite(ps_weapon)->x = ((pr_gatk()&3)-2); + player->GetPSprite(ps_weapon)->y = WEAPONTOP + (pr_gatk()&3); Angle = self->Angles.Yaw; if (power) { @@ -425,7 +425,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireMacePL1) AActor *ball; player_t *player; - if (NULL == (player = self->player)) + if (nullptr == (player = self->player)) { return 0; } @@ -436,13 +436,13 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireMacePL1) return 0; } AWeapon *weapon = player->ReadyWeapon; - if (weapon != NULL) + if (weapon != nullptr) { if (!weapon->DepleteAmmo(weapon->bAltFire)) return 0; } - player->psprites[ps_weapon].sx = ((pr_maceatk() & 3) - 2); - player->psprites[ps_weapon].sy = WEAPONTOP + (pr_maceatk() & 3); + player->GetPSprite(ps_weapon)->x = ((pr_maceatk() & 3) - 2); + player->GetPSprite(ps_weapon)->y = WEAPONTOP + (pr_maceatk() & 3); ball = P_SpawnPlayerMissile(self, PClass::FindActor("MaceFX1"), self->Angles.Yaw + (((pr_maceatk() & 7) - 4) * (360. / 256))); if (ball) { @@ -1158,7 +1158,7 @@ IMPLEMENT_CLASS (APhoenixRodPowered) void APhoenixRodPowered::EndPowerup () { - P_SetPsprite (Owner->player, ps_weapon, SisterWeapon->GetReadyState()); + Owner->player->GetPSprite(ps_weapon)->SetState(SisterWeapon->GetReadyState()); DepleteAmmo (bAltFire); Owner->player->refire = 0; S_StopSound (Owner, CHAN_WEAPON); @@ -1298,7 +1298,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FirePhoenixPL2) player_t *player; APhoenixRod *flamethrower; - if (NULL == (player = self->player)) + if (nullptr == (player = self->player)) { return 0; } @@ -1306,9 +1306,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_FirePhoenixPL2) soundid = "weapons/phoenixpowshoot"; flamethrower = static_cast (player->ReadyWeapon); - if (flamethrower == NULL || --flamethrower->FlameCount == 0) + if (flamethrower == nullptr || --flamethrower->FlameCount == 0) { // Out of flame - P_SetPsprite (player, ps_weapon, flamethrower->FindState("Powerdown")); + player->GetPSprite(ps_weapon)->SetState(flamethrower->FindState("Powerdown")); player->refire = 0; S_StopSound (self, CHAN_WEAPON); return 0; diff --git a/src/g_hexen/a_clericstaff.cpp b/src/g_hexen/a_clericstaff.cpp index d936e8d1d..898ff9b0e 100644 --- a/src/g_hexen/a_clericstaff.cpp +++ b/src/g_hexen/a_clericstaff.cpp @@ -58,7 +58,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CStaffCheck) FTranslatedLineTarget t; PClassActor *puff; - if (NULL == (player = self->player)) + if (nullptr == (player = self->player)) { return 0; } @@ -77,7 +77,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CStaffCheck) if (t.linetarget) { P_LineAttack(pmo, angle, 1.5 * MELEERANGE, slope, damage, NAME_Melee, puff, false, &t); - if (t.linetarget != NULL) + if (t.linetarget != nullptr) { pmo->Angles.Yaw = t.angleFromSource; if (((t.linetarget->player && (!t.linetarget->IsTeammate(pmo) || level.teamdamage != 0)) || t.linetarget->flags3&MF3_ISMONSTER) @@ -89,13 +89,13 @@ DEFINE_ACTION_FUNCTION(AActor, A_CStaffCheck) { pmo->health = player->health = newLife; } - if (weapon != NULL) + if (weapon != nullptr) { FState * newstate = weapon->FindState("Drain"); - if (newstate != NULL) P_SetPsprite(player, ps_weapon, newstate); + if (newstate != nullptr) player->GetPSprite(ps_weapon)->SetState(newstate); } } - if (weapon != NULL) + if (weapon != nullptr) { weapon->DepleteAmmo(weapon->bAltFire, false); } @@ -187,7 +187,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CStaffCheckBlink) { if (!--self->weaponspecial) { - P_SetPsprite (self->player, ps_weapon, self->player->ReadyWeapon->FindState ("Blink")); + self->player->GetPSprite(ps_weapon)->SetState(self->player->ReadyWeapon->FindState ("Blink")); self->weaponspecial = (pr_blink()+50)>>2; } else diff --git a/src/g_hexen/a_fighteraxe.cpp b/src/g_hexen/a_fighteraxe.cpp index c83726b44..7fe867697 100644 --- a/src/g_hexen/a_fighteraxe.cpp +++ b/src/g_hexen/a_fighteraxe.cpp @@ -70,13 +70,13 @@ DEFINE_ACTION_FUNCTION(AActor, A_FAxeCheckReady) player_t *player; - if (NULL == (player = self->player)) + if (nullptr == (player = self->player)) { return 0; } if (player->ReadyWeapon->Ammo1->Amount) { - P_SetPsprite (player, ps_weapon, player->ReadyWeapon->FindState ("ReadyGlow")); + player->GetPSprite(ps_weapon)->SetState(player->ReadyWeapon->FindState ("ReadyGlow")); } else { @@ -97,13 +97,13 @@ DEFINE_ACTION_FUNCTION(AActor, A_FAxeCheckReadyG) player_t *player; - if (NULL == (player = self->player)) + if (nullptr == (player = self->player)) { return 0; } if (player->ReadyWeapon->Ammo1->Amount <= 0) { - P_SetPsprite (player, ps_weapon, player->ReadyWeapon->FindState ("Ready")); + player->GetPSprite(ps_weapon)->SetState(player->ReadyWeapon->FindState ("Ready")); } else { @@ -124,13 +124,13 @@ DEFINE_ACTION_FUNCTION(AActor, A_FAxeCheckUp) player_t *player; - if (NULL == (player = self->player)) + if (nullptr == (player = self->player)) { return 0; } if (player->ReadyWeapon->Ammo1->Amount) { - P_SetPsprite (player, ps_weapon, player->ReadyWeapon->FindState ("SelectGlow")); + player->GetPSprite(ps_weapon)->SetState(player->ReadyWeapon->FindState ("SelectGlow")); } else { @@ -151,13 +151,13 @@ DEFINE_ACTION_FUNCTION(AActor, A_FAxeCheckUpG) player_t *player; - if (NULL == (player = self->player)) + if (nullptr == (player = self->player)) { return 0; } if (player->ReadyWeapon->Ammo1->Amount <= 0) { - P_SetPsprite (player, ps_weapon, player->ReadyWeapon->FindState ("Select")); + player->GetPSprite(ps_weapon)->SetState(player->ReadyWeapon->FindState ("Select")); } else { @@ -178,13 +178,13 @@ DEFINE_ACTION_FUNCTION(AActor, A_FAxeCheckAtk) player_t *player; - if (NULL == (player = self->player)) + if (nullptr == (player = self->player)) { return 0; } if (player->ReadyWeapon->Ammo1->Amount) { - P_SetPsprite (player, ps_weapon, player->ReadyWeapon->FindState ("FireGlow")); + player->GetPSprite(ps_weapon)->SetState(player->ReadyWeapon->FindState ("FireGlow")); } return 0; } @@ -210,7 +210,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FAxeAttack) PClassActor *pufftype; FTranslatedLineTarget t; - if (NULL == (player = self->player)) + if (nullptr == (player = self->player)) { return 0; } @@ -241,7 +241,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FAxeAttack) if (t.linetarget) { P_LineAttack(pmo, angle, AXERANGE, slope, damage, NAME_Melee, pufftype, true, &t); - if (t.linetarget != NULL) + if (t.linetarget != nullptr) { if (t.linetarget->flags3&MF3_ISMONSTER || t.linetarget->player) { @@ -265,15 +265,15 @@ axedone: if (useMana == 2) { AWeapon *weapon = player->ReadyWeapon; - if (weapon != NULL) + if (weapon != nullptr) { weapon->DepleteAmmo (weapon->bAltFire, false); - if ((weapon->Ammo1 == NULL || weapon->Ammo1->Amount == 0) && + if ((weapon->Ammo1 == nullptr || weapon->Ammo1->Amount == 0) && (!(weapon->WeaponFlags & WIF_PRIMARY_USES_BOTH) || - weapon->Ammo2 == NULL || weapon->Ammo2->Amount == 0)) + weapon->Ammo2 == nullptr || weapon->Ammo2->Amount == 0)) { - P_SetPsprite (player, ps_weapon, player->ReadyWeapon->FindState ("Fire") + 5); + player->GetPSprite(ps_weapon)->SetState(player->ReadyWeapon->FindState ("Fire") + 5); } } } diff --git a/src/g_hexen/a_fighterplayer.cpp b/src/g_hexen/a_fighterplayer.cpp index c8f3aa19f..35b08f860 100644 --- a/src/g_hexen/a_fighterplayer.cpp +++ b/src/g_hexen/a_fighterplayer.cpp @@ -105,7 +105,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FPunchAttack) int i; player_t *player; - if (NULL == (player = self->player)) + if (nullptr == (player = self->player)) { return 0; } @@ -120,7 +120,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FPunchAttack) if (pmo->weaponspecial >= 3) { pmo->weaponspecial = 0; - P_SetPsprite (player, ps_weapon, player->ReadyWeapon->FindState("Fire2")); + player->GetPSprite(ps_weapon)->SetState(player->ReadyWeapon->FindState("Fire2")); S_Sound (pmo, CHAN_VOICE, "*fistgrunt", 1, ATTN_NORM); } return 0; diff --git a/src/g_hexen/a_pig.cpp b/src/g_hexen/a_pig.cpp index b53442c14..58db7dfc6 100644 --- a/src/g_hexen/a_pig.cpp +++ b/src/g_hexen/a_pig.cpp @@ -37,9 +37,9 @@ void APigPlayer::MorphPlayerThink () } if(Vel.X == 0 && Vel.Y == 0 && pr_pigplayerthink() < 64) { // Snout sniff - if (player->ReadyWeapon != NULL) + if (player->ReadyWeapon != nullptr) { - P_SetPsprite(player, ps_weapon, player->ReadyWeapon->FindState("Grunt")); + player->GetPSprite(ps_weapon)->SetState(player->ReadyWeapon->FindState("Grunt")); } S_Sound (this, CHAN_VOICE, "PigActive1", 1, ATTN_NORM); // snort return; diff --git a/src/g_shared/a_artifacts.cpp b/src/g_shared/a_artifacts.cpp index d36cdfe65..1b48678ab 100644 --- a/src/g_shared/a_artifacts.cpp +++ b/src/g_shared/a_artifacts.cpp @@ -1109,17 +1109,17 @@ void APowerWeaponLevel2::InitEffect () Super::InitEffect(); - if (Owner->player == NULL) + if (Owner->player == nullptr) return; weapon = Owner->player->ReadyWeapon; - if (weapon == NULL) + if (weapon == nullptr) return; sister = weapon->SisterWeapon; - if (sister == NULL) + if (sister == nullptr) return; if (!(sister->WeaponFlags & WIF_POWERED_UP)) @@ -1131,7 +1131,7 @@ void APowerWeaponLevel2::InitEffect () if (weapon->GetReadyState() != sister->GetReadyState()) { - P_SetPsprite (Owner->player, ps_weapon, sister->GetReadyState()); + Owner->player->GetPSprite(ps_weapon)->SetState(sister->GetReadyState()); } } @@ -1298,22 +1298,22 @@ void APowerTargeter::InitEffect () Super::InitEffect(); - if ((player = Owner->player) == NULL) + if ((player = Owner->player) == nullptr) return; FState *state = FindState("Targeter"); - if (state != NULL) + if (state != nullptr) { - P_SetPsprite (player, ps_targetcenter, state + 0); - P_SetPsprite (player, ps_targetleft, state + 1); - P_SetPsprite (player, ps_targetright, state + 2); + player->GetPSprite(ps_targetcenter)->SetState(state + 0); + player->GetPSprite(ps_targetleft)->SetState(state + 1); + player->GetPSprite(ps_targetright)->SetState(state + 2); } - player->psprites[ps_targetcenter].sx = (160-3); - player->psprites[ps_targetcenter].sy = - player->psprites[ps_targetleft].sy = - player->psprites[ps_targetright].sy = (100-3); + player->GetPSprite(ps_targetcenter)->x = (160-3); + player->GetPSprite(ps_targetcenter)->y = + player->GetPSprite(ps_targetleft)->y = + player->GetPSprite(ps_targetright)->y = (100-3); PositionAccuracy (); } @@ -1333,7 +1333,7 @@ void APowerTargeter::DoEffect () { Super::DoEffect (); - if (Owner != NULL && Owner->player != NULL) + if (Owner != nullptr && Owner->player != nullptr) { player_t *player = Owner->player; @@ -1342,17 +1342,17 @@ void APowerTargeter::DoEffect () { FState *state = FindState("Targeter"); - if (state != NULL) + if (state != nullptr) { if (EffectTics & 32) { - P_SetPsprite (player, ps_targetright, NULL); - P_SetPsprite (player, ps_targetleft, state+1); + player->GetPSprite(ps_targetright)->SetState(nullptr); + player->GetPSprite(ps_targetleft)->SetState(state + 1); } else if (EffectTics & 16) { - P_SetPsprite (player, ps_targetright, state+2); - P_SetPsprite (player, ps_targetleft, NULL); + player->GetPSprite(ps_targetright)->SetState(state + 2); + player->GetPSprite(ps_targetleft)->SetState(nullptr); } } } @@ -1362,11 +1362,11 @@ void APowerTargeter::DoEffect () void APowerTargeter::EndEffect () { Super::EndEffect(); - if (Owner != NULL && Owner->player != NULL) + if (Owner != nullptr && Owner->player != nullptr) { - P_SetPsprite (Owner->player, ps_targetcenter, NULL); - P_SetPsprite (Owner->player, ps_targetleft, NULL); - P_SetPsprite (Owner->player, ps_targetright, NULL); + Owner->player->GetPSprite(ps_targetcenter)->SetState(nullptr); + Owner->player->GetPSprite(ps_targetleft)->SetState(nullptr); + Owner->player->GetPSprite(ps_targetright)->SetState(nullptr); } } @@ -1374,10 +1374,10 @@ void APowerTargeter::PositionAccuracy () { player_t *player = Owner->player; - if (player != NULL) + if (player != nullptr) { - player->psprites[ps_targetleft].sx = (160-3) - ((100 - player->mo->accuracy)); - player->psprites[ps_targetright].sx = (160-3)+ ((100 - player->mo->accuracy)); + player->GetPSprite(ps_targetleft)->x = (160-3) - ((100 - player->mo->accuracy)); + player->GetPSprite(ps_targetright)->x = (160-3)+ ((100 - player->mo->accuracy)); } } diff --git a/src/g_shared/a_weapons.cpp b/src/g_shared/a_weapons.cpp index adb010d0c..f561a26de 100644 --- a/src/g_shared/a_weapons.cpp +++ b/src/g_shared/a_weapons.cpp @@ -608,15 +608,18 @@ bool AWeapon::DepleteAmmo (bool altFire, bool checkEnough, int ammouse) void AWeapon::PostMorphWeapon () { - if (Owner == NULL) + DPSprite *pspr; + if (Owner == nullptr) { return; } Owner->player->PendingWeapon = WP_NOCHANGE; Owner->player->ReadyWeapon = this; - Owner->player->psprites[ps_weapon].sy = WEAPONBOTTOM; Owner->player->refire = 0; - P_SetPsprite (Owner->player, ps_weapon, GetUpState()); + + pspr = Owner->player->GetPSprite(ps_weapon); + pspr->y = WEAPONBOTTOM; + pspr->SetState(GetUpState()); } //=========================================================================== diff --git a/src/g_strife/a_strifestuff.cpp b/src/g_strife/a_strifestuff.cpp index 097965e34..98ffa0f96 100644 --- a/src/g_strife/a_strifestuff.cpp +++ b/src/g_strife/a_strifestuff.cpp @@ -350,11 +350,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_ItBurnsItBurns) S_Sound (self, CHAN_VOICE, "human/imonfire", 1, ATTN_NORM); - if (self->player != NULL && self->player->mo == self) + if (self->player != nullptr && self->player->mo == self) { - P_SetPsprite (self->player, ps_weapon, self->FindState("FireHands")); - P_SetPsprite (self->player, ps_flash, NULL); - self->player->ReadyWeapon = NULL; + self->player->GetPSprite(ps_weapon)->SetState(self->FindState("FireHands")); + self->player->GetPSprite(ps_flash)->SetState(nullptr); + self->player->ReadyWeapon = nullptr; self->player->PendingWeapon = WP_NOCHANGE; self->player->playerstate = PST_LIVE; self->player->extralight = 3; @@ -376,12 +376,13 @@ DEFINE_ACTION_FUNCTION(AActor, A_CrispyPlayer) { PARAM_ACTION_PROLOGUE; - if (self->player != NULL && self->player->mo == self) + if (self->player != nullptr && self->player->mo == self) { self->player->playerstate = PST_DEAD; - P_SetPsprite (self->player, ps_weapon, - self->player->psprites[ps_weapon].state + - (self->FindState("FireHandsLower") - self->FindState("FireHands"))); + + DPSprite *psp; + psp = self->player->GetPSprite(ps_weapon); + psp->SetState(psp->GetState() + (self->FindState("FireHandsLower") - self->FindState("FireHands"))); } return 0; } @@ -390,13 +391,13 @@ DEFINE_ACTION_FUNCTION(AActor, A_HandLower) { PARAM_ACTION_PROLOGUE; - if (self->player != NULL) + if (self->player != nullptr) { - pspdef_t *psp = &self->player->psprites[ps_weapon]; - psp->sy += 9; - if (psp->sy > WEAPONBOTTOM*2) + DPSprite *psp = self->player->GetPSprite(ps_weapon); + psp->y += 9; + if (psp->y > WEAPONBOTTOM*2) { - P_SetPsprite (self->player, ps_weapon, NULL); + psp->SetState(nullptr); } if (self->player->extralight > 0) self->player->extralight--; } diff --git a/src/g_strife/a_strifeweapons.cpp b/src/g_strife/a_strifeweapons.cpp index 96d53d431..32ae96366 100644 --- a/src/g_strife/a_strifeweapons.cpp +++ b/src/g_strife/a_strifeweapons.cpp @@ -216,10 +216,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_ClearFlash) player_t *player = self->player; - if (player == NULL) + if (player == nullptr) return 0; - P_SetPsprite (player, ps_flash, NULL); + player->GetPSprite(ps_flash)->SetState(nullptr); return 0; } @@ -233,9 +233,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_ShowElectricFlash) { PARAM_ACTION_PROLOGUE; - if (self->player != NULL) + if (self->player != nullptr) { - P_SetPsprite (self->player, ps_flash, self->player->ReadyWeapon->FindState(NAME_Flash)); + self->player->GetPSprite(ps_flash)->SetState(self->player->ReadyWeapon->FindState(NAME_Flash)); } return 0; } @@ -498,10 +498,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireMauler2Pre) S_Sound (self, CHAN_WEAPON, "weapons/mauler2charge", 1, ATTN_NORM); - if (self->player != NULL) + if (self->player != nullptr) { - self->player->psprites[ps_weapon].sx += pr_mauler2.Random2() / 64.; - self->player->psprites[ps_weapon].sy += pr_mauler2.Random2() / 64.; + self->player->GetPSprite(ps_weapon)->x += pr_mauler2.Random2() / 64.; + self->player->GetPSprite(ps_weapon)->y += pr_mauler2.Random2() / 64.; } return 0; } @@ -698,24 +698,23 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FireGrenade) DAngle an; AWeapon *weapon; - if (player == NULL || grenadetype == NULL) + if (player == nullptr || grenadetype == nullptr) return 0; - if ((weapon = player->ReadyWeapon) == NULL) + if ((weapon = player->ReadyWeapon) == nullptr) return 0; if (!weapon->DepleteAmmo (weapon->bAltFire)) return 0; - P_SetPsprite (player, ps_flash, flash); - self->player->psprites[ps_flash].processPending = true; + player->GetPSprite(ps_flash)->SetState(flash, true); - if (grenadetype != NULL) + if (grenadetype != nullptr) { self->AddZ(32); grenade = P_SpawnSubMissile (self, grenadetype, self); self->AddZ(-32); - if (grenade == NULL) + if (grenade == nullptr) return 0; if (grenade->SeeSound != 0) @@ -849,15 +848,16 @@ DEFINE_ACTION_FUNCTION(AActor, A_SelectSigilView) { PARAM_ACTION_PROLOGUE; + DPSprite *pspr; int pieces; - if (self->player == NULL) + if (self->player == nullptr) { return 0; } pieces = static_cast(self->player->ReadyWeapon)->NumPieces; - P_SetPsprite (self->player, ps_weapon, - self->player->psprites[ps_weapon].state + pieces); + pspr = self->player->GetPSprite(ps_weapon); + pspr->SetState(pspr->GetState() + pieces); return 0; } @@ -875,9 +875,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_SelectSigilDown) { PARAM_ACTION_PROLOGUE; + DPSprite *pspr; int pieces; - if (self->player == NULL) + if (self->player == nullptr) { return 0; } @@ -887,8 +888,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_SelectSigilDown) { pieces = static_cast(self->player->ReadyWeapon)->NumPieces; } - P_SetPsprite (self->player, ps_weapon, - self->player->psprites[ps_weapon].state + pieces); + pspr = self->player->GetPSprite(ps_weapon); + pspr->SetState(pspr->GetState() + pieces); return 0; } @@ -904,15 +905,16 @@ DEFINE_ACTION_FUNCTION(AActor, A_SelectSigilAttack) { PARAM_ACTION_PROLOGUE; + DPSprite *pspr; int pieces; - if (self->player == NULL) + if (self->player == nullptr) { return 0; } pieces = static_cast(self->player->ReadyWeapon)->NumPieces; - P_SetPsprite (self->player, ps_weapon, - self->player->psprites[ps_weapon].state + 4*pieces - 3); + pspr = self->player->GetPSprite(ps_weapon); + pspr->SetState(pspr->GetState() + 4*pieces - 3); return 0; } diff --git a/src/m_cheat.cpp b/src/m_cheat.cpp index ff9e2ac9a..bb9d41d55 100644 --- a/src/m_cheat.cpp +++ b/src/m_cheat.cpp @@ -314,7 +314,7 @@ void cht_DoCheat (player_t *player, int cheat) // [GRB] case CHT_RESSURECT: - if (player->playerstate != PST_LIVE && player->mo != NULL) + if (player->playerstate != PST_LIVE && player->mo != nullptr) { if (player->mo->IsKindOf(RUNTIME_CLASS(APlayerChunk))) { @@ -343,9 +343,9 @@ void cht_DoCheat (player_t *player, int cheat) player->mo->Translation = TRANSLATION(TRANSLATION_Players, BYTE(player-players)); } player->mo->DamageType = NAME_None; - if (player->ReadyWeapon != NULL) + if (player->ReadyWeapon != nullptr) { - P_SetPsprite(player, ps_weapon, player->ReadyWeapon->GetUpState()); + player->GetPSprite(ps_weapon)->SetState(player->ReadyWeapon->GetUpState()); } if (player->morphTics > 0) @@ -932,10 +932,10 @@ void cht_Take (player_t *player, const char *name, int amount) if (weapon) weapon->Destroy (); - player->ReadyWeapon = NULL; + player->ReadyWeapon = nullptr; player->PendingWeapon = WP_NOCHANGE; - player->psprites[ps_weapon].state = NULL; - player->psprites[ps_flash].state = NULL; + player->GetPSprite(ps_weapon)->SetState(nullptr); + player->GetPSprite(ps_flash)->SetState(nullptr); } } diff --git a/src/p_local.h b/src/p_local.h index 8e64c3414..14d7e9152 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -75,7 +75,6 @@ extern int bmapnegy; // P_PSPR // void P_SetupPsprites (player_t* curplayer, bool startweaponup); -void P_MovePsprites (player_t* curplayer); void P_DropWeapon (player_t* player); diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index fe049bdb4..94f8c57c3 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -997,12 +997,12 @@ void AActor::ClearInventory() invp = &inv->Inventory; } } - if (player != NULL) + if (player != nullptr) { - player->ReadyWeapon = NULL; + player->ReadyWeapon = nullptr; player->PendingWeapon = WP_NOCHANGE; - player->psprites[ps_weapon].state = NULL; - player->psprites[ps_flash].state = NULL; + player->GetPSprite(ps_weapon)->SetState(nullptr); + player->GetPSprite(ps_flash)->SetState(nullptr); } } diff --git a/src/p_pspr.cpp b/src/p_pspr.cpp index fad782b41..656ee4c38 100644 --- a/src/p_pspr.cpp +++ b/src/p_pspr.cpp @@ -93,25 +93,92 @@ static const FGenericButtons ButtonChecks[] = // CODE -------------------------------------------------------------------- +//------------------------------------------------------------------------ +// +// +// +//------------------------------------------------------------------------ + +IMPLEMENT_POINTY_CLASS(DPSprite) + DECLARE_POINTER(Caller) + DECLARE_POINTER(Next) +END_POINTERS + +//------------------------------------------------------------------------ +// +// +// +//------------------------------------------------------------------------ + +DPSprite::DPSprite(player_t *owner, AInventory *caller, int id) +: processPending(true), firstTic(true), Owner(owner), Caller(caller), ID(id) +{ + DPSprite **prev = &Owner->psprites; + while (*prev && (*prev)->ID < ID) + prev = &(*prev)->Next; + + Next = *prev; + *prev = this; + + if (Next && Next->ID == ID && ID != 0) + Next->Destroy(); // Replace it. +} + +//------------------------------------------------------------------------ +// +// +// +//------------------------------------------------------------------------ + +DPSprite *player_t::GetPSprite(psprnum_t layer) +{ + assert(layer > 0 && layer < NUMPSPRITES); + + DPSprite *weapon = nullptr; + DPSprite *pspr = psprites; + while (pspr) + { + if (pspr->ID == layer) + return pspr; + + if (pspr->ID == ps_weapon) + weapon = pspr; + + pspr = pspr->Next; + } + + pspr = new DPSprite(this, ReadyWeapon, layer); + + if (layer == ps_flash && weapon) + { + pspr->x = weapon->x; + pspr->y = weapon->y; + } + + return pspr; +} + //--------------------------------------------------------------------------- // // PROC P_NewPspriteTick // //--------------------------------------------------------------------------- -void P_NewPspriteTick() +void DPSprite::NewTick() { // This function should be called after the beginning of a tick, before any possible // prprite-event, or near the end, after any possible psprite event. // Because data is reset for every tick (which it must be) this has no impact on savegames. - for (int i = 0; iprocessPending = true; + + pspr = pspr->Next; } } } @@ -123,79 +190,85 @@ void P_NewPspriteTick() // //--------------------------------------------------------------------------- -void P_SetPsprite (player_t *player, int position, FState *state, bool nofunction) +void DPSprite::SetState(FState *newstate, bool pending) { - pspdef_t *psp; - - if (position == ps_weapon && !nofunction) + if (ID == ps_weapon) { // A_WeaponReady will re-set these as needed - player->WeaponState &= ~(WF_WEAPONREADY | WF_WEAPONREADYALT | WF_WEAPONBOBBING | WF_WEAPONSWITCHOK | WF_WEAPONRELOADOK | WF_WEAPONZOOMOK | + Owner->WeaponState &= ~(WF_WEAPONREADY | WF_WEAPONREADYALT | WF_WEAPONBOBBING | WF_WEAPONSWITCHOK | WF_WEAPONRELOADOK | WF_WEAPONZOOMOK | WF_USER1OK | WF_USER2OK | WF_USER3OK | WF_USER4OK); } - psp = &player->psprites[position]; - psp->processPending = false; // Do not subsequently perform periodic processing within the same tick. + // Special handling for the old hardcoded layers. + if (ID > 0 && ID < NUMPSPRITES) + Caller = Owner->ReadyWeapon; + + processPending = pending; do { - if (state == NULL) + if (newstate == nullptr) { // Object removed itself. - psp->state = NULL; - break; + Destroy(); + return; } - psp->state = state; + State = newstate; - if (state->sprite != SPR_FIXED) + if (newstate->sprite != SPR_FIXED) { // okay to change sprite and/or frame - if (!state->GetSameFrame()) + if (!newstate->GetSameFrame()) { // okay to change frame - psp->frame = state->GetFrame(); + Frame = newstate->GetFrame(); } - if (state->sprite != SPR_NOCHANGE) + if (newstate->sprite != SPR_NOCHANGE) { // okay to change sprite - psp->sprite = state->sprite; + Sprite = newstate->sprite; } } + Tics = newstate->GetTics(); // could be 0 - if (sv_fastweapons == 2 && position == ps_weapon) - psp->tics = state->ActionFunc == NULL ? 0 : 1; - else if (sv_fastweapons == 3) - psp->tics = (state->GetTics() != 0); - else if (sv_fastweapons) - psp->tics = 1; // great for producing decals :) - else - psp->tics = state->GetTics(); // could be 0 + if ((ID > 0 && ID < NUMPSPRITES) || Caller->IsKindOf(RUNTIME_CLASS(AWeapon))) + { // The targeter layers are affected by this too. + if (sv_fastweapons == 2 && ID == ps_weapon) + Tics = newstate->ActionFunc == nullptr ? 0 : 1; + else if (sv_fastweapons == 3) + Tics = (newstate->GetTics() != 0); + else if (sv_fastweapons) + Tics = 1; // great for producing decals :) + } - if (state->GetMisc1()) + if (newstate->GetMisc1()) { // Set coordinates. - psp->sx = state->GetMisc1(); + x = newstate->GetMisc1(); } - if (state->GetMisc2()) + if (newstate->GetMisc2()) { - psp->sy = state->GetMisc2(); + y = newstate->GetMisc2(); } - if (!nofunction && player->mo != NULL) + if (Owner->mo != nullptr) { - FState *newstate; - if (state->CallAction(player->mo, player->ReadyWeapon, &newstate)) + FState *nextstate; + if (newstate->CallAction(Owner->mo, Caller, &nextstate)) { - if (newstate != NULL) + if (nextstate != nullptr) { - state = newstate; - psp->tics = 0; + newstate = nextstate; + Tics = 0; continue; } - if (psp->state == NULL) + if (State == nullptr) { - break; + Destroy(); + return; } } } - state = psp->state->GetNextState(); - } while (!psp->tics); // An initial state of 0 could cycle through. + newstate = State->GetNextState(); + } while (!Tics); // An initial state of 0 could cycle through. + + return; } //--------------------------------------------------------------------------- @@ -211,13 +284,14 @@ void P_BringUpWeapon (player_t *player) { FState *newstate; AWeapon *weapon; + DPSprite *psweapon = player->GetPSprite(ps_weapon); if (player->PendingWeapon == WP_NOCHANGE) { - if (player->ReadyWeapon != NULL) + if (player->ReadyWeapon != nullptr) { - player->psprites[ps_weapon].sy = WEAPONTOP; - P_SetPsprite (player, ps_weapon, player->ReadyWeapon->GetReadyState()); + psweapon->y = WEAPONTOP; + psweapon->SetState(player->ReadyWeapon->GetReadyState()); } return; } @@ -226,7 +300,7 @@ void P_BringUpWeapon (player_t *player) // If the player has a tome of power, use this weapon's powered up // version, if one is available. - if (weapon != NULL && + if (weapon != nullptr && weapon->SisterWeapon && weapon->SisterWeapon->WeaponFlags & WIF_POWERED_UP && player->mo->FindInventory (RUNTIME_CLASS(APowerWeaponLevel2), true)) @@ -234,7 +308,7 @@ void P_BringUpWeapon (player_t *player) weapon = weapon->SisterWeapon; } - if (weapon != NULL) + if (weapon != nullptr) { if (weapon->UpSound) { @@ -245,20 +319,19 @@ void P_BringUpWeapon (player_t *player) } else { - newstate = NULL; + newstate = nullptr; } player->PendingWeapon = WP_NOCHANGE; player->ReadyWeapon = weapon; - player->psprites[ps_weapon].sy = player->cheats & CF_INSTANTWEAPSWITCH + psweapon->y = player->cheats & CF_INSTANTWEAPSWITCH ? WEAPONTOP : WEAPONBOTTOM; + psweapon->SetState(newstate); // make sure that the previous weapon's flash state is terminated. // When coming here from a weapon drop it may still be active. - P_SetPsprite(player, ps_flash, NULL); - P_SetPsprite (player, ps_weapon, newstate); + player->GetPSprite(ps_flash)->SetState(nullptr); player->mo->weaponspecial = 0; } - //--------------------------------------------------------------------------- // // PROC P_FireWeapon @@ -271,24 +344,24 @@ void P_FireWeapon (player_t *player, FState *state) // [SO] 9/2/02: People were able to do an awful lot of damage // when they were observers... - if (player->Bot == NULL && bot_observer) + if (player->Bot == nullptr && bot_observer) { return; } weapon = player->ReadyWeapon; - if (weapon == NULL || !weapon->CheckAmmo (AWeapon::PrimaryFire, true)) + if (weapon == nullptr || !weapon->CheckAmmo (AWeapon::PrimaryFire, true)) { return; } player->mo->PlayAttacking (); weapon->bAltFire = false; - if (state == NULL) + if (state == nullptr) { state = weapon->GetAtkState(!!player->refire); } - P_SetPsprite (player, ps_weapon, state); + player->GetPSprite(ps_weapon)->SetState(state); if (!(weapon->WeaponFlags & WIF_NOALERT)) { P_NoiseAlert (player->mo, player->mo, false); @@ -307,13 +380,13 @@ void P_FireWeaponAlt (player_t *player, FState *state) // [SO] 9/2/02: People were able to do an awful lot of damage // when they were observers... - if (player->Bot == NULL && bot_observer) + if (player->Bot == nullptr && bot_observer) { return; } weapon = player->ReadyWeapon; - if (weapon == NULL || weapon->FindState(NAME_AltFire) == NULL || !weapon->CheckAmmo (AWeapon::AltFire, true)) + if (weapon == nullptr || weapon->FindState(NAME_AltFire) == nullptr || !weapon->CheckAmmo (AWeapon::AltFire, true)) { return; } @@ -321,12 +394,12 @@ void P_FireWeaponAlt (player_t *player, FState *state) player->mo->PlayAttacking (); weapon->bAltFire = true; - if (state == NULL) + if (state == nullptr) { state = weapon->GetAltAtkState(!!player->refire); } - P_SetPsprite (player, ps_weapon, state); + player->GetPSprite(ps_weapon)->SetState(state); if (!(weapon->WeaponFlags & WIF_NOALERT)) { P_NoiseAlert (player->mo, player->mo, false); @@ -343,15 +416,15 @@ void P_FireWeaponAlt (player_t *player, FState *state) void P_DropWeapon (player_t *player) { - if (player == NULL) + if (player == nullptr) { return; } // Since the weapon is dropping, stop blocking switching. player->WeaponState &= ~WF_DISABLESWITCH; - if (player->ReadyWeapon != NULL) + if (player->ReadyWeapon != nullptr) { - P_SetPsprite (player, ps_weapon, player->ReadyWeapon->GetDownState()); + player->GetPSprite(ps_weapon)->SetState(player->ReadyWeapon->GetDownState()); } } @@ -367,7 +440,7 @@ void P_DropWeapon (player_t *player) // //============================================================================ -void P_BobWeapon (player_t *player, pspdef_t *psp, float *x, float *y, double ticfrac) +void P_BobWeapon (player_t *player, float *x, float *y, double ticfrac) { static float curbob; double xx[2], yy[2]; @@ -377,7 +450,7 @@ void P_BobWeapon (player_t *player, pspdef_t *psp, float *x, float *y, double ti weapon = player->ReadyWeapon; - if (weapon == NULL || weapon->WeaponFlags & WIF_DONTBOB) + if (weapon == nullptr || weapon->WeaponFlags & WIF_DONTBOB) { *x = *y = 0; return; @@ -528,7 +601,7 @@ void DoReadyWeaponToFire (AActor *self, bool prim, bool alt) } // Play ready sound, if any. - if (weapon->ReadySound && player->psprites[ps_weapon].state == weapon->FindState(NAME_Ready)) + if (weapon->ReadySound && player->GetPSprite(ps_weapon)->GetState() == weapon->FindState(NAME_Ready)) { if (!(weapon->WeaponFlags & WIF_READYSNDHALF) || pr_wpnreadysnd() < 128) { @@ -547,8 +620,8 @@ void DoReadyWeaponToBob (AActor *self) { // Prepare for bobbing action. self->player->WeaponState |= WF_WEAPONBOBBING; - self->player->psprites[ps_weapon].sx = 0; - self->player->psprites[ps_weapon].sy = WEAPONTOP; + self->player->GetPSprite(ps_weapon)->x = 0; + self->player->GetPSprite(ps_weapon)->y = WEAPONTOP; } } @@ -673,12 +746,12 @@ void P_CheckWeaponSwitch (player_t *player) static void P_CheckWeaponButtons (player_t *player) { - if (player->Bot == NULL && bot_observer) + if (player->Bot == nullptr && bot_observer) { return; } AWeapon *weapon = player->ReadyWeapon; - if (weapon == NULL) + if (weapon == nullptr) { return; } @@ -693,11 +766,11 @@ static void P_CheckWeaponButtons (player_t *player) // [XA] don't change state if still null, so if the modder // sets WRF_xxx to true but forgets to define the corresponding // state, the weapon won't disappear. ;) - if (state != NULL) + if (state != nullptr) { - P_SetPsprite(player, ps_weapon, state); + player->GetPSprite(ps_weapon)->SetState(state); return; - } + } } } } @@ -808,31 +881,31 @@ DEFINE_ACTION_FUNCTION(AInventory, A_WeaponOffset) } player_t *player = self->player; - pspdef_t *psp; + DPSprite *psp; if (player && (player->playerstate != PST_DEAD)) { - psp = &player->psprites[ps_weapon]; + psp = player->GetPSprite(ps_weapon); if (!(flags & WOF_KEEPX)) { if (flags & WOF_ADD) { - psp->sx += wx; + psp->x += wx; } else { - psp->sx = wx; + psp->x = wx; } } if (!(flags & WOF_KEEPY)) { if (flags & WOF_ADD) { - psp->sy += wy; + psp->y += wy; } else { - psp->sy = wy; + psp->y = wy; } } } @@ -851,35 +924,35 @@ DEFINE_ACTION_FUNCTION(AInventory, A_Lower) PARAM_ACTION_PROLOGUE; player_t *player = self->player; - pspdef_t *psp; + DPSprite *psp; - if (NULL == player) + if (nullptr == player) { return 0; } - psp = &player->psprites[ps_weapon]; + psp = player->GetPSprite(ps_weapon); if (player->morphTics || player->cheats & CF_INSTANTWEAPSWITCH) { - psp->sy = WEAPONBOTTOM; + psp->y = WEAPONBOTTOM; } else { - psp->sy += LOWERSPEED; + psp->y += LOWERSPEED; } - if (psp->sy < WEAPONBOTTOM) + if (psp->y < WEAPONBOTTOM) { // Not lowered all the way yet return 0; } if (player->playerstate == PST_DEAD) { // Player is dead, so don't bring up a pending weapon - psp->sy = WEAPONBOTTOM; + psp->y = WEAPONBOTTOM; // Player is dead, so keep the weapon off screen - P_SetPsprite (player, ps_weapon, NULL); + psp->SetState(nullptr); return 0; } // [RH] Clear the flash state. Only needed for Strife. - P_SetPsprite (player, ps_flash, NULL); + player->GetPSprite(ps_flash)->SetState(nullptr); P_BringUpWeapon (player); return 0; } @@ -894,14 +967,14 @@ DEFINE_ACTION_FUNCTION(AInventory, A_Raise) { PARAM_ACTION_PROLOGUE; - if (self == NULL) + if (self == nullptr) { return 0; } player_t *player = self->player; - pspdef_t *psp; + DPSprite *psp; - if (NULL == player) + if (nullptr == player) { return 0; } @@ -910,20 +983,20 @@ DEFINE_ACTION_FUNCTION(AInventory, A_Raise) P_DropWeapon(player); return 0; } - psp = &player->psprites[ps_weapon]; - psp->sy -= RAISESPEED; - if (psp->sy > WEAPONTOP) + psp = player->GetPSprite(ps_weapon); + psp->y -= RAISESPEED; + if (psp->y > WEAPONTOP) { // Not raised all the way yet return 0; } - psp->sy = WEAPONTOP; - if (player->ReadyWeapon != NULL) + psp->y = WEAPONTOP; + if (player->ReadyWeapon != nullptr) { - P_SetPsprite (player, ps_weapon, player->ReadyWeapon->GetReadyState()); + psp->SetState(player->ReadyWeapon->GetReadyState()); } else { - player->psprites[ps_weapon].state = NULL; + psp->SetState(nullptr); } return 0; } @@ -942,12 +1015,12 @@ enum GF_Flags DEFINE_ACTION_FUNCTION_PARAMS(AInventory, A_GunFlash) { PARAM_ACTION_PROLOGUE; - PARAM_STATE_OPT(flash) { flash = NULL; } + PARAM_STATE_OPT(flash) { flash = nullptr; } PARAM_INT_OPT (flags) { flags = 0; } player_t *player = self->player; - if (NULL == player) + if (nullptr == player) { return 0; } @@ -955,18 +1028,18 @@ DEFINE_ACTION_FUNCTION_PARAMS(AInventory, A_GunFlash) { player->mo->PlayAttacking2 (); } - if (flash == NULL) + if (flash == nullptr) { if (player->ReadyWeapon->bAltFire) { flash = player->ReadyWeapon->FindState(NAME_AltFlash); } - if (flash == NULL) + if (flash == nullptr) { flash = player->ReadyWeapon->FindState(NAME_Flash); } } - P_SetPsprite (player, ps_flash, flash); + player->GetPSprite(ps_flash)->SetState(flash); return 0; } @@ -1084,13 +1157,9 @@ DEFINE_ACTION_FUNCTION_PARAMS(AInventory, A_Light) void P_SetupPsprites(player_t *player, bool startweaponup) { - int i; - // Remove all psprites - for (i = 0; i < NUMPSPRITES; i++) - { - player->psprites[i].state = NULL; - } + player->DestroyPSprites(); + // Spawn the ready weapon player->PendingWeapon = !startweaponup ? player->ReadyWeapon : WP_NOCHANGE; P_BringUpWeapon (player); @@ -1104,61 +1173,167 @@ void P_SetupPsprites(player_t *player, bool startweaponup) // //------------------------------------------------------------------------ -void P_MovePsprites (player_t *player) +void player_t::TickPSprites() { - int i; - pspdef_t *psp; - FState *state; + DPSprite *weapon = nullptr; + DPSprite *flash = nullptr; + bool noweapon = (ReadyWeapon == nullptr && (health > 0 || mo->DamageType != NAME_Fire)); - // [RH] If you don't have a weapon, then the psprites should be NULL. - if (player->ReadyWeapon == NULL && (player->health > 0 || player->mo->DamageType != NAME_Fire)) + DPSprite *pspr = psprites; + while (pspr) { - P_SetPsprite (player, ps_weapon, NULL); - P_SetPsprite (player, ps_flash, NULL); - if (player->PendingWeapon != WP_NOCHANGE) + // Destroy the psprite if it's from a weapon that isn't currently selected by the player + // or if it's from an inventory item that the player no longer owns. + // (except for the old hardcoded layers) + if (!(pspr->ID > 0 && pspr->ID < NUMPSPRITES) && + (pspr->Caller == nullptr || + (pspr->Caller->IsKindOf(RUNTIME_CLASS(AWeapon)) && pspr->Caller != pspr->Owner->ReadyWeapon) || + (pspr->Caller->Owner != pspr->Owner->mo))) { - P_BringUpWeapon (player); + pspr->Destroy(); } + else if (!(pspr->ID > 0 && pspr->ID < NUMPSPRITES && noweapon)) + { + pspr->Tick(); + } + + if (pspr->ID == ps_weapon) + weapon = pspr; + else if (pspr->ID == ps_flash) + flash = pspr; + + pspr = pspr->Next; + } + + if (noweapon) + { + if (weapon) weapon->SetState(nullptr); + if (flash) flash->SetState(nullptr); + if (PendingWeapon != WP_NOCHANGE) + P_BringUpWeapon(this); } else { - psp = &player->psprites[0]; - for (i = 0; i < NUMPSPRITES; i++, psp++) + if (weapon && flash) { - if ((state = psp->state) != NULL && psp->processPending) // a null state means not active - { - // drop tic count and possibly change state - if (psp->tics != -1) // a -1 tic count never changes - { - psp->tics--; - - // [BC] Apply double firing speed. - if ( psp->tics && (player->cheats & CF_DOUBLEFIRINGSPEED)) - psp->tics--; - - if(!psp->tics) - { - P_SetPsprite (player, i, psp->state->GetNextState()); - } - } - } + flash->x = weapon->x; + flash->y = weapon->y; } - player->psprites[ps_flash].sx = player->psprites[ps_weapon].sx; - player->psprites[ps_flash].sy = player->psprites[ps_weapon].sy; - P_CheckWeaponSwitch (player); - if (player->WeaponState & (WF_WEAPONREADY | WF_WEAPONREADYALT)) + P_CheckWeaponSwitch(this); + if (WeaponState & (WF_WEAPONREADY | WF_WEAPONREADYALT)) { - P_CheckWeaponFire (player); + P_CheckWeaponFire(this); } - // Check custom buttons - P_CheckWeaponButtons(player); - } + P_CheckWeaponButtons(this); + } } -FArchive &operator<< (FArchive &arc, pspdef_t &def) +//------------------------------------------------------------------------ +// +// +// +//------------------------------------------------------------------------ + +void DPSprite::Tick() { - arc << def.state << def.tics << def.sx << def.sy - << def.sprite << def.frame; - return arc; + oldx = x; + oldy = y; + + if (processPending) + { + // drop tic count and possibly change state + if (Tics != -1) // a -1 tic count never changes + { + Tics--; + + // [BC] Apply double firing speed. + // This is applied to the targeter layers too. + if (((ID > 0 && ID < NUMPSPRITES) || (Caller->IsKindOf(RUNTIME_CLASS(AWeapon)))) && + (Tics && Owner->cheats & CF_DOUBLEFIRINGSPEED)) + Tics--; + + if (!Tics) + SetState(State->GetNextState()); + } + } +} + +//------------------------------------------------------------------------ +// +// +// +//------------------------------------------------------------------------ + +void DPSprite::Serialize(FArchive &arc) +{ + Super::Serialize(arc); + + arc << Next << Caller << Owner + << State << Tics << Sprite << Frame + << ID << x << y << oldx << oldy; +} + +//------------------------------------------------------------------------ +// +// +// +//------------------------------------------------------------------------ + +void player_t::DestroyPSprites() +{ + DPSprite *pspr = psprites; + while (pspr) + { + pspr->Destroy(); + pspr = pspr->Next; + } +} + +//------------------------------------------------------------------------ +// +// +// +//------------------------------------------------------------------------ + +void DPSprite::Destroy() +{ + DPSprite **prev = &Owner->psprites; + while (*prev != this) + prev = &(*prev)->Next; + + *prev = Next; + + Super::Destroy(); +} + +//------------------------------------------------------------------------ +// +// +// +//------------------------------------------------------------------------ + +ADD_STAT(psprites) +{ + FString out; + DPSprite *pspr; + for (int i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i]) + continue; + + out.AppendFormat("[psprites] player: %d | layers: ", i); + + pspr = players[i].psprites; + while (pspr) + { + out.AppendFormat("%d, ", pspr->GetID()); + + pspr = pspr->GetNext(); + } + + out.AppendFormat("\n"); + } + + return out; } diff --git a/src/p_pspr.h b/src/p_pspr.h index 397ac4fff..87e78ef1f 100644 --- a/src/p_pspr.h +++ b/src/p_pspr.h @@ -34,59 +34,72 @@ // the right spot at 320x200. #define WEAPONTOP (32+6./16) +class AInventory; +class FArchive; // // Overlay psprites are scaled shapes // drawn directly on the view screen, // coordinates are given for a 320*200 view screen. // -typedef enum +enum psprnum_t // These are all called by the owner's ReadyWeapon. { - ps_weapon, + ps_weapon = 1, ps_flash, ps_targetcenter, ps_targetleft, ps_targetright, NUMPSPRITES - -} psprnum_t; - -/* -inline FArchive &operator<< (FArchive &arc, psprnum_t &i) -{ - BYTE val = (BYTE)i; - arc << val; - i = (psprnum_t)val; - return arc; -} -*/ - -struct pspdef_t -{ - FState* state; // a NULL state means not active - int tics; - double sx; - double sy; - int sprite; - int frame; - bool processPending; // true: waiting for periodic processing on this tick }; -class FArchive; +class DPSprite : public DObject +{ + DECLARE_CLASS (DPSprite, DObject) + HAS_OBJECT_POINTERS +public: + DPSprite(player_t *owner, AInventory *caller, int id); -FArchive &operator<< (FArchive &, pspdef_t &); + static void NewTick(); + void SetState(FState *newstate, bool pending = false); -class player_t; -class AActor; -struct FState; + int GetID() const { return ID; } + int GetSprite() const { return Sprite; } + int GetFrame() const { return Frame; } + FState* GetState() const { return State; } + DPSprite* GetNext() const { return Next; } + TObjPtr GetCaller() const { return Caller; } + + double x, y; + double oldx, oldy; + bool firstTic; + int Tics; + +private: + DPSprite () {} + + void Serialize(FArchive &arc); + void Tick(); + void Destroy(); + + TObjPtr Caller; + DPSprite *Next; + player_t *Owner; + FState *State; + int Sprite; + int Frame; + int ID; + bool processPending; // true: waiting for periodic processing on this tick + + friend class player_t; + friend void CopyPlayer(player_t *dst, player_t *src, const char *name); +}; void P_NewPspriteTick(); -void P_SetPsprite (player_t *player, int position, FState *state, bool nofunction=false); void P_CalcSwing (player_t *player); void P_BringUpWeapon (player_t *player); void P_FireWeapon (player_t *player); void P_DropWeapon (player_t *player); -void P_BobWeapon (player_t *player, pspdef_t *psp, float *x, float *y, double ticfrac); +void P_BobWeapon (player_t *player, float *x, float *y, double ticfrac); DAngle P_BulletSlope (AActor *mo, FTranslatedLineTarget *pLineTarget = NULL, int aimflags = 0); void P_GunShot (AActor *mo, bool accurate, PClassActor *pufftype, DAngle pitch); diff --git a/src/p_saveg.cpp b/src/p_saveg.cpp index af5992488..049673abd 100644 --- a/src/p_saveg.cpp +++ b/src/p_saveg.cpp @@ -274,7 +274,7 @@ static void CopyPlayer (player_t *dst, player_t *src, const char *name) dst->cheats |= chasecam; - if (dst->Bot != NULL) + if (dst->Bot != nullptr) { botinfo_t *thebot = bglobal.botinfo; while (thebot && stricmp (name, thebot->name)) @@ -296,10 +296,23 @@ static void CopyPlayer (player_t *dst, player_t *src, const char *name) dst->userinfo.SkinNumChanged(R_FindSkin(skins[dst->userinfo.GetSkin()].name, dst->CurrentPlayerClass)); // Make sure the player pawn points to the proper player struct. - if (dst->mo != NULL) + if (dst->mo != nullptr) { dst->mo->player = dst; } + + // Same for the psprites. + DPSprite *pspr = dst->psprites; + while (pspr) + { + pspr->Owner = dst; + + pspr = pspr->Next; + } + + // Don't let the psprites be destroyed when src is destroyed. + src->psprites = nullptr; + // These 2 variables may not be overwritten. dst->attackdown = attackdown; dst->usedown = usedown; diff --git a/src/p_tick.cpp b/src/p_tick.cpp index 032aa8bf5..e3704d3ff 100644 --- a/src/p_tick.cpp +++ b/src/p_tick.cpp @@ -87,7 +87,7 @@ void P_Ticker (void) if (paused || P_CheckTickerPaused()) return; - P_NewPspriteTick(); + DPSprite::NewTick(); // [RH] Frozen mode is only changed every 4 tics, to make it work with A_Tracer(). if ((level.time & 3) == 0) diff --git a/src/p_user.cpp b/src/p_user.cpp index 486044070..353c35309 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -270,6 +270,7 @@ player_t::player_t() WeaponState(0), ReadyWeapon(0), PendingWeapon(0), + psprites(0), cheats(0), timefreezer(0), refire(0), @@ -315,7 +316,11 @@ player_t::player_t() { memset (&cmd, 0, sizeof(cmd)); memset (frags, 0, sizeof(frags)); - memset (psprites, 0, sizeof(psprites)); +} + +player_t::~player_t() +{ + DestroyPSprites(); } player_t &player_t::operator=(const player_t &p) @@ -371,7 +376,7 @@ player_t &player_t::operator=(const player_t &p) extralight = p.extralight; fixedcolormap = p.fixedcolormap; fixedlightlevel = p.fixedlightlevel; - memcpy(psprites, &p.psprites, sizeof(psprites)); + psprites = p.psprites; morphTics = p.morphTics; MorphedPlayerClass = p.MorphedPlayerClass; MorphStyle = p.MorphStyle; @@ -433,6 +438,7 @@ size_t player_t::FixPointers (const DObject *old, DObject *rep) if (ReadyWeapon == old) ReadyWeapon = static_cast(rep), changed++; if (PendingWeapon == old) PendingWeapon = static_cast(rep), changed++; if (*&PremorphWeapon == old) PremorphWeapon = static_cast(rep), changed++; + if (psprites == old) psprites = static_cast(rep), changed++; if (*&ConversationNPC == old) ConversationNPC = replacement, changed++; if (*&ConversationPC == old) ConversationPC = replacement, changed++; if (*&MUSINFOactor == old) MUSINFOactor = replacement, changed++; @@ -451,6 +457,7 @@ size_t player_t::PropagateMark() GC::Mark(ConversationPC); GC::Mark(MUSINFOactor); GC::Mark(PremorphWeapon); + GC::Mark(psprites); if (PendingWeapon != WP_NOCHANGE) { GC::Mark(PendingWeapon); @@ -1369,35 +1376,36 @@ void APlayerPawn::MorphPlayerThink () void APlayerPawn::ActivateMorphWeapon () { PClassActor *morphweapon = PClass::FindActor (MorphWeapon); + DPSprite *pspr = player->GetPSprite(ps_weapon); player->PendingWeapon = WP_NOCHANGE; - player->psprites[ps_weapon].sy = WEAPONTOP; + pspr->y = WEAPONTOP; - if (morphweapon == NULL || !morphweapon->IsDescendantOf (RUNTIME_CLASS(AWeapon))) + if (morphweapon == nullptr || !morphweapon->IsDescendantOf (RUNTIME_CLASS(AWeapon))) { // No weapon at all while morphed! - player->ReadyWeapon = NULL; - P_SetPsprite (player, ps_weapon, NULL); + player->ReadyWeapon = nullptr; + pspr->SetState(nullptr); } else { player->ReadyWeapon = static_cast(player->mo->FindInventory (morphweapon)); - if (player->ReadyWeapon == NULL) + if (player->ReadyWeapon == nullptr) { player->ReadyWeapon = static_cast(player->mo->GiveInventoryType (morphweapon)); - if (player->ReadyWeapon != NULL) + if (player->ReadyWeapon != nullptr) { player->ReadyWeapon->GivenAsMorphWeapon = true; // flag is used only by new beastweap semantics in P_UndoPlayerMorph } } - if (player->ReadyWeapon != NULL) + if (player->ReadyWeapon != nullptr) { - P_SetPsprite (player, ps_weapon, player->ReadyWeapon->GetReadyState()); + pspr->SetState(player->ReadyWeapon->GetReadyState()); } else { - P_SetPsprite (player, ps_weapon, NULL); + pspr->SetState(nullptr); } } - P_SetPsprite (player, ps_flash, NULL); + player->GetPSprite(ps_flash)->SetState(nullptr); player->PendingWeapon = WP_NOCHANGE; } @@ -2114,7 +2122,7 @@ void P_DeathThink (player_t *player) int dir; DAngle delta; - P_MovePsprites (player); + player->TickPSprites(); player->onground = (player->mo->Z() <= player->mo->floorz); if (player->mo->IsKindOf (RUNTIME_CLASS(APlayerChunk))) @@ -2634,7 +2642,7 @@ void P_PlayerThink (player_t *player) } } // Cycle psprites - P_MovePsprites (player); + player->TickPSprites(); // Other Counters if (player->damagecount) @@ -3064,8 +3072,37 @@ void player_t::Serialize (FArchive &arc) for (i = 0; i < MAXPLAYERS; i++) arc << frags[i]; - for (i = 0; i < NUMPSPRITES; i++) - arc << psprites[i]; + + if (SaveVersion < 4547) + { + for (i = ps_weapon; i < NUMPSPRITES; i++) + { + FState *state; + int tics; + double sx, sy; + int sprite; + int frame; + + arc << state << tics + << sx << sy + << sprite << frame; + + if (state != nullptr) + { + DPSprite *pspr; + pspr = GetPSprite(psprnum_t(i)); + pspr->State = state; + pspr->Tics = tics; + pspr->x = sx; + pspr->y = sy; + pspr->Sprite = sprite; + pspr->Frame = frame; + pspr->Owner = this; + } + } + } + else + arc << psprites; arc << CurrentPlayerClass; diff --git a/src/r_things.cpp b/src/r_things.cpp index 427e61b06..704b6509c 100644 --- a/src/r_things.cpp +++ b/src/r_things.cpp @@ -92,6 +92,7 @@ extern double globaluclip, globaldclip; extern float MaskedScaleY; #define MINZ double((2048*4) / double(1 << 20)) +#define BASEXCENTER (160) #define BASEYCENTER (100) EXTERN_CVAR (Bool, st_scale) @@ -111,9 +112,15 @@ double pspriteyscale; fixed_t sky1scale; // [RH] Sky 1 scale factor fixed_t sky2scale; // [RH] Sky 2 scale factor -vissprite_t *VisPSprites[NUMPSPRITES]; -int VisPSpritesX1[NUMPSPRITES]; -FDynamicColormap *VisPSpritesBaseColormap[NUMPSPRITES]; +// Used to store a psprite's drawing information if it needs to be drawn later. +struct vispsp_t +{ + vissprite_t *vis; + FDynamicColormap *basecolormap; + int x1; +}; +TArray vispsprites; +unsigned int vispspindex; static int spriteshade; @@ -1269,48 +1276,41 @@ void R_AddSprites (sector_t *sec, int lightlevel, int fakeside) } } - // // R_DrawPSprite // -void R_DrawPSprite (pspdef_t* psp, int pspnum, AActor *owner, double sx, double sy) +void R_DrawPSprite(DPSprite *pspr, AActor *owner, double ofsx, double ofsy, double ticfrac) { double tx; int x1; int x2; + double sx, sy; spritedef_t* sprdef; spriteframe_t* sprframe; FTextureID picnum; WORD flip; FTexture* tex; vissprite_t* vis; - static vissprite_t avis[NUMPSPRITES + 1]; - static vissprite_t *avisp[countof(avis)]; - bool noaccel; + bool noaccel; + bool isweapon; + static TArray avis; - assert(pspnum >= 0 && pspnum < NUMPSPRITES); - - if (avisp[0] == NULL) - { - for (unsigned i = 0; i < countof(avis); ++i) - { - avisp[i] = &avis[i]; - } - } + if (avis.Size() < vispspindex + 1) + avis.Reserve(avis.Size() - vispspindex + 1); // decide which patch to use - if ( (unsigned)psp->sprite >= (unsigned)sprites.Size ()) + if ((unsigned)pspr->GetSprite() >= (unsigned)sprites.Size()) { - DPrintf ("R_DrawPSprite: invalid sprite number %i\n", psp->sprite); + DPrintf("R_DrawPSprite: invalid sprite number %i\n", pspr->GetSprite()); return; } - sprdef = &sprites[psp->sprite]; - if (psp->frame >= sprdef->numframes) + sprdef = &sprites[pspr->GetSprite()]; + if (pspr->GetFrame() >= sprdef->numframes) { - DPrintf ("R_DrawPSprite: invalid sprite frame %i : %i\n", psp->sprite, psp->frame); + DPrintf("R_DrawPSprite: invalid sprite frame %i : %i\n", pspr->GetSprite(), pspr->GetFrame()); return; } - sprframe = &SpriteFrames[sprdef->spriteframes + psp->frame]; + sprframe = &SpriteFrames[sprdef->spriteframes + pspr->GetFrame()]; picnum = sprframe->Texture[0]; flip = sprframe->Flip & 1; @@ -1319,15 +1319,33 @@ void R_DrawPSprite (pspdef_t* psp, int pspnum, AActor *owner, double sx, double if (tex->UseType == FTexture::TEX_Null) return; + isweapon = ((pspr->GetID() > 0 && pspr->GetID() < ps_targetcenter) || + (pspr->GetID() >= NUMPSPRITES && pspr->GetCaller() && pspr->GetCaller()->IsKindOf(RUNTIME_CLASS(AWeapon)))); + + if (pspr->firstTic) + { // Can't interpolate the first tic. + pspr->firstTic = false; + pspr->oldx = pspr->x; + pspr->oldy = pspr->y; + } + + sx = pspr->oldx + (pspr->x - pspr->oldx) * ticfrac; + sy = pspr->oldy + (pspr->y - pspr->oldy) * ticfrac; + if (isweapon) + { // [RH] Don't bob the targeter/non-weapon layers. + sx += ofsx; + sy += ofsy; + } + // calculate edges of the shape - tx = sx - (320 / 2); + tx = sx - BASEXCENTER; tx -= tex->GetScaledLeftOffset(); x1 = xs_RoundToInt(CenterX + tx * pspritexscale); // off the right side if (x1 > viewwidth) - return; + return; tx += tex->GetScaledWidth(); x2 = xs_RoundToInt(CenterX + tx * pspritexscale); @@ -1335,9 +1353,9 @@ void R_DrawPSprite (pspdef_t* psp, int pspnum, AActor *owner, double sx, double // off the left side if (x2 <= 0) return; - + // store information in a vissprite - vis = avisp[NUMPSPRITES]; + vis = &avis[vispspindex]; vis->renderflags = owner->renderflags; vis->floorclip = 0; @@ -1345,14 +1363,14 @@ void R_DrawPSprite (pspdef_t* psp, int pspnum, AActor *owner, double sx, double if (camera->player && (RenderTarget != screen || viewheight == RenderTarget->GetHeight() || - (RenderTarget->GetWidth() > 320 && !st_scale))) + (RenderTarget->GetWidth() > (BASEXCENTER * 2) && !st_scale))) { // Adjust PSprite for fullscreen views - AWeapon *weapon = NULL; - if (camera->player != NULL) + AWeapon *weapon = nullptr; + if (camera->player != nullptr) { weapon = camera->player->ReadyWeapon; } - if (pspnum <= ps_flash && weapon != NULL && weapon->YAdjust != 0) + if (isweapon && weapon != nullptr && weapon->YAdjust != 0) { if (RenderTarget != screen || viewheight == RenderTarget->GetHeight()) { @@ -1360,11 +1378,11 @@ void R_DrawPSprite (pspdef_t* psp, int pspnum, AActor *owner, double sx, double } else { - vis->texturemid -= StatusBar->GetDisplacement () * weapon->YAdjust; + vis->texturemid -= StatusBar->GetDisplacement() * weapon->YAdjust; } } } - if (pspnum <= ps_flash) + if (isweapon) { // Move the weapon down for 1280x1024. vis->texturemid -= BaseRatioSizes[WidescreenRatio][2]; } @@ -1388,11 +1406,11 @@ void R_DrawPSprite (pspdef_t* psp, int pspnum, AActor *owner, double sx, double } if (vis->x1 > x1) - vis->startfrac += vis->xiscale*(vis->x1-x1); + vis->startfrac += vis->xiscale*(vis->x1 - x1); noaccel = false; - FDynamicColormap *colormap_to_use = NULL; - if (pspnum <= ps_flash) + FDynamicColormap *colormap_to_use = nullptr; + if (isweapon) { vis->Style.Alpha = float(owner->Alpha); vis->Style.RenderStyle = owner->RenderStyle; @@ -1413,16 +1431,16 @@ void R_DrawPSprite (pspdef_t* psp, int pspnum, AActor *owner, double sx, double { if (invertcolormap) { // Fade to white - mybasecolormap = GetSpecialLights(mybasecolormap->Color, MAKERGB(255,255,255), mybasecolormap->Desaturate); + mybasecolormap = GetSpecialLights(mybasecolormap->Color, MAKERGB(255, 255, 255), mybasecolormap->Desaturate); invertcolormap = false; } else { // Fade to black - mybasecolormap = GetSpecialLights(mybasecolormap->Color, MAKERGB(0,0,0), mybasecolormap->Desaturate); + mybasecolormap = GetSpecialLights(mybasecolormap->Color, MAKERGB(0, 0, 0), mybasecolormap->Desaturate); } } - if (realfixedcolormap != NULL) + if (realfixedcolormap != nullptr) { // fixed color vis->Style.colormap = realfixedcolormap->Colormap; } @@ -1436,25 +1454,25 @@ void R_DrawPSprite (pspdef_t* psp, int pspnum, AActor *owner, double sx, double { vis->Style.colormap = mybasecolormap->Maps + fixedlightlev; } - else if (!foggy && psp->state->GetFullbright()) + else if (!foggy && pspr->GetState()->GetFullbright()) { // full bright vis->Style.colormap = mybasecolormap->Maps; // [RH] use basecolormap } else { // local light - vis->Style.colormap = mybasecolormap->Maps + (GETPALOOKUP (0, spriteshade) << COLORMAPSHIFT); + vis->Style.colormap = mybasecolormap->Maps + (GETPALOOKUP(0, spriteshade) << COLORMAPSHIFT); } } - if (camera->Inventory != NULL) + if (camera->Inventory != nullptr) { lighttable_t *oldcolormap = vis->Style.colormap; - camera->Inventory->AlterWeaponSprite (&vis->Style); + camera->Inventory->AlterWeaponSprite(&vis->Style); if (vis->Style.colormap != oldcolormap) { // The colormap has changed. Is it one we can easily identify? // If not, then don't bother trying to identify it for // hardware accelerated drawing. - if (vis->Style.colormap < SpecialColormaps[0].Colormap || + if (vis->Style.colormap < SpecialColormaps[0].Colormap || vis->Style.colormap > SpecialColormaps.Last().Colormap) { noaccel = true; @@ -1462,7 +1480,7 @@ void R_DrawPSprite (pspdef_t* psp, int pspnum, AActor *owner, double sx, double // Has the basecolormap changed? If so, we can't hardware accelerate it, // since we don't know what it is anymore. else if (vis->Style.colormap < mybasecolormap->Maps || - vis->Style.colormap >= mybasecolormap->Maps + NUMCOLORMAPS*256) + vis->Style.colormap >= mybasecolormap->Maps + NUMCOLORMAPS * 256) { noaccel = true; } @@ -1482,7 +1500,7 @@ void R_DrawPSprite (pspdef_t* psp, int pspnum, AActor *owner, double sx, double } // If the main colormap has fixed lights, and this sprite is being drawn with that // colormap, disable acceleration so that the lights can remain fixed. - if (!noaccel && realfixedcolormap == NULL && + if (!noaccel && realfixedcolormap == nullptr && NormalLightHasFixedLights && mybasecolormap == &NormalLight && vis->pic->UseBasePalette()) { @@ -1505,18 +1523,19 @@ void R_DrawPSprite (pspdef_t* psp, int pspnum, AActor *owner, double sx, double style.CheckFuzz(); if (style.BlendOp != STYLEOP_Fuzz) { - VisPSpritesX1[pspnum] = x1; - VisPSpritesBaseColormap[pspnum] = colormap_to_use; - VisPSprites[pspnum] = vis; - swapvalues(avisp[pspnum], avisp[NUMPSPRITES]); + if (vispsprites.Size() < vispspindex + 1) + vispsprites.Reserve(vispsprites.Size() - vispspindex + 1); + + vispsprites[vispspindex].vis = vis; + vispsprites[vispspindex].basecolormap = colormap_to_use; + vispsprites[vispspindex].x1 = x1; + vispspindex++; return; } } - R_DrawVisSprite (vis); + R_DrawVisSprite(vis); } - - //========================================================================== // // R_DrawPlayerSprites @@ -1527,7 +1546,7 @@ void R_DrawPlayerSprites () { int i; int lightnum; - pspdef_t* psp; + DPSprite* psp; sector_t* sec = NULL; static sector_t tempsec; int floorlight, ceilinglight; @@ -1540,28 +1559,35 @@ void R_DrawPlayerSprites () (r_deathcamera && camera->health <= 0)) return; - if(fixedlightlev < 0 && viewsector->e && viewsector->e->XFloor.lightlist.Size()) { - for(i = viewsector->e->XFloor.lightlist.Size() - 1; i >= 0; i--) - if(ViewPos.Z <= viewsector->e->XFloor.lightlist[i].plane.Zat0()) { + if (fixedlightlev < 0 && viewsector->e && viewsector->e->XFloor.lightlist.Size()) + { + for (i = viewsector->e->XFloor.lightlist.Size() - 1; i >= 0; i--) + { + if (ViewPos.Z <= viewsector->e->XFloor.lightlist[i].plane.Zat0()) + { rover = viewsector->e->XFloor.lightlist[i].caster; - if(rover) { - if(rover->flags & FF_DOUBLESHADOW && ViewPos.Z <= rover->bottom.plane->Zat0()) + if (rover) + { + if (rover->flags & FF_DOUBLESHADOW && ViewPos.Z <= rover->bottom.plane->Zat0()) break; sec = rover->model; - if(rover->flags & FF_FADEWALLS) + if (rover->flags & FF_FADEWALLS) basecolormap = sec->ColorMap; else basecolormap = viewsector->e->XFloor.lightlist[i].extra_colormap; } break; } - if(!sec) { + } + if(!sec) + { sec = viewsector; basecolormap = sec->ColorMap; } floorlight = ceilinglight = sec->lightlevel; - } else { - // This used to use camera->Sector but due to interpolation that can be incorrect + } + else + { // This used to use camera->Sector but due to interpolation that can be incorrect // when the interpolated viewpoint is in a different sector than the camera. sec = R_FakeFlat (viewsector, &tempsec, &floorlight, &ceilinglight, false); @@ -1589,23 +1615,19 @@ void R_DrawPlayerSprites () CenterY = viewheight / 2; - P_BobWeapon (camera->player, &camera->player->psprites[ps_weapon], &ofsx, &ofsy, r_TicFracF); + P_BobWeapon (camera->player, &ofsx, &ofsy, r_TicFracF); // add all active psprites - for (i = 0, psp = camera->player->psprites; - i < NUMPSPRITES; - i++, psp++) + psp = camera->player->psprites; + while (psp) { // [RH] Don't draw the targeter's crosshair if the player already has a crosshair set. - if (psp->state && (i != ps_targetcenter || CrosshairImage == NULL)) + if (psp->GetID() != ps_targetcenter || CrosshairImage == nullptr) { - R_DrawPSprite (psp, i, camera, psp->sx + ofsx, psp->sy + ofsy); - } - // [RH] Don't bob the targeter. - if (i == ps_flash) - { - ofsx = ofsy = 0; + R_DrawPSprite(psp, camera, ofsx, ofsy, r_TicFracF); } + + psp = psp->GetNext(); } CenterY = centerhack; @@ -1623,65 +1645,62 @@ void R_DrawPlayerSprites () void R_DrawRemainingPlayerSprites() { - for (int i = 0; i < NUMPSPRITES; ++i) + for (unsigned int i = 0; i < vispspindex; i++) { vissprite_t *vis; - vis = VisPSprites[i]; - VisPSprites[i] = NULL; + vis = vispsprites[i].vis; + FDynamicColormap *colormap = vispsprites[i].basecolormap; + bool flip = vis->xiscale < 0; + FSpecialColormap *special = NULL; + PalEntry overlay = 0; + FColormapStyle colormapstyle; + bool usecolormapstyle = false; - if (vis != NULL) + if (vis->Style.colormap >= SpecialColormaps[0].Colormap && + vis->Style.colormap < SpecialColormaps[SpecialColormaps.Size()].Colormap) { - FDynamicColormap *colormap = VisPSpritesBaseColormap[i]; - bool flip = vis->xiscale < 0; - FSpecialColormap *special = NULL; - PalEntry overlay = 0; - FColormapStyle colormapstyle; - bool usecolormapstyle = false; - - if (vis->Style.colormap >= SpecialColormaps[0].Colormap && - vis->Style.colormap < SpecialColormaps[SpecialColormaps.Size()].Colormap) - { - // Yuck! There needs to be a better way to store colormaps in the vissprite... :( - ptrdiff_t specialmap = (vis->Style.colormap - SpecialColormaps[0].Colormap) / sizeof(FSpecialColormap); - special = &SpecialColormaps[specialmap]; - } - else if (colormap->Color == PalEntry(255,255,255) && - colormap->Desaturate == 0) - { - overlay = colormap->Fade; - overlay.a = BYTE(((vis->Style.colormap - colormap->Maps) >> 8) * 255 / NUMCOLORMAPS); - } - else - { - usecolormapstyle = true; - colormapstyle.Color = colormap->Color; - colormapstyle.Fade = colormap->Fade; - colormapstyle.Desaturate = colormap->Desaturate; - colormapstyle.FadeLevel = ((vis->Style.colormap - colormap->Maps) >> 8) / float(NUMCOLORMAPS); - } - screen->DrawTexture(vis->pic, - viewwindowx + VisPSpritesX1[i], - viewwindowy + viewheight/2 - vis->texturemid * vis->yscale - 0.5, - DTA_DestWidthF, FIXED2DBL(vis->pic->GetWidth() * vis->xscale), - DTA_DestHeightF, vis->pic->GetHeight() * vis->yscale, - DTA_Translation, TranslationToTable(vis->Translation), - DTA_FlipX, flip, - DTA_TopOffset, 0, - DTA_LeftOffset, 0, - DTA_ClipLeft, viewwindowx, - DTA_ClipTop, viewwindowy, - DTA_ClipRight, viewwindowx + viewwidth, - DTA_ClipBottom, viewwindowy + viewheight, - DTA_AlphaF, vis->Style.Alpha, - DTA_RenderStyle, vis->Style.RenderStyle, - DTA_FillColor, vis->FillColor, - DTA_SpecialColormap, special, - DTA_ColorOverlay, overlay.d, - DTA_ColormapStyle, usecolormapstyle ? &colormapstyle : NULL, - TAG_DONE); + // Yuck! There needs to be a better way to store colormaps in the vissprite... :( + ptrdiff_t specialmap = (vis->Style.colormap - SpecialColormaps[0].Colormap) / sizeof(FSpecialColormap); + special = &SpecialColormaps[specialmap]; } + else if (colormap->Color == PalEntry(255,255,255) && + colormap->Desaturate == 0) + { + overlay = colormap->Fade; + overlay.a = BYTE(((vis->Style.colormap - colormap->Maps) >> 8) * 255 / NUMCOLORMAPS); + } + else + { + usecolormapstyle = true; + colormapstyle.Color = colormap->Color; + colormapstyle.Fade = colormap->Fade; + colormapstyle.Desaturate = colormap->Desaturate; + colormapstyle.FadeLevel = ((vis->Style.colormap - colormap->Maps) >> 8) / float(NUMCOLORMAPS); + } + screen->DrawTexture(vis->pic, + viewwindowx + vispsprites[i].x1, + viewwindowy + viewheight/2 - vis->texturemid * vis->yscale - 0.5, + DTA_DestWidthF, FIXED2DBL(vis->pic->GetWidth() * vis->xscale), + DTA_DestHeightF, vis->pic->GetHeight() * vis->yscale, + DTA_Translation, TranslationToTable(vis->Translation), + DTA_FlipX, flip, + DTA_TopOffset, 0, + DTA_LeftOffset, 0, + DTA_ClipLeft, viewwindowx, + DTA_ClipTop, viewwindowy, + DTA_ClipRight, viewwindowx + viewwidth, + DTA_ClipBottom, viewwindowy + viewheight, + DTA_AlphaF, vis->Style.Alpha, + DTA_RenderStyle, vis->Style.RenderStyle, + DTA_FillColor, vis->FillColor, + DTA_SpecialColormap, special, + DTA_ColorOverlay, overlay.d, + DTA_ColormapStyle, usecolormapstyle ? &colormapstyle : NULL, + TAG_DONE); } + + vispspindex = 0; } // diff --git a/src/r_things.h b/src/r_things.h index 1cf9b0200..29e69d3a5 100644 --- a/src/r_things.h +++ b/src/r_things.h @@ -130,7 +130,6 @@ void R_WallSpriteColumn (void (*drawfunc)(const BYTE *column, const FTexture::Sp void R_CacheSprite (spritedef_t *sprite); void R_SortVisSprites (int (*compare)(const void *, const void *), size_t first); void R_AddSprites (sector_t *sec, int lightlevel, int fakeside); -void R_AddPSprites (); void R_DrawSprites (); void R_ClearSprites (); void R_DrawMasked (); diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index afbc036a6..aaa4981eb 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -5706,15 +5706,18 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetTics) PARAM_ACTION_PROLOGUE; PARAM_INT(tics_to_set); - if (stateowner != self && self->player != NULL && stateowner->IsKindOf(RUNTIME_CLASS(AWeapon))) - { // Is this a weapon? Need to check psp states for a match, then. Blah. - for (int i = 0; i < NUMPSPRITES; ++i) + if (stateowner != self && self->player != nullptr && stateowner->IsKindOf(RUNTIME_CLASS(AInventory))) + { // Need to check psp states for a match, then. Blah. + DPSprite *pspr = self->player->psprites; + while (pspr) { - if (self->player->psprites[i].state == callingstate) + if (pspr->GetState() == callingstate) { - self->player->psprites[i].tics = tics_to_set; + pspr->Tics = tics_to_set; return 0; } + + pspr = pspr->GetNext(); } } // Just set tics for self. diff --git a/src/version.h b/src/version.h index 52b7ea0ba..5378c5721 100644 --- a/src/version.h +++ b/src/version.h @@ -76,7 +76,7 @@ const char *GetVersionString(); // Use 4500 as the base git save version, since it's higher than the // SVN revision ever got. -#define SAVEVER 4546 +#define SAVEVER 4547 #define SAVEVERSTRINGIFY2(x) #x #define SAVEVERSTRINGIFY(x) SAVEVERSTRINGIFY2(x) From 1ecfb5897b05c0b9605e5195e61433a5e5b17714 Mon Sep 17 00:00:00 2001 From: Leonard2 Date: Wed, 11 May 2016 23:13:02 +0200 Subject: [PATCH 02/25] Added A_Overlay --- src/p_pspr.cpp | 25 +++++++++++++++++++++++ wadsrc/static/actors/shared/inventory.txt | 1 + 2 files changed, 26 insertions(+) diff --git a/src/p_pspr.cpp b/src/p_pspr.cpp index 656ee4c38..c271e4795 100644 --- a/src/p_pspr.cpp +++ b/src/p_pspr.cpp @@ -251,6 +251,11 @@ void DPSprite::SetState(FState *newstate, bool pending) FState *nextstate; if (newstate->CallAction(Owner->mo, Caller, &nextstate)) { + // It's possible this call resulted in this very layer being replaced. + if (ObjectFlags & OF_EuthanizeMe) + { + return; + } if (nextstate != nullptr) { newstate = nextstate; @@ -1001,8 +1006,28 @@ DEFINE_ACTION_FUNCTION(AInventory, A_Raise) return 0; } +//--------------------------------------------------------------------------- +// +// PROC A_Overlay +// +//--------------------------------------------------------------------------- +DEFINE_ACTION_FUNCTION_PARAMS(AInventory, A_Overlay) +{ + PARAM_ACTION_PROLOGUE; + PARAM_INT (layer); + PARAM_STATE_OPT (state) { state = nullptr; } + player_t *player = self->player; + + if (player == nullptr) + return 0; + + DPSprite *pspr; + pspr = new DPSprite(player, reinterpret_cast(stateowner), layer); + pspr->SetState(state); + return 0; +} // // A_GunFlash diff --git a/wadsrc/static/actors/shared/inventory.txt b/wadsrc/static/actors/shared/inventory.txt index f7250117d..990205869 100644 --- a/wadsrc/static/actors/shared/inventory.txt +++ b/wadsrc/static/actors/shared/inventory.txt @@ -40,6 +40,7 @@ ACTOR Inventory native action native A_ReFire(state flash = ""); action native A_ClearReFire(); action native A_CheckReload(); + action native A_Overlay(int layer, state start = ""); action native A_GunFlash(state flash = "", int flags = 0); action native A_Saw(sound fullsound = "weapons/sawfull", sound hitsound = "weapons/sawhit", int damage = 2, class pufftype = "BulletPuff", int flags = 0, float range = 0, float/*angle*/ spread_xy = 2.8125, float/*angle*/ spread_z = 0, float lifesteal = 0, int lifestealmax = 0, class armorbonustype = "ArmorBonus"); action native state A_CheckForReload(int counter, state label, bool dontincrement = false); From 8c205ebac3bb1e20d29e8f9a4fa891b2c8c4d218 Mon Sep 17 00:00:00 2001 From: Leonard2 Date: Wed, 18 May 2016 14:20:36 +0200 Subject: [PATCH 03/25] Added A_OverlayOffset Like A_WeaponOffset except it can access any psprites --- src/d_player.h | 1 + src/p_pspr.cpp | 61 +++++++++++++++++++---- wadsrc/static/actors/shared/inventory.txt | 1 + 3 files changed, 53 insertions(+), 10 deletions(-) diff --git a/src/d_player.h b/src/d_player.h index ee9e64f0c..e743a7b4f 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -532,6 +532,7 @@ public: void TickPSprites(); void DestroyPSprites(); DPSprite *GetPSprite(psprnum_t layer); // Used ONLY for compatibility with the old hardcoded layers. + DPSprite *FindPSprite(int layer); }; // Bookkeeping on players - state. diff --git a/src/p_pspr.cpp b/src/p_pspr.cpp index c271e4795..11433b6f8 100644 --- a/src/p_pspr.cpp +++ b/src/p_pspr.cpp @@ -158,6 +158,29 @@ DPSprite *player_t::GetPSprite(psprnum_t layer) return pspr; } +//------------------------------------------------------------------------ +// +// +// +//------------------------------------------------------------------------ + +DPSprite *player_t::FindPSprite(int layer) +{ + if (layer == 0) + return nullptr; + + DPSprite *pspr = psprites; + while (pspr) + { + if (pspr->ID == layer) + break; + + pspr = pspr->Next; + } + + return pspr; +} + //--------------------------------------------------------------------------- // // PROC P_NewPspriteTick @@ -863,7 +886,7 @@ DEFINE_ACTION_FUNCTION(AInventory, A_CheckReload) //--------------------------------------------------------------------------- // -// PROC A_WeaponOffset +// PROC A_OverlayOffset // //--------------------------------------------------------------------------- enum WOFFlags @@ -873,16 +896,11 @@ enum WOFFlags WOF_ADD = 1 << 2, }; -DEFINE_ACTION_FUNCTION(AInventory, A_WeaponOffset) +void A_OverlayOffset(AActor *self, int layer, double wx, double wy, int flags) { - PARAM_ACTION_PROLOGUE; - PARAM_FLOAT_OPT(wx) { wx = 0.; } - PARAM_FLOAT_OPT(wy) { wy = 32.; } - PARAM_INT_OPT(flags) { flags = 0; } - if ((flags & WOF_KEEPX) && (flags & WOF_KEEPY)) { - return 0; + return; } player_t *player = self->player; @@ -890,7 +908,11 @@ DEFINE_ACTION_FUNCTION(AInventory, A_WeaponOffset) if (player && (player->playerstate != PST_DEAD)) { - psp = player->GetPSprite(ps_weapon); + psp = player->FindPSprite(layer); + + if (psp == nullptr) + return; + if (!(flags & WOF_KEEPX)) { if (flags & WOF_ADD) @@ -914,7 +936,26 @@ DEFINE_ACTION_FUNCTION(AInventory, A_WeaponOffset) } } } - +} + +DEFINE_ACTION_FUNCTION(AInventory, A_OverlayOffset) +{ + PARAM_ACTION_PROLOGUE; + PARAM_INT_OPT(layer) { layer = ps_weapon; } + PARAM_FLOAT_OPT(wx) { wx = 0.; } + PARAM_FLOAT_OPT(wy) { wy = 32.; } + PARAM_INT_OPT(flags) { flags = 0; } + A_OverlayOffset(self, layer, wx, wy, flags); + return 0; +} + +DEFINE_ACTION_FUNCTION(AInventory, A_WeaponOffset) +{ + PARAM_ACTION_PROLOGUE; + PARAM_FLOAT_OPT(wx) { wx = 0.; } + PARAM_FLOAT_OPT(wy) { wy = 32.; } + PARAM_INT_OPT(flags) { flags = 0; } + A_OverlayOffset(self, ps_weapon, wx, wy, flags); return 0; } diff --git a/wadsrc/static/actors/shared/inventory.txt b/wadsrc/static/actors/shared/inventory.txt index 990205869..396274332 100644 --- a/wadsrc/static/actors/shared/inventory.txt +++ b/wadsrc/static/actors/shared/inventory.txt @@ -50,6 +50,7 @@ ACTOR Inventory native action native A_RestoreSpecialThing1(); action native A_RestoreSpecialThing2(); action native A_WeaponOffset(float wx = 0, float wy = 32, int flags = 0); + action native A_OverlayOffset(int layer = 1, float wx = 0, float wy = 32, int flags = 0); States { From d767d10322ba312a71cbf5f655588d600ce5c0fb Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 21 May 2016 13:11:43 +0200 Subject: [PATCH 04/25] - made PSprites submission GC aware. --- src/d_player.h | 2 +- src/p_pspr.cpp | 55 +++++++++++++++++++++++++++++++++++++++----------- src/p_pspr.h | 6 +++--- 3 files changed, 47 insertions(+), 16 deletions(-) diff --git a/src/d_player.h b/src/d_player.h index e743a7b4f..650799f6d 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -436,6 +436,7 @@ public: AWeapon *ReadyWeapon; AWeapon *PendingWeapon; // WP_NOCHANGE if not changing + TObjPtr psprites; // view sprites (gun, etc) int cheats; // bit flags int timefreezer; // Player has an active time freezer @@ -528,7 +529,6 @@ public: int GetSpawnClass(); // PSprite layers - DPSprite *psprites; // view sprites (gun, etc) void TickPSprites(); void DestroyPSprites(); DPSprite *GetPSprite(psprnum_t layer); // Used ONLY for compatibility with the old hardcoded layers. diff --git a/src/p_pspr.cpp b/src/p_pspr.cpp index 11433b6f8..f2ab02b82 100644 --- a/src/p_pspr.cpp +++ b/src/p_pspr.cpp @@ -113,12 +113,25 @@ END_POINTERS DPSprite::DPSprite(player_t *owner, AInventory *caller, int id) : processPending(true), firstTic(true), Owner(owner), Caller(caller), ID(id) { - DPSprite **prev = &Owner->psprites; - while (*prev && (*prev)->ID < ID) - prev = &(*prev)->Next; - - Next = *prev; - *prev = this; + DPSprite *prev = nullptr; + DPSprite *next = Owner->psprites; + while (next != nullptr && next->ID < ID) + { + prev = next; + next = next->Next; + } + Next = next; + GC::WriteBarrier(this, next); + if (prev == NULL) + { + Owner->psprites = this; + GC::WriteBarrier(this); + } + else + { + prev->Next = this; + GC::WriteBarrier(prev, this); + } if (Next && Next->ID == ID && ID != 0) Next->Destroy(); // Replace it. @@ -1349,10 +1362,13 @@ void DPSprite::Serialize(FArchive &arc) void player_t::DestroyPSprites() { DPSprite *pspr = psprites; + psprites = nullptr; while (pspr) { + DPSprite *next = pspr->Next; + pspr->Next = nullptr; pspr->Destroy(); - pspr = pspr->Next; + pspr = next; } } @@ -1364,12 +1380,27 @@ void player_t::DestroyPSprites() void DPSprite::Destroy() { - DPSprite **prev = &Owner->psprites; - while (*prev != this) - prev = &(*prev)->Next; - - *prev = Next; + // Do not crash if this gets called on partially initialized objects. + if (Owner != nullptr && Owner->psprites != nullptr) + { + if (Owner->psprites != this) + { + DPSprite *prev = Owner->psprites; + while (prev != nullptr && prev->Next != this) + prev = prev->Next; + if (prev != nullptr && prev->Next == this) + { + prev->Next = Next; + GC::WriteBarrier(prev, Next); + } + } + else + { + Owner->psprites = Next; + GC::WriteBarrier(Next); + } + } Super::Destroy(); } diff --git a/src/p_pspr.h b/src/p_pspr.h index 87e78ef1f..5f9292d98 100644 --- a/src/p_pspr.h +++ b/src/p_pspr.h @@ -66,8 +66,8 @@ public: int GetSprite() const { return Sprite; } int GetFrame() const { return Frame; } FState* GetState() const { return State; } - DPSprite* GetNext() const { return Next; } - TObjPtr GetCaller() const { return Caller; } + DPSprite* GetNext() { return Next; } + AInventory* GetCaller() { return Caller; } double x, y; double oldx, oldy; @@ -82,7 +82,7 @@ private: void Destroy(); TObjPtr Caller; - DPSprite *Next; + TObjPtr Next; player_t *Owner; FState *State; int Sprite; From f1844380327c564e5c1789986df25148b7b8b052 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 22 May 2016 01:26:13 +0200 Subject: [PATCH 05/25] - fixed: Polyobjects did not save their specialdata pointer. - fixed: DMovePoly did not save its m_Speedv member. --- src/p_saveg.cpp | 5 +++++ src/po_man.cpp | 25 ++++--------------------- src/po_man.h | 24 ++++++++++++++++++++++-- src/version.h | 2 +- 4 files changed, 32 insertions(+), 24 deletions(-) diff --git a/src/p_saveg.cpp b/src/p_saveg.cpp index 049673abd..4b5b8cb19 100644 --- a/src/p_saveg.cpp +++ b/src/p_saveg.cpp @@ -578,6 +578,7 @@ void P_SerializePolyobjs (FArchive &arc) for(i = 0, po = polyobjs; i < po_NumPolyobjs; i++, po++) { arc << po->tag << po->Angle << po->StartSpot.pos << po->interpolation << po->bBlocked << po->bHasPortals; + arc << po->specialdata; } } else @@ -605,6 +606,10 @@ void P_SerializePolyobjs (FArchive &arc) arc << angle << delta << po->interpolation; arc << po->bBlocked; arc << po->bHasPortals; + if (SaveVersion >= 4548) + { + arc << po->specialdata; + } po->RotatePolyobj (angle, true); delta -= po->StartSpot.pos; diff --git a/src/po_man.cpp b/src/po_man.cpp index 7b5e187a8..001f308f1 100644 --- a/src/po_man.cpp +++ b/src/po_man.cpp @@ -68,27 +68,6 @@ inline FArchive &operator<< (FArchive &arc, podoortype_t &type) return arc; } -class DPolyAction : public DThinker -{ - DECLARE_CLASS (DPolyAction, DThinker) - HAS_OBJECT_POINTERS -public: - DPolyAction (int polyNum); - void Serialize (FArchive &arc); - void Destroy(); - void Stop(); - double GetSpeed() const { return m_Speed; } - - void StopInterpolation (); -protected: - DPolyAction (); - int m_PolyObj; - double m_Speed; - double m_Dist; - TObjPtr m_Interpolation; - - void SetInterpolation (); -}; class DRotatePoly : public DPolyAction { @@ -302,6 +281,10 @@ void DMovePoly::Serialize (FArchive &arc) { Super::Serialize (arc); arc << m_Angle << m_Speed; + if (SaveVersion >= 4548) + { + arc << m_Speedv; + } } DMovePoly::DMovePoly (int polyNum) diff --git a/src/po_man.h b/src/po_man.h index 9bc853255..18b01d9cc 100644 --- a/src/po_man.h +++ b/src/po_man.h @@ -5,7 +5,27 @@ #include "r_defs.h" #include "m_bbox.h" -class DPolyAction; +class DPolyAction : public DThinker +{ + DECLARE_CLASS(DPolyAction, DThinker) + HAS_OBJECT_POINTERS +public: + DPolyAction(int polyNum); + void Serialize(FArchive &arc); + void Destroy(); + void Stop(); + double GetSpeed() const { return m_Speed; } + + void StopInterpolation(); +protected: + DPolyAction(); + int m_PolyObj; + double m_Speed; + double m_Dist; + TObjPtr m_Interpolation; + + void SetInterpolation(); +}; struct FPolyVertex { @@ -67,7 +87,7 @@ struct FPolyObj int seqType; double Size; // polyobj size (area of POLY_AREAUNIT == size of FRACUNIT) FPolyNode *subsectorlinks; - DPolyAction *specialdata; // pointer to a thinker, if the poly is moving + TObjPtr specialdata; // pointer to a thinker, if the poly is moving TObjPtr interpolation; FPolyObj(); diff --git a/src/version.h b/src/version.h index 5378c5721..9aa4ad799 100644 --- a/src/version.h +++ b/src/version.h @@ -76,7 +76,7 @@ const char *GetVersionString(); // Use 4500 as the base git save version, since it's higher than the // SVN revision ever got. -#define SAVEVER 4547 +#define SAVEVER 4548 #define SAVEVERSTRINGIFY2(x) #x #define SAVEVERSTRINGIFY(x) SAVEVERSTRINGIFY2(x) From e6d89b9f71aa840a2995ff00d40d5541be6ed25a Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 24 May 2016 13:05:43 +0200 Subject: [PATCH 06/25] - re-added P_SetPSprite. For debugging purposes it's better to have this as a function. --- src/g_doom/a_doomweaps.cpp | 12 ++++++------ src/g_heretic/a_chicken.cpp | 2 +- src/g_heretic/a_hereticweaps.cpp | 4 ++-- src/g_hexen/a_clericstaff.cpp | 4 ++-- src/g_hexen/a_fighteraxe.cpp | 12 ++++++------ src/g_hexen/a_fighterplayer.cpp | 2 +- src/g_hexen/a_pig.cpp | 2 +- src/g_shared/a_artifacts.cpp | 22 +++++++++++----------- src/g_strife/a_strifestuff.cpp | 4 ++-- src/g_strife/a_strifeweapons.cpp | 6 +++--- src/m_cheat.cpp | 6 +++--- src/p_mobj.cpp | 4 ++-- src/p_pspr.cpp | 20 +++++++++++++------- src/p_pspr.h | 1 + src/p_user.cpp | 2 +- 15 files changed, 55 insertions(+), 48 deletions(-) diff --git a/src/g_doom/a_doomweaps.cpp b/src/g_doom/a_doomweaps.cpp index a96fab8fc..0d87e803e 100644 --- a/src/g_doom/a_doomweaps.cpp +++ b/src/g_doom/a_doomweaps.cpp @@ -81,7 +81,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FirePistol) if (!weapon->DepleteAmmo (weapon->bAltFire, true, 1)) return 0; - self->player->GetPSprite(ps_flash)->SetState(weapon->FindState(NAME_Flash), true); + P_SetPsprite(self->player, ps_flash, weapon->FindState(NAME_Flash), true); } self->player->mo->PlayAttacking2 (); @@ -273,7 +273,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireShotgun) { if (!weapon->DepleteAmmo (weapon->bAltFire, true, 1)) return 0; - player->GetPSprite(ps_flash)->SetState(weapon->FindState(NAME_Flash), true); + P_SetPsprite(player, ps_flash, weapon->FindState(NAME_Flash), true); } player->mo->PlayAttacking2 (); @@ -309,7 +309,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireShotgun2) { if (!weapon->DepleteAmmo (weapon->bAltFire, true, 2)) return 0; - player->GetPSprite(ps_flash)->SetState(weapon->FindState(NAME_Flash), true); + P_SetPsprite(player, ps_flash, weapon->FindState(NAME_Flash), true); } player->mo->PlayAttacking2 (); @@ -381,13 +381,13 @@ void P_SetSafeFlash(AWeapon *weapon, player_t *player, FState *flashstate, int i if (flashstate + index < cls->OwnedStates + cls->NumOwnedStates) { // we're ok so set the state - player->GetPSprite(ps_flash)->SetState(flashstate + index, true); + P_SetPsprite(player, ps_flash, flashstate + index, true); return; } else { // oh, no! The state is beyond the end of the state table so use the original flash state. - player->GetPSprite(ps_flash)->SetState(flashstate, true); + P_SetPsprite(player, ps_flash, flashstate, true); return; } } @@ -403,7 +403,7 @@ void P_SetSafeFlash(AWeapon *weapon, player_t *player, FState *flashstate, int i { // Invalid state. With no index offset, it should at least be valid. index = 0; } - player->GetPSprite(ps_flash)->SetState(flashstate + index, true); + P_SetPsprite(player, ps_flash, flashstate + index, true); } // diff --git a/src/g_heretic/a_chicken.cpp b/src/g_heretic/a_chicken.cpp index cb8bc7fc9..e9844b57e 100644 --- a/src/g_heretic/a_chicken.cpp +++ b/src/g_heretic/a_chicken.cpp @@ -146,7 +146,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_BeakRaise) return 0; } player->GetPSprite(ps_weapon)->y = WEAPONTOP; - player->GetPSprite(ps_weapon)->SetState(player->ReadyWeapon->GetReadyState()); + P_SetPsprite(player, ps_weapon, player->ReadyWeapon->GetReadyState()); return 0; } diff --git a/src/g_heretic/a_hereticweaps.cpp b/src/g_heretic/a_hereticweaps.cpp index 8b5409f5b..344fc33c6 100644 --- a/src/g_heretic/a_hereticweaps.cpp +++ b/src/g_heretic/a_hereticweaps.cpp @@ -1158,7 +1158,7 @@ IMPLEMENT_CLASS (APhoenixRodPowered) void APhoenixRodPowered::EndPowerup () { - Owner->player->GetPSprite(ps_weapon)->SetState(SisterWeapon->GetReadyState()); + P_SetPsprite(Owner->player, ps_weapon, SisterWeapon->GetReadyState()); DepleteAmmo (bAltFire); Owner->player->refire = 0; S_StopSound (Owner, CHAN_WEAPON); @@ -1308,7 +1308,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FirePhoenixPL2) flamethrower = static_cast (player->ReadyWeapon); if (flamethrower == nullptr || --flamethrower->FlameCount == 0) { // Out of flame - player->GetPSprite(ps_weapon)->SetState(flamethrower->FindState("Powerdown")); + P_SetPsprite(player, ps_weapon, flamethrower->FindState("Powerdown")); player->refire = 0; S_StopSound (self, CHAN_WEAPON); return 0; diff --git a/src/g_hexen/a_clericstaff.cpp b/src/g_hexen/a_clericstaff.cpp index 898ff9b0e..d67baba8e 100644 --- a/src/g_hexen/a_clericstaff.cpp +++ b/src/g_hexen/a_clericstaff.cpp @@ -92,7 +92,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CStaffCheck) if (weapon != nullptr) { FState * newstate = weapon->FindState("Drain"); - if (newstate != nullptr) player->GetPSprite(ps_weapon)->SetState(newstate); + if (newstate != nullptr) P_SetPsprite(player, ps_weapon, newstate); } } if (weapon != nullptr) @@ -187,7 +187,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CStaffCheckBlink) { if (!--self->weaponspecial) { - self->player->GetPSprite(ps_weapon)->SetState(self->player->ReadyWeapon->FindState ("Blink")); + P_SetPsprite(self->player, ps_weapon, self->player->ReadyWeapon->FindState ("Blink")); self->weaponspecial = (pr_blink()+50)>>2; } else diff --git a/src/g_hexen/a_fighteraxe.cpp b/src/g_hexen/a_fighteraxe.cpp index 7fe867697..98ed409f7 100644 --- a/src/g_hexen/a_fighteraxe.cpp +++ b/src/g_hexen/a_fighteraxe.cpp @@ -76,7 +76,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FAxeCheckReady) } if (player->ReadyWeapon->Ammo1->Amount) { - player->GetPSprite(ps_weapon)->SetState(player->ReadyWeapon->FindState ("ReadyGlow")); + P_SetPsprite(player, ps_weapon, player->ReadyWeapon->FindState ("ReadyGlow")); } else { @@ -103,7 +103,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FAxeCheckReadyG) } if (player->ReadyWeapon->Ammo1->Amount <= 0) { - player->GetPSprite(ps_weapon)->SetState(player->ReadyWeapon->FindState ("Ready")); + P_SetPsprite(player, ps_weapon, player->ReadyWeapon->FindState ("Ready")); } else { @@ -130,7 +130,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FAxeCheckUp) } if (player->ReadyWeapon->Ammo1->Amount) { - player->GetPSprite(ps_weapon)->SetState(player->ReadyWeapon->FindState ("SelectGlow")); + P_SetPsprite(player, ps_weapon, player->ReadyWeapon->FindState ("SelectGlow")); } else { @@ -157,7 +157,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FAxeCheckUpG) } if (player->ReadyWeapon->Ammo1->Amount <= 0) { - player->GetPSprite(ps_weapon)->SetState(player->ReadyWeapon->FindState ("Select")); + P_SetPsprite(player, ps_weapon, player->ReadyWeapon->FindState ("Select")); } else { @@ -184,7 +184,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FAxeCheckAtk) } if (player->ReadyWeapon->Ammo1->Amount) { - player->GetPSprite(ps_weapon)->SetState(player->ReadyWeapon->FindState ("FireGlow")); + P_SetPsprite(player, ps_weapon, player->ReadyWeapon->FindState ("FireGlow")); } return 0; } @@ -273,7 +273,7 @@ axedone: (!(weapon->WeaponFlags & WIF_PRIMARY_USES_BOTH) || weapon->Ammo2 == nullptr || weapon->Ammo2->Amount == 0)) { - player->GetPSprite(ps_weapon)->SetState(player->ReadyWeapon->FindState ("Fire") + 5); + P_SetPsprite(player, ps_weapon, player->ReadyWeapon->FindState ("Fire") + 5); } } } diff --git a/src/g_hexen/a_fighterplayer.cpp b/src/g_hexen/a_fighterplayer.cpp index 35b08f860..1ec9372ed 100644 --- a/src/g_hexen/a_fighterplayer.cpp +++ b/src/g_hexen/a_fighterplayer.cpp @@ -120,7 +120,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FPunchAttack) if (pmo->weaponspecial >= 3) { pmo->weaponspecial = 0; - player->GetPSprite(ps_weapon)->SetState(player->ReadyWeapon->FindState("Fire2")); + P_SetPsprite(player, ps_weapon, player->ReadyWeapon->FindState("Fire2")); S_Sound (pmo, CHAN_VOICE, "*fistgrunt", 1, ATTN_NORM); } return 0; diff --git a/src/g_hexen/a_pig.cpp b/src/g_hexen/a_pig.cpp index 58db7dfc6..e1fb0b224 100644 --- a/src/g_hexen/a_pig.cpp +++ b/src/g_hexen/a_pig.cpp @@ -39,7 +39,7 @@ void APigPlayer::MorphPlayerThink () { // Snout sniff if (player->ReadyWeapon != nullptr) { - player->GetPSprite(ps_weapon)->SetState(player->ReadyWeapon->FindState("Grunt")); + P_SetPsprite(player, ps_weapon, player->ReadyWeapon->FindState("Grunt")); } S_Sound (this, CHAN_VOICE, "PigActive1", 1, ATTN_NORM); // snort return; diff --git a/src/g_shared/a_artifacts.cpp b/src/g_shared/a_artifacts.cpp index 1b48678ab..32a6da15a 100644 --- a/src/g_shared/a_artifacts.cpp +++ b/src/g_shared/a_artifacts.cpp @@ -1131,7 +1131,7 @@ void APowerWeaponLevel2::InitEffect () if (weapon->GetReadyState() != sister->GetReadyState()) { - Owner->player->GetPSprite(ps_weapon)->SetState(sister->GetReadyState()); + P_SetPsprite(Owner->player, ps_weapon, sister->GetReadyState()); } } @@ -1305,9 +1305,9 @@ void APowerTargeter::InitEffect () if (state != nullptr) { - player->GetPSprite(ps_targetcenter)->SetState(state + 0); - player->GetPSprite(ps_targetleft)->SetState(state + 1); - player->GetPSprite(ps_targetright)->SetState(state + 2); + P_SetPsprite(player, ps_targetcenter, state + 0); + P_SetPsprite(player, ps_targetleft, state + 1); + P_SetPsprite(player, ps_targetright, state + 2); } player->GetPSprite(ps_targetcenter)->x = (160-3); @@ -1346,13 +1346,13 @@ void APowerTargeter::DoEffect () { if (EffectTics & 32) { - player->GetPSprite(ps_targetright)->SetState(nullptr); - player->GetPSprite(ps_targetleft)->SetState(state + 1); + P_SetPsprite(player, ps_targetright, nullptr); + P_SetPsprite(player, ps_targetleft, state + 1); } else if (EffectTics & 16) { - player->GetPSprite(ps_targetright)->SetState(state + 2); - player->GetPSprite(ps_targetleft)->SetState(nullptr); + P_SetPsprite(player, ps_targetright, state + 2); + P_SetPsprite(player, ps_targetleft, nullptr); } } } @@ -1364,9 +1364,9 @@ void APowerTargeter::EndEffect () Super::EndEffect(); if (Owner != nullptr && Owner->player != nullptr) { - Owner->player->GetPSprite(ps_targetcenter)->SetState(nullptr); - Owner->player->GetPSprite(ps_targetleft)->SetState(nullptr); - Owner->player->GetPSprite(ps_targetright)->SetState(nullptr); + P_SetPsprite (Owner->player, ps_targetcenter, nullptr); + P_SetPsprite (Owner->player, ps_targetleft, nullptr); + P_SetPsprite (Owner->player, ps_targetright, nullptr); } } diff --git a/src/g_strife/a_strifestuff.cpp b/src/g_strife/a_strifestuff.cpp index 98ffa0f96..cefd10ba2 100644 --- a/src/g_strife/a_strifestuff.cpp +++ b/src/g_strife/a_strifestuff.cpp @@ -352,8 +352,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_ItBurnsItBurns) if (self->player != nullptr && self->player->mo == self) { - self->player->GetPSprite(ps_weapon)->SetState(self->FindState("FireHands")); - self->player->GetPSprite(ps_flash)->SetState(nullptr); + P_SetPsprite(self->player, ps_weapon, self->FindState("FireHands")); + P_SetPsprite(self->player, ps_flash, nullptr); self->player->ReadyWeapon = nullptr; self->player->PendingWeapon = WP_NOCHANGE; self->player->playerstate = PST_LIVE; diff --git a/src/g_strife/a_strifeweapons.cpp b/src/g_strife/a_strifeweapons.cpp index 32ae96366..4e81e218c 100644 --- a/src/g_strife/a_strifeweapons.cpp +++ b/src/g_strife/a_strifeweapons.cpp @@ -219,7 +219,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_ClearFlash) if (player == nullptr) return 0; - player->GetPSprite(ps_flash)->SetState(nullptr); + P_SetPsprite (player, ps_flash, nullptr); return 0; } @@ -235,7 +235,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_ShowElectricFlash) if (self->player != nullptr) { - self->player->GetPSprite(ps_flash)->SetState(self->player->ReadyWeapon->FindState(NAME_Flash)); + P_SetPsprite (self->player, ps_flash, self->player->ReadyWeapon->FindState(NAME_Flash)); } return 0; } @@ -707,7 +707,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FireGrenade) if (!weapon->DepleteAmmo (weapon->bAltFire)) return 0; - player->GetPSprite(ps_flash)->SetState(flash, true); + P_SetPsprite (player, ps_flash, flash, true); if (grenadetype != nullptr) { diff --git a/src/m_cheat.cpp b/src/m_cheat.cpp index bb9d41d55..9c5df642c 100644 --- a/src/m_cheat.cpp +++ b/src/m_cheat.cpp @@ -345,7 +345,7 @@ void cht_DoCheat (player_t *player, int cheat) player->mo->DamageType = NAME_None; if (player->ReadyWeapon != nullptr) { - player->GetPSprite(ps_weapon)->SetState(player->ReadyWeapon->GetUpState()); + P_SetPsprite(player, ps_weapon, player->ReadyWeapon->GetUpState()); } if (player->morphTics > 0) @@ -934,8 +934,8 @@ void cht_Take (player_t *player, const char *name, int amount) player->ReadyWeapon = nullptr; player->PendingWeapon = WP_NOCHANGE; - player->GetPSprite(ps_weapon)->SetState(nullptr); - player->GetPSprite(ps_flash)->SetState(nullptr); + P_SetPsprite(player, ps_weapon, nullptr); + P_SetPsprite(player, ps_flash, nullptr); } } diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 94f8c57c3..b414c1baa 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -1001,8 +1001,8 @@ void AActor::ClearInventory() { player->ReadyWeapon = nullptr; player->PendingWeapon = WP_NOCHANGE; - player->GetPSprite(ps_weapon)->SetState(nullptr); - player->GetPSprite(ps_flash)->SetState(nullptr); + P_SetPsprite(player, ps_weapon, nullptr); + P_SetPsprite(player, ps_flash, nullptr); } } diff --git a/src/p_pspr.cpp b/src/p_pspr.cpp index f2ab02b82..da07e8004 100644 --- a/src/p_pspr.cpp +++ b/src/p_pspr.cpp @@ -312,6 +312,12 @@ void DPSprite::SetState(FState *newstate, bool pending) return; } +void P_SetPsprite(player_t *player, psprnum_t id, FState *state, bool pending) +{ + if (player == nullptr) return; + player->GetPSprite(id)->SetState(state, pending); +} + //--------------------------------------------------------------------------- // // PROC P_BringUpWeapon @@ -369,7 +375,7 @@ void P_BringUpWeapon (player_t *player) psweapon->SetState(newstate); // make sure that the previous weapon's flash state is terminated. // When coming here from a weapon drop it may still be active. - player->GetPSprite(ps_flash)->SetState(nullptr); + P_SetPsprite(player, ps_flash, nullptr); player->mo->weaponspecial = 0; } @@ -402,7 +408,7 @@ void P_FireWeapon (player_t *player, FState *state) { state = weapon->GetAtkState(!!player->refire); } - player->GetPSprite(ps_weapon)->SetState(state); + P_SetPsprite(player, ps_weapon, state); if (!(weapon->WeaponFlags & WIF_NOALERT)) { P_NoiseAlert (player->mo, player->mo, false); @@ -440,7 +446,7 @@ void P_FireWeaponAlt (player_t *player, FState *state) state = weapon->GetAltAtkState(!!player->refire); } - player->GetPSprite(ps_weapon)->SetState(state); + P_SetPsprite(player, ps_weapon, state); if (!(weapon->WeaponFlags & WIF_NOALERT)) { P_NoiseAlert (player->mo, player->mo, false); @@ -465,7 +471,7 @@ void P_DropWeapon (player_t *player) player->WeaponState &= ~WF_DISABLESWITCH; if (player->ReadyWeapon != nullptr) { - player->GetPSprite(ps_weapon)->SetState(player->ReadyWeapon->GetDownState()); + P_SetPsprite(player, ps_weapon, player->ReadyWeapon->GetDownState()); } } @@ -809,7 +815,7 @@ static void P_CheckWeaponButtons (player_t *player) // state, the weapon won't disappear. ;) if (state != nullptr) { - player->GetPSprite(ps_weapon)->SetState(state); + P_SetPsprite(player, ps_weapon, state); return; } } @@ -1011,7 +1017,7 @@ DEFINE_ACTION_FUNCTION(AInventory, A_Lower) return 0; } // [RH] Clear the flash state. Only needed for Strife. - player->GetPSprite(ps_flash)->SetState(nullptr); + P_SetPsprite(player, ps_flash, nullptr); P_BringUpWeapon (player); return 0; } @@ -1118,7 +1124,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AInventory, A_GunFlash) flash = player->ReadyWeapon->FindState(NAME_Flash); } } - player->GetPSprite(ps_flash)->SetState(flash); + P_SetPsprite(player, ps_flash, flash); return 0; } diff --git a/src/p_pspr.h b/src/p_pspr.h index 5f9292d98..68baddc70 100644 --- a/src/p_pspr.h +++ b/src/p_pspr.h @@ -96,6 +96,7 @@ private: void P_NewPspriteTick(); void P_CalcSwing (player_t *player); +void P_SetPsprite(player_t *player, psprnum_t id, FState *state, bool pending = false); void P_BringUpWeapon (player_t *player); void P_FireWeapon (player_t *player); void P_DropWeapon (player_t *player); diff --git a/src/p_user.cpp b/src/p_user.cpp index 353c35309..9a36fdc46 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -1405,7 +1405,7 @@ void APlayerPawn::ActivateMorphWeapon () pspr->SetState(nullptr); } } - player->GetPSprite(ps_flash)->SetState(nullptr); + P_SetPsprite(player, ps_flash, nullptr); player->PendingWeapon = WP_NOCHANGE; } From 599fa7cfd1429bd8775c6540deb60be84088b5e9 Mon Sep 17 00:00:00 2001 From: Leonard2 Date: Fri, 27 May 2016 22:31:18 +0200 Subject: [PATCH 07/25] Fixed: it was no longer possible to set the flash state in the very first weapon's state This was due to an oversight in my first commit --- src/p_pspr.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_pspr.cpp b/src/p_pspr.cpp index da07e8004..9b9e5919c 100644 --- a/src/p_pspr.cpp +++ b/src/p_pspr.cpp @@ -372,10 +372,10 @@ void P_BringUpWeapon (player_t *player) player->ReadyWeapon = weapon; psweapon->y = player->cheats & CF_INSTANTWEAPSWITCH ? WEAPONTOP : WEAPONBOTTOM; - psweapon->SetState(newstate); // make sure that the previous weapon's flash state is terminated. // When coming here from a weapon drop it may still be active. P_SetPsprite(player, ps_flash, nullptr); + psweapon->SetState(newstate); player->mo->weaponspecial = 0; } From bca98299509c42a7faa6b813eb225ef1566983cb Mon Sep 17 00:00:00 2001 From: Leonard2 Date: Fri, 27 May 2016 22:56:42 +0200 Subject: [PATCH 08/25] Fixed: a few members weren't properly initialized This could go wrong if a layer had only one state of -1 tics --- src/p_pspr.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/p_pspr.cpp b/src/p_pspr.cpp index 9b9e5919c..cc1deea0c 100644 --- a/src/p_pspr.cpp +++ b/src/p_pspr.cpp @@ -111,7 +111,13 @@ END_POINTERS //------------------------------------------------------------------------ DPSprite::DPSprite(player_t *owner, AInventory *caller, int id) -: processPending(true), firstTic(true), Owner(owner), Caller(caller), ID(id) +: processPending(true), + firstTic(true), + x(.0), y(.0), + oldx(.0), oldy(.0), + Flags(0), ID(id), + Caller(caller), + Owner(owner) { DPSprite *prev = nullptr; DPSprite *next = Owner->psprites; From b220db4ebe9ab3b265c7239fc6e4a16f524632bc Mon Sep 17 00:00:00 2001 From: Leonard2 Date: Fri, 27 May 2016 23:32:23 +0200 Subject: [PATCH 09/25] Fixed: a layer's movements weren't interpolated in some cases The old position members would be incorrectly updated if a layer sets another layer's offsets and this layer ticks before the other --- src/p_pspr.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/p_pspr.cpp b/src/p_pspr.cpp index cc1deea0c..d918c40c5 100644 --- a/src/p_pspr.cpp +++ b/src/p_pspr.cpp @@ -219,6 +219,8 @@ void DPSprite::NewTick() while (pspr) { pspr->processPending = true; + pspr->oldx = pspr->x; + pspr->oldy = pspr->y; pspr = pspr->Next; } @@ -1328,9 +1330,6 @@ void player_t::TickPSprites() void DPSprite::Tick() { - oldx = x; - oldy = y; - if (processPending) { // drop tic count and possibly change state From 8f360f3bea82075b155039c69184bc2a61f503fe Mon Sep 17 00:00:00 2001 From: Leonard2 Date: Thu, 26 May 2016 21:58:46 +0200 Subject: [PATCH 10/25] Small refactor --- src/d_player.h | 2 +- src/p_pspr.cpp | 48 ++++++++++++++++++++++++------------------------ src/p_pspr.h | 12 ++++++------ 3 files changed, 31 insertions(+), 31 deletions(-) diff --git a/src/d_player.h b/src/d_player.h index 650799f6d..8a90d9680 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -531,8 +531,8 @@ public: // PSprite layers void TickPSprites(); void DestroyPSprites(); - DPSprite *GetPSprite(psprnum_t layer); // Used ONLY for compatibility with the old hardcoded layers. DPSprite *FindPSprite(int layer); + DPSprite *GetPSprite(psprnum_t layer); // Used ONLY for compatibility with the old hardcoded layers. }; // Bookkeeping on players - state. diff --git a/src/p_pspr.cpp b/src/p_pspr.cpp index d918c40c5..ab50fc982 100644 --- a/src/p_pspr.cpp +++ b/src/p_pspr.cpp @@ -128,7 +128,7 @@ DPSprite::DPSprite(player_t *owner, AInventory *caller, int id) } Next = next; GC::WriteBarrier(this, next); - if (prev == NULL) + if (prev == nullptr) { Owner->psprites = this; GC::WriteBarrier(this); @@ -149,6 +149,29 @@ DPSprite::DPSprite(player_t *owner, AInventory *caller, int id) // //------------------------------------------------------------------------ +DPSprite *player_t::FindPSprite(int layer) +{ + if (layer == 0) + return nullptr; + + DPSprite *pspr = psprites; + while (pspr) + { + if (pspr->ID == layer) + break; + + pspr = pspr->Next; + } + + return pspr; +} + +//------------------------------------------------------------------------ +// +// +// +//------------------------------------------------------------------------ + DPSprite *player_t::GetPSprite(psprnum_t layer) { assert(layer > 0 && layer < NUMPSPRITES); @@ -177,29 +200,6 @@ DPSprite *player_t::GetPSprite(psprnum_t layer) return pspr; } -//------------------------------------------------------------------------ -// -// -// -//------------------------------------------------------------------------ - -DPSprite *player_t::FindPSprite(int layer) -{ - if (layer == 0) - return nullptr; - - DPSprite *pspr = psprites; - while (pspr) - { - if (pspr->ID == layer) - break; - - pspr = pspr->Next; - } - - return pspr; -} - //--------------------------------------------------------------------------- // // PROC P_NewPspriteTick diff --git a/src/p_pspr.h b/src/p_pspr.h index 68baddc70..b9104d4aa 100644 --- a/src/p_pspr.h +++ b/src/p_pspr.h @@ -62,12 +62,12 @@ public: static void NewTick(); void SetState(FState *newstate, bool pending = false); - int GetID() const { return ID; } - int GetSprite() const { return Sprite; } - int GetFrame() const { return Frame; } - FState* GetState() const { return State; } - DPSprite* GetNext() { return Next; } - AInventory* GetCaller() { return Caller; } + int GetID() const { return ID; } + int GetSprite() const { return Sprite; } + int GetFrame() const { return Frame; } + FState* GetState() const { return State; } + DPSprite* GetNext() { return Next; } + AInventory* GetCaller() { return Caller; } double x, y; double oldx, oldy; From c82620129cbbc25817a98ee327b1de791c9570a5 Mon Sep 17 00:00:00 2001 From: Leonard2 Date: Thu, 26 May 2016 21:51:52 +0200 Subject: [PATCH 11/25] Added A_OverlayFlags Allows psprites to follow the weapon and/or the player's bobbing --- src/p_pspr.cpp | 83 ++++++++++++++--------- src/p_pspr.h | 7 ++ src/p_user.cpp | 21 +++++- src/r_things.cpp | 45 +++++++++--- wadsrc/static/actors/constants.txt | 9 ++- wadsrc/static/actors/shared/inventory.txt | 1 + 6 files changed, 122 insertions(+), 44 deletions(-) diff --git a/src/p_pspr.cpp b/src/p_pspr.cpp index ab50fc982..52fc483dc 100644 --- a/src/p_pspr.cpp +++ b/src/p_pspr.cpp @@ -141,6 +141,13 @@ DPSprite::DPSprite(player_t *owner, AInventory *caller, int id) if (Next && Next->ID == ID && ID != 0) Next->Destroy(); // Replace it. + + if (ID == ps_weapon || ID == ps_flash || (ID >= NUMPSPRITES && Caller->IsKindOf(RUNTIME_CLASS(AWeapon)))) + { + Flags |= PSPF_ADDBOB; + if (ID != ps_weapon) + Flags |= PSPF_ADDWEAPON; + } } //------------------------------------------------------------------------ @@ -176,26 +183,9 @@ DPSprite *player_t::GetPSprite(psprnum_t layer) { assert(layer > 0 && layer < NUMPSPRITES); - DPSprite *weapon = nullptr; - DPSprite *pspr = psprites; - while (pspr) - { - if (pspr->ID == layer) - return pspr; - - if (pspr->ID == ps_weapon) - weapon = pspr; - - pspr = pspr->Next; - } - - pspr = new DPSprite(this, ReadyWeapon, layer); - - if (layer == ps_flash && weapon) - { - pspr->x = weapon->x; - pspr->y = weapon->y; - } + DPSprite *pspr = FindPSprite(layer); + if (pspr == nullptr) + pspr = new DPSprite(this, ReadyWeapon, layer); return pspr; } @@ -281,13 +271,16 @@ void DPSprite::SetState(FState *newstate, bool pending) Tics = 1; // great for producing decals :) } - if (newstate->GetMisc1()) - { // Set coordinates. - x = newstate->GetMisc1(); - } - if (newstate->GetMisc2()) - { - y = newstate->GetMisc2(); + if (ID != ps_flash) + { // It's still possible to set the flash layer's offsets with the action function. + if (newstate->GetMisc1()) + { // Set coordinates. + x = newstate->GetMisc1(); + } + if (newstate->GetMisc2()) + { + y = newstate->GetMisc2(); + } } if (Owner->mo != nullptr) @@ -986,6 +979,35 @@ DEFINE_ACTION_FUNCTION(AInventory, A_WeaponOffset) return 0; } +//--------------------------------------------------------------------------- +// +// PROC A_OverlayFlags +// +//--------------------------------------------------------------------------- + +DEFINE_ACTION_FUNCTION(AInventory, A_OverlayFlags) +{ + PARAM_ACTION_PROLOGUE; + PARAM_INT(layer); + PARAM_INT(flags); + PARAM_BOOL(set); + + if (self->player == nullptr) + return 0; + + DPSprite *pspr = self->player->FindPSprite(layer); + + if (pspr == nullptr) + return 0; + + if (set) + pspr->Flags |= flags; + else + pspr->Flags &= ~flags; + + return 0; +} + //--------------------------------------------------------------------------- // // PROC A_Lower @@ -1307,11 +1329,6 @@ void player_t::TickPSprites() } else { - if (weapon && flash) - { - flash->x = weapon->x; - flash->y = weapon->y; - } P_CheckWeaponSwitch(this); if (WeaponState & (WF_WEAPONREADY | WF_WEAPONREADYALT)) { @@ -1359,7 +1376,7 @@ void DPSprite::Serialize(FArchive &arc) { Super::Serialize(arc); - arc << Next << Caller << Owner + arc << Next << Caller << Owner << Flags << State << Tics << Sprite << Frame << ID << x << y << oldx << oldy; } diff --git a/src/p_pspr.h b/src/p_pspr.h index b9104d4aa..65293a79c 100644 --- a/src/p_pspr.h +++ b/src/p_pspr.h @@ -52,6 +52,12 @@ enum psprnum_t // These are all called by the owner's ReadyWeapon. NUMPSPRITES }; +enum PSPFlags +{ + PSPF_ADDWEAPON = 1 << 0, + PSPF_ADDBOB = 1 << 1, +}; + class DPSprite : public DObject { DECLARE_CLASS (DPSprite, DObject) @@ -73,6 +79,7 @@ public: double oldx, oldy; bool firstTic; int Tics; + int Flags; private: DPSprite () {} diff --git a/src/p_user.cpp b/src/p_user.cpp index 9a36fdc46..cbdab0730 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -3093,11 +3093,28 @@ void player_t::Serialize (FArchive &arc) pspr = GetPSprite(psprnum_t(i)); pspr->State = state; pspr->Tics = tics; - pspr->x = sx; - pspr->y = sy; pspr->Sprite = sprite; pspr->Frame = frame; pspr->Owner = this; + + if (i == ps_flash) + { + pspr->x = 0; + pspr->y = 0; + } + else + { + pspr->x = sx; + pspr->y = sy; + } + + pspr->Flags = 0; + if (i < ps_targetcenter) + { + pspr->Flags |= PSPF_ADDBOB; + if (i == ps_flash) + pspr->Flags |= PSPF_ADDWEAPON; + } } } } diff --git a/src/r_things.cpp b/src/r_things.cpp index 704b6509c..e194dc6d4 100644 --- a/src/r_things.cpp +++ b/src/r_things.cpp @@ -1279,7 +1279,7 @@ void R_AddSprites (sector_t *sec, int lightlevel, int fakeside) // // R_DrawPSprite // -void R_DrawPSprite(DPSprite *pspr, AActor *owner, double ofsx, double ofsy, double ticfrac) +void R_DrawPSprite(DPSprite *pspr, AActor *owner, float bobx, float boby, double wx, double wy, double ticfrac) { double tx; int x1; @@ -1331,10 +1331,17 @@ void R_DrawPSprite(DPSprite *pspr, AActor *owner, double ofsx, double ofsy, doub sx = pspr->oldx + (pspr->x - pspr->oldx) * ticfrac; sy = pspr->oldy + (pspr->y - pspr->oldy) * ticfrac; - if (isweapon) - { // [RH] Don't bob the targeter/non-weapon layers. - sx += ofsx; - sy += ofsy; + + if (pspr->Flags & PSPF_ADDBOB) + { + sx += bobx; + sy += boby; + } + + if (pspr->Flags & PSPF_ADDWEAPON) + { + sx += wx; + sy += wy; } // calculate edges of the shape @@ -1547,6 +1554,7 @@ void R_DrawPlayerSprites () int i; int lightnum; DPSprite* psp; + DPSprite* weapon; sector_t* sec = NULL; static sector_t tempsec; int floorlight, ceilinglight; @@ -1611,11 +1619,32 @@ void R_DrawPlayerSprites () if (camera->player != NULL) { double centerhack = CenterY; - float ofsx, ofsy; + double wx, wy; + float bobx, boby; CenterY = viewheight / 2; - P_BobWeapon (camera->player, &ofsx, &ofsy, r_TicFracF); + P_BobWeapon (camera->player, &bobx, &boby, r_TicFracF); + + // Interpolate the main weapon layer once so as to be able to add it to other layers. + if ((weapon = camera->player->FindPSprite(ps_weapon)) != nullptr) + { + if (weapon->firstTic) + { + wx = weapon->x; + wy = weapon->y; + } + else + { + wx = weapon->oldx + (weapon->x - weapon->oldx) * r_TicFracF; + wy = weapon->oldy + (weapon->y - weapon->oldy) * r_TicFracF; + } + } + else + { + wx = 0; + wy = 0; + } // add all active psprites psp = camera->player->psprites; @@ -1624,7 +1653,7 @@ void R_DrawPlayerSprites () // [RH] Don't draw the targeter's crosshair if the player already has a crosshair set. if (psp->GetID() != ps_targetcenter || CrosshairImage == nullptr) { - R_DrawPSprite(psp, camera, ofsx, ofsy, r_TicFracF); + R_DrawPSprite(psp, camera, bobx, boby, wx, wy, r_TicFracF); } psp = psp->GetNext(); diff --git a/wadsrc/static/actors/constants.txt b/wadsrc/static/actors/constants.txt index 911e1036b..8e082cc72 100644 --- a/wadsrc/static/actors/constants.txt +++ b/wadsrc/static/actors/constants.txt @@ -568,4 +568,11 @@ enum WOF_KEEPX = 1, WOF_KEEPY = 1 << 1, WOF_ADD = 1 << 2, -}; \ No newline at end of file +}; + +// Flags for psprite layers +enum +{ + PSPF_ADDWEAPON = 1 << 0, + PSPF_ADDBOB = 1 << 1, +}; diff --git a/wadsrc/static/actors/shared/inventory.txt b/wadsrc/static/actors/shared/inventory.txt index 396274332..0dffc106b 100644 --- a/wadsrc/static/actors/shared/inventory.txt +++ b/wadsrc/static/actors/shared/inventory.txt @@ -51,6 +51,7 @@ ACTOR Inventory native action native A_RestoreSpecialThing2(); action native A_WeaponOffset(float wx = 0, float wy = 32, int flags = 0); action native A_OverlayOffset(int layer = 1, float wx = 0, float wy = 32, int flags = 0); + action native A_OverlayFlags(int layer, int flags, bool set); States { From 2f5ae3b51e514706fe06f1d83ec2240863c49b42 Mon Sep 17 00:00:00 2001 From: Leonard2 Date: Fri, 27 May 2016 18:08:56 +0200 Subject: [PATCH 12/25] Changed the default layer indices and renamed them Note that this doesn't compile yet --- src/d_player.h | 2 +- src/p_pspr.cpp | 44 ++++++++++------------- src/p_pspr.h | 15 ++++---- src/p_user.cpp | 18 +++++++--- src/r_things.cpp | 8 ++--- wadsrc/static/actors/constants.txt | 7 ++++ wadsrc/static/actors/shared/inventory.txt | 2 +- 7 files changed, 52 insertions(+), 44 deletions(-) diff --git a/src/d_player.h b/src/d_player.h index 8a90d9680..48649de7a 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -532,7 +532,7 @@ public: void TickPSprites(); void DestroyPSprites(); DPSprite *FindPSprite(int layer); - DPSprite *GetPSprite(psprnum_t layer); // Used ONLY for compatibility with the old hardcoded layers. + DPSprite *GetPSprite(PSPLayers layer); // Used ONLY for compatibility with the old hardcoded layers. }; // Bookkeeping on players - state. diff --git a/src/p_pspr.cpp b/src/p_pspr.cpp index 52fc483dc..b37e30a6f 100644 --- a/src/p_pspr.cpp +++ b/src/p_pspr.cpp @@ -142,10 +142,10 @@ DPSprite::DPSprite(player_t *owner, AInventory *caller, int id) if (Next && Next->ID == ID && ID != 0) Next->Destroy(); // Replace it. - if (ID == ps_weapon || ID == ps_flash || (ID >= NUMPSPRITES && Caller->IsKindOf(RUNTIME_CLASS(AWeapon)))) + if (ID == PSP_WEAPON || ID == PSP_FLASH || (ID < PSP_TARGETCENTER && Caller->IsKindOf(RUNTIME_CLASS(AWeapon)))) { Flags |= PSPF_ADDBOB; - if (ID != ps_weapon) + if (ID != PSP_WEAPON) Flags |= PSPF_ADDWEAPON; } } @@ -179,10 +179,8 @@ DPSprite *player_t::FindPSprite(int layer) // //------------------------------------------------------------------------ -DPSprite *player_t::GetPSprite(psprnum_t layer) +DPSprite *player_t::GetPSprite(PSPLayers layer) { - assert(layer > 0 && layer < NUMPSPRITES); - DPSprite *pspr = FindPSprite(layer); if (pspr == nullptr) pspr = new DPSprite(this, ReadyWeapon, layer); @@ -226,14 +224,14 @@ void DPSprite::NewTick() void DPSprite::SetState(FState *newstate, bool pending) { - if (ID == ps_weapon) + if (ID == PSP_WEAPON) { // A_WeaponReady will re-set these as needed Owner->WeaponState &= ~(WF_WEAPONREADY | WF_WEAPONREADYALT | WF_WEAPONBOBBING | WF_WEAPONSWITCHOK | WF_WEAPONRELOADOK | WF_WEAPONZOOMOK | WF_USER1OK | WF_USER2OK | WF_USER3OK | WF_USER4OK); } // Special handling for the old hardcoded layers. - if (ID > 0 && ID < NUMPSPRITES) + if (ID == PSP_WEAPON || ID == PSP_FLASH || ID >= PSP_TARGETCENTER) Caller = Owner->ReadyWeapon; processPending = pending; @@ -261,9 +259,9 @@ void DPSprite::SetState(FState *newstate, bool pending) Tics = newstate->GetTics(); // could be 0 - if ((ID > 0 && ID < NUMPSPRITES) || Caller->IsKindOf(RUNTIME_CLASS(AWeapon))) + if ((ID == PSP_WEAPON || ID == PSP_FLASH || ID >= PSP_TARGETCENTER) || Caller->IsKindOf(RUNTIME_CLASS(AWeapon))) { // The targeter layers are affected by this too. - if (sv_fastweapons == 2 && ID == ps_weapon) + if (sv_fastweapons == 2 && ID == PSP_WEAPON) Tics = newstate->ActionFunc == nullptr ? 0 : 1; else if (sv_fastweapons == 3) Tics = (newstate->GetTics() != 0); @@ -271,7 +269,7 @@ void DPSprite::SetState(FState *newstate, bool pending) Tics = 1; // great for producing decals :) } - if (ID != ps_flash) + if (ID != PSP_FLASH) { // It's still possible to set the flash layer's offsets with the action function. if (newstate->GetMisc1()) { // Set coordinates. @@ -313,7 +311,7 @@ void DPSprite::SetState(FState *newstate, bool pending) return; } -void P_SetPsprite(player_t *player, psprnum_t id, FState *state, bool pending) +void P_SetPsprite(player_t *player, PSPLayers id, FState *state, bool pending) { if (player == nullptr) return; player->GetPSprite(id)->SetState(state, pending); @@ -961,7 +959,7 @@ void A_OverlayOffset(AActor *self, int layer, double wx, double wy, int flags) DEFINE_ACTION_FUNCTION(AInventory, A_OverlayOffset) { PARAM_ACTION_PROLOGUE; - PARAM_INT_OPT(layer) { layer = ps_weapon; } + PARAM_INT_OPT(layer) { layer = PSP_WEAPON; } PARAM_FLOAT_OPT(wx) { wx = 0.; } PARAM_FLOAT_OPT(wy) { wy = 32.; } PARAM_INT_OPT(flags) { flags = 0; } @@ -975,7 +973,7 @@ DEFINE_ACTION_FUNCTION(AInventory, A_WeaponOffset) PARAM_FLOAT_OPT(wx) { wx = 0.; } PARAM_FLOAT_OPT(wy) { wy = 32.; } PARAM_INT_OPT(flags) { flags = 0; } - A_OverlayOffset(self, ps_weapon, wx, wy, flags); + A_OverlayOffset(self, PSP_WEAPON, wx, wy, flags); return 0; } @@ -1290,8 +1288,6 @@ void P_SetupPsprites(player_t *player, bool startweaponup) void player_t::TickPSprites() { - DPSprite *weapon = nullptr; - DPSprite *flash = nullptr; bool noweapon = (ReadyWeapon == nullptr && (health > 0 || mo->DamageType != NAME_Fire)); DPSprite *pspr = psprites; @@ -1299,31 +1295,29 @@ void player_t::TickPSprites() { // Destroy the psprite if it's from a weapon that isn't currently selected by the player // or if it's from an inventory item that the player no longer owns. - // (except for the old hardcoded layers) - if (!(pspr->ID > 0 && pspr->ID < NUMPSPRITES) && + // Exclude the old hardcoded layers from this check. + if (!(pspr->ID == PSP_WEAPON || pspr->ID == PSP_FLASH || pspr->ID >= PSP_TARGETCENTER) && (pspr->Caller == nullptr || (pspr->Caller->IsKindOf(RUNTIME_CLASS(AWeapon)) && pspr->Caller != pspr->Owner->ReadyWeapon) || (pspr->Caller->Owner != pspr->Owner->mo))) { pspr->Destroy(); } - else if (!(pspr->ID > 0 && pspr->ID < NUMPSPRITES && noweapon)) + else if (!((pspr->ID == PSP_WEAPON || pspr->ID == PSP_FLASH || pspr->ID >= PSP_TARGETCENTER) && noweapon)) { pspr->Tick(); } - if (pspr->ID == ps_weapon) - weapon = pspr; - else if (pspr->ID == ps_flash) - flash = pspr; + if (noweapon && (pspr->ID == PSP_WEAPON || pspr->ID == PSP_FLASH)) + { // Special treatment to destroy both the flash and weapon layers. + pspr->Destroy(); + } pspr = pspr->Next; } if (noweapon) { - if (weapon) weapon->SetState(nullptr); - if (flash) flash->SetState(nullptr); if (PendingWeapon != WP_NOCHANGE) P_BringUpWeapon(this); } @@ -1356,7 +1350,7 @@ void DPSprite::Tick() // [BC] Apply double firing speed. // This is applied to the targeter layers too. - if (((ID > 0 && ID < NUMPSPRITES) || (Caller->IsKindOf(RUNTIME_CLASS(AWeapon)))) && + if (((ID == PSP_WEAPON || ID == PSP_FLASH || ID >= PSP_TARGETCENTER) || Caller->IsKindOf(RUNTIME_CLASS(AWeapon))) && (Tics && Owner->cheats & CF_DOUBLEFIRINGSPEED)) Tics--; diff --git a/src/p_pspr.h b/src/p_pspr.h index 65293a79c..edcad9dd6 100644 --- a/src/p_pspr.h +++ b/src/p_pspr.h @@ -42,14 +42,13 @@ class FArchive; // drawn directly on the view screen, // coordinates are given for a 320*200 view screen. // -enum psprnum_t // These are all called by the owner's ReadyWeapon. +enum PSPLayers // These are all called by the owner's ReadyWeapon. { - ps_weapon = 1, - ps_flash, - ps_targetcenter, - ps_targetleft, - ps_targetright, - NUMPSPRITES + PSP_WEAPON = 1, + PSP_FLASH = 1000, + PSP_TARGETCENTER = INT_MAX - 2, + PSP_TARGETLEFT, + PSP_TARGETRIGHT, }; enum PSPFlags @@ -103,7 +102,7 @@ private: void P_NewPspriteTick(); void P_CalcSwing (player_t *player); -void P_SetPsprite(player_t *player, psprnum_t id, FState *state, bool pending = false); +void P_SetPsprite(player_t *player, PSPLayers id, FState *state, bool pending = false); void P_BringUpWeapon (player_t *player); void P_FireWeapon (player_t *player); void P_DropWeapon (player_t *player); diff --git a/src/p_user.cpp b/src/p_user.cpp index cbdab0730..0f3704b25 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -3075,7 +3075,8 @@ void player_t::Serialize (FArchive &arc) if (SaveVersion < 4547) { - for (i = ps_weapon; i < NUMPSPRITES; i++) + int layer = PSP_WEAPON; + for (i = 0; i < 5; i++) { FState *state; int tics; @@ -3090,14 +3091,14 @@ void player_t::Serialize (FArchive &arc) if (state != nullptr) { DPSprite *pspr; - pspr = GetPSprite(psprnum_t(i)); + pspr = GetPSprite(PSPLayers(layer)); pspr->State = state; pspr->Tics = tics; pspr->Sprite = sprite; pspr->Frame = frame; pspr->Owner = this; - if (i == ps_flash) + if (layer == PSP_FLASH) { pspr->x = 0; pspr->y = 0; @@ -3109,13 +3110,20 @@ void player_t::Serialize (FArchive &arc) } pspr->Flags = 0; - if (i < ps_targetcenter) + if (layer < PSP_TARGETCENTER) { pspr->Flags |= PSPF_ADDBOB; - if (i == ps_flash) + if (layer == PSP_FLASH) pspr->Flags |= PSPF_ADDWEAPON; } } + + if (layer == PSP_WEAPON) + layer = PSP_FLASH; + else if (layer == PSP_FLASH) + layer = PSP_TARGETCENTER; + else + layer++; } } else diff --git a/src/r_things.cpp b/src/r_things.cpp index e194dc6d4..35b9a51fa 100644 --- a/src/r_things.cpp +++ b/src/r_things.cpp @@ -1319,8 +1319,8 @@ void R_DrawPSprite(DPSprite *pspr, AActor *owner, float bobx, float boby, double if (tex->UseType == FTexture::TEX_Null) return; - isweapon = ((pspr->GetID() > 0 && pspr->GetID() < ps_targetcenter) || - (pspr->GetID() >= NUMPSPRITES && pspr->GetCaller() && pspr->GetCaller()->IsKindOf(RUNTIME_CLASS(AWeapon)))); + isweapon = ((pspr->GetID() == PSP_WEAPON || pspr->GetID() == PSP_FLASH) || + (pspr->GetID() < PSP_TARGETCENTER && pspr->GetCaller()->IsKindOf(RUNTIME_CLASS(AWeapon)))); if (pspr->firstTic) { // Can't interpolate the first tic. @@ -1627,7 +1627,7 @@ void R_DrawPlayerSprites () P_BobWeapon (camera->player, &bobx, &boby, r_TicFracF); // Interpolate the main weapon layer once so as to be able to add it to other layers. - if ((weapon = camera->player->FindPSprite(ps_weapon)) != nullptr) + if ((weapon = camera->player->FindPSprite(PSP_WEAPON)) != nullptr) { if (weapon->firstTic) { @@ -1651,7 +1651,7 @@ void R_DrawPlayerSprites () while (psp) { // [RH] Don't draw the targeter's crosshair if the player already has a crosshair set. - if (psp->GetID() != ps_targetcenter || CrosshairImage == nullptr) + if (psp->GetID() != PSP_TARGETCENTER || CrosshairImage == nullptr) { R_DrawPSprite(psp, camera, bobx, boby, wx, wy, r_TicFracF); } diff --git a/wadsrc/static/actors/constants.txt b/wadsrc/static/actors/constants.txt index 8e082cc72..d65e9e463 100644 --- a/wadsrc/static/actors/constants.txt +++ b/wadsrc/static/actors/constants.txt @@ -576,3 +576,10 @@ enum PSPF_ADDWEAPON = 1 << 0, PSPF_ADDBOB = 1 << 1, }; + +// Default psprite layers +enum +{ + PSP_WEAPON = 1, + PSP_FLASH = 1000, +}; diff --git a/wadsrc/static/actors/shared/inventory.txt b/wadsrc/static/actors/shared/inventory.txt index 0dffc106b..d523afe5c 100644 --- a/wadsrc/static/actors/shared/inventory.txt +++ b/wadsrc/static/actors/shared/inventory.txt @@ -50,7 +50,7 @@ ACTOR Inventory native action native A_RestoreSpecialThing1(); action native A_RestoreSpecialThing2(); action native A_WeaponOffset(float wx = 0, float wy = 32, int flags = 0); - action native A_OverlayOffset(int layer = 1, float wx = 0, float wy = 32, int flags = 0); + action native A_OverlayOffset(int layer = PSP_WEAPON, float wx = 0, float wy = 32, int flags = 0); action native A_OverlayFlags(int layer, int flags, bool set); States From 360ad7a8445bdd96e266113688e38b4111dd6d85 Mon Sep 17 00:00:00 2001 From: Leonard2 Date: Fri, 27 May 2016 19:01:03 +0200 Subject: [PATCH 13/25] Replaced every remaining instances of the old layer names --- src/g_doom/a_doomweaps.cpp | 14 ++++++------- src/g_heretic/a_chicken.cpp | 10 +++++----- src/g_heretic/a_hereticweaps.cpp | 12 +++++------ src/g_hexen/a_clericstaff.cpp | 4 ++-- src/g_hexen/a_fighteraxe.cpp | 12 +++++------ src/g_hexen/a_fighterplayer.cpp | 2 +- src/g_hexen/a_pig.cpp | 2 +- src/g_shared/a_artifacts.cpp | 34 ++++++++++++++++---------------- src/g_shared/a_weapons.cpp | 2 +- src/g_strife/a_strifestuff.cpp | 8 ++++---- src/g_strife/a_strifeweapons.cpp | 16 +++++++-------- src/m_cheat.cpp | 6 +++--- src/p_mobj.cpp | 4 ++-- src/p_pspr.cpp | 26 ++++++++++++------------ src/p_user.cpp | 4 ++-- 15 files changed, 78 insertions(+), 78 deletions(-) diff --git a/src/g_doom/a_doomweaps.cpp b/src/g_doom/a_doomweaps.cpp index 0d87e803e..c5eb9f1a8 100644 --- a/src/g_doom/a_doomweaps.cpp +++ b/src/g_doom/a_doomweaps.cpp @@ -81,7 +81,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FirePistol) if (!weapon->DepleteAmmo (weapon->bAltFire, true, 1)) return 0; - P_SetPsprite(self->player, ps_flash, weapon->FindState(NAME_Flash), true); + P_SetPsprite(self->player, PSP_FLASH, weapon->FindState(NAME_Flash), true); } self->player->mo->PlayAttacking2 (); @@ -273,7 +273,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireShotgun) { if (!weapon->DepleteAmmo (weapon->bAltFire, true, 1)) return 0; - P_SetPsprite(player, ps_flash, weapon->FindState(NAME_Flash), true); + P_SetPsprite(player, PSP_FLASH, weapon->FindState(NAME_Flash), true); } player->mo->PlayAttacking2 (); @@ -309,7 +309,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireShotgun2) { if (!weapon->DepleteAmmo (weapon->bAltFire, true, 2)) return 0; - P_SetPsprite(player, ps_flash, weapon->FindState(NAME_Flash), true); + P_SetPsprite(player, PSP_FLASH, weapon->FindState(NAME_Flash), true); } player->mo->PlayAttacking2 (); @@ -381,13 +381,13 @@ void P_SetSafeFlash(AWeapon *weapon, player_t *player, FState *flashstate, int i if (flashstate + index < cls->OwnedStates + cls->NumOwnedStates) { // we're ok so set the state - P_SetPsprite(player, ps_flash, flashstate + index, true); + P_SetPsprite(player, PSP_FLASH, flashstate + index, true); return; } else { // oh, no! The state is beyond the end of the state table so use the original flash state. - P_SetPsprite(player, ps_flash, flashstate, true); + P_SetPsprite(player, PSP_FLASH, flashstate, true); return; } } @@ -403,7 +403,7 @@ void P_SetSafeFlash(AWeapon *weapon, player_t *player, FState *flashstate, int i { // Invalid state. With no index offset, it should at least be valid. index = 0; } - P_SetPsprite(player, ps_flash, flashstate + index, true); + P_SetPsprite(player, PSP_FLASH, flashstate + index, true); } // @@ -434,7 +434,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireCGun) // [RH] Fix for Sparky's messed-up Dehacked patch! Blargh! FState * atk = weapon->FindState(NAME_Fire); - int theflash = clamp (int(player->GetPSprite(ps_weapon)->GetState() - atk), 0, 1); + int theflash = clamp (int(player->GetPSprite(PSP_WEAPON)->GetState() - atk), 0, 1); if (flash[theflash].sprite != flash->sprite) { diff --git a/src/g_heretic/a_chicken.cpp b/src/g_heretic/a_chicken.cpp index e9844b57e..b70e4ff08 100644 --- a/src/g_heretic/a_chicken.cpp +++ b/src/g_heretic/a_chicken.cpp @@ -125,7 +125,7 @@ void P_UpdateBeak (AActor *self) { if (self->player != nullptr) { - self->player->GetPSprite(ps_weapon)->y = WEAPONTOP + self->player->chickenPeck / 2; + self->player->GetPSprite(PSP_WEAPON)->y = WEAPONTOP + self->player->chickenPeck / 2; } } @@ -145,8 +145,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_BeakRaise) { return 0; } - player->GetPSprite(ps_weapon)->y = WEAPONTOP; - P_SetPsprite(player, ps_weapon, player->ReadyWeapon->GetReadyState()); + player->GetPSprite(PSP_WEAPON)->y = WEAPONTOP; + P_SetPsprite(player, PSP_WEAPON, player->ReadyWeapon->GetReadyState()); return 0; } @@ -192,7 +192,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_BeakAttackPL1) } P_PlayPeck (player->mo); player->chickenPeck = 12; - player->GetPSprite(ps_weapon)->Tics -= pr_beakatkpl1() & 7; + player->GetPSprite(PSP_WEAPON)->Tics -= pr_beakatkpl1() & 7; return 0; } @@ -227,6 +227,6 @@ DEFINE_ACTION_FUNCTION(AActor, A_BeakAttackPL2) } P_PlayPeck (player->mo); player->chickenPeck = 12; - player->GetPSprite(ps_weapon)->Tics -= pr_beakatkpl2()&3; + player->GetPSprite(PSP_WEAPON)->Tics -= pr_beakatkpl2()&3; return 0; } diff --git a/src/g_heretic/a_hereticweaps.cpp b/src/g_heretic/a_hereticweaps.cpp index 344fc33c6..5283c9884 100644 --- a/src/g_heretic/a_hereticweaps.cpp +++ b/src/g_heretic/a_hereticweaps.cpp @@ -272,8 +272,8 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_GauntletAttack) if (!weapon->DepleteAmmo (weapon->bAltFire)) return 0; } - player->GetPSprite(ps_weapon)->x = ((pr_gatk()&3)-2); - player->GetPSprite(ps_weapon)->y = WEAPONTOP + (pr_gatk()&3); + player->GetPSprite(PSP_WEAPON)->x = ((pr_gatk()&3)-2); + player->GetPSprite(PSP_WEAPON)->y = WEAPONTOP + (pr_gatk()&3); Angle = self->Angles.Yaw; if (power) { @@ -441,8 +441,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireMacePL1) if (!weapon->DepleteAmmo(weapon->bAltFire)) return 0; } - player->GetPSprite(ps_weapon)->x = ((pr_maceatk() & 3) - 2); - player->GetPSprite(ps_weapon)->y = WEAPONTOP + (pr_maceatk() & 3); + player->GetPSprite(PSP_WEAPON)->x = ((pr_maceatk() & 3) - 2); + player->GetPSprite(PSP_WEAPON)->y = WEAPONTOP + (pr_maceatk() & 3); ball = P_SpawnPlayerMissile(self, PClass::FindActor("MaceFX1"), self->Angles.Yaw + (((pr_maceatk() & 7) - 4) * (360. / 256))); if (ball) { @@ -1158,7 +1158,7 @@ IMPLEMENT_CLASS (APhoenixRodPowered) void APhoenixRodPowered::EndPowerup () { - P_SetPsprite(Owner->player, ps_weapon, SisterWeapon->GetReadyState()); + P_SetPsprite(Owner->player, PSP_WEAPON, SisterWeapon->GetReadyState()); DepleteAmmo (bAltFire); Owner->player->refire = 0; S_StopSound (Owner, CHAN_WEAPON); @@ -1308,7 +1308,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FirePhoenixPL2) flamethrower = static_cast (player->ReadyWeapon); if (flamethrower == nullptr || --flamethrower->FlameCount == 0) { // Out of flame - P_SetPsprite(player, ps_weapon, flamethrower->FindState("Powerdown")); + P_SetPsprite(player, PSP_WEAPON, flamethrower->FindState("Powerdown")); player->refire = 0; S_StopSound (self, CHAN_WEAPON); return 0; diff --git a/src/g_hexen/a_clericstaff.cpp b/src/g_hexen/a_clericstaff.cpp index d67baba8e..de4e1d75f 100644 --- a/src/g_hexen/a_clericstaff.cpp +++ b/src/g_hexen/a_clericstaff.cpp @@ -92,7 +92,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CStaffCheck) if (weapon != nullptr) { FState * newstate = weapon->FindState("Drain"); - if (newstate != nullptr) P_SetPsprite(player, ps_weapon, newstate); + if (newstate != nullptr) P_SetPsprite(player, PSP_WEAPON, newstate); } } if (weapon != nullptr) @@ -187,7 +187,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CStaffCheckBlink) { if (!--self->weaponspecial) { - P_SetPsprite(self->player, ps_weapon, self->player->ReadyWeapon->FindState ("Blink")); + P_SetPsprite(self->player, PSP_WEAPON, self->player->ReadyWeapon->FindState ("Blink")); self->weaponspecial = (pr_blink()+50)>>2; } else diff --git a/src/g_hexen/a_fighteraxe.cpp b/src/g_hexen/a_fighteraxe.cpp index 98ed409f7..f47ad6a9d 100644 --- a/src/g_hexen/a_fighteraxe.cpp +++ b/src/g_hexen/a_fighteraxe.cpp @@ -76,7 +76,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FAxeCheckReady) } if (player->ReadyWeapon->Ammo1->Amount) { - P_SetPsprite(player, ps_weapon, player->ReadyWeapon->FindState ("ReadyGlow")); + P_SetPsprite(player, PSP_WEAPON, player->ReadyWeapon->FindState ("ReadyGlow")); } else { @@ -103,7 +103,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FAxeCheckReadyG) } if (player->ReadyWeapon->Ammo1->Amount <= 0) { - P_SetPsprite(player, ps_weapon, player->ReadyWeapon->FindState ("Ready")); + P_SetPsprite(player, PSP_WEAPON, player->ReadyWeapon->FindState ("Ready")); } else { @@ -130,7 +130,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FAxeCheckUp) } if (player->ReadyWeapon->Ammo1->Amount) { - P_SetPsprite(player, ps_weapon, player->ReadyWeapon->FindState ("SelectGlow")); + P_SetPsprite(player, PSP_WEAPON, player->ReadyWeapon->FindState ("SelectGlow")); } else { @@ -157,7 +157,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FAxeCheckUpG) } if (player->ReadyWeapon->Ammo1->Amount <= 0) { - P_SetPsprite(player, ps_weapon, player->ReadyWeapon->FindState ("Select")); + P_SetPsprite(player, PSP_WEAPON, player->ReadyWeapon->FindState ("Select")); } else { @@ -184,7 +184,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FAxeCheckAtk) } if (player->ReadyWeapon->Ammo1->Amount) { - P_SetPsprite(player, ps_weapon, player->ReadyWeapon->FindState ("FireGlow")); + P_SetPsprite(player, PSP_WEAPON, player->ReadyWeapon->FindState ("FireGlow")); } return 0; } @@ -273,7 +273,7 @@ axedone: (!(weapon->WeaponFlags & WIF_PRIMARY_USES_BOTH) || weapon->Ammo2 == nullptr || weapon->Ammo2->Amount == 0)) { - P_SetPsprite(player, ps_weapon, player->ReadyWeapon->FindState ("Fire") + 5); + P_SetPsprite(player, PSP_WEAPON, player->ReadyWeapon->FindState ("Fire") + 5); } } } diff --git a/src/g_hexen/a_fighterplayer.cpp b/src/g_hexen/a_fighterplayer.cpp index 1ec9372ed..3624ed625 100644 --- a/src/g_hexen/a_fighterplayer.cpp +++ b/src/g_hexen/a_fighterplayer.cpp @@ -120,7 +120,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FPunchAttack) if (pmo->weaponspecial >= 3) { pmo->weaponspecial = 0; - P_SetPsprite(player, ps_weapon, player->ReadyWeapon->FindState("Fire2")); + P_SetPsprite(player, PSP_WEAPON, player->ReadyWeapon->FindState("Fire2")); S_Sound (pmo, CHAN_VOICE, "*fistgrunt", 1, ATTN_NORM); } return 0; diff --git a/src/g_hexen/a_pig.cpp b/src/g_hexen/a_pig.cpp index e1fb0b224..ea767dccd 100644 --- a/src/g_hexen/a_pig.cpp +++ b/src/g_hexen/a_pig.cpp @@ -39,7 +39,7 @@ void APigPlayer::MorphPlayerThink () { // Snout sniff if (player->ReadyWeapon != nullptr) { - P_SetPsprite(player, ps_weapon, player->ReadyWeapon->FindState("Grunt")); + P_SetPsprite(player, PSP_WEAPON, player->ReadyWeapon->FindState("Grunt")); } S_Sound (this, CHAN_VOICE, "PigActive1", 1, ATTN_NORM); // snort return; diff --git a/src/g_shared/a_artifacts.cpp b/src/g_shared/a_artifacts.cpp index 32a6da15a..f89c1360d 100644 --- a/src/g_shared/a_artifacts.cpp +++ b/src/g_shared/a_artifacts.cpp @@ -1131,7 +1131,7 @@ void APowerWeaponLevel2::InitEffect () if (weapon->GetReadyState() != sister->GetReadyState()) { - P_SetPsprite(Owner->player, ps_weapon, sister->GetReadyState()); + P_SetPsprite(Owner->player, PSP_WEAPON, sister->GetReadyState()); } } @@ -1305,15 +1305,15 @@ void APowerTargeter::InitEffect () if (state != nullptr) { - P_SetPsprite(player, ps_targetcenter, state + 0); - P_SetPsprite(player, ps_targetleft, state + 1); - P_SetPsprite(player, ps_targetright, state + 2); + P_SetPsprite(player, PSP_TARGETCENTER, state + 0); + P_SetPsprite(player, PSP_TARGETLEFT, state + 1); + P_SetPsprite(player, PSP_TARGETRIGHT, state + 2); } - player->GetPSprite(ps_targetcenter)->x = (160-3); - player->GetPSprite(ps_targetcenter)->y = - player->GetPSprite(ps_targetleft)->y = - player->GetPSprite(ps_targetright)->y = (100-3); + player->GetPSprite(PSP_TARGETCENTER)->x = (160-3); + player->GetPSprite(PSP_TARGETCENTER)->y = + player->GetPSprite(PSP_TARGETLEFT)->y = + player->GetPSprite(PSP_TARGETRIGHT)->y = (100-3); PositionAccuracy (); } @@ -1346,13 +1346,13 @@ void APowerTargeter::DoEffect () { if (EffectTics & 32) { - P_SetPsprite(player, ps_targetright, nullptr); - P_SetPsprite(player, ps_targetleft, state + 1); + P_SetPsprite(player, PSP_TARGETRIGHT, nullptr); + P_SetPsprite(player, PSP_TARGETLEFT, state + 1); } else if (EffectTics & 16) { - P_SetPsprite(player, ps_targetright, state + 2); - P_SetPsprite(player, ps_targetleft, nullptr); + P_SetPsprite(player, PSP_TARGETRIGHT, state + 2); + P_SetPsprite(player, PSP_TARGETLEFT, nullptr); } } } @@ -1364,9 +1364,9 @@ void APowerTargeter::EndEffect () Super::EndEffect(); if (Owner != nullptr && Owner->player != nullptr) { - P_SetPsprite (Owner->player, ps_targetcenter, nullptr); - P_SetPsprite (Owner->player, ps_targetleft, nullptr); - P_SetPsprite (Owner->player, ps_targetright, nullptr); + P_SetPsprite (Owner->player, PSP_TARGETCENTER, nullptr); + P_SetPsprite (Owner->player, PSP_TARGETLEFT, nullptr); + P_SetPsprite (Owner->player, PSP_TARGETRIGHT, nullptr); } } @@ -1376,8 +1376,8 @@ void APowerTargeter::PositionAccuracy () if (player != nullptr) { - player->GetPSprite(ps_targetleft)->x = (160-3) - ((100 - player->mo->accuracy)); - player->GetPSprite(ps_targetright)->x = (160-3)+ ((100 - player->mo->accuracy)); + player->GetPSprite(PSP_TARGETLEFT)->x = (160-3) - ((100 - player->mo->accuracy)); + player->GetPSprite(PSP_TARGETRIGHT)->x = (160-3)+ ((100 - player->mo->accuracy)); } } diff --git a/src/g_shared/a_weapons.cpp b/src/g_shared/a_weapons.cpp index f561a26de..e7ebfc77b 100644 --- a/src/g_shared/a_weapons.cpp +++ b/src/g_shared/a_weapons.cpp @@ -617,7 +617,7 @@ void AWeapon::PostMorphWeapon () Owner->player->ReadyWeapon = this; Owner->player->refire = 0; - pspr = Owner->player->GetPSprite(ps_weapon); + pspr = Owner->player->GetPSprite(PSP_WEAPON); pspr->y = WEAPONBOTTOM; pspr->SetState(GetUpState()); } diff --git a/src/g_strife/a_strifestuff.cpp b/src/g_strife/a_strifestuff.cpp index cefd10ba2..fd8b797fb 100644 --- a/src/g_strife/a_strifestuff.cpp +++ b/src/g_strife/a_strifestuff.cpp @@ -352,8 +352,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_ItBurnsItBurns) if (self->player != nullptr && self->player->mo == self) { - P_SetPsprite(self->player, ps_weapon, self->FindState("FireHands")); - P_SetPsprite(self->player, ps_flash, nullptr); + P_SetPsprite(self->player, PSP_WEAPON, self->FindState("FireHands")); + P_SetPsprite(self->player, PSP_FLASH, nullptr); self->player->ReadyWeapon = nullptr; self->player->PendingWeapon = WP_NOCHANGE; self->player->playerstate = PST_LIVE; @@ -381,7 +381,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CrispyPlayer) self->player->playerstate = PST_DEAD; DPSprite *psp; - psp = self->player->GetPSprite(ps_weapon); + psp = self->player->GetPSprite(PSP_WEAPON); psp->SetState(psp->GetState() + (self->FindState("FireHandsLower") - self->FindState("FireHands"))); } return 0; @@ -393,7 +393,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_HandLower) if (self->player != nullptr) { - DPSprite *psp = self->player->GetPSprite(ps_weapon); + DPSprite *psp = self->player->GetPSprite(PSP_WEAPON); psp->y += 9; if (psp->y > WEAPONBOTTOM*2) { diff --git a/src/g_strife/a_strifeweapons.cpp b/src/g_strife/a_strifeweapons.cpp index 4e81e218c..f81ca79f7 100644 --- a/src/g_strife/a_strifeweapons.cpp +++ b/src/g_strife/a_strifeweapons.cpp @@ -219,7 +219,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_ClearFlash) if (player == nullptr) return 0; - P_SetPsprite (player, ps_flash, nullptr); + P_SetPsprite (player, PSP_FLASH, nullptr); return 0; } @@ -235,7 +235,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_ShowElectricFlash) if (self->player != nullptr) { - P_SetPsprite (self->player, ps_flash, self->player->ReadyWeapon->FindState(NAME_Flash)); + P_SetPsprite (self->player, PSP_FLASH, self->player->ReadyWeapon->FindState(NAME_Flash)); } return 0; } @@ -500,8 +500,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireMauler2Pre) if (self->player != nullptr) { - self->player->GetPSprite(ps_weapon)->x += pr_mauler2.Random2() / 64.; - self->player->GetPSprite(ps_weapon)->y += pr_mauler2.Random2() / 64.; + self->player->GetPSprite(PSP_WEAPON)->x += pr_mauler2.Random2() / 64.; + self->player->GetPSprite(PSP_WEAPON)->y += pr_mauler2.Random2() / 64.; } return 0; } @@ -707,7 +707,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FireGrenade) if (!weapon->DepleteAmmo (weapon->bAltFire)) return 0; - P_SetPsprite (player, ps_flash, flash, true); + P_SetPsprite (player, PSP_FLASH, flash, true); if (grenadetype != nullptr) { @@ -856,7 +856,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SelectSigilView) return 0; } pieces = static_cast(self->player->ReadyWeapon)->NumPieces; - pspr = self->player->GetPSprite(ps_weapon); + pspr = self->player->GetPSprite(PSP_WEAPON); pspr->SetState(pspr->GetState() + pieces); return 0; } @@ -888,7 +888,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SelectSigilDown) { pieces = static_cast(self->player->ReadyWeapon)->NumPieces; } - pspr = self->player->GetPSprite(ps_weapon); + pspr = self->player->GetPSprite(PSP_WEAPON); pspr->SetState(pspr->GetState() + pieces); return 0; } @@ -913,7 +913,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SelectSigilAttack) return 0; } pieces = static_cast(self->player->ReadyWeapon)->NumPieces; - pspr = self->player->GetPSprite(ps_weapon); + pspr = self->player->GetPSprite(PSP_WEAPON); pspr->SetState(pspr->GetState() + 4*pieces - 3); return 0; } diff --git a/src/m_cheat.cpp b/src/m_cheat.cpp index 9c5df642c..d4b0e980f 100644 --- a/src/m_cheat.cpp +++ b/src/m_cheat.cpp @@ -345,7 +345,7 @@ void cht_DoCheat (player_t *player, int cheat) player->mo->DamageType = NAME_None; if (player->ReadyWeapon != nullptr) { - P_SetPsprite(player, ps_weapon, player->ReadyWeapon->GetUpState()); + P_SetPsprite(player, PSP_WEAPON, player->ReadyWeapon->GetUpState()); } if (player->morphTics > 0) @@ -934,8 +934,8 @@ void cht_Take (player_t *player, const char *name, int amount) player->ReadyWeapon = nullptr; player->PendingWeapon = WP_NOCHANGE; - P_SetPsprite(player, ps_weapon, nullptr); - P_SetPsprite(player, ps_flash, nullptr); + P_SetPsprite(player, PSP_WEAPON, nullptr); + P_SetPsprite(player, PSP_FLASH, nullptr); } } diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index b414c1baa..0087d25de 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -1001,8 +1001,8 @@ void AActor::ClearInventory() { player->ReadyWeapon = nullptr; player->PendingWeapon = WP_NOCHANGE; - P_SetPsprite(player, ps_weapon, nullptr); - P_SetPsprite(player, ps_flash, nullptr); + P_SetPsprite(player, PSP_WEAPON, nullptr); + P_SetPsprite(player, PSP_FLASH, nullptr); } } diff --git a/src/p_pspr.cpp b/src/p_pspr.cpp index b37e30a6f..02ba29180 100644 --- a/src/p_pspr.cpp +++ b/src/p_pspr.cpp @@ -330,7 +330,7 @@ void P_BringUpWeapon (player_t *player) { FState *newstate; AWeapon *weapon; - DPSprite *psweapon = player->GetPSprite(ps_weapon); + DPSprite *psweapon = player->GetPSprite(PSP_WEAPON); if (player->PendingWeapon == WP_NOCHANGE) { @@ -373,7 +373,7 @@ void P_BringUpWeapon (player_t *player) ? 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. - P_SetPsprite(player, ps_flash, nullptr); + P_SetPsprite(player, PSP_FLASH, nullptr); psweapon->SetState(newstate); player->mo->weaponspecial = 0; } @@ -407,7 +407,7 @@ void P_FireWeapon (player_t *player, FState *state) { state = weapon->GetAtkState(!!player->refire); } - P_SetPsprite(player, ps_weapon, state); + P_SetPsprite(player, PSP_WEAPON, state); if (!(weapon->WeaponFlags & WIF_NOALERT)) { P_NoiseAlert (player->mo, player->mo, false); @@ -445,7 +445,7 @@ void P_FireWeaponAlt (player_t *player, FState *state) state = weapon->GetAltAtkState(!!player->refire); } - P_SetPsprite(player, ps_weapon, state); + P_SetPsprite(player, PSP_WEAPON, state); if (!(weapon->WeaponFlags & WIF_NOALERT)) { P_NoiseAlert (player->mo, player->mo, false); @@ -470,7 +470,7 @@ void P_DropWeapon (player_t *player) player->WeaponState &= ~WF_DISABLESWITCH; if (player->ReadyWeapon != nullptr) { - P_SetPsprite(player, ps_weapon, player->ReadyWeapon->GetDownState()); + P_SetPsprite(player, PSP_WEAPON, player->ReadyWeapon->GetDownState()); } } @@ -647,7 +647,7 @@ void DoReadyWeaponToFire (AActor *self, bool prim, bool alt) } // Play ready sound, if any. - if (weapon->ReadySound && player->GetPSprite(ps_weapon)->GetState() == weapon->FindState(NAME_Ready)) + if (weapon->ReadySound && player->GetPSprite(PSP_WEAPON)->GetState() == weapon->FindState(NAME_Ready)) { if (!(weapon->WeaponFlags & WIF_READYSNDHALF) || pr_wpnreadysnd() < 128) { @@ -666,8 +666,8 @@ void DoReadyWeaponToBob (AActor *self) { // Prepare for bobbing action. self->player->WeaponState |= WF_WEAPONBOBBING; - self->player->GetPSprite(ps_weapon)->x = 0; - self->player->GetPSprite(ps_weapon)->y = WEAPONTOP; + self->player->GetPSprite(PSP_WEAPON)->x = 0; + self->player->GetPSprite(PSP_WEAPON)->y = WEAPONTOP; } } @@ -814,7 +814,7 @@ static void P_CheckWeaponButtons (player_t *player) // state, the weapon won't disappear. ;) if (state != nullptr) { - P_SetPsprite(player, ps_weapon, state); + P_SetPsprite(player, PSP_WEAPON, state); return; } } @@ -1023,7 +1023,7 @@ DEFINE_ACTION_FUNCTION(AInventory, A_Lower) { return 0; } - psp = player->GetPSprite(ps_weapon); + psp = player->GetPSprite(PSP_WEAPON); if (player->morphTics || player->cheats & CF_INSTANTWEAPSWITCH) { psp->y = WEAPONBOTTOM; @@ -1045,7 +1045,7 @@ DEFINE_ACTION_FUNCTION(AInventory, A_Lower) return 0; } // [RH] Clear the flash state. Only needed for Strife. - P_SetPsprite(player, ps_flash, nullptr); + P_SetPsprite(player, PSP_FLASH, nullptr); P_BringUpWeapon (player); return 0; } @@ -1076,7 +1076,7 @@ DEFINE_ACTION_FUNCTION(AInventory, A_Raise) P_DropWeapon(player); return 0; } - psp = player->GetPSprite(ps_weapon); + psp = player->GetPSprite(PSP_WEAPON); psp->y -= RAISESPEED; if (psp->y > WEAPONTOP) { // Not raised all the way yet @@ -1152,7 +1152,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AInventory, A_GunFlash) flash = player->ReadyWeapon->FindState(NAME_Flash); } } - P_SetPsprite(player, ps_flash, flash); + P_SetPsprite(player, PSP_FLASH, flash); return 0; } diff --git a/src/p_user.cpp b/src/p_user.cpp index 0f3704b25..921702388 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -1376,7 +1376,7 @@ void APlayerPawn::MorphPlayerThink () void APlayerPawn::ActivateMorphWeapon () { PClassActor *morphweapon = PClass::FindActor (MorphWeapon); - DPSprite *pspr = player->GetPSprite(ps_weapon); + DPSprite *pspr = player->GetPSprite(PSP_WEAPON); player->PendingWeapon = WP_NOCHANGE; pspr->y = WEAPONTOP; @@ -1405,7 +1405,7 @@ void APlayerPawn::ActivateMorphWeapon () pspr->SetState(nullptr); } } - P_SetPsprite(player, ps_flash, nullptr); + P_SetPsprite(player, PSP_FLASH, nullptr); player->PendingWeapon = WP_NOCHANGE; } From d933f77bf5e5ea58c9f8cdfac02f6573d57ce328 Mon Sep 17 00:00:00 2001 From: Leonard2 Date: Thu, 2 Jun 2016 19:43:21 +0200 Subject: [PATCH 14/25] Fixed: the game could crash if some inventory items were destroyed in a certain way --- src/r_things.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/r_things.cpp b/src/r_things.cpp index 35b9a51fa..309d18bf4 100644 --- a/src/r_things.cpp +++ b/src/r_things.cpp @@ -1651,7 +1651,10 @@ void R_DrawPlayerSprites () while (psp) { // [RH] Don't draw the targeter's crosshair if the player already has a crosshair set. - if (psp->GetID() != PSP_TARGETCENTER || CrosshairImage == nullptr) + // It's possible this psprite's caller is now null but the layer itself hasn't been destroyed + // because it didn't tick yet (if we typed 'take all' while in the console for example). + // In this case let's simply not draw it to avoid crashing. + if ((psp->GetID() != PSP_TARGETCENTER || CrosshairImage == nullptr) && psp->GetCaller() != nullptr) { R_DrawPSprite(psp, camera, bobx, boby, wx, wy, r_TicFracF); } From 8668719bbcfaeac16438bd529ab61f696cb562c0 Mon Sep 17 00:00:00 2001 From: Leonard2 Date: Sun, 29 May 2016 23:21:49 +0200 Subject: [PATCH 15/25] Revert "- re-added P_SetPSrite." This reverts commit e6d89b9f71aa840a2995ff00d40d5541be6ed25a. --- src/g_doom/a_doomweaps.cpp | 12 ++++++------ src/g_heretic/a_chicken.cpp | 2 +- src/g_heretic/a_hereticweaps.cpp | 4 ++-- src/g_hexen/a_clericstaff.cpp | 4 ++-- src/g_hexen/a_fighteraxe.cpp | 12 ++++++------ src/g_hexen/a_fighterplayer.cpp | 2 +- src/g_hexen/a_pig.cpp | 2 +- src/g_shared/a_artifacts.cpp | 22 +++++++++++----------- src/g_strife/a_strifestuff.cpp | 4 ++-- src/g_strife/a_strifeweapons.cpp | 6 +++--- src/m_cheat.cpp | 6 +++--- src/p_mobj.cpp | 4 ++-- src/p_pspr.cpp | 20 +++++++------------- src/p_pspr.h | 1 - src/p_user.cpp | 2 +- 15 files changed, 48 insertions(+), 55 deletions(-) diff --git a/src/g_doom/a_doomweaps.cpp b/src/g_doom/a_doomweaps.cpp index c5eb9f1a8..7f1f578ca 100644 --- a/src/g_doom/a_doomweaps.cpp +++ b/src/g_doom/a_doomweaps.cpp @@ -81,7 +81,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FirePistol) if (!weapon->DepleteAmmo (weapon->bAltFire, true, 1)) return 0; - P_SetPsprite(self->player, PSP_FLASH, weapon->FindState(NAME_Flash), true); + self->player->GetPSprite(PSP_FLASH)->SetState(weapon->FindState(NAME_Flash), true); } self->player->mo->PlayAttacking2 (); @@ -273,7 +273,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireShotgun) { if (!weapon->DepleteAmmo (weapon->bAltFire, true, 1)) return 0; - P_SetPsprite(player, PSP_FLASH, weapon->FindState(NAME_Flash), true); + player->GetPSprite(PSP_FLASH)->SetState(weapon->FindState(NAME_Flash), true); } player->mo->PlayAttacking2 (); @@ -309,7 +309,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireShotgun2) { if (!weapon->DepleteAmmo (weapon->bAltFire, true, 2)) return 0; - P_SetPsprite(player, PSP_FLASH, weapon->FindState(NAME_Flash), true); + player->GetPSprite(PSP_FLASH)->SetState(weapon->FindState(NAME_Flash), true); } player->mo->PlayAttacking2 (); @@ -381,13 +381,13 @@ void P_SetSafeFlash(AWeapon *weapon, player_t *player, FState *flashstate, int i if (flashstate + index < cls->OwnedStates + cls->NumOwnedStates) { // we're ok so set the state - P_SetPsprite(player, PSP_FLASH, flashstate + index, true); + player->GetPSprite(PSP_FLASH)->SetState(flashstate + index, true); return; } else { // oh, no! The state is beyond the end of the state table so use the original flash state. - P_SetPsprite(player, PSP_FLASH, flashstate, true); + player->GetPSprite(PSP_FLASH)->SetState(flashstate, true); return; } } @@ -403,7 +403,7 @@ void P_SetSafeFlash(AWeapon *weapon, player_t *player, FState *flashstate, int i { // Invalid state. With no index offset, it should at least be valid. index = 0; } - P_SetPsprite(player, PSP_FLASH, flashstate + index, true); + player->GetPSprite(PSP_FLASH)->SetState(flashstate + index, true); } // diff --git a/src/g_heretic/a_chicken.cpp b/src/g_heretic/a_chicken.cpp index b70e4ff08..4e496bb44 100644 --- a/src/g_heretic/a_chicken.cpp +++ b/src/g_heretic/a_chicken.cpp @@ -146,7 +146,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_BeakRaise) return 0; } player->GetPSprite(PSP_WEAPON)->y = WEAPONTOP; - P_SetPsprite(player, PSP_WEAPON, player->ReadyWeapon->GetReadyState()); + player->GetPSprite(PSP_WEAPON)->SetState(player->ReadyWeapon->GetReadyState()); return 0; } diff --git a/src/g_heretic/a_hereticweaps.cpp b/src/g_heretic/a_hereticweaps.cpp index 5283c9884..fba33e257 100644 --- a/src/g_heretic/a_hereticweaps.cpp +++ b/src/g_heretic/a_hereticweaps.cpp @@ -1158,7 +1158,7 @@ IMPLEMENT_CLASS (APhoenixRodPowered) void APhoenixRodPowered::EndPowerup () { - P_SetPsprite(Owner->player, PSP_WEAPON, SisterWeapon->GetReadyState()); + Owner->player->GetPSprite(PSP_WEAPON)->SetState(SisterWeapon->GetReadyState()); DepleteAmmo (bAltFire); Owner->player->refire = 0; S_StopSound (Owner, CHAN_WEAPON); @@ -1308,7 +1308,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FirePhoenixPL2) flamethrower = static_cast (player->ReadyWeapon); if (flamethrower == nullptr || --flamethrower->FlameCount == 0) { // Out of flame - P_SetPsprite(player, PSP_WEAPON, flamethrower->FindState("Powerdown")); + player->GetPSprite(PSP_WEAPON)->SetState(flamethrower->FindState("Powerdown")); player->refire = 0; S_StopSound (self, CHAN_WEAPON); return 0; diff --git a/src/g_hexen/a_clericstaff.cpp b/src/g_hexen/a_clericstaff.cpp index de4e1d75f..c278d8893 100644 --- a/src/g_hexen/a_clericstaff.cpp +++ b/src/g_hexen/a_clericstaff.cpp @@ -92,7 +92,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CStaffCheck) if (weapon != nullptr) { FState * newstate = weapon->FindState("Drain"); - if (newstate != nullptr) P_SetPsprite(player, PSP_WEAPON, newstate); + if (newstate != nullptr) player->GetPSprite(PSP_WEAPON)->SetState(newstate); } } if (weapon != nullptr) @@ -187,7 +187,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CStaffCheckBlink) { if (!--self->weaponspecial) { - P_SetPsprite(self->player, PSP_WEAPON, self->player->ReadyWeapon->FindState ("Blink")); + self->player->GetPSprite(PSP_WEAPON)->SetState(self->player->ReadyWeapon->FindState ("Blink")); self->weaponspecial = (pr_blink()+50)>>2; } else diff --git a/src/g_hexen/a_fighteraxe.cpp b/src/g_hexen/a_fighteraxe.cpp index f47ad6a9d..3813e9c3e 100644 --- a/src/g_hexen/a_fighteraxe.cpp +++ b/src/g_hexen/a_fighteraxe.cpp @@ -76,7 +76,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FAxeCheckReady) } if (player->ReadyWeapon->Ammo1->Amount) { - P_SetPsprite(player, PSP_WEAPON, player->ReadyWeapon->FindState ("ReadyGlow")); + player->GetPSprite(PSP_WEAPON)->SetState(player->ReadyWeapon->FindState ("ReadyGlow")); } else { @@ -103,7 +103,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FAxeCheckReadyG) } if (player->ReadyWeapon->Ammo1->Amount <= 0) { - P_SetPsprite(player, PSP_WEAPON, player->ReadyWeapon->FindState ("Ready")); + player->GetPSprite(PSP_WEAPON)->SetState(player->ReadyWeapon->FindState ("Ready")); } else { @@ -130,7 +130,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FAxeCheckUp) } if (player->ReadyWeapon->Ammo1->Amount) { - P_SetPsprite(player, PSP_WEAPON, player->ReadyWeapon->FindState ("SelectGlow")); + player->GetPSprite(PSP_WEAPON)->SetState(player->ReadyWeapon->FindState ("SelectGlow")); } else { @@ -157,7 +157,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FAxeCheckUpG) } if (player->ReadyWeapon->Ammo1->Amount <= 0) { - P_SetPsprite(player, PSP_WEAPON, player->ReadyWeapon->FindState ("Select")); + player->GetPSprite(PSP_WEAPON)->SetState(player->ReadyWeapon->FindState ("Select")); } else { @@ -184,7 +184,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FAxeCheckAtk) } if (player->ReadyWeapon->Ammo1->Amount) { - P_SetPsprite(player, PSP_WEAPON, player->ReadyWeapon->FindState ("FireGlow")); + player->GetPSprite(PSP_WEAPON)->SetState(player->ReadyWeapon->FindState ("FireGlow")); } return 0; } @@ -273,7 +273,7 @@ axedone: (!(weapon->WeaponFlags & WIF_PRIMARY_USES_BOTH) || weapon->Ammo2 == nullptr || weapon->Ammo2->Amount == 0)) { - P_SetPsprite(player, PSP_WEAPON, player->ReadyWeapon->FindState ("Fire") + 5); + player->GetPSprite(PSP_WEAPON)->SetState(player->ReadyWeapon->FindState ("Fire") + 5); } } } diff --git a/src/g_hexen/a_fighterplayer.cpp b/src/g_hexen/a_fighterplayer.cpp index 3624ed625..a8e26773b 100644 --- a/src/g_hexen/a_fighterplayer.cpp +++ b/src/g_hexen/a_fighterplayer.cpp @@ -120,7 +120,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FPunchAttack) if (pmo->weaponspecial >= 3) { pmo->weaponspecial = 0; - P_SetPsprite(player, PSP_WEAPON, player->ReadyWeapon->FindState("Fire2")); + player->GetPSprite(PSP_WEAPON)->SetState(player->ReadyWeapon->FindState("Fire2")); S_Sound (pmo, CHAN_VOICE, "*fistgrunt", 1, ATTN_NORM); } return 0; diff --git a/src/g_hexen/a_pig.cpp b/src/g_hexen/a_pig.cpp index ea767dccd..22c83ef3a 100644 --- a/src/g_hexen/a_pig.cpp +++ b/src/g_hexen/a_pig.cpp @@ -39,7 +39,7 @@ void APigPlayer::MorphPlayerThink () { // Snout sniff if (player->ReadyWeapon != nullptr) { - P_SetPsprite(player, PSP_WEAPON, player->ReadyWeapon->FindState("Grunt")); + player->GetPSprite(PSP_WEAPON)->SetState(player->ReadyWeapon->FindState("Grunt")); } S_Sound (this, CHAN_VOICE, "PigActive1", 1, ATTN_NORM); // snort return; diff --git a/src/g_shared/a_artifacts.cpp b/src/g_shared/a_artifacts.cpp index f89c1360d..48214c4c7 100644 --- a/src/g_shared/a_artifacts.cpp +++ b/src/g_shared/a_artifacts.cpp @@ -1131,7 +1131,7 @@ void APowerWeaponLevel2::InitEffect () if (weapon->GetReadyState() != sister->GetReadyState()) { - P_SetPsprite(Owner->player, PSP_WEAPON, sister->GetReadyState()); + Owner->player->GetPSprite(PSP_WEAPON)->SetState(sister->GetReadyState()); } } @@ -1305,9 +1305,9 @@ void APowerTargeter::InitEffect () if (state != nullptr) { - P_SetPsprite(player, PSP_TARGETCENTER, state + 0); - P_SetPsprite(player, PSP_TARGETLEFT, state + 1); - P_SetPsprite(player, PSP_TARGETRIGHT, state + 2); + player->GetPSprite(PSP_TARGETCENTER)->SetState(state + 0); + player->GetPSprite(PSP_TARGETLEFT)->SetState(state + 1); + player->GetPSprite(PSP_TARGETRIGHT)->SetState(state + 2); } player->GetPSprite(PSP_TARGETCENTER)->x = (160-3); @@ -1346,13 +1346,13 @@ void APowerTargeter::DoEffect () { if (EffectTics & 32) { - P_SetPsprite(player, PSP_TARGETRIGHT, nullptr); - P_SetPsprite(player, PSP_TARGETLEFT, state + 1); + player->GetPSprite(PSP_TARGETRIGHT)->SetState(nullptr); + player->GetPSprite(PSP_TARGETLEFT)->SetState(state + 1); } else if (EffectTics & 16) { - P_SetPsprite(player, PSP_TARGETRIGHT, state + 2); - P_SetPsprite(player, PSP_TARGETLEFT, nullptr); + player->GetPSprite(PSP_TARGETRIGHT)->SetState(state + 2); + player->GetPSprite(PSP_TARGETLEFT)->SetState(nullptr); } } } @@ -1364,9 +1364,9 @@ void APowerTargeter::EndEffect () Super::EndEffect(); if (Owner != nullptr && Owner->player != nullptr) { - P_SetPsprite (Owner->player, PSP_TARGETCENTER, nullptr); - P_SetPsprite (Owner->player, PSP_TARGETLEFT, nullptr); - P_SetPsprite (Owner->player, PSP_TARGETRIGHT, nullptr); + Owner->player->GetPSprite(PSP_TARGETCENTER)->SetState(nullptr); + Owner->player->GetPSprite(PSP_TARGETLEFT)->SetState(nullptr); + Owner->player->GetPSprite(PSP_TARGETRIGHT)->SetState(nullptr); } } diff --git a/src/g_strife/a_strifestuff.cpp b/src/g_strife/a_strifestuff.cpp index fd8b797fb..3f444c39b 100644 --- a/src/g_strife/a_strifestuff.cpp +++ b/src/g_strife/a_strifestuff.cpp @@ -352,8 +352,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_ItBurnsItBurns) if (self->player != nullptr && self->player->mo == self) { - P_SetPsprite(self->player, PSP_WEAPON, self->FindState("FireHands")); - P_SetPsprite(self->player, PSP_FLASH, nullptr); + self->player->GetPSprite(PSP_WEAPON)->SetState(self->FindState("FireHands")); + self->player->GetPSprite(PSP_FLASH)->SetState(nullptr); self->player->ReadyWeapon = nullptr; self->player->PendingWeapon = WP_NOCHANGE; self->player->playerstate = PST_LIVE; diff --git a/src/g_strife/a_strifeweapons.cpp b/src/g_strife/a_strifeweapons.cpp index f81ca79f7..006bc76fa 100644 --- a/src/g_strife/a_strifeweapons.cpp +++ b/src/g_strife/a_strifeweapons.cpp @@ -219,7 +219,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_ClearFlash) if (player == nullptr) return 0; - P_SetPsprite (player, PSP_FLASH, nullptr); + player->GetPSprite(PSP_FLASH)->SetState(nullptr); return 0; } @@ -235,7 +235,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_ShowElectricFlash) if (self->player != nullptr) { - P_SetPsprite (self->player, PSP_FLASH, self->player->ReadyWeapon->FindState(NAME_Flash)); + self->player->GetPSprite(PSP_FLASH)->SetState(self->player->ReadyWeapon->FindState(NAME_Flash)); } return 0; } @@ -707,7 +707,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FireGrenade) if (!weapon->DepleteAmmo (weapon->bAltFire)) return 0; - P_SetPsprite (player, PSP_FLASH, flash, true); + player->GetPSprite(PSP_FLASH)->SetState(flash, true); if (grenadetype != nullptr) { diff --git a/src/m_cheat.cpp b/src/m_cheat.cpp index d4b0e980f..4197c79b1 100644 --- a/src/m_cheat.cpp +++ b/src/m_cheat.cpp @@ -345,7 +345,7 @@ void cht_DoCheat (player_t *player, int cheat) player->mo->DamageType = NAME_None; if (player->ReadyWeapon != nullptr) { - P_SetPsprite(player, PSP_WEAPON, player->ReadyWeapon->GetUpState()); + player->GetPSprite(PSP_WEAPON)->SetState(player->ReadyWeapon->GetUpState()); } if (player->morphTics > 0) @@ -934,8 +934,8 @@ void cht_Take (player_t *player, const char *name, int amount) player->ReadyWeapon = nullptr; player->PendingWeapon = WP_NOCHANGE; - P_SetPsprite(player, PSP_WEAPON, nullptr); - P_SetPsprite(player, PSP_FLASH, nullptr); + player->GetPSprite(PSP_WEAPON)->SetState(nullptr); + player->GetPSprite(PSP_FLASH)->SetState(nullptr); } } diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 0087d25de..78ee5928c 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -1001,8 +1001,8 @@ void AActor::ClearInventory() { player->ReadyWeapon = nullptr; player->PendingWeapon = WP_NOCHANGE; - P_SetPsprite(player, PSP_WEAPON, nullptr); - P_SetPsprite(player, PSP_FLASH, nullptr); + player->GetPSprite(PSP_WEAPON)->SetState(nullptr); + player->GetPSprite(PSP_FLASH)->SetState(nullptr); } } diff --git a/src/p_pspr.cpp b/src/p_pspr.cpp index 02ba29180..84d44c348 100644 --- a/src/p_pspr.cpp +++ b/src/p_pspr.cpp @@ -311,12 +311,6 @@ void DPSprite::SetState(FState *newstate, bool pending) return; } -void P_SetPsprite(player_t *player, PSPLayers id, FState *state, bool pending) -{ - if (player == nullptr) return; - player->GetPSprite(id)->SetState(state, pending); -} - //--------------------------------------------------------------------------- // // PROC P_BringUpWeapon @@ -373,7 +367,7 @@ void P_BringUpWeapon (player_t *player) ? 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. - P_SetPsprite(player, PSP_FLASH, nullptr); + player->GetPSprite(PSP_FLASH)->SetState(nullptr); psweapon->SetState(newstate); player->mo->weaponspecial = 0; } @@ -407,7 +401,7 @@ void P_FireWeapon (player_t *player, FState *state) { state = weapon->GetAtkState(!!player->refire); } - P_SetPsprite(player, PSP_WEAPON, state); + player->GetPSprite(PSP_WEAPON)->SetState(state); if (!(weapon->WeaponFlags & WIF_NOALERT)) { P_NoiseAlert (player->mo, player->mo, false); @@ -445,7 +439,7 @@ void P_FireWeaponAlt (player_t *player, FState *state) state = weapon->GetAltAtkState(!!player->refire); } - P_SetPsprite(player, PSP_WEAPON, state); + player->GetPSprite(PSP_WEAPON)->SetState(state); if (!(weapon->WeaponFlags & WIF_NOALERT)) { P_NoiseAlert (player->mo, player->mo, false); @@ -470,7 +464,7 @@ void P_DropWeapon (player_t *player) player->WeaponState &= ~WF_DISABLESWITCH; if (player->ReadyWeapon != nullptr) { - P_SetPsprite(player, PSP_WEAPON, player->ReadyWeapon->GetDownState()); + player->GetPSprite(PSP_WEAPON)->SetState(player->ReadyWeapon->GetDownState()); } } @@ -814,7 +808,7 @@ static void P_CheckWeaponButtons (player_t *player) // state, the weapon won't disappear. ;) if (state != nullptr) { - P_SetPsprite(player, PSP_WEAPON, state); + player->GetPSprite(PSP_WEAPON)->SetState(state); return; } } @@ -1045,7 +1039,7 @@ DEFINE_ACTION_FUNCTION(AInventory, A_Lower) return 0; } // [RH] Clear the flash state. Only needed for Strife. - P_SetPsprite(player, PSP_FLASH, nullptr); + player->GetPSprite(PSP_FLASH)->SetState(nullptr); P_BringUpWeapon (player); return 0; } @@ -1152,7 +1146,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AInventory, A_GunFlash) flash = player->ReadyWeapon->FindState(NAME_Flash); } } - P_SetPsprite(player, PSP_FLASH, flash); + player->GetPSprite(PSP_FLASH)->SetState(flash); return 0; } diff --git a/src/p_pspr.h b/src/p_pspr.h index edcad9dd6..c3400f43d 100644 --- a/src/p_pspr.h +++ b/src/p_pspr.h @@ -102,7 +102,6 @@ private: void P_NewPspriteTick(); void P_CalcSwing (player_t *player); -void P_SetPsprite(player_t *player, PSPLayers id, FState *state, bool pending = false); void P_BringUpWeapon (player_t *player); void P_FireWeapon (player_t *player); void P_DropWeapon (player_t *player); diff --git a/src/p_user.cpp b/src/p_user.cpp index 921702388..8a8f2c6d4 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -1405,7 +1405,7 @@ void APlayerPawn::ActivateMorphWeapon () pspr->SetState(nullptr); } } - P_SetPsprite(player, PSP_FLASH, nullptr); + player->GetPSprite(PSP_FLASH)->SetState(nullptr); player->PendingWeapon = WP_NOCHANGE; } From f14a8407771f38e204f86620a197db63b7f04f70 Mon Sep 17 00:00:00 2001 From: Leonard2 Date: Mon, 30 May 2016 15:09:03 +0200 Subject: [PATCH 16/25] The ReadyWeapon is now assumed to not be null --- src/p_pspr.cpp | 63 +++++++++++++++++++++++++++--------------------- src/p_user.cpp | 10 +------- src/r_things.cpp | 4 +-- 3 files changed, 39 insertions(+), 38 deletions(-) diff --git a/src/p_pspr.cpp b/src/p_pspr.cpp index 84d44c348..8b7cb22d7 100644 --- a/src/p_pspr.cpp +++ b/src/p_pspr.cpp @@ -142,12 +142,8 @@ DPSprite::DPSprite(player_t *owner, AInventory *caller, int id) if (Next && Next->ID == ID && ID != 0) Next->Destroy(); // Replace it. - if (ID == PSP_WEAPON || ID == PSP_FLASH || (ID < PSP_TARGETCENTER && Caller->IsKindOf(RUNTIME_CLASS(AWeapon)))) - { - Flags |= PSPF_ADDBOB; - if (ID != PSP_WEAPON) - Flags |= PSPF_ADDWEAPON; - } + if (Caller->IsKindOf(RUNTIME_CLASS(AWeapon))) + Flags = (PSPF_ADDWEAPON|PSPF_ADDBOB); } //------------------------------------------------------------------------ @@ -181,9 +177,36 @@ DPSprite *player_t::FindPSprite(int layer) DPSprite *player_t::GetPSprite(PSPLayers layer) { + assert(ReadyWeapon != nullptr); + + AInventory *oldcaller; DPSprite *pspr = FindPSprite(layer); if (pspr == nullptr) + { pspr = new DPSprite(this, ReadyWeapon, layer); + oldcaller = nullptr; + } + else + { + oldcaller = pspr->Caller; + } + + // Always update the caller here in case we switched weapon + // or if the layer was being used by an inventory item before. + pspr->Caller = ReadyWeapon; + + if (ReadyWeapon != oldcaller) + { // Only change the flags if this layer was created now or if we updated the caller. + if (layer != PSP_FLASH) + { // Only the flash layer should follow the weapon. + pspr->Flags &= ~PSPF_ADDWEAPON; + + if (layer != PSP_WEAPON) + { // [RH] Don't bob the targeter. + pspr->Flags &= ~PSPF_ADDBOB; + } + } + } return pspr; } @@ -230,10 +253,6 @@ void DPSprite::SetState(FState *newstate, bool pending) WF_USER1OK | WF_USER2OK | WF_USER3OK | WF_USER4OK); } - // Special handling for the old hardcoded layers. - if (ID == PSP_WEAPON || ID == PSP_FLASH || ID >= PSP_TARGETCENTER) - Caller = Owner->ReadyWeapon; - processPending = pending; do @@ -259,7 +278,7 @@ void DPSprite::SetState(FState *newstate, bool pending) Tics = newstate->GetTics(); // could be 0 - if ((ID == PSP_WEAPON || ID == PSP_FLASH || ID >= PSP_TARGETCENTER) || Caller->IsKindOf(RUNTIME_CLASS(AWeapon))) + if (Caller->IsKindOf(RUNTIME_CLASS(AWeapon))) { // The targeter layers are affected by this too. if (sv_fastweapons == 2 && ID == PSP_WEAPON) Tics = newstate->ActionFunc == nullptr ? 0 : 1; @@ -1282,35 +1301,26 @@ void P_SetupPsprites(player_t *player, bool startweaponup) void player_t::TickPSprites() { - bool noweapon = (ReadyWeapon == nullptr && (health > 0 || mo->DamageType != NAME_Fire)); - DPSprite *pspr = psprites; while (pspr) { // Destroy the psprite if it's from a weapon that isn't currently selected by the player // or if it's from an inventory item that the player no longer owns. - // Exclude the old hardcoded layers from this check. - if (!(pspr->ID == PSP_WEAPON || pspr->ID == PSP_FLASH || pspr->ID >= PSP_TARGETCENTER) && - (pspr->Caller == nullptr || - (pspr->Caller->IsKindOf(RUNTIME_CLASS(AWeapon)) && pspr->Caller != pspr->Owner->ReadyWeapon) || - (pspr->Caller->Owner != pspr->Owner->mo))) + if ((pspr->Caller == nullptr || + (pspr->Caller->Owner != pspr->Owner->mo) || + (pspr->Caller->IsKindOf(RUNTIME_CLASS(AWeapon)) && pspr->Caller != pspr->Owner->ReadyWeapon))) { pspr->Destroy(); } - else if (!((pspr->ID == PSP_WEAPON || pspr->ID == PSP_FLASH || pspr->ID >= PSP_TARGETCENTER) && noweapon)) + else { pspr->Tick(); } - if (noweapon && (pspr->ID == PSP_WEAPON || pspr->ID == PSP_FLASH)) - { // Special treatment to destroy both the flash and weapon layers. - pspr->Destroy(); - } - pspr = pspr->Next; } - if (noweapon) + if (ReadyWeapon == nullptr && (health > 0 || mo->DamageType != NAME_Fire)) { if (PendingWeapon != WP_NOCHANGE) P_BringUpWeapon(this); @@ -1344,8 +1354,7 @@ void DPSprite::Tick() // [BC] Apply double firing speed. // This is applied to the targeter layers too. - if (((ID == PSP_WEAPON || ID == PSP_FLASH || ID >= PSP_TARGETCENTER) || Caller->IsKindOf(RUNTIME_CLASS(AWeapon))) && - (Tics && Owner->cheats & CF_DOUBLEFIRINGSPEED)) + if (Caller->IsKindOf(RUNTIME_CLASS(AWeapon)) && Tics && Owner->cheats & CF_DOUBLEFIRINGSPEED) Tics--; if (!Tics) diff --git a/src/p_user.cpp b/src/p_user.cpp index 8a8f2c6d4..e232e416b 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -3088,7 +3088,7 @@ void player_t::Serialize (FArchive &arc) << sx << sy << sprite << frame; - if (state != nullptr) + if (state != nullptr && ReadyWeapon != nullptr) { DPSprite *pspr; pspr = GetPSprite(PSPLayers(layer)); @@ -3108,14 +3108,6 @@ void player_t::Serialize (FArchive &arc) pspr->x = sx; pspr->y = sy; } - - pspr->Flags = 0; - if (layer < PSP_TARGETCENTER) - { - pspr->Flags |= PSPF_ADDBOB; - if (layer == PSP_FLASH) - pspr->Flags |= PSPF_ADDWEAPON; - } } if (layer == PSP_WEAPON) diff --git a/src/r_things.cpp b/src/r_things.cpp index 309d18bf4..75630e859 100644 --- a/src/r_things.cpp +++ b/src/r_things.cpp @@ -1319,8 +1319,8 @@ void R_DrawPSprite(DPSprite *pspr, AActor *owner, float bobx, float boby, double if (tex->UseType == FTexture::TEX_Null) return; - isweapon = ((pspr->GetID() == PSP_WEAPON || pspr->GetID() == PSP_FLASH) || - (pspr->GetID() < PSP_TARGETCENTER && pspr->GetCaller()->IsKindOf(RUNTIME_CLASS(AWeapon)))); + // The targeters aren't weapons. + isweapon = (pspr->GetID() < PSP_TARGETCENTER && pspr->GetCaller()->IsKindOf(RUNTIME_CLASS(AWeapon))); if (pspr->firstTic) { // Can't interpolate the first tic. From 9ee5e57340f6f5a7c087436d54a6cde50d963a85 Mon Sep 17 00:00:00 2001 From: Leonard2 Date: Mon, 30 May 2016 15:37:02 +0200 Subject: [PATCH 17/25] Call GetPSprite here to update the ReadyWeapon but avoid doing so if it is null TickPSprites will take care of destroying the weapon/flash layers if the ReadyWeapon is null --- src/p_pspr.cpp | 31 +++++++++++++------------------ 1 file changed, 13 insertions(+), 18 deletions(-) diff --git a/src/p_pspr.cpp b/src/p_pspr.cpp index 8b7cb22d7..42d2336a5 100644 --- a/src/p_pspr.cpp +++ b/src/p_pspr.cpp @@ -341,16 +341,14 @@ void DPSprite::SetState(FState *newstate, bool pending) void P_BringUpWeapon (player_t *player) { - FState *newstate; AWeapon *weapon; - DPSprite *psweapon = player->GetPSprite(PSP_WEAPON); if (player->PendingWeapon == WP_NOCHANGE) { if (player->ReadyWeapon != nullptr) { - psweapon->y = WEAPONTOP; - psweapon->SetState(player->ReadyWeapon->GetReadyState()); + player->GetPSprite(PSP_WEAPON)->y = WEAPONTOP; + player->GetPSprite(PSP_WEAPON)->SetState(player->ReadyWeapon->GetReadyState()); } return; } @@ -367,28 +365,25 @@ void P_BringUpWeapon (player_t *player) weapon = weapon->SisterWeapon; } + player->PendingWeapon = WP_NOCHANGE; + player->ReadyWeapon = weapon; + player->mo->weaponspecial = 0; + if (weapon != nullptr) { if (weapon->UpSound) { S_Sound (player->mo, CHAN_WEAPON, weapon->UpSound, 1, ATTN_NORM); } - newstate = weapon->GetUpState (); player->refire = 0; + + player->GetPSprite(PSP_WEAPON)->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->GetPSprite(PSP_FLASH)->SetState(nullptr); + player->GetPSprite(PSP_WEAPON)->SetState(weapon->GetUpState()); } - else - { - newstate = nullptr; - } - player->PendingWeapon = WP_NOCHANGE; - player->ReadyWeapon = weapon; - psweapon->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->GetPSprite(PSP_FLASH)->SetState(nullptr); - psweapon->SetState(newstate); - player->mo->weaponspecial = 0; } //--------------------------------------------------------------------------- From 8244d2c844624c04ca2830b3cc7c2cb1cf4d40ec Mon Sep 17 00:00:00 2001 From: Leonard2 Date: Wed, 1 Jun 2016 23:00:04 +0200 Subject: [PATCH 18/25] Make sure never to call GetPSprite when the ReadyWeapon is null --- src/g_heretic/a_hereticweaps.cpp | 12 +++++++----- src/m_cheat.cpp | 2 -- src/p_mobj.cpp | 2 -- src/p_pspr.cpp | 18 ++++++++++-------- src/p_user.cpp | 20 +++++++++++--------- 5 files changed, 28 insertions(+), 26 deletions(-) diff --git a/src/g_heretic/a_hereticweaps.cpp b/src/g_heretic/a_hereticweaps.cpp index fba33e257..8d5a902b1 100644 --- a/src/g_heretic/a_hereticweaps.cpp +++ b/src/g_heretic/a_hereticweaps.cpp @@ -271,9 +271,10 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_GauntletAttack) { if (!weapon->DepleteAmmo (weapon->bAltFire)) return 0; + + player->GetPSprite(PSP_WEAPON)->x = ((pr_gatk() & 3) - 2); + player->GetPSprite(PSP_WEAPON)->y = WEAPONTOP + (pr_gatk() & 3); } - player->GetPSprite(PSP_WEAPON)->x = ((pr_gatk()&3)-2); - player->GetPSprite(PSP_WEAPON)->y = WEAPONTOP + (pr_gatk()&3); Angle = self->Angles.Yaw; if (power) { @@ -440,9 +441,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireMacePL1) { if (!weapon->DepleteAmmo(weapon->bAltFire)) return 0; + + player->GetPSprite(PSP_WEAPON)->x = ((pr_maceatk() & 3) - 2); + player->GetPSprite(PSP_WEAPON)->y = WEAPONTOP + (pr_maceatk() & 3); } - player->GetPSprite(PSP_WEAPON)->x = ((pr_maceatk() & 3) - 2); - player->GetPSprite(PSP_WEAPON)->y = WEAPONTOP + (pr_maceatk() & 3); ball = P_SpawnPlayerMissile(self, PClass::FindActor("MaceFX1"), self->Angles.Yaw + (((pr_maceatk() & 7) - 4) * (360. / 256))); if (ball) { @@ -1158,11 +1160,11 @@ IMPLEMENT_CLASS (APhoenixRodPowered) void APhoenixRodPowered::EndPowerup () { - Owner->player->GetPSprite(PSP_WEAPON)->SetState(SisterWeapon->GetReadyState()); DepleteAmmo (bAltFire); Owner->player->refire = 0; S_StopSound (Owner, CHAN_WEAPON); Owner->player->ReadyWeapon = SisterWeapon; + Owner->player->GetPSprite(PSP_WEAPON)->SetState(SisterWeapon->GetReadyState()); } class APhoenixFX1 : public AActor diff --git a/src/m_cheat.cpp b/src/m_cheat.cpp index 4197c79b1..be1ec8730 100644 --- a/src/m_cheat.cpp +++ b/src/m_cheat.cpp @@ -934,8 +934,6 @@ void cht_Take (player_t *player, const char *name, int amount) player->ReadyWeapon = nullptr; player->PendingWeapon = WP_NOCHANGE; - player->GetPSprite(PSP_WEAPON)->SetState(nullptr); - player->GetPSprite(PSP_FLASH)->SetState(nullptr); } } diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 78ee5928c..9bb73898a 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -1001,8 +1001,6 @@ void AActor::ClearInventory() { player->ReadyWeapon = nullptr; player->PendingWeapon = WP_NOCHANGE; - player->GetPSprite(PSP_WEAPON)->SetState(nullptr); - player->GetPSprite(PSP_FLASH)->SetState(nullptr); } } diff --git a/src/p_pspr.cpp b/src/p_pspr.cpp index 42d2336a5..26567e61d 100644 --- a/src/p_pspr.cpp +++ b/src/p_pspr.cpp @@ -1031,6 +1031,11 @@ DEFINE_ACTION_FUNCTION(AInventory, A_Lower) { return 0; } + if (nullptr == player->ReadyWeapon) + { + P_BringUpWeapon(player); + return 0; + } psp = player->GetPSprite(PSP_WEAPON); if (player->morphTics || player->cheats & CF_INSTANTWEAPSWITCH) { @@ -1084,6 +1089,10 @@ DEFINE_ACTION_FUNCTION(AInventory, A_Raise) P_DropWeapon(player); return 0; } + if (player->ReadyWeapon == nullptr) + { + return 0; + } psp = player->GetPSprite(PSP_WEAPON); psp->y -= RAISESPEED; if (psp->y > WEAPONTOP) @@ -1091,14 +1100,7 @@ DEFINE_ACTION_FUNCTION(AInventory, A_Raise) return 0; } psp->y = WEAPONTOP; - if (player->ReadyWeapon != nullptr) - { - psp->SetState(player->ReadyWeapon->GetReadyState()); - } - else - { - psp->SetState(nullptr); - } + psp->SetState(player->ReadyWeapon->GetReadyState()); return 0; } diff --git a/src/p_user.cpp b/src/p_user.cpp index e232e416b..cba8782f1 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -1376,14 +1376,16 @@ void APlayerPawn::MorphPlayerThink () void APlayerPawn::ActivateMorphWeapon () { PClassActor *morphweapon = PClass::FindActor (MorphWeapon); - DPSprite *pspr = player->GetPSprite(PSP_WEAPON); player->PendingWeapon = WP_NOCHANGE; - pspr->y = WEAPONTOP; + + if (player->ReadyWeapon != nullptr) + { + player->GetPSprite(PSP_WEAPON)->y = WEAPONTOP; + } if (morphweapon == nullptr || !morphweapon->IsDescendantOf (RUNTIME_CLASS(AWeapon))) { // No weapon at all while morphed! player->ReadyWeapon = nullptr; - pspr->SetState(nullptr); } else { @@ -1398,14 +1400,14 @@ void APlayerPawn::ActivateMorphWeapon () } if (player->ReadyWeapon != nullptr) { - pspr->SetState(player->ReadyWeapon->GetReadyState()); - } - else - { - pspr->SetState(nullptr); + player->GetPSprite(PSP_WEAPON)->SetState(player->ReadyWeapon->GetReadyState()); } } - player->GetPSprite(PSP_FLASH)->SetState(nullptr); + + if (player->ReadyWeapon != nullptr) + { + player->GetPSprite(PSP_FLASH)->SetState(nullptr); + } player->PendingWeapon = WP_NOCHANGE; } From e1f139ddcd9ef3b4c3b75987cb8b63e5c7c79a81 Mon Sep 17 00:00:00 2001 From: Leonard2 Date: Wed, 1 Jun 2016 23:20:18 +0200 Subject: [PATCH 19/25] The targeter layers now use a proper Caller This will avoid having to check for certain stuff and also allow them to not be destroyed when the ReadyWeapon is null like before --- src/g_shared/a_artifacts.cpp | 12 +++++++++--- src/p_pspr.cpp | 33 ++++++++++++++++++++------------- src/p_user.cpp | 4 +++- src/r_things.cpp | 3 +-- 4 files changed, 33 insertions(+), 19 deletions(-) diff --git a/src/g_shared/a_artifacts.cpp b/src/g_shared/a_artifacts.cpp index 48214c4c7..6afae78f8 100644 --- a/src/g_shared/a_artifacts.cpp +++ b/src/g_shared/a_artifacts.cpp @@ -1364,9 +1364,15 @@ void APowerTargeter::EndEffect () Super::EndEffect(); if (Owner != nullptr && Owner->player != nullptr) { - Owner->player->GetPSprite(PSP_TARGETCENTER)->SetState(nullptr); - Owner->player->GetPSprite(PSP_TARGETLEFT)->SetState(nullptr); - Owner->player->GetPSprite(PSP_TARGETRIGHT)->SetState(nullptr); + // Calling GetPSprite here could crash if we're creating a new game. + // This is because P_SetupLevel nulls the player's mo before destroying + // every DThinker which in turn ends up calling this. + // However P_SetupLevel is only called after G_NewInit which calls + // every player's dtor which destroys all their psprites. + DPSprite *pspr; + if ((pspr = Owner->player->FindPSprite(PSP_TARGETCENTER)) != nullptr) pspr->SetState(nullptr); + if ((pspr = Owner->player->FindPSprite(PSP_TARGETLEFT)) != nullptr) pspr->SetState(nullptr); + if ((pspr = Owner->player->FindPSprite(PSP_TARGETRIGHT)) != nullptr) pspr->SetState(nullptr); } } diff --git a/src/p_pspr.cpp b/src/p_pspr.cpp index 26567e61d..b9ba6b932 100644 --- a/src/p_pspr.cpp +++ b/src/p_pspr.cpp @@ -177,14 +177,27 @@ DPSprite *player_t::FindPSprite(int layer) DPSprite *player_t::GetPSprite(PSPLayers layer) { - assert(ReadyWeapon != nullptr); + AInventory *oldcaller = nullptr; + AInventory *newcaller = nullptr; + + if (layer >= PSP_TARGETCENTER) + { + if (mo != nullptr) + { + newcaller = mo->FindInventory(RUNTIME_CLASS(APowerTargeter), true); + } + } + else + { + newcaller = ReadyWeapon; + } + + assert(newcaller != nullptr); - AInventory *oldcaller; DPSprite *pspr = FindPSprite(layer); if (pspr == nullptr) { - pspr = new DPSprite(this, ReadyWeapon, layer); - oldcaller = nullptr; + pspr = new DPSprite(this, newcaller, layer); } else { @@ -193,18 +206,13 @@ DPSprite *player_t::GetPSprite(PSPLayers layer) // Always update the caller here in case we switched weapon // or if the layer was being used by an inventory item before. - pspr->Caller = ReadyWeapon; + pspr->Caller = newcaller; - if (ReadyWeapon != oldcaller) + if (newcaller != oldcaller) { // Only change the flags if this layer was created now or if we updated the caller. if (layer != PSP_FLASH) { // Only the flash layer should follow the weapon. pspr->Flags &= ~PSPF_ADDWEAPON; - - if (layer != PSP_WEAPON) - { // [RH] Don't bob the targeter. - pspr->Flags &= ~PSPF_ADDBOB; - } } } @@ -279,7 +287,7 @@ void DPSprite::SetState(FState *newstate, bool pending) Tics = newstate->GetTics(); // could be 0 if (Caller->IsKindOf(RUNTIME_CLASS(AWeapon))) - { // The targeter layers are affected by this too. + { if (sv_fastweapons == 2 && ID == PSP_WEAPON) Tics = newstate->ActionFunc == nullptr ? 0 : 1; else if (sv_fastweapons == 3) @@ -1350,7 +1358,6 @@ void DPSprite::Tick() Tics--; // [BC] Apply double firing speed. - // This is applied to the targeter layers too. if (Caller->IsKindOf(RUNTIME_CLASS(AWeapon)) && Tics && Owner->cheats & CF_DOUBLEFIRINGSPEED) Tics--; diff --git a/src/p_user.cpp b/src/p_user.cpp index cba8782f1..2ca7434d5 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -3090,7 +3090,9 @@ void player_t::Serialize (FArchive &arc) << sx << sy << sprite << frame; - if (state != nullptr && ReadyWeapon != nullptr) + if (state != nullptr && + ((layer < PSP_TARGETCENTER && ReadyWeapon != nullptr) || + (layer >= PSP_TARGETCENTER && mo->FindInventory(RUNTIME_CLASS(APowerTargeter), true)))) { DPSprite *pspr; pspr = GetPSprite(PSPLayers(layer)); diff --git a/src/r_things.cpp b/src/r_things.cpp index 75630e859..caca6a11c 100644 --- a/src/r_things.cpp +++ b/src/r_things.cpp @@ -1319,8 +1319,7 @@ void R_DrawPSprite(DPSprite *pspr, AActor *owner, float bobx, float boby, double if (tex->UseType == FTexture::TEX_Null) return; - // The targeters aren't weapons. - isweapon = (pspr->GetID() < PSP_TARGETCENTER && pspr->GetCaller()->IsKindOf(RUNTIME_CLASS(AWeapon))); + isweapon = pspr->GetCaller()->IsKindOf(RUNTIME_CLASS(AWeapon)); if (pspr->firstTic) { // Can't interpolate the first tic. From bc334ccc9f5255079754da0e15dbe3ee0ea5a570 Mon Sep 17 00:00:00 2001 From: Leonard2 Date: Thu, 2 Jun 2016 19:19:50 +0200 Subject: [PATCH 20/25] Avoid creating the targeter layers if the inventory item isn't attached to its owner yet --- src/g_shared/a_artifacts.cpp | 15 +++++++++++++-- src/g_shared/a_artifacts.h | 1 + 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/g_shared/a_artifacts.cpp b/src/g_shared/a_artifacts.cpp index 6afae78f8..55496a7f1 100644 --- a/src/g_shared/a_artifacts.cpp +++ b/src/g_shared/a_artifacts.cpp @@ -1294,6 +1294,11 @@ void APowerTargeter::Travelled () void APowerTargeter::InitEffect () { + // Why is this called when the inventory isn't even attached yet + // in APowerup::CreateCopy? + if (!Owner->FindInventory(GetClass(), true)) + return; + player_t *player; Super::InitEffect(); @@ -1317,6 +1322,14 @@ void APowerTargeter::InitEffect () PositionAccuracy (); } +void APowerTargeter::AttachToOwner(AActor *other) +{ + Super::AttachToOwner(other); + + // Let's actually properly call this for the targeters. + InitEffect(); +} + bool APowerTargeter::HandlePickup(AInventory *item) { if (Super::HandlePickup(item)) @@ -1327,8 +1340,6 @@ bool APowerTargeter::HandlePickup(AInventory *item) return false; } - - void APowerTargeter::DoEffect () { Super::DoEffect (); diff --git a/src/g_shared/a_artifacts.h b/src/g_shared/a_artifacts.h index 9ed285ca5..2a52756ab 100644 --- a/src/g_shared/a_artifacts.h +++ b/src/g_shared/a_artifacts.h @@ -182,6 +182,7 @@ protected: void EndEffect (); void PositionAccuracy (); void Travelled (); + void AttachToOwner(AActor *other); bool HandlePickup(AInventory *item); }; From 543414d31f40c1a8f9a5f7ca82dff911887fef36 Mon Sep 17 00:00:00 2001 From: Leonard2 Date: Thu, 2 Jun 2016 23:58:21 +0200 Subject: [PATCH 21/25] Added 2 new layer flags: PSPF_CVARFAST and PSPF_POWDOUBLE These flags allowed to easily restore a lost part of the targeter layers behavior --- src/p_pspr.cpp | 10 +++++++--- src/p_pspr.h | 2 ++ wadsrc/static/actors/constants.txt | 2 ++ 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/p_pspr.cpp b/src/p_pspr.cpp index b9ba6b932..0f01522d1 100644 --- a/src/p_pspr.cpp +++ b/src/p_pspr.cpp @@ -143,7 +143,7 @@ DPSprite::DPSprite(player_t *owner, AInventory *caller, int id) Next->Destroy(); // Replace it. if (Caller->IsKindOf(RUNTIME_CLASS(AWeapon))) - Flags = (PSPF_ADDWEAPON|PSPF_ADDBOB); + Flags = (PSPF_ADDWEAPON|PSPF_ADDBOB|PSPF_POWDOUBLE|PSPF_CVARFAST); } //------------------------------------------------------------------------ @@ -210,6 +210,10 @@ DPSprite *player_t::GetPSprite(PSPLayers layer) if (newcaller != oldcaller) { // Only change the flags if this layer was created now or if we updated the caller. + if (layer >= PSP_TARGETCENTER) + { // The targeter layers were affected by those. + pspr->Flags |= (PSPF_CVARFAST|PSPF_POWDOUBLE); + } if (layer != PSP_FLASH) { // Only the flash layer should follow the weapon. pspr->Flags &= ~PSPF_ADDWEAPON; @@ -286,7 +290,7 @@ void DPSprite::SetState(FState *newstate, bool pending) Tics = newstate->GetTics(); // could be 0 - if (Caller->IsKindOf(RUNTIME_CLASS(AWeapon))) + if (Flags & PSPF_CVARFAST) { if (sv_fastweapons == 2 && ID == PSP_WEAPON) Tics = newstate->ActionFunc == nullptr ? 0 : 1; @@ -1358,7 +1362,7 @@ void DPSprite::Tick() Tics--; // [BC] Apply double firing speed. - if (Caller->IsKindOf(RUNTIME_CLASS(AWeapon)) && Tics && Owner->cheats & CF_DOUBLEFIRINGSPEED) + if ((Flags & PSPF_POWDOUBLE) && Tics && (Owner->cheats & CF_DOUBLEFIRINGSPEED)) Tics--; if (!Tics) diff --git a/src/p_pspr.h b/src/p_pspr.h index c3400f43d..9ef3208e5 100644 --- a/src/p_pspr.h +++ b/src/p_pspr.h @@ -55,6 +55,8 @@ enum PSPFlags { PSPF_ADDWEAPON = 1 << 0, PSPF_ADDBOB = 1 << 1, + PSPF_POWDOUBLE = 1 << 2, + PSPF_CVARFAST = 1 << 3, }; class DPSprite : public DObject diff --git a/wadsrc/static/actors/constants.txt b/wadsrc/static/actors/constants.txt index d65e9e463..4bd2dc199 100644 --- a/wadsrc/static/actors/constants.txt +++ b/wadsrc/static/actors/constants.txt @@ -575,6 +575,8 @@ enum { PSPF_ADDWEAPON = 1 << 0, PSPF_ADDBOB = 1 << 1, + PSPF_POWDOUBLE = 1 << 2, + PSPF_CVARFAST = 1 << 3, }; // Default psprite layers From eeff17c550e2aeaf3bdbe51b81f832d63f5e6752 Mon Sep 17 00:00:00 2001 From: Leonard2 Date: Wed, 1 Jun 2016 23:33:08 +0200 Subject: [PATCH 22/25] Account for this on the renderer's side instead This fixes the weapon's layer behaving differently when called from A_Overlay (the flag would be set in this case breaking the offsets) --- src/p_pspr.cpp | 4 ---- src/r_things.cpp | 2 +- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/src/p_pspr.cpp b/src/p_pspr.cpp index 0f01522d1..1ff46faf0 100644 --- a/src/p_pspr.cpp +++ b/src/p_pspr.cpp @@ -214,10 +214,6 @@ DPSprite *player_t::GetPSprite(PSPLayers layer) { // The targeter layers were affected by those. pspr->Flags |= (PSPF_CVARFAST|PSPF_POWDOUBLE); } - if (layer != PSP_FLASH) - { // Only the flash layer should follow the weapon. - pspr->Flags &= ~PSPF_ADDWEAPON; - } } return pspr; diff --git a/src/r_things.cpp b/src/r_things.cpp index caca6a11c..91c88afa9 100644 --- a/src/r_things.cpp +++ b/src/r_things.cpp @@ -1337,7 +1337,7 @@ void R_DrawPSprite(DPSprite *pspr, AActor *owner, float bobx, float boby, double sy += boby; } - if (pspr->Flags & PSPF_ADDWEAPON) + if (pspr->Flags & PSPF_ADDWEAPON && pspr->GetID() != PSP_WEAPON) { sx += wx; sy += wy; From afa708c138f0c28cf348e5c1eabf208f386d226f Mon Sep 17 00:00:00 2001 From: Leonard2 Date: Fri, 3 Jun 2016 19:18:58 +0200 Subject: [PATCH 23/25] Allow psprite layers to be manipulated directly from the player's own body --- src/p_pspr.cpp | 20 ++++++++++---------- src/p_pspr.h | 6 +++--- src/thingdef/thingdef_codeptr.cpp | 2 +- wadsrc/static/actors/actor.txt | 5 +++++ wadsrc/static/actors/shared/inventory.txt | 6 +----- 5 files changed, 20 insertions(+), 19 deletions(-) diff --git a/src/p_pspr.cpp b/src/p_pspr.cpp index 1ff46faf0..d8f6ef58c 100644 --- a/src/p_pspr.cpp +++ b/src/p_pspr.cpp @@ -110,7 +110,7 @@ END_POINTERS // //------------------------------------------------------------------------ -DPSprite::DPSprite(player_t *owner, AInventory *caller, int id) +DPSprite::DPSprite(player_t *owner, AActor *caller, int id) : processPending(true), firstTic(true), x(.0), y(.0), @@ -142,7 +142,7 @@ DPSprite::DPSprite(player_t *owner, AInventory *caller, int id) if (Next && Next->ID == ID && ID != 0) Next->Destroy(); // Replace it. - if (Caller->IsKindOf(RUNTIME_CLASS(AWeapon))) + if (Caller->IsKindOf(RUNTIME_CLASS(AWeapon)) || Caller->IsKindOf(RUNTIME_CLASS(APlayerPawn))) Flags = (PSPF_ADDWEAPON|PSPF_ADDBOB|PSPF_POWDOUBLE|PSPF_CVARFAST); } @@ -177,8 +177,8 @@ DPSprite *player_t::FindPSprite(int layer) DPSprite *player_t::GetPSprite(PSPLayers layer) { - AInventory *oldcaller = nullptr; - AInventory *newcaller = nullptr; + AActor *oldcaller = nullptr; + AActor *newcaller = nullptr; if (layer >= PSP_TARGETCENTER) { @@ -972,7 +972,7 @@ void A_OverlayOffset(AActor *self, int layer, double wx, double wy, int flags) } } -DEFINE_ACTION_FUNCTION(AInventory, A_OverlayOffset) +DEFINE_ACTION_FUNCTION(AActor, A_OverlayOffset) { PARAM_ACTION_PROLOGUE; PARAM_INT_OPT(layer) { layer = PSP_WEAPON; } @@ -983,7 +983,7 @@ DEFINE_ACTION_FUNCTION(AInventory, A_OverlayOffset) return 0; } -DEFINE_ACTION_FUNCTION(AInventory, A_WeaponOffset) +DEFINE_ACTION_FUNCTION(AActor, A_WeaponOffset) { PARAM_ACTION_PROLOGUE; PARAM_FLOAT_OPT(wx) { wx = 0.; } @@ -999,7 +999,7 @@ DEFINE_ACTION_FUNCTION(AInventory, A_WeaponOffset) // //--------------------------------------------------------------------------- -DEFINE_ACTION_FUNCTION(AInventory, A_OverlayFlags) +DEFINE_ACTION_FUNCTION(AActor, A_OverlayFlags) { PARAM_ACTION_PROLOGUE; PARAM_INT(layer); @@ -1118,7 +1118,7 @@ DEFINE_ACTION_FUNCTION(AInventory, A_Raise) // //--------------------------------------------------------------------------- -DEFINE_ACTION_FUNCTION_PARAMS(AInventory, A_Overlay) +DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Overlay) { PARAM_ACTION_PROLOGUE; PARAM_INT (layer); @@ -1130,7 +1130,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AInventory, A_Overlay) return 0; DPSprite *pspr; - pspr = new DPSprite(player, reinterpret_cast(stateowner), layer); + pspr = new DPSprite(player, stateowner, layer); pspr->SetState(state); return 0; } @@ -1312,7 +1312,7 @@ void player_t::TickPSprites() // Destroy the psprite if it's from a weapon that isn't currently selected by the player // or if it's from an inventory item that the player no longer owns. if ((pspr->Caller == nullptr || - (pspr->Caller->Owner != pspr->Owner->mo) || + (pspr->Caller->IsKindOf(RUNTIME_CLASS(AInventory)) && barrier_cast(pspr->Caller)->Owner != pspr->Owner->mo) || (pspr->Caller->IsKindOf(RUNTIME_CLASS(AWeapon)) && pspr->Caller != pspr->Owner->ReadyWeapon))) { pspr->Destroy(); diff --git a/src/p_pspr.h b/src/p_pspr.h index 9ef3208e5..5f2dda275 100644 --- a/src/p_pspr.h +++ b/src/p_pspr.h @@ -64,7 +64,7 @@ class DPSprite : public DObject DECLARE_CLASS (DPSprite, DObject) HAS_OBJECT_POINTERS public: - DPSprite(player_t *owner, AInventory *caller, int id); + DPSprite(player_t *owner, AActor *caller, int id); static void NewTick(); void SetState(FState *newstate, bool pending = false); @@ -74,7 +74,7 @@ public: int GetFrame() const { return Frame; } FState* GetState() const { return State; } DPSprite* GetNext() { return Next; } - AInventory* GetCaller() { return Caller; } + AActor* GetCaller() { return Caller; } double x, y; double oldx, oldy; @@ -89,7 +89,7 @@ private: void Tick(); void Destroy(); - TObjPtr Caller; + TObjPtr Caller; TObjPtr Next; player_t *Owner; FState *State; diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index aaa4981eb..5b50b4e1c 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -5706,7 +5706,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetTics) PARAM_ACTION_PROLOGUE; PARAM_INT(tics_to_set); - if (stateowner != self && self->player != nullptr && stateowner->IsKindOf(RUNTIME_CLASS(AInventory))) + if (self->player != nullptr) { // Need to check psp states for a match, then. Blah. DPSprite *pspr = self->player->psprites; while (pspr) diff --git a/wadsrc/static/actors/actor.txt b/wadsrc/static/actors/actor.txt index 44ebb1dc3..abf6cab8a 100644 --- a/wadsrc/static/actors/actor.txt +++ b/wadsrc/static/actors/actor.txt @@ -331,6 +331,11 @@ ACTOR Actor native //: Thinker native void A_TransferPointer(int ptr_source, int ptr_recepient, int sourcefield, int recepientfield=AAPTR_DEFAULT, int flags=0); action native A_CopyFriendliness(int ptr_source = AAPTR_MASTER); + action native A_Overlay(int layer, state start = ""); + action native A_WeaponOffset(float wx = 0, float wy = 32, int flags = 0); + action native A_OverlayOffset(int layer = PSP_WEAPON, float wx = 0, float wy = 32, int flags = 0); + action native A_OverlayFlags(int layer, int flags, bool set); + native int ACS_NamedExecute(name script, int mapnum=0, int arg1=0, int arg2=0, int arg3=0); native int ACS_NamedSuspend(name script, int mapnum=0); native int ACS_NamedTerminate(name script, int mapnum=0); diff --git a/wadsrc/static/actors/shared/inventory.txt b/wadsrc/static/actors/shared/inventory.txt index d523afe5c..c98c88dd7 100644 --- a/wadsrc/static/actors/shared/inventory.txt +++ b/wadsrc/static/actors/shared/inventory.txt @@ -40,7 +40,6 @@ ACTOR Inventory native action native A_ReFire(state flash = ""); action native A_ClearReFire(); action native A_CheckReload(); - action native A_Overlay(int layer, state start = ""); action native A_GunFlash(state flash = "", int flags = 0); action native A_Saw(sound fullsound = "weapons/sawfull", sound hitsound = "weapons/sawhit", int damage = 2, class pufftype = "BulletPuff", int flags = 0, float range = 0, float/*angle*/ spread_xy = 2.8125, float/*angle*/ spread_z = 0, float lifesteal = 0, int lifestealmax = 0, class armorbonustype = "ArmorBonus"); action native state A_CheckForReload(int counter, state label, bool dontincrement = false); @@ -49,10 +48,7 @@ ACTOR Inventory native action native A_RestoreSpecialDoomThing(); action native A_RestoreSpecialThing1(); action native A_RestoreSpecialThing2(); - action native A_WeaponOffset(float wx = 0, float wy = 32, int flags = 0); - action native A_OverlayOffset(int layer = PSP_WEAPON, float wx = 0, float wy = 32, int flags = 0); - action native A_OverlayFlags(int layer, int flags, bool set); - + States { HideDoomish: From 0b88bae458f4cf795028985c59bee6e75e442727 Mon Sep 17 00:00:00 2001 From: Leonard2 Date: Fri, 3 Jun 2016 19:46:31 +0200 Subject: [PATCH 24/25] The strife firehands now make proper use of the psprite layers --- src/g_strife/a_strifestuff.cpp | 7 +++---- src/p_pspr.cpp | 4 ++++ src/p_pspr.h | 1 + 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/g_strife/a_strifestuff.cpp b/src/g_strife/a_strifestuff.cpp index 3f444c39b..b92621ce0 100644 --- a/src/g_strife/a_strifestuff.cpp +++ b/src/g_strife/a_strifestuff.cpp @@ -352,8 +352,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_ItBurnsItBurns) if (self->player != nullptr && self->player->mo == self) { - self->player->GetPSprite(PSP_WEAPON)->SetState(self->FindState("FireHands")); - self->player->GetPSprite(PSP_FLASH)->SetState(nullptr); + self->player->GetPSprite(PSP_STRIFEHANDS)->SetState(self->FindState("FireHands")); self->player->ReadyWeapon = nullptr; self->player->PendingWeapon = WP_NOCHANGE; self->player->playerstate = PST_LIVE; @@ -381,7 +380,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CrispyPlayer) self->player->playerstate = PST_DEAD; DPSprite *psp; - psp = self->player->GetPSprite(PSP_WEAPON); + psp = self->player->GetPSprite(PSP_STRIFEHANDS); psp->SetState(psp->GetState() + (self->FindState("FireHandsLower") - self->FindState("FireHands"))); } return 0; @@ -393,7 +392,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_HandLower) if (self->player != nullptr) { - DPSprite *psp = self->player->GetPSprite(PSP_WEAPON); + DPSprite *psp = self->player->GetPSprite(PSP_STRIFEHANDS); psp->y += 9; if (psp->y > WEAPONBOTTOM*2) { diff --git a/src/p_pspr.cpp b/src/p_pspr.cpp index d8f6ef58c..3defe5a41 100644 --- a/src/p_pspr.cpp +++ b/src/p_pspr.cpp @@ -187,6 +187,10 @@ DPSprite *player_t::GetPSprite(PSPLayers layer) newcaller = mo->FindInventory(RUNTIME_CLASS(APowerTargeter), true); } } + else if (layer == PSP_STRIFEHANDS) + { + newcaller = mo; + } else { newcaller = ReadyWeapon; diff --git a/src/p_pspr.h b/src/p_pspr.h index 5f2dda275..63c285075 100644 --- a/src/p_pspr.h +++ b/src/p_pspr.h @@ -44,6 +44,7 @@ class FArchive; // enum PSPLayers // These are all called by the owner's ReadyWeapon. { + PSP_STRIFEHANDS = -1, PSP_WEAPON = 1, PSP_FLASH = 1000, PSP_TARGETCENTER = INT_MAX - 2, From c9f4620702a2788a20a4e906a63425b84975e04b Mon Sep 17 00:00:00 2001 From: MajorCooke Date: Thu, 16 Jun 2016 07:24:00 -0500 Subject: [PATCH 25/25] Reimplemented P_SetPsprite. --- src/g_doom/a_doomweaps.cpp | 12 ++++++------ src/g_heretic/a_chicken.cpp | 2 +- src/g_heretic/a_hereticweaps.cpp | 4 ++-- src/g_hexen/a_clericstaff.cpp | 4 ++-- src/g_hexen/a_fighteraxe.cpp | 12 ++++++------ src/g_hexen/a_fighterplayer.cpp | 2 +- src/g_hexen/a_pig.cpp | 2 +- src/g_shared/a_artifacts.cpp | 16 ++++++++-------- src/g_strife/a_strifestuff.cpp | 2 +- src/g_strife/a_strifeweapons.cpp | 6 +++--- src/m_cheat.cpp | 2 +- src/p_pspr.cpp | 24 +++++++++++++++--------- src/p_pspr.h | 1 + src/p_user.cpp | 4 ++-- 14 files changed, 50 insertions(+), 43 deletions(-) diff --git a/src/g_doom/a_doomweaps.cpp b/src/g_doom/a_doomweaps.cpp index 7f1f578ca..c5eb9f1a8 100644 --- a/src/g_doom/a_doomweaps.cpp +++ b/src/g_doom/a_doomweaps.cpp @@ -81,7 +81,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FirePistol) if (!weapon->DepleteAmmo (weapon->bAltFire, true, 1)) return 0; - self->player->GetPSprite(PSP_FLASH)->SetState(weapon->FindState(NAME_Flash), true); + P_SetPsprite(self->player, PSP_FLASH, weapon->FindState(NAME_Flash), true); } self->player->mo->PlayAttacking2 (); @@ -273,7 +273,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireShotgun) { if (!weapon->DepleteAmmo (weapon->bAltFire, true, 1)) return 0; - player->GetPSprite(PSP_FLASH)->SetState(weapon->FindState(NAME_Flash), true); + P_SetPsprite(player, PSP_FLASH, weapon->FindState(NAME_Flash), true); } player->mo->PlayAttacking2 (); @@ -309,7 +309,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireShotgun2) { if (!weapon->DepleteAmmo (weapon->bAltFire, true, 2)) return 0; - player->GetPSprite(PSP_FLASH)->SetState(weapon->FindState(NAME_Flash), true); + P_SetPsprite(player, PSP_FLASH, weapon->FindState(NAME_Flash), true); } player->mo->PlayAttacking2 (); @@ -381,13 +381,13 @@ void P_SetSafeFlash(AWeapon *weapon, player_t *player, FState *flashstate, int i if (flashstate + index < cls->OwnedStates + cls->NumOwnedStates) { // we're ok so set the state - player->GetPSprite(PSP_FLASH)->SetState(flashstate + index, true); + P_SetPsprite(player, PSP_FLASH, flashstate + index, true); return; } else { // oh, no! The state is beyond the end of the state table so use the original flash state. - player->GetPSprite(PSP_FLASH)->SetState(flashstate, true); + P_SetPsprite(player, PSP_FLASH, flashstate, true); return; } } @@ -403,7 +403,7 @@ void P_SetSafeFlash(AWeapon *weapon, player_t *player, FState *flashstate, int i { // Invalid state. With no index offset, it should at least be valid. index = 0; } - player->GetPSprite(PSP_FLASH)->SetState(flashstate + index, true); + P_SetPsprite(player, PSP_FLASH, flashstate + index, true); } // diff --git a/src/g_heretic/a_chicken.cpp b/src/g_heretic/a_chicken.cpp index 4e496bb44..b70e4ff08 100644 --- a/src/g_heretic/a_chicken.cpp +++ b/src/g_heretic/a_chicken.cpp @@ -146,7 +146,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_BeakRaise) return 0; } player->GetPSprite(PSP_WEAPON)->y = WEAPONTOP; - player->GetPSprite(PSP_WEAPON)->SetState(player->ReadyWeapon->GetReadyState()); + P_SetPsprite(player, PSP_WEAPON, player->ReadyWeapon->GetReadyState()); return 0; } diff --git a/src/g_heretic/a_hereticweaps.cpp b/src/g_heretic/a_hereticweaps.cpp index 8d5a902b1..d20146339 100644 --- a/src/g_heretic/a_hereticweaps.cpp +++ b/src/g_heretic/a_hereticweaps.cpp @@ -1164,7 +1164,7 @@ void APhoenixRodPowered::EndPowerup () Owner->player->refire = 0; S_StopSound (Owner, CHAN_WEAPON); Owner->player->ReadyWeapon = SisterWeapon; - Owner->player->GetPSprite(PSP_WEAPON)->SetState(SisterWeapon->GetReadyState()); + P_SetPsprite(Owner->player, PSP_WEAPON, SisterWeapon->GetReadyState()); } class APhoenixFX1 : public AActor @@ -1310,7 +1310,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FirePhoenixPL2) flamethrower = static_cast (player->ReadyWeapon); if (flamethrower == nullptr || --flamethrower->FlameCount == 0) { // Out of flame - player->GetPSprite(PSP_WEAPON)->SetState(flamethrower->FindState("Powerdown")); + P_SetPsprite(player, PSP_WEAPON, flamethrower->FindState("Powerdown")); player->refire = 0; S_StopSound (self, CHAN_WEAPON); return 0; diff --git a/src/g_hexen/a_clericstaff.cpp b/src/g_hexen/a_clericstaff.cpp index c278d8893..de4e1d75f 100644 --- a/src/g_hexen/a_clericstaff.cpp +++ b/src/g_hexen/a_clericstaff.cpp @@ -92,7 +92,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CStaffCheck) if (weapon != nullptr) { FState * newstate = weapon->FindState("Drain"); - if (newstate != nullptr) player->GetPSprite(PSP_WEAPON)->SetState(newstate); + if (newstate != nullptr) P_SetPsprite(player, PSP_WEAPON, newstate); } } if (weapon != nullptr) @@ -187,7 +187,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CStaffCheckBlink) { if (!--self->weaponspecial) { - self->player->GetPSprite(PSP_WEAPON)->SetState(self->player->ReadyWeapon->FindState ("Blink")); + P_SetPsprite(self->player, PSP_WEAPON, self->player->ReadyWeapon->FindState ("Blink")); self->weaponspecial = (pr_blink()+50)>>2; } else diff --git a/src/g_hexen/a_fighteraxe.cpp b/src/g_hexen/a_fighteraxe.cpp index 3813e9c3e..f47ad6a9d 100644 --- a/src/g_hexen/a_fighteraxe.cpp +++ b/src/g_hexen/a_fighteraxe.cpp @@ -76,7 +76,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FAxeCheckReady) } if (player->ReadyWeapon->Ammo1->Amount) { - player->GetPSprite(PSP_WEAPON)->SetState(player->ReadyWeapon->FindState ("ReadyGlow")); + P_SetPsprite(player, PSP_WEAPON, player->ReadyWeapon->FindState ("ReadyGlow")); } else { @@ -103,7 +103,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FAxeCheckReadyG) } if (player->ReadyWeapon->Ammo1->Amount <= 0) { - player->GetPSprite(PSP_WEAPON)->SetState(player->ReadyWeapon->FindState ("Ready")); + P_SetPsprite(player, PSP_WEAPON, player->ReadyWeapon->FindState ("Ready")); } else { @@ -130,7 +130,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FAxeCheckUp) } if (player->ReadyWeapon->Ammo1->Amount) { - player->GetPSprite(PSP_WEAPON)->SetState(player->ReadyWeapon->FindState ("SelectGlow")); + P_SetPsprite(player, PSP_WEAPON, player->ReadyWeapon->FindState ("SelectGlow")); } else { @@ -157,7 +157,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FAxeCheckUpG) } if (player->ReadyWeapon->Ammo1->Amount <= 0) { - player->GetPSprite(PSP_WEAPON)->SetState(player->ReadyWeapon->FindState ("Select")); + P_SetPsprite(player, PSP_WEAPON, player->ReadyWeapon->FindState ("Select")); } else { @@ -184,7 +184,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FAxeCheckAtk) } if (player->ReadyWeapon->Ammo1->Amount) { - player->GetPSprite(PSP_WEAPON)->SetState(player->ReadyWeapon->FindState ("FireGlow")); + P_SetPsprite(player, PSP_WEAPON, player->ReadyWeapon->FindState ("FireGlow")); } return 0; } @@ -273,7 +273,7 @@ axedone: (!(weapon->WeaponFlags & WIF_PRIMARY_USES_BOTH) || weapon->Ammo2 == nullptr || weapon->Ammo2->Amount == 0)) { - player->GetPSprite(PSP_WEAPON)->SetState(player->ReadyWeapon->FindState ("Fire") + 5); + P_SetPsprite(player, PSP_WEAPON, player->ReadyWeapon->FindState ("Fire") + 5); } } } diff --git a/src/g_hexen/a_fighterplayer.cpp b/src/g_hexen/a_fighterplayer.cpp index a8e26773b..3624ed625 100644 --- a/src/g_hexen/a_fighterplayer.cpp +++ b/src/g_hexen/a_fighterplayer.cpp @@ -120,7 +120,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FPunchAttack) if (pmo->weaponspecial >= 3) { pmo->weaponspecial = 0; - player->GetPSprite(PSP_WEAPON)->SetState(player->ReadyWeapon->FindState("Fire2")); + P_SetPsprite(player, PSP_WEAPON, player->ReadyWeapon->FindState("Fire2")); S_Sound (pmo, CHAN_VOICE, "*fistgrunt", 1, ATTN_NORM); } return 0; diff --git a/src/g_hexen/a_pig.cpp b/src/g_hexen/a_pig.cpp index 22c83ef3a..ea767dccd 100644 --- a/src/g_hexen/a_pig.cpp +++ b/src/g_hexen/a_pig.cpp @@ -39,7 +39,7 @@ void APigPlayer::MorphPlayerThink () { // Snout sniff if (player->ReadyWeapon != nullptr) { - player->GetPSprite(PSP_WEAPON)->SetState(player->ReadyWeapon->FindState("Grunt")); + P_SetPsprite(player, PSP_WEAPON, player->ReadyWeapon->FindState("Grunt")); } S_Sound (this, CHAN_VOICE, "PigActive1", 1, ATTN_NORM); // snort return; diff --git a/src/g_shared/a_artifacts.cpp b/src/g_shared/a_artifacts.cpp index 55496a7f1..07071daa6 100644 --- a/src/g_shared/a_artifacts.cpp +++ b/src/g_shared/a_artifacts.cpp @@ -1131,7 +1131,7 @@ void APowerWeaponLevel2::InitEffect () if (weapon->GetReadyState() != sister->GetReadyState()) { - Owner->player->GetPSprite(PSP_WEAPON)->SetState(sister->GetReadyState()); + P_SetPsprite(Owner->player, PSP_WEAPON, sister->GetReadyState()); } } @@ -1310,9 +1310,9 @@ void APowerTargeter::InitEffect () if (state != nullptr) { - player->GetPSprite(PSP_TARGETCENTER)->SetState(state + 0); - player->GetPSprite(PSP_TARGETLEFT)->SetState(state + 1); - player->GetPSprite(PSP_TARGETRIGHT)->SetState(state + 2); + P_SetPsprite(player, PSP_TARGETCENTER, state + 0); + P_SetPsprite(player, PSP_TARGETLEFT, state + 1); + P_SetPsprite(player, PSP_TARGETRIGHT, state + 2); } player->GetPSprite(PSP_TARGETCENTER)->x = (160-3); @@ -1357,13 +1357,13 @@ void APowerTargeter::DoEffect () { if (EffectTics & 32) { - player->GetPSprite(PSP_TARGETRIGHT)->SetState(nullptr); - player->GetPSprite(PSP_TARGETLEFT)->SetState(state + 1); + P_SetPsprite(player, PSP_TARGETRIGHT, nullptr); + P_SetPsprite(player, PSP_TARGETLEFT, state + 1); } else if (EffectTics & 16) { - player->GetPSprite(PSP_TARGETRIGHT)->SetState(state + 2); - player->GetPSprite(PSP_TARGETLEFT)->SetState(nullptr); + P_SetPsprite(player, PSP_TARGETRIGHT, state + 2); + P_SetPsprite(player, PSP_TARGETLEFT, nullptr); } } } diff --git a/src/g_strife/a_strifestuff.cpp b/src/g_strife/a_strifestuff.cpp index b92621ce0..a64c5bae9 100644 --- a/src/g_strife/a_strifestuff.cpp +++ b/src/g_strife/a_strifestuff.cpp @@ -352,7 +352,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_ItBurnsItBurns) if (self->player != nullptr && self->player->mo == self) { - self->player->GetPSprite(PSP_STRIFEHANDS)->SetState(self->FindState("FireHands")); + P_SetPsprite(self->player, PSP_STRIFEHANDS, self->FindState("FireHands")); self->player->ReadyWeapon = nullptr; self->player->PendingWeapon = WP_NOCHANGE; self->player->playerstate = PST_LIVE; diff --git a/src/g_strife/a_strifeweapons.cpp b/src/g_strife/a_strifeweapons.cpp index 006bc76fa..f81ca79f7 100644 --- a/src/g_strife/a_strifeweapons.cpp +++ b/src/g_strife/a_strifeweapons.cpp @@ -219,7 +219,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_ClearFlash) if (player == nullptr) return 0; - player->GetPSprite(PSP_FLASH)->SetState(nullptr); + P_SetPsprite (player, PSP_FLASH, nullptr); return 0; } @@ -235,7 +235,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_ShowElectricFlash) if (self->player != nullptr) { - self->player->GetPSprite(PSP_FLASH)->SetState(self->player->ReadyWeapon->FindState(NAME_Flash)); + P_SetPsprite (self->player, PSP_FLASH, self->player->ReadyWeapon->FindState(NAME_Flash)); } return 0; } @@ -707,7 +707,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FireGrenade) if (!weapon->DepleteAmmo (weapon->bAltFire)) return 0; - player->GetPSprite(PSP_FLASH)->SetState(flash, true); + P_SetPsprite (player, PSP_FLASH, flash, true); if (grenadetype != nullptr) { diff --git a/src/m_cheat.cpp b/src/m_cheat.cpp index be1ec8730..6b2f4f595 100644 --- a/src/m_cheat.cpp +++ b/src/m_cheat.cpp @@ -345,7 +345,7 @@ void cht_DoCheat (player_t *player, int cheat) player->mo->DamageType = NAME_None; if (player->ReadyWeapon != nullptr) { - player->GetPSprite(PSP_WEAPON)->SetState(player->ReadyWeapon->GetUpState()); + P_SetPsprite(player, PSP_WEAPON, player->ReadyWeapon->GetUpState()); } if (player->morphTics > 0) diff --git a/src/p_pspr.cpp b/src/p_pspr.cpp index 3defe5a41..36aa00aae 100644 --- a/src/p_pspr.cpp +++ b/src/p_pspr.cpp @@ -175,6 +175,12 @@ DPSprite *player_t::FindPSprite(int layer) // //------------------------------------------------------------------------ +void P_SetPsprite(player_t *player, PSPLayers id, FState *state, bool pending) +{ + if (player == nullptr) return; + player->GetPSprite(id)->SetState(state, pending); +} + DPSprite *player_t::GetPSprite(PSPLayers layer) { AActor *oldcaller = nullptr; @@ -360,7 +366,7 @@ void P_BringUpWeapon (player_t *player) if (player->ReadyWeapon != nullptr) { player->GetPSprite(PSP_WEAPON)->y = WEAPONTOP; - player->GetPSprite(PSP_WEAPON)->SetState(player->ReadyWeapon->GetReadyState()); + P_SetPsprite(player, PSP_WEAPON, player->ReadyWeapon->GetReadyState()); } return; } @@ -393,8 +399,8 @@ void P_BringUpWeapon (player_t *player) ? 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->GetPSprite(PSP_FLASH)->SetState(nullptr); - player->GetPSprite(PSP_WEAPON)->SetState(weapon->GetUpState()); + P_SetPsprite(player, PSP_FLASH, nullptr); + P_SetPsprite(player, PSP_WEAPON, weapon->GetUpState()); } } @@ -427,7 +433,7 @@ void P_FireWeapon (player_t *player, FState *state) { state = weapon->GetAtkState(!!player->refire); } - player->GetPSprite(PSP_WEAPON)->SetState(state); + P_SetPsprite(player, PSP_WEAPON, state); if (!(weapon->WeaponFlags & WIF_NOALERT)) { P_NoiseAlert (player->mo, player->mo, false); @@ -465,7 +471,7 @@ void P_FireWeaponAlt (player_t *player, FState *state) state = weapon->GetAltAtkState(!!player->refire); } - player->GetPSprite(PSP_WEAPON)->SetState(state); + P_SetPsprite(player, PSP_WEAPON, state); if (!(weapon->WeaponFlags & WIF_NOALERT)) { P_NoiseAlert (player->mo, player->mo, false); @@ -490,7 +496,7 @@ void P_DropWeapon (player_t *player) player->WeaponState &= ~WF_DISABLESWITCH; if (player->ReadyWeapon != nullptr) { - player->GetPSprite(PSP_WEAPON)->SetState(player->ReadyWeapon->GetDownState()); + P_SetPsprite(player, PSP_WEAPON, player->ReadyWeapon->GetDownState()); } } @@ -834,7 +840,7 @@ static void P_CheckWeaponButtons (player_t *player) // state, the weapon won't disappear. ;) if (state != nullptr) { - player->GetPSprite(PSP_WEAPON)->SetState(state); + P_SetPsprite(player, PSP_WEAPON, state); return; } } @@ -1070,7 +1076,7 @@ DEFINE_ACTION_FUNCTION(AInventory, A_Lower) return 0; } // [RH] Clear the flash state. Only needed for Strife. - player->GetPSprite(PSP_FLASH)->SetState(nullptr); + P_SetPsprite(player, PSP_FLASH, nullptr); P_BringUpWeapon (player); return 0; } @@ -1174,7 +1180,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AInventory, A_GunFlash) flash = player->ReadyWeapon->FindState(NAME_Flash); } } - player->GetPSprite(PSP_FLASH)->SetState(flash); + P_SetPsprite(player, PSP_FLASH, flash); return 0; } diff --git a/src/p_pspr.h b/src/p_pspr.h index 63c285075..2c7a36518 100644 --- a/src/p_pspr.h +++ b/src/p_pspr.h @@ -105,6 +105,7 @@ private: void P_NewPspriteTick(); void P_CalcSwing (player_t *player); +void P_SetPsprite(player_t *player, PSPLayers id, FState *state, bool pending = false); void P_BringUpWeapon (player_t *player); void P_FireWeapon (player_t *player); void P_DropWeapon (player_t *player); diff --git a/src/p_user.cpp b/src/p_user.cpp index 2ca7434d5..e4b6ec6bd 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -1400,13 +1400,13 @@ void APlayerPawn::ActivateMorphWeapon () } if (player->ReadyWeapon != nullptr) { - player->GetPSprite(PSP_WEAPON)->SetState(player->ReadyWeapon->GetReadyState()); + P_SetPsprite(player, PSP_WEAPON, player->ReadyWeapon->GetReadyState()); } } if (player->ReadyWeapon != nullptr) { - player->GetPSprite(PSP_FLASH)->SetState(nullptr); + P_SetPsprite(player, PSP_FLASH, nullptr); } player->PendingWeapon = WP_NOCHANGE;