diff --git a/mp/src/game/client/in_camera.cpp b/mp/src/game/client/in_camera.cpp index ec40ac180..263e9c5c9 100644 --- a/mp/src/game/client/in_camera.cpp +++ b/mp/src/game/client/in_camera.cpp @@ -26,10 +26,10 @@ static ConVar cam_command( "cam_command", "0", FCVAR_CHEAT | FCVAR_CHEAT); // t static ConVar cam_snapto( "cam_snapto", "0", FCVAR_ARCHIVE | FCVAR_CHEAT); // snap to thirdperson view static ConVar cam_ideallag( "cam_ideallag", "4.0", FCVAR_ARCHIVE| FCVAR_CHEAT, "Amount of lag used when matching offset to ideal angles in thirdperson view" ); static ConVar cam_idealdelta( "cam_idealdelta", "4.0", FCVAR_ARCHIVE| FCVAR_CHEAT, "Controls the speed when matching offset to ideal angles in thirdperson view" ); -ConVar cam_idealyaw( "cam_idealyaw", "0", FCVAR_ARCHIVE| FCVAR_CHEAT ); // thirdperson yaw +ConVar cam_idealyaw( "cam_idealyaw", "1", FCVAR_ARCHIVE| FCVAR_CHEAT ); // thirdperson yaw ConVar cam_idealpitch( "cam_idealpitch", "0", FCVAR_ARCHIVE | FCVAR_CHEAT ); // thirperson pitch -ConVar cam_idealdist( "cam_idealdist", "150", FCVAR_ARCHIVE | FCVAR_CHEAT ); // thirdperson distance -ConVar cam_idealdistright( "cam_idealdistright", "0", FCVAR_ARCHIVE | FCVAR_CHEAT ); // thirdperson distance +ConVar cam_idealdist( "cam_idealdist", "40", FCVAR_ARCHIVE | FCVAR_CHEAT ); // thirdperson distance +ConVar cam_idealdistright( "cam_idealdistright", "15", FCVAR_ARCHIVE | FCVAR_CHEAT ); // thirdperson distance ConVar cam_idealdistup( "cam_idealdistup", "0", FCVAR_ARCHIVE | FCVAR_CHEAT ); // thirdperson distance static ConVar cam_collision( "cam_collision", "1", FCVAR_ARCHIVE | FCVAR_CHEAT, "When in thirdperson and cam_collision is set to 1, an attempt is made to keep the camera from passing though walls." ); static ConVar cam_showangles( "cam_showangles", "0", FCVAR_CHEAT, "When in thirdperson, print viewangles/idealangles/cameraoffsets to the console." ); diff --git a/mp/src/game/client/neo/c_neo_player.cpp b/mp/src/game/client/neo/c_neo_player.cpp index 57c6b616c..9815d4ed9 100644 --- a/mp/src/game/client/neo/c_neo_player.cpp +++ b/mp/src/game/client/neo/c_neo_player.cpp @@ -908,7 +908,10 @@ void C_NEO_Player::PostThink(void) Vector eyeForward; this->EyeVectors(&eyeForward, NULL, NULL); Assert(eyeForward.IsValid()); - m_pPlayerAnimState->Update(eyeForward[YAW], eyeForward[PITCH]); + + float flPitch = asin(-eyeForward[2]); + float flYaw = atan2(eyeForward[1], eyeForward[0]); + m_pPlayerAnimState->Update(RAD2DEG(flYaw), RAD2DEG(flPitch)); } bool C_NEO_Player::IsAllowedToSuperJump(void) diff --git a/mp/src/game/server/neo/neo_player.cpp b/mp/src/game/server/neo/neo_player.cpp index 6f6644f5a..3adf595c3 100644 --- a/mp/src/game/server/neo/neo_player.cpp +++ b/mp/src/game/server/neo/neo_player.cpp @@ -1014,7 +1014,10 @@ void CNEO_Player::PostThink(void) Vector eyeForward; this->EyeVectors(&eyeForward, NULL, NULL); Assert(eyeForward.IsValid()); - m_pPlayerAnimState->Update(eyeForward[YAW], eyeForward[PITCH]); + + float flPitch = asin(-eyeForward[2]); + float flYaw = atan2(eyeForward[1], eyeForward[0]); + m_pPlayerAnimState->Update(RAD2DEG(flYaw), RAD2DEG(flPitch)); } void CNEO_Player::PlayerDeathThink() @@ -1450,6 +1453,7 @@ bool CNEO_Player::Weapon_Switch( CBaseCombatWeapon *pWeapon, int viewmodelindex ) { ShowCrosshair(false); + Weapon_SetZoom(false); return BaseClass::Weapon_Switch(pWeapon, viewmodelindex); } diff --git a/mp/src/game/shared/hl2mp/hl2mp_player_shared.cpp b/mp/src/game/shared/hl2mp/hl2mp_player_shared.cpp index d07bc28b7..6afe4bd04 100644 --- a/mp/src/game/shared/hl2mp/hl2mp_player_shared.cpp +++ b/mp/src/game/shared/hl2mp/hl2mp_player_shared.cpp @@ -428,41 +428,30 @@ void CPlayerAnimState::ComputePoseParam_BodyXY(void) ((speed / ((GetOuter()->GetFlags() & FL_DUCKING) ? NEO_RECON_CROUCH_SPEED : NEO_RECON_NORM_SPEED))), 0, 1); - int forwardSign = 0; - if (GetOuter()->m_nButtons & IN_FORWARD) - { - if (!(GetOuter()->m_nButtons & IN_BACK)) - { - forwardSign = 1; - } - } - else if (GetOuter()->m_nButtons & IN_BACK) - { - forwardSign = -1; - } + Vector eyeForward; + GetOuter()->EyeVectors(&eyeForward, NULL, NULL); + Assert(eyeForward.IsValid()); + Vector velocity = GetOuter()->GetLocalVelocity(); - int sideSign = 0; - if (GetOuter()->m_nButtons & IN_MOVERIGHT) - { - if (!(GetOuter()->m_nButtons & IN_MOVELEFT)) - { - sideSign = 1; - } - } - else if (GetOuter()->m_nButtons & IN_MOVELEFT) - { - sideSign = -1; - } + Vector2D eyeForward2D = eyeForward.AsVector2D(); + Vector2D velocity2D = velocity.AsVector2D(); - float speed_x = speedScale * forwardSign; - float speed_y = speedScale * sideSign; + eyeForward2D.NormalizeInPlace(); + velocity2D.NormalizeInPlace(); + + float forwardDot = eyeForward2D[0] * velocity2D[0] + eyeForward2D[1] * velocity2D[1]; + Vector2D eyeRight2D = Vector2D(eyeForward2D[1], eyeForward2D[0] * -1); // eyeForward2D rotated by 90 degrees + float sideDot = eyeRight2D[0] * velocity2D[0] + eyeRight2D[1] * velocity2D[1]; + + float speed_x = speedScale * forwardDot; + float speed_y = speedScale * sideDot; GetOuter()->SetPoseParameter(poseparam_move_x, speed_x); GetOuter()->SetPoseParameter("move_y", speed_y); bool bIsMoving; const float flPlaybackRate = CalcMovementPlaybackRate(speed, GetOuter()->GetSequenceGroundSpeed(GetOuter()->GetSequence()), &bIsMoving) * sv_neo_animrate_scale.GetFloat(); - + if (bIsMoving) { GetOuter()->SetPlaybackRate(flPlaybackRate); diff --git a/mp/src/game/shared/neo/neo_playeranimstate.cpp b/mp/src/game/shared/neo/neo_playeranimstate.cpp index dc7ecd454..4f817de5a 100644 --- a/mp/src/game/shared/neo/neo_playeranimstate.cpp +++ b/mp/src/game/shared/neo/neo_playeranimstate.cpp @@ -1,5 +1,8 @@ #include "cbase.h" #include "base_playeranimstate.h" +#include "weapon_grenade.h" +#include "weapon_smokegrenade.h" +#include "weapon_detpack.h" #include "tier0/vprof.h" #include "animation.h" @@ -48,6 +51,12 @@ class CNEOPlayerAnimState : public CBasePlayerAnimState, public INEOPlayerAnimSt virtual bool IsThrowingGrenade(); virtual int CalcAimLayerSequence(float *flCycle, float *flAimSequenceWeight, bool bForceIdle); virtual void ClearAnimationState(); + virtual void ClearAnimationFlags(); + virtual void UpdateAnimationFlags(); + virtual void UpdateGrenadeAnimationFlags(CWeaponGrenade* grenadeWeapon); + virtual void UpdateSmokeGrenadeAnimationFlags(CWeaponSmokeGrenade* grenadeWeapon); + virtual void UpdateDetpackAnimationFlags(CWeaponDetpack* detpackWeapon); + virtual void UpdateBaseWeaponAnimationFlags(CBaseCombatWeapon* currentWeapon); virtual bool CanThePlayerMove(); virtual float GetCurrentMaxGroundSpeed(); virtual Activity CalcMainActivity(); @@ -84,6 +93,8 @@ class CNEOPlayerAnimState : public CBasePlayerAnimState, public INEOPlayerAnimSt int CalcGrenadeThrowSequence(); int GetOuterGrenadeThrowCounter(); + void ComputeDetpackSequence(CStudioHdr* pStudioHdr); + const char* GetWeaponSuffix(); bool IsAirborne(); @@ -115,6 +126,12 @@ class CNEOPlayerAnimState : public CBasePlayerAnimState, public INEOPlayerAnimSt int m_iGrenadeSequence; int m_iLastThrowGrenadeCounter; // used to detect when the guy threw the grenade. + // Detpack Animations + bool m_bThrowingDetpack; + bool m_bTriggeringDetpack; + float m_flDetpackCycle; + int m_iDetpackSequence; + INEOPlayerAnimStateHelpers *m_pHelpers; CSequenceTransitioner m_ReloadSequenceTransitioner; @@ -167,22 +184,31 @@ INEOPlayerAnimStateHelpers* CreateAnimStateHelpers(CNEO_Player* pPlayer) // ------------------------------------------------------------------------- // CNEOPlayerAnimState::CNEOPlayerAnimState() { + // Base weapon reloading m_bReloading = false; m_flReloadCycle = 0; m_iReloadSequence = 0; m_bFreshJump = false; + // Base weapon firing m_bFiring = false; m_iFireSequence = 0; m_flFireCycle = 0; - m_bThrowingGrenade = false; + // Grenade prime and firing m_bPrimingGrenade = false; + m_bThrowingGrenade = false; m_flGrenadeCycle = 0; m_iGrenadeSequence = 0; m_iLastThrowGrenadeCounter = 0; + // Detpack throwing and triggering + m_bThrowingDetpack = false; + m_bTriggeringDetpack = false; + m_flDetpackCycle = 0; + m_iDetpackSequence = 0; + m_pHelpers = NULL; } @@ -205,14 +231,155 @@ void CNEOPlayerAnimState::InitNEO(CBaseAnimatingOverlay *pPlayer, } void CNEOPlayerAnimState::ClearAnimationState() +{ + ClearAnimationFlags(); + BaseClass::ClearAnimationState(); +} + +void CNEOPlayerAnimState::ClearAnimationFlags() { m_bFiring = false; m_bReloading = false; - m_bThrowingGrenade = m_bPrimingGrenade = false; + m_bPrimingGrenade = m_bThrowingGrenade = false; + m_bThrowingDetpack = m_bTriggeringDetpack = false; m_iLastThrowGrenadeCounter = GetOuterGrenadeThrowCounter(); +} - BaseClass::ClearAnimationState(); + +void CNEOPlayerAnimState::UpdateAnimationFlags() +{ + CWeaponGrenade* grenadeWeapon = dynamic_cast(m_pOuter->MyCombatCharacterPointer()->GetActiveWeapon()); + if (grenadeWeapon != nullptr) + { // Current weapon is a grenade + UpdateGrenadeAnimationFlags(grenadeWeapon); + return; + } + + CWeaponSmokeGrenade* smokeGrenadeWeapon = dynamic_cast(m_pOuter->MyCombatCharacterPointer()->GetActiveWeapon()); + if (smokeGrenadeWeapon != nullptr) + { // Current weapon is a smoke grenade + UpdateSmokeGrenadeAnimationFlags(smokeGrenadeWeapon); + return; + } + + CWeaponDetpack* detpackWeapon = dynamic_cast(m_pOuter->MyCombatCharacterPointer()->GetActiveWeapon()); + if (detpackWeapon != nullptr) + { // Current weapon is a detpack + UpdateDetpackAnimationFlags(detpackWeapon); + return; + } + + CBaseCombatWeapon* currentWeapon = dynamic_cast(m_pOuter->MyCombatCharacterPointer()->GetActiveWeapon()); + if (currentWeapon != nullptr) + { // Current weapon is a firearm/melee weapon + UpdateBaseWeaponAnimationFlags(currentWeapon); + return; + } + // Character hands are empty? + ClearAnimationFlags(); + return; +} + +void CNEOPlayerAnimState::UpdateGrenadeAnimationFlags(CWeaponGrenade* grenadeWeapon) +{ + m_bFiring = false; + m_bReloading = false; + m_bThrowingGrenade = false; + + if (!m_bThrowingGrenade && m_flGrenadeCycle < 1) + { // Grenade was recently thrown, continue playing throw animation + return; + } + + if (m_bPrimingGrenade && !grenadeWeapon->IsPrimed()) + { // Play throw sequence if grenade was primed but now isn't, grenade was thrown (unless user switched to a different grenade after priming a grenade, need to keep track of grenade names? NEO FIXME) + m_bPrimingGrenade = false; + m_bThrowingGrenade = true; + m_iGrenadeSequence = CalcGrenadePrimeSequence(); // This should be ThrowSequence but ThrowSequence returns 0 NEO FIXME + m_flGrenadeCycle = 0; + return; + } + + if (m_bPrimingGrenade && grenadeWeapon->IsPrimed()) + {// Still priming grenade + return; + } + + m_bPrimingGrenade = grenadeWeapon->IsPrimed(); + if (m_bPrimingGrenade) + { // Begin prime sequence + //m_iGrenadeSequence = CalcGrenadePrimeSequence(); // Can add a grenade priming animation here, there is no such animation in the orignal game NEO TODO + m_flGrenadeCycle = 0; + return; + } +} + +void CNEOPlayerAnimState::UpdateSmokeGrenadeAnimationFlags(CWeaponSmokeGrenade* grenadeWeapon) +{ + m_bFiring = false; + m_bReloading = false; + m_bThrowingGrenade = false; + + if (!m_bThrowingGrenade && m_flGrenadeCycle < 1) + { // Grenade was recently thrown, continue playing throw animation + return; + } + + if (m_bPrimingGrenade && !grenadeWeapon->IsPrimed()) + { // Play throw sequence if grenade was primed but now isn't, grenade was thrown (unless user switched to a different grenade after priming a grenade, need to keep track of grenade names? NEO FIXME) + m_bPrimingGrenade = false; + m_bThrowingGrenade = true; + m_iGrenadeSequence = CalcGrenadePrimeSequence(); // This should be ThrowSequence but ThrowSequence returns 0 NEO FIXME + m_flGrenadeCycle = 0; + return; + } + + if (m_bPrimingGrenade && grenadeWeapon->IsPrimed()) + {// Still priming grenade + return; + } + + m_bPrimingGrenade = grenadeWeapon->IsPrimed(); + if (m_bPrimingGrenade) + { // Begin prime sequence + //m_iGrenadeSequence = CalcGrenadePrimeSequence(); // Can add a grenade priming animation here, there is no such animation in the orignal game NEO TODO + m_flGrenadeCycle = 0; + return; + } +} + +void CNEOPlayerAnimState::UpdateDetpackAnimationFlags(CWeaponDetpack* detpackWeapon) +{ + if (detpackWeapon->m_bRemoteHasBeenTriggered) + { // detpack triggering + if (!m_bTriggeringDetpack) + { + m_flDetpackCycle = 0; + m_iDetpackSequence = CalcSequenceIndex("Idle_Shoot_detremote"); + m_bTriggeringDetpack = true; + } + m_bThrowingDetpack = false; + return; + } + + if (detpackWeapon->m_bWantsToThrowThisDetpack && !detpackWeapon->m_fDrawbackFinished) + { // detpack throwing + if (!m_bThrowingDetpack) + { // first tick + m_flDetpackCycle = 0; + m_iDetpackSequence = CalcSequenceIndex("Idle_Shoot_detpack"); + m_bThrowingDetpack = true; + } + m_bTriggeringDetpack = false; + return; + } +} + +void CNEOPlayerAnimState::UpdateBaseWeaponAnimationFlags(CBaseCombatWeapon* currentWeapon) +{ + m_bFiring = !((gpGlobals->curtime - currentWeapon->m_flNextPrimaryAttack.Get()) > 0.5f); + m_bReloading = currentWeapon->m_bInReload.Get(); } void CNEOPlayerAnimState::DoAnimationEvent(PlayerAnimEvent_t event, int nData) @@ -295,10 +462,6 @@ int CNEOPlayerAnimState::CalcReloadLayerSequence() void CNEOPlayerAnimState::UpdateLayerSequenceGeneric(CStudioHdr *pStudioHdr, int iLayer, bool &bEnabled, float &flCurCycle, int &iSequence, bool bWaitAtEnd) { -#ifdef GAME_DLL - Assert(false); - return; -#else if (!bEnabled) { return; @@ -311,6 +474,7 @@ void CNEOPlayerAnimState::UpdateLayerSequenceGeneric(CStudioHdr *pStudioHdr, if (bWaitAtEnd) { flCurCycle = 1; + return; } else { @@ -330,7 +494,6 @@ void CNEOPlayerAnimState::UpdateLayerSequenceGeneric(CStudioHdr *pStudioHdr, pLayer->m_flPlaybackRate = 1.0; pLayer->m_flWeight = 1.0f; pLayer->m_nOrder = iLayer; -#endif } // We don't have a concept of cooking grenades, so checking for the actual moment of tossing it. @@ -350,58 +513,36 @@ bool CNEOPlayerAnimState::IsOuterGrenadePrimed() void CNEOPlayerAnimState::ComputeGrenadeSequence(CStudioHdr *pStudioHdr) { -#ifdef CLIENT_DLL if (m_bThrowingGrenade) { UpdateLayerSequenceGeneric(pStudioHdr, GRENADESEQUENCE_LAYER, m_bThrowingGrenade, m_flGrenadeCycle, m_iGrenadeSequence, false); } - else + if (m_bPrimingGrenade) { - // Priming the grenade isn't an event.. we just watch the player for it. - // Also play the prime animation first if he wants to throw the grenade. - bool bThrowPending = (m_iLastThrowGrenadeCounter != GetOuterGrenadeThrowCounter()); - if (IsOuterGrenadePrimed() || bThrowPending) - { - if (!m_bPrimingGrenade) - { - // If this guy just popped into our PVS, and he's got his grenade primed, then - // let's assume that it's all the way primed rather than playing the prime - // animation from the start. - if (TimeSinceLastAnimationStateClear() < 0.4f) - m_flGrenadeCycle = 1; - else - m_flGrenadeCycle = 0; - - m_iGrenadeSequence = CalcGrenadePrimeSequence(); - } - - m_bPrimingGrenade = true; - UpdateLayerSequenceGeneric(pStudioHdr, GRENADESEQUENCE_LAYER, m_bPrimingGrenade, - m_flGrenadeCycle, m_iGrenadeSequence, true); + UpdateLayerSequenceGeneric(pStudioHdr, GRENADESEQUENCE_LAYER, m_bPrimingGrenade, + m_flGrenadeCycle, m_iGrenadeSequence, true); + } + bool grenadeBeingThrown = m_flGrenadeCycle < 1; + if (!m_bThrowingGrenade && grenadeBeingThrown) + { + UpdateLayerSequenceGeneric(pStudioHdr, GRENADESEQUENCE_LAYER, grenadeBeingThrown, + m_flGrenadeCycle, m_iGrenadeSequence, false); + } +} - // If we're waiting to throw and we're done playing the prime animation... - if (bThrowPending && m_flGrenadeCycle == 1) - { - m_iLastThrowGrenadeCounter = GetOuterGrenadeThrowCounter(); - - // Now play the throw animation. - m_iGrenadeSequence = CalcGrenadeThrowSequence(); - if (m_iGrenadeSequence != -1) - { - // Configure to start playing - m_bThrowingGrenade = true; - m_bPrimingGrenade = false; - m_flGrenadeCycle = 0; - } - } - } - else - { - m_bPrimingGrenade = false; - } +void CNEOPlayerAnimState::ComputeDetpackSequence(CStudioHdr* pStudioHdr) +{ + if (m_bThrowingDetpack) + { + UpdateLayerSequenceGeneric(pStudioHdr, GRENADESEQUENCE_LAYER, m_bThrowingDetpack, + m_flDetpackCycle, m_iDetpackSequence, false); + } + if (m_bTriggeringDetpack) + { + UpdateLayerSequenceGeneric(pStudioHdr, GRENADESEQUENCE_LAYER, m_bTriggeringDetpack, + m_flDetpackCycle, m_iDetpackSequence, false); } -#endif } int CNEOPlayerAnimState::CalcGrenadePrimeSequence() @@ -430,12 +571,8 @@ int CNEOPlayerAnimState::GetOuterGrenadeThrowCounter() void CNEOPlayerAnimState::ComputeReloadSequence(CStudioHdr *pStudioHdr) { -#ifdef CLIENT_DLL UpdateLayerSequenceGeneric(pStudioHdr, RELOADSEQUENCE_LAYER, m_bReloading, m_flReloadCycle, m_iReloadSequence, false); -#else - // Server doesn't bother with different fire sequences. -#endif } int CNEOPlayerAnimState::CalcAimLayerSequence(float *flCycle, @@ -660,7 +797,6 @@ Activity CNEOPlayerAnimState::CalcMainActivity() void CNEOPlayerAnimState::DebugShowAnimState(int iStartLine) { -#ifdef CLIENT_DLL engine->Con_NPrintf(iStartLine++, "fire : %s, cycle: %.2f\n", m_bFiring ? GetSequenceName(m_pOuter->GetModelPtr(), m_iFireSequence) : "[not firing]", m_flFireCycle); @@ -670,16 +806,17 @@ void CNEOPlayerAnimState::DebugShowAnimState(int iStartLine) "[not reloading]", m_flReloadCycle); BaseClass::DebugShowAnimState(iStartLine); -#endif } void CNEOPlayerAnimState::ComputeSequences(CStudioHdr *pStudioHdr) { BaseClass::ComputeSequences(pStudioHdr); + UpdateAnimationFlags(); ComputeFireSequence(pStudioHdr); ComputeReloadSequence(pStudioHdr); ComputeGrenadeSequence(pStudioHdr); + ComputeDetpackSequence(pStudioHdr); } void CNEOPlayerAnimState::ClearAnimationLayers() @@ -700,12 +837,8 @@ void CNEOPlayerAnimState::ClearAnimationLayers() void CNEOPlayerAnimState::ComputeFireSequence(CStudioHdr *pStudioHdr) { -#ifdef CLIENT_DLL UpdateLayerSequenceGeneric(pStudioHdr, FIRESEQUENCE_LAYER, m_bFiring, m_flFireCycle, m_iFireSequence, false); -#else - // Server doesn't bother with different fire sequences. -#endif } bool CNEOPlayerAnimState::ShouldBlendAimSequenceToIdle() @@ -731,7 +864,7 @@ bool CNEOPlayerAnimState::ShouldBlendReloadSequenceToIdle() m_bReloading = m_pOuter->MyCombatCharacterPointer()->GetActiveWeapon()->m_bInReload; } - return (m_bReloading && (static_cast(m_pOuter)->GetFlags() & FL_DUCKING)); + return (m_bReloading && ((m_pOuter)->GetFlags() & FL_DUCKING)); } void CNEOPlayerAnimState::ComputeAimSequence() diff --git a/mp/src/game/shared/neo/weapons/weapon_detpack.h b/mp/src/game/shared/neo/weapons/weapon_detpack.h index f8faf18e0..3dd095c78 100644 --- a/mp/src/game/shared/neo/weapons/weapon_detpack.h +++ b/mp/src/game/shared/neo/weapons/weapon_detpack.h @@ -56,15 +56,15 @@ class CWeaponDetpack : public CNEOBaseCombatWeapon void TossDetpack(CBasePlayer* pPlayer); -private: - // Check a throw from vecSrc. If not valid, move the position back along the line to vecEye - void CheckTossPosition(CBasePlayer* pPlayer, const Vector& vecEye, Vector& vecSrc); - CNetworkVar(bool, m_fDrawbackFinished); CNetworkVar(bool, m_bWantsToThrowThisDetpack); CNetworkVar(bool, m_bThisDetpackHasBeenThrown); CNetworkVar(bool, m_bRemoteHasBeenTriggered); +private: + // Check a throw from vecSrc. If not valid, move the position back along the line to vecEye + void CheckTossPosition(CBasePlayer* pPlayer, const Vector& vecEye, Vector& vecSrc); + CWeaponDetpack(const CWeaponDetpack &other); #ifdef GAME_DLL