weapons update

- add pistol binary trigger aka pistol script and attack queueing
- add gorge heal spray +movement
- lerk flap +movement update
- fix for onos attack release bugs with +movement
This commit is contained in:
pierow 2024-02-04 04:05:28 -05:00
parent a024343cb0
commit ceb814f4f6
11 changed files with 183 additions and 61 deletions

View file

@ -387,9 +387,9 @@ void WeaponsResource::UserCmd_MovementOn()
wID = AVH_ABILITY_LEAP;
break;
//TODO: Make healspray work with attack2
//case AVH_USER3_ALIEN_PLAYER2:
// wID = AVH_WEAPON_HEALINGSPRAY;
// break;
case AVH_USER3_ALIEN_PLAYER2:
wID = AVH_WEAPON_HEALINGSPRAY;
break;
case AVH_USER3_ALIEN_PLAYER3:
lerkFlap = true;
break;
@ -404,7 +404,24 @@ void WeaponsResource::UserCmd_MovementOn()
return;
}
if (wID > -1)
if (wID == AVH_WEAPON_HEALINGSPRAY)
{
WEAPON* healWeapon = this->GetWeapon(AVH_WEAPON_HEALINGSPRAY);
WEAPON* currentWeapon = this->GetWeapon(gHUD.GetCurrentWeaponID());
if (healWeapon != NULL && currentWeapon != NULL)
{
//if (healWeapon != currentWeapon)
//{
healSprayLastWeapon = currentWeapon;
//}
ServerCmd(healWeapon->szName);
g_weaponselect = healWeapon->iId;
IN_Attack2Down();
}
}
else if (wID > -1)
{
// Fetch the needed movement weapon
WEAPON *p = this->GetWeapon(wID);
@ -427,6 +444,22 @@ void WeaponsResource::UserCmd_MovementOff()
// Ensure that we're not activating any weapons when selected
IN_Attack2Up();
IN_ReloadUp();
if (gViewPort)
{
if (gHUD.GetHUDUser3() == AVH_USER3_ALIEN_PLAYER2)
{
WEAPON* healWeapon = this->GetWeapon(AVH_WEAPON_HEALINGSPRAY);
if (healWeapon != NULL && healSprayLastWeapon != NULL)
{
//if (healsprayLastWeapon != healWeapon)
//{
ServerCmd(healSprayLastWeapon->szName);
g_weaponselect = healSprayLastWeapon->iId;
//}
}
}
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View file

@ -73,6 +73,7 @@ private:
WEAPON rgWeapons[MAX_WEAPONS]; // current weapon state
WEAPON* rgSlots[MAX_WEAPON_SLOTS][MAX_WEAPON_POSITIONS]; // current weapon slot map
WEAPON* lastWeapon; // client-side lastinv
WEAPON* healSprayLastWeapon;
int riAmmo[MAX_AMMO_TYPES]; // current ammo counts
int iOldWeaponBits;

View file

@ -525,63 +525,80 @@ void CBasePlayerWeapon::ItemPostFrame( void )
}
}
if ( (m_pPlayer->pev->button & IN_ATTACK) && !(m_pPlayer->pev->button & IN_ATTACK2))
if ((m_pPlayer->pev->button & IN_ATTACK || this->m_bAttackQueued) && (!(m_pPlayer->pev->button & IN_ATTACK2) || gHUD.GetHUDUser3() == AVH_USER3_ALIEN_PLAYER3))
{
if ((m_fInSpecialReload == 1 || m_fInSpecialReload == 2) && m_iClip != 0)
{
m_fInSpecialReload = 3;
Reload();
}
else if (GetCanUseWeapon() && (m_flNextPrimaryAttack <= 0.0))
if (GetCanUseWeapon())
{
if ( (m_iClip == 0 && ii.pszAmmo1) ||
(ii.iMaxClip == -1 && !m_pPlayer->m_rgAmmo[PrimaryAmmoIndex()] ) )
{
m_fFireOnEmpty = TRUE;
}
if ((gHUD.GetHUDUser3() == AVH_USER3_ALIEN_PLAYER1)
&& (gHUD.GetCurrentWeaponID() == AVH_ABILITY_LEAP)
&& (this->m_flLastAnimationPlayed + (float)BALANCE_VAR(kLeapROF) <= gpGlobals->time))
if ((m_fInSpecialReload == 1 || m_fInSpecialReload == 2) && m_iClip != 0)
{
// : 0001151 predict energy too
AvHAlienWeapon* theWeapon = dynamic_cast<AvHAlienWeapon *>(g_pWpns[AVH_ABILITY_LEAP]);
if ( theWeapon && theWeapon->IsUseable() ) {
float theVolumeScalar = 1.0f;
cl_entity_t *player = gEngfuncs.GetLocalPlayer();
int theSilenceLevel = AvHGetAlienUpgradeLevel(player->curstate.iuser4, MASK_UPGRADE_6);
switch(theSilenceLevel)
{
case 1:
theVolumeScalar = (float)BALANCE_VAR(kSilenceLevel1Volume);
break;
case 2:
theVolumeScalar = (float)BALANCE_VAR(kSilenceLevel2Volume);
break;
case 3:
theVolumeScalar = (float)BALANCE_VAR(kSilenceLevel3Volume);
break;
}
HUD_PlaySound( kLeapSound, theVolumeScalar);
AvHMUDeductAlienEnergy(m_pPlayer->pev->fuser3, theWeapon->GetEnergyForAttack() );
gEngfuncs.pEventAPI->EV_WeaponAnimation(3, 2);
this->m_flLastAnimationPlayed = gpGlobals->time;
}
m_fInSpecialReload = 3;
Reload();
}
else if (m_flNextPrimaryAttack <= 0.0)
{
if ( (m_iClip == 0 && ii.pszAmmo1) ||
(ii.iMaxClip == -1 && !m_pPlayer->m_rgAmmo[PrimaryAmmoIndex()] ) )
{
m_fFireOnEmpty = TRUE;
}
if ((gHUD.GetHUDUser3() == AVH_USER3_ALIEN_PLAYER1)
&& (gHUD.GetCurrentWeaponID() == AVH_ABILITY_LEAP)
&& (this->m_flLastAnimationPlayed + (float)BALANCE_VAR(kLeapROF) <= gpGlobals->time))
{
// : 0001151 predict energy too
AvHAlienWeapon* theWeapon = dynamic_cast<AvHAlienWeapon *>(g_pWpns[AVH_ABILITY_LEAP]);
if ( theWeapon && theWeapon->IsUseable() ) {
float theVolumeScalar = 1.0f;
cl_entity_t *player = gEngfuncs.GetLocalPlayer();
int theSilenceLevel = AvHGetAlienUpgradeLevel(player->curstate.iuser4, MASK_UPGRADE_6);
switch(theSilenceLevel)
{
case 1:
theVolumeScalar = (float)BALANCE_VAR(kSilenceLevel1Volume);
break;
case 2:
theVolumeScalar = (float)BALANCE_VAR(kSilenceLevel2Volume);
break;
case 3:
theVolumeScalar = (float)BALANCE_VAR(kSilenceLevel3Volume);
break;
}
HUD_PlaySound( kLeapSound, theVolumeScalar);
AvHMUDeductAlienEnergy(m_pPlayer->pev->fuser3, theWeapon->GetEnergyForAttack() );
gEngfuncs.pEventAPI->EV_WeaponAnimation(3, 2);
this->m_flLastAnimationPlayed = gpGlobals->time;
}
}
//#ifdef AVH_CLIENT
//if((m_iClip == 0) && ?
//#endif
PrimaryAttack();
//return;
}
else
{
QueueAttack();
}
//#ifdef AVH_CLIENT
//if((m_iClip == 0) && ?
//#endif
PrimaryAttack();
//return;
}
}
// +movement: Rewritten to allow us to use +attack2 for movement abilities
else if ((m_pPlayer->pev->button & IN_ATTACK2) && (gHUD.GetIsAlien()))
{
AvHUser3 theUser3 = gHUD.GetHUDUser3();
//m_flNextSecondaryAttack
// Find out what kind of special movement we are using, and execute the animation for it
if (this->PrevAttack2Status == false)
if (theUser3 == AVH_USER3_ALIEN_PLAYER2)
{
if (GetCanUseWeapon() && m_flNextPrimaryAttack <= 0.0)
{
SecondaryAttack();
}
}
else if (this->PrevAttack2Status == false)
{
bool enabled=false;
// : 0001151 predict energy too
@ -589,7 +606,7 @@ void CBasePlayerWeapon::ItemPostFrame( void )
if ( theWeapon )
enabled=theWeapon->IsUseable();
switch (gHUD.GetHUDUser3())
switch (theUser3)
{
case AVH_USER3_ALIEN_PLAYER1:
@ -644,8 +661,7 @@ void CBasePlayerWeapon::ItemPostFrame( void )
}
}
if ((gHUD.GetHUDUser3() == AVH_USER3_ALIEN_PLAYER1)
&& (this->m_flLastAnimationPlayed + BALANCE_VAR(kLeapROF) < gpGlobals->time))
if ((theUser3 == AVH_USER3_ALIEN_PLAYER1) && (this->m_flLastAnimationPlayed + BALANCE_VAR(kLeapROF) < gpGlobals->time))
this->PrevAttack2Status = false;
else
this->PrevAttack2Status = true;

View file

@ -61,6 +61,7 @@ extern "C"
#include "mod/AvHScrollHandler.h"
#include "mod/AvHCommanderModeHandler.h"
#include "util/Mat3.h"
#include "mod/AvHBasePlayerWeaponConstants.h"
#include "engine/APIProxy.h"
#include "Exports.h"
@ -145,6 +146,7 @@ cvar_t *senslock;
cvar_t *cl_chatbeep;
cvar_t *cl_mutemenu;
cvar_t *cl_weaponcfgs;
cvar_t *cl_pistoltrigger;
/*
===============================================================================
@ -808,7 +810,7 @@ void IN_AttackUp(void)
in_cancel = 0;
// Attack2up only for onos so it can end +attack onos charges. Attack2up for all causes blink and leap to cancel if you release attack while blinking or leaping.
if (g_iUser3 == AVH_USER3_ALIEN_PLAYER5)
if (gHUD.GetCurrentWeaponID() == AVH_ABILITY_CHARGE)
{
IN_Attack2Up();
}
@ -824,6 +826,32 @@ void IN_AttackUpForced(void)
KeyUpForced( &in_attack );
}
void IN_AttackHandlerDown(void)
{
if (gHUD.GetCurrentWeaponID() == AVH_WEAPON_PISTOL && cl_pistoltrigger && cl_pistoltrigger->value)
{
IN_AttackDown();
IN_AttackUp();
}
else
{
IN_AttackDown();
}
}
void IN_AttackHandlerUp(void)
{
if (gHUD.GetCurrentWeaponID() == AVH_WEAPON_PISTOL && cl_pistoltrigger && cl_pistoltrigger->value)
{
IN_AttackDown();
IN_AttackUp();
}
else
{
IN_AttackUp();
}
}
// Special handling
void IN_Cancel(void)
{
@ -1602,8 +1630,8 @@ void InitInput (void)
gEngfuncs.pfnAddCommand ("-moveright", IN_MoverightUp);
gEngfuncs.pfnAddCommand ("+speed", IN_SpeedDown);
gEngfuncs.pfnAddCommand ("-speed", IN_SpeedUp);
gEngfuncs.pfnAddCommand ("+attack", IN_AttackDown);
gEngfuncs.pfnAddCommand ("-attack", IN_AttackUp);
gEngfuncs.pfnAddCommand ("+attack", IN_AttackHandlerDown);
gEngfuncs.pfnAddCommand ("-attack", IN_AttackHandlerUp);
//gEngfuncs.pfnAddCommand ("+movement", IN_Attack2Down);
//gEngfuncs.pfnAddCommand ("-movement", IN_Attack2Up);
gEngfuncs.pfnAddCommand ("+use", IN_UseDown);
@ -1687,6 +1715,7 @@ void InitInput (void)
cl_chatbeep = gEngfuncs.pfnRegisterVariable ("cl_chatbeep", "1", FCVAR_ARCHIVE);
cl_mutemenu = gEngfuncs.pfnRegisterVariable ("cl_mutemenu", "3", FCVAR_ARCHIVE);
cl_weaponcfgs = gEngfuncs.pfnRegisterVariable ("cl_weaponcfgs", "1", FCVAR_ARCHIVE);
cl_pistoltrigger = gEngfuncs.pfnRegisterVariable ("cl_pistoltrigger", "1", FCVAR_ARCHIVE);
// Initialize third person camera controls.
CAM_Init();

View file

@ -949,7 +949,8 @@ BOOL CanAttack( float attack_time, float curtime, BOOL isPredicted )
void CBasePlayerWeapon::ItemPostFrame( void )
{
bool theAttackPressed = (m_pPlayer->pev->button & IN_ATTACK) && !(m_pPlayer->pev->button & IN_ATTACK2);
// Block attacks during +movement except for lerk.
bool theAttackPressed = (m_pPlayer->pev->button & IN_ATTACK) && (!(m_pPlayer->pev->button & IN_ATTACK2) || m_pPlayer->pev->iuser3 == AVH_USER3_ALIEN_PLAYER3);
bool theWeaponPrimes = (this->GetWeaponPrimeTime() > 0.0f);
bool theWeaponIsPriming = this->GetIsWeaponPriming();
@ -988,7 +989,7 @@ void CBasePlayerWeapon::ItemPostFrame( void )
else
*/
if ( theAttackPressed && m_pPlayer->GetCanUseWeapon())
if ( (theAttackPressed || m_bAttackQueued) && m_pPlayer->GetCanUseWeapon())
{
if ((m_fInSpecialReload == 1 || m_fInSpecialReload == 2) && m_iClip != 0)
{
@ -1005,6 +1006,20 @@ void CBasePlayerWeapon::ItemPostFrame( void )
m_pPlayer->TabulateAmmo();
PrimaryAttack();
}
else
{
QueueAttack();
}
}
else if (m_pPlayer->pev->button & IN_ATTACK2)
{
if (m_pPlayer->pev->iuser3 == AVH_USER3_ALIEN_PLAYER2 && m_pPlayer->GetCanUseWeapon())
{
if (CanAttack(m_flNextPrimaryAttack, gpGlobals->time, UseDecrement()))
{
SecondaryAttack();
}
}
}
else if ( m_pPlayer->pev->button & IN_RELOAD && iMaxClip() != WEAPON_NOCLIP && !m_fInReload )
{

View file

@ -354,6 +354,7 @@ public:
virtual void ItemPostFrame( void ); // called each frame by the player PostThink
// called by CBasePlayerWeapons ItemPostFrame()
virtual void PrimaryAttack( void ) { return; } // do "+ATTACK"
virtual void QueueAttack(void) { return; } // queue an attack
virtual void SecondaryAttack( void ) { return; } // do "+ATTACK2"
virtual void Reload( void ) { return; } // do "+RELOAD"
virtual void WeaponIdle( void ) { return; } // called when no buttons pressed
@ -385,6 +386,7 @@ public:
bool PrevAttack2Status; // HACK: For +movement weapon animations
float m_flLastAnimationPlayed;
bool m_bAttackQueued;
};

View file

@ -426,6 +426,8 @@ public:
virtual void Precache(void);
virtual void SecondaryAttack();
virtual void Spawn();
protected:

View file

@ -675,6 +675,8 @@ void AvHBasePlayerWeapon::Holster( int skiplocal)
#ifdef AVH_SERVER
this->mInOverwatch = false;
#endif
this->m_bAttackQueued = false;
}
float AvHBasePlayerWeapon::GetTimePassedThisTick() const

View file

@ -137,6 +137,11 @@ void AvHHealingSpray::Precache()
this->mEvent = PRECACHE_EVENT(1, kHealingSprayEventName);
}
// Use secondary attack to call primary attack so client predicted ghost spit attacks don't occur on the first frame of +movement use, as the weapon also switches that frame.
void AvHHealingSpray::SecondaryAttack(void)
{
AvHHealingSpray::PrimaryAttack();
}
void AvHHealingSpray::Spawn()
{

View file

@ -233,6 +233,10 @@ public:
virtual void Precache(void);
virtual void PrimaryAttack();
virtual void QueueAttack(void);
virtual void Spawn();
protected:

View file

@ -174,6 +174,19 @@ void AvHPistol::Precache()
this->mEvent = PRECACHE_EVENT(1, kHGEventName);
}
void AvHPistol::PrimaryAttack()
{
this->m_bAttackQueued = false;
AvHMarineWeapon::PrimaryAttack();
}
void AvHPistol::QueueAttack(void)
{
if (!this->mAttackButtonDownLastFrame)
{
this->m_bAttackQueued = true;
}
}
void AvHPistol::Spawn()
{