You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
372 lines
10 KiB
372 lines
10 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: |
|
// |
|
// $Workfile: $ |
|
// $NoKeywords: $ |
|
//=============================================================================// |
|
#include "cbase.h" |
|
#include "mapdata.h" |
|
#include "hud.h" |
|
#include "hud_macros.h" |
|
#include <KeyValues.h> |
|
#include "playeroverlay.h" |
|
#include "iclientmode.h" |
|
#include "hud_technologytreedoc.h" |
|
#include "C_World.h" |
|
#include "c_basetfplayer.h" |
|
#include "c_team.h" |
|
#include "c_tfteam.h" |
|
#include "c_func_resource.h" |
|
#include "vgui_bitmapimage.h" |
|
#include "C_Shield.h" |
|
#include "c_obj_respawn_station.h" |
|
|
|
bool IsEntityVisibleToTactical( int iLocalTeamNumber, int iLocalTeamPlayers, |
|
int iLocalTeamObjects, int iEntIndex, const char *pEntName, int pEntTeamNumber, const Vector &pEntOrigin ); |
|
|
|
// All of the parsing occurs mapdata_parse.cpp |
|
bool ParseMinimapData( const char *filename, MinimapData_t *pMinimap, CMapZones *pZones, CMapTeamColors *pTeamColors, KeyValues *pKV ); |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Gets at the singleton map data |
|
//----------------------------------------------------------------------------- |
|
|
|
static CMapData g_MapData; |
|
CMapData& MapData() |
|
{ |
|
// Singleton object |
|
return g_MapData; |
|
} |
|
|
|
IMapData *g_pMapData = &g_MapData; |
|
|
|
DECLARE_COMMAND( g_MapData, ForceMapReload ); |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: This is a total hack, but should allow reloading the mapfile.txt stuff on the fly |
|
//----------------------------------------------------------------------------- |
|
void CMapData::UserCmd_ForceMapReload( void ) |
|
{ |
|
if ( m_szMap[0] ) |
|
{ |
|
LevelInit( m_szMap ); |
|
// Force other data to reinit itself |
|
GetTechnologyTreeDoc().Init(); |
|
|
|
// Force any needed viewport fixups |
|
g_pClientMode->Disable(); |
|
g_pClientMode->Enable(); |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
CMapData::CMapData( void ) |
|
{ |
|
m_szMap[0]=0; |
|
|
|
int i, j; |
|
m_Minimap.m_szBackgroundMaterial[0] = 0; |
|
|
|
for ( i = 0; i < MAX_ZONES; i++ ) |
|
{ |
|
m_Zones[ i ].m_pZoneImage = NULL; |
|
m_Zones[ i ].m_nControllingTeam = -1; |
|
} |
|
|
|
for ( i = 0; i < MAX_PLAYERS; i++ ) |
|
{ |
|
m_Players[ i ].m_pImage = NULL; |
|
m_Players[ i ].m_nTeam = 0; |
|
m_Players[ i ].m_bSelected = false; |
|
m_Players[ i ].m_nSquadNumber = 0; |
|
|
|
} |
|
|
|
for ( i = 0; i <= MAX_MAP_TEAMS; i++ ) |
|
{ |
|
m_TeamColors[ i ].m_pImage = NULL; |
|
|
|
for ( j = 0; j < MAX_CLASSES; j++ ) |
|
{ |
|
if ( m_TeamColors[ i ].m_ClassColors[ j ].m_pClassImage ) |
|
{ |
|
m_TeamColors[ i ].m_ClassColors[ j ].m_pClassImage = NULL; |
|
} |
|
} |
|
} |
|
|
|
UseDefaults(); |
|
} |
|
|
|
HOOK_COMMAND( forcemapreload, ForceMapReload ); |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: One time init |
|
//----------------------------------------------------------------------------- |
|
void CMapData::Init( void ) |
|
{ |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Delete all dynamic images, but leave rest of data structures |
|
//----------------------------------------------------------------------------- |
|
void CMapData::Clear( void ) |
|
{ |
|
int i, j; |
|
|
|
// Delete old zones... |
|
for ( i = 0; i < MAX_ZONES; i++ ) |
|
{ |
|
delete m_Zones[ i ].m_pZoneImage; |
|
m_Zones[ i ].m_pZoneImage = NULL; |
|
} |
|
|
|
for ( i = 0; i <= MAX_MAP_TEAMS; i++ ) |
|
{ |
|
delete m_TeamColors[ i ].m_pImage; |
|
m_TeamColors[ i ].m_pImage = NULL; |
|
|
|
for ( j = 0; j < MAX_CLASSES; j++ ) |
|
{ |
|
delete m_TeamColors[ i ].m_ClassColors[ j ].m_pClassImage; |
|
m_TeamColors[ i ].m_ClassColors[ j ].m_pClassImage = NULL; |
|
} |
|
} |
|
|
|
m_Minimap.m_szBackgroundMaterial[0] = 0; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
CMapData::~CMapData( void ) |
|
{ |
|
Clear(); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Set a team's default colors |
|
//----------------------------------------------------------------------------- |
|
void CMapData::SetTeamDefaultColor( int iTeamNumber, int r, int g, int b ) |
|
{ |
|
m_TeamColors[ iTeamNumber ].m_clrBlip.SetColor( r,g,b, 0 ); |
|
m_TeamColors[ iTeamNumber ].m_clrTeam.SetColor( r,g,b, 128 ); |
|
|
|
for ( int j = 0; j < MAX_CLASSES; j++ ) |
|
{ |
|
m_TeamColors[ iTeamNumber ].m_ClassColors->m_clrClass.SetColor( r,g,b, 0 ); |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Fill in placeholder colors, etc. |
|
//----------------------------------------------------------------------------- |
|
void CMapData::UseDefaults( void ) |
|
{ |
|
// Init colors for all teams |
|
SetTeamDefaultColor( 1, 255, 0, 0 ); |
|
SetTeamDefaultColor( 2, 0, 0, 255 ); |
|
SetTeamDefaultColor( 3, 0, 0, 0 ); |
|
SetTeamDefaultColor( 4, 0, 0, 0 ); |
|
SetTeamDefaultColor( 5, 0, 0, 0 ); |
|
SetTeamDefaultColor( 6, 0, 0, 0 ); |
|
SetTeamDefaultColor( 7, 0, 0, 0 ); |
|
SetTeamDefaultColor( 8, 0, 0, 0 ); |
|
|
|
m_Minimap.m_szBackgroundMaterial[0] = 0; |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Get the bounding box of the world |
|
//----------------------------------------------------------------------------- |
|
void CMapData::GetMapBounds(Vector &mins, Vector& maxs) |
|
{ |
|
C_BaseEntity *ent = cl_entitylist->GetEnt( 0 ); |
|
C_World* pWorld = dynamic_cast<C_World*>(ent); |
|
if (pWorld) |
|
{ |
|
VectorCopy( pWorld->m_WorldMins, mins ); |
|
VectorCopy( pWorld->m_WorldMaxs, maxs ); |
|
|
|
// Backward compatability... |
|
if ((mins.LengthSqr() == 0.0f) && (maxs.LengthSqr() == 0.0f)) |
|
{ |
|
mins.Init( -6500, -6500, -6500 ); |
|
maxs.Init( 6500, 6500, 6500 ); |
|
} |
|
} |
|
else |
|
{ |
|
Assert(0); |
|
mins.Init( 0, 0, 0 ); |
|
maxs.Init( 1, 1, 1 ); |
|
} |
|
} |
|
|
|
void CMapData::GetMapOrigin(Vector &org) |
|
{ |
|
Vector mins, maxs; |
|
GetMapBounds( mins, maxs ); |
|
VectorAdd( mins, maxs, org ); |
|
VectorMultiply( org, 0.5, org ); |
|
} |
|
|
|
void CMapData::GetMapSize(Vector &size) |
|
{ |
|
Vector mins, maxs; |
|
GetMapBounds( mins, maxs ); |
|
VectorSubtract( maxs, mins, size ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
//----------------------------------------------------------------------------- |
|
void CMapData::Get3DSkyboxOrigin( Vector &vecOrigin ) |
|
{ |
|
// NOTE: If the player hasn't been created yet -- this doesn't work!!! |
|
// We need to pass the data along in the map - requires a tool change. |
|
C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer(); |
|
if ( pPlayer ) |
|
{ |
|
CPlayerLocalData *pLocalData = &pPlayer->m_Local; |
|
VectorCopy( pLocalData->m_skybox3d.origin, vecOrigin ); |
|
} |
|
else |
|
{ |
|
// Debugging! |
|
Assert( 0 ); |
|
vecOrigin.Init(); |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
//----------------------------------------------------------------------------- |
|
float CMapData::Get3DSkyboxScale( void ) |
|
{ |
|
// NOTE: If the player hasn't been created yet -- this doesn't work!!! |
|
// We need to pass the data along in the map - requires a tool change. |
|
C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer(); |
|
if ( pPlayer ) |
|
{ |
|
CPlayerLocalData *pLocalData = &pPlayer->m_Local; |
|
return pLocalData->m_skybox3d.scale; |
|
} |
|
else |
|
{ |
|
// Debugging! |
|
Assert( 0 ); |
|
return ( 1.0f ); |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// What's my visible area? |
|
//----------------------------------------------------------------------------- |
|
void CMapData::SetVisibleArea( const Vector& mins, const Vector& maxs ) |
|
{ |
|
m_VisibleMins = mins; |
|
m_VisibleMaxs = maxs; |
|
} |
|
|
|
void CMapData::GetVisibleArea( Vector& mins, Vector& maxs ) |
|
{ |
|
mins = m_VisibleMins; |
|
maxs = m_VisibleMaxs; |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: The client is about to change maps |
|
// Input : *map - name of the new map |
|
//----------------------------------------------------------------------------- |
|
void CMapData::LevelInit( const char *map ) |
|
{ |
|
Q_strncpy( m_szMap, map, MINIMAP_STRING_SIZE ); |
|
|
|
// Clear leftover data |
|
Clear(); |
|
|
|
// The name of the background material for the map is well-defined |
|
Q_snprintf( m_Minimap.m_szBackgroundMaterial, MINIMAP_MATERIAL_STRING_SIZE, |
|
"hud/minimap/%s/%s", map, map ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CMapData::LevelShutdown( void ) |
|
{ |
|
Clear(); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Update fog of war |
|
//----------------------------------------------------------------------------- |
|
void CMapData::Update( void ) |
|
{ |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Is entity visible to tactical? |
|
//----------------------------------------------------------------------------- |
|
bool CMapData::IsEntityVisibleToTactical( C_BaseEntity* pEnt ) const |
|
{ |
|
C_BaseTFPlayer *pPlayer = C_BaseTFPlayer::GetLocalPlayer(); |
|
if (!pPlayer) |
|
return false; |
|
|
|
// If the local player hasn't chosen a class or a team, nothing's visible |
|
if ((pPlayer->GetClass() == TFCLASS_UNDECIDED) || (pPlayer->GetTeamNumber() == 0)) |
|
return false; |
|
|
|
C_TFTeam *pTeam = (C_TFTeam *)pPlayer->GetTeam(); |
|
if (!pTeam) |
|
return false; |
|
|
|
// Local player is always visible, as long as he's chosen a class. |
|
if (pEnt == pPlayer) |
|
return true; |
|
|
|
int iNumberObjects = 0; |
|
int iNumberPlayers = 0; |
|
if ( pTeam ) |
|
{ |
|
iNumberObjects = pTeam->GetNumObjects(); |
|
iNumberPlayers = pTeam->Get_Number_Players(); |
|
} |
|
|
|
int localteam = pPlayer->GetTeamNumber(); |
|
|
|
// If on our team, not on a team, or is a resource zone, can't be cloaked |
|
if ( !pEnt->GetTeamNumber() || pEnt->GetTeamNumber() == localteam ) |
|
{ |
|
return true; |
|
} |
|
|
|
// NOTE: The global IsEntityVisibleToTactical returns true in situations |
|
// where the entity would otherwise not be visible |
|
bool bRet = ::IsEntityVisibleToTactical( localteam, iNumberPlayers, |
|
iNumberObjects, pEnt->entindex(), pEnt->GetClassname(), pEnt->GetTeamNumber(), pEnt->GetAbsOrigin() ); |
|
|
|
if ( bRet ) |
|
{ |
|
return true; |
|
} |
|
|
|
// Make sure it's within a well-defined radius of the local player... |
|
Vector2D dist; |
|
Vector2DSubtract( pEnt->GetAbsOrigin().AsVector2D(), pPlayer->GetAbsOrigin().AsVector2D(), dist ); |
|
|
|
// Cloaked by this object? |
|
if ( dist.LengthSqr() > LOCAL_PLAYER_SCANNER_RANGE * LOCAL_PLAYER_SCANNER_RANGE ) |
|
return false; |
|
|
|
// On other team, and not cloaked by technician |
|
return true; |
|
}
|
|
|