This commit is contained in:
FluorescentCIAAfricanAmerican
2020-04-22 12:56:21 -04:00
commit 3bf9df6b27
15370 changed files with 5489726 additions and 0 deletions
+470
View File
@@ -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 );
}
+21
View File
@@ -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
+73
View File
@@ -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
+155
View File
@@ -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" );
}
+17
View File
@@ -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
+73
View File
@@ -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" );
}
}
+21
View File
@@ -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
+56
View File
@@ -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;
}
+33
View File
@@ -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
+405
View File
@@ -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
+254
View File
@@ -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
+76
View File
@@ -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 );
}
+279
View File
@@ -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;
}
+58
View File
@@ -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
+117
View File
@@ -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();
}
+60
View File
@@ -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