- scriptified A_WeaponReady and its subfunctions.

This commit is contained in:
Christoph Oelckers 2018-11-25 00:54:13 +01:00
parent 34b7e5f435
commit ae27acb944
3 changed files with 105 additions and 122 deletions

View file

@ -93,8 +93,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 },
@ -592,124 +590,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<APlayerPawn *>(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

View file

@ -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);
//===========================================================================

View file

@ -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