diff --git a/src/p_pspr.cpp b/src/p_pspr.cpp index 3a27f0f8d..b58189681 100644 --- a/src/p_pspr.cpp +++ b/src/p_pspr.cpp @@ -94,8 +94,6 @@ CVAR(Int, sv_fastweapons, false, CVAR_SERVERINFO); // PRIVATE DATA DEFINITIONS ------------------------------------------------ -static FRandom pr_wpnreadysnd ("WpnReadySnd"); - static const FGenericButtons ButtonChecks[] = { { WRF_AllowZoom, WF_WEAPONZOOMOK, BT_ZOOM, NAME_Zoom }, @@ -593,124 +591,6 @@ void P_BobWeapon (player_t *player, float *x, float *y, double ticfrac) *x = *y = 0; } -//============================================================================ -// -// PROC A_WeaponReady -// -// Readies a weapon for firing or bobbing with its three ancillary functions, -// DoReadyWeaponToSwitch(), DoReadyWeaponToFire() and DoReadyWeaponToBob(). -// [XA] Added DoReadyWeaponToReload() and DoReadyWeaponToZoom() -// -//============================================================================ - -void DoReadyWeaponToSwitch (AActor *self, bool switchable) -{ - // Prepare for switching action. - player_t *player; - if (self && (player = self->player)) - { - if (switchable) - { - player->WeaponState |= WF_WEAPONSWITCHOK | WF_REFIRESWITCHOK; - } - else - { - // WF_WEAPONSWITCHOK is automatically cleared every tic by P_SetPsprite(). - player->WeaponState &= ~WF_REFIRESWITCHOK; - } - } -} - -void DoReadyWeaponDisableSwitch (AActor *self, INTBOOL disable) -{ - // Discard all switch attempts? - player_t *player; - if (self && (player = self->player)) - { - if (disable) - { - player->WeaponState |= WF_DISABLESWITCH; - player->WeaponState &= ~WF_REFIRESWITCHOK; - } - else - { - player->WeaponState &= ~WF_DISABLESWITCH; - } - } -} - -void DoReadyWeaponToFire (AActor *self, bool prim, bool alt) -{ - player_t *player; - AWeapon *weapon; - - if (!self || !(player = self->player) || !(weapon = player->ReadyWeapon)) - { - return; - } - - // Change player from attack state - if (self->InStateSequence(self->state, self->MissileState) || - self->InStateSequence(self->state, self->MeleeState)) - { - static_cast(self)->PlayIdle (); - } - - // Play ready sound, if any. - if (weapon->ReadySound && player->GetPSprite(PSP_WEAPON)->GetState() == weapon->FindState(NAME_Ready)) - { - if (!(weapon->WeaponFlags & WIF_READYSNDHALF) || pr_wpnreadysnd() < 128) - { - S_Sound (self, CHAN_WEAPON, weapon->ReadySound, 1, ATTN_NORM); - } - } - - // Prepare for firing action. - player->WeaponState |= ((prim ? WF_WEAPONREADY : 0) | (alt ? WF_WEAPONREADYALT : 0)); - return; -} - -void DoReadyWeaponToBob (AActor *self) -{ - if (self && self->player && self->player->ReadyWeapon) - { - // Prepare for bobbing action. - self->player->WeaponState |= WF_WEAPONBOBBING; - self->player->GetPSprite(PSP_WEAPON)->x = 0; - self->player->GetPSprite(PSP_WEAPON)->y = WEAPONTOP; - } -} - -void DoReadyWeaponToGeneric(AActor *self, int paramflags) -{ - int flags = 0; - - for (size_t i = 0; i < countof(ButtonChecks); ++i) - { - if (paramflags & ButtonChecks[i].ReadyFlag) - { - flags |= ButtonChecks[i].StateFlag; - } - } - if (self != NULL && self->player != NULL) - { - self->player->WeaponState |= flags; - } -} - -DEFINE_ACTION_FUNCTION(AStateProvider, A_WeaponReady) -{ - PARAM_ACTION_PROLOGUE(AStateProvider); - PARAM_INT(flags); - - DoReadyWeaponToSwitch(self, !(flags & WRF_NoSwitch)); - if ((flags & WRF_NoFire) != WRF_NoFire) DoReadyWeaponToFire(self, !(flags & WRF_NoPrimary), !(flags & WRF_NoSecondary)); - if (!(flags & WRF_NoBob)) DoReadyWeaponToBob(self); - DoReadyWeaponToGeneric(self, flags); - DoReadyWeaponDisableSwitch(self, flags & WRF_DisableSwitch); - return 0; -} - //--------------------------------------------------------------------------- // // PROC P_CheckWeaponButtons diff --git a/wadsrc/static/zscript/inventory/stateprovider.txt b/wadsrc/static/zscript/inventory/stateprovider.txt index 03cfd9b8d..3f5a88c55 100644 --- a/wadsrc/static/zscript/inventory/stateprovider.txt +++ b/wadsrc/static/zscript/inventory/stateprovider.txt @@ -1,8 +1,6 @@ class StateProvider : Inventory native { - action native void A_WeaponReady(int flags = 0); - //========================================================================== // // State jump function @@ -446,6 +444,7 @@ class CustomInventory : StateProvider deprecated("2.3") action void A_Lower() {} deprecated("2.3") action void A_Raise() {} deprecated("2.3") action void A_CheckReload() {} + deprecated("3.7") action void A_WeaponReady(int flags = 0) {} // this was somehow missed in 2.3 ... native bool CallStateChain (Actor actor, State state); //=========================================================================== diff --git a/wadsrc/static/zscript/inventory/weapons.txt b/wadsrc/static/zscript/inventory/weapons.txt index 1832e2d21..d07239f4a 100644 --- a/wadsrc/static/zscript/inventory/weapons.txt +++ b/wadsrc/static/zscript/inventory/weapons.txt @@ -233,6 +233,110 @@ class Weapon : StateProvider native return; } + //============================================================================ + // + // PROC A_WeaponReady + // + // Readies a weapon for firing or bobbing with its three ancillary functions, + // DoReadyWeaponToSwitch(), DoReadyWeaponToFire() and DoReadyWeaponToBob(). + // [XA] Added DoReadyWeaponToReload() and DoReadyWeaponToZoom() + // + //============================================================================ + + static void DoReadyWeaponToSwitch (PlayerInfo player, bool switchable) + { + // Prepare for switching action. + if (switchable) + { + player.WeaponState |= WF_WEAPONSWITCHOK | WF_REFIRESWITCHOK; + } + else + { + // WF_WEAPONSWITCHOK is automatically cleared every tic by P_SetPsprite(). + player.WeaponState &= ~WF_REFIRESWITCHOK; + } + } + + static void DoReadyWeaponDisableSwitch (PlayerInfo player, int disable) + { + // Discard all switch attempts? + if (disable) + { + player.WeaponState |= WF_DISABLESWITCH; + player.WeaponState &= ~WF_REFIRESWITCHOK; + } + else + { + player.WeaponState &= ~WF_DISABLESWITCH; + } + } + + static void DoReadyWeaponToFire (PlayerPawn pawn, bool prim, bool alt) + { + let player = pawn.player; + let weapon = player.ReadyWeapon; + if (!weapon) + { + return; + } + + // Change player from attack state + if (pawn.InStateSequence(pawn.curstate, pawn.MissileState) || + pawn.InStateSequence(pawn.curstate, pawn.MeleeState)) + { + pawn.PlayIdle (); + } + + // Play ready sound, if any. + if (weapon.ReadySound && player.GetPSprite(PSP_WEAPON).curState == weapon.FindState('Ready')) + { + if (!weapon.bReadySndHalf || random[WpnReadySnd]() < 128) + { + pawn.A_PlaySound(weapon.ReadySound, CHAN_WEAPON); + } + } + + // Prepare for firing action. + player.WeaponState |= ((prim ? WF_WEAPONREADY : 0) | (alt ? WF_WEAPONREADYALT : 0)); + return; + } + + static void DoReadyWeaponToBob (PlayerInfo player) + { + if (player.ReadyWeapon) + { + // Prepare for bobbing action. + player.WeaponState |= WF_WEAPONBOBBING; + let pspr = player.GetPSprite(PSP_WEAPON); + pspr.x = 0; + pspr.y = WEAPONTOP; + } + } + + static int GetButtonStateFlags(int flags) + { + // Rewritten for efficiency and clarity + int outflags = 0; + if (flags & WRF_AllowZoom) outflags |= WF_WEAPONZOOMOK; + if (flags & WRF_AllowReload) outflags |= WF_WEAPONRELOADOK; + if (flags & WRF_AllowUser1) outflags |= WF_USER1OK; + if (flags & WRF_AllowUser2) outflags |= WF_USER2OK; + if (flags & WRF_AllowUser3) outflags |= WF_USER3OK; + if (flags & WRF_AllowUser4) outflags |= WF_USER4OK; + return outflags; + } + + action void A_WeaponReady(int flags = 0) + { + if (!player) return; + DoReadyWeaponToSwitch(player, !(flags & WRF_NoSwitch)); + if ((flags & WRF_NoFire) != WRF_NoFire) DoReadyWeaponToFire(player.mo, !(flags & WRF_NoPrimary), !(flags & WRF_NoSecondary)); + if (!(flags & WRF_NoBob)) DoReadyWeaponToBob(player); + + player.WeaponState |= GetButtonStateFlags(flags); + DoReadyWeaponDisableSwitch(player, flags & WRF_DisableSwitch); + } + //--------------------------------------------------------------------------- // // PROC A_CheckReload