mirror of
https://github.com/nillerusr/source-engine.git
synced 2026-08-08 01:39:36 +00:00
1
This commit is contained in:
@@ -0,0 +1,470 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Basic BOT handling.
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// $Log: $
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "player.h"
|
||||
#include "tfc_player.h"
|
||||
#include "in_buttons.h"
|
||||
#include "movehelper_server.h"
|
||||
|
||||
void ClientPutInServer( edict_t *pEdict, const char *playername );
|
||||
void Bot_Think( CTFCPlayer *pBot );
|
||||
|
||||
ConVar bot_forcefireweapon( "bot_forcefireweapon", "", 0, "Force bots with the specified weapon to fire." );
|
||||
ConVar bot_forceattack2( "bot_forceattack2", "0", 0, "When firing, use attack2." );
|
||||
ConVar bot_forceattackon( "bot_forceattackon", "0", 0, "When firing, don't tap fire, hold it down." );
|
||||
ConVar bot_flipout( "bot_flipout", "0", 0, "When on, all bots fire their guns." );
|
||||
ConVar bot_defend( "bot_defend", "0", 0, "Set to a team number, and that team will all keep their combat shields raised." );
|
||||
ConVar bot_changeclass( "bot_changeclass", "0", 0, "Force all bots to change to the specified class." );
|
||||
static ConVar bot_mimic( "bot_mimic", "0", 0, "Bot uses usercmd of player by index." );
|
||||
static ConVar bot_mimic_yaw_offset( "bot_mimic_yaw_offset", "180", 0, "Offsets the bot yaw." );
|
||||
|
||||
static int BotNumber = 1;
|
||||
static int g_iNextBotTeam = -1;
|
||||
static int g_iNextBotClass = -1;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
bool backwards;
|
||||
|
||||
float nextturntime;
|
||||
bool lastturntoright;
|
||||
|
||||
float nextstrafetime;
|
||||
float sidemove;
|
||||
|
||||
QAngle forwardAngle;
|
||||
QAngle lastAngles;
|
||||
|
||||
float m_flJoinTeamTime;
|
||||
int m_WantedTeam;
|
||||
int m_WantedClass;
|
||||
|
||||
bool m_bWasDead;
|
||||
float m_flDeadTime;
|
||||
} botdata_t;
|
||||
|
||||
static botdata_t g_BotData[ MAX_PLAYERS ];
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Create a new Bot and put it in the game.
|
||||
// Output : Pointer to the new Bot, or NULL if there's no free clients.
|
||||
//-----------------------------------------------------------------------------
|
||||
CBasePlayer *BotPutInServer( bool bFrozen, int iTeam, int iClass )
|
||||
{
|
||||
g_iNextBotTeam = iTeam;
|
||||
g_iNextBotClass = iClass;
|
||||
|
||||
char botname[ 64 ];
|
||||
Q_snprintf( botname, sizeof( botname ), "Bot%02i", BotNumber );
|
||||
|
||||
edict_t *pEdict = engine->CreateFakeClient( botname );
|
||||
if (!pEdict)
|
||||
{
|
||||
Msg( "Failed to create Bot.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Allocate a CBasePlayer for the bot, and call spawn
|
||||
//ClientPutInServer( pEdict, botname );
|
||||
CTFCPlayer *pPlayer = ((CTFCPlayer *)CBaseEntity::Instance( pEdict ));
|
||||
pPlayer->ClearFlags();
|
||||
pPlayer->AddFlag( FL_CLIENT | FL_FAKECLIENT );
|
||||
|
||||
if ( bFrozen )
|
||||
pPlayer->AddEFlags( EFL_BOT_FROZEN );
|
||||
|
||||
BotNumber++;
|
||||
|
||||
botdata_t *pBot = &g_BotData[ pPlayer->entindex() - 1 ];
|
||||
pBot->m_bWasDead = false;
|
||||
pBot->m_WantedTeam = iTeam;
|
||||
pBot->m_WantedClass = iClass;
|
||||
pBot->m_flJoinTeamTime = gpGlobals->curtime + 0.3;
|
||||
|
||||
return pPlayer;
|
||||
}
|
||||
|
||||
|
||||
// Handler for the "bot" command.
|
||||
CON_COMMAND_F( "bot", "Add a bot.", FCVAR_CHEAT )
|
||||
{
|
||||
//CDODPlayer *pPlayer = CDODPlayer::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 = 0;
|
||||
const char *pVal = args.FindArg( "-team" );
|
||||
if ( pVal )
|
||||
{
|
||||
if ( stricmp( pVal, "red" ) == 0 )
|
||||
iTeam = TEAM_RED;
|
||||
else
|
||||
iTeam = TEAM_BLUE;
|
||||
}
|
||||
|
||||
// Look at -frozen.
|
||||
bool bFrozen = !!args.FindArg( "-frozen" );
|
||||
|
||||
// Ok, spawn all the bots.
|
||||
while ( --count >= 0 )
|
||||
{
|
||||
// What class do they want?
|
||||
int iClass = RandomInt( 0, PC_LASTCLASS-1 );
|
||||
pVal = args.FindArg( "-class" );
|
||||
if ( pVal )
|
||||
{
|
||||
for ( int i=0; i < PC_LASTCLASS; i++ )
|
||||
{
|
||||
if ( stricmp( GetTFCClassInfo( i )->m_pClassName, pVal ) == 0 )
|
||||
{
|
||||
iClass = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BotPutInServer( bFrozen, iTeam, iClass );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Run through all the Bots in the game and let them think.
|
||||
//-----------------------------------------------------------------------------
|
||||
void Bot_RunAll( void )
|
||||
{
|
||||
for ( int i = 1; i <= gpGlobals->maxClients; i++ )
|
||||
{
|
||||
CTFCPlayer *pPlayer = ToTFCPlayer( UTIL_PlayerByIndex( i ) );
|
||||
|
||||
if ( pPlayer && (pPlayer->GetFlags() & FL_FAKECLIENT) )
|
||||
{
|
||||
Bot_Think( pPlayer );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool RunMimicCommand( CUserCmd& cmd )
|
||||
{
|
||||
if ( bot_mimic.GetInt() <= 0 )
|
||||
return false;
|
||||
|
||||
if ( bot_mimic.GetInt() > gpGlobals->maxClients )
|
||||
return false;
|
||||
|
||||
|
||||
CBasePlayer *pPlayer = UTIL_PlayerByIndex( bot_mimic.GetInt() );
|
||||
if ( !pPlayer )
|
||||
return false;
|
||||
|
||||
if ( !pPlayer->GetLastUserCommand() )
|
||||
return false;
|
||||
|
||||
cmd = *pPlayer->GetLastUserCommand();
|
||||
cmd.viewangles[YAW] += bot_mimic_yaw_offset.GetFloat();
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Simulates a single frame of movement for a player
|
||||
// Input : *fakeclient -
|
||||
// *viewangles -
|
||||
// forwardmove -
|
||||
// sidemove -
|
||||
// upmove -
|
||||
// buttons -
|
||||
// impulse -
|
||||
// msec -
|
||||
// Output : virtual void
|
||||
//-----------------------------------------------------------------------------
|
||||
static void RunPlayerMove( CTFCPlayer *fakeclient, const QAngle& viewangles, float forwardmove, float sidemove, float upmove, unsigned short buttons, byte impulse, float frametime )
|
||||
{
|
||||
if ( !fakeclient )
|
||||
return;
|
||||
|
||||
CUserCmd cmd;
|
||||
|
||||
// Store off the globals.. they're gonna get whacked
|
||||
float flOldFrametime = gpGlobals->frametime;
|
||||
float flOldCurtime = gpGlobals->curtime;
|
||||
|
||||
float flTimeBase = gpGlobals->curtime + gpGlobals->frametime - frametime;
|
||||
fakeclient->SetTimeBase( flTimeBase );
|
||||
|
||||
Q_memset( &cmd, 0, sizeof( cmd ) );
|
||||
|
||||
if ( !RunMimicCommand( cmd ) )
|
||||
{
|
||||
VectorCopy( viewangles, cmd.viewangles );
|
||||
cmd.forwardmove = forwardmove;
|
||||
cmd.sidemove = sidemove;
|
||||
cmd.upmove = upmove;
|
||||
cmd.buttons = buttons;
|
||||
cmd.impulse = impulse;
|
||||
cmd.random_seed = random->RandomInt( 0, 0x7fffffff );
|
||||
}
|
||||
|
||||
MoveHelperServer()->SetHost( fakeclient );
|
||||
fakeclient->PlayerRunCommand( &cmd, MoveHelperServer() );
|
||||
|
||||
// save off the last good usercmd
|
||||
fakeclient->SetLastUserCommand( cmd );
|
||||
|
||||
// Clear out any fixangle that has been set
|
||||
fakeclient->pl.fixangle = FIXANGLE_NONE;
|
||||
|
||||
// Restore the globals..
|
||||
gpGlobals->frametime = flOldFrametime;
|
||||
gpGlobals->curtime = flOldCurtime;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Run this Bot's AI for one frame.
|
||||
//-----------------------------------------------------------------------------
|
||||
void Bot_Think( CTFCPlayer *pBot )
|
||||
{
|
||||
// Make sure we stay being a bot
|
||||
pBot->AddFlag( FL_FAKECLIENT );
|
||||
|
||||
botdata_t *botdata = &g_BotData[ ENTINDEX( pBot->edict() ) - 1 ];
|
||||
|
||||
QAngle vecViewAngles;
|
||||
float forwardmove = 0.0;
|
||||
float sidemove = botdata->sidemove;
|
||||
float upmove = 0.0;
|
||||
unsigned short buttons = 0;
|
||||
byte impulse = 0;
|
||||
float frametime = gpGlobals->frametime;
|
||||
|
||||
vecViewAngles = pBot->GetLocalAngles();
|
||||
|
||||
|
||||
// Create some random values
|
||||
if ( pBot->GetTeamNumber() == TEAM_UNASSIGNED && gpGlobals->curtime > botdata->m_flJoinTeamTime )
|
||||
{
|
||||
pBot->HandleCommand_JoinTeam( botdata->m_WantedTeam == TEAM_RED ? "red" : "blue" );
|
||||
}
|
||||
else if ( pBot->GetTeamNumber() != TEAM_UNASSIGNED && pBot->m_Shared.GetPlayerClass() == PC_UNDEFINED )
|
||||
{
|
||||
// If they're on a team but haven't picked a class, choose a random class..
|
||||
pBot->HandleCommand_JoinClass( GetTFCClassInfo( botdata->m_WantedClass )->m_pClassName );
|
||||
}
|
||||
else if ( pBot->IsAlive() && (pBot->GetSolid() == SOLID_BBOX) )
|
||||
{
|
||||
trace_t trace;
|
||||
|
||||
botdata->m_bWasDead = false;
|
||||
|
||||
// Stop when shot
|
||||
if ( !pBot->IsEFlagSet(EFL_BOT_FROZEN) )
|
||||
{
|
||||
if ( pBot->m_iHealth == 100 )
|
||||
{
|
||||
forwardmove = 600 * ( botdata->backwards ? -1 : 1 );
|
||||
if ( botdata->sidemove != 0.0f )
|
||||
{
|
||||
forwardmove *= random->RandomFloat( 0.1, 1.0f );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
forwardmove = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Only turn if I haven't been hurt
|
||||
if ( !pBot->IsEFlagSet(EFL_BOT_FROZEN) && pBot->m_iHealth == 100 )
|
||||
{
|
||||
Vector vecEnd;
|
||||
Vector forward;
|
||||
|
||||
QAngle angle;
|
||||
float angledelta = 15.0;
|
||||
|
||||
int maxtries = (int)360.0/angledelta;
|
||||
|
||||
if ( botdata->lastturntoright )
|
||||
{
|
||||
angledelta = -angledelta;
|
||||
}
|
||||
|
||||
angle = pBot->GetLocalAngles();
|
||||
|
||||
Vector vecSrc;
|
||||
while ( --maxtries >= 0 )
|
||||
{
|
||||
AngleVectors( angle, &forward );
|
||||
|
||||
vecSrc = pBot->GetLocalOrigin() + Vector( 0, 0, 36 );
|
||||
|
||||
vecEnd = vecSrc + forward * 10;
|
||||
|
||||
UTIL_TraceHull( vecSrc, vecEnd, VEC_HULL_MIN_SCALED( pBot ), VEC_HULL_MAX_SCALED( pBot ),
|
||||
MASK_PLAYERSOLID, pBot, COLLISION_GROUP_NONE, &trace );
|
||||
|
||||
if ( trace.fraction == 1.0 )
|
||||
{
|
||||
if ( gpGlobals->curtime < botdata->nextturntime )
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
angle.y += angledelta;
|
||||
|
||||
if ( angle.y > 180 )
|
||||
angle.y -= 360;
|
||||
else if ( angle.y < -180 )
|
||||
angle.y += 360;
|
||||
|
||||
botdata->nextturntime = gpGlobals->curtime + 2.0;
|
||||
botdata->lastturntoright = random->RandomInt( 0, 1 ) == 0 ? true : false;
|
||||
|
||||
botdata->forwardAngle = angle;
|
||||
botdata->lastAngles = angle;
|
||||
|
||||
}
|
||||
|
||||
|
||||
if ( gpGlobals->curtime >= botdata->nextstrafetime )
|
||||
{
|
||||
botdata->nextstrafetime = gpGlobals->curtime + 1.0f;
|
||||
|
||||
if ( random->RandomInt( 0, 5 ) == 0 )
|
||||
{
|
||||
botdata->sidemove = -600.0f + 1200.0f * random->RandomFloat( 0, 2 );
|
||||
}
|
||||
else
|
||||
{
|
||||
botdata->sidemove = 0;
|
||||
}
|
||||
sidemove = botdata->sidemove;
|
||||
|
||||
if ( random->RandomInt( 0, 20 ) == 0 )
|
||||
{
|
||||
botdata->backwards = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
botdata->backwards = false;
|
||||
}
|
||||
}
|
||||
|
||||
pBot->SetLocalAngles( angle );
|
||||
vecViewAngles = angle;
|
||||
}
|
||||
|
||||
// Is my team being forced to defend?
|
||||
if ( bot_defend.GetInt() == pBot->GetTeamNumber() )
|
||||
{
|
||||
buttons |= IN_ATTACK2;
|
||||
}
|
||||
// If bots are being forced to fire a weapon, see if I have it
|
||||
else if ( bot_forcefireweapon.GetString() )
|
||||
{
|
||||
CBaseCombatWeapon *pWeapon = pBot->Weapon_OwnsThisType( bot_forcefireweapon.GetString() );
|
||||
if ( pWeapon )
|
||||
{
|
||||
// Switch to it if we don't have it out
|
||||
CBaseCombatWeapon *pActiveWeapon = pBot->GetActiveWeapon();
|
||||
|
||||
// Switch?
|
||||
if ( pActiveWeapon != pWeapon )
|
||||
{
|
||||
pBot->Weapon_Switch( pWeapon );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Start firing
|
||||
// Some weapons require releases, so randomise firing
|
||||
if ( bot_forceattackon.GetBool() || (RandomFloat(0.0,1.0) > 0.5) )
|
||||
{
|
||||
buttons |= bot_forceattack2.GetBool() ? IN_ATTACK2 : IN_ATTACK;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( bot_flipout.GetInt() )
|
||||
{
|
||||
if ( bot_forceattackon.GetBool() || (RandomFloat(0.0,1.0) > 0.5) )
|
||||
{
|
||||
buttons |= bot_forceattack2.GetBool() ? IN_ATTACK2 : IN_ATTACK;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Wait for Reinforcement wave
|
||||
if ( !pBot->IsAlive() )
|
||||
{
|
||||
if ( botdata->m_bWasDead )
|
||||
{
|
||||
// Wait for a few seconds before respawning.
|
||||
if ( gpGlobals->curtime - botdata->m_flDeadTime > 3 )
|
||||
{
|
||||
// Respawn the bot
|
||||
buttons |= IN_JUMP;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Start a timer to respawn them in a few seconds.
|
||||
botdata->m_bWasDead = true;
|
||||
botdata->m_flDeadTime = gpGlobals->curtime;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( bot_flipout.GetInt() >= 2 )
|
||||
{
|
||||
|
||||
QAngle angOffset = RandomAngle( -1, 1 );
|
||||
|
||||
botdata->lastAngles += angOffset;
|
||||
|
||||
for ( int i = 0 ; i < 2; i++ )
|
||||
{
|
||||
if ( fabs( botdata->lastAngles[ i ] - botdata->forwardAngle[ i ] ) > 15.0f )
|
||||
{
|
||||
if ( botdata->lastAngles[ i ] > botdata->forwardAngle[ i ] )
|
||||
{
|
||||
botdata->lastAngles[ i ] = botdata->forwardAngle[ i ] + 15;
|
||||
}
|
||||
else
|
||||
{
|
||||
botdata->lastAngles[ i ] = botdata->forwardAngle[ i ] - 15;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
botdata->lastAngles[ 2 ] = 0;
|
||||
|
||||
pBot->SetLocalAngles( botdata->lastAngles );
|
||||
}
|
||||
|
||||
RunPlayerMove( pBot, pBot->GetLocalAngles(), forwardmove, sidemove, upmove, buttons, impulse, frametime );
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef TFC_BOT_TEMP_H
|
||||
#define TFC_BOT_TEMP_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
// If iTeam or iClass is -1, then a team or class is randomly chosen.
|
||||
CBasePlayer *BotPutInServer( bool bFrozen, int iTeam, int iClass );
|
||||
|
||||
void Bot_RunAll();
|
||||
|
||||
|
||||
#endif // TFC_BOT_TEMP_H
|
||||
@@ -0,0 +1,73 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef TFC_BUILDING_H
|
||||
#define TFC_BUILDING_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
#include "baseanimating.h"
|
||||
#include "tfc_shareddefs.h"
|
||||
|
||||
|
||||
class CTFBaseBuilding : public CBaseAnimating
|
||||
{
|
||||
public:
|
||||
EHANDLE real_owner;
|
||||
};
|
||||
|
||||
|
||||
class CTFTeleporter : public CTFBaseBuilding
|
||||
{
|
||||
public:
|
||||
void Spawn(void);
|
||||
void Precache(void);
|
||||
|
||||
void EXPORT Teleporter_Explode( void );
|
||||
void EXPORT TeleporterThink( void );
|
||||
void EXPORT TeleporterTouch( CBaseEntity *pOther );
|
||||
|
||||
Class_T Classify(void) { return CLASS_MACHINE; };
|
||||
int BloodColor( void ) { return DONT_BLEED; }
|
||||
|
||||
void Remove( void );
|
||||
|
||||
void TeamFortress_TakeEMPBlast(CBaseEntity* pevGren);
|
||||
void Finished( void );
|
||||
static CTFTeleporter *CreateTeleporter( Vector vecOrigin, Vector vecAngles, CBaseEntity *pOwner, int type );
|
||||
BOOL EngineerUse( CBasePlayer *pPlayer );
|
||||
void Killed( CBaseEntity *pevInflictor, CBaseEntity *pevAttacker, int iGib );
|
||||
void TeleporterSend( CBasePlayer *pPlayer );
|
||||
void TeleporterReceive( CBasePlayer *pPlayer, float flDelay );
|
||||
void TeleporterKilled( void );
|
||||
BOOL TeleportersReady( void );
|
||||
void TeleporterFadePlayer( int direction );
|
||||
void TeleporterProcessFade( void );
|
||||
void SetTeleporterRings( int state );
|
||||
void SetTeleporterParticles( int state );
|
||||
float GetDamageMultiplier( void );
|
||||
CTFTeleporter* FindMatch( void );
|
||||
const Vector& GetTeamColor( void );
|
||||
bool PlayerIsStandingOnTeleporter( CBaseEntity *pOther );
|
||||
|
||||
CBasePlayer *m_pPlayer; // player being teleported
|
||||
|
||||
float m_flInitialUseDelay;
|
||||
|
||||
int m_iType; // entry or exit
|
||||
int m_iState; // state of the teleporter (idle, ready, sending, etc.)
|
||||
int m_iDestroyed; // has this teleporter been destroyed
|
||||
|
||||
int m_iShardIndex; // Metal shards
|
||||
|
||||
float m_flMyNextThink; // used to control the pace at which the teleporters work
|
||||
float m_flDamageDelay; // damage multiplier that slows the teleporters when they're damaged
|
||||
};
|
||||
|
||||
|
||||
#endif // TFC_BUILDING_H
|
||||
@@ -0,0 +1,155 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
/*
|
||||
|
||||
===== tf_client.cpp ========================================================
|
||||
|
||||
HL2 client/server game specific stuff
|
||||
|
||||
*/
|
||||
|
||||
#include "cbase.h"
|
||||
#include "player.h"
|
||||
#include "gamerules.h"
|
||||
#include "entitylist.h"
|
||||
#include "physics.h"
|
||||
#include "game.h"
|
||||
#include "ai_network.h"
|
||||
#include "ai_node.h"
|
||||
#include "ai_hull.h"
|
||||
#include "shake.h"
|
||||
#include "player_resource.h"
|
||||
#include "engine/IEngineSound.h"
|
||||
#include "tfc_player.h"
|
||||
#include "tfc_gamerules.h"
|
||||
#include "tier0/vprof.h"
|
||||
#include "tfc_bot_temp.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
|
||||
extern CBaseEntity *FindPickerEntity( CBasePlayer *pPlayer );
|
||||
|
||||
extern bool g_fGameOver;
|
||||
|
||||
|
||||
void FinishClientPutInServer( CTFCPlayer *pPlayer )
|
||||
{
|
||||
pPlayer->InitialSpawn();
|
||||
pPlayer->Spawn();
|
||||
|
||||
char sName[128];
|
||||
Q_strncpy( sName, pPlayer->GetPlayerName(), sizeof( sName ) );
|
||||
|
||||
// First parse the name and remove any %'s
|
||||
for ( char *pApersand = sName; pApersand != NULL && *pApersand != 0; pApersand++ )
|
||||
{
|
||||
// Replace it with a space
|
||||
if ( *pApersand == '%' )
|
||||
*pApersand = ' ';
|
||||
}
|
||||
|
||||
// notify other clients of player joining the game
|
||||
UTIL_ClientPrintAll( HUD_PRINTNOTIFY, "#Game_connected", sName[0] != 0 ? sName : "<unconnected>" );
|
||||
}
|
||||
|
||||
/*
|
||||
===========
|
||||
ClientPutInServer
|
||||
|
||||
called each time a player is spawned into the game
|
||||
============
|
||||
*/
|
||||
void ClientPutInServer( edict_t *pEdict, const char *playername )
|
||||
{
|
||||
// Allocate a CBaseTFPlayer for pev, and call spawn
|
||||
CTFCPlayer *pPlayer = CTFCPlayer::CreatePlayer( "player", pEdict );
|
||||
pPlayer->SetPlayerName( playername );
|
||||
}
|
||||
|
||||
|
||||
void ClientActive( edict_t *pEdict, bool bLoadGame )
|
||||
{
|
||||
// Can't load games in CS!
|
||||
Assert( !bLoadGame );
|
||||
|
||||
CTFCPlayer *pPlayer = ToTFCPlayer( CBaseEntity::Instance( pEdict ) );
|
||||
FinishClientPutInServer( pPlayer );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
===============
|
||||
const char *GetGameDescription()
|
||||
|
||||
Returns the descriptive name of this .dll. E.g., Half-Life, or Team Fortress 2
|
||||
===============
|
||||
*/
|
||||
const char *GetGameDescription()
|
||||
{
|
||||
if ( g_pGameRules ) // this function may be called before the world has spawned, and the game rules initialized
|
||||
return g_pGameRules->GetGameDescription();
|
||||
else
|
||||
return "CounterStrike";
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Precache game-specific models & sounds
|
||||
//-----------------------------------------------------------------------------
|
||||
void ClientGamePrecache( void )
|
||||
{
|
||||
// Materials used by the client effects
|
||||
CBaseEntity::PrecacheModel( "sprites/white.vmt" );
|
||||
CBaseEntity::PrecacheModel( "sprites/physbeam.vmt" );
|
||||
}
|
||||
|
||||
|
||||
// called by ClientKill and DeadThink
|
||||
void respawn( CBaseEntity *pEdict, bool fCopyCorpse )
|
||||
{
|
||||
if (gpGlobals->coop || gpGlobals->deathmatch)
|
||||
{
|
||||
if ( fCopyCorpse )
|
||||
{
|
||||
// make a copy of the dead body for appearances sake
|
||||
dynamic_cast< CBasePlayer* >( pEdict )->CreateCorpse();
|
||||
}
|
||||
|
||||
// respawn player
|
||||
pEdict->Spawn();
|
||||
}
|
||||
else
|
||||
{ // restart the entire server
|
||||
engine->ServerCommand("reload\n");
|
||||
}
|
||||
}
|
||||
|
||||
void GameStartFrame( void )
|
||||
{
|
||||
VPROF( "GameStartFrame" );
|
||||
|
||||
if ( g_pGameRules )
|
||||
g_pGameRules->Think();
|
||||
|
||||
if ( g_fGameOver )
|
||||
return;
|
||||
|
||||
gpGlobals->teamplay = teamplay.GetInt() ? true : false;
|
||||
|
||||
Bot_RunAll();
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
// instantiate the proper game rules object
|
||||
//=========================================================
|
||||
void InstallGameRules()
|
||||
{
|
||||
CreateGameRulesObject( "CTFCGameRules" );
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef TFC_CLIENT_H
|
||||
#define TFC_CLIENT_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
void respawn( CBaseEntity *pEdict, bool fCopyCorpse );
|
||||
|
||||
|
||||
#endif // TFC_CLIENT_H
|
||||
@@ -0,0 +1,73 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "tfc_player.h"
|
||||
#include "tfc_building.h"
|
||||
|
||||
|
||||
//=========================================================================
|
||||
// Destroys a single Engineer building
|
||||
void DestroyBuilding(CTFCPlayer *eng, char *bld)
|
||||
{
|
||||
CBaseEntity *pEnt = gEntList.FindEntityByClassname( NULL, bld );
|
||||
while ( pEnt )
|
||||
{
|
||||
CTFBaseBuilding *pBuilding = dynamic_cast<CTFBaseBuilding*>( pEnt );
|
||||
|
||||
if (pBuilding && pBuilding->real_owner == eng)
|
||||
{
|
||||
// If it's fallen out of the world, give the engineer
|
||||
// some metal back
|
||||
int pos = UTIL_PointContents(pEnt->GetAbsOrigin());
|
||||
#ifdef TFCTODO // CONTENTS_SKY doesn't exist in the new engine
|
||||
if (pos == CONTENT_SOLID || pos == CONTENT_SKY)
|
||||
#else
|
||||
if (pos == CONTENTS_SOLID)
|
||||
#endif
|
||||
{
|
||||
eng->GiveAmmo( 100, TFC_AMMO_CELLS );
|
||||
eng->TeamFortress_CheckClassStats();
|
||||
}
|
||||
|
||||
pEnt->TakeDamage( CTakeDamageInfo( pEnt, pEnt, 500, 0 ) );
|
||||
}
|
||||
|
||||
pEnt = gEntList.FindEntityByClassname( pEnt, bld );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//=========================================================================
|
||||
// Destroys a teleporter (determined by type)
|
||||
void DestroyTeleporter(CTFCPlayer *eng, int type)
|
||||
{
|
||||
CBaseEntity *pEnt = gEntList.FindEntityByClassname( NULL, "building_teleporter" );
|
||||
while ( pEnt )
|
||||
{
|
||||
CTFTeleporter *pTeleporter = dynamic_cast<CTFTeleporter*>( pEnt );
|
||||
|
||||
if (pTeleporter && pTeleporter->real_owner == eng && pTeleporter->m_iType == type )
|
||||
{
|
||||
// If it's fallen out of the world, give the engineer
|
||||
// some metal back
|
||||
int pos = UTIL_PointContents(pEnt->GetAbsOrigin());
|
||||
#ifdef TFCTODO // CONTENTS_SKY doesn't exist in the new engine
|
||||
if (pos == CONTENT_SOLID || pos == CONTENT_SKY)
|
||||
#else
|
||||
if (pos == CONTENTS_SOLID)
|
||||
#endif
|
||||
{
|
||||
eng->GiveAmmo( 100, TFC_AMMO_CELLS );
|
||||
eng->TeamFortress_CheckClassStats();
|
||||
}
|
||||
|
||||
pEnt->TakeDamage( CTakeDamageInfo( pEnt, pEnt, 500, 0 ) );
|
||||
}
|
||||
|
||||
pEnt = gEntList.FindEntityByClassname( pEnt, "building_teleporter" );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef TFC_ENGINEER_H
|
||||
#define TFC_ENGINEER_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
class CTFCPlayer;
|
||||
|
||||
|
||||
void DestroyBuilding(CTFCPlayer *eng, char *bld);
|
||||
void DestroyTeleporter(CTFCPlayer *eng, int type);
|
||||
|
||||
|
||||
#endif // TFC_ENGINEER_H
|
||||
@@ -0,0 +1,56 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "../EventLog.h"
|
||||
#include "KeyValues.h"
|
||||
|
||||
class CTFCEventLog : public CEventLog
|
||||
{
|
||||
private:
|
||||
typedef CEventLog BaseClass;
|
||||
|
||||
public:
|
||||
virtual ~CTFCEventLog() {};
|
||||
|
||||
public:
|
||||
bool PrintEvent( KeyValues * event ) // override virtual function
|
||||
{
|
||||
if ( BaseClass::PrintEvent( event ) )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( Q_strcmp(event->GetName(), "cstrike_") == 0 )
|
||||
{
|
||||
return PrintCStrikeEvent( event );
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
bool PrintCStrikeEvent( KeyValues * event ) // print Mod specific logs
|
||||
{
|
||||
// const char * name = event->GetName() + Q_strlen("cstrike_"); // remove prefix
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
CTFCEventLog g_TFCEventLog;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Singleton access
|
||||
//-----------------------------------------------------------------------------
|
||||
IGameSystem* GameLogSystem()
|
||||
{
|
||||
return &g_TFCEventLog;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "gameinterface.h"
|
||||
#include "mapentities.h"
|
||||
|
||||
|
||||
// -------------------------------------------------------------------------------------------- //
|
||||
// Mod-specific CServerGameClients implementation.
|
||||
// -------------------------------------------------------------------------------------------- //
|
||||
|
||||
void CServerGameClients::GetPlayerLimits( int& minplayers, int& maxplayers, int &defaultMaxPlayers ) const
|
||||
{
|
||||
minplayers = 2; // Force multiplayer.
|
||||
maxplayers = MAX_PLAYERS;
|
||||
defaultMaxPlayers = 32;
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------------------------------------------------------------- //
|
||||
// Mod-specific CServerGameDLL implementation.
|
||||
// -------------------------------------------------------------------------------------------- //
|
||||
|
||||
void CServerGameDLL::LevelInit_ParseAllEntities( const char *pMapEntities )
|
||||
{
|
||||
MapEntity_ParseAllEntities( pMapEntities, NULL );
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,405 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef TFC_MAPITEMS_H
|
||||
#define TFC_MAPITEMS_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
#include "tfc_shareddefs.h"
|
||||
|
||||
|
||||
class CTFCPlayer;
|
||||
|
||||
|
||||
/*==================================================*/
|
||||
/* CTF Support defines */
|
||||
/*==================================================*/
|
||||
#define CTF_FLAG1 1
|
||||
#define CTF_FLAG2 2
|
||||
#define CTF_DROPOFF1 3
|
||||
#define CTF_DROPOFF2 4
|
||||
#define CTF_SCORE1 5
|
||||
#define CTF_SCORE2 6
|
||||
|
||||
|
||||
// Defines for GoalItem Removing from Player Methods
|
||||
#define GI_DROP_PLAYERDEATH 0 // Dropped by a dying player
|
||||
#define GI_DROP_REMOVEGOAL 1 // Removed by a Goal
|
||||
#define GI_DROP_PLAYERDROP 2 // Dropped by a player
|
||||
|
||||
|
||||
// Defines for methods of GoalItem returning
|
||||
#define GI_RET_DROP_DEAD 0 // Dropped by a dead player
|
||||
#define GI_RET_DROP_LIVING 1 // Dropped by a living player
|
||||
#define GI_RET_GOAL 2 // Returned by a Goal
|
||||
#define GI_RET_TIME 3 // Returned due to timeout
|
||||
|
||||
|
||||
// Defines for Goal States
|
||||
#define TFGS_ACTIVE 1
|
||||
#define TFGS_INACTIVE 2
|
||||
#define TFGS_REMOVED 3
|
||||
#define TFGS_DELAYED 4
|
||||
|
||||
|
||||
// Defines for Goal Result types : goal_result
|
||||
#define TFGR_SINGLE 1 // Goal can only be activated once
|
||||
#define TFGR_ADD_BONUSES 2 // Any Goals activated by this one give their bonuses
|
||||
#define TFGR_ENDGAME 4 // Goal fires Intermission, displays scores, and ends level
|
||||
#define TFGR_NO_ITEM_RESULTS 8 // GoalItems given by this Goal don't do results
|
||||
#define TFGR_REMOVE_DISGUISE 16 // Prevent/Remove undercover from any Spy
|
||||
#define TFGR_FORCE_RESPAWN 32 // Forces the player to teleport to a respawn point
|
||||
#define TFGR_DESTROY_BUILDINGS 64 // Destroys this player's buildings, if anys
|
||||
|
||||
|
||||
// Defines for Goal Item types, : goal_activation (in items)
|
||||
#define TFGI_GLOW 1 // Players carrying this GoalItem will glow
|
||||
#define TFGI_SLOW 2 // Players carrying this GoalItem will move at half-speed
|
||||
#define TFGI_DROP 4 // Players dying with this item will drop it
|
||||
#define TFGI_RETURN_DROP 8 // Return if a player with it dies
|
||||
#define TFGI_RETURN_GOAL 16 // Return if a player with it has it removed by a goal's activation
|
||||
#define TFGI_RETURN_REMOVE 32 // Return if it is removed by TFGI_REMOVE
|
||||
#define TFGI_REVERSE_AP 64 // Only pickup if the player _doesn't_ match AP Details
|
||||
#define TFGI_REMOVE 128 // Remove if left untouched for 2 minutes after being dropped
|
||||
#define TFGI_KEEP 256 // Players keep this item even when they die
|
||||
#define TFGI_ITEMGLOWS 512 // Item glows when on the ground
|
||||
#define TFGI_DONTREMOVERES 1024 // Don't remove results when the item is removed
|
||||
#define TFGI_DROPTOGROUND 2048 // Drop To Ground when spawning
|
||||
#define TFGI_CANBEDROPPED 4096 // Can be voluntarily dropped by players
|
||||
#define TFGI_SOLID 8192 // Is solid... blocks bullets, etc
|
||||
|
||||
|
||||
// For all these defines, see the tfortmap.txt that came with the zip
|
||||
// for complete descriptions.
|
||||
// Defines for Goal Activation types : goal_activation (in goals)
|
||||
#define TFGA_TOUCH 1 // Activated when touched
|
||||
#define TFGA_TOUCH_DETPACK 2 // Activated when touched by a detpack explosion
|
||||
#define TFGA_REVERSE_AP 4 // Activated when AP details are _not_ met
|
||||
#define TFGA_SPANNER 8 // Activated when hit by an engineer's spanner
|
||||
#define TFGA_DROPTOGROUND 2048 // Drop to Ground when spawning
|
||||
|
||||
|
||||
// Defines for Goal Effects types : goal_effect
|
||||
#define TFGE_AP 1 // AP is affected. Default.
|
||||
#define TFGE_AP_TEAM 2 // All of the AP's team.
|
||||
#define TFGE_NOT_AP_TEAM 4 // All except AP's team.
|
||||
#define TFGE_NOT_AP 8 // All except AP.
|
||||
#define TFGE_WALL 16 // If set, walls stop the Radius effects
|
||||
#define TFGE_SAME_ENVIRONMENT 32 // If set, players in a different environment to the Goal are not affected
|
||||
#define TFGE_TIMER_CHECK_AP 64 // If set, Timer Goals check their critera for all players fitting their effects
|
||||
|
||||
|
||||
class CTFBaseItem : public CBaseAnimating
|
||||
{
|
||||
public:
|
||||
|
||||
bool CheckExistence();
|
||||
|
||||
|
||||
public:
|
||||
|
||||
int group_no;
|
||||
int goal_no;
|
||||
int goal_state; // TFGS_
|
||||
// Goal/Timer/GoalItem/Trigger existence checking
|
||||
int ex_skill_min; // Exists when the skill is >= this value
|
||||
int ex_skill_max; // Exists when the skill is <= this value
|
||||
string_t teamcheck; // TeamCheck entity that should be checked
|
||||
};
|
||||
|
||||
|
||||
class CTFGoal : public CTFBaseItem
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( CTFGoal, CBaseAnimating );
|
||||
DECLARE_DATADESC();
|
||||
|
||||
void Spawn( void );
|
||||
void StartGoal( void );
|
||||
void PlaceGoal( void );
|
||||
void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
|
||||
void tfgoal_touch( CBaseEntity *pOther );
|
||||
|
||||
void DelayedResult();
|
||||
|
||||
Class_T Classify ( void ) { return CLASS_TFGOAL; }
|
||||
|
||||
void SetObjectCollisionBox( void );
|
||||
|
||||
void tfgoal_timer_tick();
|
||||
void DoRespawn();
|
||||
|
||||
|
||||
public:
|
||||
//TFCTODO: lots of these variables need to be put in the FGD file.
|
||||
int goal_effects; // TFGE_
|
||||
int goal_result; // TFGR_
|
||||
|
||||
int playerclass; // One of the PC_ defines.
|
||||
|
||||
float t_length; // Goal Criteria radius check
|
||||
|
||||
// NOTE: In CTFGoal, these are overridden to mean: if they're not zero, then this goal only
|
||||
// affects players...
|
||||
int maxammo_shells; // ... with that team number
|
||||
int maxammo_nails; // ... without that team number
|
||||
|
||||
int ammo_shells;
|
||||
int ammo_nails;
|
||||
int ammo_rockets;
|
||||
int ammo_cells;
|
||||
int ammo_medikit;
|
||||
int ammo_detpack;
|
||||
int no_grenades_1;
|
||||
int no_grenades_2;
|
||||
|
||||
// Replacement_Model Stuff
|
||||
string_t replacement_model;
|
||||
int replacement_model_body;
|
||||
int replacement_model_skin;
|
||||
int replacement_model_flags;
|
||||
|
||||
// Item Displaying details
|
||||
int display_item_status[4]; // Goal displays the status of these items
|
||||
string_t team_str_home; // Displayed when the item is at home base
|
||||
string_t team_str_moved; // Displayed when the item has been moved
|
||||
string_t team_str_carried; // Displayed when the item is being carried
|
||||
string_t non_team_str_home; // Displayed when the item is at home base
|
||||
string_t non_team_str_moved; // Displayed when the item has been moved
|
||||
string_t non_team_str_carried; // Displayed when the item is being carried
|
||||
|
||||
float invincible_finished;
|
||||
float invisible_finished;
|
||||
float super_damage_finished;
|
||||
float radsuit_finished;
|
||||
|
||||
int lives;
|
||||
int frags;
|
||||
float wait;
|
||||
|
||||
float search_time; // Timer goal delay
|
||||
int item_list; // Used to keep track of which goalitems are
|
||||
// affecting the player at any time.
|
||||
// GoalItems use it to keep track of their own
|
||||
// mask to apply to a player's item_list
|
||||
|
||||
float drop_time; // Time spent untouched before item return
|
||||
float armortype;
|
||||
int armorvalue;
|
||||
int armorclass; // Type of armor being worn;
|
||||
|
||||
int count; // Change teamscores
|
||||
|
||||
// Goal Size
|
||||
Vector goal_min;
|
||||
Vector goal_max;
|
||||
|
||||
bool m_bAddBonuses;
|
||||
|
||||
int items;
|
||||
int items_allowed;
|
||||
|
||||
int else_goal;
|
||||
int if_goal_is_active;
|
||||
int if_goal_is_inactive;
|
||||
int if_goal_is_removed;
|
||||
int if_group_is_active;
|
||||
int if_group_is_inactive;
|
||||
int if_group_is_removed;
|
||||
|
||||
int speed_reduction;
|
||||
|
||||
int return_item_no;
|
||||
int if_item_has_moved;
|
||||
int if_item_hasnt_moved;
|
||||
|
||||
int has_item_from_group;
|
||||
int hasnt_item_from_group;
|
||||
|
||||
int goal_activation;
|
||||
int delay_time;
|
||||
int weapon;
|
||||
string_t owned_by_teamcheck;
|
||||
int owned_by;
|
||||
string_t noise;
|
||||
|
||||
// Spawnpoint behaviour
|
||||
int remove_spawnpoint;
|
||||
int restore_spawnpoint;
|
||||
int remove_spawngroup;
|
||||
int restore_spawngroup;
|
||||
|
||||
// These are the old centerprinting methods.
|
||||
// They now print using the large fancy text
|
||||
string_t broadcast; // Centerprinted to all, overridden by the next two
|
||||
string_t team_broadcast; // Centerprinted to AP's team members, but not the AP
|
||||
string_t non_team_broadcast; // Centerprinted to non AP's team members
|
||||
string_t owners_team_broadcast; // Centerprinted to the members of the team that own the Goal/Item
|
||||
string_t non_owners_team_broadcast; // Centerprinted to the members of the team that don't own the Goal/Item
|
||||
string_t team_drop; // Centerprinted to item owners team
|
||||
string_t non_team_drop; // Centerprinted to everone not on item owners team
|
||||
|
||||
// These are new fields that print the old fashioned centerprint method
|
||||
string_t org_broadcast; // Centerprinted to all, overridden by the next two
|
||||
string_t org_team_broadcast; // Centerprinted to AP's team members, but not the AP
|
||||
string_t org_non_team_broadcast; // Centerprinted to non AP's team members
|
||||
string_t org_owners_team_broadcast; // Centerprinted to the members of the team that own the Goal/Item
|
||||
string_t org_non_owners_team_broadcast; // Centerprinted to the members of the team that don't own the Goal/Item
|
||||
string_t org_team_drop; // Centerprinted to item owners team
|
||||
string_t org_non_team_drop; // Centerprinted to everone not on item owners team
|
||||
string_t org_message; // Centerprinted to the AP upon activation
|
||||
string_t org_noise3;
|
||||
string_t org_noise4;
|
||||
// These still print the old centerprint fashion
|
||||
string_t netname_broadcast; // same as above, prepended by AP netname and bprinted
|
||||
string_t netname_team_broadcast; // same as above, prepended by AP netname and bprinted
|
||||
string_t netname_non_team_broadcast; // same as above, prepended by AP netname and bprinted
|
||||
string_t netname_owners_team_broadcast; // same as above, prepended by AP netname and bprinted
|
||||
string_t netname_team_drop; // same as above, prepended by AP netname and bprinted
|
||||
string_t netname_non_team_drop; // same as above, prepended by AP netname and bprinted
|
||||
string_t speak; // VOX Spoken to Everyone
|
||||
string_t AP_speak; // VOX Spoken the AP
|
||||
string_t team_speak; // VOX Spoken to AP's team_members, including the AP
|
||||
string_t non_team_speak; // VOX Spoken to non AP's team_members
|
||||
string_t owners_team_speak; // VOX Spoken to members of the team that own this Goal
|
||||
string_t non_owners_team_speak; // VOX Spoken to everyone bit the members of the team that own this Goal
|
||||
|
||||
float m_flEndRoundTime;
|
||||
string_t m_iszEndRoundMsg_Team1_Win;
|
||||
string_t m_iszEndRoundMsg_Team2_Win;
|
||||
string_t m_iszEndRoundMsg_Team3_Win;
|
||||
string_t m_iszEndRoundMsg_Team4_Win;
|
||||
string_t m_iszEndRoundMsg_Team1_Lose;
|
||||
string_t m_iszEndRoundMsg_Team2_Lose;
|
||||
string_t m_iszEndRoundMsg_Team3_Lose;
|
||||
string_t m_iszEndRoundMsg_Team4_Lose;
|
||||
string_t m_iszEndRoundMsg_Team1;
|
||||
string_t m_iszEndRoundMsg_Team2;
|
||||
string_t m_iszEndRoundMsg_Team3;
|
||||
string_t m_iszEndRoundMsg_Team4;
|
||||
string_t m_iszEndRoundMsg_OwnedBy;
|
||||
string_t m_iszEndRoundMsg_NonOwnedBy;
|
||||
|
||||
int all_active;
|
||||
int last_impulse; // The previous impulse command from this player
|
||||
|
||||
int activate_goal_no;
|
||||
int inactivate_goal_no;
|
||||
int remove_goal_no;
|
||||
int restore_goal_no;
|
||||
int activate_group_no;
|
||||
int inactivate_group_no;
|
||||
int remove_group_no;
|
||||
int restore_group_no;
|
||||
|
||||
BOOL do_triggerwork; // Overrides for trigger handling in TF Goals
|
||||
string_t killtarget; // Remove ents with this target
|
||||
string_t target;
|
||||
|
||||
string_t message;
|
||||
|
||||
// Score increases
|
||||
int increase_team[4]; // Increase the scores of teams
|
||||
int increase_team_owned_by; // Increase the score of the team that owns this entity
|
||||
|
||||
EHANDLE enemy;
|
||||
|
||||
Vector oldorigin;
|
||||
int axhitme; // Remove item from AP
|
||||
|
||||
int remove_item_group;
|
||||
};
|
||||
|
||||
|
||||
class CTFGoalItem : public CTFGoal
|
||||
{
|
||||
public:
|
||||
void Spawn( void );
|
||||
void StartItem( void );
|
||||
void PlaceItem( void );
|
||||
|
||||
Class_T Classify ( void ) { return CLASS_TFGOAL_ITEM; }
|
||||
|
||||
void item_tfgoal_touch( CBaseEntity *pOther );
|
||||
void tfgoalitem_droptouch();
|
||||
void tfgoalitem_dropthink();
|
||||
void tfgoalitem_remove();
|
||||
|
||||
void DoDrop( Vector vecOrigin );
|
||||
|
||||
|
||||
public:
|
||||
|
||||
float m_flDroppedAt;
|
||||
|
||||
float speed;
|
||||
int speed_reduction;
|
||||
|
||||
float distance;
|
||||
float pain_finished;
|
||||
float attack_finished;
|
||||
|
||||
Vector redrop_origin; // Original drop position
|
||||
int redrop_count; // Number of time's we redropped.
|
||||
};
|
||||
|
||||
|
||||
class CTFTimerGoal : public CTFGoal
|
||||
{
|
||||
public:
|
||||
void Spawn( void );
|
||||
|
||||
Class_T Classify ( void ) { return CLASS_TFGOAL_TIMER; }
|
||||
};
|
||||
|
||||
|
||||
class CTFSpawn : public CTFBaseItem
|
||||
{
|
||||
public:
|
||||
void Spawn( void );
|
||||
void Activate( void );
|
||||
Class_T Classify ( void ) { return CLASS_TFSPAWN; }
|
||||
BOOL CheckTeam( int iTeamNo );
|
||||
|
||||
EHANDLE m_pTeamCheck;
|
||||
};
|
||||
|
||||
|
||||
class CBaseDelay : public CTFGoal
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( CBaseDelay, CTFGoal );
|
||||
|
||||
void SUB_UseTargets( CBaseEntity *pActivator, USE_TYPE useType, float value );
|
||||
void KeyValue( KeyValueData *pkvd );
|
||||
void DelayThink( void );
|
||||
virtual bool KeyValue( const char *szKeyName, const char *szValue );
|
||||
|
||||
public:
|
||||
float m_flDelay;
|
||||
string_t m_iszKillTarget;
|
||||
int button;
|
||||
};
|
||||
|
||||
|
||||
class CTeamCheck : public CBaseDelay
|
||||
{
|
||||
public:
|
||||
void Spawn( void );
|
||||
void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
|
||||
BOOL TeamMatches( int iTeam );
|
||||
};
|
||||
|
||||
|
||||
// Global functions.
|
||||
CTFGoalItem* Finditem(int ino);
|
||||
void DisplayItemStatus(CTFGoal *Goal, CTFCPlayer *Player, CTFGoalItem *Item);
|
||||
|
||||
|
||||
#endif // TFC_MAPITEMS_H
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,254 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Player for HL1.
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef TFC_PLAYER_H
|
||||
#define TFC_PLAYER_H
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "player.h"
|
||||
#include "server_class.h"
|
||||
#include "tfc_playeranimstate.h"
|
||||
#include "tfc_shareddefs.h"
|
||||
#include "tfc_player_shared.h"
|
||||
|
||||
|
||||
class CTFCPlayer;
|
||||
class CTFGoal;
|
||||
class CTFGoalItem;
|
||||
|
||||
|
||||
// Function table for each player state.
|
||||
class CPlayerStateInfo
|
||||
{
|
||||
public:
|
||||
TFCPlayerState m_iPlayerState;
|
||||
const char *m_pStateName;
|
||||
|
||||
void (CTFCPlayer::*pfnEnterState)(); // Init and deinit the state.
|
||||
void (CTFCPlayer::*pfnLeaveState)();
|
||||
|
||||
void (CTFCPlayer::*pfnThink)(); // Called every frame.
|
||||
};
|
||||
|
||||
|
||||
//=============================================================================
|
||||
// >> CounterStrike player
|
||||
//=============================================================================
|
||||
class CTFCPlayer : public CBasePlayer
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( CTFCPlayer, CBasePlayer );
|
||||
DECLARE_SERVERCLASS();
|
||||
|
||||
|
||||
CTFCPlayer();
|
||||
~CTFCPlayer();
|
||||
|
||||
static CTFCPlayer *CreatePlayer( const char *className, edict_t *ed );
|
||||
static CTFCPlayer* Instance( int iEnt );
|
||||
|
||||
// This passes the event to the client's and server's CPlayerAnimState.
|
||||
void DoAnimationEvent( PlayerAnimEvent_t event );
|
||||
|
||||
virtual void PostThink();
|
||||
virtual void InitialSpawn();
|
||||
virtual void Spawn();
|
||||
virtual void Precache();
|
||||
virtual bool ClientCommand( const CCommand &args );
|
||||
virtual void ChangeTeam( int iTeamNum ) OVERRIDE;
|
||||
virtual int TakeHealth( float flHealth, int bitsDamageType );
|
||||
virtual void Event_Killed( const CTakeDamageInfo &info );
|
||||
|
||||
void ClientHearVox( const char *pSentence );
|
||||
void DisplayLocalItemStatus( CTFGoal *pGoal );
|
||||
|
||||
|
||||
public:
|
||||
|
||||
// Is this entity an ally (on our team)?
|
||||
bool IsAlly( CBaseEntity *pEnt ) const;
|
||||
|
||||
TFCPlayerState State_Get() const; // Get the current state.
|
||||
|
||||
void TF_AddFrags( int nFrags );
|
||||
|
||||
void ResetMenu();
|
||||
|
||||
// On fire..
|
||||
int GetNumFlames() const;
|
||||
void SetNumFlames( int nFlames );
|
||||
|
||||
void ForceRespawn();
|
||||
|
||||
void TeamFortress_SetSpeed();
|
||||
void TeamFortress_CheckClassStats();
|
||||
void TeamFortress_SetSkin();
|
||||
void TeamFortress_RemoveLiveGrenades();
|
||||
void TeamFortress_RemoveRockets();
|
||||
void TeamFortress_DetpackStop( void );
|
||||
|
||||
BOOL TeamFortress_RemoveDetpacks( void );
|
||||
void RemovePipebombs( void );
|
||||
void RemoveOwnedEnt( char *pEntName );
|
||||
|
||||
// SPY STUFF
|
||||
public:
|
||||
|
||||
void Spy_RemoveDisguise();
|
||||
void TeamFortress_SpyCalcName();
|
||||
void Spy_ResetExternalWeaponModel( void );
|
||||
|
||||
|
||||
// ENGINEER STUFF
|
||||
public:
|
||||
|
||||
void Engineer_RemoveBuildings();
|
||||
|
||||
// Building
|
||||
BOOL is_building; // TRUE for an ENGINEER if they're building something
|
||||
EHANDLE building; // The building the ENGINEER is using
|
||||
float building_wait; // Used to prevent using a building again immediately
|
||||
EHANDLE real_owner;
|
||||
float has_dispenser; // TRUE if engineer has a dispenser
|
||||
float has_sentry; // TRUE if engineer has a sentry
|
||||
float has_entry_teleporter; // TRUE if engineer has an entry teleporter
|
||||
float has_exit_teleporter; // TRUE if engineer has an exit teleporter
|
||||
|
||||
|
||||
// DEMO STUFF
|
||||
public:
|
||||
|
||||
int m_iPipebombCount;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
// Get the class info associated with us.
|
||||
const CTFCPlayerClassInfo* GetClassInfo() const;
|
||||
|
||||
// Helpers to ease porting...
|
||||
int tp_grenades_1() const { return GetClassInfo()->m_iGrenadeType1; }
|
||||
int tp_grenades_2() const { return GetClassInfo()->m_iGrenadeType2; }
|
||||
int no_grenades_1() const { return GetAmmoCount( TFC_AMMO_GRENADES1 ); }
|
||||
int no_grenades_2() const { return GetAmmoCount( TFC_AMMO_GRENADES2 ); }
|
||||
|
||||
|
||||
public:
|
||||
|
||||
CTFCPlayerShared m_Shared;
|
||||
|
||||
int item_list; // Used to keep track of which goalitems are
|
||||
// affecting the player at any time.
|
||||
// GoalItems use it to keep track of their own
|
||||
// mask to apply to a player's item_list
|
||||
|
||||
float armortype;
|
||||
//float armorvalue; // Use CBasePlayer::m_ArmorValue.
|
||||
int armorclass; // Type of armor being worn
|
||||
float armor_allowed;
|
||||
|
||||
float invincible_finished;
|
||||
float invisible_finished;
|
||||
float super_damage_finished;
|
||||
float radsuit_finished;
|
||||
|
||||
int lives; // The number of lives you have left
|
||||
int is_unableto_spy_or_teleport;
|
||||
|
||||
BOOL bRemoveGrenade; // removes the primed grenade if set
|
||||
|
||||
// Replacement_Model Stuff
|
||||
string_t replacement_model;
|
||||
int replacement_model_body;
|
||||
int replacement_model_skin;
|
||||
int replacement_model_flags;
|
||||
|
||||
// Spy
|
||||
int undercover_team; // The team the Spy is pretending to be in
|
||||
int undercover_skin; // The skin the Spy is pretending to have
|
||||
EHANDLE undercover_target; // The player the Spy is pretending to be
|
||||
BOOL is_feigning; // TRUE for a SPY if they're feigning death
|
||||
float immune_to_check;
|
||||
BOOL is_undercover; // TRUE for a SPY if they're undercover
|
||||
|
||||
// TEAMFORTRESS VARIABLES
|
||||
int no_sentry_message;
|
||||
int no_dispenser_message;
|
||||
|
||||
// teleporter variables
|
||||
int no_entry_teleporter_message;
|
||||
int no_exit_teleporter_message;
|
||||
|
||||
BOOL is_detpacking; // TRUE for a DEMOMAN if they're setting a detpack
|
||||
|
||||
float current_menu; // is set to the number of the current menu, is 0 if they are not in a menu
|
||||
|
||||
// State management.
|
||||
private:
|
||||
|
||||
void State_Transition( TFCPlayerState newState );
|
||||
void State_Enter( TFCPlayerState newState );
|
||||
void State_Leave();
|
||||
CPlayerStateInfo* State_LookupInfo( TFCPlayerState state );
|
||||
|
||||
CPlayerStateInfo *m_pCurStateInfo;
|
||||
|
||||
void State_Enter_WELCOME();
|
||||
void State_Enter_PICKINGTEAM();
|
||||
void State_Enter_PICKINGCLASS();
|
||||
void State_Enter_ACTIVE();
|
||||
void State_Enter_OBSERVER_MODE();
|
||||
void State_Enter_DYING();
|
||||
|
||||
|
||||
private:
|
||||
|
||||
friend void Bot_Think( CTFCPlayer *pBot );
|
||||
void HandleCommand_JoinTeam( const char *pTeamName );
|
||||
void HandleCommand_JoinClass( const char *pClassName );
|
||||
|
||||
void GiveDefaultItems();
|
||||
|
||||
void TFCPlayerThink();
|
||||
|
||||
void PhysObjectSleep();
|
||||
void PhysObjectWake();
|
||||
|
||||
void GetIntoGame();
|
||||
|
||||
|
||||
private:
|
||||
|
||||
// Copyed from EyeAngles() so we can send it to the client.
|
||||
CNetworkQAngle( m_angEyeAngles );
|
||||
|
||||
ITFCPlayerAnimState *m_PlayerAnimState;
|
||||
|
||||
int m_iLegDamage;
|
||||
};
|
||||
|
||||
|
||||
inline CTFCPlayer *ToTFCPlayer( CBaseEntity *pEntity )
|
||||
{
|
||||
if ( !pEntity || !pEntity->IsPlayer() )
|
||||
return NULL;
|
||||
|
||||
#ifdef _DEBUG
|
||||
Assert( dynamic_cast<CTFCPlayer*>( pEntity ) != 0 );
|
||||
#endif
|
||||
return static_cast< CTFCPlayer* >( pEntity );
|
||||
}
|
||||
|
||||
|
||||
inline const CTFCPlayerClassInfo* CTFCPlayer::GetClassInfo() const
|
||||
{
|
||||
return GetTFCClassInfo( m_Shared.GetPlayerClass() );
|
||||
}
|
||||
|
||||
|
||||
#endif // TFC_PLAYER_H
|
||||
@@ -0,0 +1,76 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "player_command.h"
|
||||
#include "igamemovement.h"
|
||||
#include "in_buttons.h"
|
||||
#include "ipredictionsystem.h"
|
||||
#include "tfc_player.h"
|
||||
|
||||
|
||||
static CMoveData g_MoveData;
|
||||
CMoveData *g_pMoveData = &g_MoveData;
|
||||
|
||||
IPredictionSystem *IPredictionSystem::g_pPredictionSystems = NULL;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Sets up the move data for TF2
|
||||
//-----------------------------------------------------------------------------
|
||||
class CTFCPlayerMove : public CPlayerMove
|
||||
{
|
||||
DECLARE_CLASS( CTFCPlayerMove, CPlayerMove );
|
||||
|
||||
public:
|
||||
virtual void StartCommand( CBasePlayer *player, CUserCmd *cmd );
|
||||
virtual void SetupMove( CBasePlayer *player, CUserCmd *ucmd, IMoveHelper *pHelper, CMoveData *move );
|
||||
virtual void FinishMove( CBasePlayer *player, CUserCmd *ucmd, CMoveData *move );
|
||||
};
|
||||
|
||||
// PlayerMove Interface
|
||||
static CTFCPlayerMove g_PlayerMove;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Singleton accessor
|
||||
//-----------------------------------------------------------------------------
|
||||
CPlayerMove *PlayerMove()
|
||||
{
|
||||
return &g_PlayerMove;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Main setup, finish
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void CTFCPlayerMove::StartCommand( CBasePlayer *player, CUserCmd *cmd )
|
||||
{
|
||||
BaseClass::StartCommand( player, cmd );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: This is called pre player movement and copies all the data necessary
|
||||
// from the player for movement. (Server-side, the client-side version
|
||||
// of this code can be found in prediction.cpp.)
|
||||
//-----------------------------------------------------------------------------
|
||||
void CTFCPlayerMove::SetupMove( CBasePlayer *player, CUserCmd *ucmd, IMoveHelper *pHelper, CMoveData *move )
|
||||
{
|
||||
BaseClass::SetupMove( player, ucmd, pHelper, move );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: This is called post player movement to copy back all data that
|
||||
// movement could have modified and that is necessary for future
|
||||
// movement. (Server-side, the client-side version of this code can
|
||||
// be found in prediction.cpp.)
|
||||
//-----------------------------------------------------------------------------
|
||||
void CTFCPlayerMove::FinishMove( CBasePlayer *player, CUserCmd *ucmd, CMoveData *move )
|
||||
{
|
||||
// Call the default FinishMove code.
|
||||
BaseClass::FinishMove( player, ucmd, move );
|
||||
}
|
||||
@@ -0,0 +1,279 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Team management class. Contains all the details for a specific team
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "tfc_team.h"
|
||||
#include "entitylist.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
|
||||
// Datatable
|
||||
IMPLEMENT_SERVERCLASS_ST(CTFCTeam, DT_TFCTeam)
|
||||
END_SEND_TABLE()
|
||||
|
||||
LINK_ENTITY_TO_CLASS( tfc_team_manager, CTFCTeam );
|
||||
|
||||
|
||||
Vector rgbcolors[5];
|
||||
team_color_t teamcolors[5][PC_LASTCLASS]; // Colors for each of the 4 teams
|
||||
int number_of_teams = 0; // This is incremented for each map as info_player_teamspawn are created.
|
||||
const char *teamnames[5] =
|
||||
{
|
||||
"spectator",
|
||||
"blue",
|
||||
"red",
|
||||
"yellow",
|
||||
"green"
|
||||
};
|
||||
|
||||
//========================================================================
|
||||
// Set the color for the team corresponding to the no passed in, to team_no
|
||||
void TeamFortress_TeamSetColor()
|
||||
{
|
||||
// Blue Team
|
||||
teamcolors[1][PC_SCOUT].topColor = 153;
|
||||
teamcolors[1][PC_SCOUT].bottomColor = 139;
|
||||
|
||||
teamcolors[1][PC_SNIPER].topColor = 153;
|
||||
teamcolors[1][PC_SNIPER].bottomColor = 145;
|
||||
|
||||
teamcolors[1][PC_SOLDIER].topColor = 153;
|
||||
teamcolors[1][PC_SOLDIER].bottomColor = 130;
|
||||
|
||||
teamcolors[1][PC_DEMOMAN].topColor = 153;
|
||||
teamcolors[1][PC_DEMOMAN].bottomColor = 145;
|
||||
|
||||
teamcolors[1][PC_MEDIC].topColor = 153;
|
||||
teamcolors[1][PC_MEDIC].bottomColor = 140;
|
||||
|
||||
teamcolors[1][PC_HWGUY].topColor = 148;
|
||||
teamcolors[1][PC_HWGUY].bottomColor = 138;
|
||||
|
||||
teamcolors[1][PC_PYRO].topColor = 140;
|
||||
teamcolors[1][PC_PYRO].bottomColor = 145;
|
||||
|
||||
teamcolors[1][PC_SPY].topColor = 150;
|
||||
teamcolors[1][PC_SPY].bottomColor = 145;
|
||||
|
||||
teamcolors[1][PC_ENGINEER].topColor = 140;
|
||||
teamcolors[1][PC_ENGINEER].bottomColor = 148;
|
||||
|
||||
teamcolors[1][PC_CIVILIAN].topColor = 150;
|
||||
teamcolors[1][PC_CIVILIAN].bottomColor = 140;
|
||||
|
||||
#ifdef TFCTODO // sentry colors
|
||||
teamcolors[1][SENTRY_COLOR].topColor = 150;
|
||||
teamcolors[1][SENTRY_COLOR].bottomColor = 0;
|
||||
|
||||
teamcolors[2][SENTRY_COLOR].topColor = 250;
|
||||
teamcolors[2][SENTRY_COLOR].bottomColor = 0;
|
||||
|
||||
teamcolors[3][SENTRY_COLOR].topColor = 45;
|
||||
teamcolors[3][SENTRY_COLOR].bottomColor = 0;
|
||||
|
||||
teamcolors[4][SENTRY_COLOR].topColor = 100;
|
||||
teamcolors[4][SENTRY_COLOR].bottomColor = 0;
|
||||
#endif
|
||||
|
||||
// Red Team
|
||||
teamcolors[2][PC_SCOUT].topColor = 255;
|
||||
teamcolors[2][PC_SCOUT].bottomColor = 10;
|
||||
|
||||
teamcolors[2][PC_SNIPER].topColor = 255;
|
||||
teamcolors[2][PC_SNIPER].bottomColor = 10;
|
||||
|
||||
teamcolors[2][PC_SOLDIER].topColor = 250;
|
||||
teamcolors[2][PC_SOLDIER].bottomColor = 28;
|
||||
|
||||
teamcolors[2][PC_DEMOMAN].topColor = 255;
|
||||
teamcolors[2][PC_DEMOMAN].bottomColor = 20;
|
||||
|
||||
teamcolors[2][PC_MEDIC].topColor = 255;
|
||||
teamcolors[2][PC_MEDIC].bottomColor = 250;
|
||||
|
||||
teamcolors[2][PC_HWGUY].topColor = 255;
|
||||
teamcolors[2][PC_HWGUY].bottomColor = 25;
|
||||
|
||||
teamcolors[2][PC_PYRO].topColor = 250;
|
||||
teamcolors[2][PC_PYRO].bottomColor = 25;
|
||||
|
||||
teamcolors[2][PC_SPY].topColor = 250;
|
||||
teamcolors[2][PC_SPY].bottomColor = 240;
|
||||
|
||||
teamcolors[2][PC_ENGINEER].topColor = 5;
|
||||
teamcolors[2][PC_ENGINEER].bottomColor = 250;
|
||||
|
||||
teamcolors[2][PC_CIVILIAN].topColor = 250;
|
||||
teamcolors[2][PC_CIVILIAN].bottomColor = 240;
|
||||
|
||||
|
||||
// Yellow Team
|
||||
teamcolors[3][PC_SCOUT].topColor = 45;
|
||||
teamcolors[3][PC_SCOUT].bottomColor = 35;
|
||||
|
||||
teamcolors[3][PC_SNIPER].topColor = 45;
|
||||
teamcolors[3][PC_SNIPER].bottomColor = 35;
|
||||
|
||||
teamcolors[3][PC_SOLDIER].topColor = 45;
|
||||
teamcolors[3][PC_SOLDIER].bottomColor = 35;
|
||||
|
||||
teamcolors[3][PC_DEMOMAN].topColor = 45;
|
||||
teamcolors[3][PC_DEMOMAN].bottomColor = 35;
|
||||
|
||||
teamcolors[3][PC_MEDIC].topColor = 45;
|
||||
teamcolors[3][PC_MEDIC].bottomColor = 35;
|
||||
|
||||
teamcolors[3][PC_HWGUY].topColor = 45;
|
||||
teamcolors[3][PC_HWGUY].bottomColor = 40;
|
||||
|
||||
teamcolors[3][PC_PYRO].topColor = 45;
|
||||
teamcolors[3][PC_PYRO].bottomColor = 35;
|
||||
|
||||
teamcolors[3][PC_SPY].topColor = 45;
|
||||
teamcolors[3][PC_SPY].bottomColor = 35;
|
||||
|
||||
teamcolors[3][PC_ENGINEER].topColor = 45;
|
||||
teamcolors[3][PC_ENGINEER].bottomColor = 45;
|
||||
|
||||
teamcolors[3][PC_CIVILIAN].topColor = 45;
|
||||
teamcolors[3][PC_CIVILIAN].bottomColor = 35;
|
||||
|
||||
// Green Team
|
||||
teamcolors[4][PC_SCOUT].topColor = 100;
|
||||
teamcolors[4][PC_SCOUT].bottomColor = 90;
|
||||
|
||||
teamcolors[4][PC_SNIPER].topColor = 80;
|
||||
teamcolors[4][PC_SNIPER].bottomColor = 90;
|
||||
|
||||
teamcolors[4][PC_SOLDIER].topColor = 100;
|
||||
teamcolors[4][PC_SOLDIER].bottomColor = 40;
|
||||
|
||||
teamcolors[4][PC_DEMOMAN].topColor = 100;
|
||||
teamcolors[4][PC_DEMOMAN].bottomColor = 90;
|
||||
|
||||
teamcolors[4][PC_MEDIC].topColor = 100;
|
||||
teamcolors[4][PC_MEDIC].bottomColor = 90;
|
||||
|
||||
teamcolors[4][PC_HWGUY].topColor = 100;
|
||||
teamcolors[4][PC_HWGUY].bottomColor = 90;
|
||||
|
||||
teamcolors[4][PC_PYRO].topColor = 100;
|
||||
teamcolors[4][PC_PYRO].bottomColor = 50;
|
||||
|
||||
teamcolors[4][PC_SPY].topColor = 100;
|
||||
teamcolors[4][PC_SPY].bottomColor = 90;
|
||||
|
||||
teamcolors[4][PC_ENGINEER].topColor = 100;
|
||||
teamcolors[4][PC_ENGINEER].bottomColor = 90;
|
||||
|
||||
teamcolors[4][PC_CIVILIAN].topColor = 100;
|
||||
teamcolors[4][PC_CIVILIAN].bottomColor = 90;
|
||||
|
||||
rgbcolors[0] = Vector( 255, 255, 255 ); // White for non-owned
|
||||
rgbcolors[1] = Vector( 0, 0, 255 );
|
||||
rgbcolors[2] = Vector( 255, 0, 0 );
|
||||
rgbcolors[3] = Vector( 255, 255, 30 );
|
||||
rgbcolors[4] = Vector( 0, 255, 0 );
|
||||
}
|
||||
class CColorInitializer
|
||||
{
|
||||
public:
|
||||
CColorInitializer()
|
||||
{
|
||||
TeamFortress_TeamSetColor();
|
||||
}
|
||||
} g_ColorInitializer;
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Get a pointer to the specified TF team manager
|
||||
//-----------------------------------------------------------------------------
|
||||
CTFCTeam *GetGlobalTFCTeam( int iIndex )
|
||||
{
|
||||
return (CTFCTeam*)GetGlobalTeam( iIndex );
|
||||
}
|
||||
|
||||
|
||||
// Display all the Team Scores
|
||||
void TeamFortress_TeamShowScores(BOOL bLong, CBasePlayer *pPlayer)
|
||||
{
|
||||
for (int i = 1; i < g_Teams.Count(); i++)
|
||||
{
|
||||
if (!bLong)
|
||||
{
|
||||
// Dump short scores
|
||||
UTIL_ClientPrintAll( HUD_PRINTNOTIFY, UTIL_VarArgs("%s: %d\n", g_szTeamColors[i], GetGlobalTeam(i)->GetScore()) );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Dump long scores
|
||||
if (pPlayer == NULL)
|
||||
UTIL_ClientPrintAll( HUD_PRINTNOTIFY, UTIL_VarArgs("Team %d (%s): %d\n", i, g_szTeamColors[i], GetGlobalTeam(i)->GetScore()) );
|
||||
else // Print to just one client
|
||||
ClientPrint( pPlayer, HUD_PRINTNOTIFY, UTIL_VarArgs("Team %d (%s): %d\n", i, g_szTeamColors[i], GetGlobalTeam(i)->GetScore()) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//=========================================================================
|
||||
// Return the score/frags of a team, depending on whether TeamFrags is on
|
||||
int TeamFortress_TeamGetScoreFrags(int tno)
|
||||
{
|
||||
CTeam *pTeam = GetGlobalTeam( tno );
|
||||
if ( pTeam )
|
||||
{
|
||||
return pTeam->GetScore();
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert( false );
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Needed because this is an entity, but should never be used
|
||||
//-----------------------------------------------------------------------------
|
||||
void CTFCTeam::Init( const char *pName, int iNumber )
|
||||
{
|
||||
BaseClass::Init( pName, iNumber );
|
||||
|
||||
// Only detect changes every half-second.
|
||||
NetworkProp()->SetUpdateInterval( 0.75f );
|
||||
}
|
||||
|
||||
|
||||
color32 CTFCTeam::GetTeamColor()
|
||||
{
|
||||
int i = GetTeamNumber();
|
||||
if ( i >= 0 && i < ARRAYSIZE( rgbcolors ) )
|
||||
{
|
||||
return Vector255ToRGBColor( rgbcolors[i] );
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert( false );
|
||||
color32 x;
|
||||
memset( &x, 0, sizeof( x ) );
|
||||
return x;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
color32 Vector255ToRGBColor( const Vector &vColor )
|
||||
{
|
||||
color32 ret;
|
||||
ret.a = 0;
|
||||
ret.r = (byte)vColor.x;
|
||||
ret.g = (byte)vColor.y;
|
||||
ret.b = (byte)vColor.z;
|
||||
return ret;
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Team management class. Contains all the details for a specific team
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef TFC_TEAM_H
|
||||
#define TFC_TEAM_H
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
#include "utlvector.h"
|
||||
#include "team.h"
|
||||
#include "tfc_shareddefs.h"
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Team Manager
|
||||
//-----------------------------------------------------------------------------
|
||||
class CTFCTeam : public CTeam
|
||||
{
|
||||
DECLARE_CLASS( CTFCTeam, CTeam );
|
||||
DECLARE_SERVERCLASS();
|
||||
|
||||
public:
|
||||
|
||||
// Initialization
|
||||
virtual void Init( const char *pName, int iNumber );
|
||||
color32 GetTeamColor();
|
||||
};
|
||||
|
||||
|
||||
extern CTFCTeam *GetGlobalTFCTeam( int iIndex );
|
||||
|
||||
void TeamFortress_TeamShowScores(BOOL bLong, CBasePlayer *pPlayer);
|
||||
int TeamFortress_TeamGetScoreFrags(int tno);
|
||||
|
||||
// Colors for each team.
|
||||
typedef struct
|
||||
{
|
||||
int topColor;
|
||||
int bottomColor;
|
||||
} team_color_t;
|
||||
|
||||
extern Vector rgbcolors[5];
|
||||
extern team_color_t teamcolors[5][PC_LASTCLASS]; // Colors for each of the 4 teams
|
||||
extern int number_of_teams; // This is incremented for each map as info_player_teamspawn are created.
|
||||
extern const char *teamnames[5];
|
||||
#define g_szTeamColors teamnames
|
||||
|
||||
color32 Vector255ToRGBColor( const Vector &vColor );
|
||||
|
||||
|
||||
#endif // TF_TEAM_H
|
||||
@@ -0,0 +1,117 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "tfc_timer.h"
|
||||
|
||||
|
||||
static CUtlLinkedList<CTimer*,int> g_Timers;
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------ //
|
||||
// CTimer functions.
|
||||
// ------------------------------------------------------------------------------------------ //
|
||||
|
||||
CTimer::CTimer()
|
||||
{
|
||||
m_iTeamNumber = 0;
|
||||
m_flNextThink = 0;
|
||||
}
|
||||
|
||||
|
||||
int CTimer::GetTeamNumber() const
|
||||
{
|
||||
return m_iTeamNumber;
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------ //
|
||||
// Global timer functions.
|
||||
// ------------------------------------------------------------------------------------------ //
|
||||
|
||||
CTimer* Timer_FindTimer( CBaseEntity *pPlayer, TFCTimer_t timerType )
|
||||
{
|
||||
FOR_EACH_LL( g_Timers, i )
|
||||
{
|
||||
CTimer *pTimer = g_Timers[i];
|
||||
|
||||
if ( pTimer->m_hOwner == pPlayer )
|
||||
{
|
||||
if ( timerType == TF_TIMER_ANY || pTimer->m_Type == timerType )
|
||||
return pTimer;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
CTimer* Timer_CreateTimer( CBaseEntity *pPlayer, TFCTimer_t timerType )
|
||||
{
|
||||
Assert( !Timer_FindTimer( pPlayer, timerType ) );
|
||||
|
||||
CTimer *pTimer = new CTimer;
|
||||
pTimer->m_hOwner = pPlayer;
|
||||
pTimer->m_Type = timerType;
|
||||
pTimer->m_iListIndex = g_Timers.AddToTail( pTimer );
|
||||
|
||||
// TFCTODO: Register the think functions here..
|
||||
if ( pTimer->m_Type == TF_TIMER_ROTHEALTH )
|
||||
{
|
||||
pTimer->m_flNextThink = gpGlobals->curtime + 5;
|
||||
}
|
||||
else if ( pTimer->m_Type == TF_TIMER_INFECTION )
|
||||
{
|
||||
pTimer->m_flNextThink = gpGlobals->curtime + 2;
|
||||
}
|
||||
|
||||
// TFCTODO: hook up thinks...
|
||||
// TF_TIMER_RETURNITEM -> CBaseEntity::ReturnItem -> <up to caller>
|
||||
// TF_TIMER_ENDROUND -> CBaseEntity::EndRoundEnd -> <up to caller>
|
||||
|
||||
return pTimer;
|
||||
}
|
||||
|
||||
|
||||
void Timer_Remove( CTimer *pTimer )
|
||||
{
|
||||
g_Timers.Remove( pTimer->m_iListIndex );
|
||||
delete pTimer;
|
||||
}
|
||||
|
||||
|
||||
void Timer_UpdateAll()
|
||||
{
|
||||
int iNext = 0;
|
||||
int i = g_Timers.Head();
|
||||
while ( i != g_Timers.InvalidIndex() )
|
||||
{
|
||||
iNext = g_Timers.Next( i );
|
||||
CTimer *pTimer = g_Timers[i];
|
||||
i = iNext;
|
||||
|
||||
// Get rid of invalid timers.
|
||||
if ( pTimer->m_hOwner.Get() == NULL )
|
||||
{
|
||||
g_Timers.Remove( i );
|
||||
delete pTimer;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Is it time to think for this timer?
|
||||
if ( gpGlobals->curtime >= pTimer->m_flNextThink )
|
||||
{
|
||||
// TFCTODO: think here.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Timer_RemoveAll()
|
||||
{
|
||||
g_Timers.PurgeAndDeleteElements();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef TFC_TIMER_H
|
||||
#define TFC_TIMER_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
#include "ehandle.h"
|
||||
#include "tfc_shareddefs.h"
|
||||
|
||||
|
||||
class CTFCPlayer;
|
||||
|
||||
|
||||
class CTimer
|
||||
{
|
||||
public:
|
||||
CTimer();
|
||||
|
||||
int GetTeamNumber() const;
|
||||
|
||||
public:
|
||||
EHANDLE m_hOwner;
|
||||
EHANDLE m_hEnemy;
|
||||
TFCTimer_t m_Type; // One of the TF_TIMER_ defines.
|
||||
int m_iTeamNumber;
|
||||
float m_flNextThink;
|
||||
int weapon; // GI_RET_ define.
|
||||
|
||||
// For g_Timers.
|
||||
int m_iListIndex;
|
||||
};
|
||||
|
||||
|
||||
// This stuff replaces the functions like CBaseEntity::FindTimer, CBaseEntity::CreateTimer,
|
||||
// and all the timer handlers in TFC.
|
||||
|
||||
// Find an active timer on the specified entity.
|
||||
CTimer* Timer_FindTimer( CBaseEntity *pPlayer, TFCTimer_t timerType );
|
||||
|
||||
// Create a new timer.
|
||||
CTimer* Timer_CreateTimer( CBaseEntity *pPlayer, TFCTimer_t timerType );
|
||||
|
||||
// Get rid of a timer.
|
||||
void Timer_Remove( CTimer *pTimer );
|
||||
|
||||
// Update all timers.
|
||||
void Timer_UpdateAll();
|
||||
|
||||
// Call at round restart.
|
||||
void Timer_RemoveAll();
|
||||
|
||||
|
||||
#endif // TFC_TIMER_H
|
||||
Reference in New Issue
Block a user