From 1966b61b8fd83621406c62dbc7e42aa80bafec29 Mon Sep 17 00:00:00 2001 From: Leonard2 Date: Mon, 9 May 2016 20:03:47 +0200 Subject: [PATCH 01/35] 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/35] 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/35] 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/35] - 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/35] - 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/35] - 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/35] 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/35] 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/35] 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/35] 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/35] 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/35] 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/35] 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/35] 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/35] 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/35] 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/35] 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/35] 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/35] 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/35] 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/35] 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/35] 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/35] 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/35] 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 b8e392eaa5f4591e716843336802b989955845a0 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 12 Jun 2016 11:43:40 +0200 Subject: [PATCH 25/35] - do not try to load empty BEHAVIOR lumps. These would otherwise print an error message but there's a lot of maps out there which only have an empty entry to mark the map as Hexen format. --- src/p_setup.cpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/p_setup.cpp b/src/p_setup.cpp index cdb180e60..cec39b93a 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -3329,14 +3329,17 @@ void P_LoadReject (MapData * map, bool junk) // // [RH] P_LoadBehavior // -void P_LoadBehavior (MapData * map) +void P_LoadBehavior(MapData * map) { - map->Seek(ML_BEHAVIOR); - FBehavior::StaticLoadModule (-1, map->file, map->Size(ML_BEHAVIOR)); - if (!FBehavior::StaticCheckAllGood ()) + if (map->Size(ML_BEHAVIOR) > 0) { - Printf ("ACS scripts unloaded.\n"); - FBehavior::StaticUnloadModules (); + map->Seek(ML_BEHAVIOR); + FBehavior::StaticLoadModule(-1, map->file, map->Size(ML_BEHAVIOR)); + } + if (!FBehavior::StaticCheckAllGood()) + { + Printf("ACS scripts unloaded.\n"); + FBehavior::StaticUnloadModules(); } } From 624c9353854c549ec4bbfdccc9e76da1c41fe383 Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Sun, 12 Jun 2016 06:28:50 -0400 Subject: [PATCH 26/35] - Fixed: Floating point conversion error in SBarInfo DrawBar which broke interpolation. --- src/g_shared/sbarinfo_commands.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/g_shared/sbarinfo_commands.cpp b/src/g_shared/sbarinfo_commands.cpp index 854cb4106..a09c49303 100644 --- a/src/g_shared/sbarinfo_commands.cpp +++ b/src/g_shared/sbarinfo_commands.cpp @@ -2786,7 +2786,7 @@ class CommandDrawBar : public SBarInfoCommand // [BL] Since we used a percentage (in order to get the most fluid animation) // we need to establish a cut off point so the last pixel won't hang as the animation slows if(pixel == -1 && statusBar->Images[foreground]) - pixel = MAX(1., 1./statusBar->Images[foreground]->GetWidth()); + pixel = MAX(1 / 65536., 1./statusBar->Images[foreground]->GetWidth()); if(fabs(drawValue - value) < pixel) drawValue = value; From d74584e5b247c057ad6192f6da0fb8a29ce74a90 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 13 Jun 2016 13:58:04 +0200 Subject: [PATCH 27/35] - fixed: DAnimatedDoor must not start an interpolation on the door sector's ceiling. --- src/dsectoreffect.cpp | 4 ++-- src/dsectoreffect.h | 2 +- src/p_doors.cpp | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/dsectoreffect.cpp b/src/dsectoreffect.cpp index 180aa9e81..d33eeb061 100644 --- a/src/dsectoreffect.cpp +++ b/src/dsectoreffect.cpp @@ -126,11 +126,11 @@ DMovingCeiling::DMovingCeiling () { } -DMovingCeiling::DMovingCeiling (sector_t *sector) +DMovingCeiling::DMovingCeiling (sector_t *sector, bool interpolate) : DMover (sector) { sector->ceilingdata = this; - interpolation = sector->SetInterpolation(sector_t::CeilingMove, true); + if (interpolate) interpolation = sector->SetInterpolation(sector_t::CeilingMove, true); } bool sector_t::MoveAttached(int crush, double move, int floorOrCeiling, bool resetfailed) diff --git a/src/dsectoreffect.h b/src/dsectoreffect.h index 3a564afc4..792771fb6 100644 --- a/src/dsectoreffect.h +++ b/src/dsectoreffect.h @@ -49,7 +49,7 @@ class DMovingCeiling : public DMover { DECLARE_CLASS (DMovingCeiling, DMover) public: - DMovingCeiling (sector_t *sector); + DMovingCeiling (sector_t *sector, bool interpolate = true); protected: DMovingCeiling (); }; diff --git a/src/p_doors.cpp b/src/p_doors.cpp index b122768bb..d6a5f3a44 100644 --- a/src/p_doors.cpp +++ b/src/p_doors.cpp @@ -526,7 +526,7 @@ DAnimatedDoor::DAnimatedDoor () } DAnimatedDoor::DAnimatedDoor (sector_t *sec) - : DMovingCeiling (sec) + : DMovingCeiling (sec, false) { } From 82bc5e7bd1111cdee929f63823c4bd38e58dc9b3 Mon Sep 17 00:00:00 2001 From: MajorCooke Date: Mon, 13 Jun 2016 09:50:12 -0500 Subject: [PATCH 28/35] Fixed wrong token for Light keyword. --- src/zscript/zcc_parser.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/zscript/zcc_parser.cpp b/src/zscript/zcc_parser.cpp index 2b914d033..1f1fa4541 100644 --- a/src/zscript/zcc_parser.cpp +++ b/src/zscript/zcc_parser.cpp @@ -153,7 +153,7 @@ static void InitTokenMap() TOKENDEF (TK_NoDelay, ZCC_NODELAY); TOKENDEF (TK_Offset, ZCC_OFFSET); TOKENDEF (TK_CanRaise, ZCC_CANRAISE); - TOKENDEF (TK_Light, ZCC_CANRAISE); + TOKENDEF (TK_Light, ZCC_LIGHT); ZCC_InitOperators(); ZCC_InitConversions(); From f1597a5d26b2263f55b1d4abd4f9ee40cf2d31f2 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 13 Jun 2016 21:30:58 +0200 Subject: [PATCH 29/35] - fixed: Trace should set CrossedWater only if a water surface actually is crossed, i.e. the start of the trace and the end of the trace are on different sides of the surface. This was incorrectly spawning splashes when shooting inside a deep water sector, but in most cases the splash just was not visible. It could become visible if its position got clipped by a nearby one-sided wall. --- src/p_trace.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/p_trace.cpp b/src/p_trace.cpp index 67a516f9c..16fff3fbe 100644 --- a/src/p_trace.cpp +++ b/src/p_trace.cpp @@ -434,7 +434,7 @@ bool FTraceInfo::LineCheck(intercept_t *in, double dist, DVector3 hit) sector_t *hsec = CurSector->GetHeightSec(); if (Results->CrossedWater == NULL && hsec != NULL && - //CurSector->heightsec->waterzone && + Start.Z > hsec->floorplane.ZatPoint(Start) && hit.Z <= hsec->floorplane.ZatPoint(hit)) { // hit crossed a water plane @@ -846,6 +846,7 @@ bool FTraceInfo::TraceTraverse (int ptflags) if (Results->CrossedWater == NULL && CurSector->heightsec != NULL && + CurSector->heightsec->floorplane.ZatPoint(Start) < Start.Z && CurSector->heightsec->floorplane.ZatPoint(Results->HitPos) >= Results->HitPos.Z) { // Save the result so that the water check doesn't destroy it. From 2d4eb8dde4de7efabeff3607304b4eb673064f45 Mon Sep 17 00:00:00 2001 From: MajorCooke Date: Tue, 14 Jun 2016 18:20:43 -0500 Subject: [PATCH 30/35] - Added limit parameter to A_RailAttack and A_CustomRailgun. --- src/p_local.h | 1 + src/p_map.cpp | 11 +++++++++-- src/thingdef/thingdef_codeptr.cpp | 4 ++++ wadsrc/static/actors/actor.txt | 2 +- wadsrc/static/actors/shared/inventory.txt | 2 +- 5 files changed, 16 insertions(+), 4 deletions(-) diff --git a/src/p_local.h b/src/p_local.h index f7862d45f..c96afa6e5 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -334,6 +334,7 @@ struct FRailParams double drift = 1.0; PClassActor *spawnclass = nullptr; int SpiralOffset = 270; + int limit = 0; }; // [RH] Shoot a railgun void P_RailAttack(FRailParams *params); diff --git a/src/p_map.cpp b/src/p_map.cpp index 69d18ce18..cf7655917 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -4610,6 +4610,8 @@ struct RailData bool ThruSpecies; bool MThruSpecies; bool ThruActors; + int limit; + int count; }; static ETraceStatus ProcessRailHit(FTraceResults &res, void *userdata) @@ -4664,7 +4666,11 @@ static ETraceStatus ProcessRailHit(FTraceResults &res, void *userdata) } data->RailHits.Push(newhit); - return data->StopAtOne ? TRACE_Stop : TRACE_Continue; + if (data->limit) + { + data->count++; + } + return (data->StopAtOne || (data->limit && (data->count >= data->limit))) ? TRACE_Stop : TRACE_Continue; } //========================================================================== @@ -4706,7 +4712,8 @@ void P_RailAttack(FRailParams *p) RailData rail_data; rail_data.Caller = source; - + rail_data.limit = p->limit; + rail_data.count = 0; rail_data.StopAtOne = !!(p->flags & RAF_NOPIERCE); start.X = xy.X; start.Y = xy.Y; diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index 4d88a56fc..e2bda69d0 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -1996,6 +1996,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_RailAttack) PARAM_CLASS_OPT (spawnclass, AActor){ spawnclass = NULL; } PARAM_FLOAT_OPT (spawnofs_z) { spawnofs_z = 0; } PARAM_INT_OPT (SpiralOffset) { SpiralOffset = 270; } + PARAM_INT_OPT (limit) { limit = 0; } if (range == 0) range = 8192; if (sparsity == 0) sparsity=1.0; @@ -2036,6 +2037,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_RailAttack) p.drift = driftspeed; p.spawnclass = spawnclass; p.SpiralOffset = SpiralOffset; + p.limit = limit; P_RailAttack(&p); return 0; } @@ -2073,6 +2075,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomRailgun) PARAM_CLASS_OPT (spawnclass, AActor){ spawnclass = NULL; } PARAM_FLOAT_OPT (spawnofs_z) { spawnofs_z = 0; } PARAM_INT_OPT (SpiralOffset) { SpiralOffset = 270; } + PARAM_INT_OPT (limit) { limit = 0; } if (range == 0) range = 8192.; if (sparsity == 0) sparsity = 1; @@ -2155,6 +2158,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomRailgun) p.drift = driftspeed; p.spawnclass = spawnclass; p.SpiralOffset = SpiralOffset; + p.limit = 0; P_RailAttack(&p); self->SetXYZ(savedpos); diff --git a/wadsrc/static/actors/actor.txt b/wadsrc/static/actors/actor.txt index 2ce48b036..0d5e8e2de 100644 --- a/wadsrc/static/actors/actor.txt +++ b/wadsrc/static/actors/actor.txt @@ -190,7 +190,7 @@ ACTOR Actor native //: Thinker native state A_Jump(int chance = 256, state label, ...); native void A_CustomMissile(class missiletype, float spawnheight = 32, float spawnofs_xy = 0, float angle = 0, int flags = 0, float pitch = 0, int ptr = AAPTR_TARGET); native void A_CustomBulletAttack(float/*angle*/ spread_xy, float/*angle*/ spread_z, int numbullets, int damageperbullet, class pufftype = "BulletPuff", float range = 0, int flags = 0, int ptr = AAPTR_TARGET); - native void A_CustomRailgun(int damage, int spawnofs_xy = 0, color color1 = "", color color2 = "", int flags = 0, int aim = 0, float maxdiff = 0, class pufftype = "BulletPuff", float/*angle*/ spread_xy = 0, float/*angle*/ spread_z = 0, float range = 0, int duration = 0, float sparsity = 1.0, float driftspeed = 1.0, class spawnclass = "none", float spawnofs_z = 0, int spiraloffset = 270); + native void A_CustomRailgun(int damage, int spawnofs_xy = 0, color color1 = "", color color2 = "", int flags = 0, int aim = 0, float maxdiff = 0, class pufftype = "BulletPuff", float/*angle*/ spread_xy = 0, float/*angle*/ spread_z = 0, float range = 0, int duration = 0, float sparsity = 1.0, float driftspeed = 1.0, class spawnclass = "none", float spawnofs_z = 0, int spiraloffset = 270, int limit = 0); native state A_JumpIfHealthLower(int health, state label, int ptr_selector = AAPTR_DEFAULT); native state A_JumpIfCloser(float distance, state label, bool noz = false); native state A_JumpIfTracerCloser(float distance, state label, bool noz = false); diff --git a/wadsrc/static/actors/shared/inventory.txt b/wadsrc/static/actors/shared/inventory.txt index f7250117d..73f252320 100644 --- a/wadsrc/static/actors/shared/inventory.txt +++ b/wadsrc/static/actors/shared/inventory.txt @@ -11,7 +11,7 @@ ACTOR Inventory native action native A_CustomPunch(int damage, bool norandom = false, int flags = CPF_USEAMMO, class pufftype = "BulletPuff", float range = 0, float lifesteal = 0, int lifestealmax = 0, class armorbonustype = "ArmorBonus", sound MeleeSound = "", sound MissSound = ""); action native A_FireBullets(float/*angle*/ spread_xy, float/*angle*/ spread_z, int numbullets, int damageperbullet, class pufftype = "BulletPuff", int flags = 1, float range = 0); action native A_FireCustomMissile(class missiletype, float angle = 0, bool useammo = true, float spawnofs_xy = 0, float spawnheight = 0, int flags = 0, float pitch = 0); - action native A_RailAttack(int damage, int spawnofs_xy = 0, bool useammo = true, color color1 = "", color color2 = "", int flags = 0, float maxdiff = 0, class pufftype = "BulletPuff", float/*angle*/ spread_xy = 0, float/*angle*/ spread_z = 0, float range = 0, int duration = 0, float sparsity = 1.0, float driftspeed = 1.0, class spawnclass = "none", float spawnofs_z = 0, int spiraloffset = 270); + action native A_RailAttack(int damage, int spawnofs_xy = 0, bool useammo = true, color color1 = "", color color2 = "", int flags = 0, float maxdiff = 0, class pufftype = "BulletPuff", float/*angle*/ spread_xy = 0, float/*angle*/ spread_z = 0, float range = 0, int duration = 0, float sparsity = 1.0, float driftspeed = 1.0, class spawnclass = "none", float spawnofs_z = 0, int spiraloffset = 270, int limit = 0); action native A_Light(int extralight); action native A_Light0(); action native A_Light1(); From 8e8248284a1f95716ec4665c73a3e828da1b4e9f Mon Sep 17 00:00:00 2001 From: Xaser Acheron Date: Fri, 10 Jun 2016 20:22:48 -0500 Subject: [PATCH 31/35] added BFGF_HURTSOURCE and BFGF_MISSILEORIGIN to A_BFGSpray --- src/g_doom/a_doomweaps.cpp | 20 ++++++++++++++++---- wadsrc/static/actors/actor.txt | 2 +- wadsrc/static/actors/constants.txt | 4 ++++ 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/src/g_doom/a_doomweaps.cpp b/src/g_doom/a_doomweaps.cpp index 21119f8a0..95ce63342 100644 --- a/src/g_doom/a_doomweaps.cpp +++ b/src/g_doom/a_doomweaps.cpp @@ -636,6 +636,12 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireBFG) // A_BFGSpray // Spawn a BFG explosion on every monster in view // +enum BFG_Flags +{ + BFGF_HURTSOURCE = 1, + BFGF_MISSILEORIGIN = 2, +}; + DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_BFGSpray) { PARAM_ACTION_PROLOGUE; @@ -646,12 +652,14 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_BFGSpray) PARAM_FLOAT_OPT (distance) { distance = 0; } PARAM_ANGLE_OPT (vrange) { vrange = 0.; } PARAM_INT_OPT (defdamage) { defdamage = 0; } + PARAM_INT_OPT (flags) { flags = 0; } int i; int j; int damage; DAngle an; FTranslatedLineTarget t; + AActor *originator; if (spraytype == NULL) spraytype = PClass::FindActor("BFGExtra"); if (numrays <= 0) numrays = 40; @@ -664,13 +672,16 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_BFGSpray) if (!self->target) return 0; + // [XA] Set the originator of the attack to the projectile (self) if + // the new flag is set, else set it to the player (self->target) + originator = (flags & BFGF_MISSILEORIGIN) ? self : self->target; + // offset angles from its attack angle for (i = 0; i < numrays; i++) { an = self->Angles.Yaw - angle / 2 + angle / numrays*i; - // self->target is the originator (player) of the missile - P_AimLineAttack(self->target, an, distance, &t, vrange); + P_AimLineAttack(originator, an, distance, &t, vrange); if (t.linetarget != NULL) { @@ -681,7 +692,8 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_BFGSpray) if (spray != NULL) { - if (spray->flags6 & MF6_MTHRUSPECIES && self->target->GetSpecies() == t.linetarget->GetSpecies()) + if ((spray->flags6 & MF6_MTHRUSPECIES && self->target->GetSpecies() == t.linetarget->GetSpecies()) || + (!(flags & BFGF_HURTSOURCE) && self->target == t.linetarget)) // [XA] Don't hit oneself unless we say so. { spray->Destroy(); // [MC] Remove it because technically, the spray isn't trying to "hit" them. continue; @@ -704,7 +716,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_BFGSpray) damage = defdamage; } - int newdam = P_DamageMobj(t.linetarget, self->target, self->target, damage, dmgType, dmgFlags|DMG_USEANGLE, t.angleFromSource.Degrees); + int newdam = P_DamageMobj(t.linetarget, originator, self->target, damage, dmgType, dmgFlags|DMG_USEANGLE, t.angleFromSource.Degrees); P_TraceBleed(newdam > 0 ? newdam : damage, &t, self); } } diff --git a/wadsrc/static/actors/actor.txt b/wadsrc/static/actors/actor.txt index 0d5e8e2de..7e4319690 100644 --- a/wadsrc/static/actors/actor.txt +++ b/wadsrc/static/actors/actor.txt @@ -56,7 +56,7 @@ ACTOR Actor native //: Thinker // End of MBF redundant functions. action native A_MonsterRail(); - action native A_BFGSpray(class spraytype = "BFGExtra", int numrays = 40, int damagecount = 15, float/*angle*/ angle = 90, float distance = 16*64, float/*angle*/ vrange = 32, int damage = 0); + action native A_BFGSpray(class spraytype = "BFGExtra", int numrays = 40, int damagecount = 15, float/*angle*/ angle = 90, float distance = 16*64, float/*angle*/ vrange = 32, int damage = 0, int flags = 0); action native A_Pain(); action native A_NoBlocking(); action native A_XScream(); diff --git a/wadsrc/static/actors/constants.txt b/wadsrc/static/actors/constants.txt index f5072d55e..813e56195 100644 --- a/wadsrc/static/actors/constants.txt +++ b/wadsrc/static/actors/constants.txt @@ -18,6 +18,10 @@ const int SF_NOPULLIN = 32; const int SF_NOTURN = 64; const int SF_STEALARMOR = 128; +// Flags for A_BFGSpray +const int BFGF_HURTSOURCE = 1; +const int BFGF_MISSILEORIGIN = 2; + // Flags for A_CustomMissile const int CMF_AIMOFFSET = 1; const int CMF_AIMDIRECTION = 2; From 481ef7a5b588ce90d7454f6ec57bd021372ef8a6 Mon Sep 17 00:00:00 2001 From: Xaser Acheron Date: Fri, 10 Jun 2016 21:38:55 -0500 Subject: [PATCH 32/35] added SMMU-BFG11k-style 'damrad' property to A_BFGSpray --- src/g_doom/a_doomweaps.cpp | 35 +++++++++++++++++++++++++++++++++- wadsrc/static/actors/actor.txt | 2 +- 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/src/g_doom/a_doomweaps.cpp b/src/g_doom/a_doomweaps.cpp index 95ce63342..f985e6ed5 100644 --- a/src/g_doom/a_doomweaps.cpp +++ b/src/g_doom/a_doomweaps.cpp @@ -653,6 +653,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_BFGSpray) PARAM_ANGLE_OPT (vrange) { vrange = 0.; } PARAM_INT_OPT (defdamage) { defdamage = 0; } PARAM_INT_OPT (flags) { flags = 0; } + PARAM_FLOAT_OPT (damrad) { damrad = 0; } int i; int j; @@ -660,6 +661,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_BFGSpray) DAngle an; FTranslatedLineTarget t; AActor *originator; + double origdist; if (spraytype == NULL) spraytype = PClass::FindActor("BFGExtra"); if (numrays <= 0) numrays = 40; @@ -672,7 +674,38 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_BFGSpray) if (!self->target) return 0; - // [XA] Set the originator of the attack to the projectile (self) if + // [XA] If damrad is set, check the originator and hurt them if too close. + // adapted from SMMU's BFG11K code with fraggle's blessing. + origdist = self->Distance2D(self->target); + if (origdist < damrad) + { + // [XA] Decrease damage with distance. This uses SMMU's formula + // and is included mainly for emulation's sake. For more + // customization, seek out A_Explode rather than this. + damage = 0; + for (j = 0; j < (damrad / 2) - (origdist / 2); ++j) + damage += (pr_bfgspray() & 7) + 1; + + // [XA] flash n' damage -- some slight copypasta here, but it works. + AActor *spray = Spawn(spraytype, self->target->PosPlusZ(self->target->Height / 4), ALLOW_REPLACE); + + int dmgFlags = 0; + FName dmgType = NAME_BFGSplash; + + if (spray != NULL) + { + // [XA] skip the species check since we've already decided to damage oneself. + if (spray->flags5 & MF5_PUFFGETSOWNER) spray->target = self->target; + if (spray->flags3 & MF3_FOILINVUL) dmgFlags |= DMG_FOILINVUL; + if (spray->flags7 & MF7_FOILBUDDHA) dmgFlags |= DMG_FOILBUDDHA; + dmgType = spray->DamageType; + } + + int selfdam = P_DamageMobj(self->target, self, self->target, damage, dmgType, dmgFlags); + P_TraceBleed(selfdam > 0 ? selfdam : damage, self->target, self); + } + + // [XA] Set the originator of the rays to the projectile (self) if // the new flag is set, else set it to the player (self->target) originator = (flags & BFGF_MISSILEORIGIN) ? self : self->target; diff --git a/wadsrc/static/actors/actor.txt b/wadsrc/static/actors/actor.txt index 7e4319690..103d8be5b 100644 --- a/wadsrc/static/actors/actor.txt +++ b/wadsrc/static/actors/actor.txt @@ -56,7 +56,7 @@ ACTOR Actor native //: Thinker // End of MBF redundant functions. action native A_MonsterRail(); - action native A_BFGSpray(class spraytype = "BFGExtra", int numrays = 40, int damagecount = 15, float/*angle*/ angle = 90, float distance = 16*64, float/*angle*/ vrange = 32, int damage = 0, int flags = 0); + action native A_BFGSpray(class spraytype = "BFGExtra", int numrays = 40, int damagecount = 15, float/*angle*/ angle = 90, float distance = 16*64, float/*angle*/ vrange = 32, int damage = 0, int flags = 0, float damrad = 0); action native A_Pain(); action native A_NoBlocking(); action native A_XScream(); From de0301a7049c226c654c4c039ab000cddfdf7f7b Mon Sep 17 00:00:00 2001 From: Xaser Acheron Date: Mon, 13 Jun 2016 19:38:00 -0500 Subject: [PATCH 33/35] split bfg self-damage code into its own function, A_RadiusDamageSelf --- src/g_doom/a_doomweaps.cpp | 33 --------------- src/thingdef/thingdef_codeptr.cpp | 67 ++++++++++++++++++++++++++++++ wadsrc/static/actors/actor.txt | 3 +- wadsrc/static/actors/constants.txt | 3 ++ 4 files changed, 72 insertions(+), 34 deletions(-) diff --git a/src/g_doom/a_doomweaps.cpp b/src/g_doom/a_doomweaps.cpp index f985e6ed5..5bba7bbf1 100644 --- a/src/g_doom/a_doomweaps.cpp +++ b/src/g_doom/a_doomweaps.cpp @@ -653,7 +653,6 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_BFGSpray) PARAM_ANGLE_OPT (vrange) { vrange = 0.; } PARAM_INT_OPT (defdamage) { defdamage = 0; } PARAM_INT_OPT (flags) { flags = 0; } - PARAM_FLOAT_OPT (damrad) { damrad = 0; } int i; int j; @@ -661,7 +660,6 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_BFGSpray) DAngle an; FTranslatedLineTarget t; AActor *originator; - double origdist; if (spraytype == NULL) spraytype = PClass::FindActor("BFGExtra"); if (numrays <= 0) numrays = 40; @@ -674,37 +672,6 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_BFGSpray) if (!self->target) return 0; - // [XA] If damrad is set, check the originator and hurt them if too close. - // adapted from SMMU's BFG11K code with fraggle's blessing. - origdist = self->Distance2D(self->target); - if (origdist < damrad) - { - // [XA] Decrease damage with distance. This uses SMMU's formula - // and is included mainly for emulation's sake. For more - // customization, seek out A_Explode rather than this. - damage = 0; - for (j = 0; j < (damrad / 2) - (origdist / 2); ++j) - damage += (pr_bfgspray() & 7) + 1; - - // [XA] flash n' damage -- some slight copypasta here, but it works. - AActor *spray = Spawn(spraytype, self->target->PosPlusZ(self->target->Height / 4), ALLOW_REPLACE); - - int dmgFlags = 0; - FName dmgType = NAME_BFGSplash; - - if (spray != NULL) - { - // [XA] skip the species check since we've already decided to damage oneself. - if (spray->flags5 & MF5_PUFFGETSOWNER) spray->target = self->target; - if (spray->flags3 & MF3_FOILINVUL) dmgFlags |= DMG_FOILINVUL; - if (spray->flags7 & MF7_FOILBUDDHA) dmgFlags |= DMG_FOILBUDDHA; - dmgType = spray->DamageType; - } - - int selfdam = P_DamageMobj(self->target, self, self->target, damage, dmgType, dmgFlags); - P_TraceBleed(selfdam > 0 ? selfdam : damage, self->target, self); - } - // [XA] Set the originator of the rays to the projectile (self) if // the new flag is set, else set it to the player (self->target) originator = (flags & BFGF_MISSILEORIGIN) ? self : self->target; diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index e2bda69d0..000f8385c 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -95,6 +95,7 @@ static FRandom pr_spawnitemex ("SpawnItemEx"); static FRandom pr_burst ("Burst"); static FRandom pr_monsterrefire ("MonsterRefire"); static FRandom pr_teleport("A_Teleport"); +static FRandom pr_bfgselfdamage("BFGSelfDamage"); //========================================================================== // @@ -1334,6 +1335,72 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_RadiusThrust) return 0; } +//========================================================================== +// +// A_RadiusDamageSelf +// +//========================================================================== +enum +{ + RDSF_BFGDAMAGE = 1, +}; + +DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_RadiusDamageSelf) +{ + PARAM_ACTION_PROLOGUE; + PARAM_INT_OPT(damage) { damage = 128; } + PARAM_FLOAT_OPT(distance) { distance = 128; } + PARAM_INT_OPT(flags) { flags = 0; } + PARAM_CLASS_OPT(flashtype, AActor) { flashtype = NULL; } + + int i; + int damageSteps; + int actualDamage; + double actualDistance; + + actualDistance = self->Distance3D(self->target); + if (actualDistance < distance) + { + // [XA] Decrease damage with distance. Use the BFG damage + // calculation formula if the flag is set (essentially + // a generalization of SMMU's BFG11K behavior, used + // with fraggle's blessing.) + damageSteps = damage - int(damage * actualDistance / distance); + if (flags & RDSF_BFGDAMAGE) + { + actualDamage = 0; + for (i = 0; i < damageSteps; ++i) + actualDamage += (pr_bfgselfdamage() & 7) + 1; + } + else + { + actualDamage = damageSteps; + } + + // optional "flash" effect -- spawn an actor on + // the player to indicate bad things happened. + AActor *flash = NULL; + if(flashtype != NULL) + flash = Spawn(flashtype, self->target->PosPlusZ(self->target->Height / 4), ALLOW_REPLACE); + + int dmgFlags = 0; + FName dmgType = NAME_BFGSplash; + + if (flash != NULL) + { + if (flash->flags5 & MF5_PUFFGETSOWNER) flash->target = self->target; + if (flash->flags3 & MF3_FOILINVUL) dmgFlags |= DMG_FOILINVUL; + if (flash->flags7 & MF7_FOILBUDDHA) dmgFlags |= DMG_FOILBUDDHA; + dmgType = flash->DamageType; + } + + int newdam = P_DamageMobj(self->target, self, self->target, actualDamage, dmgType, dmgFlags); + P_TraceBleed(newdam > 0 ? newdam : actualDamage, self->target, self); + } + + return 0; +} + //========================================================================== // // Execute a line special / script diff --git a/wadsrc/static/actors/actor.txt b/wadsrc/static/actors/actor.txt index 103d8be5b..220e9e5e8 100644 --- a/wadsrc/static/actors/actor.txt +++ b/wadsrc/static/actors/actor.txt @@ -56,7 +56,7 @@ ACTOR Actor native //: Thinker // End of MBF redundant functions. action native A_MonsterRail(); - action native A_BFGSpray(class spraytype = "BFGExtra", int numrays = 40, int damagecount = 15, float/*angle*/ angle = 90, float distance = 16*64, float/*angle*/ vrange = 32, int damage = 0, int flags = 0, float damrad = 0); + action native A_BFGSpray(class spraytype = "BFGExtra", int numrays = 40, int damagecount = 15, float/*angle*/ angle = 90, float distance = 16*64, float/*angle*/ vrange = 32, int damage = 0, int flags = 0); action native A_Pain(); action native A_NoBlocking(); action native A_XScream(); @@ -247,6 +247,7 @@ ACTOR Actor native //: Thinker native void A_Burst(class chunktype); action native A_Blast(int flags = 0, float strength = 255, float radius = 255, float speed = 20, class blasteffect = "BlastEffect", sound blastsound = "BlastRadius"); action native A_RadiusThrust(int force = 128, int distance = -1, int flags = RTF_AFFECTSOURCE, int fullthrustdistance = 0); + action native A_RadiusDamageSelf(int damage = 128, float distance = 128, int flags = 0, class flashtype = "None"); action native A_Explode(int damage = -1, int distance = -1, int flags = XF_HURTSOURCE, bool alert = false, int fulldamagedistance = 0, int nails = 0, int naildamage = 10, class pufftype = "BulletPuff"); action native A_Stop(); action native A_Respawn(int flags = 1); diff --git a/wadsrc/static/actors/constants.txt b/wadsrc/static/actors/constants.txt index 813e56195..c43a3b2aa 100644 --- a/wadsrc/static/actors/constants.txt +++ b/wadsrc/static/actors/constants.txt @@ -184,6 +184,9 @@ const int RTF_NOIMPACTDAMAGE = 2; const int RTF_NOTMISSILE = 4; const int RTF_THRUSTZ = 16; +// Flags for A_RadiusDamageSelf +const int RDSF_BFGDAMAGE = 1; + // Flags for A_Blast const int BF_USEAMMO = 1; const int BF_DONTWARN = 2; From c9f4620702a2788a20a4e906a63425b84975e04b Mon Sep 17 00:00:00 2001 From: MajorCooke Date: Thu, 16 Jun 2016 07:24:00 -0500 Subject: [PATCH 34/35] 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; From cfaa3e3fa95cb1780eaa24d0418a9d568cfb03ad Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 16 Jun 2016 16:11:00 +0200 Subject: [PATCH 35/35] - changed action function interface so that callers can be identified directly, instead of guessing it from looking at the parameters. With arbitrary PSP layers the old method was no longer safe because the layer ID was not available in the action function. --- src/d_dehacked.cpp | 13 +++++++------ src/info.cpp | 4 ++-- src/info.h | 19 +++++++++++++++++-- src/p_mobj.cpp | 6 ++++-- src/p_pspr.cpp | 3 ++- src/thingdef/thingdef.h | 8 ++++---- src/thingdef/thingdef_codeptr.cpp | 28 ++++++++++++++-------------- src/thingdef/thingdef_expression.cpp | 2 +- src/zscript/vm.h | 3 +++ 9 files changed, 54 insertions(+), 32 deletions(-) diff --git a/src/d_dehacked.cpp b/src/d_dehacked.cpp index e4acc75a6..f79924b2b 100644 --- a/src/d_dehacked.cpp +++ b/src/d_dehacked.cpp @@ -807,11 +807,12 @@ void SetDehParams(FState *state, int codepointer) VMFunctionBuilder buildit; // Allocate registers used to pass parameters in. // self, stateowner, state (all are pointers) - buildit.Registers[REGT_POINTER].Get(3); + buildit.Registers[REGT_POINTER].Get(NAP); // Emit code to pass the standard action function parameters. - buildit.Emit(OP_PARAM, 0, REGT_POINTER, 0); - buildit.Emit(OP_PARAM, 0, REGT_POINTER, 1); - buildit.Emit(OP_PARAM, 0, REGT_POINTER, 2); + for (int i = 0; i < NAP; i++) + { + buildit.Emit(OP_PARAM, 0, REGT_POINTER, i); + } // Emit code for action parameters. int argcount = MBFCodePointerFactories[codepointer](buildit, value1, value2); buildit.Emit(OP_TAIL_K, buildit.GetConstantAddress(sym->Variants[0].Implementation, ATAG_OBJECT), NAP + argcount, 0); @@ -2114,7 +2115,7 @@ static int PatchCodePtrs (int dummy) else { TArray &args = sym->Variants[0].ArgFlags; - if ((sym->Flags & (VARF_Method | VARF_Action)) != (VARF_Method | VARF_Action) || (args.Size() > 3 && !(args[3] & VARF_Optional))) + if ((sym->Flags & (VARF_Method | VARF_Action)) != (VARF_Method | VARF_Action) || (args.Size() > NAP && !(args[NAP] & VARF_Optional))) { Printf("Frame %d: Incompatible code pointer '%s'\n", frame, Line2); sym = NULL; @@ -2726,7 +2727,7 @@ static bool LoadDehSupp () else { TArray &args = sym->Variants[0].ArgFlags; - if ((sym->Flags & (VARF_Method|VARF_Action)) != (VARF_Method | VARF_Action) || (args.Size() > 3 && !(args[3] & VARF_Optional))) + if ((sym->Flags & (VARF_Method|VARF_Action)) != (VARF_Method | VARF_Action) || (args.Size() > NAP && !(args[NAP] & VARF_Optional))) { sc.ScriptMessage("Incompatible code pointer '%s'", sc.String); } diff --git a/src/info.cpp b/src/info.cpp index 49f139ebe..7198a5de4 100644 --- a/src/info.cpp +++ b/src/info.cpp @@ -69,14 +69,14 @@ void FState::SetAction(const char *name) ActionFunc = FindGlobalActionFunction(name)->Variants[0].Implementation; } -bool FState::CallAction(AActor *self, AActor *stateowner, FState **stateret) +bool FState::CallAction(AActor *self, AActor *stateowner, FStateParamInfo *info, FState **stateret) { if (ActionFunc != NULL) { ActionCycles.Clock(); static VMFrameStack stack; - VMValue params[3] = { self, stateowner, VMValue(this, ATAG_STATE) }; + VMValue params[3] = { self, stateowner, VMValue(info, ATAG_STATEINFO) }; // If the function returns a state, store it at *stateret. // If it doesn't return a state but stateret is non-NULL, we need // to set *stateret to NULL. diff --git a/src/info.h b/src/info.h index 6d3de5015..6ced755a3 100644 --- a/src/info.h +++ b/src/info.h @@ -55,6 +55,21 @@ struct FActorInfo; class FArchive; class FIntCVar; +enum EStateType +{ + STATE_Actor, + STATE_Psprite, + STATE_StateChain, +}; + +struct FStateParamInfo +{ + FState *mCallingState; + EStateType mStateType; + int mPSPIndex; +}; + + // Sprites that are fixed in position because they can have special meanings. enum { @@ -129,7 +144,7 @@ struct FState void SetAction(VMFunction *func) { ActionFunc = func; } void ClearAction() { ActionFunc = NULL; } void SetAction(const char *name); - bool CallAction(AActor *self, AActor *stateowner, FState **stateret); + bool CallAction(AActor *self, AActor *stateowner, FStateParamInfo *stateinfo, FState **stateret); static PClassActor *StaticFindStateOwner (const FState *state); static PClassActor *StaticFindStateOwner (const FState *state, PClassActor *info); static FRandom pr_statetics; @@ -338,7 +353,7 @@ void AddStateLight(FState *state, const char *lname); PARAM_PROLOGUE; \ PARAM_OBJECT (self, type); \ PARAM_OBJECT_OPT (stateowner, AActor) { stateowner = self; } \ - PARAM_STATE_OPT (callingstate) { callingstate = NULL; } \ + PARAM_STATEINFO_OPT (stateinfo) { stateinfo = nullptr; } \ #define PARAM_ACTION_PROLOGUE PARAM_ACTION_PROLOGUE_TYPE(AActor) diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 39b0f423e..be875b951 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -556,7 +556,8 @@ bool AActor::SetState (FState *newstate, bool nofunction) if (!nofunction) { FState *returned_state; - if (newstate->CallAction(this, this, &returned_state)) + FStateParamInfo stp = { newstate, STATE_Actor, PSP_WEAPON }; + if (newstate->CallAction(this, this, &stp, &returned_state)) { // Check whether the called action function resulted in destroying the actor if (ObjectFlags & OF_EuthanizeMe) @@ -3866,7 +3867,8 @@ bool AActor::CheckNoDelay() // For immediately spawned objects with the NoDelay flag set for their // Spawn state, explicitly call the current state's function. FState *newstate; - if (state->CallAction(this, this, &newstate)) + FStateParamInfo stp = { state, STATE_Actor, PSP_WEAPON }; + if (state->CallAction(this, this, &stp, &newstate)) { if (ObjectFlags & OF_EuthanizeMe) { diff --git a/src/p_pspr.cpp b/src/p_pspr.cpp index 36aa00aae..d91b7ab00 100644 --- a/src/p_pspr.cpp +++ b/src/p_pspr.cpp @@ -321,7 +321,8 @@ void DPSprite::SetState(FState *newstate, bool pending) if (Owner->mo != nullptr) { FState *nextstate; - if (newstate->CallAction(Owner->mo, Caller, &nextstate)) + FStateParamInfo stp = { newstate, STATE_Psprite, ID }; + if (newstate->CallAction(Owner->mo, Caller, &stp, &nextstate)) { // It's possible this call resulted in this very layer being replaced. if (ObjectFlags & OF_EuthanizeMe) diff --git a/src/thingdef/thingdef.h b/src/thingdef/thingdef.h index d522ad573..21ab33dfb 100644 --- a/src/thingdef/thingdef.h +++ b/src/thingdef/thingdef.h @@ -350,7 +350,7 @@ int MatchString (const char *in, const char **strings); //#define PUSH_PARAMINFO self, stateowner, CallingState, ParameterIndex, statecall #define CALL_ACTION(name,self) { /*AF_##name(self, self, NULL, 0, NULL)*/ \ - VMValue params[3] = { self, self, VMValue(NULL, ATAG_STATE) }; \ + VMValue params[3] = { self, self, VMValue(NULL, ATAG_STATEINFO) }; \ stack->Call(name##_VMPtr, params, countof(params), NULL, 0, NULL); \ } @@ -360,7 +360,7 @@ int MatchString (const char *in, const char **strings); #define ACTION_RETURN_BOOL(v) ACTION_RETURN_INT(v) // Checks to see what called the current action function -#define ACTION_CALL_FROM_ACTOR() (callingstate == self->state) -#define ACTION_CALL_FROM_WEAPON() (self->player && callingstate != self->state && !(stateowner->flags5 & MF5_INSTATECALL)) -#define ACTION_CALL_FROM_INVENTORY() (!(stateowner->flags5 & MF5_INSTATECALL)) +#define ACTION_CALL_FROM_ACTOR() (stateinfo == nullptr || stateinfo->mStateType == STATE_Actor) +#define ACTION_CALL_FROM_WEAPON() (self->player && stateinfo != nullptr && stateinfo->mStateType == STATE_Psprite) +#define ACTION_CALL_FROM_INVENTORY() (stateinfo != nullptr && stateinfo->mStateType == STATE_StateChain) #endif diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index 1fbb67fe4..77c2fcbd1 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -133,8 +133,9 @@ bool ACustomInventory::CallStateChain (AActor *actor, FState *state) VMFrameStack stack; PPrototype *proto = state->ActionFunc->Proto; VMReturn *wantret; + FStateParamInfo stp = { state, STATE_StateChain, PSP_WEAPON }; - params[2] = VMValue(state, ATAG_STATE); + params[2] = VMValue(&stp, ATAG_STATEINFO); retval = true; // assume success wantret = NULL; // assume no return value wanted numret = 0; @@ -5839,22 +5840,21 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetTics) PARAM_ACTION_PROLOGUE; PARAM_INT(tics_to_set); - if (self->player != nullptr) - { // Need to check psp states for a match, then. Blah. - DPSprite *pspr = self->player->psprites; - while (pspr) + if (ACTION_CALL_FROM_WEAPON()) + { + DPSprite *pspr = self->player->FindPSprite(stateinfo->mPSPIndex); + if (pspr != nullptr) { - if (pspr->GetState() == callingstate) - { - pspr->Tics = tics_to_set; - return 0; - } - - pspr = pspr->GetNext(); + pspr->Tics = tics_to_set; + return 0; } } - // Just set tics for self. - self->tics = tics_to_set; + else if (ACTION_CALL_FROM_ACTOR()) + { + // Just set tics for self. + self->tics = tics_to_set; + } + // for inventory state chains this needs to be ignored. return 0; } diff --git a/src/thingdef/thingdef_expression.cpp b/src/thingdef/thingdef_expression.cpp index d500458a2..04410189a 100644 --- a/src/thingdef/thingdef_expression.cpp +++ b/src/thingdef/thingdef_expression.cpp @@ -2916,7 +2916,7 @@ ExpEmit FxDamage::Emit(VMFunctionBuilder *build) build->Emit(OP_LO, dmgfunc.RegNum, 0/*self*/, build->GetConstantInt(myoffsetof(AActor, Damage))); // If it's non-null... - build->Emit(OP_EQA_K, 1, dmgfunc.RegNum, build->GetConstantAddress(0, ATAG_GENERIC)); + build->Emit(OP_EQA_K, 1, dmgfunc.RegNum, build->GetConstantAddress(nullptr, ATAG_GENERIC)); size_t nulljump = build->Emit(OP_JMP, 0); // ...call it diff --git a/src/zscript/vm.h b/src/zscript/vm.h index 317a69846..52b354028 100644 --- a/src/zscript/vm.h +++ b/src/zscript/vm.h @@ -152,6 +152,7 @@ enum ATAG_AREGISTER, // pointer to an address register ATAG_STATE, // pointer to FState + ATAG_STATEINFO, // FState plus some info. ATAG_RNG, // pointer to FRandom }; @@ -914,6 +915,7 @@ void VMDisasm(FILE *out, const VMOP *code, int codesize, const VMScriptFunction #define PARAM_ANGLE_OPT_AT(p,x) DAngle x; if ((p) < numparam && param[p].Type != REGT_NIL) { assert(param[p].Type == REGT_FLOAT); x = param[p].f; } else #define PARAM_STRING_OPT_AT(p,x) FString x; if ((p) < numparam && param[p].Type != REGT_NIL) { assert(param[p].Type == REGT_STRING); x = param[p].s(); } else #define PARAM_STATE_OPT_AT(p,x) FState *x; if ((p) < numparam && param[p].Type != REGT_NIL) { assert(param[p].Type == REGT_POINTER && (param[p].atag == ATAG_STATE || param[p].a == NULL)); x = (FState *)param[p].a; } else +#define PARAM_STATEINFO_OPT_AT(p,x) FStateParamInfo *x; if ((p) < numparam && param[p].Type != REGT_NIL) { assert(param[p].Type == REGT_POINTER && (param[p].atag == ATAG_STATEINFO || param[p].a == NULL)); x = (FStateParamInfo *)param[p].a; } else #define PARAM_POINTER_OPT_AT(p,x,type) type *x; if ((p) < numparam && param[p].Type != REGT_NIL) { assert(param[p].Type == REGT_POINTER); x = (type *)param[p].a; } else #define PARAM_OBJECT_OPT_AT(p,x,type) type *x; if ((p) < numparam && param[p].Type != REGT_NIL) { assert(param[p].Type == REGT_POINTER && (param[p].atag == ATAG_OBJECT || param[p].a == NULL)); x = (type *)param[p].a; assert(x == NULL || x->IsKindOf(RUNTIME_CLASS(type))); } else #define PARAM_CLASS_OPT_AT(p,x,base) base::MetaClass *x; if ((p) < numparam && param[p].Type != REGT_NIL) { assert(param[p].Type == REGT_POINTER && (param[p].atag == ATAG_OBJECT || param[p].a == NULL)); x = (base::MetaClass *)param[p].a; assert(x == NULL || x->IsDescendantOf(RUNTIME_CLASS(base))); } else @@ -943,6 +945,7 @@ void VMDisasm(FILE *out, const VMOP *code, int codesize, const VMScriptFunction #define PARAM_ANGLE_OPT(x) ++paramnum; PARAM_ANGLE_OPT_AT(paramnum,x) #define PARAM_STRING_OPT(x) ++paramnum; PARAM_STRING_OPT_AT(paramnum,x) #define PARAM_STATE_OPT(x) ++paramnum; PARAM_STATE_OPT_AT(paramnum,x) +#define PARAM_STATEINFO_OPT(x) ++paramnum; PARAM_STATEINFO_OPT_AT(paramnum,x) #define PARAM_POINTER_OPT(x,type) ++paramnum; PARAM_POINTER_OPT_AT(paramnum,x,type) #define PARAM_OBJECT_OPT(x,type) ++paramnum; PARAM_OBJECT_OPT_AT(paramnum,x,type) #define PARAM_CLASS_OPT(x,base) ++paramnum; PARAM_CLASS_OPT_AT(paramnum,x,base)