summaryrefslogtreecommitdiff
path: root/game/client/tf2/hud_minimap.h
blob: a0c6ab1fe4e7787ad1e41fe54e11d8953506ec71 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: 
//
// $Workfile:     $
// $NoKeywords: $
//=============================================================================//
#if !defined( HUD_MINIMAP_H )
#define HUD_MINIMAP_H

#ifdef _WIN32
#pragma once
#endif

#include "mathlib/vector.h"
#include "cdll_client_int.h"
#include "hudelement.h"
#include "utllinkedlist.h"
#include "CommanderOverlay.h"
#include "MapData.h"

class BitmapImage;
class CTextHelpPanel;

//-----------------------------------------------------------------------------
// This interfaces gets called when a click occurs in the minimap
//-----------------------------------------------------------------------------
class IMinimapClient
{
public:
	virtual void MinimapClicked( const Vector& clickWorldPos ) = 0;
};


//-----------------------------------------------------------------------------
// Ways to perform WorldToMinimap
//-----------------------------------------------------------------------------
enum MinimapPosType_t
{
	MINIMAP_NOCLIP = 0,	// Don't draw things off the minimap
	MINIMAP_CLAMP,		// Clamp the position to lie within the minimap
	MINIMAP_CLIP,		// Clip the vector from minimap center to object
						// to the minimap bounds and put the object on the edge
	MINIMAP_ALWAYS_ACCEPT // Just do the scaling and return a value - don't worry about clipping.
};


//-----------------------------------------------------------------------------
// Purpose: On the left side of the screen is an overview map and a highlight 
// rectangle showing the current viewport
//
// NOTE: The minimap panel is architected in such a way as to view some global
// state. There can be many instances of the minimap panel
//-----------------------------------------------------------------------------
class CMinimapPanel : public CHudElement, public vgui::Panel
{
	DECLARE_CLASS_SIMPLE( CMinimapPanel, vgui::Panel );

public:
	enum
	{
		STABLE = 0,
		GROWING,
		SHRINKING
	};
	
							CMinimapPanel( const char *pElementName );
	virtual					~CMinimapPanel( void );

	void					Init( IMinimapClient* pClient = NULL );

	virtual void			LevelInit( const char *mapname );
	virtual void			LevelShutdown( void );

	virtual void			ApplySchemeSettings( vgui::IScheme *scheme );

	virtual void			OnMousePressed(vgui::MouseCode code);

	virtual void			Paint();

	virtual void			OnTick();
	virtual void			OnThink();

	virtual void			OnSizeChanged( int w, int h );

	// Converts a world-space position to a coordinate in minimap panel space
	bool					WorldToMinimap( MinimapPosType_t posType, const Vector &pos, float& outx, float& outy );

	// The following methods deal with management of the minimap data
	static vgui::Panel		*MinimapRootPanel();
	static CMinimapPanel	*MinimapPanel();

	// Call this when the minimap panel is going to be drawn...
	void					Activate();

	// 0 is minimized and won't draw zoom details, 1.0 is fully maximized
	bool					ShouldDrawZoomDetails( int& alpha );

	bool					InternalWorldToMinimap( MinimapPosType_t posType, const Vector &pos, const Vector& origin, float zoomscale, float& outx, float& outy );

	static void				Zoom_Minimap_f( void );
	void					ZoomIn( void );

	void					ToggleMinimap( void );
	void					SetMinimapZoom( bool bZoom);

	virtual void			ProcessInput( void );

	float					GetAdjustedZoom( void );
	float					GetTrueZoom( void );

	// Handler for our message
	void					MsgFunc_MinimapPulse( bf_read &msg );

private:
	void					SetBackgroundMaterials( char const* pMaterialName );

	void					GetMapOriginAndScale( Vector& origin, float& scale );

	void					SetBackgroundViewport( float minx, float miny, float maxx, float maxy, bool includedetails );
	void					PaintActOverlays( int teamIndex, int alpha );
	void					AdjustNormalizedPositionForAspectRatio( float& x, float& y );

	void					DrawVisibleArea( void );

	void					ComputeMapOrigin( Vector& origin );

	void					InitOverlays( const char *materialrootname );
	void					ShutdownOverlays( void );

	vgui::Panel				*GetTextPaintPanel( void );

	void					InvokeOnTickOnChildren( vgui::Panel *parent );

	bool	m_DrawVisibleArea;
	IMinimapClient	*m_pClient;

	CPanelAnimationVar( float, m_flExpansionFrac, "ExpansionFrac", "0" );
	CPanelAnimationVar( float, m_flDetailsAlpha, "DetailsAlpha", "0" );
	CPanelAnimationVar( float, m_flMapScale, "MapScale", "2000" );
	CPanelAnimationVar( float, m_flZoomAmount, "ZoomAmount", "1.0" );
	CPanelAnimationVar( float, m_flCenterOnPlayer, "CenterOnPlayer", "1" );

	CPanelAnimationVar( float, m_flInsetPixels, "InsetPixels", "16" );

	float					m_flPrevZoomAmount;

	CPanelAnimationVar( Color, m_BackgroundColor, "BackgroundColor", "Black" );
	CPanelAnimationVar( Color, m_BorderColor, "BorderColor", "FgColor" );

	int						m_nZoomLevel;
	bool					m_bMinimapZoomed;
	int						m_nCurrentAct;

	float					m_flZoomAdjust;  // Adjustment needed to get map to fit exactly into box in one dimension assuming
												// m_flZoomAmount == 1.0f


	enum
	{
		NUM_WIDTHS = 2,
	};


	// Calculated once per frame and cached
	Vector					m_vecCurrentOrigin;
	Vector					m_vecMapCenter;
	float					m_flMapAspectRatio;
	float					m_flViewportAspectRatio;
	// map aspect / viewport aspect
	float					m_flAspectAdjustment;

	float					m_flNormalizedXScale;
	float					m_flNormalizedYScale;
	float					m_flNormalizedXOffset;
	float					m_flNormalizedYOffset;


	//	These are the wordspace corners of the minimap
	float					m_flWorldSpaceBounds[ 4 ];
	 // These are the above, except clamped to actual world mins/maxs
	float					m_flClippedWorldSpaceBounds[ 4 ];
	// These are used to clamp the map origin to keep the zoomed map from scrolling off screen
	float					m_flWorldSpaceInsets[ 4 ];

	enum
	{
		MAX_ACTS = 16,
		MAX_ACT_TEAMS = 2
	};

	struct Overlays
	{
		bool				m_bInUse;
		BitmapImage			*m_pOverlay;
		BitmapImage			*m_pText;
	};

	BitmapImage				*m_pBackground[ MAX_ACT_TEAMS ];
	Overlays				m_rgOverlays[ MAX_ACT_TEAMS ][ MAX_ACTS ];

	CTextHelpPanel			*m_pTextPanel;
	vgui::Panel				*m_pBackgroundPanel;
};


//-----------------------------------------------------------------------------
// minimap render order
//-----------------------------------------------------------------------------
enum
{
	MINIMAP_GROUND_LINES = 0,
	MINIMAP_RESOURCE_ZONES,
	MINIMAP_OBJECTS, 
	MINIMAP_SPY_CAMERAS,
	MINIMAP_COLLECTORS,
	MINIMAP_MAP_GOALS,
	MINIMAP_PLAYERS,
	MINIMAP_LOCAL_PLAYER,
	MINIMAP_SNIPER_RESPAWN,
	MINIMAP_PERSONAL_ORDERS
};


//-----------------------------------------------------------------------------
// Instantiate a temporary trace (position based, or entity based)
//-----------------------------------------------------------------------------
void MinimapCreateTempTrace( const char* pMetaClassName, int sortOrder, const Vector &vecPosition );
void MinimapCreateTempTrace( const char* pMetaClassName, int sortOrder, C_BaseEntity *pEntity, const Vector &vecOffset );


//-----------------------------------------------------------------------------
// Helper macro to make overlay factories one line of code. Use like this:
//	DECLARE_MINIMAP_FACTORY( CEntityImagePanel, "image" );
//-----------------------------------------------------------------------------
struct MinimapInitData_t
{
	C_BaseEntity *m_pEntity;
	Vector m_vecPosition;	// relative to m_pEntity if it's specified, otherwise absolute position

	MinimapInitData_t() : m_pEntity(NULL), m_vecPosition( 0, 0, 0 ) {}
	MinimapInitData_t( C_BaseEntity *pEntity ) : m_pEntity(pEntity), m_vecPosition( 0, 0, 0 ) {}
};

#define DECLARE_MINIMAP_FACTORY( _PanelClass, _nameString )	\
	DECLARE_PANEL_FACTORY( _PanelClass, MinimapInitData_t, _nameString )


//-----------------------------------------------------------------------------
// Macros for help with simple registration of minimap
// Put DECLARE_MINIMAP_PANEL() in your class definition
// and CONSTRUCT_MINIMAP_PANEL( "panelname", SORT_ORDER ) in your class constructor
//-----------------------------------------------------------------------------
#define DECLARE_MINIMAP_PANEL( )	DECLARE_METACLASS_PANEL( m_MinimapTrace )
#define CONSTRUCT_MINIMAP_PANEL( _name, _sortorder )	\
	MinimapInitData_t _traceInit( this );				\
	CONSTRUCT_METACLASS_PANEL( m_MinimapTrace, _name, CMinimapPanel::MinimapRootPanel(), _sortorder, &_traceInit )
#define DESTRUCT_MINIMAP_PANEL( )		\
	DESTRUCT_METACLASS_PANEL( m_MinimapTrace )
#define IS_MINIMAP_PANEL_DEFINED( )	( m_MinimapTrace.GetPanel() != NULL )

// Kind of a hack; assumes all minimap panels inherit from CMinimapTracePanel, but that's reasonable..
#define SET_MINIMAP_PANEL_VISIBILITY( _visible )		\
	do													\
	{													\
		if (m_MinimapTrace.GetPanel())					\
		{												\
			static_cast<CMinimapTracePanel*>(m_MinimapTrace.GetPanel())->SetTraceVisibility( _visible );	\
		}												\
	} while (0)

#endif // HUD_MINIMAP_H