You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
2243 lines
93 KiB
2243 lines
93 KiB
![]()
4 years ago
|
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||
|
//
|
||
|
// Purpose: The TF Game rules
|
||
|
//
|
||
|
// $NoKeywords: $
|
||
|
//=============================================================================//
|
||
|
|
||
|
#include "cbase.h"
|
||
|
#include "tf_gamerules.h"
|
||
|
#include "tf_shareddefs.h"
|
||
|
#include "ammodef.h"
|
||
|
#include "basetfcombatweapon_shared.h"
|
||
|
#include <KeyValues.h>
|
||
|
|
||
|
|
||
|
#ifdef CLIENT_DLL
|
||
|
|
||
|
#include "c_shield.h"
|
||
|
#include "c_te_effect_dispatch.h"
|
||
|
#define CShield C_Shield
|
||
|
|
||
|
#else
|
||
|
|
||
|
#include "tf_shield.h"
|
||
|
#include "te_effect_dispatch.h"
|
||
|
#include "player.h"
|
||
|
#include "tf_player.h"
|
||
|
#include "game.h"
|
||
|
#include "gamerules.h"
|
||
|
#include "teamplay_gamerules.h"
|
||
|
#include "menu_base.h"
|
||
|
#include "ammodef.h"
|
||
|
#include "techtree.h"
|
||
|
#include "tf_team.h"
|
||
|
#include "tf_shield.h"
|
||
|
#include "mathlib/mathlib.h"
|
||
|
#include "entitylist.h"
|
||
|
#include "basecombatweapon.h"
|
||
|
#include "voice_gamemgr.h"
|
||
|
#include "tf_class_infiltrator.h"
|
||
|
#include "team_messages.h"
|
||
|
#include "ndebugoverlay.h"
|
||
|
#include "bot_base.h"
|
||
|
#include "vstdlib/random.h"
|
||
|
#include "info_act.h"
|
||
|
#include "igamesystem.h"
|
||
|
#include "filesystem.h"
|
||
|
#include "info_vehicle_bay.h"
|
||
|
#include "IserverVehicle.h"
|
||
|
#include "weapon_builder.h"
|
||
|
#include "weapon_objectselection.h"
|
||
|
#include "tf_player_resource.h"
|
||
|
|
||
|
#endif
|
||
|
|
||
|
// memdbgon must be the last include file in a .cpp file!!!
|
||
|
#include "tier0/memdbgon.h"
|
||
|
|
||
|
REGISTER_GAMERULES_CLASS( CTeamFortress );
|
||
|
|
||
|
|
||
|
#ifdef CLIENT_DLL
|
||
|
|
||
|
|
||
|
#else
|
||
|
|
||
|
#define MAX_OBJECT_COMMAND_DISTANCE 120.0f
|
||
|
|
||
|
class CVoiceGameMgrHelper : public IVoiceGameMgrHelper
|
||
|
{
|
||
|
public:
|
||
|
virtual bool CanPlayerHearPlayer( CBasePlayer *pListener, CBasePlayer *pTalker )
|
||
|
{
|
||
|
// Gagged players can't talk at all
|
||
|
if ( ((CBaseTFPlayer*)pTalker)->CanSpeak() == false )
|
||
|
return false;
|
||
|
|
||
|
// Dead players can only be heard by other dead team mates
|
||
|
if ( pTalker->IsAlive() == false )
|
||
|
{
|
||
|
if ( pListener->IsAlive() == false )
|
||
|
return ( pListener->InSameTeam( pTalker ) );
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
return ( pListener->InSameTeam( pTalker ) );
|
||
|
}
|
||
|
};
|
||
|
CVoiceGameMgrHelper g_VoiceGameMgrHelper;
|
||
|
IVoiceGameMgrHelper *g_pVoiceGameMgrHelper = &g_VoiceGameMgrHelper;
|
||
|
|
||
|
|
||
|
// Load the objects.txt file.
|
||
|
class CObjectsFileLoad : public CAutoGameSystem
|
||
|
{
|
||
|
public:
|
||
|
virtual bool Init()
|
||
|
{
|
||
|
LoadObjectInfos( filesystem );
|
||
|
return true;
|
||
|
}
|
||
|
} g_ObjectsFileLoad;
|
||
|
|
||
|
|
||
|
|
||
|
extern bool g_fGameOver;
|
||
|
float g_flNextReinforcementTime = 0.0f;
|
||
|
extern ConVar tf_knockdowntime;
|
||
|
|
||
|
// Time between reinforcements
|
||
|
#define REINFORCEMENT_TIME 15.0
|
||
|
|
||
|
ConVar sk_plr_dmg_grenade ( "sk_plr_dmg_grenade","0");
|
||
|
|
||
|
char *sTeamNames[] =
|
||
|
{
|
||
|
"Unassigned",
|
||
|
"Spectator",
|
||
|
"Human",
|
||
|
"Alien",
|
||
|
};
|
||
|
|
||
|
// Handle the "PossessBot" command.
|
||
|
void PossessBot_f()
|
||
|
{
|
||
|
CBaseTFPlayer *pPlayer = CBaseTFPlayer::Instance( UTIL_GetCommandClientIndex() );
|
||
|
if ( !pPlayer )
|
||
|
return;
|
||
|
|
||
|
// Put the local player in control of this bot.
|
||
|
if ( args.ArgC() != 2 )
|
||
|
{
|
||
|
Warning( "PossessBot <client index>\n" );
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
int iBotClient = atoi( args[1) );
|
||
|
int iBotEnt = iBotClient + 1;
|
||
|
|
||
|
if ( iBotClient < 0 ||
|
||
|
iBotClient >= gpGlobals->maxClients ||
|
||
|
pPlayer->entindex() == iBotEnt )
|
||
|
{
|
||
|
Warning( "PossessBot <client index>\n" );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
edict_t *pPlayerData = pPlayer->edict();
|
||
|
edict_t *pBotData = engine->PEntityOfEntIndex( iBotEnt );
|
||
|
if ( pBotData && pBotData->GetUnknown() )
|
||
|
{
|
||
|
// SWAP EDICTS
|
||
|
|
||
|
// Backup things we don't want to swap.
|
||
|
edict_t oldPlayerData = *pPlayerData;
|
||
|
edict_t oldBotData = *pBotData;
|
||
|
|
||
|
// Swap edicts.
|
||
|
edict_t tmp = *pPlayerData;
|
||
|
*pPlayerData = *pBotData;
|
||
|
*pBotData = tmp;
|
||
|
|
||
|
CBaseEntity *pPlayerBaseEnt = CBaseEntity::Instance( pPlayerData );
|
||
|
CBaseEntity *pBotBaseEnt = CBaseEntity::Instance( pBotData );
|
||
|
|
||
|
// Make the other a bot and make the player not a bot.
|
||
|
pPlayerBaseEnt->RemoveFlag( FL_FAKECLIENT );
|
||
|
pBotBaseEnt->AddFlag( FL_FAKECLIENT );
|
||
|
|
||
|
// Point the CBaseEntities at the right players.
|
||
|
pPlayerBaseEnt->NetworkProp()->SetEdict( pPlayerData );
|
||
|
pBotBaseEnt->NetworkProp()->SetEdict( pBotData );
|
||
|
|
||
|
// Freeze the bot.
|
||
|
pBotBaseEnt->AddEFlags( EFL_BOT_FROZEN );
|
||
|
|
||
|
// Remove orders to both of them..
|
||
|
CTFTeam *pTeam = pPlayer->GetTFTeam();
|
||
|
if ( pTeam )
|
||
|
{
|
||
|
pTeam->RemoveOrdersToPlayer( (CBaseTFPlayer*)pPlayerBaseEnt );
|
||
|
pTeam->RemoveOrdersToPlayer( (CBaseTFPlayer*)pBotBaseEnt );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
// Handler for the "bot" command.
|
||
|
CON_COMMAND_F( "bot", "Add a bot.", FCVAR_CHEAT )
|
||
|
{
|
||
|
CBaseTFPlayer *pPlayer = CBaseTFPlayer::Instance( UTIL_GetCommandClientIndex() );
|
||
|
|
||
|
// The bot command uses switches like command-line switches.
|
||
|
// -count <count> tells how many bots to spawn.
|
||
|
// -team <index> selects the bot's team. Default is -1 which chooses randomly.
|
||
|
// Note: if you do -team !, then it
|
||
|
// -class <index> selects the bot's class. Default is -1 which chooses randomly.
|
||
|
// -frozen prevents the bots from running around when they spawn in.
|
||
|
|
||
|
// Look at -count.
|
||
|
int count = args.FindArgInt( "-count", 1 );
|
||
|
count = clamp( count, 1, 16 );
|
||
|
|
||
|
int iTeam = -1;
|
||
|
const char *pVal = args.FindArg( "-team" );
|
||
|
if ( pVal )
|
||
|
{
|
||
|
if ( pVal[0] == '!' )
|
||
|
{
|
||
|
iTeam = pPlayer->GetTFTeam()->GetEnemyTeam()->GetTeamNumber();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
iTeam = atoi( pVal );
|
||
|
iTeam = clamp( iTeam, 0, (GetNumberOfTeams()-1) );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
int iClass = args.FindArgInt( "-class", -1 );
|
||
|
iClass = clamp( iClass, -1, TFCLASS_CLASS_COUNT );
|
||
|
if ( iClass == TFCLASS_UNDECIDED )
|
||
|
iClass = TFCLASS_RECON;
|
||
|
|
||
|
// Look at -frozen.
|
||
|
bool bFrozen = !!args.FindArg( "-frozen" );
|
||
|
|
||
|
// Ok, spawn all the bots.
|
||
|
while ( --count >= 0 )
|
||
|
{
|
||
|
BotPutInServer( bFrozen, iTeam, iClass );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
ConCommand cc_PossessBot( "PossessBot", PossessBot_f, "Toggle. Possess a bot.\n\tArguments: <bot client number>", FCVAR_CHEAT );
|
||
|
|
||
|
|
||
|
Vector MaybeDropToGround(
|
||
|
CBaseEntity *pMainEnt,
|
||
|
bool bDropToGround,
|
||
|
const Vector &vPos,
|
||
|
const Vector &vMins,
|
||
|
const Vector &vMaxs )
|
||
|
{
|
||
|
if ( bDropToGround )
|
||
|
{
|
||
|
trace_t trace;
|
||
|
UTIL_TraceHull( vPos, vPos + Vector( 0, 0, -500 ), vMins, vMaxs, MASK_SOLID, pMainEnt, COLLISION_GROUP_NONE, &trace );
|
||
|
return trace.endpos;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
return vPos;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: This function can be used to find a valid placement location for an entity.
|
||
|
// Given an origin to start looking from and a minimum radius to place the entity at,
|
||
|
// it will sweep out a circle around vOrigin and try to find a valid spot (on the ground)
|
||
|
// where mins and maxs will fit.
|
||
|
// Input : *pMainEnt - Entity to place
|
||
|
// &vOrigin - Point to search around
|
||
|
// fRadius - Radius to search within
|
||
|
// nTries - Number of tries to attempt
|
||
|
// &mins - mins of the Entity
|
||
|
// &maxs - maxs of the Entity
|
||
|
// &outPos - Return point
|
||
|
// Output : Returns true and fills in outPos if it found a spot.
|
||
|
//-----------------------------------------------------------------------------
|
||
|
bool EntityPlacementTest( CBaseEntity *pMainEnt, const Vector &vOrigin, Vector &outPos, bool bDropToGround )
|
||
|
{
|
||
|
// This function moves the box out in each dimension in each step trying to find empty space like this:
|
||
|
//
|
||
|
// X
|
||
|
// X X
|
||
|
// Step 1: X Step 2: XXX Step 3: XXXXX
|
||
|
// X X
|
||
|
// X
|
||
|
//
|
||
|
|
||
|
Vector mins, maxs;
|
||
|
pMainEnt->CollisionProp()->WorldSpaceAABB( &mins, &maxs );
|
||
|
mins -= pMainEnt->GetAbsOrigin();
|
||
|
maxs -= pMainEnt->GetAbsOrigin();
|
||
|
|
||
|
// Put some padding on their bbox.
|
||
|
float flPadSize = 5;
|
||
|
Vector vTestMins = mins - Vector( flPadSize, flPadSize, flPadSize );
|
||
|
Vector vTestMaxs = maxs + Vector( flPadSize, flPadSize, flPadSize );
|
||
|
|
||
|
// First test the starting origin.
|
||
|
if ( UTIL_IsSpaceEmpty( pMainEnt, vOrigin + vTestMins, vOrigin + vTestMaxs ) )
|
||
|
{
|
||
|
outPos = MaybeDropToGround( pMainEnt, bDropToGround, vOrigin, vTestMins, vTestMaxs );
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
Vector vDims = vTestMaxs - vTestMins;
|
||
|
|
||
|
|
||
|
// Keep branching out until we get too far.
|
||
|
int iCurIteration = 0;
|
||
|
int nMaxIterations = 15;
|
||
|
|
||
|
int offset = 0;
|
||
|
do
|
||
|
{
|
||
|
for ( int iDim=0; iDim < 3; iDim++ )
|
||
|
{
|
||
|
float flCurOffset = offset * vDims[iDim];
|
||
|
|
||
|
for ( int iSign=0; iSign < 2; iSign++ )
|
||
|
{
|
||
|
Vector vBase = vOrigin;
|
||
|
vBase[iDim] += (iSign*2-1) * flCurOffset;
|
||
|
|
||
|
if ( UTIL_IsSpaceEmpty( pMainEnt, vBase + vTestMins, vBase + vTestMaxs ) )
|
||
|
{
|
||
|
// Ensure that there is a clear line of sight from the spawnpoint entity to the actual spawn point.
|
||
|
// (Useful for keeping things from spawning behind walls near a spawn point)
|
||
|
trace_t tr;
|
||
|
UTIL_TraceLine( vOrigin, vBase, MASK_SOLID, pMainEnt, COLLISION_GROUP_NONE, &tr );
|
||
|
|
||
|
if ( tr.fraction != 1.0 )
|
||
|
{
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
outPos = MaybeDropToGround( pMainEnt, bDropToGround, vBase, vTestMins, vTestMaxs );
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
++offset;
|
||
|
} while ( iCurIteration++ < nMaxIterations );
|
||
|
|
||
|
// Warning( "EntityPlacementTest for ent %d:%s failed!\n", pMainEnt->entindex(), pMainEnt->GetClassname() );
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
CBaseEntity *CTeamFortress::GetPlayerSpawnSpot( CBasePlayer *pPlayer )
|
||
|
{
|
||
|
CBaseEntity *pSpawnSpot = pPlayer->EntSelectSpawnPoint();
|
||
|
|
||
|
// Make sure the spawn spot isn't blocked...
|
||
|
Vector vecTestOrg = pSpawnSpot->GetAbsOrigin();
|
||
|
|
||
|
vecTestOrg.z += pPlayer->WorldAlignSize().z * 0.5;
|
||
|
Vector origin;
|
||
|
EntityPlacementTest( pPlayer, vecTestOrg, origin, true );
|
||
|
|
||
|
// Move the player to the place it said.
|
||
|
pPlayer->Teleport( &origin, NULL, NULL );
|
||
|
|
||
|
pPlayer->SetAbsVelocity( vec3_origin );
|
||
|
pPlayer->SetLocalAngles( pSpawnSpot->GetLocalAngles() );
|
||
|
pPlayer->m_Local.m_vecPunchAngle = vec3_angle;
|
||
|
pPlayer->SnapEyeAngles( pSpawnSpot->GetLocalAngles() );
|
||
|
|
||
|
return pSpawnSpot;
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
CTeamFortress::CTeamFortress()
|
||
|
{
|
||
|
m_bAllowWeaponSwitch = true;
|
||
|
|
||
|
// Create the team managers
|
||
|
for ( int i = 0; i < MAX_TF_TEAMS; i++ )
|
||
|
{
|
||
|
CTFTeam *pTeam = static_cast<CTFTeam*>(CreateEntityByName( "tf_team_manager" ));
|
||
|
pTeam->Init( sTeamNames[i], i );
|
||
|
|
||
|
g_Teams.AddToTail( pTeam );
|
||
|
}
|
||
|
|
||
|
// Create the hint manager
|
||
|
CBaseEntity::Create( "tf_hintmanager", vec3_origin, vec3_angle );
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
CTeamFortress::~CTeamFortress()
|
||
|
{
|
||
|
// Note, don't delete each team since they are in the gEntList and will
|
||
|
// automatically be deleted from there, instead.
|
||
|
g_Teams.Purge();
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CTeamFortress::UpdateClientData( CBasePlayer *player )
|
||
|
{
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Called after every level and load change
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CTeamFortress::LevelInitPostEntity()
|
||
|
{
|
||
|
g_flNextReinforcementTime = gpGlobals->curtime + REINFORCEMENT_TIME;
|
||
|
BaseClass::LevelInitPostEntity();
|
||
|
}
|
||
|
|
||
|
void CTeamFortress::CreateStandardEntities()
|
||
|
{
|
||
|
// Create the player resource
|
||
|
g_pPlayerResource = (CPlayerResource*)CBaseEntity::Create( "tf_player_manager", vec3_origin, vec3_angle );
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: The gamerules think function
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CTeamFortress::Think( void )
|
||
|
{
|
||
|
BaseClass::Think();
|
||
|
|
||
|
// Check the reinforcement time
|
||
|
if ( g_flNextReinforcementTime <= gpGlobals->curtime )
|
||
|
{
|
||
|
//Msg( "Reinforcement Tick\n" );
|
||
|
|
||
|
// Reinforce any dead players
|
||
|
for ( int i = 1; i <= gpGlobals->maxClients; i++ )
|
||
|
{
|
||
|
CBaseTFPlayer *pPlayer = ToBaseTFPlayer( UTIL_PlayerByIndex(i) );
|
||
|
if ( pPlayer )
|
||
|
{
|
||
|
// Ready to respawn?
|
||
|
if ( pPlayer->IsReadyToReinforce() )
|
||
|
{
|
||
|
pPlayer->Reinforce();
|
||
|
//pPlayer->GetTFTeam()->PostMessage( TEAMMSG_REINFORCEMENTS_ARRIVED );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
g_flNextReinforcementTime += REINFORCEMENT_TIME;
|
||
|
}
|
||
|
|
||
|
// Tell each Team to think
|
||
|
for ( int i = 0; i < GetNumberOfTeams(); i++ )
|
||
|
{
|
||
|
GetGlobalTeam( i )->Think();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Player has just left the game
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CTeamFortress::ClientDisconnected( edict_t *pClient )
|
||
|
{
|
||
|
CBaseTFPlayer *pPlayer = (CBaseTFPlayer *)CBaseEntity::Instance( pClient );
|
||
|
if ( pPlayer )
|
||
|
{
|
||
|
// Tell all orders that this player's left
|
||
|
COrderEvent_PlayerDisconnected order( pPlayer );
|
||
|
GlobalOrderEvent( &order );
|
||
|
|
||
|
// Delete this player's playerclass
|
||
|
pPlayer->ClearPlayerClass();
|
||
|
}
|
||
|
|
||
|
BaseClass::ClientDisconnected( pClient );
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: TF2 Specific Client Commands
|
||
|
// Input :
|
||
|
// Output :
|
||
|
//-----------------------------------------------------------------------------
|
||
|
bool CTeamFortress::ClientCommand( CBaseEntity *pEdict, const CCommand &args )
|
||
|
{
|
||
|
CBaseTFPlayer *pPlayer = (CBaseTFPlayer *)pEdict;
|
||
|
|
||
|
const char *pcmd = args[0];
|
||
|
if ( FStrEq( pcmd, "objcmd" ) )
|
||
|
{
|
||
|
if ( args.ArgC() < 3 )
|
||
|
return true;
|
||
|
|
||
|
int entindex = atoi( args[1] );
|
||
|
edict_t* pEdict = INDEXENT(entindex);
|
||
|
if (pEdict)
|
||
|
{
|
||
|
CBaseEntity* pBaseEntity = GetContainingEntity(pEdict);
|
||
|
CBaseObject* pObject = dynamic_cast<CBaseObject*>(pBaseEntity);
|
||
|
if (pObject && pObject->InSameTeam(pPlayer))
|
||
|
{
|
||
|
// We have to be relatively close to the object too...
|
||
|
|
||
|
// FIXME: When I put in a better dismantle solution (namely send the dismantle
|
||
|
// command along with a cancledismantle command), re-enable this.
|
||
|
// Also, need to solve the problem of control panels on large objects
|
||
|
// For the battering ram, for instance, this distance is too far.
|
||
|
|
||
|
// float flDistSq = pObject->GetAbsOrigin().DistToSqr( pPlayer->GetAbsOrigin() );
|
||
|
// if (flDistSq <= (MAX_OBJECT_COMMAND_DISTANCE * MAX_OBJECT_COMMAND_DISTANCE))
|
||
|
{
|
||
|
CCommand objectArgs( args.ArgC() - 2, &args.ArgV()[2]);
|
||
|
pObject->ClientCommand( pPlayer, objectArgs );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
if ( FStrEq( pcmd, "buildvehicle" ) )
|
||
|
{
|
||
|
if ( args.ArgC() < 3 )
|
||
|
return true;
|
||
|
|
||
|
int entindex = atoi( args[1] );
|
||
|
int ivehicle = atoi( args[2] );
|
||
|
edict_t *pEdict = INDEXENT(entindex);
|
||
|
if (pEdict)
|
||
|
{
|
||
|
CBaseEntity *pBaseEntity = GetContainingEntity(pEdict);
|
||
|
CVGuiScreenVehicleBay *pBayScreen = dynamic_cast<CVGuiScreenVehicleBay*>(pBaseEntity);
|
||
|
if ( pBayScreen && pBayScreen->InSameTeam(pPlayer) )
|
||
|
{
|
||
|
// Need the same logic as objcmd above to ensure the player's near the vehicle bay vgui screen
|
||
|
pBayScreen->BuildVehicle( pPlayer, ivehicle );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
// TF Commands
|
||
|
if ( FStrEq( pcmd, "menuselect" ) )
|
||
|
{
|
||
|
if ( pPlayer->m_pCurrentMenu == NULL )
|
||
|
return true;
|
||
|
if ( args.ArgC() < 2 )
|
||
|
return true;
|
||
|
|
||
|
int slot = atoi( args[1] );
|
||
|
|
||
|
// select the item from the current menu
|
||
|
if ( pPlayer->m_pCurrentMenu->Input( pPlayer, slot ) == false )
|
||
|
{
|
||
|
// invalid selection, force menu refresh
|
||
|
pPlayer->m_MenuUpdateTime = gpGlobals->curtime;
|
||
|
pPlayer->m_MenuRefreshTime = gpGlobals->curtime;
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
else if ( FStrEq( pcmd, "changeclass" ) )
|
||
|
{
|
||
|
pPlayer->m_pCurrentMenu = gMenus[MENU_CLASS];
|
||
|
pPlayer->m_MenuUpdateTime = gpGlobals->curtime;
|
||
|
pPlayer->m_MenuRefreshTime = gpGlobals->curtime;
|
||
|
return true;
|
||
|
}
|
||
|
else if ( FStrEq( pcmd, "changeteam" ) )
|
||
|
{
|
||
|
pPlayer->m_pCurrentMenu = gMenus[MENU_TEAM];
|
||
|
pPlayer->m_MenuUpdateTime = gpGlobals->curtime;
|
||
|
pPlayer->m_MenuRefreshTime = gpGlobals->curtime;
|
||
|
return true;
|
||
|
}
|
||
|
else if ( FStrEq( pcmd, "tactical" ) )
|
||
|
{
|
||
|
bool bTactical = args[1][0] == '!' ? !pPlayer->GetLocalData()->m_nInTacticalView : (atoi( args[1] ) ? true : false);
|
||
|
|
||
|
pPlayer->ShowTacticalView( bTactical );
|
||
|
return true;
|
||
|
}
|
||
|
else if ( FStrEq( pcmd, "tech" ) )
|
||
|
{
|
||
|
CTFTeam *pTFTeam = pPlayer->GetTFTeam();
|
||
|
if ( !pTFTeam )
|
||
|
return true;
|
||
|
|
||
|
if ( args.ArgC() == 2 )
|
||
|
{
|
||
|
const char *name = args[1];
|
||
|
|
||
|
CBaseTechnology *tech = pTFTeam->m_pTechnologyTree->GetTechnology( name );
|
||
|
if ( tech )
|
||
|
{
|
||
|
pTFTeam->EnableTechnology( tech );
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
Msg( "usage: tech <name>\n" );
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
else if ( FStrEq( pcmd, "techall" ) )
|
||
|
{
|
||
|
if ( pPlayer->GetTFTeam() )
|
||
|
{
|
||
|
pPlayer->GetTFTeam()->EnableAllTechnologies();
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
else if ( FStrEq( pcmd, "tank" ) )
|
||
|
{
|
||
|
CBaseEntity::Create( "tank", pPlayer->WorldSpaceCenter(), pPlayer->GetLocalAngles() );
|
||
|
}
|
||
|
else if ( FStrEq( pcmd, "addres" ) || FStrEq( pcmd, "ar" ) )
|
||
|
{
|
||
|
if ( args.ArgC() == 3 )
|
||
|
{
|
||
|
int team = atoi( args[1] );
|
||
|
float flResourceAmount = atof( args[2] );
|
||
|
if ( team >= 0 && team < GetNumberOfTeams() )
|
||
|
{
|
||
|
GetGlobalTFTeam( team )->AddTeamResources( flResourceAmount );
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
Msg( "usage: ar <team 1 : 2> <amount>\n" );
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
else if ( FStrEq( pcmd, "preftech" ) )
|
||
|
{
|
||
|
CTFTeam *pTFTeam = pPlayer->GetTFTeam();
|
||
|
if ( !pTFTeam )
|
||
|
return true;
|
||
|
|
||
|
if ( args.ArgC() == 2 )
|
||
|
{
|
||
|
int iPrefTechIndex = atoi( args[1] );
|
||
|
|
||
|
pPlayer->SetPreferredTechnology( pTFTeam->m_pTechnologyTree, iPrefTechIndex );
|
||
|
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
else if( FStrEq( pcmd, "decaltest" ) )
|
||
|
{
|
||
|
trace_t trace;
|
||
|
int entityIndex;
|
||
|
Vector vForward;
|
||
|
|
||
|
AngleVectors( pEdict->GetAbsAngles(), &vForward, NULL, NULL );
|
||
|
|
||
|
UTIL_TraceLine( pEdict->GetAbsOrigin(), pEdict->GetAbsOrigin() + vForward * 10000, MASK_SOLID_BRUSHONLY, pEdict, COLLISION_GROUP_NONE, &trace );
|
||
|
|
||
|
entityIndex = trace.GetEntityIndex();
|
||
|
|
||
|
int id = UTIL_PrecacheDecal( "decals/tscorch", true );
|
||
|
CBroadcastRecipientFilter filter;
|
||
|
te->BSPDecal( filter, 0.0,
|
||
|
&trace.endpos, entityIndex, id );
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
else if( FStrEq( pcmd, "killorder" ) )
|
||
|
{
|
||
|
if( pPlayer->GetTFTeam() )
|
||
|
pPlayer->GetTFTeam()->RemoveOrdersToPlayer( pPlayer );
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
else if( BaseClass::ClientCommand( pEdict, args ) )
|
||
|
{
|
||
|
return true;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
return pPlayer->ClientCommand( args );
|
||
|
}
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Player has just spawned. Equip them.
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CTeamFortress::PlayerSpawn( CBasePlayer *pPlayer )
|
||
|
{
|
||
|
pPlayer->EquipSuit();
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
bool CTeamFortress::PlayFootstepSounds( CBasePlayer *pl )
|
||
|
{
|
||
|
if ( footsteps.GetInt() == 0 )
|
||
|
return false;
|
||
|
|
||
|
CBaseTFPlayer *tfPlayer = static_cast< CBaseTFPlayer * >( pl );
|
||
|
if ( tfPlayer )
|
||
|
{
|
||
|
if ( tfPlayer->IsKnockedDown() )
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// only make step sounds in multiplayer if the player is moving fast enough
|
||
|
if ( pl->IsOnLadder() || pl->GetAbsVelocity().Length2D() > 100 )
|
||
|
return true;
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Remove falling damage for jetpacking recons
|
||
|
//-----------------------------------------------------------------------------
|
||
|
float CTeamFortress::FlPlayerFallDamage( CBasePlayer *pPlayer )
|
||
|
{
|
||
|
int iFallDamage = (int)falldamage.GetFloat();
|
||
|
|
||
|
CBaseTFPlayer *pTFPlayer = (CBaseTFPlayer *)pPlayer;
|
||
|
if ( pTFPlayer->IsClass( TFCLASS_RECON ) )
|
||
|
return 0;
|
||
|
|
||
|
switch ( iFallDamage )
|
||
|
{
|
||
|
case 1://progressive
|
||
|
pPlayer->m_Local.m_flFallVelocity -= PLAYER_MAX_SAFE_FALL_SPEED;
|
||
|
return pPlayer->m_Local.m_flFallVelocity * DAMAGE_FOR_FALL_SPEED;
|
||
|
break;
|
||
|
default:
|
||
|
case 0:// fixed
|
||
|
return 10;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Is the ray blocked by enemy shields?
|
||
|
//-----------------------------------------------------------------------------
|
||
|
bool CTeamFortress::IsBlockedByEnemyShields( const Vector& src, const Vector& end, int nFriendlyTeam )
|
||
|
{
|
||
|
// Iterate over all shields on the same team, disable them so
|
||
|
// we don't intersect with them...
|
||
|
CShield::ActivateShields( false, nFriendlyTeam );
|
||
|
|
||
|
bool bBlocked = CShield::IsBlockedByShields( src, end );
|
||
|
|
||
|
CShield::ActivateShields( true, nFriendlyTeam );
|
||
|
|
||
|
return bBlocked;
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Traces a line vs a shield, returns damage reduction
|
||
|
//-----------------------------------------------------------------------------
|
||
|
float CTeamFortress::WeaponTraceEntity( CBaseEntity *pEntity,
|
||
|
const Vector &src, const Vector &end, unsigned int mask, trace_t *pTrace )
|
||
|
{
|
||
|
int damageType = pEntity->GetDamageType();
|
||
|
|
||
|
// Iterate over all shields on the same team, disable them so
|
||
|
// we don't intersect with them...
|
||
|
CShield::ActivateShields( false, pEntity->GetTeamNumber() );
|
||
|
|
||
|
// Trace it baby...
|
||
|
float damage = 1.0f;
|
||
|
bool done;
|
||
|
do
|
||
|
{
|
||
|
// FIXME: Optimize so we don't test the same ray but start at the
|
||
|
// previous collision point
|
||
|
done = true;
|
||
|
UTIL_TraceEntity( pEntity, src, end, mask, pTrace );
|
||
|
|
||
|
// Shield check...
|
||
|
if (pTrace->fraction != 1.0)
|
||
|
{
|
||
|
CBaseEntity *pCollidedEntity = pTrace->m_pEnt;
|
||
|
|
||
|
// Did we hit a shield?
|
||
|
CShield* pShield = dynamic_cast<CShield*>(pCollidedEntity);
|
||
|
if (pShield)
|
||
|
{
|
||
|
Vector vecDir;
|
||
|
VectorSubtract( end, src, vecDir );
|
||
|
|
||
|
// Let's see if we let this damage type through...
|
||
|
if (pShield->ProtectionAmount( damageType ) == 1.0f)
|
||
|
{
|
||
|
// We deflected all of the damage
|
||
|
pShield->RegisterDeflection( vecDir, damageType, pTrace );
|
||
|
damage = 0.0f;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// We deflected part of the damage, but we need to trace again
|
||
|
// only this time we can't let the shield register a collision
|
||
|
damage *= 1.0f - pShield->ProtectionAmount( damageType );
|
||
|
|
||
|
// FIXME: DMG_BULLET should be something else
|
||
|
pShield->RegisterPassThru( vecDir, damageType, pTrace );
|
||
|
pShield->ActivateCollisions( false );
|
||
|
|
||
|
done = false;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
while (!done);
|
||
|
|
||
|
// Reduce the damage dealt... but don't worry about if if the
|
||
|
// shield actually deflected it. In that case, we actually want
|
||
|
// explosive things to explode at full blast power. The shield will prevent
|
||
|
// the blast damage to things behind the shield
|
||
|
if (damage != 0.0)
|
||
|
{
|
||
|
pEntity->SetDamage(pEntity->GetDamage() * damage);
|
||
|
}
|
||
|
|
||
|
// Reactivate all shields
|
||
|
CShield::ActivateShields( true );
|
||
|
return damage;
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Is trace blocked by a world or a shield?
|
||
|
//-----------------------------------------------------------------------------
|
||
|
bool CTeamFortress::IsTraceBlockedByWorldOrShield( const Vector& src, const Vector& end, CBaseEntity *pShooter, int damageType, trace_t* pTrace )
|
||
|
{
|
||
|
// Iterate over all shields on the same team, disable them so
|
||
|
// we don't intersect with them...
|
||
|
CShield::ActivateShields( false, pShooter->GetTeamNumber() );
|
||
|
|
||
|
//NDebugOverlay::Line( src, pTrace->endpos, 255,255,255, true, 5.0 );
|
||
|
//NDebugOverlay::Box( pTrace->endpos, Vector(-2,-2,-2), Vector(2,2,2), 255,255,255, true, 5.0 );
|
||
|
|
||
|
// Now make sure there isn't something other than team players in the way.
|
||
|
class CShieldWorldFilter : public CTraceFilterSimple
|
||
|
{
|
||
|
public:
|
||
|
CShieldWorldFilter( CBaseEntity *pShooter ) : CTraceFilterSimple( pShooter, TFCOLLISION_GROUP_WEAPON )
|
||
|
{
|
||
|
}
|
||
|
|
||
|
virtual bool ShouldHitEntity( IHandleEntity *pHandleEntity, int contentsMask )
|
||
|
{
|
||
|
CBaseEntity *pEnt = static_cast<CBaseEntity*>(pHandleEntity);
|
||
|
|
||
|
// Did we hit a brushmodel?
|
||
|
if ( pEnt->GetSolid() == SOLID_BSP )
|
||
|
return true;
|
||
|
|
||
|
// Ignore collisions with everything but shields
|
||
|
if ( pEnt->GetCollisionGroup() != TFCOLLISION_GROUP_SHIELD )
|
||
|
return false;
|
||
|
|
||
|
return CTraceFilterSimple::ShouldHitEntity( pHandleEntity, contentsMask );
|
||
|
}
|
||
|
};
|
||
|
|
||
|
trace_t tr;
|
||
|
CShieldWorldFilter shieldworldFilter( pShooter );
|
||
|
UTIL_TraceLine( src, end, MASK_SOLID, &shieldworldFilter, pTrace );
|
||
|
|
||
|
// Shield check...
|
||
|
if (pTrace->fraction != 1.0)
|
||
|
{
|
||
|
CBaseEntity *pEntity = pTrace->m_pEnt;
|
||
|
CShield* pShield = dynamic_cast<CShield*>(pEntity);
|
||
|
if (pShield)
|
||
|
{
|
||
|
Vector vecDir;
|
||
|
VectorSubtract( end, src, vecDir );
|
||
|
|
||
|
// We deflected all of the damage
|
||
|
pShield->RegisterDeflection( vecDir, damageType, pTrace );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Reactivate all shields
|
||
|
CShield::ActivateShields( true );
|
||
|
return ( pTrace->fraction < 1.0 );
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Default implementation of radius damage
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CTeamFortress::RadiusDamage( const CTakeDamageInfo &info, const Vector &vecSrcIn, float flRadius, int iClassIgnore )
|
||
|
{
|
||
|
CBaseEntity *pEntity = NULL;
|
||
|
trace_t tr;
|
||
|
float flAdjustedDamage, falloff;
|
||
|
Vector vecSpot;
|
||
|
Vector vecSrc = vecSrcIn;
|
||
|
|
||
|
if ( flRadius )
|
||
|
falloff = info.GetDamage() / flRadius;
|
||
|
else
|
||
|
falloff = 1.0;
|
||
|
|
||
|
int bInWater = (UTIL_PointContents ( vecSrc ) & MASK_WATER) ? true : false;
|
||
|
|
||
|
// in case grenade is lying on the ground
|
||
|
// Is this even needed anymore? Grenades already jump up in their explode code...
|
||
|
vecSrc.z += 1;
|
||
|
|
||
|
// iterate on all entities in the vicinity.
|
||
|
for ( CEntitySphereQuery sphere( vecSrc, flRadius ); ( pEntity = sphere.GetCurrentEntity() ) != NULL; sphere.NextEntity() )
|
||
|
{
|
||
|
if ( pEntity->m_takedamage != DAMAGE_NO )
|
||
|
{
|
||
|
// UNDONE: this should check a damage mask, not an ignore
|
||
|
if ( iClassIgnore != CLASS_NONE && pEntity->Classify() == iClassIgnore )
|
||
|
continue;
|
||
|
|
||
|
// blast's don't tavel into or out of water
|
||
|
if (bInWater && pEntity->GetWaterLevel() == 0)
|
||
|
continue;
|
||
|
if (!bInWater && pEntity->GetWaterLevel() == 3)
|
||
|
continue;
|
||
|
|
||
|
// Copy initial values out of the info
|
||
|
CTakeDamageInfo subInfo = info;
|
||
|
if ( !subInfo.GetAttacker() )
|
||
|
{
|
||
|
subInfo.SetAttacker( subInfo.GetInflictor() );
|
||
|
}
|
||
|
|
||
|
// Don't bother with hitboxes on this test
|
||
|
vecSpot = pEntity->WorldSpaceCenter( );
|
||
|
WeaponTraceLine ( vecSrc, vecSpot, MASK_SHOT & (~CONTENTS_HITBOX), subInfo.GetInflictor(), subInfo.GetDamageType(), &tr );
|
||
|
if ( tr.fraction != 1.0 && tr.m_pEnt != pEntity )
|
||
|
continue;
|
||
|
|
||
|
// We're going to need to see if it actually hit a shield
|
||
|
// the explosion can 'see' this entity, so hurt them!
|
||
|
if (tr.startsolid)
|
||
|
{
|
||
|
// if we're stuck inside them, fixup the position and distance
|
||
|
tr.endpos = vecSrc;
|
||
|
tr.fraction = 0.0;
|
||
|
}
|
||
|
|
||
|
// decrease damage for an ent that's farther from the bomb.
|
||
|
flAdjustedDamage = ( vecSrc - tr.endpos ).Length() * falloff;
|
||
|
flAdjustedDamage = subInfo.GetDamage() - flAdjustedDamage;
|
||
|
if ( flAdjustedDamage > 0 )
|
||
|
{
|
||
|
// Knockdown
|
||
|
// For now, just use damage. Eventually we should do it on a per-weapon basis.
|
||
|
/*
|
||
|
if ( pEntity->IsPlayer() && flAdjustedDamage > 40 )
|
||
|
{
|
||
|
Vector vecForce = vecSpot - vecSrc;
|
||
|
// Reduce the Z component and increase the X,Y
|
||
|
vecForce.x *= 3.0;
|
||
|
vecForce.y *= 3.0;
|
||
|
vecForce.z *= 0.5;
|
||
|
VectorNormalize( vecForce );
|
||
|
((CBaseTFPlayer*)pEntity)->KnockDownPlayer( vecForce, flAdjustedDamage * 15.0f, tf_knockdowntime.GetFloat() );
|
||
|
}
|
||
|
*/
|
||
|
|
||
|
// Msg( "hit %s\n", pEntity->GetClassname() );
|
||
|
subInfo.SetDamage( flAdjustedDamage );
|
||
|
|
||
|
Vector dir = tr.endpos - vecSrc;
|
||
|
if ( VectorNormalize( dir ) == 0 )
|
||
|
{
|
||
|
dir = vecSpot - vecSrc;
|
||
|
VectorNormalize( dir );
|
||
|
}
|
||
|
|
||
|
// If we don't have a damage force, manufacture one
|
||
|
if ( subInfo.GetDamagePosition() == vec3_origin || subInfo.GetDamageForce() == vec3_origin )
|
||
|
{
|
||
|
CalculateExplosiveDamageForce( &subInfo, dir, vecSrc );
|
||
|
}
|
||
|
|
||
|
if (tr.fraction != 1.0)
|
||
|
{
|
||
|
ClearMultiDamage( );
|
||
|
|
||
|
pEntity->DispatchTraceAttack( subInfo, dir, &tr );
|
||
|
ApplyMultiDamage();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
pEntity->TakeDamage( subInfo );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Find out if this player had an assistant when he killed an enemy
|
||
|
//-----------------------------------------------------------------------------
|
||
|
CBasePlayer *CTeamFortress::GetDeathAssistant( CBaseEntity *pKiller, CBaseEntity *pInflictor )
|
||
|
{
|
||
|
if ( !pKiller || pKiller->Classify() != CLASS_PLAYER )
|
||
|
return NULL;
|
||
|
|
||
|
CBaseTFPlayer *pAssistant = NULL;
|
||
|
|
||
|
// Killing entity might be specifying a scorer player
|
||
|
IScorer *pScorerInterface = dynamic_cast<IScorer*>( pKiller );
|
||
|
if ( pScorerInterface )
|
||
|
{
|
||
|
pAssistant = (CBaseTFPlayer*)pScorerInterface->GetAssistant();
|
||
|
}
|
||
|
|
||
|
// Inflicting entity might be specifying a scoring player
|
||
|
if ( !pAssistant )
|
||
|
{
|
||
|
pScorerInterface = dynamic_cast<IScorer*>( pInflictor );
|
||
|
if ( pScorerInterface )
|
||
|
{
|
||
|
pAssistant = (CBaseTFPlayer*)pScorerInterface->GetAssistant();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Don't allow self assistance
|
||
|
Assert( pAssistant != pKiller );
|
||
|
return pAssistant;
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
// Input : *pVictim -
|
||
|
// *pKiller -
|
||
|
// *pInflictor -
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CTeamFortress::DeathNotice( CBasePlayer *pVictim, const CTakeDamageInfo &info )
|
||
|
{
|
||
|
// 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_index = 0;
|
||
|
int assist_index = 0;
|
||
|
|
||
|
// Find the killer & the scorer
|
||
|
CBaseEntity *pInflictor = info.GetInflictor();
|
||
|
CBaseEntity *pKiller = info.GetAttacker();
|
||
|
CBasePlayer *pScorer = GetDeathScorer( pKiller, pInflictor );
|
||
|
CBasePlayer *pAssistant = GetDeathAssistant( pKiller, pInflictor );
|
||
|
|
||
|
if ( pAssistant )
|
||
|
{
|
||
|
assist_index = pAssistant->entindex();
|
||
|
}
|
||
|
|
||
|
// Custom kill type?
|
||
|
if ( info.GetDamageCustom() )
|
||
|
{
|
||
|
killer_weapon_name = GetDamageCustomString( info );
|
||
|
if ( pScorer )
|
||
|
{
|
||
|
killer_index = pScorer->entindex();
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// Is the killer a client?
|
||
|
if ( pScorer )
|
||
|
{
|
||
|
killer_index = pScorer->entindex();
|
||
|
|
||
|
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()->GetDeathNoticeName();
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
killer_weapon_name = STRING( pInflictor->m_iClassname ); // it's just that easy
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
killer_weapon_name = STRING( pInflictor->m_iClassname );
|
||
|
}
|
||
|
|
||
|
// 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_", 8 ) == 0 )
|
||
|
{
|
||
|
killer_weapon_name += 8;
|
||
|
}
|
||
|
else if ( strncmp( killer_weapon_name, "func_", 5 ) == 0 )
|
||
|
{
|
||
|
killer_weapon_name += 5;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* CReliableBroadcastRecipientFilter filter;
|
||
|
UserMessageBegin( filter, "DeathMsg" );
|
||
|
WRITE_BYTE( killer_index ); // the killer
|
||
|
WRITE_BYTE( assist_index ); // the assistant, if any
|
||
|
WRITE_BYTE( ENTINDEX(pVictim->edict()) ); // the victim
|
||
|
WRITE_STRING( killer_weapon_name ); // what they were killed by (should this be a string?)
|
||
|
MessageEnd();
|
||
|
|
||
|
// Did he kill himself?
|
||
|
if ( pVictim == pScorer )
|
||
|
{
|
||
|
UTIL_LogPrintf( "\"%s<%i>\" killed self with %s\n", pVictim->GetPlayerName(), engine->GetPlayerUserId( pVictim->edict() ), killer_weapon_name );
|
||
|
}
|
||
|
else if ( pScorer )
|
||
|
{
|
||
|
UTIL_LogPrintf( "\"%s<%i>\" killed \"%s<%i>\" with %s\n", pScorer->GetPlayerName() ),
|
||
|
engine->GetPlayerUserId( pScorer->edict() ),
|
||
|
pVictim->GetPlayerName(),
|
||
|
engine->GetPlayerUserId( pVictim->edict() ),
|
||
|
killer_weapon_name );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// killed by the world
|
||
|
UTIL_LogPrintf( "\"%s<%i>\" killed by world with %s\n", pVictim->GetPlayerName(), engine->GetPlayerUserId( pVictim->edict() ), killer_weapon_name );
|
||
|
} */
|
||
|
|
||
|
KeyValues * event = new KeyValues( "player_death" );
|
||
|
event->SetInt("killer", pScorer ? pScorer->GetUserID() : 0 );
|
||
|
event->SetInt("victim", pVictim->GetUserID() );
|
||
|
event->SetString("weapon", killer_weapon_name );
|
||
|
|
||
|
gameeventmanager->FireEvent( event );
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Custom kill types for TF
|
||
|
//-----------------------------------------------------------------------------
|
||
|
const char *CTeamFortress::GetDamageCustomString( const CTakeDamageInfo &info )
|
||
|
{
|
||
|
switch( info.GetDamageCustom() )
|
||
|
{
|
||
|
case DMG_KILL_BULLRUSH:
|
||
|
return "bullrush";
|
||
|
break;
|
||
|
default:
|
||
|
break;
|
||
|
};
|
||
|
|
||
|
return "INVALID CUSTOM KILL TYPE";
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
// Input : *pListener -
|
||
|
// *pSpeaker -
|
||
|
// Output : Returns true on success, false on failure.
|
||
|
//-----------------------------------------------------------------------------
|
||
|
bool CTeamFortress::PlayerCanHearChat( CBasePlayer *pListener, CBasePlayer *pSpeaker )
|
||
|
{
|
||
|
if ( BaseClass::PlayerCanHearChat( pListener, pSpeaker ) )
|
||
|
{
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
CBaseTFPlayer *listener = static_cast< CBaseTFPlayer * >( pListener );
|
||
|
CBaseTFPlayer *speaker = static_cast< CBaseTFPlayer * >( pSpeaker );
|
||
|
|
||
|
if ( listener && speaker )
|
||
|
{
|
||
|
if ( listener->IsClass( TFCLASS_INFILTRATOR ) )
|
||
|
{
|
||
|
Vector delta;
|
||
|
delta = listener->EarPosition() - speaker->GetAbsOrigin();
|
||
|
if ( delta.Length() < INFILTRATOR_EAVESDROP_RADIUS )
|
||
|
{
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
|
||
|
void CTeamFortress::InitDefaultAIRelationships( void )
|
||
|
{
|
||
|
// Allocate memory for default relationships
|
||
|
CBaseCombatCharacter::AllocateDefaultRelationships();
|
||
|
|
||
|
// --------------------------------------------------------------
|
||
|
// First initialize table so we can report missing relationships
|
||
|
// --------------------------------------------------------------
|
||
|
int i, j;
|
||
|
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, 5);
|
||
|
CBaseCombatCharacter::SetDefaultRelationship(CLASS_ANTLION, CLASS_BARNACLE, D_HT, 0);
|
||
|
CBaseCombatCharacter::SetDefaultRelationship(CLASS_ANTLION, CLASS_BULLSEYE, D_NU, 0);
|
||
|
CBaseCombatCharacter::SetDefaultRelationship(CLASS_ANTLION, CLASS_CITIZEN_PASSIVE, D_HT, 0);
|
||
|
CBaseCombatCharacter::SetDefaultRelationship(CLASS_ANTLION, CLASS_CITIZEN_REBEL, D_HT, 0);
|
||
|
CBaseCombatCharacter::SetDefaultRelationship(CLASS_ANTLION, CLASS_COMBINE, D_HT, 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_MANHACK, D_HT, 0);
|
||
|
CBaseCombatCharacter::SetDefaultRelationship(CLASS_ANTLION, CLASS_METROPOLICE, D_HT, 0);
|
||
|
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);
|
||
|
|
||
|
// ------------------------------------------------------------
|
||
|
// > CLASS_BARNACLE
|
||
|
// ------------------------------------------------------------
|
||
|
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_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_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_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_NU, 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_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_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_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);
|
||
|
|
||
|
// ------------------------------------------------------------
|
||
|
// > 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_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_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_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_NU, 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);
|
||
|
|
||
|
// ------------------------------------------------------------
|
||
|
// > 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_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_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_MANHACK, D_FR, 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_NU, 0);
|
||
|
CBaseCombatCharacter::SetDefaultRelationship(CLASS_CITIZEN_REBEL, CLASS_ZOMBIE, D_FR, 0);
|
||
|
CBaseCombatCharacter::SetDefaultRelationship(CLASS_CITIZEN_REBEL, CLASS_PROTOSNIPER, D_NU, 0);
|
||
|
CBaseCombatCharacter::SetDefaultRelationship(CLASS_CITIZEN_REBEL, CLASS_EARTH_FAUNA, 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_CITIZEN_PASSIVE, D_NU, 0);
|
||
|
CBaseCombatCharacter::SetDefaultRelationship(CLASS_COMBINE, CLASS_CITIZEN_REBEL, D_HT, 0);
|
||
|
CBaseCombatCharacter::SetDefaultRelationship(CLASS_COMBINE, CLASS_COMBINE, D_NU, 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_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_FR, 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);
|
||
|
|
||
|
// ------------------------------------------------------------
|
||
|
// > 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_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_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_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);
|
||
|
|
||
|
// ------------------------------------------------------------
|
||
|
// > 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_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_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_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);
|
||
|
|
||
|
// ------------------------------------------------------------
|
||
|
// > 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_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_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_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);
|
||
|
|
||
|
|
||
|
// ------------------------------------------------------------
|
||
|
// > 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_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_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_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);
|
||
|
|
||
|
// ------------------------------------------------------------
|
||
|
// > CLASS_METROPOLICE
|
||
|
// ------------------------------------------------------------
|
||
|
CBaseCombatCharacter::SetDefaultRelationship(CLASS_METROPOLICE, CLASS_NONE, D_NU, 0);
|
||
|
CBaseCombatCharacter::SetDefaultRelationship(CLASS_METROPOLICE, CLASS_PLAYER, D_HT, 0);
|
||
|
CBaseCombatCharacter::SetDefaultRelationship(CLASS_METROPOLICE, CLASS_ANTLION, D_HT, 0);
|
||
|
CBaseCombatCharacter::SetDefaultRelationship(CLASS_METROPOLICE, CLASS_BARNACLE, D_NU, 0);
|
||
|
CBaseCombatCharacter::SetDefaultRelationship(CLASS_METROPOLICE, CLASS_BULLSEYE, D_NU, 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_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_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);
|
||
|
|
||
|
// ------------------------------------------------------------
|
||
|
// > 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_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_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_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);
|
||
|
|
||
|
// ------------------------------------------------------------
|
||
|
// > 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_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_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_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);
|
||
|
|
||
|
// ------------------------------------------------------------
|
||
|
// > 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_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_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_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);
|
||
|
|
||
|
// ------------------------------------------------------------
|
||
|
// > 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_CITIZEN_PASSIVE, D_NU, 0);
|
||
|
CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER, CLASS_CITIZEN_REBEL, D_NU, 0);
|
||
|
CBaseCombatCharacter::SetDefaultRelationship(CLASS_PLAYER, CLASS_COMBINE, 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_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_NU, 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);
|
||
|
|
||
|
// ------------------------------------------------------------
|
||
|
// > CLASS_SCANNER
|
||
|
// ------------------------------------------------------------
|
||
|
CBaseCombatCharacter::SetDefaultRelationship(CLASS_SCANNER, CLASS_NONE, D_NU, 0);
|
||
|
CBaseCombatCharacter::SetDefaultRelationship(CLASS_SCANNER, CLASS_PLAYER, D_NU, 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_CITIZEN_PASSIVE, D_NU, 0);
|
||
|
CBaseCombatCharacter::SetDefaultRelationship(CLASS_SCANNER, CLASS_CITIZEN_REBEL, D_HT, 0);
|
||
|
CBaseCombatCharacter::SetDefaultRelationship(CLASS_SCANNER, CLASS_COMBINE, D_NU, 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_MANHACK, D_NU, 0);
|
||
|
CBaseCombatCharacter::SetDefaultRelationship(CLASS_SCANNER, CLASS_METROPOLICE, D_NU, 0);
|
||
|
CBaseCombatCharacter::SetDefaultRelationship(CLASS_SCANNER, CLASS_MILITARY, D_NU, 0);
|
||
|
CBaseCombatCharacter::SetDefaultRelationship(CLASS_SCANNER, CLASS_MISSILE, D_NU, 0);
|
||
|
CBaseCombatCharacter::SetDefaultRelationship(CLASS_SCANNER, CLASS_SCANNER, D_NU, 0);
|
||
|
CBaseCombatCharacter::SetDefaultRelationship(CLASS_SCANNER, CLASS_STALKER, D_NU, 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_NU, 0);
|
||
|
CBaseCombatCharacter::SetDefaultRelationship(CLASS_SCANNER, CLASS_EARTH_FAUNA, D_NU, 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_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_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_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);
|
||
|
|
||
|
// ------------------------------------------------------------
|
||
|
// > CLASS_VORTIGAUNT
|
||
|
// ------------------------------------------------------------
|
||
|
CBaseCombatCharacter::SetDefaultRelationship(CLASS_VORTIGAUNT, CLASS_NONE, D_NU, 0);
|
||
|
CBaseCombatCharacter::SetDefaultRelationship(CLASS_VORTIGAUNT, CLASS_PLAYER, D_NU, 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_CITIZEN_PASSIVE, D_NU, 0);
|
||
|
CBaseCombatCharacter::SetDefaultRelationship(CLASS_VORTIGAUNT, CLASS_CITIZEN_REBEL, D_NU, 0);
|
||
|
CBaseCombatCharacter::SetDefaultRelationship(CLASS_VORTIGAUNT, CLASS_COMBINE, D_HT, 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_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);
|
||
|
|
||
|
// ------------------------------------------------------------
|
||
|
// > 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_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_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_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);
|
||
|
|
||
|
// ------------------------------------------------------------
|
||
|
// > 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_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_CONSCRIPT, D_HT, 0);
|
||
|
CBaseCombatCharacter::SetDefaultRelationship(CLASS_PROTOSNIPER, CLASS_FLARE, D_NU, 0);
|
||
|
CBaseCombatCharacter::SetDefaultRelationship(CLASS_PROTOSNIPER, CLASS_HEADCRAB, 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);
|
||
|
|
||
|
// ------------------------------------------------------------
|
||
|
// > CLASS_EARTH_FAUNA
|
||
|
//
|
||
|
// Fears pretty much everything except other earth fauna:
|
||
|
//
|
||
|
// 5. Fears flares and missiles most of all.
|
||
|
// 4. Fears flying machines next.
|
||
|
// 3. Fears aliens next.
|
||
|
// 2. Fears combine human military next.
|
||
|
// 1. Fears humans next.
|
||
|
// 0. Fears the player the least.
|
||
|
//
|
||
|
// ------------------------------------------------------------
|
||
|
CBaseCombatCharacter::SetDefaultRelationship(CLASS_EARTH_FAUNA, CLASS_NONE, D_FR, 0);
|
||
|
CBaseCombatCharacter::SetDefaultRelationship(CLASS_EARTH_FAUNA, CLASS_PLAYER, D_FR, 0);
|
||
|
CBaseCombatCharacter::SetDefaultRelationship(CLASS_EARTH_FAUNA, CLASS_ANTLION, D_FR, 2);
|
||
|
CBaseCombatCharacter::SetDefaultRelationship(CLASS_EARTH_FAUNA, CLASS_BARNACLE, D_NU, 0);
|
||
|
CBaseCombatCharacter::SetDefaultRelationship(CLASS_EARTH_FAUNA, CLASS_BULLSEYE, D_FR, 0);
|
||
|
CBaseCombatCharacter::SetDefaultRelationship(CLASS_EARTH_FAUNA, CLASS_CITIZEN_PASSIVE, D_FR, 1);
|
||
|
CBaseCombatCharacter::SetDefaultRelationship(CLASS_EARTH_FAUNA, CLASS_CITIZEN_REBEL, D_FR, 1);
|
||
|
CBaseCombatCharacter::SetDefaultRelationship(CLASS_EARTH_FAUNA, CLASS_COMBINE, D_FR, 3);
|
||
|
CBaseCombatCharacter::SetDefaultRelationship(CLASS_EARTH_FAUNA, CLASS_CONSCRIPT, D_FR, 1);
|
||
|
CBaseCombatCharacter::SetDefaultRelationship(CLASS_EARTH_FAUNA, CLASS_FLARE, D_FR, 5);
|
||
|
CBaseCombatCharacter::SetDefaultRelationship(CLASS_EARTH_FAUNA, CLASS_HEADCRAB, D_FR, 2);
|
||
|
CBaseCombatCharacter::SetDefaultRelationship(CLASS_EARTH_FAUNA, CLASS_MANHACK, D_FR, 4);
|
||
|
CBaseCombatCharacter::SetDefaultRelationship(CLASS_EARTH_FAUNA, CLASS_METROPOLICE, D_FR, 1);
|
||
|
CBaseCombatCharacter::SetDefaultRelationship(CLASS_EARTH_FAUNA, CLASS_MILITARY, D_FR, 1);
|
||
|
CBaseCombatCharacter::SetDefaultRelationship(CLASS_EARTH_FAUNA, CLASS_MISSILE, D_FR, 5);
|
||
|
CBaseCombatCharacter::SetDefaultRelationship(CLASS_EARTH_FAUNA, CLASS_SCANNER, D_FR, 4);
|
||
|
CBaseCombatCharacter::SetDefaultRelationship(CLASS_EARTH_FAUNA, CLASS_STALKER, D_FR, 2);
|
||
|
CBaseCombatCharacter::SetDefaultRelationship(CLASS_EARTH_FAUNA, CLASS_VORTIGAUNT, D_FR, 2);
|
||
|
CBaseCombatCharacter::SetDefaultRelationship(CLASS_EARTH_FAUNA, CLASS_ZOMBIE, D_FR, 1);
|
||
|
CBaseCombatCharacter::SetDefaultRelationship(CLASS_EARTH_FAUNA, CLASS_PROTOSNIPER, D_NU, 0);
|
||
|
CBaseCombatCharacter::SetDefaultRelationship(CLASS_EARTH_FAUNA, CLASS_EARTH_FAUNA, D_LI, 0);
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Return a pointer to the opposing team
|
||
|
//-----------------------------------------------------------------------------
|
||
|
CTFTeam *GetOpposingTeam( CTeam *pTeam )
|
||
|
{
|
||
|
// Hacky!
|
||
|
if ( pTeam->GetTeamNumber() == 1 )
|
||
|
return GetGlobalTFTeam( 2 );
|
||
|
|
||
|
return GetGlobalTFTeam( 1 );
|
||
|
}
|
||
|
|
||
|
|
||
|
//------------------------------------------------------------------------------
|
||
|
// Purpose : Return classify text for classify type
|
||
|
//------------------------------------------------------------------------------
|
||
|
const char *CTeamFortress::AIClassText(int classType)
|
||
|
{
|
||
|
switch (classType)
|
||
|
{
|
||
|
case CLASS_NONE: return "CLASS_NONE";
|
||
|
case CLASS_PLAYER: return "CLASS_PLAYER";
|
||
|
case CLASS_ANTLION: return "CLASS_ANTLION";
|
||
|
case CLASS_BARNACLE: return "CLASS_BARNACLE";
|
||
|
case CLASS_BULLSEYE: return "CLASS_BULLSEYE";
|
||
|
case CLASS_CITIZEN_PASSIVE: return "CLASS_CITIZEN_PASSIVE";
|
||
|
case CLASS_CITIZEN_REBEL: return "CLASS_CITIZEN_REBEL";
|
||
|
case CLASS_COMBINE: return "CLASS_COMBINE";
|
||
|
case CLASS_CONSCRIPT: return "CLASS_CONSCRIPT";
|
||
|
case CLASS_HEADCRAB: return "CLASS_HEADCRAB";
|
||
|
case CLASS_MANHACK: return "CLASS_MANHACK";
|
||
|
case CLASS_METROPOLICE: return "CLASS_METROPOLICE";
|
||
|
case CLASS_MILITARY: return "CLASS_MILITARY";
|
||
|
case CLASS_SCANNER: return "CLASS_SCANNER";
|
||
|
case CLASS_STALKER: return "CLASS_STALKER";
|
||
|
case CLASS_VORTIGAUNT: return "CLASS_VORTIGAUNT";
|
||
|
case CLASS_ZOMBIE: return "CLASS_ZOMBIE";
|
||
|
case CLASS_PROTOSNIPER: return "CLASS_PROTOSNIPER";
|
||
|
case CLASS_MISSILE: return "CLASS_MISSILE";
|
||
|
case CLASS_FLARE: return "CLASS_FLARE";
|
||
|
case CLASS_EARTH_FAUNA: return "CLASS_EARTH_FAUNA";
|
||
|
|
||
|
default: return "MISSING CLASS in ClassifyText()";
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: When gaining new technologies in TF, prevent auto switching if we
|
||
|
// receive a weapon during the switch
|
||
|
// Input : *pPlayer -
|
||
|
// *pWeapon -
|
||
|
// Output : Returns true on success, false on failure.
|
||
|
//-----------------------------------------------------------------------------
|
||
|
bool CTeamFortress::FShouldSwitchWeapon( CBasePlayer *pPlayer, CBaseCombatWeapon *pWeapon )
|
||
|
{
|
||
|
if ( !GetAllowWeaponSwitch() )
|
||
|
return false;
|
||
|
|
||
|
// Never auto switch to object placement
|
||
|
if ( dynamic_cast<CWeaponBuilder*>(pWeapon) )
|
||
|
return false;
|
||
|
if ( dynamic_cast<CWeaponObjectSelection*>(pWeapon) )
|
||
|
return false;
|
||
|
|
||
|
return BaseClass::FShouldSwitchWeapon( pPlayer, pWeapon );
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
// Input : allow -
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CTeamFortress::SetAllowWeaponSwitch( bool allow )
|
||
|
{
|
||
|
m_bAllowWeaponSwitch = allow;
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
// Output : Returns true on success, false on failure.
|
||
|
//-----------------------------------------------------------------------------
|
||
|
bool CTeamFortress::GetAllowWeaponSwitch( void )
|
||
|
{
|
||
|
return m_bAllowWeaponSwitch;
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
// Input : *pPlayer -
|
||
|
// Output : const char
|
||
|
//-----------------------------------------------------------------------------
|
||
|
const char *CTeamFortress::SetDefaultPlayerTeam( CBasePlayer *pPlayer )
|
||
|
{
|
||
|
Assert( pPlayer );
|
||
|
// int clientIndex = pPlayer->entindex();
|
||
|
// engine->SetClientKeyValue( clientIndex, engine->GetInfoKeyBuffer( pPlayer->edict() ), "model", "" );
|
||
|
return BaseClass::SetDefaultPlayerTeam( pPlayer );
|
||
|
}
|
||
|
|
||
|
// Called when game rules are destroyed by CWorld
|
||
|
void CTeamFortress::LevelShutdown( void )
|
||
|
{
|
||
|
g_flNextReinforcementTime = 0.0f;
|
||
|
|
||
|
g_hCurrentAct = NULL;
|
||
|
|
||
|
BaseClass::LevelShutdown();
|
||
|
}
|
||
|
|
||
|
void InitBodyQue(void)
|
||
|
{
|
||
|
// FIXME: Make this work
|
||
|
}
|
||
|
|
||
|
#endif
|
||
|
|
||
|
|
||
|
// ----------------------------------------------------------------------------- //
|
||
|
// Shared CTeamFortress code.
|
||
|
// ----------------------------------------------------------------------------- //
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Send the appropriate weapon impact
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void WeaponImpact( trace_t *tr, Vector vecDir, bool bHurt, CBaseEntity *pEntity, int iDamageType )
|
||
|
{
|
||
|
// If we hit a combat shield, play the hit effect
|
||
|
if ( iDamageType & (DMG_PLASMA | DMG_ENERGYBEAM) )
|
||
|
{
|
||
|
if ( bHurt )
|
||
|
{
|
||
|
Assert( pEntity );
|
||
|
bool bHitHandheldShield = (pEntity->IsPlayer() && ((CBaseTFPlayer*)pEntity)->IsHittingShield( vecDir, NULL ));
|
||
|
if ( bHitHandheldShield )
|
||
|
{
|
||
|
UTIL_ImpactTrace( tr, iDamageType, "PlasmaShield" );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// Client waits for server version
|
||
|
#ifndef CLIENT_DLL
|
||
|
// Make sure the server sends to us, even though we're predicting
|
||
|
CDisablePredictionFiltering dpf;
|
||
|
UTIL_ImpactTrace( tr, iDamageType, "PlasmaHurt" );
|
||
|
#endif
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
UTIL_ImpactTrace( tr, iDamageType, "PlasmaUnhurt" );
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if ( bHurt )
|
||
|
{
|
||
|
Assert( pEntity );
|
||
|
bool bHitHandheldShield = (pEntity->IsPlayer() && ((CBaseTFPlayer*)pEntity)->IsHittingShield( vecDir, NULL ));
|
||
|
if ( bHitHandheldShield )
|
||
|
{
|
||
|
UTIL_ImpactTrace( tr, iDamageType, "ImpactShield" );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// Client waits for server version
|
||
|
#ifndef CLIENT_DLL
|
||
|
// Make sure the server sends to us, even though we're predicting
|
||
|
CDisablePredictionFiltering dpf;
|
||
|
UTIL_ImpactTrace( tr, iDamageType, "Impact" );
|
||
|
#endif
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
UTIL_ImpactTrace( tr, iDamageType, "ImpactUnhurt" );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
static bool CheckCollisionGroupPlayerMovement( int collisionGroup0, int collisionGroup1 )
|
||
|
{
|
||
|
if ( collisionGroup0 == COLLISION_GROUP_PLAYER )
|
||
|
{
|
||
|
// Players don't collide with objects or other players
|
||
|
if ( collisionGroup1 == COLLISION_GROUP_PLAYER || collisionGroup1 == TFCOLLISION_GROUP_OBJECT )
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
|
||
|
if ( collisionGroup1 == COLLISION_GROUP_PLAYER_MOVEMENT )
|
||
|
{
|
||
|
// This is only for probing, so it better not be on both sides!!!
|
||
|
Assert( collisionGroup0 != COLLISION_GROUP_PLAYER_MOVEMENT );
|
||
|
|
||
|
// No collide with players any more
|
||
|
// Nor with objects or grenades
|
||
|
switch ( collisionGroup0 )
|
||
|
{
|
||
|
default:
|
||
|
break;
|
||
|
case COLLISION_GROUP_PLAYER:
|
||
|
return false;
|
||
|
case TFCOLLISION_GROUP_OBJECT_SOLIDTOPLAYERMOVEMENT:
|
||
|
// Certain objects are still solid to player movement
|
||
|
return true;
|
||
|
case TFCOLLISION_GROUP_COMBATOBJECT:
|
||
|
case TFCOLLISION_GROUP_OBJECT:
|
||
|
return false;
|
||
|
case TFCOLLISION_GROUP_GRENADE:
|
||
|
case COLLISION_GROUP_DEBRIS:
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
|
||
|
void CTeamFortress::WeaponTraceLine( const Vector& src, const Vector& end, unsigned int mask, CBaseEntity *pShooter, int damageType, trace_t* pTrace )
|
||
|
{
|
||
|
// Iterate over all shields on the same team, disable them so
|
||
|
// we don't intersect with them...
|
||
|
CShield::ActivateShields( false, pShooter->GetTeamNumber() );
|
||
|
|
||
|
UTIL_TraceLine(src, end, mask, pShooter, TFCOLLISION_GROUP_WEAPON, pTrace);
|
||
|
|
||
|
// NDebugOverlay::Line( src, pTrace->endpos, 255,255,255, true, 5.0 );
|
||
|
// NDebugOverlay::Box( pTrace->endpos, Vector(-2,-2,-2), Vector(2,2,2), 255,255,255, true, 5.0 );
|
||
|
|
||
|
// Shield check...
|
||
|
if (pTrace->fraction != 1.0)
|
||
|
{
|
||
|
CBaseEntity *pEntity = pTrace->m_pEnt;
|
||
|
CShield* pShield = dynamic_cast<CShield*>(pEntity);
|
||
|
if (pShield)
|
||
|
{
|
||
|
Vector vecDir;
|
||
|
VectorSubtract( end, src, vecDir );
|
||
|
|
||
|
// We deflected all of the damage
|
||
|
pShield->RegisterDeflection( vecDir, damageType, pTrace );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Reactivate all shields
|
||
|
CShield::ActivateShields( true );
|
||
|
}
|
||
|
|
||
|
|
||
|
bool CTeamFortress::ShouldCollide( int collisionGroup0, int collisionGroup1 )
|
||
|
{
|
||
|
if ( collisionGroup0 > collisionGroup1 )
|
||
|
{
|
||
|
// swap so that lowest is always first
|
||
|
swap(collisionGroup0,collisionGroup1);
|
||
|
}
|
||
|
|
||
|
// Ignore base class HL2 definition for COLLISION_GROUP_WEAPON, change to COLLISION_GROUP_NONE
|
||
|
if ( collisionGroup0 == COLLISION_GROUP_WEAPON )
|
||
|
{
|
||
|
collisionGroup0 = COLLISION_GROUP_NONE;
|
||
|
}
|
||
|
if ( collisionGroup1 == COLLISION_GROUP_WEAPON )
|
||
|
{
|
||
|
collisionGroup1 = COLLISION_GROUP_NONE;
|
||
|
}
|
||
|
|
||
|
// Shields collide with weapons + grenades only
|
||
|
if ( collisionGroup0 == TFCOLLISION_GROUP_SHIELD )
|
||
|
{
|
||
|
return ((collisionGroup1 == TFCOLLISION_GROUP_WEAPON) || (collisionGroup1 == TFCOLLISION_GROUP_GRENADE));
|
||
|
}
|
||
|
|
||
|
// Weapons can collide with things (players) in vehicles.
|
||
|
if( collisionGroup0 == COLLISION_GROUP_IN_VEHICLE && collisionGroup1 == TFCOLLISION_GROUP_WEAPON )
|
||
|
{
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
// COLLISION TEST:
|
||
|
// Players don't collide with other players or objects
|
||
|
if ( !CheckCollisionGroupPlayerMovement( collisionGroup0, collisionGroup1 ) )
|
||
|
return false;
|
||
|
// Reciprocal test
|
||
|
if ( !CheckCollisionGroupPlayerMovement( collisionGroup1, collisionGroup0 ) )
|
||
|
return false;
|
||
|
|
||
|
// Grenades don't collide with debris
|
||
|
if ( collisionGroup1 == TFCOLLISION_GROUP_GRENADE )
|
||
|
{
|
||
|
if ( collisionGroup0 == COLLISION_GROUP_DEBRIS )
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
// Combat objects don't collide with players
|
||
|
if ( collisionGroup1 == TFCOLLISION_GROUP_COMBATOBJECT )
|
||
|
{
|
||
|
if ( collisionGroup0 == COLLISION_GROUP_PLAYER )
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
// Resource chunks don't collide with each other or vehicles
|
||
|
if ( collisionGroup1 == TFCOLLISION_GROUP_RESOURCE_CHUNK )
|
||
|
{
|
||
|
if ( collisionGroup0 == TFCOLLISION_GROUP_RESOURCE_CHUNK )
|
||
|
return false;
|
||
|
// if ( collisionGroup0 == COLLISION_GROUP_VEHICLE )
|
||
|
// return false;
|
||
|
}
|
||
|
|
||
|
return BaseClass::ShouldCollide( collisionGroup0, collisionGroup1 );
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Fire a generic bullet
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CTeamFortress::FireBullets( const CTakeDamageInfo &info, int cShots, const Vector &vecSrc, const Vector &vecDirShooting,
|
||
|
const Vector &vecSpread, float flDistance, int iAmmoType,
|
||
|
int iTracerFreq, int firingEntID, int attachmentID, const char *sCustomTracer )
|
||
|
{
|
||
|
static int tracerCount;
|
||
|
bool tracer;
|
||
|
trace_t tr;
|
||
|
CTakeDamageInfo subInfo = info;
|
||
|
CBaseTFCombatWeapon *pWeapon = dynamic_cast<CBaseTFCombatWeapon*>(info.GetInflictor());
|
||
|
|
||
|
Assert( subInfo.GetInflictor() );
|
||
|
|
||
|
// Default attacker is the inflictor
|
||
|
if ( subInfo.GetAttacker() == NULL )
|
||
|
{
|
||
|
subInfo.SetAttacker( subInfo.GetInflictor() );
|
||
|
}
|
||
|
|
||
|
// --------------------------------------------------
|
||
|
// Get direction vectors for spread
|
||
|
// --------------------------------------------------
|
||
|
Vector vecUp = Vector(0,0,1);
|
||
|
Vector vecRight;
|
||
|
CrossProduct ( vecDirShooting, vecUp, vecRight );
|
||
|
CrossProduct ( vecDirShooting, -vecRight, vecUp );
|
||
|
|
||
|
#ifndef CLIENT_DLL
|
||
|
ClearMultiDamage();
|
||
|
#endif
|
||
|
|
||
|
int seed = 0;
|
||
|
|
||
|
for (int iShot = 0; iShot < cShots; iShot++)
|
||
|
{
|
||
|
// get circular gaussian spread
|
||
|
float x, y, z;
|
||
|
|
||
|
do
|
||
|
{
|
||
|
float x1, x2, y1, y2;
|
||
|
|
||
|
// Note the additional seed because otherwise we get the same set of random #'s and will get stuck
|
||
|
// in an infinite loop here potentially
|
||
|
// FIXME: Can we use a gaussian random # function instead? ywb
|
||
|
if ( CBaseEntity::GetPredictionRandomSeed() != -1 )
|
||
|
{
|
||
|
x1 = SHARED_RANDOMFLOAT_SEED( -0.5, 0.5, ++seed );
|
||
|
x2 = SHARED_RANDOMFLOAT_SEED( -0.5, 0.5, ++seed );
|
||
|
y1 = SHARED_RANDOMFLOAT_SEED( -0.5, 0.5, ++seed );
|
||
|
y2 = SHARED_RANDOMFLOAT_SEED( -0.5, 0.5, ++seed );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
x1 = RandomFloat( -0.5, 0.5 );
|
||
|
x2 = RandomFloat( -0.5, 0.5 );
|
||
|
y1 = RandomFloat( -0.5, 0.5 );
|
||
|
y2 = RandomFloat( -0.5, 0.5 );
|
||
|
}
|
||
|
|
||
|
x = x1 + x2;
|
||
|
y = y1 + y2;
|
||
|
|
||
|
z = x*x+y*y;
|
||
|
} while (z > 1);
|
||
|
|
||
|
Vector vecDir = vecDirShooting + x * vecSpread.x * vecRight + y * vecSpread.y * vecUp;
|
||
|
Vector vecEnd = vecSrc + vecDir * flDistance;
|
||
|
|
||
|
// Try the trace
|
||
|
WeaponTraceLine( vecSrc, vecEnd, MASK_SHOT, subInfo.GetInflictor(), subInfo.GetDamageType(), &tr );
|
||
|
|
||
|
tracer = false;
|
||
|
if (iTracerFreq != 0 && (tracerCount++ % iTracerFreq) == 0)
|
||
|
{
|
||
|
Vector vecTracerSrc;
|
||
|
|
||
|
// adjust tracer position for player
|
||
|
if ( subInfo.GetInflictor()->IsPlayer() )
|
||
|
{
|
||
|
Vector forward, right;
|
||
|
CBasePlayer *pPlayer = ToBasePlayer( subInfo.GetInflictor() );
|
||
|
pPlayer->EyeVectors( &forward, &right, NULL );
|
||
|
vecTracerSrc = vecSrc + Vector ( 0 , 0 , -4 ) + right * 2 + forward * 16;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
vecTracerSrc = vecSrc;
|
||
|
}
|
||
|
|
||
|
if ( iTracerFreq != 1 ) // guns that always trace also always decal
|
||
|
tracer = true;
|
||
|
|
||
|
if ( sCustomTracer )
|
||
|
{
|
||
|
UTIL_Tracer( vecTracerSrc, tr.endpos, subInfo.GetInflictor()->entindex(), TRACER_DONT_USE_ATTACHMENT, 0, false, (char*)sCustomTracer );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
UTIL_Tracer( vecTracerSrc, tr.endpos, subInfo.GetInflictor()->entindex() );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// do damage, paint decals
|
||
|
if ( tr.fraction != 1.0 )
|
||
|
{
|
||
|
CBaseEntity *pEntity = tr.m_pEnt;
|
||
|
|
||
|
// NOTE: If we want to know more than whether or not the entity can actually be hurt
|
||
|
// for the purposes of impact effects, the client needs to know a lot more.
|
||
|
bool bTargetCouldBeHurt = false;
|
||
|
if ( pEntity->m_takedamage )
|
||
|
{
|
||
|
if ( !pEntity->InSameTeam( subInfo.GetInflictor() ) )
|
||
|
{
|
||
|
bTargetCouldBeHurt = true;
|
||
|
}
|
||
|
#ifndef CLIENT_DLL
|
||
|
subInfo.SetDamagePosition( vecSrc );
|
||
|
// Hit the target
|
||
|
pEntity->DispatchTraceAttack( subInfo, vecDir, &tr );
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
// No decal if we hit a shield
|
||
|
if ( pEntity->GetCollisionGroup() != TFCOLLISION_GROUP_SHIELD )
|
||
|
{
|
||
|
WeaponImpact( &tr, vecDir, bTargetCouldBeHurt, pEntity, subInfo.GetDamageType() );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ( pWeapon )
|
||
|
{
|
||
|
pWeapon->BulletWasFired( vecSrc, tr.endpos );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Apply any damage we've stacked up
|
||
|
#ifndef CLIENT_DLL
|
||
|
ApplyMultiDamage();
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Init TF2 ammo definitions
|
||
|
//-----------------------------------------------------------------------------
|
||
|
CAmmoDef *GetAmmoDef()
|
||
|
{
|
||
|
static CAmmoDef def;
|
||
|
static bool bInitted = false;
|
||
|
|
||
|
if ( !bInitted )
|
||
|
{
|
||
|
bInitted = true;
|
||
|
|
||
|
def.AddAmmoType("Bullets", DMG_BULLET, TRACER_LINE, 0, 0, INFINITE_AMMO, 0, 0);
|
||
|
def.AddAmmoType("Rockets", DMG_BLAST, TRACER_LINE, 0, 0, 6, 0, 0);
|
||
|
def.AddAmmoType("Grenades", DMG_BLAST, TRACER_LINE, 0, 0, 3, 0, 0);
|
||
|
def.AddAmmoType("ShieldGrenades", DMG_ENERGYBEAM, TRACER_LINE, 0, 0, 5, 0, 0);
|
||
|
def.AddAmmoType("ShotgunEnergy", DMG_ENERGYBEAM, TRACER_LINE, 0, 0, INFINITE_AMMO, 0, 0);
|
||
|
def.AddAmmoType("PlasmaGrenade", DMG_ENERGYBEAM|DMG_BLAST, TRACER_LINE, 0, 0, 30, 0, 0);
|
||
|
def.AddAmmoType("ResourceChunks", DMG_GENERIC,TRACER_LINE, 0, 0, 4, 0, 0); // Resource chunks
|
||
|
def.AddAmmoType("Limpets", DMG_BLAST, TRACER_LINE, 0, 0, 40, 0, 0);
|
||
|
def.AddAmmoType("Gasoline", DMG_BURN, TRACER_LINE, 0, 0, 80, 0, 0);
|
||
|
|
||
|
// Combat Objects
|
||
|
def.AddAmmoType("RallyFlags", DMG_GENERIC, TRACER_NONE, 0, 0, 1, 0, 0);
|
||
|
def.AddAmmoType("EMPGenerators", DMG_GENERIC, TRACER_NONE, 0, 0, 1, 0, 0);
|
||
|
}
|
||
|
|
||
|
return &def;
|
||
|
}
|