summaryrefslogtreecommitdiff
path: root/game/shared/tfc
diff options
context:
space:
mode:
authorFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
committerFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
commit3bf9df6b2785fa6d951086978a3e66f49427166a (patch)
tree2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /game/shared/tfc
downloadarchived-source-engine-2018-hl2-src-master.tar.xz
archived-source-engine-2018-hl2-src-master.zip
Diffstat (limited to 'game/shared/tfc')
-rw-r--r--game/shared/tfc/nailgun_nail.cpp152
-rw-r--r--game/shared/tfc/nailgun_nail.h45
-rw-r--r--game/shared/tfc/tfc_gamemovement.cpp105
-rw-r--r--game/shared/tfc/tfc_gamerules.cpp422
-rw-r--r--game/shared/tfc/tfc_gamerules.h104
-rw-r--r--game/shared/tfc/tfc_player_shared.cpp97
-rw-r--r--game/shared/tfc/tfc_player_shared.h138
-rw-r--r--game/shared/tfc/tfc_playeranimstate.cpp323
-rw-r--r--game/shared/tfc/tfc_playeranimstate.h55
-rw-r--r--game/shared/tfc/tfc_shareddefs.cpp436
-rw-r--r--game/shared/tfc/tfc_shareddefs.h321
-rw-r--r--game/shared/tfc/tfc_usermessages.cpp41
-rw-r--r--game/shared/tfc/tfc_weapon_parse.cpp28
-rw-r--r--game/shared/tfc/tfc_weapon_parse.h30
-rw-r--r--game/shared/tfc/weapon_tfc_crowbar.cpp330
-rw-r--r--game/shared/tfc/weapon_tfc_crowbar.h88
-rw-r--r--game/shared/tfc/weapon_tfc_knife.cpp58
-rw-r--r--game/shared/tfc/weapon_tfc_knife.h53
-rw-r--r--game/shared/tfc/weapon_tfc_medikit.cpp248
-rw-r--r--game/shared/tfc/weapon_tfc_medikit.h59
-rw-r--r--game/shared/tfc/weapon_tfc_minigun.cpp282
-rw-r--r--game/shared/tfc/weapon_tfc_minigun.h84
-rw-r--r--game/shared/tfc/weapon_tfc_nailgun.cpp114
-rw-r--r--game/shared/tfc/weapon_tfc_nailgun.h57
-rw-r--r--game/shared/tfc/weapon_tfc_shotgun.cpp232
-rw-r--r--game/shared/tfc/weapon_tfc_shotgun.h68
-rw-r--r--game/shared/tfc/weapon_tfc_spanner.cpp114
-rw-r--r--game/shared/tfc/weapon_tfc_spanner.h63
-rw-r--r--game/shared/tfc/weapon_tfc_super_nailgun.cpp109
-rw-r--r--game/shared/tfc/weapon_tfc_super_nailgun.h56
-rw-r--r--game/shared/tfc/weapon_tfc_super_shotgun.cpp119
-rw-r--r--game/shared/tfc/weapon_tfc_super_shotgun.h56
-rw-r--r--game/shared/tfc/weapon_tfcbase.cpp193
-rw-r--r--game/shared/tfc/weapon_tfcbase.h126
34 files changed, 4806 insertions, 0 deletions
diff --git a/game/shared/tfc/nailgun_nail.cpp b/game/shared/tfc/nailgun_nail.cpp
new file mode 100644
index 0000000..b711989
--- /dev/null
+++ b/game/shared/tfc/nailgun_nail.cpp
@@ -0,0 +1,152 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================//
+
+#include "cbase.h"
+#include "nailgun_nail.h"
+
+
+#define NAILGUN_MODEL "models/nail.mdl"
+
+
+LINK_ENTITY_TO_CLASS( tf_nailgun_nail, CTFNailgunNail );
+PRECACHE_REGISTER( tf_nailgun_nail );
+
+BEGIN_DATADESC( CTFNailgunNail )
+ DEFINE_FUNCTION( NailTouch )
+END_DATADESC()
+
+
+
+CTFNailgunNail *CTFNailgunNail::CreateNail(
+ bool fSendClientNail,
+ Vector vecOrigin,
+ QAngle vecAngles,
+ CBaseEntity *pOwner,
+ CBaseEntity *pLauncher,
+ bool fMakeClientNail )
+{
+ CTFNailgunNail *pNail = (CTFNailgunNail*)CreateEntityByName( "tf_nailgun_nail" );
+ if ( !pNail )
+ return NULL;
+
+ pNail->SetAbsOrigin( vecOrigin );
+ pNail->SetAbsAngles( vecAngles );
+ pNail->SetOwnerEntity( pOwner );
+ pNail->Spawn();
+ pNail->SetTouch( &CTFNailgunNail::NailTouch );
+ pNail->m_iDamage = 9;
+/*
+ if ( fMakeClientNail )
+ {
+ edict_t *pOwner;
+ int indexOwner;
+
+ // don't send to clients.
+ pNail->pev->effects |= EF_NODRAW;
+ pOwner = ENT( pNail->pev->owner );
+ indexOwner = ENTINDEX(pOwner);
+
+ if ( fSendClientNail )
+ UTIL_ClientProjectile( pNail->pev->origin, pNail->pev->velocity, g_sModelIndexNail, indexOwner, 6 );
+ }
+*/
+ return pNail;
+}
+
+
+
+CTFNailgunNail *CTFNailgunNail::CreateSuperNail( Vector vecOrigin, QAngle vecAngles, CBaseEntity *pOwner, CBaseEntity *pLauncher )
+{
+ // Super nails simply do more damage
+ CTFNailgunNail *pNail = CreateNail( false, vecOrigin, vecAngles, pOwner, pLauncher, true );
+ pNail->m_iDamage = 13;
+ return pNail;
+}
+
+
+//=========================================================
+// CTFNailgunNail::Spawn
+//
+// Creates an nail entity on the server that is invisible
+// so that it won't be sent to clients. At the same time sends a
+// tiny message that creates a flying nail entity on all
+// clients. (sjb)
+//=========================================================
+void CTFNailgunNail::Spawn()
+{
+ // motor
+ SetMoveType( MOVETYPE_FLYGRAVITY );
+ SetSolid( SOLID_BBOX );
+
+ SetModel( NAILGUN_MODEL );
+
+ SetSize( Vector( 0, 0, 0), Vector(0, 0, 0) );
+
+ Vector vForward;
+ AngleVectors( GetAbsAngles(), &vForward );
+ SetAbsVelocity( vForward * 1000 );
+ SetGravity( 0.5 );
+
+ SetNextThink( gpGlobals->curtime + 6 );
+ SetThink( &CTFNailgunNail::SUB_Remove );
+}
+
+
+void CTFNailgunNail::Precache()
+{
+ PrecacheModel( NAILGUN_MODEL );
+ BaseClass::Precache();
+}
+
+
+void CTFNailgunNail::NailTouch( CBaseEntity *pOther )
+{
+ // Damage person hit by the nail
+ CBaseEntity *pevOwner = GetOwnerEntity();
+ if ( !pevOwner || !pOther )
+ {
+ UTIL_Remove( this );
+ return;
+ }
+
+ // Nails don't touch each other.
+ if ( dynamic_cast< CTFNailgunNail* >( pOther ) == NULL )
+ {
+ Vector vVelNorm = GetAbsVelocity();
+ VectorNormalize( vVelNorm );
+
+ Vector vDamageForce = vVelNorm;
+ Vector vDamagePosition = GetAbsOrigin();
+
+ int iStartHealth = pOther->GetHealth();
+ CTakeDamageInfo info( this, pevOwner, vDamageForce, vDamagePosition, m_iDamage, DMG_SLASH );
+ pOther->TakeDamage( info );
+
+ // Did they take the damage?
+ if ( pOther->GetHealth() < iStartHealth )
+ {
+ SpawnBlood( GetAbsOrigin(), GetAbsVelocity(), pOther->BloodColor(), m_iDamage );
+ }
+
+ // Do an impact trace in case we hit the world.
+ trace_t tr;
+ UTIL_TraceLine(
+ GetAbsOrigin() - vVelNorm * 30,
+ GetAbsOrigin() + vVelNorm * 50,
+ MASK_SOLID_BRUSHONLY,
+ pevOwner,
+ COLLISION_GROUP_DEBRIS,
+ &tr );
+
+ if ( tr.fraction < 1 )
+ {
+ UTIL_ImpactTrace( &tr, DMG_SLASH );
+ }
+
+ UTIL_Remove( this );
+ }
+}
+
diff --git a/game/shared/tfc/nailgun_nail.h b/game/shared/tfc/nailgun_nail.h
new file mode 100644
index 0000000..29dde18
--- /dev/null
+++ b/game/shared/tfc/nailgun_nail.h
@@ -0,0 +1,45 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================//
+
+#ifndef NAILGUN_NAIL_H
+#define NAILGUN_NAIL_H
+#ifdef _WIN32
+#pragma once
+#endif
+
+
+class CTFNailgunNail : public CBaseAnimating
+{
+public:
+ DECLARE_CLASS( CTFNailgunNail, CBaseAnimating );
+ DECLARE_DATADESC();
+
+ void Spawn();
+ void Precache();
+
+ // Functions to create all the various types of nails.
+ static CTFNailgunNail *CreateNail( bool fSendClientNail, Vector vecOrigin, QAngle vecAngles, CBaseEntity *pOwner, CBaseEntity *pLauncher, bool fCreateClientNail );
+ static CTFNailgunNail *CreateSuperNail( Vector vecOrigin, QAngle vecAngles, CBaseEntity *pOwner, CBaseEntity *pLauncher );
+ static CTFNailgunNail *CreateTranqNail( Vector vecOrigin, QAngle vecAngles, CBaseEntity *pOwner, CBaseEntity *pLauncher );
+ static CTFNailgunNail *CreateRailgunNail( Vector vecOrigin, QAngle vecAngles, CBaseEntity *pOwner, CBaseEntity *pLauncher );
+ static CTFNailgunNail *CreateNailGrenNail( Vector vecOrigin, QAngle vecAngles, CBaseEntity *pOwner, CBaseEntity *pNailGren );
+
+
+private:
+
+ void RailgunNail_Think();
+ void NailTouch( CBaseEntity *pOther );
+ void TranqTouch( CBaseEntity *pOther );
+ void RailgunNailTouch( CBaseEntity *pOther );
+
+
+private:
+ Vector m_vecPreviousVelocity;
+ int m_iDamage; // How much damage this nail does when it hits an enemy.
+};
+
+
+#endif // NAILGUN_NAIL_H
diff --git a/game/shared/tfc/tfc_gamemovement.cpp b/game/shared/tfc/tfc_gamemovement.cpp
new file mode 100644
index 0000000..0a4cc48
--- /dev/null
+++ b/game/shared/tfc/tfc_gamemovement.cpp
@@ -0,0 +1,105 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//=============================================================================//
+
+//========= Copyright � 1996-2001, Valve LLC, All rights reserved. ============
+//
+// Purpose:
+//
+// $NoKeywords: $
+//=============================================================================
+#include "cbase.h"
+#include "gamemovement.h"
+#include "tfc_gamerules.h"
+#include "tfc_shareddefs.h"
+#include "in_buttons.h"
+#include "movevars_shared.h"
+
+
+#ifdef CLIENT_DLL
+ #include "c_tfc_player.h"
+#else
+ #include "tfc_player.h"
+#endif
+
+
+class CTFCGameMovement : public CGameMovement
+{
+public:
+ DECLARE_CLASS( CTFCGameMovement, CGameMovement );
+
+ CTFCGameMovement();
+
+ virtual void ProcessMovement( CBasePlayer *pBasePlayer, CMoveData *pMove );
+ virtual bool CanAccelerate();
+ virtual bool CheckJumpButton();
+
+
+private:
+
+ CTFCPlayer *m_pTFCPlayer;
+};
+
+
+// Expose our interface.
+static CTFCGameMovement g_GameMovement;
+IGameMovement *g_pGameMovement = ( IGameMovement * )&g_GameMovement;
+
+EXPOSE_SINGLE_INTERFACE_GLOBALVAR(CGameMovement, IGameMovement,INTERFACENAME_GAMEMOVEMENT, g_GameMovement );
+
+
+// ---------------------------------------------------------------------------------------- //
+// CTFCGameMovement.
+// ---------------------------------------------------------------------------------------- //
+
+CTFCGameMovement::CTFCGameMovement()
+{
+ m_vecViewOffsetNormal = TFC_PLAYER_VIEW_OFFSET;
+ m_pTFCPlayer = NULL;
+}
+
+
+void CTFCGameMovement::ProcessMovement( CBasePlayer *pBasePlayer, CMoveData *pMove )
+{
+ m_pTFCPlayer = ToTFCPlayer( pBasePlayer );
+ Assert( m_pTFCPlayer );
+
+ BaseClass::ProcessMovement( pBasePlayer, pMove );
+}
+
+
+bool CTFCGameMovement::CanAccelerate()
+{
+ // Only allow the player to accelerate when in certain states.
+ TFCPlayerState curState = m_pTFCPlayer->m_Shared.State_Get();
+ if ( curState == STATE_ACTIVE )
+ {
+ return player->GetWaterJumpTime() == 0;
+ }
+ else if ( player->IsObserver() )
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+
+bool CTFCGameMovement::CheckJumpButton()
+{
+ if ( BaseClass::CheckJumpButton() )
+ {
+ m_pTFCPlayer->DoAnimationEvent( PLAYERANIMEVENT_JUMP );
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
diff --git a/game/shared/tfc/tfc_gamerules.cpp b/game/shared/tfc/tfc_gamerules.cpp
new file mode 100644
index 0000000..20e208d
--- /dev/null
+++ b/game/shared/tfc/tfc_gamerules.cpp
@@ -0,0 +1,422 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: The TF Game rules
+//
+// $NoKeywords: $
+//=============================================================================//
+
+#include "cbase.h"
+#include "tfc_gamerules.h"
+#include "ammodef.h"
+#include "KeyValues.h"
+#include "weapon_tfcbase.h"
+
+
+#ifdef CLIENT_DLL
+
+ #include "c_tfc_player.h"
+
+#else
+
+ #include "voice_gamemgr.h"
+ #include "team.h"
+ #include "tfc_bot_temp.h"
+ #include "tfc_player.h"
+ #include "tfc_timer.h"
+ #include "tfc_team.h"
+
+#endif
+
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+
+#ifndef CLIENT_DLL
+LINK_ENTITY_TO_CLASS(info_player_terrorist, CPointEntity);
+LINK_ENTITY_TO_CLASS(info_player_counterterrorist,CPointEntity);
+#endif
+
+REGISTER_GAMERULES_CLASS( CTFCGameRules );
+
+
+BEGIN_NETWORK_TABLE_NOBASE( CTFCGameRules, DT_TFCGameRules )
+END_NETWORK_TABLE()
+
+
+LINK_ENTITY_TO_CLASS( tfc_gamerules, CTFCGameRulesProxy );
+IMPLEMENT_NETWORKCLASS_ALIASED( TFCGameRulesProxy, DT_TFCGameRulesProxy )
+
+
+#ifdef CLIENT_DLL
+ void RecvProxy_TFCGameRules( const RecvProp *pProp, void **pOut, void *pData, int objectID )
+ {
+ CTFCGameRules *pRules = TFCGameRules();
+ Assert( pRules );
+ *pOut = pRules;
+ }
+
+ BEGIN_RECV_TABLE( CTFCGameRulesProxy, DT_TFCGameRulesProxy )
+ RecvPropDataTable( "tfc_gamerules_data", 0, 0, &REFERENCE_RECV_TABLE( DT_TFCGameRules ), RecvProxy_TFCGameRules )
+ END_RECV_TABLE()
+#else
+ void *SendProxy_TFCGameRules( const SendProp *pProp, const void *pStructBase, const void *pData, CSendProxyRecipients *pRecipients, int objectID )
+ {
+ CTFCGameRules *pRules = TFCGameRules();
+ Assert( pRules );
+ pRecipients->SetAllRecipients();
+ return pRules;
+ }
+
+ BEGIN_SEND_TABLE( CTFCGameRulesProxy, DT_TFCGameRulesProxy )
+ SendPropDataTable( "tfc_gamerules_data", 0, &REFERENCE_SEND_TABLE( DT_TFCGameRules ), SendProxy_TFCGameRules )
+ END_SEND_TABLE()
+#endif
+
+
+ConVar mp_fadetoblack(
+ "mp_fadetoblack",
+ "0",
+ FCVAR_REPLICATED,
+ "fade a player's screen to black when he dies" );
+
+
+// (We clamp ammo ourselves elsewhere).
+ConVar ammo_max( "ammo_max", "5000", FCVAR_REPLICATED );
+
+
+CTFCGameRules::CTFCGameRules()
+{
+ CTF_Map = true;
+
+#ifdef GAME_DLL
+ // Create the team managers
+ for ( int i = 0; i < ARRAYSIZE( teamnames ); i++ )
+ {
+ CTeam *pTeam = static_cast<CTeam*>(CreateEntityByName( "tfc_team_manager" ));
+ pTeam->Init( teamnames[i], i );
+
+ g_Teams.AddToTail( pTeam );
+ }
+#endif
+}
+
+
+#ifdef CLIENT_DLL
+
+
+#else
+
+
+ int cease_fire;
+ int no_cease_fire_text;
+
+
+ // --------------------------------------------------------------------------------------------------- //
+ // Voice helper
+ // --------------------------------------------------------------------------------------------------- //
+
+ class CVoiceGameMgrHelper : public IVoiceGameMgrHelper
+ {
+ public:
+ virtual bool CanPlayerHearPlayer( CBasePlayer *pListener, CBasePlayer *pTalker )
+ {
+ // Dead players can only be heard by other dead team mates
+ if ( pTalker->IsAlive() == false )
+ {
+ if ( pListener->IsAlive() == false )
+ return ( pListener->InSameTeam( pTalker ) );
+
+ return false;
+ }
+
+ return ( pListener->InSameTeam( pTalker ) );
+ }
+ };
+ CVoiceGameMgrHelper g_VoiceGameMgrHelper;
+ IVoiceGameMgrHelper *g_pVoiceGameMgrHelper = &g_VoiceGameMgrHelper;
+
+
+
+ // --------------------------------------------------------------------------------------------------- //
+ // Globals.
+ // --------------------------------------------------------------------------------------------------- //
+
+ // NOTE: the indices here must match TEAM_TERRORIST, TEAM_CT, TEAM_SPECTATOR, etc.
+ char *sTeamNames[] =
+ {
+ "Unassigned",
+ "Spectator",
+ "Terrorist",
+ "Counter-Terrorist"
+ };
+
+
+ // --------------------------------------------------------------------------------------------------- //
+ // Global helper functions.
+ // --------------------------------------------------------------------------------------------------- //
+
+ // World.cpp calls this but we don't use it in TFC.
+ void InitBodyQue()
+ {
+ }
+
+ //-----------------------------------------------------------------------------
+ // Purpose:
+ //-----------------------------------------------------------------------------
+ CTFCGameRules::~CTFCGameRules()
+ {
+ // Note, don't delete each team since they are in the gEntList and will
+ // automatically be deleted from there, instead.
+ g_Teams.Purge();
+ }
+
+ //-----------------------------------------------------------------------------
+ // Purpose: TF2 Specific Client Commands
+ // Input :
+ // Output :
+ //-----------------------------------------------------------------------------
+ bool CTFCGameRules::ClientCommand( CBaseEntity *pEdict, const CCommand &args )
+ {
+ CTFCPlayer *pPlayer = ToTFCPlayer( pEdict );
+
+ if( pPlayer->ClientCommand( args ) )
+ return true;
+
+ return BaseClass::ClientCommand( pEdict, args );
+ }
+
+ //-----------------------------------------------------------------------------
+ // Purpose: Player has just spawned. Equip them.
+ //-----------------------------------------------------------------------------
+
+ void CTFCGameRules::RadiusDamage( const CTakeDamageInfo &info, const Vector &vecSrcIn, float flRadius, int iClassIgnore )
+ {
+ RadiusDamage( info, vecSrcIn, flRadius, iClassIgnore, false );
+ }
+
+ // Add the ability to ignore the world trace
+ void CTFCGameRules::RadiusDamage( const CTakeDamageInfo &info, const Vector &vecSrcIn, float flRadius, int iClassIgnore, bool bIgnoreWorld )
+ {
+ CBaseEntity *pEntity = NULL;
+ trace_t tr;
+ float flAdjustedDamage, falloff;
+ Vector vecSpot;
+ Vector vecToTarget;
+ Vector vecEndPos;
+
+ Vector vecSrc = vecSrcIn;
+
+ if ( flRadius )
+ falloff = info.GetDamage() / flRadius;
+ else
+ falloff = 1.0;
+
+ int bInWater = (UTIL_PointContents ( vecSrc ) & MASK_WATER) ? true : false;
+
+ vecSrc.z += 1;// in case grenade is lying on the ground
+
+ // iterate on all entities in the vicinity.
+ for ( CEntitySphereQuery sphere( vecSrc, flRadius ); pEntity = sphere.GetCurrentEntity(); sphere.NextEntity() )
+ {
+ if ( pEntity->m_takedamage != DAMAGE_NO )
+ {
+ // UNDONE: this should check a damage mask, not an ignore
+ if ( iClassIgnore != CLASS_NONE && pEntity->Classify() == iClassIgnore )
+ {// houndeyes don't hurt other houndeyes with their attack
+ continue;
+ }
+
+ // blast's don't tavel into or out of water
+ if (bInWater && pEntity->GetWaterLevel() == 0)
+ continue;
+ if (!bInWater && pEntity->GetWaterLevel() == 3)
+ continue;
+
+ // radius damage can only be blocked by the world
+ vecSpot = pEntity->BodyTarget( vecSrc );
+
+
+
+ bool bHit = false;
+
+ if( bIgnoreWorld )
+ {
+ vecEndPos = vecSpot;
+ bHit = true;
+ }
+ else
+ {
+ UTIL_TraceLine( vecSrc, vecSpot, MASK_SOLID_BRUSHONLY, info.GetInflictor(), COLLISION_GROUP_NONE, &tr );
+
+ if (tr.startsolid)
+ {
+ // if we're stuck inside them, fixup the position and distance
+ tr.endpos = vecSrc;
+ tr.fraction = 0.0;
+ }
+
+ vecEndPos = tr.endpos;
+
+ if( tr.fraction == 1.0 || tr.m_pEnt == pEntity )
+ {
+ bHit = true;
+ }
+ }
+
+ if ( bHit )
+ {
+ // the explosion can 'see' this entity, so hurt them!
+ //vecToTarget = ( vecSrc - vecEndPos );
+ vecToTarget = ( vecEndPos - vecSrc );
+
+ // decrease damage for an ent that's farther from the bomb.
+ flAdjustedDamage = vecToTarget.Length() * falloff;
+ flAdjustedDamage = info.GetDamage() - flAdjustedDamage;
+
+ if ( flAdjustedDamage > 0 )
+ {
+ CTakeDamageInfo adjustedInfo = info;
+ adjustedInfo.SetDamage( flAdjustedDamage );
+
+ Vector dir = vecToTarget;
+ VectorNormalize( dir );
+
+ // If we don't have a damage force, manufacture one
+ if ( adjustedInfo.GetDamagePosition() == vec3_origin || adjustedInfo.GetDamageForce() == vec3_origin )
+ {
+ CalculateExplosiveDamageForce( &adjustedInfo, dir, vecSrc, 1.5 /* explosion scale! */ );
+ }
+ else
+ {
+ // Assume the force passed in is the maximum force. Decay it based on falloff.
+ float flForce = adjustedInfo.GetDamageForce().Length() * falloff;
+ adjustedInfo.SetDamageForce( dir * flForce );
+ adjustedInfo.SetDamagePosition( vecSrc );
+ }
+
+ pEntity->TakeDamage( adjustedInfo );
+
+ // Now hit all triggers along the way that respond to damage...
+ pEntity->TraceAttackToTriggers( adjustedInfo, vecSrc, vecEndPos, dir );
+ }
+ }
+ }
+ }
+ }
+
+ void CTFCGameRules::Think()
+ {
+ Timer_UpdateAll();
+
+ BaseClass::Think();
+ }
+
+ const char *CTFCGameRules::GetChatPrefix( bool bTeamOnly, CBasePlayer *pPlayer )
+ {
+ return "(chat prefix)";
+ }
+
+
+ bool CTFCGameRules::IsInPreMatch() const
+ {
+ // TFCTODO return (cb_prematch_time > gpGlobals->time)
+ return false;
+ }
+
+ float CTFCGameRules::GetPreMatchEndTime() const
+ {
+ //TFCTODO: implement this.
+ return gpGlobals->curtime;
+ }
+
+ void CTFCGameRules::TFCGoToIntermission()
+ {
+ // TFCTODO: implement this.
+ Assert( false );
+ }
+
+
+#endif
+
+
+bool CTFCGameRules::ShouldCollide( int collisionGroup0, int collisionGroup1 )
+{
+ if ( collisionGroup0 > collisionGroup1 )
+ {
+ // swap so that lowest is always first
+ swap(collisionGroup0,collisionGroup1);
+ }
+
+ //Don't stand on COLLISION_GROUP_WEAPONs
+ if( collisionGroup0 == COLLISION_GROUP_PLAYER_MOVEMENT &&
+ collisionGroup1 == COLLISION_GROUP_WEAPON )
+ {
+ return false;
+ }
+
+ if ( collisionGroup0 == COLLISION_GROUP_PLAYER )
+ {
+ // Players don't collide with objects or other players
+ if ( collisionGroup1 == COLLISION_GROUP_PLAYER )
+ return false;
+ }
+
+ if ( collisionGroup1 == COLLISION_GROUP_PLAYER_MOVEMENT )
+ {
+ // This is only for probing, so it better not be on both sides!!!
+ Assert( collisionGroup0 != COLLISION_GROUP_PLAYER_MOVEMENT );
+
+ // No collide with players any more
+ // Nor with objects or grenades
+ switch ( collisionGroup0 )
+ {
+ default:
+ break;
+ case COLLISION_GROUP_PLAYER:
+ return false;
+ }
+ }
+
+ return BaseClass::ShouldCollide( collisionGroup0, collisionGroup1 );
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Init CS ammo definitions
+//-----------------------------------------------------------------------------
+
+// shared ammo definition
+// JAY: Trying to make a more physical bullet response
+#define BULLET_MASS_GRAINS_TO_LB(grains) (0.002285*(grains)/16.0f)
+#define BULLET_MASS_GRAINS_TO_KG(grains) lbs2kg(BULLET_MASS_GRAINS_TO_LB(grains))
+
+// exaggerate all of the forces, but use real numbers to keep them consistent
+#define BULLET_IMPULSE_EXAGGERATION 1
+
+// convert a velocity in ft/sec and a mass in grains to an impulse in kg in/s
+#define BULLET_IMPULSE(grains, ftpersec) ((ftpersec)*12*BULLET_MASS_GRAINS_TO_KG(grains)*BULLET_IMPULSE_EXAGGERATION)
+
+
+CAmmoDef* GetAmmoDef()
+{
+ static CAmmoDef def;
+ static bool bInitted = false;
+
+ if ( !bInitted )
+ {
+ bInitted = true;
+
+ // Start at 1 here and skip the dummy ammo type to make CAmmoDef use the same indices
+ // as our #defines.
+ for ( int i=1; i < TFC_NUM_AMMO_TYPES; i++ )
+ {
+ def.AddAmmoType( g_AmmoTypeNames[i], DMG_BULLET, TRACER_LINE, 0, 0, "ammo_max", 2400, 10, 14 );
+ Assert( def.Index( g_AmmoTypeNames[i] ) == i );
+ }
+ }
+
+ return &def;
+}
+
+
diff --git a/game/shared/tfc/tfc_gamerules.h b/game/shared/tfc/tfc_gamerules.h
new file mode 100644
index 0000000..6f678f3
--- /dev/null
+++ b/game/shared/tfc/tfc_gamerules.h
@@ -0,0 +1,104 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: The TF Game rules object
+//
+// $Workfile: $
+// $Date: $
+// $NoKeywords: $
+//=============================================================================//
+
+#ifndef TFC_GAMERULES_H
+#define TFC_GAMERULES_H
+
+#ifdef _WIN32
+#pragma once
+#endif
+
+
+#include "teamplay_gamerules.h"
+#include "convar.h"
+#include "gamevars_shared.h"
+
+#ifdef CLIENT_DLL
+ #include "c_baseplayer.h"
+#else
+ #include "player.h"
+#endif
+
+
+#ifdef CLIENT_DLL
+
+ #define CTFCGameRules C_TFCGameRules
+ #define CTFCGameRulesProxy C_TFCGameRulesProxy
+
+#else
+
+ extern BOOL no_cease_fire_text;
+ extern BOOL cease_fire;
+
+#endif
+
+
+class CTFCGameRulesProxy : public CGameRulesProxy
+{
+public:
+ DECLARE_CLASS( CTFCGameRulesProxy, CGameRulesProxy );
+ DECLARE_NETWORKCLASS();
+};
+
+
+class CTFCGameRules : public CTeamplayRules
+{
+public:
+ DECLARE_CLASS( CTFCGameRules, CTeamplayRules );
+
+ CTFCGameRules();
+
+ virtual bool ShouldCollide( int collisionGroup0, int collisionGroup1 );
+ void RadiusDamage( const CTakeDamageInfo &info, const Vector &vecSrcIn, float flRadius, int iClassIgnore, bool bIgnoreWorld );
+
+ #ifdef CLIENT_DLL
+
+ DECLARE_CLIENTCLASS_NOBASE(); // This makes datatables able to access our private vars.
+
+ #else
+
+ DECLARE_SERVERCLASS_NOBASE(); // This makes datatables able to access our private vars.
+
+ virtual ~CTFCGameRules();
+
+ virtual bool ClientCommand( CBaseEntity *pEdict, const CCommand &args );
+ virtual void RadiusDamage( const CTakeDamageInfo &info, const Vector &vecSrcIn, float flRadius, int iClassIgnore );
+ virtual void Think();
+
+ virtual const char *GetChatPrefix( bool bTeamOnly, CBasePlayer *pPlayer );
+
+ bool IsInPreMatch() const;
+ float GetPreMatchEndTime() const; // Returns the time at which the prematch will be over.
+ void TFCGoToIntermission();
+
+ private:
+
+#endif
+
+
+public:
+
+ bool CTF_Map;
+
+};
+
+//-----------------------------------------------------------------------------
+// Gets us at the team fortress game rules
+//-----------------------------------------------------------------------------
+
+inline CTFCGameRules* TFCGameRules()
+{
+ return static_cast<CTFCGameRules*>(g_pGameRules);
+}
+
+
+extern ConVar mp_fadetoblack;
+
+
+#endif // TFC_GAMERULES_H
diff --git a/game/shared/tfc/tfc_player_shared.cpp b/game/shared/tfc/tfc_player_shared.cpp
new file mode 100644
index 0000000..8430903
--- /dev/null
+++ b/game/shared/tfc/tfc_player_shared.cpp
@@ -0,0 +1,97 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================//
+
+#include "cbase.h"
+#include "tfc_gamerules.h"
+#include "tfc_player_shared.h"
+#include "takedamageinfo.h"
+#include "weapon_tfcbase.h"
+
+
+#ifdef CLIENT_DLL
+
+ #include "c_tfc_player.h"
+
+ BEGIN_RECV_TABLE_NOBASE( CTFCPlayerShared, DT_TFCPlayerShared )
+ RecvPropInt( RECVINFO( m_iPlayerClass ) ),
+ RecvPropInt( RECVINFO( m_iPlayerState ) ),
+ RecvPropInt( RECVINFO( m_StateFlags ) ),
+ RecvPropInt( RECVINFO( m_ItemFlags ) )
+ END_RECV_TABLE()
+
+ BEGIN_PREDICTION_DATA_NO_BASE( CTFCPlayerShared )
+ DEFINE_PRED_FIELD( m_iPlayerState, FIELD_INTEGER, FTYPEDESC_INSENDTABLE )
+ END_PREDICTION_DATA()
+
+#else
+
+ #include "tfc_player.h"
+
+ BEGIN_SEND_TABLE_NOBASE( CTFCPlayerShared, DT_TFCPlayerShared )
+ SendPropInt( SENDINFO(m_iPlayerClass), NumBitsForCount( PC_LASTCLASS+1 ), SPROP_UNSIGNED ),
+ SendPropInt( SENDINFO(m_iPlayerState), NumBitsForCount( TFC_NUM_PLAYER_STATES ), SPROP_UNSIGNED ),
+ SendPropInt( SENDINFO(m_StateFlags) , NumBitsForCount( TFSTATE_HIGHEST_VALUE+1 ), SPROP_UNSIGNED ),
+ SendPropInt( SENDINFO(m_StateFlags) , NumBitsForCount( IT_LAST_ITEM+1 ), SPROP_UNSIGNED )
+ END_SEND_TABLE()
+
+#endif
+
+
+// --------------------------------------------------------------------------------------------------- //
+// Shared CTFCPlayer implementation.
+// --------------------------------------------------------------------------------------------------- //
+
+
+
+// --------------------------------------------------------------------------------------------------- //
+// CTFCPlayerShared implementation.
+// --------------------------------------------------------------------------------------------------- //
+
+CTFCPlayerShared::CTFCPlayerShared()
+{
+ m_iPlayerClass = PC_UNDEFINED;
+ m_iPlayerState = STATE_WELCOME;
+}
+
+
+void CTFCPlayerShared::Init( CTFCPlayer *pPlayer )
+{
+ m_pOuter = pPlayer;
+}
+
+
+void CTFCPlayerShared::SetPlayerClass( int playerclass )
+{
+ m_iPlayerClass = playerclass;
+}
+
+int CTFCPlayerShared::GetPlayerClass() const
+{
+ return m_iPlayerClass;
+}
+
+
+TFCPlayerState CTFCPlayerShared::State_Get() const
+{
+ return m_iPlayerState;
+}
+
+
+CWeaponTFCBase* CTFCPlayerShared::GetActiveTFCWeapon() const
+{
+ CBaseCombatWeapon *pRet = m_pOuter->GetActiveWeapon();
+ if ( pRet )
+ {
+ Assert( dynamic_cast< CWeaponTFCBase* >( pRet ) != NULL );
+ return static_cast< CWeaponTFCBase * >( pRet );
+ }
+ else
+ {
+ return NULL;
+ }
+}
+
+
diff --git a/game/shared/tfc/tfc_player_shared.h b/game/shared/tfc/tfc_player_shared.h
new file mode 100644
index 0000000..aca3b23
--- /dev/null
+++ b/game/shared/tfc/tfc_player_shared.h
@@ -0,0 +1,138 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================//
+
+#ifndef TFC_PLAYER_SHARED_H
+#define TFC_PLAYER_SHARED_H
+#ifdef _WIN32
+#pragma once
+#endif
+
+
+#include "networkvar.h"
+#include "tfc_shareddefs.h"
+#include "weapon_tfcbase.h"
+
+
+#ifdef CLIENT_DLL
+ class C_TFCPlayer;
+ EXTERN_RECV_TABLE( DT_TFCPlayerShared );
+#else
+ class CTFCPlayer;
+ EXTERN_SEND_TABLE( DT_TFCPlayerShared );
+#endif
+
+
+
+// Data in the DoD player that is accessed by shared code.
+// This data isn't necessarily transmitted between client and server.
+class CTFCPlayerShared
+{
+public:
+
+#ifdef CLIENT_DLL
+ friend class C_TFCPlayer;
+ typedef C_TFCPlayer OuterClass;
+ DECLARE_PREDICTABLE();
+#else
+ friend class CTFCPlayer;
+ typedef CTFCPlayer OuterClass;
+#endif
+
+ DECLARE_EMBEDDED_NETWORKVAR()
+ DECLARE_CLASS_NOBASE( CTFCPlayerShared );
+
+
+ CTFCPlayerShared();
+
+ void Init( OuterClass *pOuter );
+
+ void SetPlayerClass( int playerclass );
+ int GetPlayerClass() const;
+ const CTFCPlayerClassInfo* GetClassInfo() const;
+
+ // State.
+ TFCPlayerState State_Get() const;
+
+ // State flags (TFSTATE_).
+ int GetStateFlags() const;
+ void SetStateFlags( int val );
+ void AddStateFlags( int flags );
+ void RemoveStateFlags( int flags );
+
+ // Item flags (IT_).
+ int GetItemFlags() const;
+ void SetItemFlags( int val );
+ void AddItemFlags( int val );
+ void RemoveItemFlags( int val );
+
+ CWeaponTFCBase* GetActiveTFCWeapon() const;
+
+// Vars that are networked.
+private:
+
+ CNetworkVar( int, m_StateFlags ); // Combination of the TFSTATE_ flags.
+ CNetworkVar( int, m_ItemFlags );
+ CNetworkVar( int, m_iPlayerClass );
+ CNetworkVar( TFCPlayerState, m_iPlayerState );
+
+
+// Vars that aren't networked.
+public:
+
+
+private:
+
+ OuterClass *m_pOuter;
+};
+
+
+inline int CTFCPlayerShared::GetStateFlags() const
+{
+ return m_StateFlags;
+}
+
+inline void CTFCPlayerShared::SetStateFlags( int val )
+{
+ m_StateFlags = val;
+}
+
+inline void CTFCPlayerShared::AddStateFlags( int flags )
+{
+ m_StateFlags |= flags;
+}
+
+inline void CTFCPlayerShared::RemoveStateFlags( int flags )
+{
+ m_StateFlags &= ~flags;
+}
+
+inline int CTFCPlayerShared::GetItemFlags() const
+{
+ return m_ItemFlags;
+}
+
+inline void CTFCPlayerShared::SetItemFlags( int val )
+{
+ m_ItemFlags = val;
+}
+
+inline void CTFCPlayerShared::AddItemFlags( int val )
+{
+ m_ItemFlags |= val;
+}
+
+inline void CTFCPlayerShared::RemoveItemFlags( int val )
+{
+ m_ItemFlags &= ~val;
+}
+
+inline const CTFCPlayerClassInfo* CTFCPlayerShared::GetClassInfo() const
+{
+ return GetTFCClassInfo( GetPlayerClass() );
+}
+
+
+#endif // TFC_PLAYER_SHARED_H
diff --git a/game/shared/tfc/tfc_playeranimstate.cpp b/game/shared/tfc/tfc_playeranimstate.cpp
new file mode 100644
index 0000000..7c47748
--- /dev/null
+++ b/game/shared/tfc/tfc_playeranimstate.cpp
@@ -0,0 +1,323 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================//
+
+#include "cbase.h"
+#include "tfc_playeranimstate.h"
+#include "base_playeranimstate.h"
+#include "tier0/vprof.h"
+#include "animation.h"
+#include "studio.h"
+#include "apparent_velocity_helper.h"
+#include "utldict.h"
+
+
+#ifdef CLIENT_DLL
+ #include "c_tfc_player.h"
+#else
+ #include "tfc_player.h"
+#endif
+
+
+// When moving this fast, he plays run anim.
+#define ARBITRARY_RUN_SPEED 175.0f
+
+#define MAX_STANDING_RUN_SPEED 320
+#define MAX_CROUCHED_RUN_SPEED 110
+
+
+// ------------------------------------------------------------------------------------------------ //
+// CPlayerAnimState declaration.
+// ------------------------------------------------------------------------------------------------ //
+
+class CTFCPlayerAnimState : public ITFCPlayerAnimState, public CBasePlayerAnimState
+{
+public:
+
+ DECLARE_CLASS( CTFCPlayerAnimState, CBasePlayerAnimState );
+
+ CTFCPlayerAnimState();
+ void InitTFC( CTFCPlayer *pPlayer );
+
+ // This is called by both the client and the server in the same way to trigger events for
+ // players firing, jumping, throwing grenades, etc.
+ virtual void DoAnimationEvent( PlayerAnimEvent_t event, int nData );
+ virtual int CalcAimLayerSequence( float *flCycle, float *flAimSequenceWeight );
+ virtual float SetOuterBodyYaw( float flValue );
+ virtual Activity CalcMainActivity();
+ virtual float GetCurrentMaxGroundSpeed();
+ virtual void ClearAnimationState();
+ virtual bool ShouldUpdateAnimState();
+
+
+private:
+
+ const char* GetWeaponSuffix();
+ bool HandleJumping();
+ bool HandleDeath( Activity *deathActivity );
+
+
+private:
+
+ CTFCPlayer *m_pOuterTFC;
+
+ bool m_bJumping;
+ bool m_bFirstJumpFrame;
+ float m_flJumpStartTime;
+
+ bool m_bFiring;
+ float m_flFireStartTime;
+
+ bool m_bDying;
+ Activity m_DeathActivity;
+};
+
+
+ITFCPlayerAnimState* CreatePlayerAnimState( CTFCPlayer *pPlayer )
+{
+ CTFCPlayerAnimState *pRet = new CTFCPlayerAnimState;
+ pRet->InitTFC( pPlayer );
+ return pRet;
+}
+
+
+// ----------------------------------------------------------------------------- //
+// CTFCPlayerAnimState implementation.
+// ----------------------------------------------------------------------------- //
+
+CTFCPlayerAnimState::CTFCPlayerAnimState()
+{
+ m_pOuterTFC = NULL;
+ m_bJumping = false;
+ m_bFirstJumpFrame = false;
+ m_bFiring = false;
+}
+
+
+void CTFCPlayerAnimState::InitTFC( CTFCPlayer *pPlayer )
+{
+ m_pOuterTFC = pPlayer;
+
+ CModAnimConfig config;
+ config.m_flMaxBodyYawDegrees = 30;
+ config.m_LegAnimType = LEGANIM_GOLDSRC;
+ config.m_bUseAimSequences = true;
+
+ BaseClass::Init( pPlayer, config );
+}
+
+
+const char* CTFCPlayerAnimState::GetWeaponSuffix()
+{
+ CBaseCombatWeapon *pWeapon = m_pOuterTFC->GetActiveWeapon();
+ if ( pWeapon )
+ return pWeapon->GetWpnData().szAnimationPrefix;
+ else
+ return "shotgun";
+}
+
+
+int CTFCPlayerAnimState::CalcAimLayerSequence( float *flCycle, float *flAimSequenceWeight )
+{
+ const char *pWeaponSuffix = GetWeaponSuffix();
+ if ( !pWeaponSuffix )
+ return 0;
+
+ // Are we aiming or firing?
+ const char *pAimOrShoot = "aim";
+ if ( m_bFiring )
+ pAimOrShoot = "shoot";
+
+ // Are we standing or crouching?
+ int iSequence = 0;
+ const char *pPrefix = "ref";
+ if ( m_bDying )
+ {
+ // While dying, only play the main sequence.. don't layer this one on top.
+ *flAimSequenceWeight = 0;
+ }
+ else
+ {
+ switch ( GetCurrentMainSequenceActivity() )
+ {
+ case ACT_CROUCHIDLE:
+ case ACT_RUN_CROUCH:
+ pPrefix = "crouch";
+ break;
+ }
+ }
+
+ iSequence = CalcSequenceIndex( "%s_%s_%s", pPrefix, pAimOrShoot, pWeaponSuffix );
+
+ // Check if we're done firing.
+ if ( m_bFiring )
+ {
+ float dur = m_pOuterTFC->SequenceDuration( iSequence );
+ *flCycle = (gpGlobals->curtime - m_flFireStartTime) / dur;
+ if ( *flCycle >= 1 )
+ {
+ *flCycle = 1;
+ m_bFiring = false;
+ }
+ }
+
+ return iSequence;
+}
+
+
+void CTFCPlayerAnimState::DoAnimationEvent( PlayerAnimEvent_t event, int nData )
+{
+ if ( event == PLAYERANIMEVENT_JUMP )
+ {
+ // Main animation goes to ACT_HOP.
+ m_bJumping = true;
+ m_bFirstJumpFrame = true;
+ m_flJumpStartTime = gpGlobals->curtime;
+ }
+ else if ( event == PLAYERANIMEVENT_FIRE_GUN )
+ {
+ // The middle part of the aim layer sequence becomes "shoot" until that animation is complete.
+ m_bFiring = true;
+ m_flFireStartTime = gpGlobals->curtime;
+ }
+ else if ( event == PLAYERANIMEVENT_DIE )
+ {
+ m_bFiring = m_bJumping = false;
+ m_bDying = true;
+
+ Activity acts[] =
+ {
+ ACT_DIESIMPLE,
+ ACT_DIEBACKWARD,
+ ACT_DIEFORWARD,
+ ACT_DIE_HEADSHOT,
+ ACT_DIE_GUTSHOT
+ };
+
+ m_DeathActivity = acts[ RandomInt( 0, ARRAYSIZE( acts ) - 1 ) ];
+ RestartMainSequence(); // Play a death animation.
+ }
+}
+
+
+float CTFCPlayerAnimState::SetOuterBodyYaw( float flValue )
+{
+ m_pOuterTFC->SetBoneController( 0, flValue );
+ return flValue;
+}
+
+
+bool CTFCPlayerAnimState::HandleJumping()
+{
+ if ( m_bJumping )
+ {
+ if ( m_bFirstJumpFrame )
+ {
+ m_bFirstJumpFrame = false;
+ RestartMainSequence(); // Reset the animation.
+ }
+
+ // Don't check if he's on the ground for a sec.. sometimes the client still has the
+ // on-ground flag set right when the message comes in.
+ if ( gpGlobals->curtime - m_flJumpStartTime > 0.2f )
+ {
+ if ( m_pOuterTFC->GetFlags() & FL_ONGROUND )
+ {
+ m_bJumping = false;
+ RestartMainSequence(); // Reset the animation.
+ }
+ }
+ }
+
+ // Are we still jumping? If so, keep playing the jump animation.
+ return m_bJumping;
+}
+
+
+bool CTFCPlayerAnimState::HandleDeath( Activity *deathActivity )
+{
+ if ( m_bDying )
+ {
+ if ( m_pOuterTFC->IsAlive() )
+ {
+ m_bDying = false;
+ }
+ else
+ {
+ *deathActivity = m_DeathActivity;
+ }
+ }
+ return m_bDying;
+}
+
+
+Activity CTFCPlayerAnimState::CalcMainActivity()
+{
+ Activity deathActivity = ACT_IDLE;
+ if ( HandleDeath( &deathActivity ) )
+ {
+ return deathActivity;
+ }
+ else if ( HandleJumping() )
+ {
+ return ACT_HOP;
+ }
+ else
+ {
+ Activity idealActivity = ACT_IDLE;
+ float flOuterSpeed = GetOuterXYSpeed();
+
+ if ( m_pOuterTFC->GetFlags() & FL_DUCKING )
+ {
+ if ( flOuterSpeed > 0.1f )
+ idealActivity = ACT_RUN_CROUCH;
+ else
+ idealActivity = ACT_CROUCHIDLE;
+ }
+ else
+ {
+ if ( flOuterSpeed > 0.1f )
+ {
+ if ( flOuterSpeed > ARBITRARY_RUN_SPEED )
+ idealActivity = ACT_RUN;
+ else
+ idealActivity = ACT_WALK;
+ }
+ else
+ {
+ idealActivity = ACT_IDLE;
+ }
+ }
+
+ return idealActivity;
+ }
+}
+
+
+float CTFCPlayerAnimState::GetCurrentMaxGroundSpeed()
+{
+ Activity act = GetCurrentMainSequenceActivity();
+ if ( act == ACT_CROUCHIDLE || act == ACT_RUN_CROUCH )
+ return MAX_CROUCHED_RUN_SPEED;
+ else
+ return MAX_STANDING_RUN_SPEED;
+}
+
+
+void CTFCPlayerAnimState::ClearAnimationState()
+{
+ m_bJumping = false;
+ m_bFiring = false;
+ m_bDying = false;
+
+ BaseClass::ClearAnimationState();
+}
+
+
+bool CTFCPlayerAnimState::ShouldUpdateAnimState()
+{
+ return true;
+}
+
diff --git a/game/shared/tfc/tfc_playeranimstate.h b/game/shared/tfc/tfc_playeranimstate.h
new file mode 100644
index 0000000..fab1a41
--- /dev/null
+++ b/game/shared/tfc/tfc_playeranimstate.h
@@ -0,0 +1,55 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================//
+
+#ifndef TFC_PLAYERANIMSTATE_H
+#define TFC_PLAYERANIMSTATE_H
+#ifdef _WIN32
+#pragma once
+#endif
+
+
+#include "convar.h"
+#include "iplayeranimstate.h"
+
+
+#if defined( CLIENT_DLL )
+ class C_TFCPlayer;
+ #define CTFCPlayer C_TFCPlayer
+#else
+ class CTFCPlayer;
+#endif
+
+
+enum PlayerAnimEvent_t
+{
+ PLAYERANIMEVENT_FIRE_GUN=0,
+ PLAYERANIMEVENT_THROW_GRENADE,
+ PLAYERANIMEVENT_JUMP,
+ PLAYERANIMEVENT_RELOAD,
+ PLAYERANIMEVENT_DIE,
+
+ PLAYERANIMEVENT_COUNT
+};
+
+
+class ITFCPlayerAnimState : virtual public IPlayerAnimState
+{
+public:
+ // This is called by both the client and the server in the same way to trigger events for
+ // players firing, jumping, throwing grenades, etc.
+ virtual void DoAnimationEvent( PlayerAnimEvent_t event, int nData ) = 0;
+};
+
+
+ITFCPlayerAnimState* CreatePlayerAnimState( CTFCPlayer *pPlayer );
+
+
+// If this is set, then the game code needs to make sure to send player animation events
+// to the local player if he's the one being watched.
+extern ConVar cl_showanimstate;
+
+
+#endif // TFC_PLAYERANIMSTATE_H
diff --git a/game/shared/tfc/tfc_shareddefs.cpp b/game/shared/tfc/tfc_shareddefs.cpp
new file mode 100644
index 0000000..3ca5460
--- /dev/null
+++ b/game/shared/tfc/tfc_shareddefs.cpp
@@ -0,0 +1,436 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================//
+
+#include "cbase.h"
+#include "tfc_shareddefs.h"
+
+
+const char *g_AmmoTypeNames[] =
+{
+ "DUMMY AMMO",
+ TFC_AMMO_SHELLS_NAME,
+ TFC_AMMO_NAILS_NAME,
+ TFC_AMMO_ROCKETS_NAME,
+ TFC_AMMO_CELLS_NAME,
+ TFC_AMMO_MEDIKIT_NAME,
+ TFC_AMMO_DETPACK_NAME,
+ TFC_AMMO_GRENADES1_NAME,
+ TFC_AMMO_GRENADES2_NAME
+};
+
+
+int g_nMaxGrenades[NUM_GRENADE_TYPES] =
+{
+ 0, // GR_TYPE_NONE
+ 4, // GR_TYPE_NORMAL
+ 3, // GR_TYPE_CONCUSSION
+ 2, // GR_TYPE_NAIL
+ 2, // GR_TYPE_MIRV
+ 2, // GR_TYPE_NAPALM
+ 2, // GR_TYPE_GAS
+ 4, // GR_TYPE_EMP
+ 3, // GR_TYPE_CALTROP
+};
+
+
+CTFCPlayerClassInfo g_TFCPlayerClassInfo[PC_LASTCLASS];
+
+
+// Note: this could go in a script, but it's not much trouble to have it all here.
+class CClassInfoInitializer
+{
+public:
+
+ CClassInfoInitializer()
+ {
+ memset( &g_TFCPlayerClassInfo, 0xFE, sizeof( g_TFCPlayerClassInfo ) );
+
+ // PC_UNDEFINED.
+ CTFCPlayerClassInfo *pInfo = &g_TFCPlayerClassInfo[PC_UNDEFINED];
+ pInfo->m_pClassName = "undefined";
+ pInfo->m_pModelName = "models/player/civilian.mdl";
+ pInfo->m_flMaxSpeed = 1;
+ memset( pInfo->m_MaxAmmo, 0, sizeof( pInfo->m_MaxAmmo ) );
+
+ // PC_SCOUT.
+ pInfo = &g_TFCPlayerClassInfo[PC_SCOUT];
+ pInfo->m_pClassName = "scout";
+ pInfo->m_pModelName = "models/player/scout.mdl";
+ pInfo->m_flMaxSpeed = 400;
+ pInfo->m_iMaxHealth = 75;
+
+ pInfo->m_iInitArmor = 25;
+ pInfo->m_iMaxArmor = 50;
+
+ pInfo->m_flInitArmorType = 0.3;
+ pInfo->m_flMaxArmorType = 0.3;
+ pInfo->m_nArmorClasses = 3;
+ pInfo->m_iInitArmorClass = 0;
+
+ pInfo->m_iGrenadeType1 = GR_TYPE_CALTROP;
+ pInfo->m_iGrenadeType2 = GR_TYPE_CONCUSSION;
+
+ pInfo->m_InitAmmo[TFC_AMMO_SHELLS] = 25;
+ pInfo->m_InitAmmo[TFC_AMMO_NAILS] = 100;
+ pInfo->m_InitAmmo[TFC_AMMO_ROCKETS] = 0;
+ pInfo->m_InitAmmo[TFC_AMMO_CELLS] = 50;
+ pInfo->m_InitAmmo[TFC_AMMO_MEDIKIT] = 0;
+ pInfo->m_InitAmmo[TFC_AMMO_DETPACK] = 0;
+ pInfo->m_InitAmmo[TFC_AMMO_GRENADES1] = 2;
+ pInfo->m_InitAmmo[TFC_AMMO_GRENADES2] = 3;
+
+ pInfo->m_MaxAmmo[TFC_AMMO_SHELLS] = 50;
+ pInfo->m_MaxAmmo[TFC_AMMO_NAILS] = 200;
+ pInfo->m_MaxAmmo[TFC_AMMO_ROCKETS] = 25;
+ pInfo->m_MaxAmmo[TFC_AMMO_CELLS] = 100;
+ pInfo->m_MaxAmmo[TFC_AMMO_MEDIKIT] = 0;
+ pInfo->m_MaxAmmo[TFC_AMMO_DETPACK] = 0;
+ pInfo->m_MaxAmmo[TFC_AMMO_GRENADES1] = 4;
+ pInfo->m_MaxAmmo[TFC_AMMO_GRENADES2] = 4;
+
+ // PC_SNIPER.
+ pInfo = &g_TFCPlayerClassInfo[PC_SNIPER];
+ pInfo->m_pClassName = "sniper";
+ pInfo->m_pModelName = "models/player/sniper.mdl";
+ pInfo->m_flMaxSpeed = 300;
+ pInfo->m_iMaxHealth = 90;
+
+ pInfo->m_iInitArmor = 25;
+ pInfo->m_iMaxArmor = 50;
+
+ pInfo->m_flInitArmorType = 0.3;
+ pInfo->m_flMaxArmorType = 0.3;
+ pInfo->m_nArmorClasses = 3;
+ pInfo->m_iInitArmorClass = 0;
+
+ pInfo->m_iGrenadeType1 = GR_TYPE_NORMAL;
+ pInfo->m_iGrenadeType2 = GR_TYPE_NONE;
+
+ pInfo->m_InitAmmo[TFC_AMMO_SHELLS] = 60;
+ pInfo->m_InitAmmo[TFC_AMMO_NAILS] = 50;
+ pInfo->m_InitAmmo[TFC_AMMO_ROCKETS] = 0;
+ pInfo->m_InitAmmo[TFC_AMMO_CELLS] = 0;
+ pInfo->m_InitAmmo[TFC_AMMO_MEDIKIT] = 0;
+ pInfo->m_InitAmmo[TFC_AMMO_DETPACK] = 0;
+ pInfo->m_InitAmmo[TFC_AMMO_GRENADES1] = 2;
+ pInfo->m_InitAmmo[TFC_AMMO_GRENADES2] = 0;
+
+ pInfo->m_MaxAmmo[TFC_AMMO_SHELLS] = 75;
+ pInfo->m_MaxAmmo[TFC_AMMO_NAILS] = 100;
+ pInfo->m_MaxAmmo[TFC_AMMO_ROCKETS] = 25;
+ pInfo->m_MaxAmmo[TFC_AMMO_CELLS] = 50;
+ pInfo->m_MaxAmmo[TFC_AMMO_MEDIKIT] = 0;
+ pInfo->m_MaxAmmo[TFC_AMMO_DETPACK] = 0;
+ pInfo->m_MaxAmmo[TFC_AMMO_GRENADES1] = 4;
+ pInfo->m_MaxAmmo[TFC_AMMO_GRENADES2] = 4;
+
+ // PC_SOLDIER.
+ pInfo = &g_TFCPlayerClassInfo[PC_SOLDIER];
+ pInfo->m_pClassName = "soldier";
+ pInfo->m_pModelName = "models/player/soldier.mdl";
+ pInfo->m_flMaxSpeed = 240;
+ pInfo->m_iMaxHealth = 100;
+
+ pInfo->m_iInitArmor = 100;
+ pInfo->m_iMaxArmor = 200;
+
+ pInfo->m_flInitArmorType = 0.8;
+ pInfo->m_flMaxArmorType = 0.8;
+ pInfo->m_nArmorClasses = 31;
+ pInfo->m_iInitArmorClass = 0;
+
+ pInfo->m_iGrenadeType1 = GR_TYPE_NORMAL;
+ pInfo->m_iGrenadeType2 = GR_TYPE_NAIL;
+
+ pInfo->m_InitAmmo[TFC_AMMO_SHELLS] = 50;
+ pInfo->m_InitAmmo[TFC_AMMO_NAILS] = 0;
+ pInfo->m_InitAmmo[TFC_AMMO_ROCKETS] = 10;
+ pInfo->m_InitAmmo[TFC_AMMO_CELLS] = 0;
+ pInfo->m_InitAmmo[TFC_AMMO_MEDIKIT] = 0;
+ pInfo->m_InitAmmo[TFC_AMMO_DETPACK] = 0;
+ pInfo->m_InitAmmo[TFC_AMMO_GRENADES1] = 2;
+ pInfo->m_InitAmmo[TFC_AMMO_GRENADES2] = 1;
+
+ pInfo->m_MaxAmmo[TFC_AMMO_SHELLS] = 100;
+ pInfo->m_MaxAmmo[TFC_AMMO_NAILS] = 100;
+ pInfo->m_MaxAmmo[TFC_AMMO_ROCKETS] = 50;
+ pInfo->m_MaxAmmo[TFC_AMMO_CELLS] = 50;
+ pInfo->m_MaxAmmo[TFC_AMMO_MEDIKIT] = 0;
+ pInfo->m_MaxAmmo[TFC_AMMO_DETPACK] = 0;
+ pInfo->m_MaxAmmo[TFC_AMMO_GRENADES1] = 4;
+ pInfo->m_MaxAmmo[TFC_AMMO_GRENADES2] = 4;
+
+
+ // PC_DEMOMAN.
+ pInfo = &g_TFCPlayerClassInfo[PC_DEMOMAN];
+ pInfo->m_pClassName = "demoman";
+ pInfo->m_pModelName = "models/player/demo.mdl";
+ pInfo->m_flMaxSpeed = 280;
+ pInfo->m_iMaxHealth = 90;
+
+ pInfo->m_iInitArmor = 50;
+ pInfo->m_iMaxArmor = 120;
+
+ pInfo->m_flInitArmorType = 0.6;
+ pInfo->m_flMaxArmorType = 0.6;
+ pInfo->m_nArmorClasses = 31;
+ pInfo->m_iInitArmorClass = 0;
+
+ pInfo->m_iGrenadeType1 = GR_TYPE_NORMAL;
+ pInfo->m_iGrenadeType2 = GR_TYPE_MIRV;
+
+ pInfo->m_InitAmmo[TFC_AMMO_SHELLS] = 30;
+ pInfo->m_InitAmmo[TFC_AMMO_NAILS] = 0;
+ pInfo->m_InitAmmo[TFC_AMMO_ROCKETS] = 20;
+ pInfo->m_InitAmmo[TFC_AMMO_CELLS] = 0;
+ pInfo->m_InitAmmo[TFC_AMMO_MEDIKIT] = 0;
+ pInfo->m_InitAmmo[TFC_AMMO_DETPACK] = 0;
+ pInfo->m_InitAmmo[TFC_AMMO_GRENADES1] = 2;
+ pInfo->m_InitAmmo[TFC_AMMO_GRENADES2] = 2;
+
+ pInfo->m_MaxAmmo[TFC_AMMO_SHELLS] = 75;
+ pInfo->m_MaxAmmo[TFC_AMMO_NAILS] = 50;
+ pInfo->m_MaxAmmo[TFC_AMMO_ROCKETS] = 50;
+ pInfo->m_MaxAmmo[TFC_AMMO_CELLS] = 50;
+ pInfo->m_MaxAmmo[TFC_AMMO_MEDIKIT] = 0;
+ pInfo->m_MaxAmmo[TFC_AMMO_DETPACK] = 0;
+ pInfo->m_MaxAmmo[TFC_AMMO_GRENADES1] = 4;
+ pInfo->m_MaxAmmo[TFC_AMMO_GRENADES2] = 4;
+
+
+ // PC_MEDIC.
+ pInfo = &g_TFCPlayerClassInfo[PC_MEDIC];
+ pInfo->m_pClassName = "medic";
+ pInfo->m_pModelName = "models/player/medic.mdl";
+ pInfo->m_flMaxSpeed = 320;
+ pInfo->m_iMaxHealth = 90;
+
+ pInfo->m_iInitArmor = 50;
+ pInfo->m_iMaxArmor = 100;
+
+ pInfo->m_flInitArmorType = 0.3;
+ pInfo->m_flMaxArmorType = 0.6;
+ pInfo->m_nArmorClasses = 11;
+ pInfo->m_iInitArmorClass = 0;
+
+ pInfo->m_iGrenadeType1 = GR_TYPE_NORMAL;
+ pInfo->m_iGrenadeType2 = GR_TYPE_CONCUSSION;
+
+ pInfo->m_InitAmmo[TFC_AMMO_SHELLS] = 50;
+ pInfo->m_InitAmmo[TFC_AMMO_NAILS] = 50;
+ pInfo->m_InitAmmo[TFC_AMMO_ROCKETS] = 0;
+ pInfo->m_InitAmmo[TFC_AMMO_CELLS] = 0;
+ pInfo->m_InitAmmo[TFC_AMMO_MEDIKIT] = 50;
+ pInfo->m_InitAmmo[TFC_AMMO_DETPACK] = 0;
+ pInfo->m_InitAmmo[TFC_AMMO_GRENADES1] = 2;
+ pInfo->m_InitAmmo[TFC_AMMO_GRENADES2] = 2;
+
+ pInfo->m_MaxAmmo[TFC_AMMO_SHELLS] = 75;
+ pInfo->m_MaxAmmo[TFC_AMMO_NAILS] = 150;
+ pInfo->m_MaxAmmo[TFC_AMMO_ROCKETS] = 25;
+ pInfo->m_MaxAmmo[TFC_AMMO_CELLS] = 50;
+ pInfo->m_MaxAmmo[TFC_AMMO_MEDIKIT] = 50;
+ pInfo->m_MaxAmmo[TFC_AMMO_DETPACK] = 0;
+ pInfo->m_MaxAmmo[TFC_AMMO_GRENADES1] = 4;
+ pInfo->m_MaxAmmo[TFC_AMMO_GRENADES2] = 4;
+
+
+ // PC_HWGUY.
+ pInfo = &g_TFCPlayerClassInfo[PC_HWGUY];
+ pInfo->m_pClassName = "hwguy";
+ pInfo->m_pModelName = "models/player/hvyweapon.mdl";
+ pInfo->m_flMaxSpeed = 230;
+ pInfo->m_iMaxHealth = 100;
+
+ pInfo->m_iInitArmor = 150;
+ pInfo->m_iMaxArmor = 300;
+
+ pInfo->m_flInitArmorType = 0.8;
+ pInfo->m_flMaxArmorType = 0.8;
+ pInfo->m_nArmorClasses = 31;
+ pInfo->m_iInitArmorClass = 0;
+
+ pInfo->m_iGrenadeType1 = GR_TYPE_NORMAL;
+ pInfo->m_iGrenadeType2 = GR_TYPE_MIRV;
+
+ pInfo->m_InitAmmo[TFC_AMMO_SHELLS] = 200;
+ pInfo->m_InitAmmo[TFC_AMMO_NAILS] = 0;
+ pInfo->m_InitAmmo[TFC_AMMO_ROCKETS] = 0;
+ pInfo->m_InitAmmo[TFC_AMMO_CELLS] = 30;
+ pInfo->m_InitAmmo[TFC_AMMO_MEDIKIT] = 0;
+ pInfo->m_InitAmmo[TFC_AMMO_DETPACK] = 0;
+ pInfo->m_InitAmmo[TFC_AMMO_GRENADES1] = 2;
+ pInfo->m_InitAmmo[TFC_AMMO_GRENADES2] = 1;
+
+ pInfo->m_MaxAmmo[TFC_AMMO_SHELLS] = 200;
+ pInfo->m_MaxAmmo[TFC_AMMO_NAILS] = 200;
+ pInfo->m_MaxAmmo[TFC_AMMO_ROCKETS] = 25;
+ pInfo->m_MaxAmmo[TFC_AMMO_CELLS] = 50;
+ pInfo->m_MaxAmmo[TFC_AMMO_MEDIKIT] = 0;
+ pInfo->m_MaxAmmo[TFC_AMMO_DETPACK] = 0;
+ pInfo->m_MaxAmmo[TFC_AMMO_GRENADES1] = 4;
+ pInfo->m_MaxAmmo[TFC_AMMO_GRENADES2] = 4;
+
+
+ // PC_PYRO.
+ pInfo = &g_TFCPlayerClassInfo[PC_PYRO];
+ pInfo->m_pClassName = "pyro";
+ pInfo->m_pModelName = "models/player/pyro.mdl";
+ pInfo->m_flMaxSpeed = 300;
+ pInfo->m_iMaxHealth = 100;
+
+ pInfo->m_iInitArmor = 50;
+ pInfo->m_iMaxArmor = 150;
+
+ pInfo->m_flInitArmorType = 0.6;
+ pInfo->m_flMaxArmorType = 0.6;
+ pInfo->m_nArmorClasses = 27;
+ pInfo->m_iInitArmorClass = 0;
+
+ pInfo->m_iGrenadeType1 = GR_TYPE_NORMAL;
+ pInfo->m_iGrenadeType2 = GR_TYPE_NAPALM;
+
+ pInfo->m_InitAmmo[TFC_AMMO_SHELLS] = 20;
+ pInfo->m_InitAmmo[TFC_AMMO_NAILS] = 0;
+ pInfo->m_InitAmmo[TFC_AMMO_ROCKETS] = 5;
+ pInfo->m_InitAmmo[TFC_AMMO_CELLS] = 120;
+ pInfo->m_InitAmmo[TFC_AMMO_MEDIKIT] = 0;
+ pInfo->m_InitAmmo[TFC_AMMO_DETPACK] = 0;
+ pInfo->m_InitAmmo[TFC_AMMO_GRENADES1] = 2;
+ pInfo->m_InitAmmo[TFC_AMMO_GRENADES2] = 4;
+
+ pInfo->m_MaxAmmo[TFC_AMMO_SHELLS] = 40;
+ pInfo->m_MaxAmmo[TFC_AMMO_NAILS] = 50;
+ pInfo->m_MaxAmmo[TFC_AMMO_ROCKETS] = 20;
+ pInfo->m_MaxAmmo[TFC_AMMO_CELLS] = 200;
+ pInfo->m_MaxAmmo[TFC_AMMO_MEDIKIT] = 0;
+ pInfo->m_MaxAmmo[TFC_AMMO_DETPACK] = 0;
+ pInfo->m_MaxAmmo[TFC_AMMO_GRENADES1] = 4;
+ pInfo->m_MaxAmmo[TFC_AMMO_GRENADES2] = 4;
+
+
+ // PC_SPY.
+ pInfo = &g_TFCPlayerClassInfo[PC_SPY];
+ pInfo->m_pClassName = "spy";
+ pInfo->m_pModelName = "models/player/spy.mdl";
+ pInfo->m_flMaxSpeed = 300;
+ pInfo->m_iMaxHealth = 90;
+
+ pInfo->m_iInitArmor = 25;
+ pInfo->m_iMaxArmor = 100;
+
+ pInfo->m_flInitArmorType = 0.6;
+ pInfo->m_flMaxArmorType = 0.6;
+ pInfo->m_nArmorClasses = 27;
+ pInfo->m_iInitArmorClass = 0;
+
+ pInfo->m_iGrenadeType1 = GR_TYPE_NORMAL;
+ pInfo->m_iGrenadeType2 = GR_TYPE_GAS;
+
+ pInfo->m_InitAmmo[TFC_AMMO_SHELLS] = 40;
+ pInfo->m_InitAmmo[TFC_AMMO_NAILS] = 50;
+ pInfo->m_InitAmmo[TFC_AMMO_ROCKETS] = 0;
+ pInfo->m_InitAmmo[TFC_AMMO_CELLS] = 10;
+ pInfo->m_InitAmmo[TFC_AMMO_MEDIKIT] = 0;
+ pInfo->m_InitAmmo[TFC_AMMO_DETPACK] = 0;
+ pInfo->m_InitAmmo[TFC_AMMO_GRENADES1] = 2;
+ pInfo->m_InitAmmo[TFC_AMMO_GRENADES2] = 2;
+
+ pInfo->m_MaxAmmo[TFC_AMMO_SHELLS] = 40;
+ pInfo->m_MaxAmmo[TFC_AMMO_NAILS] = 100;
+ pInfo->m_MaxAmmo[TFC_AMMO_ROCKETS] = 15;
+ pInfo->m_MaxAmmo[TFC_AMMO_CELLS] = 30;
+ pInfo->m_MaxAmmo[TFC_AMMO_MEDIKIT] = 0;
+ pInfo->m_MaxAmmo[TFC_AMMO_DETPACK] = 0;
+ pInfo->m_MaxAmmo[TFC_AMMO_GRENADES1] = 4;
+ pInfo->m_MaxAmmo[TFC_AMMO_GRENADES2] = 4;
+
+
+ // PC_ENGINEER.
+ pInfo = &g_TFCPlayerClassInfo[PC_ENGINEER];
+ pInfo->m_pClassName = "engineer";
+ pInfo->m_pModelName = "models/player/engineer.mdl";
+ pInfo->m_flMaxSpeed = 300;
+ pInfo->m_iMaxHealth = 80;
+
+ pInfo->m_iInitArmor = 25;
+ pInfo->m_iMaxArmor = 50;
+
+ pInfo->m_flInitArmorType = 0.3;
+ pInfo->m_flMaxArmorType = 0.6;
+ pInfo->m_nArmorClasses = 31;
+ pInfo->m_iInitArmorClass = 0;
+
+ pInfo->m_iGrenadeType1 = GR_TYPE_NORMAL;
+ pInfo->m_iGrenadeType2 = GR_TYPE_EMP;
+
+ pInfo->m_InitAmmo[TFC_AMMO_SHELLS] = 20;
+ pInfo->m_InitAmmo[TFC_AMMO_NAILS] = 25;
+ pInfo->m_InitAmmo[TFC_AMMO_ROCKETS] = 0;
+ pInfo->m_InitAmmo[TFC_AMMO_CELLS] = 100;
+ pInfo->m_InitAmmo[TFC_AMMO_MEDIKIT] = 0;
+ pInfo->m_InitAmmo[TFC_AMMO_DETPACK] = 0;
+ pInfo->m_InitAmmo[TFC_AMMO_GRENADES1] = 2;
+ pInfo->m_InitAmmo[TFC_AMMO_GRENADES2] = 2;
+
+ pInfo->m_MaxAmmo[TFC_AMMO_SHELLS] = 50;
+ pInfo->m_MaxAmmo[TFC_AMMO_NAILS] = 50;
+ pInfo->m_MaxAmmo[TFC_AMMO_ROCKETS] = 30;
+ pInfo->m_MaxAmmo[TFC_AMMO_CELLS] = 200;
+ pInfo->m_MaxAmmo[TFC_AMMO_MEDIKIT] = 0;
+ pInfo->m_MaxAmmo[TFC_AMMO_DETPACK] = 0;
+ pInfo->m_MaxAmmo[TFC_AMMO_GRENADES1] = 4;
+ pInfo->m_MaxAmmo[TFC_AMMO_GRENADES2] = 4;
+
+
+ // PC_CIVILIAN.
+ pInfo = &g_TFCPlayerClassInfo[PC_CIVILIAN];
+ pInfo->m_pClassName = "civilian";
+ pInfo->m_pModelName = "models/player/civilian.mdl";
+ pInfo->m_flMaxSpeed = 240;
+ pInfo->m_iMaxHealth = 50;
+
+ pInfo->m_iInitArmor = 0;
+ pInfo->m_iMaxArmor = 0;
+
+ pInfo->m_flInitArmorType = 0;
+ pInfo->m_flMaxArmorType = 0;
+ pInfo->m_nArmorClasses = 0;
+ pInfo->m_iInitArmorClass = 0;
+
+ pInfo->m_iGrenadeType1 = GR_TYPE_NONE;
+ pInfo->m_iGrenadeType2 = GR_TYPE_NONE;
+
+ pInfo->m_InitAmmo[TFC_AMMO_SHELLS] = 0;
+ pInfo->m_InitAmmo[TFC_AMMO_NAILS] = 0;
+ pInfo->m_InitAmmo[TFC_AMMO_ROCKETS] = 0;
+ pInfo->m_InitAmmo[TFC_AMMO_CELLS] = 0;
+ pInfo->m_InitAmmo[TFC_AMMO_MEDIKIT] = 0;
+ pInfo->m_InitAmmo[TFC_AMMO_DETPACK] = 0;
+ pInfo->m_InitAmmo[TFC_AMMO_GRENADES1] = 0;
+ pInfo->m_InitAmmo[TFC_AMMO_GRENADES2] = 0;
+
+ pInfo->m_MaxAmmo[TFC_AMMO_SHELLS] = 0;
+ pInfo->m_MaxAmmo[TFC_AMMO_NAILS] = 0;
+ pInfo->m_MaxAmmo[TFC_AMMO_ROCKETS] = 0;
+ pInfo->m_MaxAmmo[TFC_AMMO_CELLS] = 0;
+ pInfo->m_MaxAmmo[TFC_AMMO_MEDIKIT] = 0;
+ pInfo->m_MaxAmmo[TFC_AMMO_DETPACK] = 0;
+ pInfo->m_MaxAmmo[TFC_AMMO_GRENADES1] = 4;
+ pInfo->m_MaxAmmo[TFC_AMMO_GRENADES2] = 4;
+ }
+
+} g_ClassInfoInitializer;
+
+
+
+
+const CTFCPlayerClassInfo* GetTFCClassInfo( int iClass )
+{
+ Assert( iClass >= 0 && iClass < PC_LASTCLASS );
+ return &g_TFCPlayerClassInfo[iClass];
+}
+
diff --git a/game/shared/tfc/tfc_shareddefs.h b/game/shared/tfc/tfc_shareddefs.h
new file mode 100644
index 0000000..8eae5ec
--- /dev/null
+++ b/game/shared/tfc/tfc_shareddefs.h
@@ -0,0 +1,321 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================//
+
+#ifndef TFC_SHAREDDEFS_H
+#define TFC_SHAREDDEFS_H
+#ifdef _WIN32
+#pragma once
+#endif
+
+
+#include "shareddefs.h"
+
+
+// Using MAP_DEBUG mode?
+#ifdef MAP_DEBUG
+ #define MDEBUG(x) x
+#else
+ #define MDEBUG(x)
+#endif
+
+
+#define TFC_PLAYER_VIEW_OFFSET Vector( 0, 0, 53.5 )
+
+
+// Team IDs.
+// #define TEAM_SPECTATOR 0 // This is set in shareddefs.h
+#define TEAM_BLUE 1
+#define TEAM_RED 2
+#define TEAM_YELLOW 3
+#define TEAM_GREEN 4
+#define TEAM_MAXCOUNT 5 // update this if we ever add teams (unlikely)
+
+
+// Defines for the playerclass
+#define PC_UNDEFINED 0
+
+#define PC_SCOUT 1
+#define PC_SNIPER 2
+#define PC_SOLDIER 3
+#define PC_DEMOMAN 4
+#define PC_MEDIC 5
+#define PC_HWGUY 6
+#define PC_PYRO 7
+#define PC_SPY 8
+#define PC_ENGINEER 9
+#define PC_LAST_NORMAL_CLASS 9
+
+#define PC_CIVILIAN 10 // Civilians are a special class. They cannot
+ // be chosen by players, only enforced by maps
+#define PC_LASTCLASS 11 // Use this as the high-boundary for any loops
+ // through the playerclass.
+
+
+/*======================*/
+// Menu stuff //
+/*======================*/
+
+#define MENU_DEFAULT 1
+#define MENU_TEAM 2
+#define MENU_CLASS 3
+#define MENU_MAPBRIEFING 4
+#define MENU_INTRO 5
+#define MENU_CLASSHELP 6
+#define MENU_CLASSHELP2 7
+#define MENU_REPEATHELP 8
+
+#define MENU_SPECHELP 9
+
+
+#define MENU_SPY 12
+#define MENU_SPY_SKIN 13
+#define MENU_SPY_COLOR 14
+#define MENU_ENGINEER 15
+#define MENU_ENGINEER_FIX_DISPENSER 16
+#define MENU_ENGINEER_FIX_SENTRYGUN 17
+#define MENU_ENGINEER_FIX_MORTAR 18
+#define MENU_DISPENSER 19
+#define MENU_CLASS_CHANGE 20
+#define MENU_TEAM_CHANGE 21
+
+#define MENU_REFRESH_RATE 25
+
+#define MENU_VOICETWEAK 50
+
+
+
+// Additional classes
+// NOTE: adding them onto the Class_T's in baseentity.h is cheesy, but so is
+// having an #ifdef for each mod in baseentity.h.
+#define CLASS_TFGOAL ((Class_T)NUM_AI_CLASSES)
+#define CLASS_TFGOAL_TIMER ((Class_T)(NUM_AI_CLASSES+1))
+#define CLASS_TFGOAL_ITEM ((Class_T)(NUM_AI_CLASSES+2))
+#define CLASS_TFSPAWN ((Class_T)(NUM_AI_CLASSES+3))
+#define CLASS_MACHINE ((Class_T)(NUM_AI_CLASSES+4))
+
+
+// Building types
+#define BUILD_DISPENSER 1
+#define BUILD_SENTRYGUN 2
+#define BUILD_MORTAR 3
+#define BUILD_TELEPORTER_ENTRY 4
+#define BUILD_TELEPORTER_EXIT 5
+
+
+// Grenade types.
+enum GrenadeType_t
+{
+ GR_TYPE_NONE=0,
+ GR_TYPE_NORMAL,
+ GR_TYPE_CONCUSSION,
+ GR_TYPE_NAIL,
+ GR_TYPE_MIRV,
+ GR_TYPE_NAPALM,
+ GR_TYPE_GAS,
+ GR_TYPE_EMP,
+ GR_TYPE_CALTROP,
+ NUM_GRENADE_TYPES
+};
+
+// Max amount of each grenade each player can carry.
+// This is in addition to the player's
+extern int g_nMaxGrenades[NUM_GRENADE_TYPES];
+
+
+// These are the names of the ammo types that go in the CAmmoDefs and that the
+// weapon script files reference.
+// These directly correspond to ammo_X in the goldsrc tfc code.
+#define TFC_AMMO_DUMMY 0 // This is a dummy index, to make the CAmmoDef indices correct for the other ammo types.
+
+#define TFC_AMMO_SHELLS 1
+#define TFC_AMMO_SHELLS_NAME "TFC_AMMO_SHELLS"
+
+#define TFC_AMMO_NAILS 2
+#define TFC_AMMO_NAILS_NAME "TFC_AMMO_NAILS"
+
+#define TFC_AMMO_ROCKETS 3
+#define TFC_AMMO_ROCKETS_NAME "TFC_AMMO_ROCKETS"
+
+#define TFC_AMMO_CELLS 4
+#define TFC_AMMO_CELLS_NAME "TFC_AMMO_CELLS"
+
+#define TFC_AMMO_MEDIKIT 5
+#define TFC_AMMO_MEDIKIT_NAME "TFC_AMMO_MEDIKIT"
+
+#define TFC_AMMO_DETPACK 6
+#define TFC_AMMO_DETPACK_NAME "TFC_AMMO_DETPACK"
+
+#define TFC_AMMO_GRENADES1 7
+#define TFC_AMMO_GRENADES1_NAME "TFC_AMMO_GRENADES1"
+
+#define TFC_AMMO_GRENADES2 8
+#define TFC_AMMO_GRENADES2_NAME "TFC_AMMO_GRENADES2"
+
+#define TFC_NUM_AMMO_TYPES 9 // NOTE: KEEP THESE UP TO DATE WITH g_AmmoTypeNames[]
+extern const char* g_AmmoTypeNames[TFC_NUM_AMMO_TYPES];
+
+
+
+// TeamFortress State Flags
+#define TFSTATE_GRENPRIMED 0x000001 // Whether the player has a primed grenade
+#define TFSTATE_RELOADING 0x000002 // Whether the player is reloading
+#define TFSTATE_ALTKILL 0x000004 // #TRUE if killed with a weapon not in self.weapon: NOT USED ANYMORE
+#define TFSTATE_RANDOMPC 0x000008 // Whether Playerclass is random, new one each respawn
+#define TFSTATE_INFECTED 0x000010 // set when player is infected by the bioweapon
+#define TFSTATE_INVINCIBLE 0x000020 // Player has permanent Invincibility (Usually by GoalItem)
+#define TFSTATE_INVISIBLE 0x000040 // Player has permanent Invisibility (Usually by GoalItem)
+#define TFSTATE_QUAD 0x000080 // Player has permanent Quad Damage (Usually by GoalItem)
+#define TFSTATE_RADSUIT 0x000100 // Player has permanent Radsuit (Usually by GoalItem)
+#define TFSTATE_BURNING 0x000200 // Is on fire
+#define TFSTATE_GRENTHROWING 0x000400 // is throwing a grenade
+#define TFSTATE_AIMING 0x000800 // is using the laser sight
+#define TFSTATE_ZOOMOFF 0x001000 // doesn't want the FOV changed when zooming
+#define TFSTATE_RESPAWN_READY 0x002000 // is waiting for respawn, and has pressed fire
+#define TFSTATE_HALLUCINATING 0x004000 // set when player is hallucinating
+#define TFSTATE_TRANQUILISED 0x008000 // set when player is tranquilised
+#define TFSTATE_CANT_MOVE 0x010000 // set when player is setting a detpack
+#define TFSTATE_RESET_FLAMETIME 0x020000 // set when the player has to have his flames increased in health
+#define TFSTATE_HIGHEST_VALUE TFSTATE_RESET_FLAMETIME
+
+
+// items
+#define IT_SHOTGUN (1<<0)
+#define IT_SUPER_SHOTGUN (1<<1)
+#define IT_NAILGUN (1<<2)
+#define IT_SUPER_NAILGUN (1<<3)
+#define IT_GRENADE_LAUNCHER (1<<4)
+#define IT_ROCKET_LAUNCHER (1<<5)
+#define IT_LIGHTNING (1<<6)
+#define IT_EXTRA_WEAPON (1<<7)
+
+#define IT_SHELLS (1<<8)
+#define IT_NAILS (1<<9)
+#define IT_ROCKETS (1<<10)
+#define IT_CELLS (1<<11)
+#define IT_AXE (1<<12)
+
+#define IT_ARMOR1 (1<<13)
+#define IT_ARMOR2 (1<<14)
+#define IT_ARMOR3 (1<<15)
+#define IT_SUPERHEALTH (1<<16)
+
+#define IT_KEY1 (1<<17)
+#define IT_KEY2 (1<<18)
+
+#define IT_INVISIBILITY (1<<19)
+#define IT_INVULNERABILITY (1<<20)
+#define IT_SUIT (1<<21)
+#define IT_QUAD (1<<22)
+#define IT_HOOK (1<<23)
+
+#define IT_KEY3 (1<<24) // Stomp invisibility
+#define IT_KEY4 (1<<25) // Stomp invulnerability
+#define IT_LAST_ITEM IT_KEY4
+
+
+enum TFCTimer_t
+{
+ TF_TIMER_ANY=0,
+ TF_TIMER_CONCUSSION,
+ TF_TIMER_INFECTION,
+ TF_TIMER_HALLUCINATION,
+ TF_TIMER_TRANQUILISATION,
+ TF_TIMER_ROTHEALTH,
+ TF_TIMER_REGENERATION,
+ TF_TIMER_GRENPRIME,
+ TF_TIMER_CELLREGENERATION,
+ TF_TIMER_DETPACKSET,
+ TF_TIMER_DETPACKDISARM,
+ TF_TIMER_BUILD,
+ TF_TIMER_CHECKBUILDDISTANCE,
+ TF_TIMER_DISGUISE,
+ TF_TIMER_DISPENSERREFILL,
+
+ // Non player timers.
+ TF_TIMER_RETURNITEM,
+ TF_TIMER_DELAYEDGOAL,
+ TF_TIMER_ENDROUND
+};
+
+
+
+/*==================================================*/
+/* New Weapon Related Defines */
+/*==================================================*/
+
+// Medikit
+#define WEAP_MEDIKIT_OVERHEAL 50 // Amount of superhealth over max_health the medikit will dispense
+#define WEAP_MEDIKIT_HEAL 200 // Amount medikit heals per hit
+
+
+
+//--------------
+// TFC Specific damage flags
+//--------------
+#define DMG_IGNORE_MAXHEALTH (DMG_LASTGENERICFLAG<<1)
+#define DMG_IGNOREARMOR (DMG_LASTGENERICFLAG<<2)
+
+
+// ------------------------------------------------------------------------------ //
+// Info for each player class.
+// ------------------------------------------------------------------------------ //
+
+class CTFCPlayerClassInfo
+{
+public:
+ const char *m_pClassName;
+ const char *m_pModelName; // What model this class uses.
+
+ float m_flMaxSpeed;
+ int m_iMaxHealth;
+
+ int m_iInitArmor;
+ int m_iMaxArmor;
+ float m_flInitArmorType;
+ float m_flMaxArmorType;
+ int m_iInitArmorClass;
+ int m_nArmorClasses;
+
+ // What types of grenades does this guy carry?
+ // GR_TYPE_ defines.
+ GrenadeType_t m_iGrenadeType1;
+ GrenadeType_t m_iGrenadeType2;
+
+ int m_InitAmmo[TFC_NUM_AMMO_TYPES]; // These are in the same order as g_AmmoTypeNames.
+ int m_MaxAmmo[TFC_NUM_AMMO_TYPES]; // These are in the same order as g_AmmoTypeNames.
+};
+
+const CTFCPlayerClassInfo* GetTFCClassInfo( int iClass );
+
+
+// The various states the player can be in during the join game process.
+enum TFCPlayerState
+{
+ // Happily running around in the game.
+ // You can't move though if CSGameRules()->IsFreezePeriod() returns true.
+ // This state can jump to a bunch of other states like STATE_PICKINGCLASS or STATE_DEATH_ANIM.
+ STATE_ACTIVE=0,
+
+ // This is the state you're in when you first enter the server.
+ // It's switching between intro cameras every few seconds, and there's a level info
+ // screen up.
+ STATE_WELCOME, // Show the level intro screen.
+
+ // During these states, you can either be a new player waiting to join, or
+ // you can be a live player in the game who wants to change teams.
+ // Either way, you can't move while choosing team or class (or while any menu is up).
+ STATE_PICKINGTEAM, // Choosing team.
+ STATE_PICKINGCLASS, // Choosing class.
+
+ STATE_OBSERVER_MODE,
+
+ STATE_DYING,
+
+ TFC_NUM_PLAYER_STATES
+};
+
+
+#endif // TFC_SHAREDDEFS_H
diff --git a/game/shared/tfc/tfc_usermessages.cpp b/game/shared/tfc/tfc_usermessages.cpp
new file mode 100644
index 0000000..5722093
--- /dev/null
+++ b/game/shared/tfc/tfc_usermessages.cpp
@@ -0,0 +1,41 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================//
+
+#include "cbase.h"
+#include "usermessages.h"
+#include "shake.h"
+#include "voice_gamemgr.h"
+
+void RegisterUserMessages()
+{
+ usermessages->Register( "Geiger", 1 ); // geiger info data
+ usermessages->Register( "Train", 1 ); // train control data
+ usermessages->Register( "HudText", -1 );
+ usermessages->Register( "SayText", -1 );
+ usermessages->Register( "TextMsg", -1 );
+ usermessages->Register( "ResetHUD", 1 ); // called every respawn
+ usermessages->Register( "GameTitle", 0 ); // show game title
+ usermessages->Register( "ItemPickup", -1 ); // for item history on screen
+ usermessages->Register( "ShowMenu", -1 ); // show hud menu
+ usermessages->Register( "Shake", 13 ); // shake view
+ usermessages->Register( "Fade", 10 ); // fade HUD in/out
+ usermessages->Register( "VGUIMenu", -1 ); // Show VGUI menu
+ usermessages->Register( "CloseCaption", -1 ); // Show a caption (by string id number)(duration in 10th of a second)
+
+ usermessages->Register( "SendAudio", -1 ); // play radion command
+
+ usermessages->Register( "VoiceMask", VOICE_MAX_PLAYERS_DW*4 * 2 + 1 );
+ usermessages->Register( "RequestState", 0 );
+
+ usermessages->Register( "BarTime", -1 ); // For the C4 progress bar.
+ usermessages->Register( "Damage", -1 ); // for HUD damage indicators
+ usermessages->Register( "RadioText", -1 ); // for HUD damage indicators
+ usermessages->Register( "HintText", -1 ); // Displays hint text display
+
+ usermessages->Register( "ReloadEffect", 2 ); // a player reloading..
+ usermessages->Register( "PlayerAnimEvent", -1 ); // jumping, firing, reload, etc.
+}
+
diff --git a/game/shared/tfc/tfc_weapon_parse.cpp b/game/shared/tfc/tfc_weapon_parse.cpp
new file mode 100644
index 0000000..3f137b4
--- /dev/null
+++ b/game/shared/tfc/tfc_weapon_parse.cpp
@@ -0,0 +1,28 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================//
+
+#include "cbase.h"
+#include <KeyValues.h>
+#include "tfc_weapon_parse.h"
+
+
+FileWeaponInfo_t* CreateWeaponInfo()
+{
+ return new CTFCWeaponInfo;
+}
+
+
+CTFCWeaponInfo::CTFCWeaponInfo()
+{
+}
+
+
+void CTFCWeaponInfo::Parse( KeyValues *pKeyValuesData, const char *szWeaponName )
+{
+ BaseClass::Parse( pKeyValuesData, szWeaponName );
+}
+
+
diff --git a/game/shared/tfc/tfc_weapon_parse.h b/game/shared/tfc/tfc_weapon_parse.h
new file mode 100644
index 0000000..1b5eace
--- /dev/null
+++ b/game/shared/tfc/tfc_weapon_parse.h
@@ -0,0 +1,30 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================//
+
+#ifndef TFC_WEAPON_PARSE_H
+#define TFC_WEAPON_PARSE_H
+#ifdef _WIN32
+#pragma once
+#endif
+
+
+#include "weapon_parse.h"
+#include "networkvar.h"
+
+
+//--------------------------------------------------------------------------------------------------------
+class CTFCWeaponInfo : public FileWeaponInfo_t
+{
+public:
+ DECLARE_CLASS_GAMEROOT( CTFCWeaponInfo, FileWeaponInfo_t );
+
+ CTFCWeaponInfo();
+
+ virtual void Parse( ::KeyValues *pKeyValuesData, const char *szWeaponName );
+};
+
+
+#endif // TFC_WEAPON_PARSE_H
diff --git a/game/shared/tfc/weapon_tfc_crowbar.cpp b/game/shared/tfc/weapon_tfc_crowbar.cpp
new file mode 100644
index 0000000..acd359f
--- /dev/null
+++ b/game/shared/tfc/weapon_tfc_crowbar.cpp
@@ -0,0 +1,330 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================//
+
+#include "cbase.h"
+#include "util.h"
+#include "weapon_tfc_crowbar.h"
+#include "decals.h"
+
+#if defined( CLIENT_DLL )
+ #include "c_tfc_player.h"
+#else
+ #include "tfc_player.h"
+#endif
+
+
+#define KNIFE_BODYHIT_VOLUME 128
+#define KNIFE_WALLHIT_VOLUME 512
+
+
+static ConVar tfc_crowbar_damage_first( "tfc_crowbar_damage_first", "25", 0, "First crowbar hit damage." );
+static ConVar tfc_crowbar_damage_next( "tfc_crowbar_damage_next", "12.5", 0, "Crowbar hit damage after first hit." );
+
+
+static Vector head_hull_mins( -16, -16, -18 );
+static Vector head_hull_maxs( 16, 16, 18 );
+
+
+// ----------------------------------------------------------------------------- //
+// CTFCCrowbar tables.
+// ----------------------------------------------------------------------------- //
+
+IMPLEMENT_NETWORKCLASS_ALIASED( TFCCrowbar, DT_WeaponCrowbar )
+
+BEGIN_NETWORK_TABLE( CTFCCrowbar, DT_WeaponCrowbar )
+END_NETWORK_TABLE()
+
+BEGIN_PREDICTION_DATA( CTFCCrowbar )
+END_PREDICTION_DATA()
+
+LINK_ENTITY_TO_CLASS( weapon_crowbar, CTFCCrowbar );
+PRECACHE_WEAPON_REGISTER( weapon_crowbar );
+
+#ifndef CLIENT_DLL
+
+ BEGIN_DATADESC( CTFCCrowbar )
+ DEFINE_FUNCTION( Smack )
+ END_DATADESC()
+
+#endif
+
+// ----------------------------------------------------------------------------- //
+// CTFCCrowbar implementation.
+// ----------------------------------------------------------------------------- //
+
+CTFCCrowbar::CTFCCrowbar()
+{
+}
+
+
+bool CTFCCrowbar::HasPrimaryAmmo()
+{
+ return true;
+}
+
+
+bool CTFCCrowbar::CanBeSelected()
+{
+ return true;
+}
+
+void CTFCCrowbar::Precache()
+{
+ BaseClass::Precache();
+}
+
+void CTFCCrowbar::Spawn()
+{
+ Precache();
+
+ m_iClip1 = -1;
+ BaseClass::Spawn();
+}
+
+
+bool CTFCCrowbar::Deploy()
+{
+ CPASAttenuationFilter filter( this );
+ filter.UsePredictionRules();
+ EmitSound( filter, entindex(), "Weapon_Crowbar.Deploy" );
+
+ return BaseClass::Deploy();
+}
+
+void CTFCCrowbar::Holster( int skiplocal )
+{
+ GetPlayerOwner()->m_flNextAttack = gpGlobals->curtime + 0.5;
+}
+
+void FindHullIntersection( const Vector &vecSrc, trace_t &tr, const Vector &mins, const Vector &maxs, CBaseEntity *pEntity )
+{
+ int i, j, k;
+ float distance;
+ Vector minmaxs[2] = {mins, maxs};
+ trace_t tmpTrace;
+ Vector vecHullEnd = tr.endpos;
+ Vector vecEnd;
+
+ distance = 1e6f;
+
+ vecHullEnd = vecSrc + ((vecHullEnd - vecSrc)*2);
+ UTIL_TraceLine( vecSrc, vecHullEnd, MASK_SOLID, pEntity, COLLISION_GROUP_NONE, &tmpTrace );
+ if ( tmpTrace.fraction < 1.0 )
+ {
+ tr = tmpTrace;
+ return;
+ }
+
+ for ( i = 0; i < 2; i++ )
+ {
+ for ( j = 0; j < 2; j++ )
+ {
+ for ( k = 0; k < 2; k++ )
+ {
+ vecEnd.x = vecHullEnd.x + minmaxs[i][0];
+ vecEnd.y = vecHullEnd.y + minmaxs[j][1];
+ vecEnd.z = vecHullEnd.z + minmaxs[k][2];
+
+ UTIL_TraceLine( vecSrc, vecEnd, MASK_SOLID, pEntity, COLLISION_GROUP_NONE, &tmpTrace );
+ if ( tmpTrace.fraction < 1.0 )
+ {
+ float thisDistance = (tmpTrace.endpos - vecSrc).Length();
+ if ( thisDistance < distance )
+ {
+ tr = tmpTrace;
+ distance = thisDistance;
+ }
+ }
+ }
+ }
+ }
+}
+
+
+void CTFCCrowbar::ItemPostFrame()
+{
+ // Store this off so we can detect if it's our first swing or not later on.
+ m_flStoredPrimaryAttack = m_flNextPrimaryAttack;
+ BaseClass::ItemPostFrame();
+}
+
+
+void CTFCCrowbar::PrimaryAttack()
+{
+ CTFCPlayer *pPlayer = GetPlayerOwner();
+
+ Vector vForward;
+ AngleVectors( pPlayer->EyeAngles(), &vForward );
+ Vector vecSrc = pPlayer->Weapon_ShootPosition();
+ Vector vecEnd = vecSrc + vForward * 32;
+
+ trace_t tr;
+ UTIL_TraceLine( vecSrc, vecEnd, MASK_SOLID, pPlayer, COLLISION_GROUP_NONE, &tr );
+
+ if ( tr.fraction >= 1.0 )
+ {
+ UTIL_TraceHull( vecSrc, vecEnd, head_hull_mins, head_hull_maxs, MASK_SOLID, pPlayer, COLLISION_GROUP_NONE, &tr );
+ if ( tr.fraction < 1.0 )
+ {
+ // Calculate the point of intersection of the line (or hull) and the object we hit
+ // This is and approximation of the "best" intersection
+ CBaseEntity *pHit = tr.m_pEnt;
+ if ( !pHit || pHit->IsBSPModel() )
+ FindHullIntersection( vecSrc, tr, VEC_DUCK_HULL_MIN, VEC_DUCK_HULL_MAX, pPlayer );
+ vecEnd = tr.endpos; // This is the point on the actual surface (the hull could have hit space)
+ }
+ }
+
+ bool bDidHit = tr.fraction < 1.0f;
+
+#ifndef CLIENT_DLL
+ bool bFirstSwing = (gpGlobals->curtime - m_flStoredPrimaryAttack) >= 1;
+#endif
+
+ pPlayer->DoAnimationEvent( PLAYERANIMEVENT_FIRE_GUN );
+
+ m_flTimeWeaponIdle = gpGlobals->curtime + 2;
+ m_flNextPrimaryAttack = gpGlobals->curtime + 0.4f;
+
+ if ( bDidHit )
+ {
+ SendWeaponAnim( ACT_VM_HITCENTER );
+ }
+ else
+ {
+ // Allow for there only being hit activities.
+ if ( !SendWeaponAnim( ACT_VM_MISSCENTER ) )
+ SendWeaponAnim( ACT_VM_HITCENTER );
+
+ // play wiff or swish sound
+ WeaponSound( MELEE_MISS );
+ }
+
+ bool bPlayImpactEffect = false;
+
+#ifndef CLIENT_DLL
+
+ if ( bDidHit )
+ {
+ CBaseEntity *pEntity = tr.m_pEnt;
+
+ ClearMultiDamage();
+
+ float flDamage = 0;
+ bool bDoEffects = true;
+ AxeHit( pEntity, bFirstSwing, tr, &flDamage, &bDoEffects );
+ if ( flDamage != 0 )
+ {
+ CTakeDamageInfo info( pPlayer, pPlayer, flDamage, DMG_CLUB | DMG_NEVERGIB );
+
+ CalculateMeleeDamageForce( &info, vForward, tr.endpos, 1.0f/flDamage );
+ pEntity->DispatchTraceAttack( info, vForward, &tr );
+ ApplyMultiDamage();
+ }
+
+ if ( bDoEffects )
+ {
+ if ( pEntity && pEntity->IsPlayer() )
+ {
+ WeaponSound( MELEE_HIT );
+
+ if ( pEntity->IsAlive() )
+ bPlayImpactEffect = true; // no blood effect on dead bodies
+ }
+ else
+ {
+ bPlayImpactEffect = true; // always show impact effects on world objects
+ }
+ }
+ else
+ {
+ bDoEffects = false;
+ }
+ }
+
+
+#endif
+
+ if ( bPlayImpactEffect )
+ {
+ // delay the decal a bit
+ m_trHit = tr;
+
+ // Store the ent in an EHANDLE, just in case it goes away by the time we get into our think function.
+ m_pTraceHitEnt = tr.m_pEnt;
+
+ SetThink( &CTFCCrowbar::Smack );
+ SetNextThink( gpGlobals->curtime + 0.2f );
+ }
+}
+
+
+void CTFCCrowbar::Smack()
+{
+ m_trHit.m_pEnt = m_pTraceHitEnt;
+ UTIL_ImpactTrace( &m_trHit, DMG_CLUB );
+
+ surfacedata_t *psurf = physprops->GetSurfaceData( m_trHit.surface.surfaceProps );
+ if ( psurf->game.material != CHAR_TEX_FLESH && psurf->game.material != CHAR_TEX_BLOODYFLESH )
+ WeaponSound( MELEE_HIT_WORLD );
+}
+
+
+
+void CTFCCrowbar::WeaponIdle()
+{
+ //ResetEmptySound();
+
+ CTFCPlayer *pPlayer = GetPlayerOwner();
+
+ if (m_flTimeWeaponIdle > gpGlobals->curtime)
+ return;
+
+ m_flTimeWeaponIdle = gpGlobals->curtime + 20;
+
+ // only idle if the slid isn't back
+ SendWeaponAnim( ACT_VM_IDLE );
+}
+
+
+bool CTFCCrowbar::CanDrop()
+{
+ return false;
+}
+
+
+TFCWeaponID CTFCCrowbar::GetWeaponID( void ) const
+{
+ return WEAPON_CROWBAR;
+}
+
+
+#ifdef CLIENT_DLL
+
+ // ------------------------------------------------------------------------------------------------ //
+ // ------------------------------------------------------------------------------------------------ //
+ // CLIENT DLL SPECIFIC CODE
+ // ------------------------------------------------------------------------------------------------ //
+ // ------------------------------------------------------------------------------------------------ //
+
+
+#else
+
+ // ------------------------------------------------------------------------------------------------ //
+ // ------------------------------------------------------------------------------------------------ //
+ // GAME DLL SPECIFIC CODE
+ // ------------------------------------------------------------------------------------------------ //
+ // ------------------------------------------------------------------------------------------------ //
+
+ void CTFCCrowbar::AxeHit( CBaseEntity *pHit, bool bFirstSwing, trace_t &tr, float *flDamage, bool *bDoEffects )
+ {
+ if ( bFirstSwing )
+ *flDamage = tfc_crowbar_damage_first.GetFloat();
+ else
+ *flDamage = tfc_crowbar_damage_next.GetFloat();
+ }
+
+#endif
diff --git a/game/shared/tfc/weapon_tfc_crowbar.h b/game/shared/tfc/weapon_tfc_crowbar.h
new file mode 100644
index 0000000..561503c
--- /dev/null
+++ b/game/shared/tfc/weapon_tfc_crowbar.h
@@ -0,0 +1,88 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================//
+
+#ifndef WEAPON_TFC_CROWBAR_H
+#define WEAPON_TFC_CROWBAR_H
+#ifdef _WIN32
+#pragma once
+#endif
+
+
+#include "weapon_tfcbase.h"
+
+
+#if defined( CLIENT_DLL )
+
+ #define CTFCCrowbar C_TFCCrowbar
+
+#endif
+
+
+// ----------------------------------------------------------------------------- //
+// CTFCCrowbar class definition.
+// ----------------------------------------------------------------------------- //
+
+class CTFCCrowbar : public CWeaponTFCBase
+{
+public:
+ DECLARE_CLASS( CTFCCrowbar, CWeaponTFCBase );
+ DECLARE_NETWORKCLASS();
+ DECLARE_PREDICTABLE();
+
+ #ifndef CLIENT_DLL
+ DECLARE_DATADESC();
+ #endif
+
+
+ CTFCCrowbar();
+
+ // We say yes to this so the weapon system lets us switch to it.
+ virtual bool HasPrimaryAmmo();
+ virtual bool CanBeSelected();
+ virtual void ItemPostFrame();
+ virtual void Precache();
+
+ void Spawn();
+ void Smack();
+ void PrimaryAttack();
+
+ bool Deploy();
+ void Holster( int skiplocal = 0 );
+ bool CanDrop();
+
+ void WeaponIdle();
+
+ virtual TFCWeaponID GetWeaponID( void ) const;
+
+
+// Overrideables.
+public:
+
+#ifdef GAME_DLL
+ // This is called first to determine if the axe should apply damage to the entity.
+ virtual void AxeHit(
+ CBaseEntity *pHit,
+ bool bFirstSwing,
+ trace_t &tr,
+ float *flDamage,
+ bool *bDoEffects
+ );
+#endif
+
+
+public:
+
+ trace_t m_trHit;
+ EHANDLE m_pTraceHitEnt;
+ float m_flStoredPrimaryAttack;
+
+
+private:
+ CTFCCrowbar( const CTFCCrowbar & ) {}
+};
+
+
+#endif // WEAPON_TFC_CROWBAR_H
diff --git a/game/shared/tfc/weapon_tfc_knife.cpp b/game/shared/tfc/weapon_tfc_knife.cpp
new file mode 100644
index 0000000..96730d1
--- /dev/null
+++ b/game/shared/tfc/weapon_tfc_knife.cpp
@@ -0,0 +1,58 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================//
+
+#include "cbase.h"
+#include "util.h"
+#include "weapon_tfc_knife.h"
+
+#if defined( CLIENT_DLL )
+ #include "c_tfc_player.h"
+#else
+ #include "tfc_player.h"
+#endif
+
+
+// ----------------------------------------------------------------------------- //
+// CTFCKnife tables.
+// ----------------------------------------------------------------------------- //
+
+IMPLEMENT_NETWORKCLASS_ALIASED( TFCKnife, DT_WeaponKnife )
+
+BEGIN_NETWORK_TABLE( CTFCKnife, DT_WeaponKnife )
+END_NETWORK_TABLE()
+
+BEGIN_PREDICTION_DATA( CTFCKnife )
+END_PREDICTION_DATA()
+
+LINK_ENTITY_TO_CLASS( weapon_knife, CTFCKnife );
+PRECACHE_WEAPON_REGISTER( weapon_knife );
+
+#ifndef CLIENT_DLL
+
+ BEGIN_DATADESC( CTFCKnife )
+ END_DATADESC()
+
+#endif
+
+// ----------------------------------------------------------------------------- //
+// CTFCKnife implementation.
+// ----------------------------------------------------------------------------- //
+
+CTFCKnife::CTFCKnife()
+{
+}
+
+
+void CTFCKnife::Precache()
+{
+ BaseClass::Precache();
+}
+
+
+TFCWeaponID CTFCKnife::GetWeaponID( void ) const
+{
+ return WEAPON_KNIFE;
+}
diff --git a/game/shared/tfc/weapon_tfc_knife.h b/game/shared/tfc/weapon_tfc_knife.h
new file mode 100644
index 0000000..e0c2826
--- /dev/null
+++ b/game/shared/tfc/weapon_tfc_knife.h
@@ -0,0 +1,53 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================//
+
+#ifndef WEAPON_TFC_KNIFE_H
+#define WEAPON_TFC_KNIFE_H
+#ifdef _WIN32
+#pragma once
+#endif
+
+
+#include "weapon_tfcbase.h"
+#include "weapon_tfc_crowbar.h"
+
+
+#if defined( CLIENT_DLL )
+
+ #define CTFCKnife C_TFCKnife
+
+#endif
+
+
+// ----------------------------------------------------------------------------- //
+// CTFCKnife class definition.
+// ----------------------------------------------------------------------------- //
+
+class CTFCKnife : public CTFCCrowbar
+{
+public:
+ DECLARE_CLASS( CTFCKnife, CTFCCrowbar );
+ DECLARE_NETWORKCLASS();
+ DECLARE_PREDICTABLE();
+
+ #ifndef CLIENT_DLL
+ DECLARE_DATADESC();
+ #endif
+
+
+ CTFCKnife();
+
+ virtual void Precache();
+
+ virtual TFCWeaponID GetWeaponID( void ) const;
+
+
+private:
+ CTFCKnife( const CTFCKnife & ) {}
+};
+
+
+#endif // WEAPON_TFC_KNIFE_H
diff --git a/game/shared/tfc/weapon_tfc_medikit.cpp b/game/shared/tfc/weapon_tfc_medikit.cpp
new file mode 100644
index 0000000..39464b2
--- /dev/null
+++ b/game/shared/tfc/weapon_tfc_medikit.cpp
@@ -0,0 +1,248 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================//
+
+#include "cbase.h"
+#include "util.h"
+#include "weapon_tfc_medikit.h"
+#include "tfc_gamerules.h"
+
+#if defined( CLIENT_DLL )
+ #include "c_tfc_player.h"
+#else
+ #include "tfc_player.h"
+ #include "tfc_timer.h"
+#endif
+
+
+// ----------------------------------------------------------------------------- //
+// CTFCMedikit tables.
+// ----------------------------------------------------------------------------- //
+
+IMPLEMENT_NETWORKCLASS_ALIASED( TFCMedikit, DT_WeaponMedikit )
+
+BEGIN_NETWORK_TABLE( CTFCMedikit, DT_WeaponMedikit )
+END_NETWORK_TABLE()
+
+BEGIN_PREDICTION_DATA( CTFCMedikit )
+END_PREDICTION_DATA()
+
+LINK_ENTITY_TO_CLASS( weapon_medikit, CTFCMedikit );
+PRECACHE_WEAPON_REGISTER( weapon_medikit );
+
+#ifndef CLIENT_DLL
+
+ BEGIN_DATADESC( CTFCMedikit )
+ END_DATADESC()
+
+#endif
+
+// ----------------------------------------------------------------------------- //
+// CTFCMedikit implementation.
+// ----------------------------------------------------------------------------- //
+
+CTFCMedikit::CTFCMedikit()
+{
+}
+
+
+void CTFCMedikit::Precache()
+{
+ BaseClass::Precache();
+}
+
+
+TFCWeaponID CTFCMedikit::GetWeaponID( void ) const
+{
+ return WEAPON_MEDIKIT;
+}
+
+
+#ifdef CLIENT_DLL
+
+ // ------------------------------------------------------------------------------------------------ //
+ // ------------------------------------------------------------------------------------------------ //
+ // CLIENT DLL SPECIFIC CODE
+ // ------------------------------------------------------------------------------------------------ //
+ // ------------------------------------------------------------------------------------------------ //
+
+
+#else
+
+ // ------------------------------------------------------------------------------------------------ //
+ // ------------------------------------------------------------------------------------------------ //
+ // GAME DLL SPECIFIC CODE
+ // ------------------------------------------------------------------------------------------------ //
+ // ------------------------------------------------------------------------------------------------ //
+
+ void CTFCMedikit::AxeHit( CBaseEntity *pHit, bool bFirstSwing, trace_t &tr, float *flDamage, bool *bDoEffects )
+ {
+ *flDamage = 0;
+ *bDoEffects = false;
+
+ CTFCPlayer *pPlayer = GetPlayerOwner();
+ if ( !pPlayer )
+ return;
+
+ // We only care about players.
+ CTFCPlayer *pTarget = ToTFCPlayer( pHit );
+ if ( !pTarget )
+ return;
+
+ // If other player is dead ( just changed teams? ) don't hit
+ if ( !pTarget->IsAlive() )
+ return;
+
+ Vector vAttackDir = tr.endpos - tr.startpos;
+ VectorNormalize( vAttackDir );
+
+ // Heal if we're on the same team, Infect if not
+ if ( pPlayer->IsAlly( pTarget ) )
+ {
+ // Heal Concussion
+ CTimer *pTimer = Timer_FindTimer( pTarget, TF_TIMER_CONCUSSION );
+ if ( pTimer )
+ {
+ // Tell everyone
+ UTIL_ClientPrintAll( HUD_PRINTNOTIFY, "#Medic_cureconc", pPlayer->GetPlayerName(), pTarget->GetPlayerName() );
+
+ // Give the medic a frag if it was an enemy concussion
+ if ( pTimer->GetTeamNumber() != pPlayer->GetTeamNumber() )
+ pPlayer->TF_AddFrags(1);
+
+ Timer_Remove( pTimer );
+ }
+
+ // Heal Hallucination
+ if ( pTarget->m_Shared.GetStateFlags() & TFSTATE_HALLUCINATING )
+ {
+ pTimer = Timer_FindTimer( pTarget, TF_TIMER_HALLUCINATION );
+ ASSERT(pTimer != NULL);
+
+ // Tell everyone
+ UTIL_ClientPrintAll( HUD_PRINTNOTIFY, "#Medic_curehalluc", pPlayer->GetPlayerName(), pTarget->GetPlayerName() );
+
+ // Give the medic a frag if it was an enemy hallucination
+ if (pTimer->GetTeamNumber() != pPlayer->GetTeamNumber())
+ pPlayer->TF_AddFrags(1);
+
+ pTarget->m_Shared.RemoveStateFlags( TFSTATE_HALLUCINATING );
+ Timer_Remove( pTimer );
+ }
+
+ // Heal Tranquilisation
+ if (pTarget->m_Shared.GetStateFlags() & TFSTATE_TRANQUILISED)
+ {
+ pTimer = Timer_FindTimer( pTarget, TF_TIMER_TRANQUILISATION );
+ ASSERT(pTimer != NULL);
+
+ // Tell everyone
+ UTIL_ClientPrintAll( HUD_PRINTNOTIFY, "#Medic_curetranq", pPlayer->GetPlayerName(), pTarget->GetPlayerName() );
+
+ // Give the medic a frag if it was an enemy tranquilisation
+ if (pTimer->GetTeamNumber() != pPlayer->GetTeamNumber())
+ pPlayer->TF_AddFrags(1);
+
+ pTarget->m_Shared.RemoveStateFlags( TFSTATE_TRANQUILISED );
+ // TFCTODO: ((CBasePlayer*)pTarget)->TeamFortress_SetSpeed();
+ Timer_Remove( pTimer );
+ }
+
+ // Heal Infection
+ if (pTarget->m_Shared.GetStateFlags() & TFSTATE_INFECTED)
+ {
+ int fDmg = pTarget->GetHealth() / 2;
+ SpawnBlood(pTarget->GetAbsOrigin(), vAttackDir, pTarget->BloodColor(), fDmg);
+
+#if !defined( CLIENT_DLL )
+ pTimer = Timer_FindTimer( pTarget, TF_TIMER_INFECTION );
+ ASSERT(pTimer != NULL);
+
+ // Tell everyone
+ UTIL_ClientPrintAll( HUD_PRINTNOTIFY, "#Medic_cureinfection", pPlayer->GetPlayerName(), pTarget->GetPlayerName() );
+
+ // Give the medic a frag if it was an enemy tranquilisation
+ if ( pTimer->GetTeamNumber() != pPlayer->GetTeamNumber() )
+ pPlayer->TF_AddFrags(1);
+
+ // The operation removes half of the player's health
+ CBaseEntity *pOwner = pTimer->m_hOwner;
+ pTarget->TakeDamage( CTakeDamageInfo( this, pOwner, fDmg, DMG_IGNOREARMOR | DMG_NERVEGAS ) );
+
+ pTarget->m_Shared.RemoveStateFlags( TFSTATE_INFECTED );
+ Timer_Remove( pTimer );
+#endif
+ }
+
+ // Extinguish Flames
+ if ( pTarget->GetNumFlames() > 0 )
+ {
+ // Tell everyone
+ UTIL_ClientPrintAll( HUD_PRINTNOTIFY, "#Medic_curefire", pPlayer->GetPlayerName(), pTarget->GetPlayerName() );
+
+ pTarget->SetNumFlames( 0 );
+ //PLAYBACK_EVENT( 0, pPlayer->edict(), m_usSteamShot );
+ }
+
+ // Heal
+ if ( pTarget->GetHealth() < pTarget->GetMaxHealth() )
+ {
+ //PLAYBACK_EVENT( 0, pPlayer->edict(), m_usNormalShot );
+
+ pTarget->TakeHealth( WEAP_MEDIKIT_HEAL, DMG_GENERIC ); // Heal fully in one hit
+ }
+ else if (pTarget->GetHealth() < pTarget->GetMaxHealth() + WEAP_MEDIKIT_OVERHEAL)
+ {
+ // "Heal" over and above the player's max health
+ //PLAYBACK_EVENT( 0, pPlayer->edict(), m_usSuperShot );
+
+ pTarget->TakeHealth( 5, DMG_GENERIC | DMG_IGNORE_MAXHEALTH);
+
+ if ( !(pTarget->m_Shared.GetItemFlags() & IT_SUPERHEALTH) )
+ {
+ pTarget->m_Shared.AddItemFlags( IT_SUPERHEALTH );
+
+ #if !defined( CLIENT_DLL )
+ // Start Superhealth rot timer
+ Timer_CreateTimer( pTarget, TF_TIMER_ROTHEALTH );
+ #endif
+ }
+ }
+ }
+ else
+ {
+ Vector vecDir;
+ AngleVectors( pPlayer->EyeAngles(), &vecDir );
+
+ // Damage Target
+ ClearMultiDamage();
+ pTarget->TraceAttack( CTakeDamageInfo( pPlayer, pPlayer, 10, DMG_CLUB ), vecDir, &tr );
+ ApplyMultiDamage();
+
+ // Don't infect if the player's already infected, a medic, or we're still in prematch
+ if ( (pTarget->m_Shared.GetStateFlags() & TFSTATE_INFECTED) ||
+ (pTarget->m_Shared.GetPlayerClass() == PC_MEDIC) ||
+ TFCGameRules()->IsInPreMatch() )
+ {
+ return;
+ }
+
+ // Infect
+ pTarget->m_Shared.AddStateFlags( TFSTATE_INFECTED );
+ #if !defined( CLIENT_DLL )
+
+ // we don't want to create another timer if the player we're attacking
+ // with the medikit is currently dying ( already "killed" but still playing
+ // their death animation )
+ if ( pTarget->m_lifeState != LIFE_ALIVE )
+ return;
+
+ CTimer *pTimer = Timer_CreateTimer( pTarget, TF_TIMER_INFECTION );
+ pTimer->m_hEnemy = pPlayer;
+ #endif
+ }
+ }
+
+#endif
diff --git a/game/shared/tfc/weapon_tfc_medikit.h b/game/shared/tfc/weapon_tfc_medikit.h
new file mode 100644
index 0000000..496609b
--- /dev/null
+++ b/game/shared/tfc/weapon_tfc_medikit.h
@@ -0,0 +1,59 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================//
+
+#ifndef WEAPON_TFC_MEDIKIT_H
+#define WEAPON_TFC_MEDIKIT_H
+#ifdef _WIN32
+#pragma once
+#endif
+
+
+#include "weapon_tfcbase.h"
+#include "weapon_tfc_crowbar.h"
+
+
+#if defined( CLIENT_DLL )
+
+ #define CTFCMedikit C_TFCMedikit
+
+#endif
+
+
+// ----------------------------------------------------------------------------- //
+// CTFCMedikit class definition.
+// ----------------------------------------------------------------------------- //
+
+class CTFCMedikit : public CTFCCrowbar
+{
+public:
+ DECLARE_CLASS( CTFCMedikit, CTFCCrowbar );
+ DECLARE_NETWORKCLASS();
+ DECLARE_PREDICTABLE();
+
+ #ifndef CLIENT_DLL
+ DECLARE_DATADESC();
+ #endif
+
+
+ CTFCMedikit();
+
+ virtual void Precache();
+
+ virtual TFCWeaponID GetWeaponID( void ) const;
+
+#ifdef CLIENT_DLL
+#else
+
+ virtual void AxeHit( CBaseEntity *pHit, bool bFirstSwing, trace_t &tr, float *flDamage, bool *bDoEffects );
+
+#endif
+
+private:
+ CTFCMedikit( const CTFCMedikit & ) {}
+};
+
+
+#endif // WEAPON_TFC_MEDIKIT_H
diff --git a/game/shared/tfc/weapon_tfc_minigun.cpp b/game/shared/tfc/weapon_tfc_minigun.cpp
new file mode 100644
index 0000000..fb5015c
--- /dev/null
+++ b/game/shared/tfc/weapon_tfc_minigun.cpp
@@ -0,0 +1,282 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================//
+
+#include "cbase.h"
+#include "util.h"
+#include "weapon_tfc_minigun.h"
+#include "decals.h"
+#include "in_buttons.h"
+
+#if defined( CLIENT_DLL )
+ #include "c_tfc_player.h"
+#else
+ #include "tfc_player.h"
+#endif
+
+
+// ----------------------------------------------------------------------------- //
+// CTFCMinigun tables.
+// ----------------------------------------------------------------------------- //
+
+IMPLEMENT_NETWORKCLASS_ALIASED( TFCMinigun, DT_WeaponMinigun )
+
+BEGIN_NETWORK_TABLE( CTFCMinigun, DT_WeaponMinigun )
+END_NETWORK_TABLE()
+
+BEGIN_PREDICTION_DATA( CTFCMinigun )
+END_PREDICTION_DATA()
+
+LINK_ENTITY_TO_CLASS( weapon_minigun, CTFCMinigun );
+PRECACHE_WEAPON_REGISTER( weapon_minigun );
+
+#ifndef CLIENT_DLL
+
+ BEGIN_DATADESC( CTFCMinigun )
+ END_DATADESC()
+
+#endif
+
+// ----------------------------------------------------------------------------- //
+// CTFCMinigun implementation.
+// ----------------------------------------------------------------------------- //
+
+CTFCMinigun::CTFCMinigun()
+{
+ m_iWeaponState = AC_STATE_IDLE;
+}
+
+
+bool CTFCMinigun::HasPrimaryAmmo()
+{
+ return true;
+}
+
+
+bool CTFCMinigun::CanBeSelected()
+{
+ return true;
+}
+
+void CTFCMinigun::Precache()
+{
+ BaseClass::Precache();
+
+ PrecacheScriptSound( "Weapon_Minigun.Deploy" );
+}
+
+bool CTFCMinigun::Deploy()
+{
+ CPASAttenuationFilter filter( this );
+ filter.UsePredictionRules();
+ EmitSound( filter, entindex(), "Weapon_Minigun.Deploy" );
+
+ return BaseClass::Deploy();
+}
+
+
+TFCWeaponID CTFCMinigun::GetWeaponID( void ) const
+{
+ return WEAPON_MINIGUN;
+}
+
+
+void CTFCMinigun::WindUp( )
+{
+ CTFCPlayer *pOwner = GetPlayerOwner();
+ if ( !pOwner )
+ return;
+
+ if ( !(pOwner->m_nButtons & IN_ATTACK) )
+ return;
+
+ WeaponSound( SPECIAL1 ); // "special1" = wind up
+
+ m_iWeaponState = AC_STATE_STARTFIRING;
+ pOwner->m_Shared.AddStateFlags( TFSTATE_AIMING );
+
+ // Play the "spin down" animation.
+ SendWeaponAnim( ACT_VM_PULLBACK_HIGH );
+
+#ifdef GAME_DLL
+ pOwner->TeamFortress_SetSpeed();
+#endif
+}
+
+
+void CTFCMinigun::WindDown( bool bFromHolster )
+{
+ CTFCPlayer *pOwner = GetPlayerOwner();
+ if ( !pOwner )
+ return;
+
+ WeaponSound( SPECIAL2 );
+
+ m_iWeaponState = AC_STATE_IDLE;
+ pOwner->m_Shared.RemoveStateFlags( TFSTATE_AIMING );
+ m_flTimeWeaponIdle = gpGlobals->curtime + 2.0;
+
+ // Play the "spin down" animation.
+ SendWeaponAnim( ACT_VM_PULLBACK_LOW );
+
+#ifdef GAME_DLL
+ pOwner->TeamFortress_SetSpeed();
+#endif
+}
+
+
+void CTFCMinigun::Spin()
+{
+ CTFCPlayer *pOwner = GetPlayerOwner();
+ if ( !pOwner )
+ return;
+
+ WeaponSound( SPECIAL3 ); // "special3" = spin
+
+ pOwner->DoAnimationEvent( PLAYERANIMEVENT_FIRE_GUN );
+}
+
+
+void CTFCMinigun::Fire()
+{
+ if ( m_flNextPrimaryAttack > gpGlobals->curtime )
+ return;
+
+ CTFCPlayer *pOwner = GetPlayerOwner();
+ if ( !pOwner )
+ return;
+
+ pOwner->DoAnimationEvent( PLAYERANIMEVENT_FIRE_GUN );
+
+ BaseClass::PrimaryAttack(); // Use the base HL2 system to fire.
+}
+
+
+void CTFCMinigun::StartSpin()
+{
+ CTFCPlayer *pOwner = GetPlayerOwner();
+ if ( !pOwner )
+ return;
+
+ WeaponSound( SPECIAL1 ); // "special1" = wind up
+
+ // Rotate barrel without firing for fun
+ m_iWeaponState = AC_STATE_SPINNING;
+
+ pOwner->DoAnimationEvent( PLAYERANIMEVENT_FIRE_GUN );
+}
+
+
+void CTFCMinigun::PrimaryAttack()
+{
+ CTFCPlayer *pOwner = GetPlayerOwner();
+ if ( !pOwner )
+ return;
+
+ switch ( m_iWeaponState )
+ {
+ default:
+ case AC_STATE_IDLE:
+ // Removed the need for cells to powerup the AC
+ WindUp();
+ m_flNextPrimaryAttack = gpGlobals->curtime + 0.5;
+ m_flTimeWeaponIdle = gpGlobals->curtime + 0.6;
+ break;
+
+ case AC_STATE_STARTFIRING:
+ // Start playing the looping fire sound
+ if ( m_flNextPrimaryAttack <= gpGlobals->curtime )
+ {
+ WeaponSound( SINGLE ); // "single" = the looping fire sound
+ m_iWeaponState = AC_STATE_FIRING;
+ m_flNextPrimaryAttack = m_flTimeWeaponIdle = gpGlobals->curtime + 0.1;
+ }
+ break;
+
+ case AC_STATE_FIRING:
+ Fire();
+ m_flNextPrimaryAttack = m_flTimeWeaponIdle = gpGlobals->curtime + 0.1;
+ break;
+ }
+}
+
+
+void CTFCMinigun::HandleFireOnEmpty()
+{
+ if ( m_iWeaponState == AC_STATE_FIRING )
+ {
+ StartSpin();
+ m_flNextPrimaryAttack = m_flTimeWeaponIdle = gpGlobals->curtime + 0.1;
+ }
+ else if ( m_iWeaponState == AC_STATE_SPINNING )
+ {
+ if ( HasPrimaryAmmo() )
+ Spin();
+ else
+ m_iWeaponState = AC_STATE_STARTFIRING;
+
+ m_flNextPrimaryAttack = m_flTimeWeaponIdle = gpGlobals->curtime + 0.1;
+ }
+ else
+ {
+ BaseClass::HandleFireOnEmpty();
+ }
+}
+
+
+void CTFCMinigun::WeaponIdle()
+{
+ //ResetEmptySound( );
+
+ if ( gpGlobals->curtime < m_flTimeWeaponIdle )
+ return;
+
+ // Always wind down if we've hit here, because it only happens when the player has stopped firing/spinning
+ if ( m_iWeaponState != AC_STATE_IDLE )// && !(m_pPlayer->pev->button & IN_ATTACK) )
+ {
+ WindDown( FALSE );
+ return;
+ }
+
+ SendWeaponAnim( ACT_IDLE );
+
+ m_flTimeWeaponIdle = gpGlobals->curtime + 12.5;// how long till we do this again.
+}
+
+
+bool CTFCMinigun::SendWeaponAnim( int iActivity )
+{
+ if ( GetActivity() == ACT_VM_PRIMARYATTACK && iActivity == ACT_VM_PRIMARYATTACK )
+ {
+ // The minigun's fire animation loops, so we don't want it to reset each time
+ // they fire a bullet.
+ return true;
+ }
+ else
+ {
+ return BaseClass::SendWeaponAnim( iActivity );
+ }
+}
+
+
+
+#ifdef CLIENT_DLL
+
+ // ------------------------------------------------------------------------------------------------ //
+ // ------------------------------------------------------------------------------------------------ //
+ // CLIENT DLL SPECIFIC CODE
+ // ------------------------------------------------------------------------------------------------ //
+ // ------------------------------------------------------------------------------------------------ //
+
+
+#else
+
+ // ------------------------------------------------------------------------------------------------ //
+ // ------------------------------------------------------------------------------------------------ //
+ // GAME DLL SPECIFIC CODE
+ // ------------------------------------------------------------------------------------------------ //
+ // ------------------------------------------------------------------------------------------------ //
+
+#endif
diff --git a/game/shared/tfc/weapon_tfc_minigun.h b/game/shared/tfc/weapon_tfc_minigun.h
new file mode 100644
index 0000000..cead9d2
--- /dev/null
+++ b/game/shared/tfc/weapon_tfc_minigun.h
@@ -0,0 +1,84 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================//
+
+#ifndef WEAPON_TFC_MINIGUN_H
+#define WEAPON_TFC_MINIGUN_H
+#ifdef _WIN32
+#pragma once
+#endif
+
+
+#include "weapon_tfcbase.h"
+
+
+#if defined( CLIENT_DLL )
+
+ #define CTFCMinigun C_TFCMinigun
+
+#endif
+
+
+enum MinigunState_t
+{
+// assault cannon firing states
+ AC_STATE_IDLE=0,
+ AC_STATE_STARTFIRING,
+ AC_STATE_FIRING,
+ AC_STATE_SPINNING
+};
+
+// ----------------------------------------------------------------------------- //
+// CTFCMinigun class definition.
+// ----------------------------------------------------------------------------- //
+
+class CTFCMinigun : public CWeaponTFCBase
+{
+public:
+ DECLARE_CLASS( CTFCMinigun, CWeaponTFCBase );
+ DECLARE_NETWORKCLASS();
+ DECLARE_PREDICTABLE();
+
+ #ifndef CLIENT_DLL
+ DECLARE_DATADESC();
+ #endif
+
+
+ CTFCMinigun();
+
+ // We say yes to this so the weapon system lets us switch to it.
+ virtual bool HasPrimaryAmmo();
+ virtual bool CanBeSelected();
+ virtual void Precache();
+ virtual void PrimaryAttack();
+ virtual void WeaponIdle();
+ virtual bool Deploy();
+ virtual bool SendWeaponAnim( int iActivity );
+ virtual void HandleFireOnEmpty();
+
+ virtual TFCWeaponID GetWeaponID( void ) const;
+
+
+// Overrideables.
+public:
+
+private:
+
+ CTFCMinigun( const CTFCMinigun & ) {}
+
+ void WindUp();
+ void Spin();
+ void Fire();
+ void StartSpin();
+ void WindDown( bool bFromHolster );
+
+
+private:
+
+ MinigunState_t m_iWeaponState;
+};
+
+
+#endif // WEAPON_TFC_MINIGUN_H
diff --git a/game/shared/tfc/weapon_tfc_nailgun.cpp b/game/shared/tfc/weapon_tfc_nailgun.cpp
new file mode 100644
index 0000000..9b249b8
--- /dev/null
+++ b/game/shared/tfc/weapon_tfc_nailgun.cpp
@@ -0,0 +1,114 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================//
+
+#include "cbase.h"
+#include "util.h"
+#include "weapon_tfc_nailgun.h"
+#include "decals.h"
+#include "in_buttons.h"
+#include "nailgun_nail.h"
+
+#if defined( CLIENT_DLL )
+ #include "c_tfc_player.h"
+#else
+ #include "tfc_player.h"
+#endif
+
+
+// ----------------------------------------------------------------------------- //
+// CTFCNailgun tables.
+// ----------------------------------------------------------------------------- //
+
+IMPLEMENT_NETWORKCLASS_ALIASED( TFCNailgun, DT_WeaponNailgun )
+
+BEGIN_NETWORK_TABLE( CTFCNailgun, DT_WeaponNailgun )
+END_NETWORK_TABLE()
+
+BEGIN_PREDICTION_DATA( CTFCNailgun )
+END_PREDICTION_DATA()
+
+LINK_ENTITY_TO_CLASS( weapon_nailgun, CTFCNailgun );
+PRECACHE_WEAPON_REGISTER( weapon_nailgun );
+
+#ifndef CLIENT_DLL
+
+ BEGIN_DATADESC( CTFCNailgun )
+ END_DATADESC()
+
+#endif
+
+// ----------------------------------------------------------------------------- //
+// CTFCNailgun implementation.
+// ----------------------------------------------------------------------------- //
+
+CTFCNailgun::CTFCNailgun()
+{
+}
+
+
+TFCWeaponID CTFCNailgun::GetWeaponID() const
+{
+ return WEAPON_NAILGUN;
+}
+
+
+void CTFCNailgun::PrimaryAttack()
+{
+ CTFCPlayer *pOwner = GetPlayerOwner();
+ if ( !pOwner )
+ return;
+
+ Assert( HasPrimaryAmmo() );
+
+ WeaponSound( SINGLE );
+ SendWeaponAnim( ACT_VM_PRIMARYATTACK );
+ pOwner->DoAnimationEvent( PLAYERANIMEVENT_FIRE_GUN );
+
+ // Fire the nail
+#ifdef GAME_DLL
+ Vector vecSrc = pOwner->Weapon_ShootPosition();
+ CTFNailgunNail *pNail = CTFNailgunNail::CreateNail(
+ false,
+ vecSrc,
+ pOwner->EyeAngles(),
+ pOwner,
+ this,
+ true );
+ pNail=pNail; // avoid compiler warning..
+#endif
+
+ pOwner->RemoveAmmo( 1, GetPrimaryAmmoType() );
+
+ // Setup fire delays
+ m_flNextPrimaryAttack = gpGlobals->curtime + 0.1;
+ m_flTimeWeaponIdle = gpGlobals->curtime + 10;
+}
+
+
+void CTFCNailgun::SecondaryAttack()
+{
+ return;
+}
+
+
+#ifdef CLIENT_DLL
+
+ // ------------------------------------------------------------------------------------------------ //
+ // ------------------------------------------------------------------------------------------------ //
+ // CLIENT DLL SPECIFIC CODE
+ // ------------------------------------------------------------------------------------------------ //
+ // ------------------------------------------------------------------------------------------------ //
+
+
+#else
+
+ // ------------------------------------------------------------------------------------------------ //
+ // ------------------------------------------------------------------------------------------------ //
+ // GAME DLL SPECIFIC CODE
+ // ------------------------------------------------------------------------------------------------ //
+ // ------------------------------------------------------------------------------------------------ //
+
+#endif
diff --git a/game/shared/tfc/weapon_tfc_nailgun.h b/game/shared/tfc/weapon_tfc_nailgun.h
new file mode 100644
index 0000000..d024bff
--- /dev/null
+++ b/game/shared/tfc/weapon_tfc_nailgun.h
@@ -0,0 +1,57 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================//
+
+#ifndef WEAPON_TFC_NAILGUN_H
+#define WEAPON_TFC_NAILGUN_H
+#ifdef _WIN32
+#pragma once
+#endif
+
+
+#include "weapon_tfc_shotgun.h"
+
+
+#if defined( CLIENT_DLL )
+
+ #define CTFCNailgun C_TFCNailgun
+
+#endif
+
+
+// ----------------------------------------------------------------------------- //
+// CTFCNailgun class definition.
+// ----------------------------------------------------------------------------- //
+
+class CTFCNailgun : public CWeaponTFCBase
+{
+public:
+ DECLARE_CLASS( CTFCNailgun, CWeaponTFCBase );
+ DECLARE_NETWORKCLASS();
+ DECLARE_PREDICTABLE();
+
+ #ifndef CLIENT_DLL
+ DECLARE_DATADESC();
+ #endif
+
+
+ CTFCNailgun();
+
+ virtual TFCWeaponID GetWeaponID( void ) const;
+ virtual void PrimaryAttack();
+ virtual void SecondaryAttack();
+
+
+// Overrideables.
+public:
+
+private:
+
+ CTFCNailgun( const CTFCNailgun & ) {}
+
+};
+
+
+#endif // WEAPON_TFC_NAILGUN_H
diff --git a/game/shared/tfc/weapon_tfc_shotgun.cpp b/game/shared/tfc/weapon_tfc_shotgun.cpp
new file mode 100644
index 0000000..41f1caa
--- /dev/null
+++ b/game/shared/tfc/weapon_tfc_shotgun.cpp
@@ -0,0 +1,232 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================//
+
+#include "cbase.h"
+#include "util.h"
+#include "weapon_tfc_shotgun.h"
+#include "decals.h"
+#include "in_buttons.h"
+
+#if defined( CLIENT_DLL )
+ #include "c_tfc_player.h"
+#else
+ #include "tfc_player.h"
+#endif
+
+
+#define RE_SHOTGUN_TIME 2
+
+
+// ----------------------------------------------------------------------------- //
+// CTFCShotgun tables.
+// ----------------------------------------------------------------------------- //
+
+IMPLEMENT_NETWORKCLASS_ALIASED( TFCShotgun, DT_WeaponShotgun )
+
+BEGIN_NETWORK_TABLE( CTFCShotgun, DT_WeaponShotgun )
+END_NETWORK_TABLE()
+
+BEGIN_PREDICTION_DATA( CTFCShotgun )
+END_PREDICTION_DATA()
+
+LINK_ENTITY_TO_CLASS( weapon_shotgun, CTFCShotgun );
+PRECACHE_WEAPON_REGISTER( weapon_shotgun );
+
+#ifndef CLIENT_DLL
+
+ BEGIN_DATADESC( CTFCShotgun )
+ END_DATADESC()
+
+#endif
+
+// ----------------------------------------------------------------------------- //
+// CTFCShotgun implementation.
+// ----------------------------------------------------------------------------- //
+
+CTFCShotgun::CTFCShotgun()
+{
+ m_fReloadTime = 0.25; // Time to insert an individual shell
+ m_iShellsReloaded = 1; // Number of shells inserted each reload
+ m_flPumpTime = -1;
+ m_fInSpecialReload = 0;
+ m_flNextReload = -1;
+}
+
+
+TFCWeaponID CTFCShotgun::GetWeaponID() const
+{
+ return WEAPON_SHOTGUN;
+}
+
+
+void CTFCShotgun::PrimaryAttack()
+{
+ CTFCPlayer *pOwner = GetPlayerOwner();
+ if ( !pOwner )
+ return;
+
+ Assert( Clip1() != 0 );
+
+ WeaponSound( SINGLE );
+ SendWeaponAnim( ACT_VM_PRIMARYATTACK );
+ pOwner->DoAnimationEvent( PLAYERANIMEVENT_FIRE_GUN );
+
+ // Shoot!
+ FireBulletsInfo_t info;
+ info.m_vecSrc = pOwner->Weapon_ShootPosition();
+ info.m_vecDirShooting = pOwner->GetAutoaimVector( AUTOAIM_5DEGREES );
+ info.m_iShots = 6;
+ info.m_flDistance = 2048;
+ info.m_iAmmoType = GetPrimaryAmmoType();
+ info.m_vecSpread = VECTOR_CONE_TF_SHOTGUN;
+ info.m_iTracerFreq = 0;
+ info.m_flDamage = 4;
+ pOwner->FireBullets( info );
+
+ m_flTimeWeaponIdle = gpGlobals->curtime + 5.0;
+ m_fInSpecialReload = 0;
+
+ pOwner->m_Shared.RemoveStateFlags( TFSTATE_RELOADING );
+
+ // Setup fire delays
+ m_iClip1 -= 1;
+ if ( Clip1() != 0 )
+ m_flPumpTime = gpGlobals->curtime + 0.5;
+
+ m_flNextPrimaryAttack = gpGlobals->curtime + 0.5;
+}
+
+
+void CTFCShotgun::SecondaryAttack()
+{
+ return;
+}
+
+
+bool CTFCShotgun::Reload()
+{
+ CTFCPlayer *pOwner = GetPlayerOwner();
+ if ( !pOwner )
+ return false;
+
+ if ( pOwner->GetAmmoCount( GetPrimaryAmmoType() ) < m_iShellsReloaded || Clip1() == GetMaxClip1() )
+ {
+ return false;
+ }
+
+ if (gpGlobals->curtime < m_flNextReload)
+ {
+ return false;
+ }
+
+ // don't reload until recoil is done
+ if (gpGlobals->curtime < m_flNextPrimaryAttack)
+ {
+ return false;
+ }
+
+ // check to see if we're ready to reload
+ if (m_fInSpecialReload == 0)
+ {
+ SendWeaponAnim( ACT_VM_PULLBACK ); // (ie: start reload)
+ pOwner->m_Shared.AddStateFlags( TFSTATE_RELOADING );
+ m_fInSpecialReload = 1;
+ m_flTimeWeaponIdle = gpGlobals->curtime + 0.1; // 0.6;
+ m_flNextPrimaryAttack = gpGlobals->curtime + 0.1; // 1.0;
+ }
+ else if (m_fInSpecialReload == 1)
+ {
+ if ( m_flTimeWeaponIdle > gpGlobals->curtime )
+ {
+ return false;
+ }
+ // was waiting for gun to move to side
+ m_fInSpecialReload = 2;
+
+ SendWeaponAnim( ACT_VM_RELOAD );
+ WeaponSound( RELOAD );
+
+ m_flNextReload = gpGlobals->curtime + m_fReloadTime; //0.5;
+ m_flTimeWeaponIdle = gpGlobals->curtime + m_fReloadTime; //0.5;
+ }
+ else
+ {
+ // Add them to the clip
+ m_iClip1 += m_iShellsReloaded;
+ pOwner->RemoveAmmo( m_iShellsReloaded, GetPrimaryAmmoType() );
+
+ m_fInSpecialReload = 1;
+ pOwner->m_Shared.RemoveStateFlags( TFSTATE_RELOADING );
+ }
+
+ return true;
+}
+
+
+void CTFCShotgun::WeaponIdle()
+{
+ CTFCPlayer *pOwner = GetPlayerOwner();
+ if ( !pOwner )
+ return;
+
+ // After firing, pump the shotgun.
+ if ( m_flPumpTime != -1 && gpGlobals->curtime >= m_flPumpTime )
+ {
+ SendWeaponAnim( ACT_VM_PULLBACK_HIGH );
+ WeaponSound( SPECIAL1 ); // Pump sound.
+
+ m_flPumpTime = -1;
+ }
+
+ if ( gpGlobals->curtime > m_flTimeWeaponIdle)
+ {
+ if (Clip1() == 0 && m_fInSpecialReload == 0 && pOwner->GetAmmoCount( GetPrimaryAmmoType() ) >= m_iShellsReloaded)
+ {
+ Reload( );
+ }
+ else if (m_fInSpecialReload != 0)
+ {
+ if (Clip1() != GetMaxClip1() && pOwner->GetAmmoCount( GetPrimaryAmmoType() ) >= m_iShellsReloaded)
+ {
+ Reload( );
+ }
+ else
+ {
+ // play pumping sound
+ SendWeaponAnim( ACT_VM_PULLBACK_HIGH );
+ WeaponSound( SPECIAL1 ); // Pump sound.
+
+ m_fInSpecialReload = 0;
+ m_flTimeWeaponIdle = gpGlobals->curtime + 1.5;
+ }
+ }
+ else
+ {
+ SendWeaponAnim( ACT_VM_IDLE );
+ m_flTimeWeaponIdle = gpGlobals->curtime + GetViewModelSequenceDuration();
+ }
+ }
+}
+
+
+#ifdef CLIENT_DLL
+
+ // ------------------------------------------------------------------------------------------------ //
+ // ------------------------------------------------------------------------------------------------ //
+ // CLIENT DLL SPECIFIC CODE
+ // ------------------------------------------------------------------------------------------------ //
+ // ------------------------------------------------------------------------------------------------ //
+
+
+#else
+
+ // ------------------------------------------------------------------------------------------------ //
+ // ------------------------------------------------------------------------------------------------ //
+ // GAME DLL SPECIFIC CODE
+ // ------------------------------------------------------------------------------------------------ //
+ // ------------------------------------------------------------------------------------------------ //
+
+#endif
diff --git a/game/shared/tfc/weapon_tfc_shotgun.h b/game/shared/tfc/weapon_tfc_shotgun.h
new file mode 100644
index 0000000..d64ae17
--- /dev/null
+++ b/game/shared/tfc/weapon_tfc_shotgun.h
@@ -0,0 +1,68 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================//
+
+#ifndef WEAPON_TFC_SHOTGUN_H
+#define WEAPON_TFC_SHOTGUN_H
+#ifdef _WIN32
+#pragma once
+#endif
+
+
+#include "weapon_tfcbase.h"
+
+
+#if defined( CLIENT_DLL )
+
+ #define CTFCShotgun C_TFCShotgun
+
+#endif
+
+
+#define VECTOR_CONE_TF_SHOTGUN Vector( 0.04, 0.04, 0.00 )
+
+
+// ----------------------------------------------------------------------------- //
+// CTFCShotgun class definition.
+// ----------------------------------------------------------------------------- //
+
+class CTFCShotgun : public CWeaponTFCBase
+{
+public:
+ DECLARE_CLASS( CTFCShotgun, CWeaponTFCBase );
+ DECLARE_NETWORKCLASS();
+ DECLARE_PREDICTABLE();
+
+ #ifndef CLIENT_DLL
+ DECLARE_DATADESC();
+ #endif
+
+
+ CTFCShotgun();
+
+ virtual TFCWeaponID GetWeaponID( void ) const;
+
+ virtual void PrimaryAttack();
+ virtual void SecondaryAttack();
+ virtual bool Reload();
+ virtual void WeaponIdle();
+
+
+protected:
+
+ int m_iShellsReloaded;
+ float m_flPumpTime;
+ float m_fReloadTime;
+ int m_fInSpecialReload;
+ float m_flNextReload;
+
+
+private:
+
+ CTFCShotgun( const CTFCShotgun & ) {}
+};
+
+
+#endif // WEAPON_TFC_SHOTGUN_H
diff --git a/game/shared/tfc/weapon_tfc_spanner.cpp b/game/shared/tfc/weapon_tfc_spanner.cpp
new file mode 100644
index 0000000..c03da78
--- /dev/null
+++ b/game/shared/tfc/weapon_tfc_spanner.cpp
@@ -0,0 +1,114 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================//
+
+#include "cbase.h"
+#include "util.h"
+#include "weapon_tfc_spanner.h"
+
+#if defined( CLIENT_DLL )
+ #include "c_tfc_player.h"
+#else
+ #include "tfc_player.h"
+#endif
+
+
+#define KNIFE_BODYHIT_VOLUME 128
+#define KNIFE_WALLHIT_VOLUME 512
+
+
+static ConVar tfc_spanner_damage_first( "tfc_spanner_damage_first", "25", 0, "First spanner hit damage." );
+static ConVar tfc_spanner_damage_next( "tfc_spanner_damage_next", "12.5", 0, "Spanner hit damage after first hit." );
+
+
+static Vector head_hull_mins( -16, -16, -18 );
+static Vector head_hull_maxs( 16, 16, 18 );
+
+
+// ----------------------------------------------------------------------------- //
+// CTFCSpanner tables.
+// ----------------------------------------------------------------------------- //
+
+IMPLEMENT_NETWORKCLASS_ALIASED( TFCSpanner, DT_WeaponSpanner )
+
+BEGIN_NETWORK_TABLE( CTFCSpanner, DT_WeaponSpanner )
+END_NETWORK_TABLE()
+
+BEGIN_PREDICTION_DATA( CTFCSpanner )
+END_PREDICTION_DATA()
+
+LINK_ENTITY_TO_CLASS( weapon_spanner, CTFCSpanner );
+PRECACHE_WEAPON_REGISTER( weapon_spanner );
+
+#ifndef CLIENT_DLL
+
+ BEGIN_DATADESC( CTFCSpanner )
+ DEFINE_FUNCTION( Smack )
+ END_DATADESC()
+
+#endif
+
+// ----------------------------------------------------------------------------- //
+// CTFCSpanner implementation.
+// ----------------------------------------------------------------------------- //
+
+CTFCSpanner::CTFCSpanner()
+{
+}
+
+
+void CTFCSpanner::Precache()
+{
+ BaseClass::Precache();
+
+ PrecacheScriptSound( "Weapon_Spanner.Slash" );
+ PrecacheScriptSound( "Weapon_Spanner.HitFlesh" );
+}
+
+
+TFCWeaponID CTFCSpanner::GetWeaponID( void ) const
+{
+ return WEAPON_SPANNER;
+}
+
+
+#ifdef CLIENT_DLL
+
+ // ------------------------------------------------------------------------------------------------ //
+ // ------------------------------------------------------------------------------------------------ //
+ // CLIENT DLL SPECIFIC CODE
+ // ------------------------------------------------------------------------------------------------ //
+ // ------------------------------------------------------------------------------------------------ //
+
+
+#else
+
+ // ------------------------------------------------------------------------------------------------ //
+ // ------------------------------------------------------------------------------------------------ //
+ // GAME DLL SPECIFIC CODE
+ // ------------------------------------------------------------------------------------------------ //
+ // ------------------------------------------------------------------------------------------------ //
+
+ void CTFCSpanner::AxeHit( CBaseEntity *pTarget, bool bFirstSwing, trace_t &tr, float *flDamage, bool *bDoEffects )
+ {
+ CTFCPlayer *pPlayer = GetPlayerOwner();
+ if ( !pPlayer )
+ return;
+
+ // Check to see if it's a trigger that's activatable by a Spanner hit
+
+ // If it's not on our team, whack it.
+ if ( !pPlayer->IsAlly( pTarget ) )
+ {
+ *flDamage = 20;
+ return;
+ }
+
+ // Otherwise, the Engineer can repair his buildings or repair his teammate's armor.
+ variant_t voidVariant;
+ *bDoEffects = pTarget->AcceptInput( "EngineerUse", pPlayer, this, voidVariant, 0 );
+ }
+
+#endif
diff --git a/game/shared/tfc/weapon_tfc_spanner.h b/game/shared/tfc/weapon_tfc_spanner.h
new file mode 100644
index 0000000..041178e
--- /dev/null
+++ b/game/shared/tfc/weapon_tfc_spanner.h
@@ -0,0 +1,63 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================//
+
+#ifndef WEAPON_TFC_SPANNER_H
+#define WEAPON_TFC_SPANNER_H
+#ifdef _WIN32
+#pragma once
+#endif
+
+
+#include "weapon_tfcbase.h"
+#include "weapon_tfc_crowbar.h"
+
+
+#if defined( CLIENT_DLL )
+
+ #define CTFCSpanner C_TFCSpanner
+
+#endif
+
+
+// ----------------------------------------------------------------------------- //
+// CTFCSpanner class definition.
+// ----------------------------------------------------------------------------- //
+
+class CTFCSpanner : public CTFCCrowbar
+{
+public:
+ DECLARE_CLASS( CTFCSpanner, CTFCCrowbar );
+ DECLARE_NETWORKCLASS();
+ DECLARE_PREDICTABLE();
+
+ #ifndef CLIENT_DLL
+ DECLARE_DATADESC();
+ #endif
+
+
+public:
+
+ CTFCSpanner();
+
+ virtual void Precache();
+ virtual TFCWeaponID GetWeaponID( void ) const;
+
+
+// CTFCCrowbar overrides.
+public:
+
+#ifdef GAME_DLL
+ virtual void AxeHit( CBaseEntity *pHit, bool bFirstSwing, trace_t &tr, float *flDamage, bool *bDoEffects );
+#endif
+
+
+private:
+
+ CTFCSpanner( const CTFCSpanner & ) {}
+};
+
+
+#endif // WEAPON_TFC_SPANNER_H
diff --git a/game/shared/tfc/weapon_tfc_super_nailgun.cpp b/game/shared/tfc/weapon_tfc_super_nailgun.cpp
new file mode 100644
index 0000000..2060798
--- /dev/null
+++ b/game/shared/tfc/weapon_tfc_super_nailgun.cpp
@@ -0,0 +1,109 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================//
+
+#include "cbase.h"
+#include "util.h"
+#include "weapon_tfc_super_nailgun.h"
+#include "decals.h"
+#include "in_buttons.h"
+#include "nailgun_nail.h"
+
+#if defined( CLIENT_DLL )
+ #include "c_tfc_player.h"
+#else
+ #include "tfc_player.h"
+#endif
+
+
+// ----------------------------------------------------------------------------- //
+// CTFCSuperNailgun tables.
+// ----------------------------------------------------------------------------- //
+
+IMPLEMENT_NETWORKCLASS_ALIASED( TFCSuperNailgun, DT_WeaponSuperNailgun )
+
+BEGIN_NETWORK_TABLE( CTFCSuperNailgun, DT_WeaponSuperNailgun )
+END_NETWORK_TABLE()
+
+BEGIN_PREDICTION_DATA( CTFCSuperNailgun )
+END_PREDICTION_DATA()
+
+LINK_ENTITY_TO_CLASS( weapon_super_nailgun, CTFCSuperNailgun );
+PRECACHE_WEAPON_REGISTER( weapon_super_nailgun );
+
+#ifndef CLIENT_DLL
+
+ BEGIN_DATADESC( CTFCSuperNailgun )
+ END_DATADESC()
+
+#endif
+
+// ----------------------------------------------------------------------------- //
+// CTFCSuperNailgun implementation.
+// ----------------------------------------------------------------------------- //
+
+CTFCSuperNailgun::CTFCSuperNailgun()
+{
+}
+
+
+TFCWeaponID CTFCSuperNailgun::GetWeaponID() const
+{
+ return WEAPON_SUPER_NAILGUN;
+}
+
+
+void CTFCSuperNailgun::PrimaryAttack()
+{
+ CTFCPlayer *pOwner = GetPlayerOwner();
+ if ( !pOwner )
+ return;
+
+ Assert( HasPrimaryAmmo() );
+
+ // Effects.
+ WeaponSound( SINGLE );
+ SendWeaponAnim( ACT_VM_PRIMARYATTACK );
+ pOwner->DoAnimationEvent( PLAYERANIMEVENT_FIRE_GUN );
+
+ // Create the nail.
+ int iCurrentAmmoCount = pOwner->GetAmmoCount( GetPrimaryAmmoType() );
+
+#ifdef GAME_DLL // TFCTODO: predict this
+ Vector vecSrc = pOwner->Weapon_ShootPosition();
+ CTFNailgunNail *pNail = NULL;
+ if ( iCurrentAmmoCount < 4 )
+ pNail = CTFNailgunNail::CreateNail( false, vecSrc, pOwner->EyeAngles(), pOwner, this, true );
+ else
+ pNail = CTFNailgunNail::CreateSuperNail( vecSrc, pOwner->EyeAngles(), pOwner, this );
+#endif
+
+ // Uses 2 nails if it can
+ pOwner->RemoveAmmo( MIN( 2, iCurrentAmmoCount ), GetPrimaryAmmoType() );
+
+ // Setup fire delays
+ m_flNextPrimaryAttack = gpGlobals->curtime + 0.1;
+ m_flTimeWeaponIdle = gpGlobals->curtime + 10;
+}
+
+
+#ifdef CLIENT_DLL
+
+ // ------------------------------------------------------------------------------------------------ //
+ // ------------------------------------------------------------------------------------------------ //
+ // CLIENT DLL SPECIFIC CODE
+ // ------------------------------------------------------------------------------------------------ //
+ // ------------------------------------------------------------------------------------------------ //
+
+
+#else
+
+ // ------------------------------------------------------------------------------------------------ //
+ // ------------------------------------------------------------------------------------------------ //
+ // GAME DLL SPECIFIC CODE
+ // ------------------------------------------------------------------------------------------------ //
+ // ------------------------------------------------------------------------------------------------ //
+
+#endif
diff --git a/game/shared/tfc/weapon_tfc_super_nailgun.h b/game/shared/tfc/weapon_tfc_super_nailgun.h
new file mode 100644
index 0000000..936c66a
--- /dev/null
+++ b/game/shared/tfc/weapon_tfc_super_nailgun.h
@@ -0,0 +1,56 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================//
+
+#ifndef WEAPON_TFC_SUPER_NAILGUN_H
+#define WEAPON_TFC_SUPER_NAILGUN_H
+#ifdef _WIN32
+#pragma once
+#endif
+
+
+#include "weapon_tfc_nailgun.h"
+
+
+#if defined( CLIENT_DLL )
+
+ #define CTFCSuperNailgun C_TFCSuperNailgun
+
+#endif
+
+
+// ----------------------------------------------------------------------------- //
+// CTFCSuperNailgun class definition.
+// ----------------------------------------------------------------------------- //
+
+class CTFCSuperNailgun : public CTFCNailgun
+{
+public:
+ DECLARE_CLASS( CTFCSuperNailgun, CTFCNailgun );
+ DECLARE_NETWORKCLASS();
+ DECLARE_PREDICTABLE();
+
+ #ifndef CLIENT_DLL
+ DECLARE_DATADESC();
+ #endif
+
+
+ CTFCSuperNailgun();
+
+ virtual TFCWeaponID GetWeaponID( void ) const;
+ virtual void PrimaryAttack();
+
+
+// Overrideables.
+public:
+
+private:
+
+ CTFCSuperNailgun( const CTFCSuperNailgun & ) {}
+
+};
+
+
+#endif // WEAPON_TFC_SUPER_NAILGUN_H
diff --git a/game/shared/tfc/weapon_tfc_super_shotgun.cpp b/game/shared/tfc/weapon_tfc_super_shotgun.cpp
new file mode 100644
index 0000000..1b4a89e
--- /dev/null
+++ b/game/shared/tfc/weapon_tfc_super_shotgun.cpp
@@ -0,0 +1,119 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================//
+
+#include "cbase.h"
+#include "util.h"
+#include "weapon_tfc_super_shotgun.h"
+#include "decals.h"
+#include "in_buttons.h"
+
+#if defined( CLIENT_DLL )
+ #include "c_tfc_player.h"
+#else
+ #include "tfc_player.h"
+#endif
+
+
+// ----------------------------------------------------------------------------- //
+// CTFCSuperShotgun tables.
+// ----------------------------------------------------------------------------- //
+
+IMPLEMENT_NETWORKCLASS_ALIASED( TFCSuperShotgun, DT_WeaponSuperShotgun )
+
+BEGIN_NETWORK_TABLE( CTFCSuperShotgun, DT_WeaponSuperShotgun )
+END_NETWORK_TABLE()
+
+BEGIN_PREDICTION_DATA( CTFCSuperShotgun )
+END_PREDICTION_DATA()
+
+LINK_ENTITY_TO_CLASS( weapon_super_shotgun, CTFCSuperShotgun );
+PRECACHE_WEAPON_REGISTER( weapon_super_shotgun );
+
+#ifndef CLIENT_DLL
+
+ BEGIN_DATADESC( CTFCSuperShotgun )
+ END_DATADESC()
+
+#endif
+
+// ----------------------------------------------------------------------------- //
+// CTFCSuperShotgun implementation.
+// ----------------------------------------------------------------------------- //
+
+CTFCSuperShotgun::CTFCSuperShotgun()
+{
+ m_iShellsReloaded = 2;
+}
+
+
+TFCWeaponID CTFCSuperShotgun::GetWeaponID() const
+{
+ return WEAPON_SUPER_SHOTGUN;
+}
+
+
+void CTFCSuperShotgun::PrimaryAttack()
+{
+ CTFCPlayer *pOwner = GetPlayerOwner();
+ if ( !pOwner )
+ return;
+
+ Assert( Clip1() > 0 );
+
+ // If we've only 1 shell left, fire a single shot
+ if ( Clip1() == 1 )
+ {
+ BaseClass::PrimaryAttack();
+ return;
+ }
+
+ WeaponSound( SINGLE );
+ SendWeaponAnim( ACT_VM_PRIMARYATTACK );
+ pOwner->DoAnimationEvent( PLAYERANIMEVENT_FIRE_GUN );
+
+
+ // Shoot!
+ FireBulletsInfo_t info;
+ info.m_vecSrc = pOwner->Weapon_ShootPosition();
+ info.m_vecDirShooting = pOwner->GetAutoaimVector( AUTOAIM_5DEGREES );
+ info.m_iShots = 14;
+ info.m_flDistance = 2048;
+ info.m_iAmmoType = GetPrimaryAmmoType();
+ info.m_vecSpread = VECTOR_CONE_TF_SHOTGUN;
+ info.m_iTracerFreq = 4;
+ info.m_flDamage = 4;
+ pOwner->FireBullets( info );
+
+ m_iClip1 -= 2;
+ m_flTimeWeaponIdle = gpGlobals->curtime + 5.0;
+ m_fInSpecialReload = 0;
+
+ // Setup fire delays
+ if ( Clip1() != 0 )
+ m_flPumpTime = gpGlobals->curtime + 0.7;
+
+ m_flNextPrimaryAttack = gpGlobals->curtime + 0.7;
+}
+
+
+#ifdef CLIENT_DLL
+
+ // ------------------------------------------------------------------------------------------------ //
+ // ------------------------------------------------------------------------------------------------ //
+ // CLIENT DLL SPECIFIC CODE
+ // ------------------------------------------------------------------------------------------------ //
+ // ------------------------------------------------------------------------------------------------ //
+
+
+#else
+
+ // ------------------------------------------------------------------------------------------------ //
+ // ------------------------------------------------------------------------------------------------ //
+ // GAME DLL SPECIFIC CODE
+ // ------------------------------------------------------------------------------------------------ //
+ // ------------------------------------------------------------------------------------------------ //
+
+#endif
diff --git a/game/shared/tfc/weapon_tfc_super_shotgun.h b/game/shared/tfc/weapon_tfc_super_shotgun.h
new file mode 100644
index 0000000..05f6234
--- /dev/null
+++ b/game/shared/tfc/weapon_tfc_super_shotgun.h
@@ -0,0 +1,56 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================//
+
+#ifndef WEAPON_TFC_SUPER_SHOTGUN_H
+#define WEAPON_TFC_SUPER_SHOTGUN_H
+#ifdef _WIN32
+#pragma once
+#endif
+
+
+#include "weapon_tfc_shotgun.h"
+
+
+#if defined( CLIENT_DLL )
+
+ #define CTFCSuperShotgun C_TFCSuperShotgun
+
+#endif
+
+
+// ----------------------------------------------------------------------------- //
+// CTFCSuperShotgun class definition.
+// ----------------------------------------------------------------------------- //
+
+class CTFCSuperShotgun : public CTFCShotgun
+{
+public:
+ DECLARE_CLASS( CTFCSuperShotgun, CTFCShotgun );
+ DECLARE_NETWORKCLASS();
+ DECLARE_PREDICTABLE();
+
+ #ifndef CLIENT_DLL
+ DECLARE_DATADESC();
+ #endif
+
+
+ CTFCSuperShotgun();
+
+ virtual TFCWeaponID GetWeaponID( void ) const;
+ virtual void PrimaryAttack();
+
+
+// Overrideables.
+public:
+
+private:
+
+ CTFCSuperShotgun( const CTFCSuperShotgun & ) {}
+
+};
+
+
+#endif // WEAPON_TFC_SUPER_SHOTGUN_H
diff --git a/game/shared/tfc/weapon_tfcbase.cpp b/game/shared/tfc/weapon_tfcbase.cpp
new file mode 100644
index 0000000..0d697bc
--- /dev/null
+++ b/game/shared/tfc/weapon_tfcbase.cpp
@@ -0,0 +1,193 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//=============================================================================//
+
+#include "cbase.h"
+#include "in_buttons.h"
+#include "takedamageinfo.h"
+#include "weapon_tfcbase.h"
+#include "ammodef.h"
+#include "tfc_gamerules.h"
+
+extern IVModelInfo* modelinfo;
+
+
+#if defined( CLIENT_DLL )
+
+ #include "vgui/ISurface.h"
+ #include "vgui_controls/Controls.h"
+ #include "c_tfc_player.h"
+ #include "hud_crosshair.h"
+
+#else
+
+ #include "tfc_player.h"
+
+#endif
+
+
+// ----------------------------------------------------------------------------- //
+// Global functions.
+// ----------------------------------------------------------------------------- //
+
+bool IsAmmoType( int iAmmoType, const char *pAmmoName )
+{
+ return GetAmmoDef()->Index( pAmmoName ) == iAmmoType;
+}
+
+
+// ----------------------------------------------------------------------------- //
+// CWeaponTFCBase tables.
+// ----------------------------------------------------------------------------- //
+
+IMPLEMENT_NETWORKCLASS_ALIASED( WeaponTFCBase, DT_WeaponTFCBase )
+
+BEGIN_NETWORK_TABLE( CWeaponTFCBase, DT_WeaponTFCBase )
+END_NETWORK_TABLE()
+
+BEGIN_PREDICTION_DATA( CWeaponTFCBase )
+END_PREDICTION_DATA()
+
+LINK_ENTITY_TO_CLASS( weapon_tfc_base, CWeaponTFCBase );
+
+
+#ifdef GAME_DLL
+
+ BEGIN_DATADESC( CWeaponTFCBase )
+
+ DEFINE_FUNCTION( FallThink )
+
+ END_DATADESC()
+
+#endif
+
+#ifdef CLIENT_DLL
+ ConVar cl_crosshaircolor( "cl_crosshaircolor", "0", FCVAR_CLIENTDLL | FCVAR_ARCHIVE );
+ ConVar cl_dynamiccrosshair( "cl_dynamiccrosshair", "1", FCVAR_CLIENTDLL | FCVAR_ARCHIVE );
+ ConVar cl_scalecrosshair( "cl_scalecrosshair", "1", FCVAR_CLIENTDLL | FCVAR_ARCHIVE );
+ ConVar cl_crosshairalpha( "cl_crosshairalpha", "200", FCVAR_CLIENTDLL | FCVAR_ARCHIVE );
+
+ int g_iScopeTextureID = 0;
+ int g_iScopeDustTextureID = 0;
+#endif
+
+// ----------------------------------------------------------------------------- //
+// CWeaponTFCBase implementation.
+// ----------------------------------------------------------------------------- //
+CWeaponTFCBase::CWeaponTFCBase()
+{
+ SetPredictionEligible( true );
+ AddSolidFlags( FSOLID_TRIGGER ); // Nothing collides with these but it gets touches.
+}
+
+
+bool CWeaponTFCBase::IsPredicted() const
+{
+ return true;
+}
+
+CTFCPlayer* CWeaponTFCBase::GetPlayerOwner() const
+{
+ return dynamic_cast< CTFCPlayer* >( GetOwner() );
+}
+
+const CTFCWeaponInfo &CWeaponTFCBase::GetTFCWpnData() const
+{
+ const FileWeaponInfo_t *pWeaponInfo = &GetWpnData();
+ const CTFCWeaponInfo *pTFCInfo;
+
+ #ifdef _DEBUG
+ pTFCInfo = dynamic_cast< const CTFCWeaponInfo* >( pWeaponInfo );
+ Assert( pTFCInfo );
+ #else
+ pTFCInfo = static_cast< const CTFCWeaponInfo* >( pWeaponInfo );
+ #endif
+
+ return *pTFCInfo;
+}
+
+
+TFCWeaponID CWeaponTFCBase::GetWeaponID( void ) const
+{
+ Assert( false ); return WEAPON_NONE;
+}
+
+
+bool CWeaponTFCBase::IsA( TFCWeaponID id ) const
+{
+ return GetWeaponID() == id;
+}
+
+
+bool CWeaponTFCBase::IsSilenced( void ) const
+{
+ return false;
+}
+
+
+void CWeaponTFCBase::Precache( void )
+{
+ BaseClass::Precache();
+}
+
+
+#ifdef CLIENT_DLL
+
+#else // CLIENT_DLL
+
+ void CWeaponTFCBase::Spawn()
+ {
+ BaseClass::Spawn();
+
+ // Set this here to allow players to shoot dropped weapons
+ SetCollisionGroup( COLLISION_GROUP_WEAPON );
+
+ // Move it up a little bit, otherwise it'll be at the guy's feet, and its sound origin
+ // will be in the ground so its EmitSound calls won't do anything.
+ SetLocalOrigin( Vector( 0, 0, 5 ) );
+ }
+
+ bool CWeaponTFCBase::DefaultReload( int iClipSize1, int iClipSize2, int iActivity )
+ {
+ if ( BaseClass::DefaultReload( iClipSize1, iClipSize2, iActivity ) )
+ {
+ SendReloadSoundEvent();
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ void CWeaponTFCBase::SendReloadSoundEvent()
+ {
+ CBasePlayer *pPlayer = GetPlayerOwner();
+
+ assert( pPlayer );
+
+ if ( !pPlayer )
+ return;
+
+ // Send a message to any clients that have this entity to play the reload.
+ CPASFilter filter( pPlayer->GetAbsOrigin() );
+ filter.RemoveRecipient( pPlayer );
+
+ UserMessageBegin( filter, "ReloadEffect" );
+ WRITE_SHORT( pPlayer->entindex() );
+ MessageEnd();
+ }
+
+ Vector CWeaponTFCBase::GetSoundEmissionOrigin() const
+ {
+ CBasePlayer *pPlayer = GetPlayerOwner();
+ if ( pPlayer )
+ return pPlayer->WorldSpaceCenter();
+ else
+ return WorldSpaceCenter();
+ }
+
+#endif
diff --git a/game/shared/tfc/weapon_tfcbase.h b/game/shared/tfc/weapon_tfcbase.h
new file mode 100644
index 0000000..274abc4
--- /dev/null
+++ b/game/shared/tfc/weapon_tfcbase.h
@@ -0,0 +1,126 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================//
+
+#ifndef WEAPON_TFCBASE_H
+#define WEAPON_TFCBASE_H
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include "tfc_playeranimstate.h"
+#include "tfc_weapon_parse.h"
+
+#if defined( CLIENT_DLL )
+ #define CWeaponTFCBase C_WeaponTFCBase
+#endif
+
+class CTFCPlayer;
+
+
+// Given an ammo type (like from a weapon's GetPrimaryAmmoType()), this compares it
+// against the ammo name you specify.
+// MIKETODO: this should use indexing instead of searching and strcmp()'ing all the time.
+bool IsAmmoType( int iAmmoType, const char *pAmmoName );
+
+
+typedef enum
+{
+ WEAPON_NONE = 0,
+
+ // Melee
+ WEAPON_CROWBAR,
+ WEAPON_SPANNER, // Engineer's wrench.
+ WEAPON_KNIFE,
+ WEAPON_MEDIKIT,
+
+ // Vector weapons
+ WEAPON_MINIGUN,
+
+ // Shotguns
+ WEAPON_SHOTGUN,
+ WEAPON_SUPER_SHOTGUN,
+
+ WEAPON_NAILGUN,
+ WEAPON_SUPER_NAILGUN,
+
+ WEAPON_MAX, // number of weapons weapon index
+
+} TFCWeaponID;
+
+
+//Class Heirarchy for tfc weapons
+
+/*
+
+ CWeaponTFCBase
+ |
+ |--> CTFCCrowbar
+ | |
+ | |--> CTFCKnife
+ | |--> CTFCMedikit
+ | |--> CTFCSpanner
+ | |--> CTFCMedikit
+ |
+ |--> CTFCMinigun
+ |
+ |--> CTFCShotgun
+ | |
+ | |--> CTFCSuperShotgun
+ |
+ |--> CTFCNailgun
+ | |
+ | |--> CTFCSuperNailgun
+
+*/
+class CWeaponTFCBase : public CBaseCombatWeapon
+{
+public:
+ DECLARE_CLASS( CWeaponTFCBase, CBaseCombatWeapon );
+ DECLARE_NETWORKCLASS();
+ DECLARE_PREDICTABLE();
+
+ CWeaponTFCBase();
+
+ virtual void Precache();
+ virtual bool IsPredicted() const;
+
+ CTFCPlayer* GetPlayerOwner() const;
+
+ // Get TFC-specific weapon data.
+ CTFCWeaponInfo const &GetTFCWpnData() const;
+
+ // Get specific TFC weapon ID (ie: WEAPON_AK47, etc)
+ virtual TFCWeaponID GetWeaponID( void ) const;
+
+ // return true if this weapon is an instance of the given weapon type (ie: "IsA" WEAPON_GLOCK)
+ bool IsA( TFCWeaponID id ) const;
+
+ // return true if this weapon has a silencer equipped
+ virtual bool IsSilenced( void ) const;
+
+
+#ifdef CLIENT_DLL
+
+#else
+
+ DECLARE_DATADESC();
+
+ virtual void Spawn();
+ virtual bool DefaultReload( int iClipSize1, int iClipSize2, int iActivity );
+ void SendReloadSoundEvent();
+
+ virtual Vector GetSoundEmissionOrigin() const;
+
+#endif
+
+
+private:
+
+ CWeaponTFCBase( const CWeaponTFCBase & );
+};
+
+
+#endif // WEAPON_TFCBASE_H