summaryrefslogtreecommitdiff
path: root/game/client/tf2/mapdata.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'game/client/tf2/mapdata.cpp')
-rw-r--r--game/client/tf2/mapdata.cpp372
1 files changed, 372 insertions, 0 deletions
diff --git a/game/client/tf2/mapdata.cpp b/game/client/tf2/mapdata.cpp
new file mode 100644
index 0000000..cc1c3c5
--- /dev/null
+++ b/game/client/tf2/mapdata.cpp
@@ -0,0 +1,372 @@
+//========= 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;
+}