o Added +movement to trigger blink, leap and charge

o +movement causes a marine player to reload
o Added charge prototype - WIP

git-svn-id: https://unknownworlds.svn.cloudforge.com/ns1@407 67975925-1194-0748-b3d5-c16f83f1a3a1
This commit is contained in:
tankefugl 2006-04-24 23:40:42 +00:00
parent 2ba500a52a
commit 130c98fed5
17 changed files with 686 additions and 278 deletions

View file

@ -351,7 +351,12 @@
#define kCatalystDamagePercent 0.25
#define kCatalystROFFactor 0.25
#define kCatalystSpeedIncrease 0.25
#define kChargeEnergyCost 0.07
#define kChargeEnergyCost 0.15
#define kChargeMaxPushbackSpeedFactor 2.50
#define kChargeMaxPushbackForce 100.0
#define kChargePushbackRadius 100.0
#define kChargeSpeed 1.00
#define kChargeThresholdTime 0.75
#define kChargingEnergyScalar 2.80
#define kClawsEnergyCost 0.07
#define kClawsROF 0.90
@ -400,6 +405,7 @@
#define kKNROF 0.65
#define kLeapEnergyCost 0.25
#define kLerkBaseAscendSpeedMax 600.00
#define kLeapROF 0.50
#define kMGROF 0.10
#define kMarineArmorLevelOne 0.20
#define kMarineArmorLevelThree 0.60

Binary file not shown.

Binary file not shown.

View file

@ -41,10 +41,24 @@ WeaponsResource gWR;
int g_weaponselect = 0;
void IN_AttackDownForced(void);
void IN_AttackUpForced(void);
void IN_Attack2Down(void);
void IN_Attack2Up(void);
void IN_ReloadDown();
void IN_ReloadUp();
bool CheckInAttack(void);
//Equivalent to DECLARE_COMMAND(lastinv,LastInv) except we use gWR instead of gHud
void __CmdFunc_LastInv(void)
{ gWR.UserCmd_LastInv(); }
// +movement
void __CmdFunc_MovementOn(void)
{ gWR.UserCmd_MovementOn(); }
void __CmdFunc_MovementOff(void)
{ gWR.UserCmd_MovementOff(); }
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
WeaponsResource::WeaponsResource(void) : lastWeapon(NULL), iOldWeaponBits(0) {}
@ -56,7 +70,10 @@ void WeaponsResource::Init( void )
{
memset( rgWeapons, 0, sizeof(WEAPON)*MAX_WEAPONS );
Reset();
HOOK_COMMAND("lastinv",LastInv);
HOOK_COMMAND("lastinv", LastInv);
// +movement
HOOK_COMMAND("+movement", MovementOn);
HOOK_COMMAND("-movement", MovementOff);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -337,6 +354,53 @@ void WeaponsResource::UserCmd_LastInv(void)
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void WeaponsResource::UserCmd_MovementOn()
{
// Find out which weapon we want to trigger
AvHUser3 theUser3 = gHUD.GetHUDUser3();
int wID = -1;
switch(theUser3)
{
case AVH_USER3_ALIEN_PLAYER1:
wID = AVH_ABILITY_LEAP;
break;
case AVH_USER3_ALIEN_PLAYER3:
// TODO: Add flap
break;
case AVH_USER3_ALIEN_PLAYER4:
wID = AVH_WEAPON_BLINK;
break;
case AVH_USER3_ALIEN_PLAYER5:
wID = AVH_ABILITY_CHARGE;
break;
default:
IN_ReloadDown();
return;
}
if (wID > -1)
{
// Fetch the needed movement weapon
WEAPON *p = this->GetWeapon(wID);
if (p != NULL && this->IsSelectable(p))
{
// Send activation of ability asap
IN_Attack2Down();
}
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void WeaponsResource::UserCmd_MovementOff()
{
// Ensure that we're not activating any weapons when selected
IN_Attack2Up();
IN_ReloadUp();
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void WeaponsResource::SetValidWeapon(void)
{
WEAPON* p = this->GetFirstPos(0); //alien attack 1 or primary marine weapon

View file

@ -62,6 +62,8 @@ public:
//CONSIDER: Should the selection functions be in the menu with the selection variables?
void UserCmd_LastInv( void );
void UserCmd_MovementOn( void );
void UserCmd_MovementOff( void );
void SetValidWeapon( void );
void SetCurrentWeapon( WEAPON* wp );
void SelectSlot( int iSlot, int fAdvance, int iDirection );

View file

@ -97,6 +97,8 @@ static globalvars_t Globals;
static CBasePlayerWeapon *g_pWpns[ 32 ];
bool CheckInAttack2(void);
vec3_t previousorigin;
// HLDM Weapon placeholder entities.
@ -489,20 +491,21 @@ void CBasePlayerWeapon::ItemPostFrame( void )
m_fInReload = FALSE;
}
if ((m_pPlayer->pev->button & IN_ATTACK2) && (m_flNextSecondaryAttack <= 0.0))
// Properly propagate the end animation
if (this->PrevAttack2Status == true && !(m_pPlayer->pev->button & IN_ATTACK2) && (gHUD.GetHUDUser3() == AVH_USER3_ALIEN_PLAYER4))
{
if (GetCanUseWeapon())
{
if ( pszAmmo2() && !m_pPlayer->m_rgAmmo[SecondaryAmmoIndex()] )
{
m_fFireOnEmpty = TRUE;
}
SecondaryAttack();
m_pPlayer->pev->button &= ~IN_ATTACK2;
}
switch (gHUD.GetCurrentWeaponID())
{
case AVH_WEAPON_SWIPE:
this->SendWeaponAnim(12);
break;
case AVH_WEAPON_ACIDROCKET:
this->SendWeaponAnim(8);
break;
}
}
else if ( (m_pPlayer->pev->button & IN_ATTACK) && (m_flNextPrimaryAttack <= 0.0) )
if ( (m_pPlayer->pev->button & IN_ATTACK) && !(m_pPlayer->pev->button & IN_ATTACK2) && (m_flNextPrimaryAttack <= 0.0) )
{
if (GetCanUseWeapon())
{
@ -518,6 +521,42 @@ void CBasePlayerWeapon::ItemPostFrame( void )
PrimaryAttack();
}
}
// +movement: Rewritten to allow us to use +attack2 for movement abilities
else if ((m_pPlayer->pev->button & IN_ATTACK2) && (m_flNextPrimaryAttack <= 0.0))
{
// Find out what kind of special movement we are using, and execute the animation for it
if (this->PrevAttack2Status == false)
{
switch (gHUD.GetHUDUser3())
{
case AVH_USER3_ALIEN_PLAYER1:
// TODO: Add prediction and cooldown to the leap animation!
this->SendWeaponAnim(3);
break;
case AVH_USER3_ALIEN_PLAYER4:
switch (gHUD.GetCurrentWeaponID())
{
case AVH_WEAPON_SWIPE:
this->SendWeaponAnim(9);
break;
case AVH_WEAPON_ACIDROCKET:
this->SendWeaponAnim(11);
break;
}
break;
}
// (gHUD.GetHUDUser3() == AVH_USER3_ALIEN_PLAYER4)
}
this->PrevAttack2Status = true;
return;
// if (GetCanUseWeapon())
// {
// PrimaryAttack();
// }
}
else if ( m_pPlayer->pev->button & IN_RELOAD && iMaxClip() != WEAPON_NOCLIP && !m_fInReload )
{
@ -527,7 +566,8 @@ void CBasePlayerWeapon::ItemPostFrame( void )
Reload();
}
}
else if ( !(m_pPlayer->pev->button & (IN_ATTACK|IN_ATTACK2) ) )
// +movement: Removed case for +attack2
else if ( !(m_pPlayer->pev->button & (IN_ATTACK /*|IN_ATTACK2 */) ) )
{
if (GetCanUseWeapon())
{
@ -549,9 +589,12 @@ void CBasePlayerWeapon::ItemPostFrame( void )
WeaponIdle( );
}
this->PrevAttack2Status = false;
return;
}
this->PrevAttack2Status = false;
// catch all
if ( ShouldWeaponIdle() )
{
@ -1240,7 +1283,7 @@ void HUD_WeaponsPostThink( local_state_s *from, local_state_s *to, usercmd_t *cm
// Make sure that weapon animation matches what the game .dll is telling us
// over the wire ( fixes some animation glitches )
if ( g_runfuncs && ( HUD_GetWeaponAnim() != to->client.weaponanim ) )
if (false) //g_runfuncs && ( HUD_GetWeaponAnim() != to->client.weaponanim ) && !(CheckInAttack2()) )
{
int body = 2;

View file

@ -356,6 +356,8 @@ void KB_Shutdown( void )
void KeyDown (kbutton_t *b);
void KeyUp (kbutton_t *b);
void KeyDownForced (kbutton_t *b);
void KeyUpForced (kbutton_t *b);
/*
============
@ -431,6 +433,21 @@ void KeyDown (kbutton_t *b)
b->state |= 1 + 2; // down + impulse down
}
/*
============
KeyDownForced
============
*/
void KeyDownForced (kbutton_t *b)
{
b->down[0] = 0;
b->down[1] = 0;
if (b->state & 1)
return; // still down
b->state |= 1 + 2; // down + impulse down
}
/*
============
KeyUp
@ -470,6 +487,19 @@ void KeyUp (kbutton_t *b)
b->state |= 4; // impulse up
}
/*
============
KeyUpForced
============
*/
void KeyUpForced (kbutton_t *b)
{
if (!(b->state & 1))
return; // still up (this should not happen)
b->state &= ~1; // now up
b->state |= 4; // impulse up
}
bool AvHContainsBlockedCommands(const char* inInput)
{
@ -760,8 +790,8 @@ void IN_SpeedDown(void) {KeyDown(&in_speed);}
void IN_SpeedUp(void) {KeyUp(&in_speed);}
void IN_StrafeDown(void) {KeyDown(&in_strafe);}
void IN_StrafeUp(void) {KeyUp(&in_strafe);}
void IN_Attack2Down(void) {KeyDown(&in_attack2);}
void IN_Attack2Up(void) {KeyUp(&in_attack2);}
void IN_Attack2Down(void) {KeyDownForced(&in_attack2);}
void IN_Attack2Up(void) {KeyUpForced(&in_attack2);}
void IN_UseDown (void)
{
KeyDown(&in_use);
@ -800,8 +830,8 @@ void IN_DuckToggle(void)
g_bDuckToggled = !g_bDuckToggled;
}
// :tankefugl
void IN_ReloadDown(void) {KeyDown(&in_reload);}
void IN_ReloadUp(void) {KeyUp(&in_reload);}
void IN_ReloadDown(void) {KeyDownForced(&in_reload);}
void IN_ReloadUp(void) {KeyUpForced(&in_reload);}
void IN_Alt1Down(void) {KeyDown(&in_alt1);}
void IN_Alt1Up(void) {KeyUp(&in_alt1);}
void IN_GraphDown(void) {KeyDown(&in_graph);}
@ -817,6 +847,17 @@ void IN_AttackUp(void)
{
KeyUp( &in_attack );
in_cancel = 0;
IN_Attack2Up();
}
void IN_AttackDownForced(void)
{
KeyDownForced( &in_attack );
}
void IN_AttackUpForced(void)
{
KeyUpForced( &in_attack );
}
// Special handling
@ -825,6 +866,16 @@ void IN_Cancel(void)
in_cancel = 1;
}
bool CheckInAttack(void)
{
return (in_attack.state & 1 || in_attack2.state & 1);
}
bool CheckInAttack2(void)
{
return (in_attack2.state & 1);
}
void IN_Impulse (void)
{
//char msg[1024];
@ -1503,8 +1554,8 @@ void InitInput (void)
gEngfuncs.pfnAddCommand ("-speed", IN_SpeedUp);
gEngfuncs.pfnAddCommand ("+attack", IN_AttackDown);
gEngfuncs.pfnAddCommand ("-attack", IN_AttackUp);
gEngfuncs.pfnAddCommand ("+attack2", IN_Attack2Down);
gEngfuncs.pfnAddCommand ("-attack2", IN_Attack2Up);
//gEngfuncs.pfnAddCommand ("+movement", IN_Attack2Down);
//gEngfuncs.pfnAddCommand ("-movement", IN_Attack2Up);
gEngfuncs.pfnAddCommand ("+use", IN_UseDown);
gEngfuncs.pfnAddCommand ("-use", IN_UseUp);
gEngfuncs.pfnAddCommand ("+jump", IN_JumpDown);

View file

@ -933,7 +933,7 @@ BOOL CanAttack( float attack_time, float curtime, BOOL isPredicted )
void CBasePlayerWeapon::ItemPostFrame( void )
{
bool theAttackPressed = (m_pPlayer->pev->button & IN_ATTACK);
bool theAttackPressed = (m_pPlayer->pev->button & IN_ATTACK) && !(m_pPlayer->pev->button & IN_ATTACK2);
bool theWeaponPrimes = (this->GetWeaponPrimeTime() > 0.0f);
bool theWeaponIsPriming = this->GetIsWeaponPriming();
@ -953,6 +953,7 @@ void CBasePlayerWeapon::ItemPostFrame( void )
m_fInReload = FALSE;
}
/* // +movement: Removed case for +attack2 since it's used for movement abilities
if ((m_pPlayer->pev->button & IN_ATTACK2) && CanAttack( m_flNextSecondaryAttack, gpGlobals->time, UseDecrement() ) )
{
if (m_pPlayer->GetCanUseWeapon())
@ -968,7 +969,9 @@ void CBasePlayerWeapon::ItemPostFrame( void )
m_pPlayer->pev->button &= ~IN_ATTACK2;
}
}
else if ( theAttackPressed && CanAttack( m_flNextPrimaryAttack, gpGlobals->time, UseDecrement() ) )
else
*/
if ( theAttackPressed && CanAttack( m_flNextPrimaryAttack, gpGlobals->time, UseDecrement() ) )
{
if (m_pPlayer->GetCanUseWeapon())
{
@ -989,7 +992,8 @@ void CBasePlayerWeapon::ItemPostFrame( void )
Reload();
}
}
else if ( !(m_pPlayer->pev->button & (IN_ATTACK|IN_ATTACK2) ) )
// +movement: Removed case for +attack2
else if ( !(m_pPlayer->pev->button & (IN_ATTACK /* |IN_ATTACK2 */) ) )
{
if (m_pPlayer->GetCanUseWeapon())
{

View file

@ -383,6 +383,7 @@ public:
int m_iDefaultAmmo;// how much ammo you get when you pick up this weapon as placed by a level designer.
bool PrevAttack2Status; // HACK: For +movement weapon animations
};

View file

@ -57,6 +57,7 @@
#include "cl_dll/hud.h"
#include "mod/AvHHud.h"
extern int g_runfuncs;
void IN_Attack2Down();
#endif
LINK_ENTITY_TO_CLASS(kwLeap, AvHLeap);
@ -144,11 +145,24 @@ void AvHLeap::Spawn()
FallInit();// get ready to fall down.
}
float AvHLeap::GetRateOfFire(void) const
{
// Dunno why the 2 has to be there ...
return 2 * (float)BALANCE_VAR(kLeapROF);
}
bool AvHLeap::UsesAmmo(void) const
{
return false;
}
void AvHLeap::SecondaryAttack()
{
#ifdef AVH_CLIENT
this->FireProjectiles();
#endif
}
void AvHLeap::FireProjectiles(void)
{
#ifdef AVH_SERVER
@ -161,6 +175,7 @@ void AvHLeap::FireProjectiles(void)
#ifdef AVH_CLIENT
if(g_runfuncs)
{
//IN_Attack2Down();
gHUD.SetAlienAbility(this->GetAbilityImpulse());
}
#endif
@ -220,7 +235,7 @@ int AvHCharge::GetDeployAnimation() const
float AvHCharge::GetDeployTime() const
{
return .6f;
return 0.0f; //.6f;
}
bool AvHCharge::GetFiresUnderwater() const
@ -278,14 +293,26 @@ bool AvHCharge::UsesAmmo(void) const
return false;
}
void AvHCharge::SecondaryAttack()
{
#ifdef AVH_CLIENT
this->FireProjectiles();
#endif
}
void AvHCharge::FireProjectiles(void)
{
#ifdef AVH_CLIENT
IN_Attack2Down();
//gHUD.SetAlienAbility(this->GetAbilityImpulse());
#endif
// Event is played back. Mark pmove with proper flag so the alien Charges forward.
PLAYBACK_EVENT_FULL(0, this->m_pPlayer->edict(), this->mAbilityEvent, 0, this->m_pPlayer->pev->origin, (float *)&g_vecZero, 0.0, 0.0, this->GetAbilityImpulse(), 0, 1, 0 );
//PLAYBACK_EVENT_FULL(0, this->m_pPlayer->edict(), this->mAbilityEvent, 0, this->m_pPlayer->pev->origin, (float *)&g_vecZero, 0.0, 0.0, this->GetAbilityImpulse(), 0, 1, 0 );
// Send fire anim
//SendWeaponAnim(5);
this->PlaybackEvent(this->mWeaponAnimationEvent, 5);
//this->PlaybackEvent(this->mWeaponAnimationEvent, 5);
}
void AvHCharge::Init()
@ -295,6 +322,6 @@ void AvHCharge::Init()
float AvHCharge::GetRateOfFire() const
{
// Approximate length of charge sound
return 5.0f;
return 1.0f;
}

View file

@ -83,6 +83,10 @@ public:
virtual bool UsesAmmo(void) const;
virtual BOOL GetTakesEnergy() { return FALSE; }
void SecondaryAttack();
virtual float GetRateOfFire(void) const;
protected:
virtual void FireProjectiles(void);
@ -129,6 +133,8 @@ public:
virtual bool UsesAmmo(void) const;
virtual BOOL GetTakesEnergy() { return FALSE; }
void SecondaryAttack();
protected:
virtual void FireProjectiles(void);
@ -174,6 +180,8 @@ public:
virtual bool UsesAmmo(void) const;
virtual float GetRateOfFire() const;
void SecondaryAttack();
protected:
virtual void FireProjectiles(void);

View file

@ -42,7 +42,6 @@ const float kLeapPunch = 2.5;
#define kLeapKillSound "weapons/leapkill.wav"
#define kLeapEventName "events/Leap.sc"
#define kLeapPModel "models/null.mdl"
const float kLeapROF = 1.5f;
const float kLeapDuration = 1.0f;
// Charge constants.
@ -55,6 +54,9 @@ const float kChargeROF = 5.0f;
#define kAlienSightOnSound "misc/aliensighton.wav"
#define kAlienSightOffSound "misc/aliensightoff.wav"
// Blink constants
#define kBlinkSound "weapons/blinksuccess.wav"
const int kAlienCloakRenderMode = kRenderTransTexture;
const int kAlienCloakAmount = 25;
// puzl: 1061 full cloaking

View file

@ -13,6 +13,7 @@ extern playermove_t* pmove;
#include "cl_dll/hud.h"
#include "mod/AvHHud.h"
extern int g_runfuncs;
void IN_Attack2Down();
#endif
#include "mod/AvHAlienAbilities.h"
@ -102,6 +103,13 @@ AvHMessageID AvHBlinkGun::GetAbilityImpulse() const
return ALIEN_ABILITY_BLINK;
}
void AvHBlinkGun::SecondaryAttack()
{
#ifdef AVH_CLIENT
//this->FireProjectiles();
#endif
}
void AvHBlinkGun::FireProjectiles(void)
{
#ifdef AVH_CLIENT

View file

@ -2281,8 +2281,8 @@ void AvHPlayer::PlayerTouch(CBaseEntity* inOther)
}
}
// Are we charging?
if(GetHasUpgrade(this->pev->iuser4, MASK_ALIEN_MOVEMENT) /*&& !this->GetIsBlinking()*/)
// Are we charging?
if(false) // GetHasUpgrade(this->pev->iuser4, MASK_ALIEN_MOVEMENT))
{
if(GetGameRules()->CanEntityDoDamageTo(this, inOther, &theScalar))
{
@ -3299,7 +3299,8 @@ void AvHPlayer::ItemPostFrame(void)
// Check if player tried to do something while we were in the ready room. If so, display tutorial message.
if(this->GetPlayMode() == PLAYMODE_READYROOM)
{
if((this->pev->button & IN_ATTACK) || (this->pev->button & IN_ATTACK2) || (this->pev->button & IN_RELOAD))
// +movement: Removed case for +attack2
if((this->pev->button & IN_ATTACK) /* || (this->pev->button & IN_ATTACK2) */ || (this->pev->button & IN_RELOAD))
{
this->SendMessageOnce(kReadyRoomMessage, TOOLTIP);
}
@ -4057,7 +4058,8 @@ void AvHPlayer::HandleTopDownInput()
{
// From CBasePlayer::PreThink():
bool theAttackOneDown = FBitSet(this->mCurrentCommand.buttons, IN_ATTACK);
bool theAttackTwoDown = FBitSet(this->mCurrentCommand.buttons, IN_ATTACK2);
// +movement: Removed case for +attack2
bool theAttackTwoDown = false; //FBitSet(this->mCurrentCommand.buttons, IN_ATTACK2);
bool theJumpHit = FBitSet(this->mCurrentCommand.buttons, IN_JUMP);
bool theCrouchDown = FBitSet(this->mCurrentCommand.buttons, IN_DUCK);
@ -6715,6 +6717,52 @@ void AvHPlayer::InternalPreThink()
PROFILE_START()
this->InternalHUDThink();
PROFILE_END(kPlayerHUDThink)
this->InternalChargeThink();
}
// Charge pushback
void AvHPlayer::InternalChargeThink()
{
// Check whether we're in a charge
if(GetHasUpgrade(this->pev->iuser4, MASK_ALIEN_MOVEMENT) && (GetUser3() == AVH_USER3_ALIEN_PLAYER5))
{
CBaseEntity* theEntity = NULL;
float radius = (float)BALANCE_VAR(kChargePushbackRadius);
float maxpushbackspeedfactor = (float)BALANCE_VAR(kChargeMaxPushbackSpeedFactor);
float pushbackfactor = (float)BALANCE_VAR(kChargeMaxPushbackForce);
// Find all entities around the onos
while((theEntity = UTIL_FindEntityInSphere(theEntity, this->pev->origin, radius)) != NULL)
{
if (theEntity->IsPlayer() && theEntity->IsAlive())
{
float distance = VectorDistance(this->pev->origin, theEntity->pev->origin);
if (distance > 0.0f)
{
float factor = pushbackfactor / (radius / distance);
vec3_t direction, heading;
VectorSubtract(theEntity->pev->origin, this->pev->origin, direction);
VectorNormalize(direction);
VectorCopy(this->pev->velocity, heading);
VectorNormalize(heading);
float dot = DotProduct(heading, direction);
if (dot > 0.0f)
{
VectorScale(direction, factor * dot, direction);
VectorAdd(theEntity->pev->velocity, direction, theEntity->pev->velocity);
if (Length(theEntity->pev->velocity) > theEntity->pev->maxspeed * maxpushbackspeedfactor)
{
VectorNormalize(theEntity->pev->velocity);
VectorScale(theEntity->pev->velocity, theEntity->pev->maxspeed * maxpushbackspeedfactor, theEntity->pev->velocity);
}
}
}
}
}
}
}
void AvHPlayer::InternalFogThink()

View file

@ -534,6 +534,7 @@ private:
void InternalPreThink();
void InternalProgressBarThink();
void InternalSpeakingThink();
void InternalChargeThink();
void EXPORT PlayerTouch(CBaseEntity* inOther);

View file

@ -327,7 +327,10 @@ void PM_NSPlaySound( int channel, const char *sample, float volume, float attenu
bool PM_GetIsBlinking()
{
if (pmove->cmd.weaponselect == 255 || pmove->flags & FL_FAKECLIENT)
if (pmove->iuser3 == AVH_USER3_ALIEN_PLAYER4 && GetHasUpgrade(pmove->iuser4, MASK_ALIEN_MOVEMENT))
return true;
if (pmove->cmd.weaponselect == 255 || pmove->flags & FL_FAKECLIENT)
{
return (pmove->iuser3 == AVH_USER3_ALIEN_PLAYER4) && (pmove->cmd.impulse == ALIEN_ABILITY_BLINK);
}
@ -336,7 +339,10 @@ bool PM_GetIsBlinking()
bool PM_GetIsLeaping()
{
if (pmove->cmd.weaponselect == 255 || pmove->flags & FL_FAKECLIENT)
if (pmove->iuser3 == AVH_USER3_ALIEN_PLAYER1 && GetHasUpgrade(pmove->iuser4, MASK_ALIEN_MOVEMENT))
return true;
if (pmove->cmd.weaponselect == 255 || pmove->flags & FL_FAKECLIENT)
{
return (pmove->iuser3 == AVH_USER3_ALIEN_PLAYER1) && (pmove->cmd.impulse == ALIEN_ABILITY_LEAP);
}
@ -345,14 +351,16 @@ bool PM_GetIsLeaping()
bool PM_GetIsCharging()
{
if (pmove->cmd.weaponselect == 255 || pmove->flags & FL_FAKECLIENT)
if (pmove->iuser3 == AVH_USER3_ALIEN_PLAYER5 && GetHasUpgrade(pmove->iuser4, MASK_ALIEN_MOVEMENT))
return true;
if (pmove->cmd.weaponselect == 255 || pmove->flags & FL_FAKECLIENT)
{
return (pmove->cmd.impulse == ALIEN_ABILITY_CHARGE);
}
return false;
}
/*
===================
PM_InitBoxHull
@ -4338,14 +4346,337 @@ bool NS_PositionFreeForPlayer(vec3_t& inPosition)
}
*/
// Fade blink
bool PM_BlinkMove (void)
{
if (pmove->fuser4 != 0.0f)
return false;
float theScalar = 500;
float theEnergyCost = 0;
AvHMUGetEnergyCost(AVH_WEAPON_BLINK, theEnergyCost);
if(AvHMUHasEnoughAlienEnergy(pmove->fuser3, theEnergyCost * 2))
{
AvHMUDeductAlienEnergy(pmove->fuser3, theEnergyCost * 2);
}
else
return false;
pmove->fuser4 = 2 * (float)BALANCE_VAR(kBlinkROF);
SetUpgradeMask(&pmove->iuser4, MASK_ALIEN_MOVEMENT, true);
PM_NSPlaySound(CHAN_WEAPON, kBlinkSound, 1.0f, ATTN_NORM, 0, 94 + pmove->RandomLong(0, 0xf));
vec3_t forward, right, up;
AngleVectors(pmove->angles, forward, right, up);
PM_Jump();
vec3_t theAbilityVelocity;
VectorScale(forward, theScalar, theAbilityVelocity);
vec3_t theFinalVelocity;
VectorAdd(pmove->velocity, theAbilityVelocity, theFinalVelocity);
VectorCopy(theFinalVelocity, pmove->velocity);
return true;
// Uncomment to experience the tankeblink
/* float theEnergyCost = (float)BALANCE_VAR(kBlinkEnergyCost) * (float)pmove->frametime;
float theBlinkThresholdTime = (float)BALANCE_VAR(kBlinkThresholdTime);
if (AvHMUHasEnoughAlienEnergy(pmove->fuser3, theEnergyCost) && (pmove->fuser4 >= 0.0f))
{
AvHMUDeductAlienEnergy(pmove->fuser3, theEnergyCost);
if (pmove->fuser4 == 0.0f)
{
int theSilenceUpgradeLevel = AvHGetAlienUpgradeLevel(pmove->iuser4, MASK_UPGRADE_6);
float theVolumeScalar = 1.0f - theSilenceUpgradeLevel/3.0f;
PM_NSPlaySound( CHAN_WEAPON, "player/metabolize_fire.wav", theVolumeScalar, ATTN_NORM, 0, PITCH_NORM );
}
pmove->fuser4 += (float)pmove->frametime;
pmove->fuser4 = max(0, min(pmove->fuser4, theBlinkThresholdTime));
}
else
return false;
if (pmove->fuser4 >= theBlinkThresholdTime)
{
SetUpgradeMask(&pmove->iuser4, MASK_ALIEN_MOVEMENT, true);
vec3_t wishvel, dest;
pmtrace_t trace;
float fmove, smove;
// Copy movement amounts
fmove = pmove->cmd.forwardmove;
smove = pmove->cmd.sidemove;
VectorNormalize(pmove->forward);
VectorScale(pmove->forward, 800, wishvel);
VectorMA(pmove->origin, pmove->frametime, wishvel, dest);
// first try moving directly to the next spot
trace = pmove->PM_PlayerTrace(pmove->origin, dest, PM_NORMAL, -1 );
// If we made it all the way, then copy trace end as new player position.
if (trace.fraction == 1)
{
VectorCopy(trace.endpos, pmove->origin);
}
else
{
// if we can't move, adjust velocity to slite along the plane we collided with
// and retry
int attempts = 0; // in case we continue to collide vs. the old planes
while (true) {
PM_ClipVelocity(wishvel, trace.plane.normal, wishvel, 1.0);
VectorMA(pmove->origin, pmove->frametime, wishvel, dest);
trace = pmove->PM_PlayerTrace(pmove->origin, dest, PM_NORMAL, -1 );
if (trace.fraction == 1)
{
VectorCopy(trace.endpos, pmove->origin);
break;
}
if (attempts++ > 5) {
break;
}
}
}
VectorClear(pmove->velocity);
}
else
{
SetUpgradeMask(&pmove->iuser4, MASK_ALIEN_MOVEMENT, false);
}
*/
}
// Skulk leap
bool PM_LeapMove()
{
if (pmove->fuser4 != 0.0f)
return false;
float theScalar = 500;
float theEnergyCost = 0;
AvHMUGetEnergyCost(AVH_ABILITY_LEAP, theEnergyCost);
if(AvHMUHasEnoughAlienEnergy(pmove->fuser3, theEnergyCost))
{
AvHMUDeductAlienEnergy(pmove->fuser3, theEnergyCost);
}
else
return false;
pmove->fuser4 = (float)BALANCE_VAR(kLeapROF);
SetUpgradeMask(&pmove->iuser4, MASK_ALIEN_MOVEMENT, true);
PM_NSPlaySound(CHAN_WEAPON, kLeapSound, 1.0f, ATTN_NORM, 0, 94 + pmove->RandomLong(0, 0xf));
vec3_t forward, right, up;
AngleVectors(pmove->angles, forward, right, up);
//gCanJump[pmove->player_index] = true;
PM_Jump();
//gCanJump[pmove->player_index] = false;
vec3_t theAbilityVelocity;
VectorScale(forward, theScalar, theAbilityVelocity);
vec3_t theFinalVelocity;
VectorAdd(pmove->velocity, theAbilityVelocity, theFinalVelocity);
VectorCopy(theFinalVelocity, pmove->velocity);
return true;
}
bool PM_FlapMove()
{
if(PM_CanFlap())
{
AvHMUDeductAlienEnergy(pmove->fuser3, kAlienEnergyFlap);
// Added by mmcguire.
// Move the lerk in the direction has is facing.
vec3_t theFlapVelocity;
float theThrust;
float theLift;
if (pmove->cmd.forwardmove != 0)
{
if (pmove->cmd.forwardmove > 0)
{
theThrust = pmove->cmd.forwardmove * kWingThrustForwardScalar;
theLift = 200 * (pmove->forward[2] + 0.5) / 1.5;
if (theLift < 0)
{
theLift = 0;
}
}
else
{
// tankefugl: 0000522 reverse lerk flight
// Uncomment to enable backwards flight
//theThrust = pmove->cmd.forwardmove * kWingThrustForwardScalar; //kWingThrustBackwardScalar;
//theLift = 200 * (pmove->forward[2] + 0.5) / 1.5;
//if (theLift < 0)
//{
// theLift = 0;
//}
theThrust = -pmove->cmd.forwardmove * kWingThrustBackwardScalar;
theLift = 200;
// :tankefugl
}
}
else
{
theLift = 300;
theThrust = 0;
}
VectorScale(pmove->forward, theThrust, theFlapVelocity);
theFlapVelocity[2] += theLift;
vec3_t theNewVelocity;
VectorAdd(pmove->velocity, theFlapVelocity, theNewVelocity);
VectorCopy(theNewVelocity, pmove->velocity);
if(pmove->runfuncs)
{
// Pick a random sound to play
int theSoundIndex = pmove->RandomLong(0, 2);
char* theSoundToPlay = NULL;
switch(theSoundIndex)
{
case 0:
theSoundToPlay = kWingFlapSound1;
break;
case 1:
theSoundToPlay = kWingFlapSound2;
break;
case 2:
theSoundToPlay = kWingFlapSound3;
break;
}
// If alien has silencio upgrade, mute footstep volume
int theSilenceUpgradeLevel = AvHGetAlienUpgradeLevel(pmove->iuser4, MASK_UPGRADE_6);
const float theBaseVolume = .5f;
float theVolumeScalar = theBaseVolume - (theSilenceUpgradeLevel/(float)3)*theBaseVolume;
theVolumeScalar = min(max(theVolumeScalar, 0.0f), 1.0f);
PM_NSPlaySound(CHAN_BODY, theSoundToPlay, theVolumeScalar, ATTN_NORM, 0, PITCH_NORM);
}
pmove->oldbuttons |= IN_JUMP; // don't jump again until released
return true; // in air, so no; effect
}
else
{
// Added by mmcguire. Lerk gliding.
if (pmove->iuser3 == AVH_USER3_ALIEN_PLAYER3 && pmove->onground == -1)
{
// Compute the velocity not in the direction we're facing.
float theGlideAmount = min(0.2f, PM_GetHorizontalSpeed() / 1000);
float speed = Length(pmove->velocity);
float projectedSpeed = DotProduct(pmove->velocity, pmove->forward);
// tankefugl: 0000522 reverse lerk flight
//if (projectedSpeed < 0)
// speed *= -1;
// :tankefugl
vec3_t forwardVelocity;
VectorScale(pmove->forward, speed, forwardVelocity);
vec3_t glideVelocity;
VectorSubtract(pmove->velocity, forwardVelocity, glideVelocity);
VectorScale(glideVelocity, theGlideAmount, glideVelocity);
VectorSubtract(pmove->velocity, glideVelocity, pmove->velocity);
}
}
return true;
}
// Onos charge
bool PM_ChargeMove()
{
// TODO: Play event for charge!
float theEnergyCost = (float)BALANCE_VAR(kChargeEnergyCost) * (float)pmove->frametime;
float theChargeThresholdTime = (float)BALANCE_VAR(kChargeThresholdTime);
float theChargeSpeed = (float)BALANCE_VAR(kChargeSpeed);
if (AvHMUHasEnoughAlienEnergy(pmove->fuser3, theEnergyCost) && (pmove->fuser4 >= 0.0f))
{
AvHMUDeductAlienEnergy(pmove->fuser3, theEnergyCost);
if (pmove->fuser4 == 0.0f)
{
int theSilenceUpgradeLevel = AvHGetAlienUpgradeLevel(pmove->iuser4, MASK_UPGRADE_6);
float theVolumeScalar = 1.0f - theSilenceUpgradeLevel/3.0f;
PM_NSPlaySound( CHAN_WEAPON, "player/pl_fallpain3-7.wav", theVolumeScalar, ATTN_NORM, 0, PITCH_NORM );
pmove->fuser4 = 0.3f;
}
pmove->fuser4 += (float)pmove->frametime;
pmove->fuser4 = max(0, min(pmove->fuser4, theChargeThresholdTime));
}
else
return false;
SetUpgradeMask(&pmove->iuser4, MASK_ALIEN_MOVEMENT, true);
if (pmove->onground != -1)
{
vec3_t forward;
vec3_t sideways;
float length = pmove->maxspeed * (1.0f + (float)BALANCE_VAR(kChargeSpeed) * pmove->fuser4 / theChargeThresholdTime);
VectorCopy(pmove->forward, forward);
VectorScale(forward, -1 * DotProduct(forward, pmove->velocity), forward);
VectorAdd(pmove->velocity, forward, sideways);
//VectorScale(sideways, 1.5f, sideways);
VectorCopy(pmove->forward, forward);
forward[2] = 0.0f;
VectorNormalize(forward);
VectorScale(forward, length, forward);
VectorAdd(forward, sideways, pmove->velocity);
//VectorCopy(forward, pmove->velocity);
// pmove->velocity[2] = 0.0f;
float velocity = Length(pmove->velocity);
float maxvel = (pmove->maxspeed * (1.0f + theChargeSpeed));
if (velocity > maxvel)
VectorScale(pmove->velocity, maxvel / velocity, pmove->velocity);
}
return true;
}
void PM_AlienAbilities()
{
// Give some energy back if we're an alien and not evolving
string theExt;
float theTimePassed = (float)pmove->frametime;
if(NS_GetIsPlayerAlien(theExt))
{
float theTimePassed = pmove->cmd.msec*0.001f;
AvHMUUpdateAlienEnergy(theTimePassed, pmove->iuser3, pmove->iuser4, pmove->fuser3);
// Stop charging when we're out of energy
@ -4358,6 +4689,55 @@ void PM_AlienAbilities()
}
}
// Movement abilities
bool canmove = true;
#ifdef AVH_SERVER
//canmove = gCanMove[pmove->player_index];
#else
//canmove = gCanMove;
#endif
bool success = false;
if ((pmove->cmd.buttons & IN_ATTACK2) && (AvHGetIsAlien(pmove->iuser3)))
{
switch (pmove->iuser3)
{
case AVH_USER3_ALIEN_PLAYER1:
success = canmove && PM_LeapMove();
break;
case AVH_USER3_ALIEN_PLAYER3:
pmove->cmd.buttons |= IN_JUMP;
success = PM_FlapMove();
break;
case AVH_USER3_ALIEN_PLAYER4:
success = canmove && PM_BlinkMove();
break;
case AVH_USER3_ALIEN_PLAYER5:
success = canmove && PM_ChargeMove();
break;
default:
{
break;
}
}
}
else if (PM_GetIsBlinking())
success = PM_BlinkMove();
else if (PM_GetIsLeaping())
success = PM_LeapMove();
if (!success)
{
SetUpgradeMask(&pmove->iuser4, MASK_ALIEN_MOVEMENT, false);
if (pmove->fuser4 >= 0.0f)
pmove->fuser4 *= -1.0f;
pmove->fuser4 += theTimePassed;
pmove->fuser4 = min(pmove->fuser4, 0.0f);
}
return;
//#endif
if (PM_GetIsLeaping() || PM_GetIsBlinking())
@ -4413,79 +4793,6 @@ void PM_AlienAbilities()
//pmove->velocity[2] += 300;
//}
}
// else if((pmove->cmd.impulse == ALIEN_ABILITY_BLINK) && (pmove->iuser3 == AVH_USER3_ALIEN_PLAYER4))
// {
//
// vec3_t theBlinkStart;
// VectorCopy(pmove->origin, theBlinkStart);
// theBlinkStart[2] += pmove->view_ofs[2];
//
// vec3_t theBlinkDirection;
// VectorCopy(pmove->forward, theBlinkDirection);
//
// vec3_t theBlinkEnd;
// VectorMA(pmove->origin, kMaxMapDimension, theBlinkDirection, theBlinkEnd);
//
// // Do traceline through glass, until we hit something (this uses the current player hull, so it's like it's actually flying forward)
// int theTraceFlags = PM_TRACELINE_ANYVISIBLE;
// int theHull = -1;//pmove->usehull;
// int theIgnoreEntity = -1;
// pmtrace_t* theTrace = pmove->PM_TraceLine(theBlinkStart, theBlinkEnd, theTraceFlags, theHull, theIgnoreEntity);
// ASSERT(theTrace);
//
// // While position isn't free, bring distance back a little
// vec3_t theFreeEndPoint;
// VectorCopy(theTrace->endpos, theFreeEndPoint);
//
// // Subtract view height again
// theFreeEndPoint[2] -= pmove->view_ofs[2];
//
// int theNumIterations = 0;
// bool theSuccess = false;
// while(!theSuccess && (theNumIterations < 5))
// {
// if(NS_PositionFreeForPlayer(theFreeEndPoint))
// {
// // If position is still in front of us
// vec3_t theFreeEndPointDirection;
// VectorSubtract(theFreeEndPoint, theBlinkStart, theFreeEndPointDirection);
// if(DotProduct(theBlinkDirection, theFreeEndPointDirection) > 0)
// {
// // Save position so client can use it to draw
// theSuccess = true;
// }
// }
// else
// {
// vec3_t theBackwardsIncrement;
// VectorMA(vec3_origin, -50, theBlinkDirection, theBackwardsIncrement);
//
// VectorAdd(theFreeEndPoint, theBackwardsIncrement, theFreeEndPoint);
// }
//
// theNumIterations++;
// }
//
// // If position is okay, exit
// if(theSuccess)
// {
// // If so, set our new location to it
// VectorCopy(theFreeEndPoint, pmove->origin);
//
// if(pmove->runfuncs)
// {
// pmove->PM_PlaybackEventFull(0, pmove->player_index, gBlinkEffectSuccessEventID, 0, (float *)theBlinkStart, (float *)theFreeEndPoint, 0.0, 0.0, 0, 0, 0, 0 );
// }
// }
// //else
// //{
// // // Play a "blink failed" event
// // pmove->PM_PlaybackEventFull(0, pmove->player_index, gBlinkEffectFailEventID, 0, (float *)pmove->origin, (float *)pmove->origin, 0.0, 0.0, 0, 0, 0, 0 );
// //}
//
// }
}
void PM_LadderMove( physent_t *pLadder )
@ -5047,172 +5354,8 @@ void PM_Jump (void)
// For wall jumping, remove bit above and replace with this (from coding forums)
if(PM_CanFlap())
{
// //pmove->punchangle[0] = -2;
// //float theXComp = (fabs(pmove->velocity[0]) > fabs(pmove->forward[0]) ? pmove->velocity[0] : pmove->forward[0]);
// //float theYComp = (fabs(pmove->velocity[1]) > fabs(pmove->forward[1]) ? pmove->velocity[1] : pmove->forward[1]);
// float theXComp = pmove->forward[0]*(pmove->cmd.forwardmove/pmove->clientmaxspeed) + pmove->right[0]*(pmove->cmd.sidemove/pmove->clientmaxspeed);
// float theYComp = pmove->forward[1]*(pmove->cmd.forwardmove/pmove->clientmaxspeed) + pmove->right[1]*(pmove->cmd.sidemove/pmove->clientmaxspeed);
//
// pmove->velocity[0] += theXComp * 8;
// pmove->velocity[1] += theYComp * 8;
// pmove->velocity[2] += 35;
AvHMUDeductAlienEnergy(pmove->fuser3, kAlienEnergyFlap);
// Added by mmcguire.
// Move the lerk in the direction has is facing.
vec3_t theFlapVelocity;
float theThrust;
float theLift;
if (pmove->cmd.forwardmove != 0)
{
if (pmove->cmd.forwardmove > 0)
{
theThrust = pmove->cmd.forwardmove * kWingThrustForwardScalar;
theLift = 200 * (pmove->forward[2] + 0.5) / 1.5;
if (theLift < 0)
{
theLift = 0;
}
}
else
{
// tankefugl: 0000522 reverse lerk flight
// Uncomment to enable backwards flight
//theThrust = pmove->cmd.forwardmove * kWingThrustForwardScalar; //kWingThrustBackwardScalar;
//theLift = 200 * (pmove->forward[2] + 0.5) / 1.5;
//if (theLift < 0)
//{
// theLift = 0;
//}
theThrust = -pmove->cmd.forwardmove * kWingThrustBackwardScalar;
theLift = 200;
// :tankefugl
}
}
else
{
theLift = 300;
theThrust = 0;
}
VectorScale(pmove->forward, theThrust, theFlapVelocity);
theFlapVelocity[2] += theLift;
vec3_t theNewVelocity;
VectorAdd(pmove->velocity, theFlapVelocity, theNewVelocity);
VectorCopy(theNewVelocity, pmove->velocity);
/*
// Old Lerk flight model.
vec3_t theWishVelocity;
PM_GetWishVelocity(theWishVelocity);
float theWishXPercent = theWishVelocity[0]/pmove->clientmaxspeed;
float theWishYPercent = theWishVelocity[1]/pmove->clientmaxspeed;
float theWishZPercent = max(0.0f, 1.0f - fabs(theWishXPercent) - fabs(theWishYPercent));
pmove->velocity[0] += theWishXPercent*kWingFlapLateralScalar;
pmove->velocity[1] += theWishYPercent*kWingFlapLateralScalar;
pmove->velocity[2] += theWishZPercent*pmove->clientmaxspeed;
*/
if(pmove->runfuncs)
{
// #ifdef AVH_CLIENT
// int theLong = pmove->RandomLong(0, 20);
// pmove->Con_Printf("Flap %d\n", theLong);
// #endif
// Pick a random sound to play
int theSoundIndex = pmove->RandomLong(0, 2);
char* theSoundToPlay = NULL;
switch(theSoundIndex)
{
case 0:
theSoundToPlay = kWingFlapSound1;
break;
case 1:
theSoundToPlay = kWingFlapSound2;
break;
case 2:
theSoundToPlay = kWingFlapSound3;
break;
}
// If alien has silencio upgrade, mute footstep volume
int theSilenceUpgradeLevel = AvHGetAlienUpgradeLevel(pmove->iuser4, MASK_UPGRADE_6);
const float theBaseVolume = .5f;
float theVolumeScalar = theBaseVolume - (theSilenceUpgradeLevel/(float)3)*theBaseVolume;
theVolumeScalar = min(max(theVolumeScalar, 0.0f), 1.0f);
PM_NSPlaySound(CHAN_BODY, theSoundToPlay, theVolumeScalar, ATTN_NORM, 0, PITCH_NORM);
//PM_NSPlaySound(channel, , 1.0f, ATTN_NORM, flags, pitch);
//gEngfuncs.pEventAPI->EV_PlaySound(inArgs->entindex, thePlayer->origin, CHAN_AUTO, kEndCloakSound, 1, ATTN_NORM, 0, 94 + gEngfuncs.pfnRandomLong( 0, 0xf ));
//PM_PlaybackEvent(gFlightEventID);
}
// else if(PM_CanWalljump())
// {
// pmove->punchangle[0] = -2;
// pmove->velocity[2] += (pmove->forward[2] * 300);
//
// //pmove->velocity[2] = sqrt(2 * 800 * 45.0);
//
// PM_PlaybackEvent(gWallJumpEventID);
// }
pmove->oldbuttons |= IN_JUMP; // don't jump again until released
return; // in air, so no; effect
}
else
{
// Added by mmcguire.
// Lerk gliding.
if (pmove->iuser3 == AVH_USER3_ALIEN_PLAYER3 && pmove->onground == -1)
{
// Compute the velocity not in the direction we're facing.
float theGlideAmount = min(0.2f, PM_GetHorizontalSpeed() / 1000);
float speed = Length(pmove->velocity);
float projectedSpeed = DotProduct(pmove->velocity, pmove->forward);
// tankefugl: 0000522 reverse lerk flight
//if (projectedSpeed < 0)
// speed *= -1;
// :tankefugl
vec3_t forwardVelocity;
VectorScale(pmove->forward, speed, forwardVelocity);
vec3_t glideVelocity;
VectorSubtract(pmove->velocity, forwardVelocity, glideVelocity);
VectorScale(glideVelocity, theGlideAmount, glideVelocity);
VectorSubtract(pmove->velocity, glideVelocity, pmove->velocity);
return;
}
}
// Lerk flight movement
PM_FlapMove();
// tankefugl: 0000972 walljump
if (canWallJump && (GetHasUpgrade(pmove->iuser4, MASK_WALLSTICKING) && (pmove->cmd.buttons & IN_JUMP) && !(pmove->oldbuttons & IN_JUMP) /*&& (gSurfaceNormal[2] < 0.7)*/))

Binary file not shown.