AI in multiplayer..
Hi all,
         I’m almost certain that this has been covered before and that others have solved it, but I’m having troubles getting it to work.
I got the AI (combine soldier) to the point that they follow me, will elbow me out of the way and even throw a grenade…but they do not shoot me with the smg1.  I have done what the tutorials have said todo and still nothing…There is one exception to this, if the player I’m controlling goes behind an obstacle such as a plank of wood, crate, (the wooden breakable staircase in lost coast) then the soldiers do fire at me and do give me damage.  In the console I can see that when they are shooting I get a developer message telling me that the handle animations event has happened…but when I come out from behind the obstacle then they stop shooting me…

Also I get errors such as
**ERROR: Combat State with no enemy! Slamming to ALERT

and im using ep1 models

If anyone has got this working so far then would they mind sharing their mp smg1 weapon code or perhaps have a look at the code I have written to see if you can see where I went wrong?

Adam Donovan


Send me an email if you can help......................................... carbon_adam@hotmail.com

Please find bellow the code for the

weapon_smg1.c++

hl2mp_gamerules.cpp

hl2mp_gamerules.h

weapon_hl2mpbase.h

basecombatweapon_shared.cpp

 

 

//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose: weapon_smg1.c++
//
//=============================================================================//

 

#include "cbase.h"
#include "npcevent.h"
#include "in_buttons.h"

#ifdef CLIENT_DLL
#include "c_hl2mp_player.h"
#else
#include "grenade_ar2.h"
#include "hl2mp_player.h"
#include "basegrenade_shared.h"

#include "basehlcombatweapon_shared.h"
#include "basecombatcharacter.h"
#include "AI_BaseNPC.h"
#include "game.h"
#include "AI_Memory.h"
#include "soundent.h"
#include "player.h"
#endif

#include "weapon_hl2mpbase.h"
#include "weapon_hl2mpbase_machinegun.h"

#ifdef CLIENT_DLL
#define CWeaponSMG1 C_WeaponSMG1
#endif

// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"

#define SMG1_GRENADE_DAMAGE 100.0f
#define SMG1_GRENADE_RADIUS 250.0f

class CWeaponSMG1 : public CHL2MPMachineGun
{
public:
DECLARE_CLASS( CWeaponSMG1, CHL2MPMachineGun );

CWeaponSMG1();

DECLARE_NETWORKCLASS();
DECLARE_PREDICTABLE();


void Precache( void );
void AddViewKick( void );
void SecondaryAttack( void );

int GetMinBurst() { return 2; }
int GetMaxBurst() { return 5; }

virtual void Equip( CBaseCombatCharacter *pOwner );
bool Reload( void );

float GetFireRate( void ) { return 0.075f; } // 13.3hz
Activity GetPrimaryAttackActivity( void );

virtual const Vector& GetBulletSpread( void )
{
static const Vector cone = VECTOR_CONE_5DEGREES;
return cone;
}

const WeaponProficiencyInfo_t *GetProficiencyValues();

#ifndef CLIENT_DLL
void Operator_HandleAnimEvent( animevent_t *pEvent, CBaseCombatCharacter *pOperator )
{
DevMsg("operator_handleanimevent smg1");
switch( pEvent->event )
{
case EVENT_WEAPON_SMG1:
{
DevMsg("event weapon smg1");
Vector vecShootOrigin, vecShootDir;
QAngle angDiscard;
if ((pEvent->options == NULL) || (pEvent->options[0] == '\0') || (!pOperator->GetAttachment(pEvent->options, vecShootOrigin, angDiscard)))
{
vecShootOrigin = pOperator->Weapon_ShootPosition();
}

CAI_BaseNPC *npc = pOperator->MyNPCPointer();
ASSERT( npc != NULL );

vecShootDir = npc->GetActualShootTrajectory( vecShootOrigin );

// FIXME: use the returned number of bullets to account for >10hz firerate
WeaponSoundRealtime( SINGLE_NPC );

CSoundEnt::InsertSound( SOUND_COMBAT, pOperator->GetAbsOrigin(), SOUNDENT_VOLUME_MACHINEGUN, 0.2, pOperator );
pOperator->FireBullets( 1, vecShootOrigin, vecShootDir, VECTOR_CONE_PRECALCULATED,
MAX_TRACE_LENGTH, m_iPrimaryAmmoType, 2, entindex(), 0 );
pOperator->DoMuzzleFlash();
m_iClip1 = m_iClip1 - 1;
}
break;

/*//FIXME: Re-enable
case EVENT_WEAPON_AR2_GRENADE:
{
CAI_BaseNPC *npc = pOperator->MyNPCPointer();

Vector vecShootOrigin, vecShootDir;
vecShootOrigin = pOperator->Weapon_ShootPosition();
vecShootDir = npc->GetShootEnemyDir( vecShootOrigin );

Vector vecThrow = m_vecTossVelocity;

CGrenadeAR2 *pGrenade = (CGrenadeAR2*)Create( "grenade_ar2", vecShootOrigin, vec3_angle, npc );
pGrenade->SetAbsVelocity( vecThrow );
pGrenade->SetLocalAngularVelocity( QAngle( 0, 400, 0 ) );
pGrenade->SetMoveType( MOVETYPE_FLYGRAVITY );
pGrenade->m_hOwner = npc;
pGrenade->m_pMyWeaponAR2 = this;
pGrenade->SetDamage(sk_npc_dmg_ar2_grenade.GetFloat());

// FIXME: arrgg ,this is hard coded into the weapon???
m_flNextGrenadeCheck = gpGlobals->curtime + 6;// wait six seconds before even looking again to see if a grenade can be thrown.

m_iClip2--;
}
break;
*/

default:
BaseClass::Operator_HandleAnimEvent( pEvent, pOperator );
break;
}
}
DECLARE_ACTTABLE();
#endif

protected:

Vector m_vecTossVelocity;
float m_flNextGrenadeCheck;

private:
CWeaponSMG1( const CWeaponSMG1 & );
};

IMPLEMENT_NETWORKCLASS_ALIASED( WeaponSMG1, DT_WeaponSMG1 )

BEGIN_NETWORK_TABLE( CWeaponSMG1, DT_WeaponSMG1 )
END_NETWORK_TABLE()

BEGIN_PREDICTION_DATA( CWeaponSMG1 )
END_PREDICTION_DATA()

LINK_ENTITY_TO_CLASS( weapon_smg1, CWeaponSMG1 );
PRECACHE_WEAPON_REGISTER(weapon_smg1);

#ifndef CLIENT_DLL
acttable_t CWeaponSMG1::m_acttable[] =
{
{ ACT_HL2MP_IDLE, ACT_HL2MP_IDLE_SMG1, false },
{ ACT_HL2MP_RUN, ACT_HL2MP_RUN_SMG1, false },
{ ACT_HL2MP_IDLE_CROUCH, ACT_HL2MP_IDLE_CROUCH_SMG1, false },
{ ACT_HL2MP_WALK_CROUCH, ACT_HL2MP_WALK_CROUCH_SMG1, false },
{ ACT_HL2MP_GESTURE_RANGE_ATTACK, ACT_HL2MP_GESTURE_RANGE_ATTACK_SMG1, false },
{ ACT_HL2MP_GESTURE_RELOAD, ACT_HL2MP_GESTURE_RELOAD_SMG1, false },
{ ACT_HL2MP_JUMP, ACT_HL2MP_JUMP_SMG1, false },
//{ ACT_RANGE_ATTACK1, ACT_RANGE_ATTACK_SMG1, false },

{ ACT_RANGE_ATTACK1, ACT_RANGE_ATTACK_SMG1, false },
{ ACT_RELOAD, ACT_RELOAD_SMG1, true },
{ ACT_IDLE, ACT_IDLE_SMG1, true },
{ ACT_IDLE_ANGRY, ACT_IDLE_ANGRY_SMG1, true },

{ ACT_WALK, ACT_WALK_RIFLE, true },
{ ACT_WALK_AIM, ACT_WALK_AIM_RIFLE, true },

// Readiness activities (not aiming)
{ ACT_IDLE_RELAXED, ACT_IDLE_SMG1_RELAXED, false },//never aims
{ ACT_IDLE_STIMULATED, ACT_IDLE_SMG1_STIMULATED, false },
{ ACT_IDLE_AGITATED, ACT_IDLE_ANGRY_SMG1, false },//always aims

{ ACT_WALK_RELAXED, ACT_WALK_RIFLE_RELAXED, false },//never aims
{ ACT_WALK_STIMULATED, ACT_WALK_RIFLE_STIMULATED, false },
{ ACT_WALK_AGITATED, ACT_WALK_AIM_RIFLE, false },//always aims

{ ACT_RUN_RELAXED, ACT_RUN_RIFLE_RELAXED, false },//never aims
{ ACT_RUN_STIMULATED, ACT_RUN_RIFLE_STIMULATED, false },
{ ACT_RUN_AGITATED, ACT_RUN_AIM_RIFLE, false },//always aims

// Readiness activities (aiming)
{ ACT_IDLE_AIM_RELAXED, ACT_IDLE_SMG1_RELAXED, false },//never aims
{ ACT_IDLE_AIM_STIMULATED, ACT_IDLE_AIM_RIFLE_STIMULATED, false },
{ ACT_IDLE_AIM_AGITATED, ACT_IDLE_ANGRY_SMG1, false },//always aims

{ ACT_WALK_AIM_RELAXED, ACT_WALK_RIFLE_RELAXED, false },//never aims
{ ACT_WALK_AIM_STIMULATED, ACT_WALK_AIM_RIFLE_STIMULATED, false },
{ ACT_WALK_AIM_AGITATED, ACT_WALK_AIM_RIFLE, false },//always aims

{ ACT_RUN_AIM_RELAXED, ACT_RUN_RIFLE_RELAXED, false },//never aims
{ ACT_RUN_AIM_STIMULATED, ACT_RUN_AIM_RIFLE_STIMULATED, false },
{ ACT_RUN_AIM_AGITATED, ACT_RUN_AIM_RIFLE, false },//always aims
//End readiness activities

{ ACT_WALK_AIM, ACT_WALK_AIM_RIFLE, true },
{ ACT_WALK_CROUCH, ACT_WALK_CROUCH_RIFLE, true },
{ ACT_WALK_CROUCH_AIM, ACT_WALK_CROUCH_AIM_RIFLE, true },
{ ACT_RUN, ACT_RUN_RIFLE, true },
{ ACT_RUN_AIM, ACT_RUN_AIM_RIFLE, true },
{ ACT_RUN_CROUCH, ACT_RUN_CROUCH_RIFLE, true },
{ ACT_RUN_CROUCH_AIM, ACT_RUN_CROUCH_AIM_RIFLE, true },
{ ACT_GESTURE_RANGE_ATTACK1, ACT_GESTURE_RANGE_ATTACK_SMG1, true },
{ ACT_RANGE_ATTACK1_LOW, ACT_RANGE_ATTACK_SMG1_LOW, true },
{ ACT_COVER_LOW, ACT_COVER_SMG1_LOW, false },
{ ACT_RANGE_AIM_LOW, ACT_RANGE_AIM_SMG1_LOW, false },
{ ACT_RELOAD_LOW, ACT_RELOAD_SMG1_LOW, false },
{ ACT_GESTURE_RELOAD, ACT_GESTURE_RELOAD_SMG1, true },
};

IMPLEMENT_ACTTABLE(CWeaponSMG1);
#endif

//=========================================================
CWeaponSMG1::CWeaponSMG1( )
{
m_fMinRange1 = 0;// No minimum range.
m_fMaxRange1 = 1400;
}

//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CWeaponSMG1::Precache( void )
{
#ifndef CLIENT_DLL
UTIL_PrecacheOther("grenade_ar2");
#endif

BaseClass::Precache();
}

//-----------------------------------------------------------------------------
// Purpose: Give this weapon longer range when wielded by an ally NPC.
//-----------------------------------------------------------------------------
void CWeaponSMG1::Equip( CBaseCombatCharacter *pOwner )
{
m_fMaxRange1 = 1400;

BaseClass::Equip( pOwner );
}

//-----------------------------------------------------------------------------
// Purpose:
// Output : Activity
//-----------------------------------------------------------------------------
Activity CWeaponSMG1::GetPrimaryAttackActivity( void )
{
if ( m_nShotsFired < 2 )
return ACT_VM_PRIMARYATTACK;

if ( m_nShotsFired < 3 )
return ACT_VM_RECOIL1;

if ( m_nShotsFired < 4 )
return ACT_VM_RECOIL2;

return ACT_VM_RECOIL3;
}

//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
bool CWeaponSMG1::Reload( void )
{
bool fRet;
float fCacheTime = m_flNextSecondaryAttack;

fRet = DefaultReload( GetMaxClip1(), GetMaxClip2(), ACT_VM_RELOAD );
if ( fRet )
{
// Undo whatever the reload process has done to our secondary
// attack timer. We allow you to interrupt reloading to fire
// a grenade.
m_flNextSecondaryAttack = GetOwner()->m_flNextAttack = fCacheTime;

WeaponSound( RELOAD );
}

return fRet;
}

//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CWeaponSMG1::AddViewKick( void )
{
#define EASY_DAMPEN 0.5f
#define MAX_VERTICAL_KICK 1.0f //Degrees
#define SLIDE_LIMIT 2.0f //Seconds

//Get the view kick
CBasePlayer *pPlayer = ToBasePlayer( GetOwner() );

if ( pPlayer == NULL )
return;

DoMachineGunKick( pPlayer, EASY_DAMPEN, MAX_VERTICAL_KICK, m_fFireDuration, SLIDE_LIMIT );
}

//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CWeaponSMG1::SecondaryAttack( void )
{
// Only the player fires this way so we can cast
CBasePlayer *pPlayer = ToBasePlayer( GetOwner() );

if ( pPlayer == NULL )
return;

//Must have ammo
if ( ( pPlayer->GetAmmoCount( m_iSecondaryAmmoType ) <= 0 ) || ( pPlayer->GetWaterLevel() == 3 ) )
{
SendWeaponAnim( ACT_VM_DRYFIRE );
BaseClass::WeaponSound( EMPTY );
m_flNextSecondaryAttack = gpGlobals->curtime + 0.5f;
return;
}

if( m_bInReload )
m_bInReload = false;

// MUST call sound before removing a round from the clip of a CMachineGun
BaseClass::WeaponSound( WPN_DOUBLE );

Vector vecSrc = pPlayer->Weapon_ShootPosition();
Vector vecThrow;
// Don't autoaim on grenade tosses
AngleVectors( pPlayer->EyeAngles() + pPlayer->GetPunchAngle(), &vecThrow );
VectorScale( vecThrow, 1000.0f, vecThrow );

#ifndef CLIENT_DLL
//Create the grenade
CGrenadeAR2 *pGrenade = (CGrenadeAR2*)Create( "grenade_ar2", vecSrc, vec3_angle, pPlayer );
pGrenade->SetAbsVelocity( vecThrow );

pGrenade->SetLocalAngularVelocity( RandomAngle( -400, 400 ) );
pGrenade->SetMoveType( MOVETYPE_FLYGRAVITY, MOVECOLLIDE_FLY_BOUNCE );
pGrenade->SetThrower( GetOwner() );
pGrenade->SetDamage( SMG1_GRENADE_DAMAGE );
pGrenade->SetDamageRadius( SMG1_GRENADE_RADIUS );
#endif

SendWeaponAnim( ACT_VM_SECONDARYATTACK );

// player "shoot" animation
pPlayer->SetAnimation( PLAYER_ATTACK1 );

// Decrease ammo
pPlayer->RemoveAmmo( 1, m_iSecondaryAmmoType );

// Can shoot again immediately
m_flNextPrimaryAttack = gpGlobals->curtime + 0.5f;

// Can blow up after a short delay (so have time to release mouse button)
m_flNextSecondaryAttack = gpGlobals->curtime + 1.0f;
}

//-----------------------------------------------------------------------------
const WeaponProficiencyInfo_t *CWeaponSMG1::GetProficiencyValues()
{
static WeaponProficiencyInfo_t proficiencyTable[] =
{
{ 7.0, 0.75 },
{ 5.00, 0.75 },
{ 10.0/3.0, 0.75 },
{ 5.0/3.0, 0.75 },
{ 1.00, 1.0 },
};

COMPILE_TIME_ASSERT( ARRAYSIZE(proficiencyTable) == WEAPON_PROFICIENCY_PERFECT + 1);

return proficiencyTable;
}

 

//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#include "cbase.h"
#include "hl2mp_gamerules.h"
#include "viewport_panel_names.h"
#include "gameeventdefs.h"
#include <KeyValues.h>
#include "ammodef.h"

#ifdef CLIENT_DLL
#include "c_hl2mp_player.h"
#else

#include "eventqueue.h"
#include "player.h"
#include "gamerules.h"
#include "game.h"
#include "items.h"
#include "entitylist.h"
#include "mapentities.h"
#include "in_buttons.h"
#include <ctype.h>
#include "voice_gamemgr.h"
#include "iscorer.h"
#include "hl2mp_player.h"
#include "weapon_hl2mpbasehlmpcombatweapon.h"
#include "team.h"
#include "voice_gamemgr.h"
#include "hl2mp_gameinterface.h"
#include "hl2mp_cvars.h"

#ifdef DEBUG
#include "hl2mp_bot_temp.h"
#endif

extern void respawn(CBaseEntity *pEdict, bool fCopyCorpse);

ConVar sv_hl2mp_weapon_respawn_time( "sv_hl2mp_weapon_respawn_time", "20", FCVAR_GAMEDLL | FCVAR_NOTIFY );
ConVar sv_hl2mp_item_respawn_time( "sv_hl2mp_item_respawn_time", "30", FCVAR_GAMEDLL | FCVAR_NOTIFY );
ConVar mp_restartgame( "mp_restartgame", "0", 0, "If non-zero, game will restart in the specified number of seconds" );
ConVar sv_report_client_settings("sv_report_client_settings", "0", FCVAR_GAMEDLL | FCVAR_NOTIFY );

extern ConVar mp_chattime;

extern CBaseEntity *g_pLastCombineSpawn;
extern CBaseEntity *g_pLastRebelSpawn;

#define WEAPON_MAX_DISTANCE_FROM_SPAWN 64

#endif

REGISTER_GAMERULES_CLASS( CHL2MPRules );

BEGIN_NETWORK_TABLE_NOBASE( CHL2MPRules, DT_HL2MPRules )

#ifdef CLIENT_DLL
RecvPropBool( RECVINFO( m_bTeamPlayEnabled ) ),
#else
SendPropBool( SENDINFO( m_bTeamPlayEnabled ) ),
#endif

END_NETWORK_TABLE()

LINK_ENTITY_TO_CLASS( hl2mp_gamerules, CHL2MPGameRulesProxy );
IMPLEMENT_NETWORKCLASS_ALIASED( HL2MPGameRulesProxy, DT_HL2MPGameRulesProxy )

static HL2MPViewVectors g_HL2MPViewVectors(
Vector( 0, 0, 64 ), //m_vView

Vector(-16, -16, 0 ), //m_vHullMin
Vector( 16, 16, 72 ), //m_vHullMax

Vector(-16, -16, 0 ), //m_vDuckHullMin
Vector( 16, 16, 36 ), //m_vDuckHullMax
Vector( 0, 0, 28 ), //m_vDuckView

Vector(-10, -10, -10 ), //m_vObsHullMin
Vector( 10, 10, 10 ), //m_vObsHullMax

Vector( 0, 0, 14 ), //m_vDeadViewHeight

Vector(-16, -16, 0 ), //m_vCrouchTraceMin
Vector( 16, 16, 60 ) //m_vCrouchTraceMax
);

static const char *s_PreserveEnts[] =
{
"ai_network",
"ai_hint",
"hl2mp_gamerules",
"team_manager",
"player_manager",
"env_soundscape",
"env_soundscape_proxy",
"env_soundscape_triggerable",
"env_sun",
"env_wind",
"env_fog_controller",
"func_brush",
"func_wall",
"func_buyzone",
"func_illusionary",
"infodecal",
"info_projecteddecal",
"info_node",
"info_target",
"info_node_hint",
"info_player_deathmatch",
"info_player_combine",
"info_player_rebel",
"info_map_parameters",
"keyframe_rope",
"move_rope",
"info_ladder",
"player",
"point_viewcontrol",
"scene_manager",
"shadow_control",
"sky_camera",
"soundent",
"trigger_soundscape",
"viewmodel",
"predicted_viewmodel",
"worldspawn",
"point_devshot_camera",
"", // END Marker
};

 

#ifdef CLIENT_DLL
void RecvProxy_HL2MPRules( const RecvProp *pProp, void **pOut, void *pData, int objectID )
{
CHL2MPRules *pRules = HL2MPRules();
Assert( pRules );
*pOut = pRules;
}

BEGIN_RECV_TABLE( CHL2MPGameRulesProxy, DT_HL2MPGameRulesProxy )
RecvPropDataTable( "hl2mp_gamerules_data", 0, 0, &REFERENCE_RECV_TABLE( DT_HL2MPRules ), RecvProxy_HL2MPRules )
END_RECV_TABLE()
#else
void* SendProxy_HL2MPRules( const SendProp *pProp, const void *pStructBase, const void *pData, CSendProxyRecipients *pRecipients, int objectID )
{
CHL2MPRules *pRules = HL2MPRules();
Assert( pRules );
return pRules;
}

BEGIN_SEND_TABLE( CHL2MPGameRulesProxy, DT_HL2MPGameRulesProxy )
SendPropDataTable( "hl2mp_gamerules_data", 0, &REFERENCE_SEND_TABLE( DT_HL2MPRules ), SendProxy_HL2MPRules )
END_SEND_TABLE()
#endif

#ifndef CLIENT_DLL

class CVoiceGameMgrHelper : public IVoiceGameMgrHelper
{
public:
virtual bool CanPlayerHearPlayer( CBasePlayer *pListener, CBasePlayer *pTalker )
{
return ( pListener->GetTeamNumber() == pTalker->GetTeamNumber() );
}
};
CVoiceGameMgrHelper g_VoiceGameMgrHelper;
IVoiceGameMgrHelper *g_pVoiceGameMgrHelper = &g_VoiceGameMgrHelper;

#endif

// NOTE: the indices here must match TEAM_TERRORIST, TEAM_CT, TEAM_SPECTATOR, etc.
char *sTeamNames[] =
{
"Unassigned",
"Spectator",
"Combine",
"Rebels",
};

CHL2MPRules::CHL2MPRules()
{
#ifndef CLIENT_DLL
// Create the team managers
for ( int i = 0; i < ARRAYSIZE( sTeamNames ); i++ )
{
CTeam *pTeam = static_cast<CTeam*>(CreateEntityByName( "team_manager" ));
pTeam->Init( sTeamNames[i], i );

g_Teams.AddToTail( pTeam );
}

m_bTeamPlayEnabled = teamplay.GetBool();
m_flIntermissionEndTime = 0.0f;
m_flGameStartTime = 0;

m_hRespawnableItemsAndWeapons.RemoveAll();
m_tmNextPeriodicThink = 0;
m_flRestartGameTime = 0;
m_bCompleteReset = false;
m_bHeardAllPlayersReady = false;
m_bAwaitingReadyRestart = false;

// EDIT IH //
InitDefaultAIRelationships();
#endif
}

const CViewVectors* CHL2MPRules::GetViewVectors()const
{
return &g_HL2MPViewVectors;
}

const HL2MPViewVectors* CHL2MPRules::GetHL2MPViewVectors()const
{
return &g_HL2MPViewVectors;
}

CHL2MPRules::~CHL2MPRules( void )
{
#ifndef CLIENT_DLL
// Note, don't delete each team since they are in the gEntList and will
// automatically be deleted from there, instead.
g_Teams.Purge();
#endif
}

void CHL2MPRules::CreateStandardEntities( void )
{

#ifndef CLIENT_DLL
// Create the entity that will send our data to the client.

BaseClass::CreateStandardEntities();

g_pLastCombineSpawn = NULL;
g_pLastRebelSpawn = NULL;

#ifdef _DEBUG
CBaseEntity *pEnt =
#endif
CBaseEntity::Create( "hl2mp_gamerules", vec3_origin, vec3_angle );
Assert( pEnt );
#endif
}

//=========================================================
// FlWeaponRespawnTime - what is the time in the future
// at which this weapon may spawn?
//=========================================================
float CHL2MPRules::FlWeaponRespawnTime( CBaseCombatWeapon *pWeapon )
{
#ifndef CLIENT_DLL
if ( weaponstay.GetInt() > 0 )
{
// make sure it's only certain weapons
if ( !(pWeapon->GetWeaponFlags() & ITEM_FLAG_LIMITINWORLD) )
{
return 0; // weapon respawns almost instantly
}
}

return sv_hl2mp_weapon_respawn_time.GetFloat();
#endif

return 0; // weapon respawns almost instantly
}

bool CHL2MPRules::IsIntermission( void )
{
#ifndef CLIENT_DLL
return m_flIntermissionEndTime > gpGlobals->curtime;
#endif

return false;
}

void CHL2MPRules::PlayerKilled( CBasePlayer *pVictim, const CTakeDamageInfo &info )
{
#ifndef CLIENT_DLL
if ( IsIntermission() )
return;
BaseClass::PlayerKilled( pVictim, info );
#endif
}

void CHL2MPRules::Think( void )
{

#ifndef CLIENT_DLL

CGameRules::Think();

if ( g_fGameOver ) // someone else quit the game already
{
// check to see if we should change levels now
if ( m_flIntermissionEndTime < gpGlobals->curtime )
{
ChangeLevel(); // intermission is over
}

return;
}

// float flTimeLimit = mp_timelimit.GetFloat() * 60;
float flFragLimit = fraglimit.GetFloat();

if ( GetMapRemainingTime() < 0 )
{
GoToIntermission();
return;
}

if ( flFragLimit )
{
if( IsTeamplay() == true )
{
CTeam *pCombine = g_Teams[TEAM_COMBINE];
CTeam *pRebels = g_Teams[TEAM_REBELS];

if ( pCombine->GetScore() >= flFragLimit || pRebels->GetScore() >= flFragLimit )
{
GoToIntermission();
return;
}
}
else
{
// check if any player is over the frag limit
for ( int i = 1; i <= gpGlobals->maxClients; i++ )
{
CBasePlayer *pPlayer = UTIL_PlayerByIndex( i );

if ( pPlayer && pPlayer->FragCount() >= flFragLimit )
{
GoToIntermission();
return;
}
}
}
}

if ( gpGlobals->curtime > m_tmNextPeriodicThink )
{
CheckAllPlayersReady();
CheckRestartGame();
m_tmNextPeriodicThink = gpGlobals->curtime + 1.0;
}

if ( m_flRestartGameTime > 0.0f && m_flRestartGameTime <= gpGlobals->curtime )
{
RestartGame();
}

if( m_bAwaitingReadyRestart && m_bHeardAllPlayersReady )
{
UTIL_ClientPrintAll( HUD_PRINTCENTER, "All players ready. Game will restart in 5 seconds" );
UTIL_ClientPrintAll( HUD_PRINTCONSOLE, "All players ready. Game will restart in 5 seconds" );

m_flRestartGameTime = gpGlobals->curtime + 5;
m_bAwaitingReadyRestart = false;
}

ManageObjectRelocation();

#endif
}

void CHL2MPRules::GoToIntermission( void )
{
#ifndef CLIENT_DLL
if ( g_fGameOver )
return;

g_fGameOver = true;

m_flIntermissionEndTime = gpGlobals->curtime + mp_chattime.GetInt();

for ( int i = 0; i < MAX_PLAYERS; i++ )
{
CBasePlayer *pPlayer = UTIL_PlayerByIndex( i );

if ( !pPlayer )
continue;

pPlayer->ShowViewPortPanel( PANEL_SCOREBOARD );
pPlayer->AddFlag( FL_FROZEN );
}
#endif

}

bool CHL2MPRules::CheckGameOver()
{
#ifndef CLIENT_DLL
if ( g_fGameOver ) // someone else quit the game already
{
// check to see if we should change levels now
if ( m_flIntermissionEndTime < gpGlobals->curtime )
{
ChangeLevel(); // intermission is over
}

return true;
}
#endif

return false;
}

// when we are within this close to running out of entities, items
// marked with the ITEM_FLAG_LIMITINWORLD will delay their respawn
#define ENTITY_INTOLERANCE 100

//=========================================================
// FlWeaponRespawnTime - Returns 0 if the weapon can respawn
// now, otherwise it returns the time at which it can try
// to spawn again.
//=========================================================
float CHL2MPRules::FlWeaponTryRespawn( CBaseCombatWeapon *pWeapon )
{
#ifndef CLIENT_DLL
if ( pWeapon && (pWeapon->GetWeaponFlags() & ITEM_FLAG_LIMITINWORLD) )
{
if ( gEntList.NumberOfEntities() < (gpGlobals->maxEntities - ENTITY_INTOLERANCE) )
return 0;

// we're past the entity tolerance level, so delay the respawn
return FlWeaponRespawnTime( pWeapon );
}
#endif
return 0;
}

//=========================================================
// VecWeaponRespawnSpot - where should this weapon spawn?
// Some game variations may choose to randomize spawn locations
//=========================================================
Vector CHL2MPRules::VecWeaponRespawnSpot( CBaseCombatWeapon *pWeapon )
{
#ifndef CLIENT_DLL
CWeaponHL2MPBase *pHL2Weapon = dynamic_cast< CWeaponHL2MPBase*>( pWeapon );

if ( pHL2Weapon )
{
return pHL2Weapon->GetOriginalSpawnOrigin();
}
#endif

return pWeapon->GetAbsOrigin();
}

#ifndef CLIENT_DLL

CItem* IsManagedObjectAnItem( CBaseEntity *pObject )
{
return dynamic_cast< CItem*>( pObject );
}

CWeaponHL2MPBase* IsManagedObjectAWeapon( CBaseEntity *pObject )
{
return dynamic_cast< CWeaponHL2MPBase*>( pObject );
}

bool GetObjectsOriginalParameters( CBaseEntity *pObject, Vector &vOriginalOrigin, QAngle &vOriginalAngles )
{
if ( CItem *pItem = IsManagedObjectAnItem( pObject ) )
{
if ( pItem->m_flNextResetCheckTime > gpGlobals->curtime )
return false;

vOriginalOrigin = pItem->GetOriginalSpawnOrigin();
vOriginalAngles = pItem->GetOriginalSpawnAngles();

pItem->m_flNextResetCheckTime = gpGlobals->curtime + sv_hl2mp_item_respawn_time.GetFloat();
return true;
}
else if ( CWeaponHL2MPBase *pWeapon = IsManagedObjectAWeapon( pObject ))
{
if ( pWeapon->m_flNextResetCheckTime > gpGlobals->curtime )
return false;

vOriginalOrigin = pWeapon->GetOriginalSpawnOrigin();
vOriginalAngles = pWeapon->GetOriginalSpawnAngles();

pWeapon->m_flNextResetCheckTime = gpGlobals->curtime + sv_hl2mp_weapon_respawn_time.GetFloat();
return true;
}

return false;
}

void CHL2MPRules::ManageObjectRelocation( void )
{
int iTotal = m_hRespawnableItemsAndWeapons.Count();

if ( iTotal > 0 )
{
for ( int i = 0; i < iTotal; i++ )
{
CBaseEntity *pObject = m_hRespawnableItemsAndWeapons[i].Get();

if ( pObject )
{
Vector vSpawOrigin;
QAngle vSpawnAngles;

if ( GetObjectsOriginalParameters( pObject, vSpawOrigin, vSpawnAngles ) == true )
{
float flDistanceFromSpawn = (pObject->GetAbsOrigin() - vSpawOrigin ).Length();

if ( flDistanceFromSpawn > WEAPON_MAX_DISTANCE_FROM_SPAWN )
{
bool shouldReset = false;
IPhysicsObject *pPhysics = pObject->VPhysicsGetObject();

if ( pPhysics )
{
shouldReset = pPhysics->IsAsleep();
}
else
{
shouldReset = (pObject->GetFlags() & FL_ONGROUND) ? true : false;
}

if ( shouldReset )
{
pObject->Teleport( &vSpawOrigin, &vSpawnAngles, NULL );
pObject->EmitSound( "AlyxEmp.Charge" );

IPhysicsObject *pPhys = pObject->VPhysicsGetObject();

if ( pPhys )
{
pPhys->Wake();
}
}
}
}
}
}
}
}

//=========================================================
//AddLevelDesignerPlacedWeapon
//=========================================================
void CHL2MPRules::AddLevelDesignerPlacedObject( CBaseEntity *pEntity )
{
if ( m_hRespawnableItemsAndWeapons.Find( pEntity ) == -1 )
{
m_hRespawnableItemsAndWeapons.AddToTail( pEntity );
}
}

//=========================================================
//RemoveLevelDesignerPlacedWeapon
//=========================================================
void CHL2MPRules::RemoveLevelDesignerPlacedObject( CBaseEntity *pEntity )
{
if ( m_hRespawnableItemsAndWeapons.Find( pEntity ) != -1 )
{
m_hRespawnableItemsAndWeapons.FindAndRemove( pEntity );
}
}

//=========================================================
// Where should this item respawn?
// Some game variations may choose to randomize spawn locations
//=========================================================
Vector CHL2MPRules::VecItemRespawnSpot( CItem *pItem )
{
return pItem->GetOriginalSpawnOrigin();
}

//=========================================================
// What angles should this item use to respawn?
//=========================================================
QAngle CHL2MPRules::VecItemRespawnAngles( CItem *pItem )
{
return pItem->GetOriginalSpawnAngles();
}

//=========================================================
// At what time in the future may this Item respawn?
//=========================================================
float CHL2MPRules::FlItemRespawnTime( CItem *pItem )
{
return sv_hl2mp_item_respawn_time.GetFloat();
}

//=========================================================
// CanHaveWeapon - returns false if the player is not allowed
// to pick up this weapon
//=========================================================
bool CHL2MPRules::CanHavePlayerItem( CBasePlayer *pPlayer, CBaseCombatWeapon *pItem )
{
if ( weaponstay.GetInt() > 0 )
{
if ( pPlayer->Weapon_OwnsThisType( pItem->GetClassname(), pItem->GetSubType() ) )
return false;
}

return BaseClass::CanHavePlayerItem( pPlayer, pItem );
}

#endif

//=========================================================
// WeaponShouldRespawn - any conditions inhibiting the
// respawning of this weapon?
//=========================================================
int CHL2MPRules::WeaponShouldRespawn( CBaseCombatWeapon *pWeapon )
{
#ifndef CLIENT_DLL
if ( pWeapon->HasSpawnFlags( SF_NORESPAWN ) )
{
return GR_WEAPON_RESPAWN_NO;
}
#endif

return GR_WEAPON_RESPAWN_YES;
}

//-----------------------------------------------------------------------------
// Purpose: Player has just left the game
//-----------------------------------------------------------------------------
void CHL2MPRules::ClientDisconnected( edict_t *pClient )
{
#ifndef CLIENT_DLL
// Msg( "CLIENT DISCONNECTED, REMOVING FROM TEAM.\n" );

CBasePlayer *pPlayer = (CBasePlayer *)CBaseEntity::Instance( pClient );
if ( pPlayer )
{
// Remove the player from his team
if ( pPlayer->GetTeam() )
{
pPlayer->GetTeam()->RemovePlayer( pPlayer );
}
}

BaseClass::ClientDisconnected( pClient );

#endif
}

//=========================================================
// Deathnotice.
//=========================================================
void CHL2MPRules::DeathNotice( CBasePlayer *pVictim, const CTakeDamageInfo &info )
{
#ifndef CLIENT_DLL
// Work out what killed the player, and send a message to all clients about it
const char *killer_weapon_name = "world"; // by default, the player is killed by the world
int killer_ID = 0;

// Find the killer & the scorer
CBaseEntity *pInflictor = info.GetInflictor();
CBaseEntity *pKiller = info.GetAttacker();
CBasePlayer *pScorer = GetDeathScorer( pKiller, pInflictor );

// Custom kill type?
if ( info.GetCustomKill() )
{
killer_weapon_name = GetCustomKillString( info );
if ( pScorer )
{
killer_ID = pScorer->GetUserID();
}
}
else
{
// Is the killer a client?
if ( pScorer )
{
killer_ID = pScorer->GetUserID();

if ( pInflictor )
{
if ( pInflictor == pScorer )
{
// If the inflictor is the killer, then it must be their current weapon doing the damage
if ( pScorer->GetActiveWeapon() )
{
killer_weapon_name = pScorer->GetActiveWeapon()->GetClassname();
}
}
else
{
killer_weapon_name = pInflictor->GetClassname(); // it's just that easy
}
}
}
else
{
killer_weapon_name = pInflictor->GetClassname();
}

// strip the NPC_* or weapon_* from the inflictor's classname
if ( strncmp( killer_weapon_name, "weapon_", 7 ) == 0 )
{
killer_weapon_name += 7;
}
else if ( strncmp( killer_weapon_name, "npc_", 4 ) == 0 )
{
killer_weapon_name += 4;
}
else if ( strncmp( killer_weapon_name, "func_", 5 ) == 0 )
{
killer_weapon_name += 5;
}
else if ( strstr( killer_weapon_name, "physics" ) )
{
killer_weapon_name = "physics";
}

if ( strcmp( killer_weapon_name, "prop_combine_ball" ) == 0 )
{
killer_weapon_name = "combine_ball";
}
else if ( strcmp( killer_weapon_name, "grenade_ar2" ) == 0 )
{
killer_weapon_name = "smg1_grenade";
}
else if ( strcmp( killer_weapon_name, "satchel" ) == 0 || strcmp( killer_weapon_name, "tripmine" ) == 0)
{
killer_weapon_name = "slam";
}

}

IGameEvent *event = gameeventmanager->CreateEvent( "player_death" );
if( event )
{
event->SetInt("userid", pVictim->GetUserID() );
event->SetInt("attacker", killer_ID );
event->SetString("weapon", killer_weapon_name );
event->SetInt( "priority", 7 );
gameeventmanager->FireEvent( event );
}
#endif

}

void CHL2MPRules::ClientSettingsChanged( CBasePlayer *pPlayer )
{
#ifndef CLIENT_DLL

CHL2MP_Player *pHL2Player = ToHL2MPPlayer( pPlayer );

if ( pHL2Player == NULL )
return;

const char *pCurrentModel = modelinfo->GetModelName( pPlayer->GetModel() );
const char *szModelName = engine->GetClientConVarValue( engine->IndexOfEdict( pPlayer->edict() ), "cl_playermodel" );

//If we're different.
if ( stricmp( szModelName, pCurrentModel ) )
{
//Too soon, set the cvar back to what it was.
//Note: this will make this function be called again
//but since our models will match it'll just skip this whole dealio.
if ( pHL2Player->GetNextModelChangeTime() >= gpGlobals->curtime )
{
char szReturnString[512];

Q_snprintf( szReturnString, sizeof (szReturnString ), "cl_playermodel %s\n", pCurrentModel );
engine->ClientCommand ( pHL2Player->edict(), szReturnString );

Q_snprintf( szReturnString, sizeof( szReturnString ), "Please wait %d more seconds before trying to switch.\n", (int)(pHL2Player->GetNextModelChangeTime() - gpGlobals->curtime) );
ClientPrint( pHL2Player, HUD_PRINTTALK, szReturnString );
return;
}

if ( HL2MPRules()->IsTeamplay() == false )
{
pHL2Player->SetPlayerModel();

const char *pszCurrentModelName = modelinfo->GetModelName( pHL2Player->GetModel() );

char szReturnString[128];
Q_snprintf( szReturnString, sizeof( szReturnString ), "Your player model is: %s\n", pszCurrentModelName );

ClientPrint( pHL2Player, HUD_PRINTTALK, szReturnString );
}
else
{
if ( Q_stristr( szModelName, "models/human") )
{
pHL2Player->ChangeTeam( TEAM_REBELS );
}
else
{
pHL2Player->ChangeTeam( TEAM_COMBINE );
}
}
}
if ( sv_report_client_settings.GetInt() == 1 )
{
UTIL_LogPrintf( "\"%s\" cl_cmdrate = \"%s\"\n", pHL2Player->GetPlayerName(), engine->GetClientConVarValue( pHL2Player->entindex(), "cl_cmdrate" ));
}

BaseClass::ClientSettingsChanged( pPlayer );
#endif

}

int CHL2MPRules::PlayerRelationship( CBaseEntity *pPlayer, CBaseEntity *pTarget )
{
#ifndef CLIENT_DLL
// half life multiplay has a simple concept of Player Relationships.
// you are either on another player's team, or you are not.
if ( !pPlayer || !pTarget || !pTarget->IsPlayer() || IsTeamplay() == false )
return GR_NOTTEAMMATE;

if ( (*GetTeamID(pPlayer) != '\0') && (*GetTeamID(pTarget) != '\0') && !stricmp( GetTeamID(pPlayer), GetTeamID(pTarget) ) )
{
return GR_TEAMMATE;
}
#endif

return GR_NOTTEAMMATE;
}

const char *CHL2MPRules::GetGameDescription( void )
{
if ( IsTeamplay() )
return "Team Deathmatch";

return "Deathmatch";
}

float CHL2MPRules::GetMapRemainingTime()
{
// if timelimit is disabled, return 0
if ( mp_timelimit.GetInt() <= 0 )
return 0;

// timelimit is in minutes

float timeleft = (m_flGameStartTime + mp_timelimit.GetInt() * 60.0f ) - gpGlobals->curtime;

return timeleft;
}

//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CHL2MPRules::Precache( void )
{
CBaseEntity::PrecacheScriptSound( "AlyxEmp.Charge" );
}

bool CHL2MPRules::ShouldCollide( int collisionGroup0, int collisionGroup1 )
{
if ( collisionGroup0 > collisionGroup1 )
{
// swap so that lowest is always first
swap(collisionGroup0,collisionGroup1);
}

if ( (collisionGroup0 == COLLISION_GROUP_PLAYER || collisionGroup0 == COLLISION_GROUP_PLAYER_MOVEMENT) &&
collisionGroup1 == COLLISION_GROUP_WEAPON )
{
return false;
}

return BaseClass::ShouldCollide( collisionGroup0, collisionGroup1 );

}

bool CHL2MPRules::ClientCommand(const char *pcmd, CBaseEntity *pEdict )
{

#ifndef CLIENT_DLL
if( BaseClass::ClientCommand(pcmd, pEdict) )
return true;

CHL2MP_Player *pPlayer = (CHL2MP_Player *) pEdict;

if ( pPlayer->ClientCommand( pcmd ) )
return true;
#endif

return false;
}

// 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 3.5
// 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;

def.AddAmmoType("AR2", DMG_BULLET, TRACER_LINE_AND_WHIZ, "sk_plr_dmg_ar2", "sk_npc_dmg_ar2", "sk_max_ar2", BULLET_IMPULSE(200, 1225), 0 );
def.AddAmmoType("AlyxGun", DMG_BULLET, TRACER_LINE, "sk_plr_dmg_alyxgun", "sk_npc_dmg_alyxgun", "sk_max_alyxgun", BULLET_IMPULSE(200, 1225), 0 );
def.AddAmmoType("Pistol", DMG_BULLET, TRACER_LINE_AND_WHIZ, "sk_plr_dmg_pistol", "sk_npc_dmg_pistol", "sk_max_pistol", BULLET_IMPULSE(200, 1225), 0 );
def.AddAmmoType("SMG1", DMG_BULLET, TRACER_LINE_AND_WHIZ, "sk_plr_dmg_smg1", "sk_npc_dmg_smg1", "sk_max_smg1", BULLET_IMPULSE(200, 1225), 0 );
def.AddAmmoType("357", DMG_BULLET, TRACER_LINE_AND_WHIZ, "sk_plr_dmg_357", "sk_npc_dmg_357", "sk_max_357", BULLET_IMPULSE(800, 5000), 0 );
def.AddAmmoType("XBowBolt", DMG_BULLET, TRACER_LINE, "sk_plr_dmg_crossbow", "sk_npc_dmg_crossbow", "sk_max_crossbow", BULLET_IMPULSE(800, 8000), 0 );

def.AddAmmoType("Buckshot", DMG_BULLET | DMG_BUCKSHOT, TRACER_LINE, "sk_plr_dmg_buckshot", "sk_npc_dmg_buckshot", "sk_max_buckshot", BULLET_IMPULSE(400, 1200), 0 );
def.AddAmmoType("RPG_Round", DMG_BURN, TRACER_NONE, "sk_plr_dmg_rpg_round", "sk_npc_dmg_rpg_round", "sk_max_rpg_round", 0, 0 );
def.AddAmmoType("SMG1_Grenade", DMG_BURN, TRACER_NONE, "sk_plr_dmg_smg1_grenade", "sk_npc_dmg_smg1_grenade", "sk_max_smg1_grenade", 0, 0 );
// def.AddAmmoType("SniperRound", DMG_BULLET | DMG_SNIPER, TRACER_NONE, "sk_plr_dmg_sniper_round", "sk_npc_dmg_sniper_round", "sk_max_sniper_round", BULLET_IMPULSE(650, 6000), 0 );
// def.AddAmmoType("SniperPenetratedRound", DMG_BULLET | DMG_SNIPER, TRACER_NONE, "sk_dmg_sniper_penetrate_plr", "sk_dmg_sniper_penetrate_npc", "sk_max_sniper_round", BULLET_IMPULSE(150, 6000), 0 );
def.AddAmmoType("Grenade", DMG_BURN, TRACER_NONE, "sk_plr_dmg_grenade", "sk_npc_dmg_grenade", "sk_max_grenade", 0, 0);
def.AddAmmoType("Thumper", DMG_SONIC, TRACER_NONE, 10, 10, 2, 0, 0 );
def.AddAmmoType("Gravity", DMG_CLUB, TRACER_NONE, 0, 0, 8, 0, 0 );
// def.AddAmmoType("Extinguisher", DMG_BURN, TRACER_NONE, 0, 0, 100, 0, 0 );
def.AddAmmoType("Battery", DMG_CLUB, TRACER_NONE, NULL, NULL, NULL, 0, 0 );
def.AddAmmoType("GaussEnergy", DMG_SHOCK, TRACER_NONE, "sk_jeep_gauss_damage", "sk_jeep_gauss_damage", "sk_max_gauss_round", BULLET_IMPULSE(650, 8000), 0 ); // hit like a 10kg weight at 400 in/s
def.AddAmmoType("CombineCannon", DMG_BULLET, TRACER_LINE, "sk_npc_dmg_gunship_to_plr", "sk_npc_dmg_gunship", NULL, 1.5 * 750 * 12, 0 ); // hit like a 1.5kg weight at 750 ft/s
def.AddAmmoType("AirboatGun", DMG_AIRBOAT, TRACER_LINE, "sk_plr_dmg_airboat", "sk_npc_dmg_airboat", NULL, BULLET_IMPULSE(10, 600), 0 );
def.AddAmmoType("StriderMinigun", DMG_BULLET, TRACER_LINE, 5, 5, 15, 1.0 * 750 * 12, AMMO_FORCE_DROP_IF_CARRIED ); // hit like a 1.0kg weight at 750 ft/s
def.AddAmmoType("StriderMinigunDirect", DMG_BULLET, TRACER_LINE, 2, 2, 15, 1.0 * 750 * 12, AMMO_FORCE_DROP_IF_CARRIED ); // hit like a 1.0kg weight at 750 ft/s
def.AddAmmoType("HelicopterGun", DMG_BULLET, TRACER_LINE_AND_WHIZ, "sk_npc_dmg_helicopter_to_plr", "sk_npc_dmg_helicopter", "sk_max_smg1", BULLET_IMPULSE(400, 1225), AMMO_FORCE_DROP_IF_CARRIED | AMMO_INTERPRET_PLRDAMAGE_AS_DAMAGE_TO_PLAYER );
def.AddAmmoType("AR2AltFire", DMG_DISSOLVE, TRACER_NONE, 0, 0, "sk_max_ar2_altfire", 0, 0 );
def.AddAmmoType("Grenade", DMG_BURN, TRACER_NONE, "sk_plr_dmg_grenade", "sk_npc_dmg_grenade", "sk_max_grenade", 0, 0);
#ifdef HL2_EPISODIC
def.AddAmmoType("Hopwire", DMG_BLAST, TRACER_NONE, "sk_plr_dmg_grenade", "sk_npc_dmg_grenade", "sk_max_hopwire", 0, 0);
def.AddAmmoType("CombineHeavyCannon", DMG_BULLET, TRACER_LINE, 40, 40, NULL, 1.5 * 750 * 12, AMMO_FORCE_DROP_IF_CARRIED ); // hit like a 100 kg weight at 750 ft/s
#endif // HL2_EPISODIC

//def.AddAmmoType("AR2", DMG_BULLET, TRACER_LINE_AND_WHIZ, 0, 0, 60, BULLET_IMPULSE(200, 1225), 0 );
//def.AddAmmoType("AR2AltFire", DMG_DISSOLVE, TRACER_NONE, 0, 0, 3, 0, 0 );
//def.AddAmmoType("Pistol", DMG_BULLET, TRACER_LINE_AND_WHIZ, 0, 0, 150, BULLET_IMPULSE(200, 1225), 0 );
//def.AddAmmoType("SMG1", DMG_BULLET, TRACER_LINE_AND_WHIZ, 0, 0, 225, BULLET_IMPULSE(200, 1225), 0 );
//def.AddAmmoType("357", DMG_BULLET, TRACER_LINE_AND_WHIZ, 0, 0, 12, BULLET_IMPULSE(800, 5000), 0 );
//def.AddAmmoType("XBowBolt", DMG_BULLET, TRACER_LINE, 0, 0, 10, BULLET_IMPULSE(800, 8000), 0 );
//def.AddAmmoType("Buckshot", DMG_BULLET | DMG_BUCKSHOT, TRACER_LINE, 0, 0, 30, BULLET_IMPULSE(400, 1200), 0 );
//def.AddAmmoType("RPG_Round", DMG_BURN, TRACER_NONE, 0, 0, 3, 0, 0 );
//def.AddAmmoType("SMG1_Grenade", DMG_BURN, TRACER_NONE, 0, 0, 3, 0, 0 );
//def.AddAmmoType("Grenade", DMG_BURN, TRACER_NONE, 0, 0, 5, 0, 0 );
//def.AddAmmoType("slam", DMG_BURN, TRACER_NONE, 0, 0, 5, 0, 0 );
}

return &def;
}

#ifdef CLIENT_DLL

ConVar cl_autowepswitch(
"cl_autowepswitch",
"1",
FCVAR_ARCHIVE | FCVAR_USERINFO,
"Automatically switch to picked up weapons (if more powerful)" );

#else

#ifdef DEBUG

// Handler for the "bot" command.
void Bot_f()
{
// Look at -count.
int count = 1;
count = clamp( count, 1, 16 );

int iTeam = TEAM_COMBINE;

// Look at -frozen.
bool bFrozen = false;

// Ok, spawn all the bots.
while ( --count >= 0 )
{
BotPutInServer( bFrozen, iTeam );
}
}

ConCommand cc_Bot( "bot", Bot_f, "Add a bot.", FCVAR_CHEAT );

#endif

bool CHL2MPRules::FShouldSwitchWeapon( CBasePlayer *pPlayer, CBaseCombatWeapon *pWeapon )
{
if ( pPlayer->GetActiveWeapon() && pPlayer->IsNetClient() )
{
// Player has an active item, so let's check cl_autowepswitch.
const char *cl_autowepswitch = engine->GetClientConVarValue( engine->IndexOfEdict( pPlayer->edict() ), "cl_autowepswitch" );
if ( cl_autowepswitch && atoi( cl_autowepswitch ) <= 0 )
{
return false;
}
}

return BaseClass::FShouldSwitchWeapon( pPlayer, pWeapon );
}

#endif

#ifndef CLIENT_DLL

bool FindInList( const char **pStrings, const char *pToFind )
{
int i = 0;
while ( pStrings[i][0] != 0 )
{
if ( Q_stricmp( pStrings[i], pToFind ) == 0 )
return true;
i++;
}

return false;
}

void CHL2MPRules::RestartGame()
{
// bounds check
if ( mp_timelimit.GetInt() < 0 )
{
mp_timelimit.SetValue( 0 );
}
m_flGameStartTime = gpGlobals->curtime;
if ( !IsFinite( m_flGameStartTime.Get() ) )
{
Warning( "Trying to set a NaN game start time\n" );
m_flGameStartTime.GetForModify() = 0.0f;
}

CleanUpMap();

// now respawn all players
for (int i = 1; i <= gpGlobals->maxClients; i++ )
{
CHL2MP_Player *pPlayer = (CHL2MP_Player*) UTIL_PlayerByIndex( i );

if ( !pPlayer )
continue;

if ( pPlayer->GetActiveWeapon() )
{
pPlayer->GetActiveWeapon()->Holster();
}
pPlayer->RemoveAllItems( true );
respawn( pPlayer, false );
pPlayer->Reset();
}

// Respawn entities (glass, doors, etc..)

CTeam *pRebels = GetGlobalTeam( TEAM_REBELS );
CTeam *pCombine = GetGlobalTeam( TEAM_COMBINE );

if ( pRebels )
{
pRebels->SetScore( 0 );
}

if ( pCombine )
{
pCombine->SetScore( 0 );
}

m_flIntermissionEndTime = 0;
m_flRestartGameTime = 0.0;
m_bCompleteReset = false;

IGameEvent * event = gameeventmanager->CreateEvent( "round_start" );
if ( event )
{
event->SetInt("fraglimit", 0 );
event->SetInt( "priority", 6 ); // HLTV event priority, not transmitted

event->SetString("objective","DEATHMATCH");

gameeventmanager->FireEvent( event );
}
}

void CHL2MPRules::CleanUpMap()
{
// Recreate all the map entities from the map data (preserving their indices),
// then remove everything else except the players.

// Get rid of all entities except players.
CBaseEntity *pCur = gEntList.FirstEnt();
while ( pCur )
{
CBaseHL2MPCombatWeapon *pWeapon = dynamic_cast< CBaseHL2MPCombatWeapon* >( pCur );
// Weapons with owners don't want to be removed..
if ( pWeapon )
{
if ( !pWeapon->GetPlayerOwner() )
{
UTIL_Remove( pCur );
}
}
// remove entities that has to be restored on roundrestart (breakables etc)
else if ( !FindInList( s_PreserveEnts, pCur->GetClassname() ) )
{
UTIL_Remove( pCur );
}

pCur = gEntList.NextEnt( pCur );
}

// Really remove the entities so we can have access to their slots below.
gEntList.CleanupDeleteList();

// Cancel all queued events, in case a func_bomb_target fired some delayed outputs that
// could kill respawning CTs
g_EventQueue.Clear();

// Now reload the map entities.
class CHL2MPMapEntityFilter : public IMapEntityFilter
{
public:
virtual bool ShouldCreateEntity( const char *pClassname )
{
// Don't recreate the preserved entities.
if ( !FindInList( s_PreserveEnts, pClassname ) )
{
return true;
}
else
{
// Increment our iterator since it's not going to call CreateNextEntity for this ent.
if ( m_iIterator != g_MapEntityRefs.InvalidIndex() )
m_iIterator = g_MapEntityRefs.Next( m_iIterator );

return false;
}
}

virtual CBaseEntity* CreateNextEntity( const char *pClassname )
{
if ( m_iIterator == g_MapEntityRefs.InvalidIndex() )
{
// This shouldn't be possible. When we loaded the map, it should have used
// CCSMapLoadEntityFilter, which should have built the g_MapEntityRefs list
// with the same list of entities we're referring to here.
Assert( false );
return NULL;
}
else
{
CMapEntityRef &ref = g_MapEntityRefs[m_iIterator];
m_iIterator = g_MapEntityRefs.Next( m_iIterator ); // Seek to the next entity.

if ( ref.m_iEdict == -1 || engine->PEntityOfEntIndex( ref.m_iEdict ) )
{
// Doh! The entity was delete and its slot was reused.
// Just use any old edict slot. This case sucks because we lose the baseline.
return CreateEntityByName( pClassname );
}
else
{
// Cool, the slot where this entity was is free again (most likely, the entity was
// freed above). Now create an entity with this specific index.
return CreateEntityByName( pClassname, ref.m_iEdict );
}
}
}

public:
int m_iIterator; // Iterator into g_MapEntityRefs.
};
CHL2MPMapEntityFilter filter;
filter.m_iIterator = g_MapEntityRefs.Head();

// DO NOT CALL SPAWN ON info_node ENTITIES!

MapEntity_ParseAllEntities( engine->GetMapEntitiesString(), &filter, true );
}

void CHL2MPRules::CheckChatForReadySignal( CHL2MP_Player *pPlayer, const char *chatmsg )
{
if( m_bAwaitingReadyRestart && FStrEq( chatmsg, mp_ready_signal.GetString() ) )
{
if( !pPlayer->IsReady() )
{
pPlayer->SetReady( true );
}
}
}

void CHL2MPRules::CheckRestartGame( void )
{
// Restart the game if specified by the server
int iRestartDelay = mp_restartgame.GetInt();

if ( iRestartDelay > 0 )
{
if ( iRestartDelay > 60 )
iRestartDelay = 60;

// let the players know
char strRestartDelay[64];
Q_snprintf( strRestartDelay, sizeof( strRestartDelay ), "%d", iRestartDelay );
UTIL_ClientPrintAll( HUD_PRINTCENTER, "Game will restart in %s1 %s2", strRestartDelay, iRestartDelay == 1 ? "SECOND" : "SECONDS" );
UTIL_ClientPrintAll( HUD_PRINTCONSOLE, "Game will restart in %s1 %s2", strRestartDelay, iRestartDelay == 1 ? "SECOND" : "SECONDS" );

m_flRestartGameTime = gpGlobals->curtime + iRestartDelay;
m_bCompleteReset = true;
mp_restartgame.SetValue( 0 );
}

if( mp_readyrestart.GetBool() )
{
m_bAwaitingReadyRestart = true;
m_bHeardAllPlayersReady = false;

const char *pszReadyString = mp_ready_signal.GetString();

// Don't let them put anything malicious in there
if( pszReadyString == NULL || Q_strlen(pszReadyString) > 16 )
{
pszReadyString = "ready";
}

IGameEvent *event = gameeventmanager->CreateEvent( "hl2mp_ready_restart" );
if ( event )
gameeventmanager->FireEvent( event );

mp_readyrestart.SetValue( 0 );

// cancel any restart round in progress
m_flRestartGameTime = -1;
}
}

void CHL2MPRules::CheckAllPlayersReady( void )
{
for (int i = 1; i <= gpGlobals->maxClients; i++ )
{
CHL2MP_Player *pPlayer = (CHL2MP_Player*) UTIL_PlayerByIndex( i );

if ( !pPlayer )
continue;
if ( !pPlayer->IsReady() )
return;
}
m_bHeardAllPlayersReady = true;
}

// EDIT IH //
//------------------------------------------------------------------------------
// Purpose : Initialize all default class relationships
// Input :
// Output :
//------------------------------------------------------------------------------
#ifndef CLIENT_DLL
void CHL2MPRules::InitDefaultAIRelationships( void )
{
int i, j;

// Allocate memory for default relationships
CBaseCombatCharacter::AllocateDefaultRelationships();

// --------------------------------------------------------------
// First initialize table so we can report missing relationships
// --------------------------------------------------------------
for (i=0;i<NUM_AI_CLASSES;i++)
{
for (j=0;j<NUM_AI_CLASSES;j++)
{
// By default all relationships are neutral of priority zero
CBaseCombatCharacter::SetDefaultRelationship( (Class_T)i, (Class_T)j, D_NU, 0 );
}
}

// ------------------------------------------------------------
// > CLASS_ANTLION
// ------------------------------------------------------------
CBaseCombatCharacter::SetDefaultRelationship(CLASS_ANTLION, CLASS_NONE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_ANTLION, CLASS_PLAYER, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_ANTLION, CLASS_BARNACLE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_ANTLION, CLASS_BULLSEYE, D_NU, 0);
//CBaseCombatCharacter::SetDefaultRelationship(CLASS_ANTLION, CLASS_BULLSQUID, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_ANTLION, CLASS_CITIZEN_PASSIVE, D_HT, 99);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_ANTLION, CLASS_CITIZEN_REBEL, D_HT, 99);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_ANTLION, CLASS_COMBINE, D_HT, 99);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_ANTLION, CLASS_COMBINE_GUNSHIP, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_ANTLION, CLASS_CONSCRIPT, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_ANTLION, CLASS_FLARE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_ANTLION, CLASS_HEADCRAB, D_HT, 0);
//CBaseCombatCharacter::SetDefaultRelationship(CLASS_ANTLION, CLASS_HOUNDEYE, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_ANTLION, CLASS_MANHACK, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_ANTLION, CLASS_METROPOLICE, D_HT, 99);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_ANTLION, CLASS_MILITARY, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_ANTLION, CLASS_MISSILE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_ANTLION, CLASS_SCANNER, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_ANTLION, CLASS_STALKER, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_ANTLION, CLASS_VORTIGAUNT, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_ANTLION, CLASS_ZOMBIE, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_ANTLION, CLASS_PROTOSNIPER, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_ANTLION, CLASS_ANTLION, D_LI, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_ANTLION, CLASS_EARTH_FAUNA, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_ANTLION, CLASS_PLAYER_ALLY, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_ANTLION, CLASS_PLAYER_ALLY_VITAL,D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_ANTLION, CLASS_HACKED_ROLLERMINE,D_HT, 0);

// ------------------------------------------------------------
// > CLASS_BARNACLE
//
// In this case, the relationship D_HT indicates which characters
// the barnacle will try to eat.
// ------------------------------------------------------------
CBaseCombatCharacter::SetDefaultRelationship(CLASS_BARNACLE, CLASS_NONE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_BARNACLE, CLASS_PLAYER, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_BARNACLE, CLASS_ANTLION, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_BARNACLE, CLASS_BARNACLE, D_LI, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_BARNACLE, CLASS_BULLSEYE, D_NU, 0);
//CBaseCombatCharacter::SetDefaultRelationship(CLASS_BARNACLE, CLASS_BULLSQUID, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_BARNACLE, CLASS_CITIZEN_PASSIVE, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_BARNACLE, CLASS_CITIZEN_REBEL, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_BARNACLE, CLASS_COMBINE, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_BARNACLE, CLASS_COMBINE_GUNSHIP, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_BARNACLE, CLASS_CONSCRIPT, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_BARNACLE, CLASS_FLARE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_BARNACLE, CLASS_HEADCRAB, D_HT, 0);
//CBaseCombatCharacter::SetDefaultRelationship(CLASS_BARNACLE, CLASS_HOUNDEYE, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_BARNACLE, CLASS_MANHACK, D_FR, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_BARNACLE, CLASS_METROPOLICE, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_BARNACLE, CLASS_MILITARY, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_BARNACLE, CLASS_MISSILE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_BARNACLE, CLASS_SCANNER, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_BARNACLE, CLASS_STALKER, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_BARNACLE, CLASS_VORTIGAUNT, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_BARNACLE, CLASS_ZOMBIE, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_BARNACLE, CLASS_PROTOSNIPER, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_BARNACLE, CLASS_EARTH_FAUNA, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_BARNACLE, CLASS_PLAYER_ALLY, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_BARNACLE, CLASS_PLAYER_ALLY_VITAL,D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_BARNACLE, CLASS_HACKED_ROLLERMINE,D_HT, 0);

// ------------------------------------------------------------
// > CLASS_BULLSEYE
// ------------------------------------------------------------
CBaseCombatCharacter::SetDefaultRelationship(CLASS_BULLSEYE, CLASS_NONE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_BULLSEYE, CLASS_PLAYER, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_BULLSEYE, CLASS_ANTLION, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_BULLSEYE, CLASS_BARNACLE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_BULLSEYE, CLASS_BULLSEYE, D_NU, 0);
//CBaseCombatCharacter::SetDefaultRelationship(CLASS_BULLSEYE, CLASS_BULLSQUID, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_BULLSEYE, CLASS_CITIZEN_PASSIVE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_BULLSEYE, CLASS_CITIZEN_REBEL, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_BULLSEYE, CLASS_COMBINE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_BULLSEYE, CLASS_COMBINE_GUNSHIP, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_BULLSEYE, CLASS_CONSCRIPT, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_BULLSEYE, CLASS_FLARE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_BULLSEYE, CLASS_HEADCRAB, D_NU, 0);
//CBaseCombatCharacter::SetDefaultRelationship(CLASS_BULLSEYE, CLASS_HOUNDEYE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_BULLSEYE, CLASS_MANHACK, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_BULLSEYE, CLASS_METROPOLICE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_BULLSEYE, CLASS_MILITARY, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_BULLSEYE, CLASS_MISSILE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_BULLSEYE, CLASS_SCANNER, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_BULLSEYE, CLASS_STALKER, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_BULLSEYE, CLASS_VORTIGAUNT, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_BULLSEYE, CLASS_ZOMBIE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_BULLSEYE, CLASS_PROTOSNIPER, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_BULLSEYE, CLASS_EARTH_FAUNA, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_BULLSEYE, CLASS_PLAYER_ALLY, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_BULLSEYE, CLASS_PLAYER_ALLY_VITAL,D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_BULLSEYE, CLASS_HACKED_ROLLERMINE,D_NU, 0);

// ------------------------------------------------------------
// > CLASS_BULLSQUID
// ------------------------------------------------------------
/*
CBaseCombatCharacter::SetDefaultRelationship(CLASS_BULLSQUID, CLASS_NONE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_BULLSQUID, CLASS_PLAYER, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_BULLSQUID, CLASS_ANTLION, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_BULLSQUID, CLASS_BARNACLE, D_FR, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_BULLSQUID, CLASS_BULLSEYE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_BULLSQUID, CLASS_BULLSQUID, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_BULLSQUID, CLASS_CITIZEN_PASSIVE, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_BULLSQUID, CLASS_CITIZEN_REBEL, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_BULLSQUID, CLASS_COMBINE, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_BULLSQUID, CLASS_COMBINE_GUNSHIP, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_BULLSQUID, CLASS_CONSCRIPT, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_BULLSQUID, CLASS_FLARE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_BULLSQUID, CLASS_HEADCRAB, D_HT, 1);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_BULLSQUID, CLASS_HOUNDEYE, D_HT, 1);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_BULLSQUID, CLASS_MANHACK, D_FR, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_BULLSQUID, CLASS_METROPOLICE, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_BULLSQUID, CLASS_MILITARY, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_BULLSQUID, CLASS_MISSILE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_BULLSQUID, CLASS_SCANNER, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_BULLSQUID, CLASS_STALKER, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_BULLSQUID, CLASS_VORTIGAUNT, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_BULLSQUID, CLASS_ZOMBIE, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_BULLSQUID, CLASS_PROTOSNIPER, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_BULLSQUID, CLASS_EARTH_FAUNA, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_BULLSQUID, CLASS_PLAYER_ALLY, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_BULLSQUID, CLASS_PLAYER_ALLY_VITAL,D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_BULLSQUID, CLASS_HACKED_ROLLERMINE,D_HT, 0);
*/
// ------------------------------------------------------------
// > CLASS_CITIZEN_PASSIVE
// ------------------------------------------------------------
CBaseCombatCharacter::SetDefaultRelationship(CLASS_CITIZEN_PASSIVE, CLASS_NONE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_CITIZEN_PASSIVE, CLASS_PLAYER, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_CITIZEN_PASSIVE, CLASS_ANTLION, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_CITIZEN_PASSIVE, CLASS_BARNACLE, D_FR, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_CITIZEN_PASSIVE, CLASS_BULLSEYE, D_NU, 0);
//CBaseCombatCharacter::SetDefaultRelationship(CLASS_CITIZEN_PASSIVE, CLASS_BULLSQUID, D_FR, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_CITIZEN_PASSIVE, CLASS_CITIZEN_PASSIVE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_CITIZEN_PASSIVE, CLASS_CITIZEN_REBEL, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_CITIZEN_PASSIVE, CLASS_COMBINE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_CITIZEN_PASSIVE, CLASS_COMBINE_GUNSHIP, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_CITIZEN_PASSIVE, CLASS_CONSCRIPT, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_CITIZEN_PASSIVE, CLASS_FLARE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_CITIZEN_PASSIVE, CLASS_HEADCRAB, D_FR, 0);
//CBaseCombatCharacter::SetDefaultRelationship(CLASS_CITIZEN_PASSIVE, CLASS_HOUNDEYE, D_FR, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_CITIZEN_PASSIVE, CLASS_MANHACK, D_FR, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_CITIZEN_PASSIVE, CLASS_METROPOLICE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_CITIZEN_PASSIVE, CLASS_MILITARY, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_CITIZEN_PASSIVE, CLASS_MISSILE, D_FR, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_CITIZEN_PASSIVE, CLASS_SCANNER, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_CITIZEN_PASSIVE, CLASS_STALKER, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_CITIZEN_PASSIVE, CLASS_VORTIGAUNT, D_LI, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_CITIZEN_PASSIVE, CLASS_ZOMBIE, D_FR, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_CITIZEN_PASSIVE, CLASS_PROTOSNIPER, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_CITIZEN_PASSIVE, CLASS_EARTH_FAUNA, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_CITIZEN_PASSIVE, CLASS_PLAYER_ALLY, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_CITIZEN_PASSIVE, CLASS_PLAYER_ALLY_VITAL,D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_CITIZEN_PASSIVE, CLASS_HACKED_ROLLERMINE,D_NU, 0);

// ------------------------------------------------------------
// > CLASS_CITIZEN_REBEL
// ------------------------------------------------------------
CBaseCombatCharacter::SetDefaultRelationship(CLASS_CITIZEN_REBEL, CLASS_NONE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_CITIZEN_REBEL, CLASS_PLAYER, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_CITIZEN_REBEL, CLASS_ANTLION, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_CITIZEN_REBEL, CLASS_BARNACLE, D_FR, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_CITIZEN_REBEL, CLASS_BULLSEYE, D_NU, 0);
//CBaseCombatCharacter::SetDefaultRelationship(CLASS_CITIZEN_REBEL, CLASS_BULLSQUID, D_FR, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_CITIZEN_REBEL, CLASS_CITIZEN_PASSIVE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_CITIZEN_REBEL, CLASS_CITIZEN_REBEL, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_CITIZEN_REBEL, CLASS_COMBINE, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_CITIZEN_REBEL, CLASS_COMBINE_GUNSHIP, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_CITIZEN_REBEL, CLASS_CONSCRIPT, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_CITIZEN_REBEL, CLASS_FLARE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_CITIZEN_REBEL, CLASS_HEADCRAB, D_HT, 0);
//CBaseCombatCharacter::SetDefaultRelationship(CLASS_CITIZEN_REBEL, CLASS_HOUNDEYE, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_CITIZEN_REBEL, CLASS_MANHACK, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_CITIZEN_REBEL, CLASS_METROPOLICE, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_CITIZEN_REBEL, CLASS_MILITARY, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_CITIZEN_REBEL, CLASS_MISSILE, D_FR, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_CITIZEN_REBEL, CLASS_SCANNER, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_CITIZEN_REBEL, CLASS_STALKER, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_CITIZEN_REBEL, CLASS_VORTIGAUNT, D_LI, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_CITIZEN_REBEL, CLASS_ZOMBIE, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_CITIZEN_REBEL, CLASS_PROTOSNIPER, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_CITIZEN_REBEL, CLASS_EARTH_FAUNA, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_CITIZEN_REBEL, CLASS_PLAYER_ALLY, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_CITIZEN_REBEL, CLASS_PLAYER_ALLY_VITAL,D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_CITIZEN_REBEL, CLASS_HACKED_ROLLERMINE,D_NU, 0);

// ------------------------------------------------------------
// > CLASS_COMBINE
// ------------------------------------------------------------
CBaseCombatCharacter::SetDefaultRelationship(CLASS_COMBINE, CLASS_NONE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_COMBINE, CLASS_PLAYER, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_COMBINE, CLASS_ANTLION, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_COMBINE, CLASS_BARNACLE, D_FR, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_COMBINE, CLASS_BULLSEYE, D_NU, 0);
//CBaseCombatCharacter::SetDefaultRelationship(CLASS_COMBINE, CLASS_BULLSQUID, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_COMBINE, CLASS_CITIZEN_PASSIVE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_COMBINE, CLASS_CITIZEN_REBEL, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_COMBINE, CLASS_COMBINE, D_LI, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_COMBINE, CLASS_COMBINE_GUNSHIP, D_LI, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_COMBINE, CLASS_CONSCRIPT, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_COMBINE, CLASS_FLARE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_COMBINE, CLASS_HEADCRAB, D_HT, 0);
//CBaseCombatCharacter::SetDefaultRelationship(CLASS_COMBINE, CLASS_HOUNDEYE, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_COMBINE, CLASS_MANHACK, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_COMBINE, CLASS_METROPOLICE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_COMBINE, CLASS_MILITARY, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_COMBINE, CLASS_MISSILE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_COMBINE, CLASS_SCANNER, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_COMBINE, CLASS_STALKER, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_COMBINE, CLASS_VORTIGAUNT, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_COMBINE, CLASS_ZOMBIE, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_COMBINE, CLASS_PROTOSNIPER, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_COMBINE, CLASS_EARTH_FAUNA, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_COMBINE, CLASS_PLAYER_ALLY, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_COMBINE, CLASS_PLAYER_ALLY_VITAL,D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_COMBINE, CLASS_HACKED_ROLLERMINE,D_HT, 0);

// ------------------------------------------------------------
// > CLASS_COMBINE_GUNSHIP
// ------------------------------------------------------------
CBaseCombatCharacter::SetDefaultRelationship(CLASS_COMBINE_GUNSHIP, CLASS_NONE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_COMBINE_GUNSHIP, CLASS_PLAYER, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_COMBINE_GUNSHIP, CLASS_ANTLION, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_COMBINE_GUNSHIP, CLASS_BARNACLE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_COMBINE_GUNSHIP, CLASS_BULLSEYE, D_NU, 0);
//CBaseCombatCharacter::SetDefaultRelationship(CLASS_COMBINE_GUNSHIP, CLASS_BULLSQUID, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_COMBINE_GUNSHIP, CLASS_CITIZEN_PASSIVE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_COMBINE_GUNSHIP, CLASS_CITIZEN_REBEL, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_COMBINE_GUNSHIP, CLASS_COMBINE, D_LI, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_COMBINE_GUNSHIP, CLASS_COMBINE_GUNSHIP, D_LI, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_COMBINE_GUNSHIP, CLASS_CONSCRIPT, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_COMBINE_GUNSHIP, CLASS_FLARE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_COMBINE_GUNSHIP, CLASS_HEADCRAB, D_NU, 0);
//CBaseCombatCharacter::SetDefaultRelationship(CLASS_COMBINE_GUNSHIP, CLASS_HOUNDEYE, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_COMBINE_GUNSHIP, CLASS_MANHACK, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_COMBINE_GUNSHIP, CLASS_METROPOLICE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_COMBINE_GUNSHIP, CLASS_MILITARY, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_COMBINE_GUNSHIP, CLASS_MISSILE, D_FR, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_COMBINE_GUNSHIP, CLASS_SCANNER, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_COMBINE_GUNSHIP, CLASS_STALKER, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_COMBINE_GUNSHIP, CLASS_VORTIGAUNT, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_COMBINE_GUNSHIP, CLASS_ZOMBIE, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_COMBINE_GUNSHIP, CLASS_PROTOSNIPER, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_COMBINE_GUNSHIP, CLASS_EARTH_FAUNA, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_COMBINE_GUNSHIP, CLASS_PLAYER_ALLY, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_COMBINE_GUNSHIP, CLASS_PLAYER_ALLY_VITAL,D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_COMBINE_GUNSHIP, CLASS_HACKED_ROLLERMINE,D_HT, 0);

// ------------------------------------------------------------
// > CLASS_CONSCRIPT
// ------------------------------------------------------------
CBaseCombatCharacter::SetDefaultRelationship(CLASS_CONSCRIPT, CLASS_NONE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_CONSCRIPT, CLASS_PLAYER, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_CONSCRIPT, CLASS_ANTLION, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_CONSCRIPT, CLASS_BARNACLE, D_FR, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_CONSCRIPT, CLASS_BULLSEYE, D_NU, 0);
//CBaseCombatCharacter::SetDefaultRelationship(CLASS_CONSCRIPT, CLASS_BULLSQUID, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_CONSCRIPT, CLASS_CITIZEN_PASSIVE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_CONSCRIPT, CLASS_CITIZEN_REBEL, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_CONSCRIPT, CLASS_COMBINE, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_CONSCRIPT, CLASS_COMBINE_GUNSHIP, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_CONSCRIPT, CLASS_CONSCRIPT, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_CONSCRIPT, CLASS_FLARE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_CONSCRIPT, CLASS_HEADCRAB, D_HT, 0);
//CBaseCombatCharacter::SetDefaultRelationship(CLASS_CONSCRIPT, CLASS_HOUNDEYE, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_CONSCRIPT, CLASS_MANHACK, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_CONSCRIPT, CLASS_METROPOLICE, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_CONSCRIPT, CLASS_MILITARY, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_CONSCRIPT, CLASS_MISSILE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_CONSCRIPT, CLASS_SCANNER, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_CONSCRIPT, CLASS_STALKER, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_CONSCRIPT, CLASS_VORTIGAUNT, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_CONSCRIPT, CLASS_ZOMBIE, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_CONSCRIPT, CLASS_PROTOSNIPER, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_CONSCRIPT, CLASS_EARTH_FAUNA, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_CONSCRIPT, CLASS_PLAYER_ALLY, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_CONSCRIPT, CLASS_PLAYER_ALLY_VITAL,D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_CONSCRIPT, CLASS_HACKED_ROLLERMINE,D_NU, 0);

// ------------------------------------------------------------
// > CLASS_FLARE
// ------------------------------------------------------------
CBaseCombatCharacter::SetDefaultRelationship(CLASS_FLARE, CLASS_NONE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_FLARE, CLASS_PLAYER, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_FLARE, CLASS_ANTLION, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_FLARE, CLASS_BARNACLE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_FLARE, CLASS_BULLSEYE, D_NU, 0);
//CBaseCombatCharacter::SetDefaultRelationship(CLASS_FLARE, CLASS_BULLSQUID, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_FLARE, CLASS_CITIZEN_PASSIVE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_FLARE, CLASS_CITIZEN_REBEL, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_FLARE, CLASS_COMBINE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_FLARE, CLASS_COMBINE_GUNSHIP, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_FLARE, CLASS_CONSCRIPT, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_FLARE, CLASS_FLARE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_FLARE, CLASS_HEADCRAB, D_NU, 0);
//CBaseCombatCharacter::SetDefaultRelationship(CLASS_FLARE, CLASS_HOUNDEYE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_FLARE, CLASS_MANHACK, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_FLARE, CLASS_METROPOLICE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_FLARE, CLASS_MILITARY, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_FLARE, CLASS_MISSILE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_FLARE, CLASS_FLARE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_FLARE, CLASS_SCANNER, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_FLARE, CLASS_STALKER, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_FLARE, CLASS_VORTIGAUNT, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_FLARE, CLASS_ZOMBIE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_FLARE, CLASS_PROTOSNIPER, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_FLARE, CLASS_EARTH_FAUNA, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_FLARE, CLASS_PLAYER_ALLY, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_FLARE, CLASS_PLAYER_ALLY_VITAL,D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_FLARE, CLASS_HACKED_ROLLERMINE,D_NU, 0);

// ------------------------------------------------------------
// > CLASS_HEADCRAB
// ------------------------------------------------------------
CBaseCombatCharacter::SetDefaultRelationship(CLASS_HEADCRAB, CLASS_NONE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_HEADCRAB, CLASS_PLAYER, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_HEADCRAB, CLASS_ANTLION, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_HEADCRAB, CLASS_BARNACLE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_HEADCRAB, CLASS_BULLSEYE, D_NU, 0);
//CBaseCombatCharacter::SetDefaultRelationship(CLASS_HEADCRAB, CLASS_BULLSQUID, D_FR, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_HEADCRAB, CLASS_CITIZEN_PASSIVE, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_HEADCRAB, CLASS_CITIZEN_REBEL, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_HEADCRAB, CLASS_COMBINE, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_HEADCRAB, CLASS_COMBINE_GUNSHIP, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_HEADCRAB, CLASS_CONSCRIPT, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_HEADCRAB, CLASS_FLARE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_HEADCRAB, CLASS_HEADCRAB, D_NU, 0);
//CBaseCombatCharacter::SetDefaultRelationship(CLASS_HEADCRAB, CLASS_HOUNDEYE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_HEADCRAB, CLASS_MANHACK, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_HEADCRAB, CLASS_METROPOLICE, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_HEADCRAB, CLASS_MILITARY, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_HEADCRAB, CLASS_MISSILE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_HEADCRAB, CLASS_SCANNER, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_HEADCRAB, CLASS_STALKER, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_HEADCRAB, CLASS_VORTIGAUNT, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_HEADCRAB, CLASS_ZOMBIE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_HEADCRAB, CLASS_PROTOSNIPER, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_HEADCRAB, CLASS_EARTH_FAUNA, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_HEADCRAB, CLASS_PLAYER_ALLY, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_HEADCRAB, CLASS_PLAYER_ALLY_VITAL,D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_HEADCRAB, CLASS_HACKED_ROLLERMINE,D_FR, 0);

// ------------------------------------------------------------
// > CLASS_HOUNDEYE
// ------------------------------------------------------------
/*
CBaseCombatCharacter::SetDefaultRelationship(CLASS_HOUNDEYE, CLASS_NONE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_HOUNDEYE, CLASS_PLAYER, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_HOUNDEYE, CLASS_ANTLION, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_HOUNDEYE, CLASS_BARNACLE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_HOUNDEYE, CLASS_BULLSEYE, D_NU, 0);
//CBaseCombatCharacter::SetDefaultRelationship(CLASS_HOUNDEYE, CLASS_BULLSQUID, D_FR, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_HOUNDEYE, CLASS_CITIZEN_PASSIVE, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_HOUNDEYE, CLASS_CITIZEN_REBEL, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_HOUNDEYE, CLASS_COMBINE, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_HOUNDEYE, CLASS_COMBINE_GUNSHIP, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_HOUNDEYE, CLASS_CONSCRIPT, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_HOUNDEYE, CLASS_FLARE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_HOUNDEYE, CLASS_HEADCRAB, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_HOUNDEYE, CLASS_HOUNDEYE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_HOUNDEYE, CLASS_MANHACK, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_HOUNDEYE, CLASS_METROPOLICE, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_HOUNDEYE, CLASS_MILITARY, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_HOUNDEYE, CLASS_MISSILE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_HOUNDEYE, CLASS_SCANNER, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_HOUNDEYE, CLASS_STALKER, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_HOUNDEYE, CLASS_VORTIGAUNT, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_HOUNDEYE, CLASS_ZOMBIE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_HOUNDEYE, CLASS_PROTOSNIPER, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_HOUNDEYE, CLASS_EARTH_FAUNA, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_HOUNDEYE, CLASS_PLAYER_ALLY, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_HOUNDEYE, CLASS_PLAYER_ALLY_VITAL,D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_HOUNDEYE, CLASS_HACKED_ROLLERMINE,D_HT, 0);
*/

// ------------------------------------------------------------
// > CLASS_MANHACK
// ------------------------------------------------------------
CBaseCombatCharacter::SetDefaultRelationship(CLASS_MANHACK, CLASS_NONE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_MANHACK, CLASS_PLAYER, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_MANHACK, CLASS_ANTLION, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_MANHACK, CLASS_BARNACLE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_MANHACK, CLASS_BULLSEYE, D_NU, 0);
//CBaseCombatCharacter::SetDefaultRelationship(CLASS_MANHACK, CLASS_BULLSQUID, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_MANHACK, CLASS_CITIZEN_PASSIVE, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_MANHACK, CLASS_CITIZEN_REBEL, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_MANHACK, CLASS_COMBINE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_MANHACK, CLASS_COMBINE_GUNSHIP, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_MANHACK, CLASS_CONSCRIPT, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_MANHACK, CLASS_FLARE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_MANHACK, CLASS_HEADCRAB, D_HT,-1);
//CBaseCombatCharacter::SetDefaultRelationship(CLASS_MANHACK, CLASS_HOUNDEYE, D_HT,-1);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_MANHACK, CLASS_MANHACK, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_MANHACK, CLASS_METROPOLICE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_MANHACK, CLASS_MILITARY, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_MANHACK, CLASS_MISSILE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_MANHACK, CLASS_SCANNER, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_MANHACK, CLASS_STALKER, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_MANHACK, CLASS_VORTIGAUNT, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_MANHACK, CLASS_ZOMBIE, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_MANHACK, CLASS_PROTOSNIPER, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_MANHACK, CLASS_EARTH_FAUNA, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_MANHACK, CLASS_PLAYER_ALLY, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_MANHACK, CLASS_PLAYER_ALLY_VITAL,D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_MANHACK, CLASS_HACKED_ROLLERMINE,D_HT, 0);

// ------------------------------------------------------------
// > CLASS_METROPOLICE
// ------------------------------------------------------------
CBaseCombatCharacter::SetDefaultRelationship(CLASS_METROPOLICE, CLASS_NONE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_METROPOLICE, CLASS_PLAYER, D_HT, 99);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_METROPOLICE, CLASS_ANTLION, D_HT, 99);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_METROPOLICE, CLASS_BARNACLE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_METROPOLICE, CLASS_BULLSEYE, D_NU, 0);
//CBaseCombatCharacter::SetDefaultRelationship(CLASS_METROPOLICE, CLASS_BULLSQUID, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_METROPOLICE, CLASS_CITIZEN_PASSIVE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_METROPOLICE, CLASS_CITIZEN_REBEL, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_METROPOLICE, CLASS_COMBINE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_METROPOLICE, CLASS_COMBINE_GUNSHIP, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_METROPOLICE, CLASS_CONSCRIPT, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_METROPOLICE, CLASS_FLARE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_METROPOLICE, CLASS_HEADCRAB, D_HT, 0);
//CBaseCombatCharacter::SetDefaultRelationship(CLASS_METROPOLICE, CLASS_HOUNDEYE, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_METROPOLICE, CLASS_MANHACK, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_METROPOLICE, CLASS_METROPOLICE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_METROPOLICE, CLASS_MILITARY, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_METROPOLICE, CLASS_MISSILE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_METROPOLICE, CLASS_SCANNER, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_METROPOLICE, CLASS_STALKER, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_METROPOLICE, CLASS_VORTIGAUNT, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_METROPOLICE, CLASS_ZOMBIE, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_METROPOLICE, CLASS_PROTOSNIPER, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_METROPOLICE, CLASS_EARTH_FAUNA, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_METROPOLICE, CLASS_PLAYER_ALLY, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_METROPOLICE, CLASS_PLAYER_ALLY_VITAL,D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_METROPOLICE, CLASS_HACKED_ROLLERMINE,D_HT, 0);

// ------------------------------------------------------------
// > CLASS_MILITARY
// ------------------------------------------------------------
CBaseCombatCharacter::SetDefaultRelationship(CLASS_MILITARY, CLASS_NONE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_MILITARY, CLASS_PLAYER, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_MILITARY, CLASS_ANTLION, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_MILITARY, CLASS_BARNACLE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_MILITARY, CLASS_BULLSEYE, D_NU, 0);
//CBaseCombatCharacter::SetDefaultRelationship(CLASS_MILITARY, CLASS_BULLSQUID, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_MILITARY, CLASS_CITIZEN_PASSIVE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_MILITARY, CLASS_CITIZEN_REBEL, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_MILITARY, CLASS_COMBINE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_MILITARY, CLASS_COMBINE_GUNSHIP, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_MILITARY, CLASS_CONSCRIPT, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_MILITARY, CLASS_FLARE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_MILITARY, CLASS_HEADCRAB, D_HT, 0);
//CBaseCombatCharacter::SetDefaultRelationship(CLASS_MILITARY, CLASS_HOUNDEYE, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_MILITARY, CLASS_MANHACK, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_MILITARY, CLASS_METROPOLICE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_MILITARY, CLASS_MILITARY, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_MILITARY, CLASS_MISSILE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_MILITARY, CLASS_SCANNER, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_MILITARY, CLASS_STALKER, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_MILITARY, CLASS_VORTIGAUNT, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_MILITARY, CLASS_ZOMBIE, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_MILITARY, CLASS_PROTOSNIPER, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_MILITARY, CLASS_EARTH_FAUNA, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_MILITARY, CLASS_PLAYER_ALLY, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_MILITARY, CLASS_PLAYER_ALLY_VITAL,D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_MILITARY, CLASS_HACKED_ROLLERMINE,D_HT, 0);

// ------------------------------------------------------------
// > CLASS_MISSILE
// ------------------------------------------------------------
CBaseCombatCharacter::SetDefaultRelationship(CLASS_MISSILE, CLASS_NONE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_MISSILE, CLASS_PLAYER, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_MISSILE, CLASS_ANTLION, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_MISSILE, CLASS_BARNACLE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_MISSILE, CLASS_BULLSEYE, D_NU, 0);
//CBaseCombatCharacter::SetDefaultRelationship(CLASS_MISSILE, CLASS_BULLSQUID, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_MISSILE, CLASS_CITIZEN_PASSIVE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_MISSILE, CLASS_CITIZEN_REBEL, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_MISSILE, CLASS_COMBINE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_MISSILE, CLASS_COMBINE_GUNSHIP, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_MISSILE, CLASS_CONSCRIPT, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_MISSILE, CLASS_FLARE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_MISSILE, CLASS_HEADCRAB, D_HT, 0);
//CBaseCombatCharacter::SetDefaultRelationship(CLASS_MISSILE, CLASS_HOUNDEYE, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_MISSILE, CLASS_MANHACK, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_MISSILE, CLASS_METROPOLICE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_MISSILE, CLASS_MILITARY, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_MISSILE, CLASS_MISSILE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_MISSILE, CLASS_SCANNER, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_MISSILE, CLASS_STALKER, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_MISSILE, CLASS_VORTIGAUNT, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_MISSILE, CLASS_ZOMBIE, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_MISSILE, CLASS_PROTOSNIPER, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_MISSILE, CLASS_EARTH_FAUNA, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_MISSILE, CLASS_PLAYER_ALLY, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_MISSILE, CLASS_PLAYER_ALLY_VITAL,D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_MISSILE, CLASS_HACKED_ROLLERMINE,D_HT, 0);

// ------------------------------------------------------------
// > CLASS_NONE
// ------------------------------------------------------------
CBaseCombatCharacter::SetDefaultRelationship(CLASS_NONE, CLASS_NONE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_NONE, CLASS_PLAYER, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_NONE, CLASS_ANTLION, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_NONE, CLASS_BARNACLE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_NONE, CLASS_BULLSEYE, D_NU, 0);
//CBaseCombatCharacter::SetDefaultRelationship(CLASS_NONE, CLASS_BULLSQUID, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_NONE, CLASS_CITIZEN_PASSIVE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_NONE, CLASS_CITIZEN_REBEL, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_NONE, CLASS_COMBINE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_NONE, CLASS_COMBINE_GUNSHIP, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_NONE, CLASS_CONSCRIPT, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_NONE, CLASS_FLARE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_NONE, CLASS_HEADCRAB, D_NU, 0);
//CBaseCombatCharacter::SetDefaultRelationship(CLASS_NONE, CLASS_HOUNDEYE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_NONE, CLASS_MANHACK, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_NONE, CLASS_METROPOLICE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_NONE, CLASS_MILITARY, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_NONE, CLASS_SCANNER, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_NONE, CLASS_STALKER, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_NONE, CLASS_VORTIGAUNT, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_NONE, CLASS_ZOMBIE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_NONE, CLASS_PROTOSNIPER, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_NONE, CLASS_EARTH_FAUNA, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_NONE, CLASS_PLAYER_ALLY, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_NONE, CLASS_PLAYER_ALLY_VITAL,D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_NONE, CLASS_HACKED_ROLLERMINE,D_NU, 0);

// ------------------------------------------------------------
// > CLASS_PLAYER
// ------------------------------------------------------------
CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER, CLASS_NONE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER, CLASS_PLAYER, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER, CLASS_ANTLION, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER, CLASS_BARNACLE, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER, CLASS_BULLSEYE, D_HT, 0);
//CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER, CLASS_BULLSQUID, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER, CLASS_CITIZEN_PASSIVE, D_LI, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER, CLASS_CITIZEN_REBEL, D_LI, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER, CLASS_COMBINE, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER, CLASS_COMBINE_GUNSHIP, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER, CLASS_CONSCRIPT, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER, CLASS_FLARE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER, CLASS_HEADCRAB, D_HT, 0);
//CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER, CLASS_HOUNDEYE, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER, CLASS_MANHACK, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER, CLASS_METROPOLICE, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER, CLASS_MILITARY, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER, CLASS_MISSILE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER, CLASS_SCANNER, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER, CLASS_STALKER, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER, CLASS_VORTIGAUNT, D_LI, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER, CLASS_ZOMBIE, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER, CLASS_PROTOSNIPER, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER, CLASS_EARTH_FAUNA, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER, CLASS_PLAYER_ALLY, D_LI, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER, CLASS_PLAYER_ALLY_VITAL,D_LI, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER, CLASS_HACKED_ROLLERMINE,D_LI, 0);

// ------------------------------------------------------------
// > CLASS_PLAYER_ALLY
// ------------------------------------------------------------
CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER_ALLY, CLASS_NONE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER_ALLY, CLASS_PLAYER, D_LI, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER_ALLY, CLASS_ANTLION, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER_ALLY, CLASS_BARNACLE, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER_ALLY, CLASS_BULLSEYE, D_NU, 0);
//CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER_ALLY, CLASS_BULLSQUID, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER_ALLY, CLASS_CITIZEN_PASSIVE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER_ALLY, CLASS_CITIZEN_REBEL, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER_ALLY, CLASS_COMBINE, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER_ALLY, CLASS_COMBINE_GUNSHIP, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER_ALLY, CLASS_CONSCRIPT, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER_ALLY, CLASS_FLARE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER_ALLY, CLASS_HEADCRAB, D_FR, 0);
//CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER_ALLY, CLASS_HOUNDEYE, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER_ALLY, CLASS_MANHACK, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER_ALLY, CLASS_METROPOLICE, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER_ALLY, CLASS_MILITARY, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER_ALLY, CLASS_MISSILE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER_ALLY, CLASS_SCANNER, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER_ALLY, CLASS_STALKER, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER_ALLY, CLASS_VORTIGAUNT, D_LI, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER_ALLY, CLASS_ZOMBIE, D_FR, 1);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER_ALLY, CLASS_PROTOSNIPER, D_FR, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER_ALLY, CLASS_EARTH_FAUNA, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER_ALLY, CLASS_PLAYER_ALLY, D_LI, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER_ALLY, CLASS_PLAYER_ALLY_VITAL,D_LI, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER_ALLY, CLASS_HACKED_ROLLERMINE,D_LI, 0);

// ------------------------------------------------------------
// > CLASS_PLAYER_ALLY_VITAL
// ------------------------------------------------------------
CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER_ALLY_VITAL, CLASS_NONE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER_ALLY_VITAL, CLASS_PLAYER, D_LI, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER_ALLY_VITAL, CLASS_ANTLION, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER_ALLY_VITAL, CLASS_BARNACLE, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER_ALLY_VITAL, CLASS_BULLSEYE, D_NU, 0);
//CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER_ALLY_VITAL, CLASS_BULLSQUID, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER_ALLY_VITAL, CLASS_CITIZEN_PASSIVE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER_ALLY_VITAL, CLASS_CITIZEN_REBEL, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER_ALLY_VITAL, CLASS_COMBINE, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER_ALLY_VITAL, CLASS_COMBINE_GUNSHIP, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER_ALLY_VITAL, CLASS_CONSCRIPT, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER_ALLY_VITAL, CLASS_FLARE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER_ALLY_VITAL, CLASS_HEADCRAB, D_HT, 0);
//CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER_ALLY_VITAL, CLASS_HOUNDEYE, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER_ALLY_VITAL, CLASS_MANHACK, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER_ALLY_VITAL, CLASS_METROPOLICE, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER_ALLY_VITAL, CLASS_MILITARY, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER_ALLY_VITAL, CLASS_MISSILE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER_ALLY_VITAL, CLASS_SCANNER, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER_ALLY_VITAL, CLASS_STALKER, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER_ALLY_VITAL, CLASS_VORTIGAUNT, D_LI, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER_ALLY_VITAL, CLASS_ZOMBIE, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER_ALLY_VITAL, CLASS_PROTOSNIPER, D_FR, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER_ALLY_VITAL, CLASS_EARTH_FAUNA, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER_ALLY_VITAL, CLASS_PLAYER_ALLY, D_LI, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER_ALLY_VITAL, CLASS_PLAYER_ALLY_VITAL,D_LI, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER_ALLY_VITAL, CLASS_HACKED_ROLLERMINE,D_LI, 0);

// ------------------------------------------------------------
// > CLASS_SCANNER
// ------------------------------------------------------------
CBaseCombatCharacter::SetDefaultRelationship(CLASS_SCANNER, CLASS_NONE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_SCANNER, CLASS_PLAYER, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_SCANNER, CLASS_ANTLION, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_SCANNER, CLASS_BARNACLE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_SCANNER, CLASS_BULLSEYE, D_NU, 0);
//CBaseCombatCharacter::SetDefaultRelationship(CLASS_SCANNER, CLASS_BULLSQUID, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_SCANNER, CLASS_CITIZEN_PASSIVE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_SCANNER, CLASS_CITIZEN_REBEL, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_SCANNER, CLASS_COMBINE, D_LI, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_SCANNER, CLASS_COMBINE_GUNSHIP, D_LI, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_SCANNER, CLASS_CONSCRIPT, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_SCANNER, CLASS_FLARE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_SCANNER, CLASS_HEADCRAB, D_NU, 0);
//CBaseCombatCharacter::SetDefaultRelationship(CLASS_SCANNER, CLASS_HOUNDEYE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_SCANNER, CLASS_MANHACK, D_LI, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_SCANNER, CLASS_METROPOLICE, D_LI, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_SCANNER, CLASS_MILITARY, D_LI, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_SCANNER, CLASS_MISSILE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_SCANNER, CLASS_SCANNER, D_LI, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_SCANNER, CLASS_STALKER, D_LI, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_SCANNER, CLASS_VORTIGAUNT, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_SCANNER, CLASS_ZOMBIE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_SCANNER, CLASS_PROTOSNIPER, D_LI, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_SCANNER, CLASS_EARTH_FAUNA, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_SCANNER, CLASS_PLAYER_ALLY, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_SCANNER, CLASS_PLAYER_ALLY_VITAL,D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_SCANNER, CLASS_HACKED_ROLLERMINE,D_HT, 0);

// ------------------------------------------------------------
// > CLASS_STALKER
// ------------------------------------------------------------
CBaseCombatCharacter::SetDefaultRelationship(CLASS_STALKER, CLASS_NONE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_STALKER, CLASS_PLAYER, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_STALKER, CLASS_ANTLION, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_STALKER, CLASS_BARNACLE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_STALKER, CLASS_BULLSEYE, D_NU, 0);
//CBaseCombatCharacter::SetDefaultRelationship(CLASS_STALKER, CLASS_BULLSQUID, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_STALKER, CLASS_CITIZEN_PASSIVE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_STALKER, CLASS_CITIZEN_REBEL, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_STALKER, CLASS_COMBINE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_STALKER, CLASS_COMBINE_GUNSHIP, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_STALKER, CLASS_CONSCRIPT, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_STALKER, CLASS_FLARE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_STALKER, CLASS_HEADCRAB, D_NU, 0);
//CBaseCombatCharacter::SetDefaultRelationship(CLASS_STALKER, CLASS_HOUNDEYE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_STALKER, CLASS_MANHACK, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_STALKER, CLASS_METROPOLICE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_STALKER, CLASS_MILITARY, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_STALKER, CLASS_MISSILE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_STALKER, CLASS_SCANNER, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_STALKER, CLASS_STALKER, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_STALKER, CLASS_VORTIGAUNT, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_STALKER, CLASS_ZOMBIE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_STALKER, CLASS_PROTOSNIPER, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_STALKER, CLASS_EARTH_FAUNA, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_STALKER, CLASS_PLAYER_ALLY, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_STALKER, CLASS_PLAYER_ALLY_VITAL,D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_STALKER, CLASS_HACKED_ROLLERMINE,D_HT, 0);

// ------------------------------------------------------------
// > CLASS_VORTIGAUNT
// ------------------------------------------------------------
CBaseCombatCharacter::SetDefaultRelationship(CLASS_VORTIGAUNT, CLASS_NONE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_VORTIGAUNT, CLASS_PLAYER, D_LI, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_VORTIGAUNT, CLASS_ANTLION, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_VORTIGAUNT, CLASS_BARNACLE, D_FR, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_VORTIGAUNT, CLASS_BULLSEYE, D_NU, 0);
//CBaseCombatCharacter::SetDefaultRelationship(CLASS_VORTIGAUNT, CLASS_BULLSQUID, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_VORTIGAUNT, CLASS_CITIZEN_PASSIVE, D_LI, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_VORTIGAUNT, CLASS_CITIZEN_REBEL, D_LI, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_VORTIGAUNT, CLASS_COMBINE, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_VORTIGAUNT, CLASS_COMBINE_GUNSHIP, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_VORTIGAUNT, CLASS_CONSCRIPT, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_VORTIGAUNT, CLASS_FLARE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_VORTIGAUNT, CLASS_HEADCRAB, D_HT, 0);
//CBaseCombatCharacter::SetDefaultRelationship(CLASS_VORTIGAUNT, CLASS_HOUNDEYE, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_VORTIGAUNT, CLASS_MANHACK, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_VORTIGAUNT, CLASS_METROPOLICE, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_VORTIGAUNT, CLASS_MILITARY, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_VORTIGAUNT, CLASS_MISSILE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_VORTIGAUNT, CLASS_SCANNER, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_VORTIGAUNT, CLASS_STALKER, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_VORTIGAUNT, CLASS_VORTIGAUNT, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_VORTIGAUNT, CLASS_ZOMBIE, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_VORTIGAUNT, CLASS_PROTOSNIPER, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_VORTIGAUNT, CLASS_EARTH_FAUNA, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_VORTIGAUNT, CLASS_PLAYER_ALLY, D_LI, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_VORTIGAUNT, CLASS_PLAYER_ALLY_VITAL,D_LI, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_VORTIGAUNT, CLASS_HACKED_ROLLERMINE,D_LI, 0);

// ------------------------------------------------------------
// > CLASS_ZOMBIE
// ------------------------------------------------------------
CBaseCombatCharacter::SetDefaultRelationship(CLASS_ZOMBIE, CLASS_NONE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_ZOMBIE, CLASS_PLAYER, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_ZOMBIE, CLASS_ANTLION, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_ZOMBIE, CLASS_BARNACLE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_ZOMBIE, CLASS_BULLSEYE, D_NU, 0);
//CBaseCombatCharacter::SetDefaultRelationship(CLASS_ZOMBIE, CLASS_BULLSQUID, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_ZOMBIE, CLASS_CITIZEN_PASSIVE, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_ZOMBIE, CLASS_CITIZEN_REBEL, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_ZOMBIE, CLASS_COMBINE, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_ZOMBIE, CLASS_COMBINE_GUNSHIP, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_ZOMBIE, CLASS_CONSCRIPT, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_ZOMBIE, CLASS_FLARE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_ZOMBIE, CLASS_HEADCRAB, D_NU, 0);
//CBaseCombatCharacter::SetDefaultRelationship(CLASS_ZOMBIE, CLASS_HOUNDEYE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_ZOMBIE, CLASS_MANHACK, D_FR, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_ZOMBIE, CLASS_METROPOLICE, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_ZOMBIE, CLASS_MILITARY, D_FR, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_ZOMBIE, CLASS_MISSILE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_ZOMBIE, CLASS_SCANNER, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_ZOMBIE, CLASS_STALKER, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_ZOMBIE, CLASS_VORTIGAUNT, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_ZOMBIE, CLASS_ZOMBIE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_ZOMBIE, CLASS_PROTOSNIPER, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_ZOMBIE, CLASS_EARTH_FAUNA, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_ZOMBIE, CLASS_PLAYER_ALLY, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_ZOMBIE, CLASS_PLAYER_ALLY_VITAL,D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_ZOMBIE, CLASS_HACKED_ROLLERMINE,D_HT, 0);

// ------------------------------------------------------------
// > CLASS_PROTOSNIPER
// ------------------------------------------------------------
CBaseCombatCharacter::SetDefaultRelationship(CLASS_PROTOSNIPER, CLASS_NONE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_PROTOSNIPER, CLASS_PLAYER, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_PROTOSNIPER, CLASS_ANTLION, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_PROTOSNIPER, CLASS_BARNACLE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_PROTOSNIPER, CLASS_BULLSEYE, D_NU, 0);
//CBaseCombatCharacter::SetDefaultRelationship(CLASS_PROTOSNIPER, CLASS_BULLSQUID, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_PROTOSNIPER, CLASS_CITIZEN_PASSIVE, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_PROTOSNIPER, CLASS_CITIZEN_REBEL, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_PROTOSNIPER, CLASS_COMBINE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_PROTOSNIPER, CLASS_COMBINE_GUNSHIP, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_PROTOSNIPER, CLASS_CONSCRIPT, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_PROTOSNIPER, CLASS_FLARE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_PROTOSNIPER, CLASS_HEADCRAB, D_HT, 0);
//CBaseCombatCharacter::SetDefaultRelationship(CLASS_PROTOSNIPER, CLASS_HOUNDEYE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_PROTOSNIPER, CLASS_MANHACK, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_PROTOSNIPER, CLASS_METROPOLICE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_PROTOSNIPER, CLASS_MILITARY, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_PROTOSNIPER, CLASS_MISSILE, D_NU, 5);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_PROTOSNIPER, CLASS_SCANNER, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_PROTOSNIPER, CLASS_STALKER, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_PROTOSNIPER, CLASS_VORTIGAUNT, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_PROTOSNIPER, CLASS_ZOMBIE, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_PROTOSNIPER, CLASS_PROTOSNIPER, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_PROTOSNIPER, CLASS_EARTH_FAUNA, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_PROTOSNIPER, CLASS_PLAYER_ALLY, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_PROTOSNIPER, CLASS_PLAYER_ALLY_VITAL,D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_PROTOSNIPER, CLASS_HACKED_ROLLERMINE,D_HT, 0);

// ------------------------------------------------------------
// > CLASS_EARTH_FAUNA
//
// Hates pretty much everything equally except other earth fauna.
// This will make the critter choose the nearest thing as its enemy.
// ------------------------------------------------------------
CBaseCombatCharacter::SetDefaultRelationship(CLASS_EARTH_FAUNA, CLASS_NONE, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_EARTH_FAUNA, CLASS_PLAYER, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_EARTH_FAUNA, CLASS_ANTLION, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_EARTH_FAUNA, CLASS_BARNACLE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_EARTH_FAUNA, CLASS_BULLSEYE, D_NU, 0);
//CBaseCombatCharacter::SetDefaultRelationship(CLASS_EARTH_FAUNA, CLASS_BULLSQUID, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_EARTH_FAUNA, CLASS_CITIZEN_PASSIVE, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_EARTH_FAUNA, CLASS_CITIZEN_REBEL, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_EARTH_FAUNA, CLASS_COMBINE, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_EARTH_FAUNA, CLASS_COMBINE_GUNSHIP, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_EARTH_FAUNA, CLASS_CONSCRIPT, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_EARTH_FAUNA, CLASS_FLARE, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_EARTH_FAUNA, CLASS_HEADCRAB, D_HT, 0);
//CBaseCombatCharacter::SetDefaultRelationship(CLASS_EARTH_FAUNA, CLASS_HOUNDEYE, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_EARTH_FAUNA, CLASS_MANHACK, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_EARTH_FAUNA, CLASS_METROPOLICE, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_EARTH_FAUNA, CLASS_MILITARY, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_EARTH_FAUNA, CLASS_MISSILE, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_EARTH_FAUNA, CLASS_SCANNER, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_EARTH_FAUNA, CLASS_STALKER, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_EARTH_FAUNA, CLASS_VORTIGAUNT, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_EARTH_FAUNA, CLASS_ZOMBIE, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_EARTH_FAUNA, CLASS_PROTOSNIPER, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_EARTH_FAUNA, CLASS_EARTH_FAUNA, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_EARTH_FAUNA, CLASS_PLAYER_ALLY, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_EARTH_FAUNA, CLASS_PLAYER_ALLY_VITAL,D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_EARTH_FAUNA, CLASS_HACKED_ROLLERMINE,D_NU, 0);

// ------------------------------------------------------------
// > CLASS_HACKED_ROLLERMINE
// ------------------------------------------------------------
CBaseCombatCharacter::SetDefaultRelationship(CLASS_HACKED_ROLLERMINE, CLASS_NONE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_HACKED_ROLLERMINE, CLASS_PLAYER, D_LI, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_HACKED_ROLLERMINE, CLASS_ANTLION, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_HACKED_ROLLERMINE, CLASS_BARNACLE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_HACKED_ROLLERMINE, CLASS_BULLSEYE, D_NU, 0);
//CBaseCombatCharacter::SetDefaultRelationship(CLASS_HACKED_ROLLERMINE, CLASS_BULLSQUID, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_HACKED_ROLLERMINE, CLASS_CITIZEN_PASSIVE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_HACKED_ROLLERMINE, CLASS_CITIZEN_REBEL, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_HACKED_ROLLERMINE, CLASS_COMBINE, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_HACKED_ROLLERMINE, CLASS_COMBINE_GUNSHIP, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_HACKED_ROLLERMINE, CLASS_CONSCRIPT, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_HACKED_ROLLERMINE, CLASS_FLARE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_HACKED_ROLLERMINE, CLASS_HEADCRAB, D_HT, 0);
//CBaseCombatCharacter::SetDefaultRelationship(CLASS_HACKED_ROLLERMINE, CLASS_HOUNDEYE, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_HACKED_ROLLERMINE, CLASS_MANHACK, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_HACKED_ROLLERMINE, CLASS_METROPOLICE, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_HACKED_ROLLERMINE, CLASS_MILITARY, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_HACKED_ROLLERMINE, CLASS_MISSILE, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_HACKED_ROLLERMINE, CLASS_SCANNER, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_HACKED_ROLLERMINE, CLASS_STALKER, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_HACKED_ROLLERMINE, CLASS_VORTIGAUNT, D_LI, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_HACKED_ROLLERMINE, CLASS_ZOMBIE, D_HT, 1);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_HACKED_ROLLERMINE, CLASS_PROTOSNIPER, D_NU, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_HACKED_ROLLERMINE, CLASS_EARTH_FAUNA, D_HT, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_HACKED_ROLLERMINE, CLASS_PLAYER_ALLY, D_LI, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_HACKED_ROLLERMINE, CLASS_PLAYER_ALLY_VITAL,D_LI, 0);
CBaseCombatCharacter::SetDefaultRelationship(CLASS_HACKED_ROLLERMINE, CLASS_HACKED_ROLLERMINE,D_LI, 0);
}
#endif

#endif

//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $Workfile: $
// $Date: $
//
//-----------------------------------------------------------------------------
// $Log: $
//
// $NoKeywords: $
//=============================================================================//

#ifndef HL2MP_GAMERULES_H
#define HL2MP_GAMERULES_H
#pragma once

#include "gamerules.h"
#include "teamplay_gamerules.h"
#include "gamevars_shared.h"

#ifndef CLIENT_DLL
#include "hl2mp_player.h"
#endif

#define VEC_CROUCH_TRACE_MIN HL2MPRules()->GetHL2MPViewVectors()->m_vCrouchTraceMin
#define VEC_CROUCH_TRACE_MAX HL2MPRules()->GetHL2MPViewVectors()->m_vCrouchTraceMax

enum
{
TEAM_COMBINE = 2,
TEAM_REBELS,
};

#ifdef CLIENT_DLL
#define CHL2MPRules C_HL2MPRules
#define CHL2MPGameRulesProxy C_HL2MPGameRulesProxy
#endif

class CHL2MPGameRulesProxy : public CGameRulesProxy
{
public:
DECLARE_CLASS( CHL2MPGameRulesProxy, CGameRulesProxy );
DECLARE_NETWORKCLASS();
};

class HL2MPViewVectors : public CViewVectors
{
public:
HL2MPViewVectors(
Vector vView,
Vector vHullMin,
Vector vHullMax,
Vector vDuckHullMin,
Vector vDuckHullMax,
Vector vDuckView,
Vector vObsHullMin,
Vector vObsHullMax,
Vector vDeadViewHeight,
Vector vCrouchTraceMin,
Vector vCrouchTraceMax ) :
CViewVectors(
vView,
vHullMin,
vHullMax,
vDuckHullMin,
vDuckHullMax,
vDuckView,
vObsHullMin,
vObsHullMax,
vDeadViewHeight )
{
m_vCrouchTraceMin = vCrouchTraceMin;
m_vCrouchTraceMax = vCrouchTraceMax;
}

Vector m_vCrouchTraceMin;
Vector m_vCrouchTraceMax;
};

class CHL2MPRules : public CTeamplayRules
{
public:
DECLARE_CLASS( CHL2MPRules, CTeamplayRules );

// EDIT IH //
#ifndef CLIENT_DLL
void InitDefaultAIRelationships( void );
#endif

#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.
#endif

CHL2MPRules();
virtual ~CHL2MPRules();

virtual void Precache( void );
virtual bool ShouldCollide( int collisionGroup0, int collisionGroup1 );
virtual bool ClientCommand( const char *pcmd, CBaseEntity *pEdict );

virtual float FlWeaponRespawnTime( CBaseCombatWeapon *pWeapon );
virtual float FlWeaponTryRespawn( CBaseCombatWeapon *pWeapon );
virtual Vector VecWeaponRespawnSpot( CBaseCombatWeapon *pWeapon );
virtual int WeaponShouldRespawn( CBaseCombatWeapon *pWeapon );
virtual void Think( void );
virtual void CreateStandardEntities( void );
virtual void ClientSettingsChanged( CBasePlayer *pPlayer );
virtual int PlayerRelationship( CBaseEntity *pPlayer, CBaseEntity *pTarget );
virtual void GoToIntermission( void );
virtual void DeathNotice( CBasePlayer *pVictim, const CTakeDamageInfo &info );
virtual const char *GetGameDescription( void );
// derive this function if you mod uses encrypted weapon info files
virtual const unsigned char *GetEncryptionKey( void ) { return (unsigned char *)"x9Ke0BY7"; }
virtual const CViewVectors* GetViewVectors() const;
const HL2MPViewVectors* GetHL2MPViewVectors() const;

float GetMapRemainingTime();
void CleanUpMap();
void CheckRestartGame();
void RestartGame();

#ifndef CLIENT_DLL
virtual Vector VecItemRespawnSpot( CItem *pItem );
virtual QAngle VecItemRespawnAngles( CItem *pItem );
virtual float FlItemRespawnTime( CItem *pItem );
virtual bool CanHavePlayerItem( CBasePlayer *pPlayer, CBaseCombatWeapon *pItem );
virtual bool FShouldSwitchWeapon( CBasePlayer *pPlayer, CBaseCombatWeapon *pWeapon );

void AddLevelDesignerPlacedObject( CBaseEntity *pEntity );
void RemoveLevelDesignerPlacedObject( CBaseEntity *pEntity );
void ManageObjectRelocation( void );
void CheckChatForReadySignal( CHL2MP_Player *pPlayer, const char *chatmsg );

#endif
virtual void ClientDisconnected( edict_t *pClient );

bool CheckGameOver( void );
bool IsIntermission( void );

void PlayerKilled( CBasePlayer *pVictim, const CTakeDamageInfo &info );


bool IsTeamplay( void ) { return m_bTeamPlayEnabled; }
void CheckAllPlayersReady( void );

private:

CNetworkVar( bool, m_bTeamPlayEnabled );
CNetworkVar( float, m_flGameStartTime );
CUtlVector<EHANDLE> m_hRespawnableItemsAndWeapons;
float m_tmNextPeriodicThink;
float m_flRestartGameTime;
bool m_bCompleteReset;
bool m_bAwaitingReadyRestart;
bool m_bHeardAllPlayersReady;

};

inline CHL2MPRules* HL2MPRules()
{
return static_cast<CHL2MPRules*>(g_pGameRules);
}

#endif //HL2MP_GAMERULES_H

//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//

#include "cbase.h"
#include "in_buttons.h"
#include "takedamageinfo.h"
#include "ammodef.h"
#include "hl2mp_gamerules.h"

#ifdef CLIENT_DLL
extern IVModelInfoClient* modelinfo;
#else
extern IVModelInfo* modelinfo;
#endif

#if defined( CLIENT_DLL )

#include "vgui/ISurface.h"
#include "vgui_controls/controls.h"
#include "c_hl2mp_player.h"
#include "hud_crosshair.h"

#else

#include "hl2mp_player.h"
#include "vphysics/constraints.h"

#endif

#include "weapon_hl2mpbase.h"

// ----------------------------------------------------------------------------- //
// Global functions.
// ----------------------------------------------------------------------------- //

bool IsAmmoType( int iAmmoType, const char *pAmmoName )
{
return GetAmmoDef()->Index( pAmmoName ) == iAmmoType;
}

static const char * s_WeaponAliasInfo[] =
{
"none", // WEAPON_NONE = 0,

//Melee
"shotgun", //WEAPON_AMERKNIFE,

NULL, // end of list marker
};

// ----------------------------------------------------------------------------- //
// CWeaponHL2MPBase tables.
// ----------------------------------------------------------------------------- //

IMPLEMENT_NETWORKCLASS_ALIASED( WeaponHL2MPBase, DT_WeaponHL2MPBase )

BEGIN_NETWORK_TABLE( CWeaponHL2MPBase, DT_WeaponHL2MPBase )

#ifdef CLIENT_DLL

#else
// world weapon models have no aminations
// SendPropExclude( "DT_AnimTimeMustBeFirst", "m_flAnimTime" ),
// SendPropExclude( "DT_BaseAnimating", "m_nSequence" ),
// SendPropExclude( "DT_LocalActiveWeaponData", "m_flTimeWeaponIdle" ),
#endif

END_NETWORK_TABLE()

BEGIN_PREDICTION_DATA( CWeaponHL2MPBase )
END_PREDICTION_DATA()

LINK_ENTITY_TO_CLASS( weapon_hl2mp_base, CWeaponHL2MPBase );

#ifdef GAME_DLL

BEGIN_DATADESC( CWeaponHL2MPBase )

END_DATADESC()

#endif

// ----------------------------------------------------------------------------- //
// CWeaponHL2MPBase implementation.
// ----------------------------------------------------------------------------- //
CWeaponHL2MPBase::CWeaponHL2MPBase()
{
SetPredictionEligible( true );
AddSolidFlags( FSOLID_TRIGGER ); // Nothing collides with these but it gets touches.

m_flNextResetCheckTime = 0.0f;
}

bool CWeaponHL2MPBase::IsPredicted() const
{
return true;
}

void CWeaponHL2MPBase::WeaponSound( WeaponSound_t sound_type, float soundtime /* = 0.0f */ )
{
#ifdef CLIENT_DLL

// If we have some sounds from the weapon classname.txt file, play a random one of them
const char *shootsound = GetWpnData().aShootSounds[ sound_type ];
if ( !shootsound || !shootsound[0] )
return;

CBroadcastRecipientFilter filter; // this is client side only
if ( !te->CanPredict() )
return;

CBaseEntity::EmitSound( filter, GetPlayerOwner()->entindex(), shootsound, &GetPlayerOwner()->GetAbsOrigin() );
#else
BaseClass::WeaponSound( sound_type, soundtime );
#endif
}

CBasePlayer* CWeaponHL2MPBase::GetPlayerOwner() const
{
return dynamic_cast< CBasePlayer* >( GetOwner() );
}

CHL2MP_Player* CWeaponHL2MPBase::GetHL2MPPlayerOwner() const
{
return dynamic_cast< CHL2MP_Player* >( GetOwner() );
}

#ifdef CLIENT_DLL

void CWeaponHL2MPBase::OnDataChanged( DataUpdateType_t type )
{
BaseClass::OnDataChanged( type );

if ( GetPredictable() && !ShouldPredict() )
ShutdownPredictable();
}

bool CWeaponHL2MPBase::ShouldPredict()
{
if ( GetOwner() && GetOwner() == C_BasePlayer::GetLocalPlayer() )
return true;

return BaseClass::ShouldPredict();
}

#else

void CWeaponHL2MPBase::Spawn()
{
BaseClass::Spawn();

// Set this here to allow players to shoot dropped weapons
SetCollisionGroup( COLLISION_GROUP_WEAPON );
}

void CWeaponHL2MPBase:: Materialize( void )
{
if ( IsEffectActive( EF_NODRAW ) )
{
// changing from invisible state to visible.
EmitSound( "AlyxEmp.Charge" );

RemoveEffects( EF_NODRAW );
DoMuzzleFlash();
}

if ( HasSpawnFlags( SF_NORESPAWN ) == false )
{
VPhysicsInitNormal( SOLID_BBOX, GetSolidFlags() | FSOLID_TRIGGER, false );
SetMoveType( MOVETYPE_VPHYSICS );

HL2MPRules()->AddLevelDesignerPlacedObject( this );
}

if ( HasSpawnFlags( SF_NORESPAWN ) == false )
{
if ( GetOriginalSpawnOrigin() == vec3_origin )
{
m_vOriginalSpawnOrigin = GetAbsOrigin();
m_vOriginalSpawnAngles = GetAbsAngles();
}
}

SetPickupTouch();

SetThink (NULL);
}

#endif

void CWeaponHL2MPBase::FallInit( void )
{
#ifndef CLIENT_DLL
SetModel( GetWorldModel() );
VPhysicsDestroyObject();

if ( HasSpawnFlags( SF_NORESPAWN ) == false )
{
SetMoveType( MOVETYPE_NONE );
SetSolid( SOLID_BBOX );
AddSolidFlags( FSOLID_TRIGGER );

UTIL_DropToFloor( this, MASK_SOLID );
}
else
{
if ( !VPhysicsInitNormal( SOLID_BBOX, GetSolidFlags() | FSOLID_TRIGGER, false ) )
{
SetMoveType( MOVETYPE_NONE );
SetSolid( SOLID_BBOX );
AddSolidFlags( FSOLID_TRIGGER );
}
else
{
#if !defined( CLIENT_DLL )
// Constrained start?
if ( HasSpawnFlags( SF_WEAPON_START_CONSTRAINED ) )
{
//Constrain the weapon in place
IPhysicsObject *pReferenceObject, *pAttachedObject;

pReferenceObject = g_PhysWorldObject;
pAttachedObject = VPhysicsGetObject();

if ( pReferenceObject && pAttachedObject )
{
constraint_fixedparams_t fixed;
fixed.Defaults();
fixed.InitWithCurrentObjectState( pReferenceObject, pAttachedObject );

fixed.constraint.forceLimit = lbs2kg( 10000 );
fixed.constraint.torqueLimit = lbs2kg( 10000 );

IPhysicsConstraint *pConstraint = GetConstraint();

pConstraint = physenv->CreateFixedConstraint( pReferenceObject, pAttachedObject, NULL, fixed );

pConstraint->SetGameData( (void *) this );
}
}
#endif //CLIENT_DLL
}
}

SetPickupTouch();

SetThink( &CBaseCombatWeapon::FallThink );

SetNextThink( gpGlobals->curtime + 0.1f );

#endif
}

const CHL2MPSWeaponInfo &CWeaponHL2MPBase::GetHL2MPWpnData() const
{
const FileWeaponInfo_t *pWeaponInfo = &GetWpnData();
const CHL2MPSWeaponInfo *pHL2MPInfo;

#ifdef _DEBUG
pHL2MPInfo = dynamic_cast< const CHL2MPSWeaponInfo* >( pWeaponInfo );
Assert( pHL2MPInfo );
#else
pHL2MPInfo = static_cast< const CHL2MPSWeaponInfo* >( pWeaponInfo );
#endif

return *pHL2MPInfo;
}
void CWeaponHL2MPBase::FireBullets( const FireBulletsInfo_t &info )
{
FireBulletsInfo_t modinfo = info;

modinfo.m_iPlayerDamage = GetHL2MPWpnData().m_iPlayerDamage;

BaseClass::FireBullets( modinfo );
}

#if defined( CLIENT_DLL )

#include "c_te_effect_dispatch.h"

#define NUM_MUZZLE_FLASH_TYPES 4

bool CWeaponHL2MPBase::OnFireEvent( C_BaseViewModel *pViewModel, const Vector& origin, const QAngle& angles, int event, const char *options )
{
return BaseClass::OnFireEvent( pViewModel, origin, angles, event, options );
}

void UTIL_ClipPunchAngleOffset( QAngle &in, const QAngle &punch, const QAngle &clip )
{
QAngle final = in + punch;

//Clip each component
for ( int i = 0; i < 3; i++ )
{
if ( final[i] > clip[i] )
{
final[i] = clip[i];
}
else if ( final[i] < -clip[i] )
{
final[i] = -clip[i];
}

//Return the result
in[i] = final[i] - punch[i];
}
}

#endif

//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#include "cbase.h"
#include "in_buttons.h"
#include "engine/IEngineSound.h"
#include "ammodef.h"
#include "SoundEmitterSystem/isoundemittersystembase.h"
#include "physics_saverestore.h"
#include "datacache/imdlcache.h"

#if !defined( CLIENT_DLL )

// Game DLL Headers
#include "soundent.h"
#include "eventqueue.h"
#include "fmtstr.h"

#ifdef HL2MP
#include "hl2mp_gamerules.h"
#endif

#endif

// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"

CBaseCombatWeapon::CBaseCombatWeapon()
{
// Constructor must call this
// CONSTRUCT_PREDICTABLE( CBaseCombatWeapon );

// Some default values. There should be set in the particular weapon classes
m_fMinRange1 = 65;
m_fMinRange2 = 65;
m_fMaxRange1 = 1024;
m_fMaxRange2 = 1024;

m_bReloadsSingly = false;

// Defaults to zero
m_nViewModelIndex = 0;

#if defined( CLIENT_DLL )
m_iState = m_iOldState = WEAPON_NOT_CARRIED;
m_iClip1 = -1;
m_iClip2 = -1;
m_iPrimaryAmmoType = -1;
m_iSecondaryAmmoType = -1;
#endif

#if !defined( CLIENT_DLL )
m_pConstraint = NULL;
OnBaseCombatWeaponCreated( this );
#endif

m_hWeaponFileInfo = GetInvalidWeaponInfoHandle();
}

//-----------------------------------------------------------------------------
// Purpose: Destructor
//-----------------------------------------------------------------------------
CBaseCombatWeapon::~CBaseCombatWeapon( void )
{
#if !defined( CLIENT_DLL )
//Remove our constraint, if we have one
if ( m_pConstraint != NULL )
{
physenv->DestroyConstraint( m_pConstraint );
m_pConstraint = NULL;
}
OnBaseCombatWeaponDestroyed( this );
#endif
}

void CBaseCombatWeapon::Activate( void )
{
BaseClass::Activate();

#ifndef CLIENT_DLL
if ( GetOwnerEntity() )
return;

if ( g_pGameRules->IsAllowedToSpawn( this ) == false )
{
UTIL_Remove( this );
return;
}
#endif

}
//-----------------------------------------------------------------------------
// Purpose: Set mode to world model and start falling to the ground
//-----------------------------------------------------------------------------
void CBaseCombatWeapon::Spawn( void )
{
Precache();

SetSolid( SOLID_BBOX );
m_flNextEmptySoundTime = 0.0f;

// Weapons won't show up in trace calls if they are being carried...
RemoveEFlags( EFL_USE_PARTITION_WHEN_NOT_SOLID );

m_iState = WEAPON_NOT_CARRIED;
// Assume
m_nViewModelIndex = 0;

// If I use clips, set my clips to the default
if ( UsesClipsForAmmo1() )
{
m_iClip1 = GetDefaultClip1();
}
else
{
SetPrimaryAmmoCount( GetDefaultClip1() );
m_iClip1 = WEAPON_NOCLIP;
}
if ( UsesClipsForAmmo2() )
{
m_iClip2 = GetDefaultClip2();
}
else
{
SetSecondaryAmmoCount( GetDefaultClip2() );
m_iClip2 = WEAPON_NOCLIP;
}

SetModel( GetWorldModel() );

#if !defined( CLIENT_DLL )
if( IsXbox() )
{
AddEffects( EF_ITEM_BLINK );
}

FallInit();
SetCollisionGroup( COLLISION_GROUP_WEAPON );
m_takedamage = DAMAGE_EVENTS_ONLY;

SetBlocksLOS( false );

// Default to non-removeable, because we don't want the
// game_weapon_manager entity to remove weapons that have
// been hand-placed by level designers. We only want to remove
// weapons that have been dropped by NPC's.
SetRemoveable( false );
#endif

// Bloat the box for player pickup
CollisionProp()->UseTriggerBounds( true, 36 );

// Use more efficient bbox culling on the client. Otherwise, it'll setup bones for most
// characters even when they're not in the frustum.
AddEffects( EF_BONEMERGE_FASTCULL );

m_iHudHintCount = 0;
}

//-----------------------------------------------------------------------------
// Purpose: get this game's encryption key for decoding weapon kv files
// Output : virtual const unsigned char
//-----------------------------------------------------------------------------
const unsigned char *CBaseCombatWeapon::GetEncryptionKey( void )
{
return g_pGameRules->GetEncryptionKey();
}

//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CBaseCombatWeapon::Precache( void )
{
#if defined( CLIENT_DLL )
Assert( Q_strlen( GetClassname() ) > 0 );
// Msg( "Client got %s\n", GetClassname() );
#endif
m_iPrimaryAmmoType = m_iSecondaryAmmoType = -1;

// Add this weapon to the weapon registry, and get our index into it
// Get weapon data from script file
if ( ReadWeaponDataFromFileForSlot( filesystem, GetClassname(), &m_hWeaponFileInfo, GetEncryptionKey() ) )
{
// Get the ammo indexes for the ammo's specified in the data file
if ( GetWpnData().szAmmo1[0] )
{
m_iPrimaryAmmoType = GetAmmoDef()->Index( GetWpnData().szAmmo1 );
if (m_iPrimaryAmmoType == -1)
{
Msg("ERROR: Weapon (%s) using undefined primary ammo type (%s)\n",GetClassname(), GetWpnData().szAmmo1);
}
}
if ( GetWpnData().szAmmo2[0] )
{
m_iSecondaryAmmoType = GetAmmoDef()->Index( GetWpnData().szAmmo2 );
if (m_iSecondaryAmmoType == -1)
{
Msg("ERROR: Weapon (%s) using undefined secondary ammo type (%s)\n",GetClassname(),GetWpnData().szAmmo2);
}

}
#if defined( CLIENT_DLL )
gWR.LoadWeaponSprites( GetWeaponFileInfoHandle() );
#endif
// Precache models (preload to avoid hitch)
m_iViewModelIndex = CBaseEntity::PrecacheModel( GetViewModel() );
m_iWorldModelIndex = CBaseEntity::PrecacheModel( GetWorldModel());

// Precache sounds, too
for ( int i = 0; i < NUM_SHOOT_SOUND_TYPES; ++i )
{
const char *shootsound = GetShootSound( i );
if ( shootsound && shootsound[0] )
{
CBaseEntity::PrecacheScriptSound( shootsound );
}
}
}
else
{
Assert( !"Missing weapon script file" );

// Couldn't read data file, remove myself
Msg( "Error reading weapon data file for: %s\n", GetClassname() );
// Remove( ); //don't remove, this gets released soon!
}
}

//-----------------------------------------------------------------------------
// Purpose: Get my data in the file weapon info array
//-----------------------------------------------------------------------------
const FileWeaponInfo_t &CBaseCombatWeapon::GetWpnData( void ) const
{
return *GetFileWeaponInfoFromHandle( m_hWeaponFileInfo );
}

//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
const char *CBaseCombatWeapon::GetViewModel( int /*viewmodelindex = 0 -- this is ignored in the base class here*/ ) const
{
return GetWpnData().szViewModel;
}

//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
const char *CBaseCombatWeapon::GetWorldModel( void ) const
{
return GetWpnData().szWorldModel;
}

//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
const char *CBaseCombatWeapon::GetAnimPrefix( void ) const
{
return GetWpnData().szAnimationPrefix;
}

//-----------------------------------------------------------------------------
// Purpose:
// Output : char const
//-----------------------------------------------------------------------------
const char *CBaseCombatWeapon::GetPrintName( void ) const
{
return GetWpnData().szPrintName;
}

//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
int CBaseCombatWeapon::GetMaxClip1( void ) const
{
return GetWpnData().iMaxClip1;
}

//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
int CBaseCombatWeapon::GetMaxClip2( void ) const
{
return GetWpnData().iMaxClip2;
}

//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
int CBaseCombatWeapon::GetDefaultClip1( void ) const
{
return GetWpnData().iDefaultClip1;
}

//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
int CBaseCombatWeapon::GetDefaultClip2( void ) const
{
return GetWpnData().iDefaultClip2;
}

//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
bool CBaseCombatWeapon::UsesClipsForAmmo1( void ) const
{
return ( GetMaxClip1() != WEAPON_NOCLIP );
}

bool CBaseCombatWeapon::IsMeleeWeapon() const
{
return GetWpnData().m_bMeleeWeapon;
}

//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
bool CBaseCombatWeapon::UsesClipsForAmmo2( void ) const
{
return ( GetMaxClip2() != WEAPON_NOCLIP );
}

//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
int CBaseCombatWeapon::GetWeight( void ) const
{
return GetWpnData().iWeight;
}

//-----------------------------------------------------------------------------
// Purpose: Whether this weapon can be autoswitched to when the player runs out
// of ammo in their current weapon or they pick this weapon up.
//-----------------------------------------------------------------------------
bool CBaseCombatWeapon::AllowsAutoSwitchTo( void ) const
{
return GetWpnData().bAutoSwitchTo;
}

//-----------------------------------------------------------------------------
// Purpose: Whether this weapon can be autoswitched away from when the player
// runs out of ammo in this weapon or picks up another weapon or ammo.
//-----------------------------------------------------------------------------
bool CBaseCombatWeapon::AllowsAutoSwitchFrom( void ) const
{
return GetWpnData().bAutoSwitchFrom;
}

//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
int CBaseCombatWeapon::GetWeaponFlags( void ) const
{
return GetWpnData().iFlags;
}

//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
int CBaseCombatWeapon::GetSlot( void ) const
{
return GetWpnData().iSlot;
}

//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
int CBaseCombatWeapon::GetPosition( void ) const
{
return GetWpnData().iPosition;
}

//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
const char *CBaseCombatWeapon::GetName( void ) const
{
return GetWpnData().szClassName;
}

//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CHudTexture const *CBaseCombatWeapon::GetSpriteActive( void ) const
{
return GetWpnData().iconActive;
}

//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CHudTexture const *CBaseCombatWeapon::GetSpriteInactive( void ) const
{
return GetWpnData().iconInactive;
}

//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CHudTexture const *CBaseCombatWeapon::GetSpriteAmmo( void ) const
{
return GetWpnData().iconAmmo;
}

//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CHudTexture const *CBaseCombatWeapon::GetSpriteAmmo2( void ) const
{
return GetWpnData().iconAmmo2;
}

//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CHudTexture const *CBaseCombatWeapon::GetSpriteCrosshair( void ) const
{
return GetWpnData().iconCrosshair;
}

//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CHudTexture const *CBaseCombatWeapon::GetSpriteAutoaim( void ) const
{
return GetWpnData().iconAutoaim;
}

//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CHudTexture const *CBaseCombatWeapon::GetSpriteZoomedCrosshair( void ) const
{
return GetWpnData().iconZoomedCrosshair;
}

//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CHudTexture const *CBaseCombatWeapon::GetSpriteZoomedAutoaim( void ) const
{
return GetWpnData().iconZoomedAutoaim;
}

//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
const char *CBaseCombatWeapon::GetShootSound( int iIndex ) const
{
return GetWpnData().aShootSounds[ iIndex ];
}

//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
int CBaseCombatWeapon::GetRumbleEffect() const
{
return GetWpnData().iRumbleEffect;
}

//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CBaseCombatCharacter *CBaseCombatWeapon::GetOwner() const
{
return ToBaseCombatCharacter( m_hOwner.Get() );
}

//-----------------------------------------------------------------------------
// Purpose:
// Input : BaseCombatCharacter -
//-----------------------------------------------------------------------------
void CBaseCombatWeapon::SetOwner( CBaseCombatCharacter *owner )
{
m_hOwner = owner;

#ifndef CLIENT_DLL
DispatchUpdateTransmitState();
#else
UpdateVisibility();
#endif
}

//-----------------------------------------------------------------------------
// Purpose: Return false if this weapon won't let the player switch away from it
//-----------------------------------------------------------------------------
bool CBaseCombatWeapon::IsAllowedToSwitch( void )
{
return true;
}

//-----------------------------------------------------------------------------
// Purpose: Return true if this weapon can be selected via the weapon selection
//-----------------------------------------------------------------------------
bool CBaseCombatWeapon::CanBeSelected( void )
{
if ( !VisibleInWeaponSelection() )
return false;

return HasAmmo();
}

//-----------------------------------------------------------------------------
// Purpose: Return true if this weapon has some ammo
//-----------------------------------------------------------------------------
bool CBaseCombatWeapon::HasAmmo( void )
{
// Weapons with no ammo types can always be selected
if ( m_iPrimaryAmmoType == -1 && m_iSecondaryAmmoType == -1 )
return true;
if ( GetWeaponFlags() & ITEM_FLAG_SELECTONEMPTY )
return true;

CBasePlayer *player = ToBasePlayer( GetOwner() );
if ( !player )
return false;
return ( m_iClip1 > 0 || player->GetAmmoCount( m_iPrimaryAmmoType ) || m_iClip2 > 0 || player->GetAmmoCount( m_iSecondaryAmmoType ) );
}

//-----------------------------------------------------------------------------
// Purpose: Return true if this weapon should be seen, and hence be selectable, in the weapon selection
//-----------------------------------------------------------------------------
bool CBaseCombatWeapon::VisibleInWeaponSelection( void )
{
return true;
}

//-----------------------------------------------------------------------------
// Purpose:
// Output : Returns true on success, false on failure.
//-----------------------------------------------------------------------------
bool CBaseCombatWeapon::HasWeaponIdleTimeElapsed( void )
{
if ( gpGlobals->curtime > m_flTimeWeaponIdle )
return true;

return false;
}

//-----------------------------------------------------------------------------
// Purpose:
// Input : time -
//-----------------------------------------------------------------------------
void CBaseCombatWeapon::SetWeaponIdleTime( float time )
{
m_flTimeWeaponIdle = time;
}

//-----------------------------------------------------------------------------
// Purpose:
// Output : float
//-----------------------------------------------------------------------------
float CBaseCombatWeapon::GetWeaponIdleTime( void )
{
return m_flTimeWeaponIdle;
}

#if !defined( CLIENT_DLL )
void WeaponManager_AmmoMod( CBaseCombatWeapon *pWeapon );
#endif

//-----------------------------------------------------------------------------
// Purpose: Drop/throw the weapon with the given velocity.
//-----------------------------------------------------------------------------
void CBaseCombatWeapon::Drop( const Vector &vecVelocity )
{
#if !defined( CLIENT_DLL )

// Once somebody drops a gun, it's fair game for removal when/if
// a game_weapon_manager does a cleanup on surplus weapons in the
// world.
SetRemoveable( true );
WeaponManager_AmmoMod( this );

//If it was dropped then there's no need to respawn it.
AddSpawnFlags( SF_NORESPAWN );

StopAnimation();
StopFollowingEntity( );
SetMoveType( MOVETYPE_FLYGRAVITY );
// clear follow stuff, setup for collision
SetGravity(1.0);
m_iState = WEAPON_NOT_CARRIED;
RemoveEffects( EF_NODRAW );
FallInit();
SetGroundEntity( NULL );
SetThink( &CBaseCombatWeapon::SetPickupTouch );
SetTouch(NULL);

if( hl2_episodic.GetBool() )
{
RemoveSpawnFlags( SF_WEAPON_NO_PLAYER_PICKUP );
}

IPhysicsObject *pObj = VPhysicsGetObject();
if ( pObj != NULL )
{
AngularImpulse angImp( 200, 200, 200 );
pObj->AddVelocity( &vecVelocity, &angImp );
}
else
{
SetAbsVelocity( vecVelocity );
}

CBaseEntity *pOwner = GetOwnerEntity();

SetNextThink( gpGlobals->curtime + 1.0f );
SetOwnerEntity( NULL );
SetOwner( NULL );

// If we're not allowing to spawn due to the gamerules,
// remove myself when I'm dropped by an NPC.
if ( pOwner && pOwner->IsNPC() )
{
if ( g_pGameRules->IsAllowedToSpawn( this ) == false )
{
UTIL_Remove( this );
return;
}
}
#endif
}

//-----------------------------------------------------------------------------
// Purpose:
// Input : *pPicker -
//-----------------------------------------------------------------------------
void CBaseCombatWeapon::OnPickedUp( CBaseCombatCharacter *pNewOwner )
{
#if !defined( CLIENT_DLL )
RemoveEffects( EF_ITEM_BLINK );

if( pNewOwner->IsPlayer() )
{
m_OnPlayerPickup.FireOutput(pNewOwner, this);

// Play the pickup sound for 1st-person observers
CRecipientFilter filter;
for ( int i=1; i <= gpGlobals->maxClients; ++i )
{
CBasePlayer *player = UTIL_PlayerByIndex(i);
if ( player && !player->IsAlive() && player->GetObserverMode() == OBS_MODE_IN_EYE )
{
filter.AddRecipient( player );
}
}
if ( filter.GetRecipientCount() )
{
CBaseEntity::EmitSound( filter, pNewOwner->entindex(), "Player.PickupWeapon" );
}

// Robin: We don't want to delete weapons the player has picked up, so
// clear the name of the weapon. This prevents wildcards that are meant
// to find NPCs finding weapons dropped by the NPCs as well.
SetName( NULL_STRING );
}
else
{
m_OnNPCPickup.FireOutput(pNewOwner, this);
}

#ifdef HL2MP
HL2MPRules()->RemoveLevelDesignerPlacedObject( this );
#endif

// Someone picked me up, so make it so that I can't be removed.
SetRemoveable( false );
#endif
}

//-----------------------------------------------------------------------------
// Purpose:
// Input : &vecTracerSrc -
// &tr -
// iTracerType -
//-----------------------------------------------------------------------------
void CBaseCombatWeapon::MakeTracer( const Vector &vecTracerSrc, const trace_t &tr, int iTracerType )
{
CBaseEntity *pOwner = GetOwner();

if ( pOwner == NULL )
{
BaseClass::MakeTracer( vecTracerSrc, tr, iTracerType );
return;
}

const char *pszTracerName = GetTracerType();

Vector vNewSrc = vecTracerSrc;
int iEntIndex = pOwner->entindex();

int iFlags = TRACER_DONT_USE_ATTACHMENT;
if ( g_pGameRules->IsMultiplayer() )
{
iFlags = 0;
iEntIndex = entindex();
}

switch ( iTracerType )
{
case TRACER_LINE:
UTIL_Tracer( vNewSrc, tr.endpos, iEntIndex, iFlags, 0.0f, true, pszTracerName );
break;

case TRACER_LINE_AND_WHIZ:
UTIL_Tracer( vNewSrc, tr.endpos, iEntIndex, iFlags, 0.0f, true, pszTracerName );
break;
}
}

//-----------------------------------------------------------------------------
// Purpose: Default Touch function for player picking up a weapon (not AI)
// Input : pOther - the entity that touched me
// Output :
//-----------------------------------------------------------------------------
void CBaseCombatWeapon::DefaultTouch( CBaseEntity *pOther )
{
#if !defined( CLIENT_DLL )
// Can't pick up dissolving weapons
if ( IsDissolving() )
return;

// if it's not a player, ignore
CBasePlayer *pPlayer = ToBasePlayer(pOther);
if ( !pPlayer )
return;

if( HasSpawnFlags(SF_WEAPON_NO_PLAYER_PICKUP) )
return;

if (pPlayer->BumpWeapon(this))
{
OnPickedUp( pPlayer );
}
#endif
}

//---------------------------------------------------------
// It's OK for base classes to override this completely
// without calling up. (sjb)
//---------------------------------------------------------
bool CBaseCombatWeapon::ShouldDisplayHUDHint()
{
if( UsesSecondaryAmmo() && HasSecondaryAmmo() )
{
return true;
}

if( !UsesSecondaryAmmo() && HasPrimaryAmmo() )
{
return true;
}

return false;
}

//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void CBaseCombatWeapon::DisplayAltFireHudHint()
{
#if !defined( CLIENT_DLL )
CFmtStr hint;
hint.sprintf( "#valve_hint_alt_%s", GetClassname() );
UTIL_HudHintText( GetOwner(), hint.Access() );
m_iHudHintCount++;
m_bHudHintDisplayed = true;
#endif//CLIENT_DLL
}

void CBaseCombatWeapon::SetPickupTouch( void )
{
#if !defined( CLIENT_DLL )
SetTouch(&CBaseCombatWeapon::DefaultTouch);

if ( gpGlobals->maxClients > 1 )
{
if ( GetSpawnFlags() & SF_NORESPAWN )
{
SetThink( &CBaseEntity::SUB_Remove );
SetNextThink( gpGlobals->curtime + 30.0f );
}
}

#endif
}

//-----------------------------------------------------------------------------
// Purpose: Become a child of the owner (MOVETYPE_FOLLOW)
// disables collisions, touch functions, thinking
// Input : *pOwner - new owner/operator
//-----------------------------------------------------------------------------
void CBaseCombatWeapon::Equip( CBaseCombatCharacter *pOwner )
{
// Attach the weapon to an owner
SetAbsVelocity( vec3_origin );
RemoveSolidFlags( FSOLID_TRIGGER );
FollowEntity( pOwner );
SetOwner( pOwner );
SetOwnerEntity( pOwner );

// Break any constraint I might have to the world.
RemoveEffects( EF_ITEM_BLINK );

#if !defined( CLIENT_DLL )
if ( m_pConstraint != NULL )
{
RemoveSpawnFlags( SF_WEAPON_START_CONSTRAINED );
physenv->DestroyConstraint( m_pConstraint );
m_pConstraint = NULL;
}
#endif

m_flNextPrimaryAttack = gpGlobals->curtime;
m_flNextSecondaryAttack = gpGlobals->curtime;
SetTouch( NULL );
SetThink( NULL );
#if !defined( CLIENT_DLL )
VPhysicsDestroyObject();
#endif

if ( pOwner->IsPlayer() )
{
SetModel( GetViewModel() );
}
else
{
// Make the weapon ready as soon as any NPC picks it up.
m_flNextPrimaryAttack = gpGlobals->curtime;
m_flNextSecondaryAttack = gpGlobals->curtime;
SetModel( GetWorldModel() );
}
}

void CBaseCombatWeapon::SetActivity( Activity act, float duration )
{
//Adrian: Oh man...ad//
if ( GetOwner()->IsPlayer() )
SetModel( GetWorldModel() );

int sequence = SelectWeightedSequence( act );

// FORCE IDLE on sequences we don't have (which should be many)
if ( sequence == ACTIVITY_NOT_AVAILABLE )
sequence = SelectWeightedSequence( ACT_VM_IDLE );

//Adrian: Oh man again...
if ( GetOwner()->IsPlayer() )
SetModel( GetViewModel() );
//ad
if ( sequence != ACTIVITY_NOT_AVAILABLE )
{
SetSequence( sequence );
SetActivity( act );
SetCycle( 0 );
ResetSequenceInfo( );

if ( duration > 0 )
{
// FIXME: does this even make sense in non-shoot animations?
m_flPlaybackRate = SequenceDuration( sequence ) / duration;
m_flPlaybackRate = min( m_flPlaybackRate, 12.0); // FIXME; magic number!, network encoding range
}
else
{
m_flPlaybackRate = 1.0;
}
}
}

//====================================================================================
// WEAPON CLIENT HANDLING
//====================================================================================
int CBaseCombatWeapon::UpdateClientData( CBasePlayer *pPlayer )
{
if ( pPlayer->GetActiveWeapon() == this )
{
if ( pPlayer->m_fOnTarget )
{
m_iState = WEAPON_IS_ONTARGET;
}
else
{
m_iState = WEAPON_IS_ACTIVE;
}
}
else
{
m_iState = WEAPON_IS_CARRIED_BY_PLAYER;
}
return 1;
}

//-----------------------------------------------------------------------------
// Purpose:
// Input : index -
//-----------------------------------------------------------------------------
void CBaseCombatWeapon::SetViewModelIndex( int index )
{
Assert( index >= 0 && index < MAX_VIEWMODELS );
m_nViewModelIndex = index;
}

//-----------------------------------------------------------------------------
// Purpose:
// Input : iActivity -
//-----------------------------------------------------------------------------
void CBaseCombatWeapon::SendViewModelAnim( int nSequence )
{
#if defined( CLIENT_DLL )
if ( !IsPredicted() )
return;
#endif

if ( nSequence < 0 )
return;

CBasePlayer *pOwner = ToBasePlayer( GetOwner() );

if ( pOwner == NULL )
return;

CBaseViewModel *vm = pOwner->GetViewModel( m_nViewModelIndex );

if ( vm == NULL )
return;

SetViewModel();
Assert( vm->ViewModelIndex() == m_nViewModelIndex );
vm->SendViewModelMatchingSequence( nSequence );
}

float CBaseCombatWeapon::GetViewModelSequenceDuration()
{
CBasePlayer *pOwner = ToBasePlayer( GetOwner() );
if ( pOwner == NULL )
{
Assert( false );
return 0;
}

CBaseViewModel *vm = pOwner->GetViewModel( m_nViewModelIndex );
if ( vm == NULL )
{
Assert( false );
return 0;
}

SetViewModel();
Assert( vm->ViewModelIndex() == m_nViewModelIndex );
return vm->SequenceDuration();
}

bool CBaseCombatWeapon::IsViewModelSequenceFinished( void )
{
// These are not valid activities and always complete immediately
if ( GetActivity() == ACT_RESET || GetActivity() == ACT_INVALID )
return true;

CBasePlayer *pOwner = ToBasePlayer( GetOwner() );
if ( pOwner == NULL )
{
Assert( false );
return false;
}

CBaseViewModel *vm = pOwner->GetViewModel( m_nViewModelIndex );
if ( vm == NULL )
{
Assert( false );
return false;
}

return vm->IsSequenceFinished();
}

//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CBaseCombatWeapon::SetViewModel()
{
CBasePlayer *pOwner = ToBasePlayer( GetOwner() );
if ( pOwner == NULL )
return;
CBaseViewModel *vm = pOwner->GetViewModel( m_nViewModelIndex );
if ( vm == NULL )
return;
Assert( vm->ViewModelIndex() == m_nViewModelIndex );
vm->SetWeaponModel( GetViewModel( m_nViewModelIndex ), this );
}

//-----------------------------------------------------------------------------
// Purpose: Set the desired activity for the weapon and its viewmodel counterpart
// Input : iActivity - activity to play
//-----------------------------------------------------------------------------
bool CBaseCombatWeapon::SendWeaponAnim( int iActivity )
{
//For now, just set the ideal activity and be done with it
return SetIdealActivity( (Activity) iActivity );
}

//====================================================================================
// WEAPON SELECTION
//====================================================================================

//-----------------------------------------------------------------------------
// Purpose: Returns true if the weapon currently has ammo or doesn't need ammo
// Output :
//-----------------------------------------------------------------------------
bool CBaseCombatWeapon::HasAnyAmmo( void )
{
// If I don't use ammo of any kind, I can always fire
if ( !UsesPrimaryAmmo() && !UsesSecondaryAmmo() )
return true;

// Otherwise, I need ammo of either type
return ( HasPrimaryAmmo() || HasSecondaryAmmo() );
}

//-----------------------------------------------------------------------------
// Purpose: Returns true if the weapon currently has ammo or doesn't need ammo
// Output :
//-----------------------------------------------------------------------------
bool CBaseCombatWeapon::HasPrimaryAmmo( void )
{
// If I use a clip, and have some ammo in it, then I have ammo
if ( UsesClipsForAmmo1() )
{
if ( m_iClip1 > 0 )
return true;
}

// Otherwise, I have ammo if I have some in my ammo counts
CBaseCombatCharacter *pOwner = GetOwner();
if ( pOwner )
{
if ( pOwner->GetAmmoCount( m_iPrimaryAmmoType ) > 0 )
return true;
}
else
{
// No owner, so return how much primary ammo I have along with me.
if( GetPrimaryAmmoCount() > 0 )
return true;
}

return false;
}

//-----------------------------------------------------------------------------
// Purpose: Returns true if the weapon currently has ammo or doesn't need ammo
// Output :
//-----------------------------------------------------------------------------
bool CBaseCombatWeapon::HasSecondaryAmmo( void )
{
// If I use a clip, and have some ammo in it, then I have ammo
if ( UsesClipsForAmmo2() )
{
if ( m_iClip2 > 0 )
return true;
}

// Otherwise, I have ammo if I have some in my ammo counts
CBaseCombatCharacter *pOwner = GetOwner();
if ( pOwner )
{
if ( pOwner->GetAmmoCount( m_iSecondaryAmmoType ) > 0 )
return true;
}

return false;
}

//-----------------------------------------------------------------------------
// Purpose: returns true if the weapon actually uses primary ammo
//-----------------------------------------------------------------------------
bool CBaseCombatWeapon::UsesPrimaryAmmo( void )
{
if ( m_iPrimaryAmmoType < 0 )
return false;
return true;
}

//-----------------------------------------------------------------------------
// Purpose: returns true if the weapon actually uses secondary ammo
//-----------------------------------------------------------------------------
bool CBaseCombatWeapon::UsesSecondaryAmmo( void )
{
if ( m_iSecondaryAmmoType < 0 )
return false;
return true;
}

//-----------------------------------------------------------------------------
// Purpose: Show/hide weapon and corresponding view model if any
// Input : visible -
//-----------------------------------------------------------------------------
void CBaseCombatWeapon::SetWeaponVisible( bool visible )
{
CBaseViewModel *vm = NULL;

CBasePlayer *pOwner = ToBasePlayer( GetOwner() );
if ( pOwner )
{
vm = pOwner->GetViewModel( m_nViewModelIndex );
}

if ( visible )
{
RemoveEffects( EF_NODRAW );
if ( vm )
{
vm->RemoveEffects( EF_NODRAW );
}
}
else
{
AddEffects( EF_NODRAW );
if ( vm )
{
vm->AddEffects( EF_NODRAW );
}
}
}

//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
bool CBaseCombatWeapon::IsWeaponVisible( void )
{
CBaseViewModel *vm = NULL;
CBasePlayer *pOwner = ToBasePlayer( GetOwner() );
if ( pOwner )
{
vm = pOwner->GetViewModel( m_nViewModelIndex );
if ( vm )
return ( !vm->IsEffectActive(EF_NODRAW) );
}

return false;
}

//-----------------------------------------------------------------------------
// Purpose: If the current weapon has more ammo, reload it. Otherwise, switch
// to the next best weapon we've got. Returns true if it took any action.
//-----------------------------------------------------------------------------
bool CBaseCombatWeapon::ReloadOrSwitchWeapons( void )
{
CBasePlayer *pOwner = ToBasePlayer( GetOwner() );
Assert( pOwner );

m_bFireOnEmpty = false;

// If we don't have any ammo, switch to the next best weapon
if ( !HasAnyAmmo() && m_flNextPrimaryAttack < gpGlobals->curtime && m_flNextSecondaryAttack < gpGlobals->curtime )
{
// weapon isn't useable, switch.
if ( ( (GetWeaponFlags() & ITEM_FLAG_NOAUTOSWITCHEMPTY) == false ) && ( g_pGameRules->SwitchToNextBestWeapon( pOwner, this ) ) )
{
m_flNextPrimaryAttack = gpGlobals->curtime + 0.3;
return true;
}
}
else
{
// Weapon is useable. Reload if empty and weapon has waited as long as it has to after firing
if ( UsesClipsForAmmo1() &&
(m_iClip1 == 0) &&
(GetWeaponFlags() & ITEM_FLAG_NOAUTORELOAD) == false &&
m_flNextPrimaryAttack < gpGlobals->curtime &&
m_flNextSecondaryAttack < gpGlobals->curtime )
{
// if we're successfully reloading, we're done
if ( Reload() )
return true;
}
}

return false;
}

//-----------------------------------------------------------------------------
// Purpose:
// Input : *szViewModel -
// *szWeaponModel -
// iActivity -
// *szAnimExt -
// Output : Returns true on success, false on failure.
//-----------------------------------------------------------------------------
bool CBaseCombatWeapon::DefaultDeploy( char *szViewModel, char *szWeaponModel, int iActivity, char *szAnimExt )
{
// Msg( "deploy %s at %f\n", GetClassname(), gpGlobals->curtime );

// Weapons that don't autoswitch away when they run out of ammo
// can still be deployed when they have no ammo.
if ( !HasAnyAmmo() && AllowsAutoSwitchFrom() )
return false;

CBasePlayer *pOwner = ToBasePlayer( GetOwner() );
if ( pOwner )
{
// Dead men deploy no weapons
if ( pOwner->IsAlive() == false )
return false;

pOwner->SetAnimationExtension( szAnimExt );

SetViewModel();
SendWeaponAnim( iActivity );

pOwner->SetNextAttack( gpGlobals->curtime + SequenceDuration() );
}

// Can't shoot again until we've finished deploying
m_flNextPrimaryAttack = gpGlobals->curtime + SequenceDuration();
m_flNextSecondaryAttack = gpGlobals->curtime + SequenceDuration();


if( m_iHudHintCount < WEAPON_ALTFIRE_HUD_HINT_COUNT )
{
m_bHudHintDisplayed = false;
m_flHudHintPollTime = gpGlobals->curtime + 5.0f;
}
else
{
// Set this to prevent the polling.
m_bHudHintDisplayed = true;
}

SetWeaponVisible( true );

/*

This code is disabled for now, because moving through the weapons in the carousel
selects and deploys each weapon as you pass it. (sjb)

*/

#ifndef CLIENT_DLL
// Cancel any pending hide events
g_EventQueue.CancelEventOn( this, "HideWeapon" );
#endif

return true;
}

//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
bool CBaseCombatWeapon::Deploy( )
{
MDLCACHE_CRITICAL_SECTION();
return DefaultDeploy( (char*)GetViewModel(), (char*)GetWorldModel(), GetDrawActivity(), (char*)GetAnimPrefix() );
}

Activity CBaseCombatWeapon::GetDrawActivity( void )
{
return ACT_VM_DRAW;
}

//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
bool CBaseCombatWeapon::Holster( CBaseCombatWeapon *pSwitchingTo )
{
// cancel any reload in progress.
m_bInReload = false;

// kill any think functions
SetThink(NULL);

// Send holster animation
SendWeaponAnim( ACT_VM_HOLSTER );

// Some weapon's don't have holster anims yet, so detect that
float flSequenceDuration = 0;
if ( GetActivity() == ACT_VM_HOLSTER )
{
flSequenceDuration = SequenceDuration();
}

CBaseCombatCharacter *pOwner = GetOwner();
if (pOwner)
{
pOwner->SetNextAttack( gpGlobals->curtime + flSequenceDuration );
}

#ifndef CLIENT_DLL
// If we don't have a holster anim, hide immediately to avoid timing issues
if ( !flSequenceDuration )
{
SetWeaponVisible( false );
}
else
{
// Hide the weapon when the holster animation's finished
g_EventQueue.AddEvent( this, "HideWeapon", flSequenceDuration, NULL, NULL );
}
#endif

return true;
}

#ifdef CLIENT_DLL

void CBaseCombatWeapon::BoneMergeFastCullBloat( Vector &localMins, Vector &localMaxs, const Vector &thisEntityMins, const Vector &thisEntityMaxs ) const
{
// The default behavior pushes it out by BONEMERGE_FASTCULL_BBOX_EXPAND in all directions, but we can do better
// since we know the weapon will never point behind him.

localMaxs.x += 20; // Leaves some space in front for long weapons.

localMins.y -= 20; // Fatten it to his left and right since he can rotate that way.
localMaxs.y += 20;

localMaxs.z += 15; // Leave some space at the top.
}

#else
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CBaseCombatWeapon::InputHideWeapon( inputdata_t &inputdata )
{
// Only hide if we're still the active weapon. If we're not the active weapon
if ( GetOwner() && GetOwner()->GetActiveWeapon() == this )
{
SetWeaponVisible( false );
}
}
#endif

//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CBaseCombatWeapon::ItemPreFrame( void )
{
MaintainIdealActivity();

#ifndef CLIENT_DLL
// If we haven't displayed the hint enough times yet, it's time to try to
// display the hint, and the player is not standing still, try to show a hud hint.
// If the player IS standing still, assume they could change away from this weapon at
// any second.
if( !m_bHudHintDisplayed && gpGlobals->curtime > m_flHudHintPollTime && GetOwner() && GetOwner()->IsPlayer() )
{
CBasePlayer *pPlayer = (CBasePlayer*)(GetOwner());

if( pPlayer && pPlayer->GetStickDist() > 0.0f )
{
// If the player is moving, they're unlikely to switch away from the current weapon
// the moment this weapon displays its HUD hint.
if( ShouldDisplayHUDHint() )
{
DisplayAltFireHudHint();
}
}
else
{
m_flHudHintPollTime = gpGlobals->curtime + 1.0f;
}
}
#endif
}

//====================================================================================
// WEAPON BEHAVIOUR
//====================================================================================
void CBaseCombatWeapon::ItemPostFrame( void )
{
CBasePlayer *pOwner = ToBasePlayer( GetOwner() );
if (!pOwner)
return;

//Track the duration of the fire
//FIXME: Check for IN_ATTACK2 as well?
//FIXME: What if we're calling ItemBusyFrame?
m_fFireDuration = ( pOwner->m_nButtons & IN_ATTACK ) ? ( m_fFireDuration + gpGlobals->frametime ) : 0.0f;

if ( UsesClipsForAmmo1() )
{
CheckReload();
}

bool bFired = false;

// Secondary attack has priority
if ((pOwner->m_nButtons & IN_ATTACK2) && (m_flNextSecondaryAttack <= gpGlobals->curtime))
{
if (UsesSecondaryAmmo() && pOwner->GetAmmoCount(m_iSecondaryAmmoType)<=0 )
{
if (m_flNextEmptySoundTime < gpGlobals->curtime)
{
WeaponSound(EMPTY);
m_flNextSecondaryAttack = m_flNextEmptySoundTime = gpGlobals->curtime + 0.5;
}
}
else if (pOwner->GetWaterLevel() == 3 && m_bAltFiresUnderwater == false)
{
// This weapon doesn't fire underwater
WeaponSound(EMPTY);
m_flNextPrimaryAttack = gpGlobals->curtime + 0.2;
return;
}
else
{
// FIXME: This isn't necessarily true if the weapon doesn't have a secondary fire!
bFired = true;
SecondaryAttack();

// Secondary ammo doesn't have a reload animation
if ( UsesClipsForAmmo2() )
{
// reload clip2 if empty
if (m_iClip2 < 1)
{
pOwner->RemoveAmmo( 1, m_iSecondaryAmmoType );
m_iClip2 = m_iClip2 + 1;
}
}
}
}

if ( !bFired && (pOwner->m_nButtons & IN_ATTACK) && (m_flNextPrimaryAttack <= gpGlobals->curtime))
{
// Clip empty? Or out of ammo on a no-clip weapon?
if ( !IsMeleeWeapon() &&
(( UsesClipsForAmmo1() && m_iClip1 <= 0) || ( !UsesClipsForAmmo1() && pOwner->GetAmmoCount(m_iPrimaryAmmoType)<=0 )) )
{
HandleFireOnEmpty();
}
else if (pOwner->GetWaterLevel() == 3 && m_bFiresUnderwater == false)
{
// This weapon doesn't fire underwater
WeaponSound(EMPTY);
m_flNextPrimaryAttack = gpGlobals->curtime + 0.2;
return;
}
else
{
//NOTENOTE: There is a bug with this code with regards to the way machine guns catch the leading edge trigger
// on the player hitting the attack key. It relies on the gun catching that case in the same frame.
// However, because the player can also be doing a secondary attack, the edge trigger may be missed.
// We really need to hold onto the edge trigger and only clear the condition when the gun has fired its
// first shot. Right now that's too much of an architecture change -- jdw

// If the firing button was just pressed, or the alt-fire just released, reset the firing time
if ( ( pOwner->m_afButtonPressed & IN_ATTACK ) || ( pOwner->m_afButtonReleased & IN_ATTACK2 ) )
{
m_flNextPrimaryAttack = gpGlobals->curtime;
}

PrimaryAttack();
}
}

// -----------------------
// Reload pressed / Clip Empty
// -----------------------
if ( pOwner->m_nButtons & IN_RELOAD && UsesClipsForAmmo1() && !m_bInReload )
{
// reload when reload is pressed, or if no buttons are down and weapon is empty.
Reload();
m_fFireDuration = 0.0f;
}

// -----------------------
// No buttons down
// -----------------------
if (!((pOwner->m_nButtons & IN_ATTACK) || (pOwner->m_nButtons & IN_ATTACK2) || (pOwner->m_nButtons & IN_RELOAD)))
{
// no fire buttons down or reloading
if ( !ReloadOrSwitchWeapons() && ( m_bInReload == false ) )
{
WeaponIdle();
}
}
}

void CBaseCombatWeapon::HandleFireOnEmpty()
{
// If we're already firing on empty, reload if we can
if ( m_bFireOnEmpty )
{
ReloadOrSwitchWeapons();
m_fFireDuration = 0.0f;
}
else
{
if (m_flNextEmptySoundTime < gpGlobals->curtime)
{
WeaponSound(EMPTY);
m_flNextEmptySoundTime = gpGlobals->curtime + 0.5;
}
m_bFireOnEmpty = true;
}
}

//-----------------------------------------------------------------------------
// Purpose: Called each frame by the player PostThink, if the player's not ready to attack yet
//-----------------------------------------------------------------------------
void CBaseCombatWeapon::ItemBusyFrame( void )
{
}

//-----------------------------------------------------------------------------
// Purpose: Base class default for getting bullet type
// Input :
// Output :
//-----------------------------------------------------------------------------
int CBaseCombatWeapon::GetBulletType( void )
{
return 0;
}

//-----------------------------------------------------------------------------
// Purpose: Base class default for getting spread
// Input :
// Output :
//-----------------------------------------------------------------------------
const Vector& CBaseCombatWeapon::GetBulletSpread( void )
{
static Vector cone = VECTOR_CONE_15DEGREES;
return cone;
}

//-----------------------------------------------------------------------------
const WeaponProficiencyInfo_t *CBaseCombatWeapon::GetProficiencyValues()
{
static WeaponProficiencyInfo_t defaultWeaponProficiencyTable[] =
{
{ 1.0, 1.0 },
{ 1.0, 1.0 },
{ 1.0, 1.0 },
{ 1.0, 1.0 },
{ 1.0, 1.0 },
};

COMPILE_TIME_ASSERT( ARRAYSIZE(defaultWeaponProficiencyTable) == WEAPON_PROFICIENCY_PERFECT + 1);
return defaultWeaponProficiencyTable;
}

//-----------------------------------------------------------------------------
// Purpose: Base class default for getting firerate
// Input :
// Output :
//-----------------------------------------------------------------------------
float CBaseCombatWeapon::GetFireRate( void )
{
return 0;
}

//-----------------------------------------------------------------------------
// Purpose: Base class default for playing shoot sound
// Input :
// Output :
//-----------------------------------------------------------------------------
void CBaseCombatWeapon::WeaponSound( WeaponSound_t sound_type, float soundtime /* = 0.0f */ )
{
// If we have some sounds from the weapon classname.txt file, play a random one of them
const char *shootsound = GetShootSound( sound_type );
if ( !shootsound || !shootsound[0] )
return;

CSoundParameters params;

if ( !GetParametersForSound( shootsound, params, NULL ) )
return;

if ( params.play_to_owner_only )
{
// Am I only to play to my owner?
if ( GetOwner() && GetOwner()->IsPlayer() )
{
CSingleUserRecipientFilter filter( ToBasePlayer( GetOwner() ) );
if ( IsPredicted() )
{
filter.UsePredictionRules();
}
EmitSound( filter, GetOwner()->entindex(), shootsound, NULL, soundtime );
}
}
else
{
// Play weapon sound from the owner
if ( GetOwner() )
{
CPASAttenuationFilter filter( GetOwner(), params.soundlevel );
if ( IsPredicted() )
{
filter.UsePredictionRules();
}
EmitSound( filter, GetOwner()->entindex(), shootsound, NULL, soundtime );

#if !defined( CLIENT_DLL )
if( sound_type == EMPTY )
{
CSoundEnt::InsertSound( SOUND_COMBAT, GetOwner()->GetAbsOrigin(), SOUNDENT_VOLUME_EMPTY, 0.2, GetOwner() );
}
#endif
}
// If no owner play from the weapon (this is used for thrown items)
else
{
CPASAttenuationFilter filter( this, params.soundlevel );
if ( IsPredicted() )
{
filter.UsePredictionRules();
}
EmitSound( filter, entindex(), shootsound, NULL, soundtime );
}
}
}

//-----------------------------------------------------------------------------
// Purpose: Stop a sound played by this weapon.
//-----------------------------------------------------------------------------
void CBaseCombatWeapon::StopWeaponSound( WeaponSound_t sound_type )
{
//if ( IsPredicted() )
// return;

// If we have some sounds from the weapon classname.txt file, play a random one of them
const char *shootsound = GetShootSound( sound_type );
if ( !shootsound || !shootsound[0] )
return;

CSoundParameters params;
if ( !GetParametersForSound( shootsound, params, NULL ) )
return;

// Am I only to play to my owner?
if ( params.play_to_owner_only )
{
if ( GetOwner() )
{
StopSound( GetOwner()->entindex(), shootsound );
}
}
else
{
// Play weapon sound from the owner
if ( GetOwner() )
{
StopSound( GetOwner()->entindex(), shootsound );
}
// If no owner play from the weapon (this is used for thrown items)
else
{
StopSound( entindex(), shootsound );
}
}
}

//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
bool CBaseCombatWeapon::DefaultReload( int iClipSize1, int iClipSize2, int iActivity )
{
CBaseCombatCharacter *pOwner = GetOwner();
if (!pOwner)
return false;

// If I don't have any spare ammo, I can't reload
if ( pOwner->GetAmmoCount(m_iPrimaryAmmoType) <= 0 )
return false;

bool bReload = false;

// If you don't have clips, then don't try to reload them.
if ( UsesClipsForAmmo1() )
{
// need to reload primary clip?
int primary = min(iClipSize1 - m_iClip1, pOwner->GetAmmoCount(m_iPrimaryAmmoType));
if ( primary != 0 )
{
bReload = true;
}
}

if ( UsesClipsForAmmo2() )
{
// need to reload secondary clip?
int secondary = min(iClipSize2 - m_iClip2, pOwner->GetAmmoCount(m_iSecondaryAmmoType));
if ( secondary != 0 )
{
bReload = true;
}
}

if ( !bReload )
return false;

#ifdef CLIENT_DLL
// Play reload
WeaponSound( RELOAD );
#endif
SendWeaponAnim( iActivity );

// Play the player's reload animation
if ( pOwner->IsPlayer() )
{
( ( CBasePlayer * )pOwner)->SetAnimation( PLAYER_RELOAD );
}

MDLCACHE_CRITICAL_SECTION();
float flSequenceEndTime = gpGlobals->curtime + SequenceDuration();
pOwner->SetNextAttack( flSequenceEndTime );
m_flNextPrimaryAttack = m_flNextSecondaryAttack = flSequenceEndTime;

m_bInReload = true;

return true;
}

//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
bool CBaseCombatWeapon::Reload( void )
{
return DefaultReload( GetMaxClip1(), GetMaxClip2(), ACT_VM_RELOAD );
}

//=========================================================
void CBaseCombatWeapon::WeaponIdle( void )
{
//Idle again if we've finished
if ( HasWeaponIdleTimeElapsed() )
{
SendWeaponAnim( ACT_VM_IDLE );
}
}

//=========================================================
Activity CBaseCombatWeapon::GetPrimaryAttackActivity( void )
{
return ACT_VM_PRIMARYATTACK;
}

//=========================================================
Activity CBaseCombatWeapon::GetSecondaryAttackActivity( void )
{
return ACT_VM_SECONDARYATTACK;
}

//-----------------------------------------------------------------------------
// Purpose: Adds in view kick and weapon accuracy degradation effect
//-----------------------------------------------------------------------------
void CBaseCombatWeapon::AddViewKick( void )
{
//NOTENOTE: By default, weapon will not kick up (defined per weapon)
}

//-----------------------------------------------------------------------------
// Purpose: Get the string to print death notices with
//-----------------------------------------------------------------------------
char *CBaseCombatWeapon::GetDeathNoticeName( void )
{
#if !defined( CLIENT_DLL )
return (char*)STRING( m_iszName );
#else
return "GetDeathNoticeName not implemented on client yet";
#endif
}

//====================================================================================
// WEAPON RELOAD TYPES
//====================================================================================
void CBaseCombatWeapon::CheckReload( void )
{
if ( m_bReloadsSingly )
{
CBasePlayer *pOwner = ToBasePlayer( GetOwner() );
if ( !pOwner )
return;

if ((m_bInReload) && (m_flNextPrimaryAttack <= gpGlobals->curtime))
{
if ( pOwner->m_nButtons & (IN_ATTACK | IN_ATTACK2) && m_iClip1 > 0 )
{
m_bInReload = false;
return;
}

// If out of ammo end reload
if (pOwner->GetAmmoCount(m_iPrimaryAmmoType) <=0)
{
FinishReload();
return;
}
// If clip not full reload again
else if (m_iClip1 < GetMaxClip1())
{
// Add them to the clip
m_iClip1 += 1;
pOwner->RemoveAmmo( 1, m_iPrimaryAmmoType );

Reload();
return;
}
// Clip full, stop reloading
else
{
FinishReload();
m_flNextPrimaryAttack = gpGlobals->curtime;
m_flNextSecondaryAttack = gpGlobals->curtime;
return;
}
}
}
else
{
if ( (m_bInReload) && (m_flNextPrimaryAttack <= gpGlobals->curtime))
{
FinishReload();
m_flNextPrimaryAttack = gpGlobals->curtime;
m_flNextSecondaryAttack = gpGlobals->curtime;
m_bInReload = false;
}
}
}

//-----------------------------------------------------------------------------
// Purpose: Reload has finished.
//-----------------------------------------------------------------------------
void CBaseCombatWeapon::FinishReload( void )
{
CBaseCombatCharacter *pOwner = GetOwner();

if (pOwner)
{
// If I use primary clips, reload primary
if ( UsesClipsForAmmo1() )
{
int primary = min( GetMaxClip1() - m_iClip1, pOwner->GetAmmoCount(m_iPrimaryAmmoType));
m_iClip1 += primary;
pOwner->RemoveAmmo( primary, m_iPrimaryAmmoType);
}

// If I use secondary clips, reload secondary
if ( UsesClipsForAmmo2() )
{
int secondary = min( GetMaxClip2() - m_iClip2, pOwner->GetAmmoCount(m_iSecondaryAmmoType));
m_iClip2 += secondary;
pOwner->RemoveAmmo( secondary, m_iSecondaryAmmoType );
}

if ( m_bReloadsSingly )
{
m_bInReload = false;
}
}
}

//-----------------------------------------------------------------------------
// Purpose: Abort any reload we have in progress
//-----------------------------------------------------------------------------
void CBaseCombatWeapon::AbortReload( void )
{
#ifdef CLIENT_DLL
StopWeaponSound( RELOAD );
#endif
m_bInReload = false;
}

//-----------------------------------------------------------------------------
// Purpose: Primary fire button attack
//-----------------------------------------------------------------------------
void CBaseCombatWeapon::PrimaryAttack( void )
{
// If my clip is empty (and I use clips) start reload
if ( UsesClipsForAmmo1() && !m_iClip1 )
{
Reload();
return;
}

// Only the player fires this way so we can cast
CBasePlayer *pPlayer = ToBasePlayer( GetOwner() );

if (!pPlayer)
{
return;
}

// MUST call sound before removing a round from the clip of a CMachineGun
WeaponSound(SINGLE);

pPlayer->DoMuzzleFlash();

SendWeaponAnim( GetPrimaryAttackActivity() );

// player "shoot" animation
pPlayer->SetAnimation( PLAYER_ATTACK1 );

FireBulletsInfo_t info;
info.m_vecSrc = pPlayer->Weapon_ShootPosition( );

info.m_vecDirShooting = pPlayer->GetAutoaimVector( AUTOAIM_SCALE_DEFAULT );

// To make the firing framerate independent, we may have to fire more than one bullet here on low-framerate systems,
// especially if the weapon we're firing has a really fast rate of fire.
info.m_iShots = 0;
float fireRate = GetFireRate();

while ( m_flNextPrimaryAttack <= gpGlobals->curtime )
{
m_flNextPrimaryAttack = m_flNextPrimaryAttack + fireRate;
info.m_iShots++;
if ( !fireRate )
break;
}

// Make sure we don't fire more than the amount in the clip
if ( UsesClipsForAmmo1() )
{
info.m_iShots = min( info.m_iShots, m_iClip1 );
m_iClip1 -= info.m_iShots;
}
else
{
info.m_iShots = min( info.m_iShots, pPlayer->GetAmmoCount( m_iPrimaryAmmoType ) );
pPlayer->RemoveAmmo( info.m_iShots, m_iPrimaryAmmoType );
}

info.m_flDistance = MAX_TRACE_LENGTH;
info.m_iAmmoType = m_iPrimaryAmmoType;
info.m_iTracerFreq = 2;

#if !defined( CLIENT_DLL )
// Fire the bullets
info.m_vecSpread = pPlayer->GetAttackSpread( this );
#else
//!!!HACKHACK - what does the client want this function for?
info.m_vecSpread = GetActiveWeapon()->GetBulletSpread();
#endif // CLIENT_DLL

pPlayer->FireBullets( info );

if (!m_iClip1 && pPlayer->GetAmmoCount(m_iPrimaryAmmoType) <= 0)
{
// HEV suit - indicate out of ammo condition
pPlayer->SetSuitUpdate("!HEV_AMO0", FALSE, 0);
}

//Add our view kick in
AddViewKick();
}

//-----------------------------------------------------------------------------
// Purpose: Called every frame to check if the weapon is going through transition animations
//-----------------------------------------------------------------------------
void CBaseCombatWeapon::MaintainIdealActivity( void )
{
// Must be transitioning
if ( GetActivity() != ACT_TRANSITION )
return;

// Must not be at our ideal already
if ( ( GetActivity() == m_IdealActivity ) && ( GetSequence() == m_nIdealSequence ) )
return;

// Must be finished with the current animation
if ( IsViewModelSequenceFinished() == false )
return;

// Move to the next animation towards our ideal
SendWeaponAnim( m_IdealActivity );
}

//-----------------------------------------------------------------------------
// Purpose: Sets the ideal activity for the weapon to be in, allowing for transitional animations inbetween
// Input : ideal - activity to end up at, ideally
//-----------------------------------------------------------------------------
bool CBaseCombatWeapon::SetIdealActivity( Activity ideal )
{
MDLCACHE_CRITICAL_SECTION();
int idealSequence = SelectWeightedSequence( ideal );

if ( idealSequence == -1 )
return false;

//Take the new activity
m_IdealActivity = ideal;
m_nIdealSequence = idealSequence;

//Find the next sequence in the potential chain of sequences leading to our ideal one
int nextSequence = FindTransitionSequence( GetSequence(), m_nIdealSequence, NULL );

// Don't use transitions when we're deploying
if ( ideal != ACT_VM_DRAW && IsWeaponVisible() && nextSequence != m_nIdealSequence )
{
//Set our activity to the next transitional animation
SetActivity( ACT_TRANSITION );
SetSequence( nextSequence );
SendViewModelAnim( nextSequence );
}
else
{
//Set our activity to the ideal
SetActivity( m_IdealActivity );
SetSequence( m_nIdealSequence );
SendViewModelAnim( m_nIdealSequence );
}

//Set the next time the weapon will idle
SetWeaponIdleTime( gpGlobals->curtime + SequenceDuration() );
return true;
}

//-----------------------------------------------------------------------------
// Returns information about the various control panels
//-----------------------------------------------------------------------------
void CBaseCombatWeapon::GetControlPanelInfo( int nPanelIndex, const char *&pPanelName )
{
pPanelName = NULL;
}

//-----------------------------------------------------------------------------
// Returns information about the various control panels
//-----------------------------------------------------------------------------
void CBaseCombatWeapon::GetControlPanelClassName( int nPanelIndex, const char *&pPanelName )
{
pPanelName = "vgui_screen";
}

//-----------------------------------------------------------------------------
// Locking a weapon is an exclusive action. If you lock a weapon, that means
// you are preventing others from doing so for themselves.
//-----------------------------------------------------------------------------
void CBaseCombatWeapon::Lock( float lockTime, CBaseEntity *pLocker )
{
m_flUnlockTime = gpGlobals->curtime + lockTime;
m_hLocker.Set( pLocker );
}

//-----------------------------------------------------------------------------
// If I'm still locked for a period of time, tell everyone except the person
// that locked me that I'm not available.
//-----------------------------------------------------------------------------
bool CBaseCombatWeapon::IsLocked( CBaseEntity *pAsker )
{
return ( m_flUnlockTime > gpGlobals->curtime && m_hLocker != pAsker );
}

//-----------------------------------------------------------------------------
// Purpose:
// Input :
// Output :
//-----------------------------------------------------------------------------
Activity CBaseCombatWeapon::ActivityOverride( Activity baseAct, bool *pRequired )
{
acttable_t *pTable = ActivityList();
int actCount = ActivityListCount();

for ( int i = 0; i < actCount; i++, pTable++ )
{
if ( baseAct == pTable->baseAct )
{
if (pRequired)
{
*pRequired = pTable->required;
}
return (Activity)pTable->weaponAct;
}
}
return baseAct;
}

//=========================================================
//=========================================================
class CGameWeaponManager : public CBaseEntity
{
DECLARE_CLASS( CGameWeaponManager, CBaseEntity );

#if !defined( CLIENT_DLL )
DECLARE_DATADESC();
#endif

public:
void Spawn();
CGameWeaponManager()
{
m_flAmmoMod = 1.0f;
}

#if !defined( CLIENT_DLL )
void Think();
void InputSetMaxPieces( inputdata_t &inputdata );
void InputSetAmmoModifier( inputdata_t &inputdata );
#endif

string_t m_iszWeaponName;
int m_iMaxPieces;
float m_flAmmoMod;
};

#if !defined( CLIENT_DLL )

BEGIN_DATADESC( CGameWeaponManager )

//fields
DEFINE_KEYFIELD( m_iszWeaponName, FIELD_STRING, "weaponname" ),
DEFINE_KEYFIELD( m_iMaxPieces, FIELD_INTEGER, "maxpieces" ),
DEFINE_KEYFIELD( m_flAmmoMod, FIELD_FLOAT, "ammomod" ),
// funcs
DEFINE_FUNCTION( Think ),
// inputs
DEFINE_INPUTFUNC( FIELD_INTEGER, "SetMaxPieces", InputSetMaxPieces ),
DEFINE_INPUTFUNC( FIELD_FLOAT, "SetAmmoModifier", InputSetAmmoModifier ),

END_DATADESC()

#endif

LINK_ENTITY_TO_CLASS( game_weapon_manager, CGameWeaponManager );

#if !defined( CLIENT_DLL )
void WeaponManager_AmmoMod( CBaseCombatWeapon *pWeapon )
{
CGameWeaponManager *pWeaponManager = (CGameWeaponManager *)gEntList.FindEntityByClassname( NULL, "game_weapon_manager" );

while ( pWeaponManager )
{
if ( pWeaponManager->m_iszWeaponName == pWeapon->m_iClassname )
{
int iNewClip = (int)(pWeapon->m_iClip1 * pWeaponManager->m_flAmmoMod);
int iNewRandomClip = iNewClip + RandomInt( -2, 2 );

if ( iNewRandomClip > pWeapon->GetMaxClip1() )
{
iNewRandomClip = pWeapon->GetMaxClip1();
}
else if ( iNewRandomClip <= 0 )
{
//Drop at least one bullet.
iNewRandomClip = 1;
}

pWeapon->m_iClip1 = iNewRandomClip;
}

pWeaponManager = (CGameWeaponManager *)gEntList.FindEntityByClassname( pWeaponManager, "game_weapon_manager" );
}
}
#endif

//---------------------------------------------------------
//---------------------------------------------------------
void CGameWeaponManager::Spawn()
{
#if !defined( CLIENT_DLL )
SetThink( &CGameWeaponManager::Think );
SetNextThink( gpGlobals->curtime );
#endif
}

//---------------------------------------------------------
// Count of all the weapons in the world of my type and
// see if we have a surplus. If there is a surplus, try
// to find suitable candidates for removal.
//
// Right now we just remove the first weapons we find that
// are behind the player, or are out of the player's PVS.
// Later, we may want to score the results so that we
// removed the farthest gun that's not in the player's
// viewcone, etc.
//
// Some notes and thoughts:
//
// This code is designed NOT to remove weapons that are
// hand-placed by level designers. It should only clean
// up weapons dropped by dead NPCs, which is useful in
// situations where enemies are spawned in for a sustained
// period of time.
//
// Right now we PREFER to remove weapons that are not in the
// player's PVS, but this could be opposite of what we
// really want. We may only want to conduct the cleanup on
// weapons that are IN the player's PVS.
//---------------------------------------------------------
#if !defined( CLIENT_DLL )

void CGameWeaponManager::Think()
{

// Don't have to think all that often.
SetNextThink( gpGlobals->curtime + 2.0 );

CBaseCombatWeapon *pWeapon = NULL;
const char *pszWeaponName = STRING( m_iszWeaponName );
int count = 0;
int removeableCount = 0;

// Firstly, count the total number of weapons of this type in the world.
// Also count how many of those can potentially be removed.
pWeapon = (CBaseCombatWeapon *)gEntList.FindEntityByClassname( pWeapon, pszWeaponName );
while( pWeapon )
{
count++;

if( pWeapon->IsRemoveable() )
{
removeableCount++;
}

pWeapon = (CBaseCombatWeapon *)gEntList.FindEntityByClassname( pWeapon, pszWeaponName );
}

// Calculate the surplus.
int surplus = removeableCount - m_iMaxPieces;

// Based on what the player can see, try to clean up the world by removing weapons that
// the player cannot see right at the moment.
CBasePlayer *pPlayer = UTIL_GetLocalPlayer();
while( surplus > 0 )
{
bool fRemovedOne = false;

pWeapon = (CBaseCombatWeapon *)gEntList.FindEntityByClassname( NULL, pszWeaponName );
while( pWeapon )
{
if( !pWeapon->IsEffectActive( EF_NODRAW ) && pWeapon->IsRemoveable() )
{
// Nodraw serves as a flag that this weapon is already being removed since
// all we're really doing inside this loop is marking them for removal by
// the entity system. We don't want to count the same weapon as removed
// more than once.
if( !UTIL_FindClientInPVS( pWeapon->edict() ) )
{
fRemovedOne = true;
}
else if( !pPlayer->FInViewCone( pWeapon ) )
{
fRemovedOne = true;
}
else if ( UTIL_DistApprox( pPlayer->GetAbsOrigin(), pWeapon->GetAbsOrigin() ) > (30*12) )
{
fRemovedOne = true;
}

if( fRemovedOne )
{
pWeapon->AddEffects( EF_NODRAW );
UTIL_Remove( pWeapon );

DevMsg( 2, "Surplus %s removed\n", pszWeaponName);
surplus--;

if( surplus == 0 )
break;
}
}

pWeapon = (CBaseCombatWeapon *)gEntList.FindEntityByClassname( pWeapon, pszWeaponName );
}

if( !fRemovedOne )
{
// No suitable candidates for removal right now.
break;
}
}
}

//---------------------------------------------------------
//---------------------------------------------------------
void CGameWeaponManager::InputSetMaxPieces( inputdata_t &inputdata )
{
m_iMaxPieces = inputdata.value.Int();
}

//---------------------------------------------------------
//---------------------------------------------------------
void CGameWeaponManager::InputSetAmmoModifier( inputdata_t &inputdata )
{
m_flAmmoMod = inputdata.value.Float();
}

#else

BEGIN_PREDICTION_DATA( CBaseCombatWeapon )

DEFINE_PRED_FIELD( m_nNextThinkTick, FIELD_INTEGER, FTYPEDESC_INSENDTABLE ),
// Networked
DEFINE_PRED_FIELD( m_hOwner, FIELD_EHANDLE, FTYPEDESC_INSENDTABLE ),
// DEFINE_FIELD( m_hWeaponFileInfo, FIELD_SHORT ),
DEFINE_PRED_FIELD( m_iState, FIELD_INTEGER, FTYPEDESC_INSENDTABLE ),
DEFINE_PRED_FIELD( m_iViewModelIndex, FIELD_INTEGER, FTYPEDESC_INSENDTABLE | FTYPEDESC_MODELINDEX ),
DEFINE_PRED_FIELD( m_iWorldModelIndex, FIELD_INTEGER, FTYPEDESC_INSENDTABLE | FTYPEDESC_MODELINDEX ),
DEFINE_PRED_FIELD_TOL( m_flNextPrimaryAttack, FIELD_FLOAT, FTYPEDESC_INSENDTABLE, TD_MSECTOLERANCE ),
DEFINE_PRED_FIELD_TOL( m_flNextSecondaryAttack, FIELD_FLOAT, FTYPEDESC_INSENDTABLE, TD_MSECTOLERANCE ),
DEFINE_PRED_FIELD_TOL( m_flTimeWeaponIdle, FIELD_FLOAT, FTYPEDESC_INSENDTABLE, TD_MSECTOLERANCE ),

DEFINE_PRED_FIELD( m_iPrimaryAmmoType, FIELD_INTEGER, FTYPEDESC_INSENDTABLE ),
DEFINE_PRED_FIELD( m_iSecondaryAmmoType, FIELD_INTEGER, FTYPEDESC_INSENDTABLE ),
DEFINE_PRED_FIELD( m_iClip1, FIELD_INTEGER, FTYPEDESC_INSENDTABLE ),
DEFINE_PRED_FIELD( m_iClip2, FIELD_INTEGER, FTYPEDESC_INSENDTABLE ),

DEFINE_PRED_FIELD( m_nViewModelIndex, FIELD_INTEGER, FTYPEDESC_INSENDTABLE ),

// Not networked

DEFINE_PRED_FIELD( m_flTimeWeaponIdle, FIELD_FLOAT, FTYPEDESC_INSENDTABLE ),
DEFINE_FIELD( m_bInReload, FIELD_BOOLEAN ),
DEFINE_FIELD( m_bFireOnEmpty, FIELD_BOOLEAN ),
DEFINE_FIELD( m_flNextEmptySoundTime, FIELD_FLOAT ),
DEFINE_FIELD( m_Activity, FIELD_INTEGER ),
DEFINE_FIELD( m_fFireDuration, FIELD_FLOAT ),
DEFINE_FIELD( m_iszName, FIELD_INTEGER ),
DEFINE_FIELD( m_bFiresUnderwater, FIELD_BOOLEAN ),
DEFINE_FIELD( m_bAltFiresUnderwater, FIELD_BOOLEAN ),
DEFINE_FIELD( m_fMinRange1, FIELD_FLOAT ),
DEFINE_FIELD( m_fMinRange2, FIELD_FLOAT ),
DEFINE_FIELD( m_fMaxRange1, FIELD_FLOAT ),
DEFINE_FIELD( m_fMaxRange2, FIELD_FLOAT ),
DEFINE_FIELD( m_bReloadsSingly, FIELD_BOOLEAN ),
DEFINE_FIELD( m_bRemoveable, FIELD_BOOLEAN ),
DEFINE_FIELD( m_iPrimaryAmmoCount, FIELD_INTEGER ),
DEFINE_FIELD( m_iSecondaryAmmoCount, FIELD_INTEGER ),

//DEFINE_PHYSPTR( m_pConstraint ),

// DEFINE_FIELD( m_iOldState, FIELD_INTEGER ),
// DEFINE_FIELD( m_bJustRestored, FIELD_BOOLEAN ),

// DEFINE_FIELD( m_OnPlayerPickup, COutputEvent ),
// DEFINE_FIELD( m_pConstraint, FIELD_INTEGER ),

END_PREDICTION_DATA()

#endif // ! CLIENT_DLL

// Special hack since we're aliasing the name C_BaseCombatWeapon with a macro on the client
IMPLEMENT_NETWORKCLASS_ALIASED( BaseCombatWeapon, DT_BaseCombatWeapon )

#if !defined( CLIENT_DLL )
//-----------------------------------------------------------------------------
// Purpose: Save Data for Base Weapon object
//-----------------------------------------------------------------------------//
BEGIN_DATADESC( CBaseCombatWeapon )

DEFINE_FIELD( m_flNextPrimaryAttack, FIELD_TIME ),
DEFINE_FIELD( m_flNextSecondaryAttack, FIELD_TIME ),
DEFINE_FIELD( m_flTimeWeaponIdle, FIELD_TIME ),

DEFINE_FIELD( m_bInReload, FIELD_BOOLEAN ),
DEFINE_FIELD( m_bFireOnEmpty, FIELD_BOOLEAN ),
DEFINE_FIELD( m_hOwner, FIELD_EHANDLE ),

DEFINE_FIELD( m_iState, FIELD_INTEGER ),
DEFINE_FIELD( m_iszName, FIELD_STRING ),
DEFINE_FIELD( m_iPrimaryAmmoType, FIELD_INTEGER ),
DEFINE_FIELD( m_iSecondaryAmmoType, FIELD_INTEGER ),
DEFINE_FIELD( m_iClip1, FIELD_INTEGER ),
DEFINE_FIELD( m_iClip2, FIELD_INTEGER ),
DEFINE_FIELD( m_bFiresUnderwater, FIELD_BOOLEAN ),
DEFINE_FIELD( m_bAltFiresUnderwater, FIELD_BOOLEAN ),
DEFINE_FIELD( m_fMinRange1, FIELD_FLOAT ),
DEFINE_FIELD( m_fMinRange2, FIELD_FLOAT ),
DEFINE_FIELD( m_fMaxRange1, FIELD_FLOAT ),
DEFINE_FIELD( m_fMaxRange2, FIELD_FLOAT ),

DEFINE_FIELD( m_iPrimaryAmmoCount, FIELD_INTEGER ),
DEFINE_FIELD( m_iSecondaryAmmoCount, FIELD_INTEGER ),

DEFINE_FIELD( m_nViewModelIndex, FIELD_INTEGER ),

// don't save these, init to 0 and regenerate
// DEFINE_FIELD( m_flNextEmptySoundTime, FIELD_TIME ),
// DEFINE_FIELD( m_Activity, FIELD_INTEGER ),
DEFINE_FIELD( m_nIdealSequence, FIELD_INTEGER ),
DEFINE_FIELD( m_IdealActivity, FIELD_INTEGER ),

DEFINE_FIELD( m_fFireDuration, FIELD_FLOAT ),

DEFINE_FIELD( m_bReloadsSingly, FIELD_BOOLEAN ),
DEFINE_FIELD( m_iSubType, FIELD_INTEGER ),
DEFINE_FIELD( m_bRemoveable, FIELD_BOOLEAN ),

DEFINE_FIELD( m_flUnlockTime, FIELD_TIME ),
DEFINE_FIELD( m_hLocker, FIELD_EHANDLE ),

// DEFINE_FIELD( m_iViewModelIndex, FIELD_INTEGER ),
// DEFINE_FIELD( m_iWorldModelIndex, FIELD_INTEGER ),
// DEFINE_FIELD( m_hWeaponFileInfo, ???? ),

DEFINE_PHYSPTR( m_pConstraint ),

DEFINE_FIELD( m_iHudHintCount, FIELD_INTEGER ),
DEFINE_FIELD( m_bHudHintDisplayed, FIELD_BOOLEAN ),
DEFINE_FIELD( m_flHudHintPollTime, FIELD_TIME ),

// Just to quiet classcheck.. this field exists only on the client
// DEFINE_FIELD( m_iOldState, FIELD_INTEGER ),
// DEFINE_FIELD( m_bJustRestored, FIELD_BOOLEAN ),

// Function pointers
DEFINE_FUNCTION( DefaultTouch ),
DEFINE_FUNCTION( FallThink ),
DEFINE_FUNCTION( Materialize ),
DEFINE_FUNCTION( AttemptToMaterialize ),
DEFINE_FUNCTION( DestroyItem ),
DEFINE_FUNCTION( SetPickupTouch ),

DEFINE_INPUTFUNC( FIELD_VOID, "HideWeapon", InputHideWeapon ),

// Outputs
DEFINE_OUTPUT( m_OnPlayerUse, "OnPlayerUse"),
DEFINE_OUTPUT( m_OnPlayerPickup, "OnPlayerPickup"),
DEFINE_OUTPUT( m_OnNPCPickup, "OnNPCPickup"),

END_DATADESC()

//-----------------------------------------------------------------------------
// Purpose: Only send to local player if this weapon is the active weapon
// Input : *pStruct -
// *pVarData -
// *pRecipients -
// objectID -
// Output : void*
//-----------------------------------------------------------------------------
void* SendProxy_SendActiveLocalWeaponDataTable( const SendProp *pProp, const void *pStruct, const void *pVarData, CSendProxyRecipients *pRecipients, int objectID )
{
// Get the weapon entity
CBaseCombatWeapon *pWeapon = (CBaseCombatWeapon*)pVarData;
if ( pWeapon )
{
// Only send this chunk of data to the player carrying this weapon
CBasePlayer *pPlayer = ToBasePlayer( pWeapon->GetOwner() );
if ( pPlayer /*&& pPlayer->GetActiveWeapon() == pWeapon*/ )
{
pRecipients->SetOnly( pPlayer->GetClientIndex() );
return (void*)pVarData;
}
}

return NULL;
}
REGISTER_SEND_PROXY_NON_MODIFIED_POINTER( SendProxy_SendActiveLocalWeaponDataTable );

//-----------------------------------------------------------------------------
// Purpose: Only send the LocalWeaponData to the player carrying the weapon
//-----------------------------------------------------------------------------
void* SendProxy_SendLocalWeaponDataTable( const SendProp *pProp, const void *pStruct, const void *pVarData, CSendProxyRecipients *pRecipients, int objectID )
{
// Get the weapon entity
CBaseCombatWeapon *pWeapon = (CBaseCombatWeapon*)pVarData;
if ( pWeapon )
{
// Only send this chunk of data to the player carrying this weapon
CBasePlayer *pPlayer = ToBasePlayer( pWeapon->GetOwner() );
if ( pPlayer )
{
pRecipients->SetOnly( pPlayer->GetClientIndex() );
return (void*)pVarData;
}
}

return NULL;
}
REGISTER_SEND_PROXY_NON_MODIFIED_POINTER( SendProxy_SendLocalWeaponDataTable );
#endif

//-----------------------------------------------------------------------------
// Purpose: Propagation data for weapons. Only sent when a player's holding it.
//-----------------------------------------------------------------------------
BEGIN_NETWORK_TABLE_NOBASE( CBaseCombatWeapon, DT_LocalActiveWeaponData )
#if !defined( CLIENT_DLL )
SendPropTime( SENDINFO( m_flNextPrimaryAttack ) ),
SendPropTime( SENDINFO( m_flNextSecondaryAttack ) ),
SendPropInt( SENDINFO( m_nNextThinkTick ) ),
SendPropTime( SENDINFO( m_flTimeWeaponIdle ) ),
#else
RecvPropTime( RECVINFO( m_flNextPrimaryAttack ) ),
RecvPropTime( RECVINFO( m_flNextSecondaryAttack ) ),
RecvPropInt( RECVINFO( m_nNextThinkTick ) ),
RecvPropTime( RECVINFO( m_flTimeWeaponIdle ) ),
#endif
END_NETWORK_TABLE()

//-----------------------------------------------------------------------------
// Purpose: Propagation data for weapons. Only sent when a player's holding it.
//-----------------------------------------------------------------------------
BEGIN_NETWORK_TABLE_NOBASE( CBaseCombatWeapon, DT_LocalWeaponData )
#if !defined( CLIENT_DLL )
SendPropIntWithMinusOneFlag( SENDINFO(m_iClip1 ), 8 ),
SendPropIntWithMinusOneFlag( SENDINFO(m_iClip2 ), 8 ),
SendPropInt( SENDINFO(m_iPrimaryAmmoType ), 8 ),
SendPropInt( SENDINFO(m_iSecondaryAmmoType ), 8 ),

SendPropInt( SENDINFO( m_nViewModelIndex ), VIEWMODEL_INDEX_BITS, SPROP_UNSIGNED ),

#else
RecvPropIntWithMinusOneFlag( RECVINFO(m_iClip1 )),
RecvPropIntWithMinusOneFlag( RECVINFO(m_iClip2 )),
RecvPropInt( RECVINFO(m_iPrimaryAmmoType )),
RecvPropInt( RECVINFO(m_iSecondaryAmmoType )),

RecvPropInt( RECVINFO( m_nViewModelIndex ) ),

#endif
END_NETWORK_TABLE()

BEGIN_NETWORK_TABLE(CBaseCombatWeapon, DT_BaseCombatWeapon)
#if !defined( CLIENT_DLL )
SendPropDataTable("LocalWeaponData", 0, &REFERENCE_SEND_TABLE(DT_LocalWeaponData), SendProxy_SendLocalWeaponDataTable ),
SendPropDataTable("LocalActiveWeaponData", 0, &REFERENCE_SEND_TABLE(DT_LocalActiveWeaponData), SendProxy_SendActiveLocalWeaponDataTable ),
SendPropModelIndex( SENDINFO(m_iViewModelIndex) ),
SendPropModelIndex( SENDINFO(m_iWorldModelIndex) ),
SendPropInt( SENDINFO(m_iState ), 8, SPROP_UNSIGNED ),
SendPropEHandle( SENDINFO(m_hOwner) ),
#else
RecvPropDataTable("LocalWeaponData", 0, 0, &REFERENCE_RECV_TABLE(DT_LocalWeaponData)),
RecvPropDataTable("LocalActiveWeaponData", 0, 0, &REFERENCE_RECV_TABLE(DT_LocalActiveWeaponData)),
RecvPropInt( RECVINFO(m_iViewModelIndex)),
RecvPropInt( RECVINFO(m_iWorldModelIndex)),
RecvPropInt( RECVINFO(m_iState )),
RecvPropEHandle( RECVINFO(m_hOwner ) ),
#endif
END_NETWORK_TABLE()