This commit is contained in:
FluorescentCIAAfricanAmerican
2020-04-22 12:56:21 -04:00
commit 3bf9df6b27
15370 changed files with 5489726 additions and 0 deletions
+152
View File
@@ -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 );
}
}
+45
View File
@@ -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
+105
View File
@@ -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;
}
}
+422
View File
@@ -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;
}
+104
View File
@@ -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
+97
View File
@@ -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;
}
}
+138
View File
@@ -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
+323
View File
@@ -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;
}
+55
View File
@@ -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
+436
View File
@@ -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];
}
+321
View File
@@ -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
+41
View File
@@ -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.
}
+28
View File
@@ -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 );
}
+30
View File
@@ -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
+330
View File
@@ -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
+88
View File
@@ -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
+58
View File
@@ -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;
}
+53
View File
@@ -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
+248
View File
@@ -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
+59
View File
@@ -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
+282
View File
@@ -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
+84
View File
@@ -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
+114
View File
@@ -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
+57
View File
@@ -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
+232
View File
@@ -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
+68
View File
@@ -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
+114
View File
@@ -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
+63
View File
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
+193
View File
@@ -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
+126
View File
@@ -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