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