318 lines
8.5 KiB
C++
318 lines
8.5 KiB
C++
/*
|
|
radar.cpp - Radar
|
|
Copyright (C) 2016 a1batross
|
|
|
|
This program is free software; you can redistribute it and/or modify it
|
|
under the terms of the GNU General Public License as published by the
|
|
Free Software Foundation; either version 2 of the License, or (at
|
|
your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful, but
|
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software Foundation,
|
|
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
|
|
In addition, as a special exception, the author gives permission to
|
|
link the code of this program with the Half-Life Game Engine ("HL
|
|
Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
|
L.L.C ("Valve"). You must obey the GNU General Public License in all
|
|
respects for all of the code used other than the HL Engine and MODs
|
|
from Valve. If you modify this file, you may extend this exception
|
|
to your version of the file, but you are not obligated to do so. If
|
|
you do not wish to do so, delete this exception statement from your
|
|
version.
|
|
*/
|
|
|
|
#include "hud.h"
|
|
#include "cl_util.h"
|
|
#include "parsemsg.h"
|
|
|
|
#ifndef M_PI
|
|
#define M_PI 3.14159265358979323846 // matches value in gcc v2 math.h
|
|
#endif
|
|
|
|
DECLARE_COMMAND( m_Radar, ShowRadar )
|
|
DECLARE_COMMAND( m_Radar, HideRadar )
|
|
|
|
DECLARE_MESSAGE( m_Radar, Radar )
|
|
|
|
int CHudRadar::Init()
|
|
{
|
|
HOOK_MESSAGE( Radar );
|
|
HOOK_COMMAND( "drawradar", ShowRadar );
|
|
HOOK_COMMAND( "hideradar", HideRadar );
|
|
|
|
m_iFlags = HUD_ACTIVE;
|
|
|
|
cl_radartype = CVAR_CREATE( "cl_radartype", "0", FCVAR_ARCHIVE );
|
|
|
|
gHUD.AddHudElem( this );
|
|
return 1;
|
|
}
|
|
|
|
void CHudRadar::Reset()
|
|
{
|
|
// make radar don't draw old players after new map
|
|
for( int i = 0; i < 34; i++ )
|
|
{
|
|
g_PlayerExtraInfo[i].radarflashon = false;
|
|
|
|
if( i <= MAX_HOSTAGES ) g_HostageInfo[i].radarflashon = false;
|
|
}
|
|
}
|
|
|
|
int CHudRadar::VidInit(void)
|
|
{
|
|
m_hRadar.SetSpriteByName( "radar" );
|
|
m_hRadarOpaque.SetSpriteByName( "radaropaque" );
|
|
return 1;
|
|
}
|
|
|
|
void CHudRadar::UserCmd_HideRadar()
|
|
{
|
|
m_iFlags = 0;
|
|
}
|
|
|
|
void CHudRadar::UserCmd_ShowRadar()
|
|
{
|
|
m_iFlags = HUD_ACTIVE;
|
|
}
|
|
|
|
int CHudRadar::MsgFunc_Radar(const char *pszName, int iSize, void *pbuf )
|
|
{
|
|
BEGIN_READ( pbuf, iSize );
|
|
|
|
int index = READ_BYTE();
|
|
g_PlayerExtraInfo[index].origin.x = READ_COORD();
|
|
g_PlayerExtraInfo[index].origin.y = READ_COORD();
|
|
g_PlayerExtraInfo[index].origin.z = READ_COORD();
|
|
return 1;
|
|
}
|
|
|
|
int CHudRadar::Draw(float flTime)
|
|
{
|
|
if ( (gHUD.m_iHideHUDDisplay & HIDEHUD_HEALTH) ||
|
|
gEngfuncs.IsSpectateOnly() ||
|
|
!(gHUD.m_iWeaponBits & (1<<(WEAPON_SUIT))) ||
|
|
gHUD.m_fPlayerDead )
|
|
return 1;
|
|
|
|
int iTeamNumber = g_PlayerExtraInfo[ gHUD.m_Scoreboard.m_iPlayerNum ].teamnumber;
|
|
int r, g, b;
|
|
|
|
if( cl_radartype->value )
|
|
{
|
|
SPR_Set(m_hRadarOpaque.spr, 200, 200, 200);
|
|
SPR_DrawHoles(0, 0, 0, &m_hRadarOpaque.rect);
|
|
}
|
|
else
|
|
{
|
|
SPR_Set( m_hRadar.spr, 25, 75, 25 );
|
|
SPR_DrawAdditive( 0, 0, 0, &m_hRadarOpaque.rect );
|
|
}
|
|
|
|
for(int i = 0; i < 33; i++)
|
|
{
|
|
// skip local player and dead players
|
|
if( i == gHUD.m_Scoreboard.m_iPlayerNum || g_PlayerExtraInfo[i].dead)
|
|
continue;
|
|
|
|
// skip non-teammates
|
|
if( g_PlayerExtraInfo[i].teamnumber != iTeamNumber )
|
|
continue;
|
|
|
|
// player with C4 must be red
|
|
if( g_PlayerExtraInfo[i].has_c4 )
|
|
{
|
|
DrawUtils::UnpackRGB( r, g, b, RGB_REDISH );
|
|
}
|
|
else
|
|
{
|
|
// white
|
|
DrawUtils::UnpackRGB( r, g, b, RGB_WHITE );
|
|
}
|
|
|
|
// calc radar position
|
|
Vector2D pos = WorldToRadar(gHUD.m_vecOrigin, g_PlayerExtraInfo[i].origin, gHUD.m_vecAngles);
|
|
|
|
|
|
float zdiff = gHUD.m_vecOrigin.z - g_PlayerExtraInfo[i].origin.z;
|
|
if( !g_PlayerExtraInfo[i].radarflashon )
|
|
{
|
|
if( zdiff < 20 && zdiff > -20 )
|
|
{
|
|
DrawRadarDot( pos.x, pos.y, 4, r, g, b, 255 );
|
|
}
|
|
else if( gHUD.m_vecOrigin.z > g_PlayerExtraInfo[i].origin.z )
|
|
{
|
|
DrawFlippedT( pos.x, pos.y, 2, r, g, b, 255);
|
|
}
|
|
else
|
|
{
|
|
DrawT( pos.x, pos.y, 2, r, g, b, 255 );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// radar flashing
|
|
if( g_PlayerExtraInfo[i].radarflashes )
|
|
{
|
|
float timer = (flTime - g_PlayerExtraInfo[i].radarflash);
|
|
if( timer > 0.5f )
|
|
{
|
|
g_PlayerExtraInfo[i].nextflash = !g_PlayerExtraInfo[i].nextflash;
|
|
g_PlayerExtraInfo[i].radarflash = flTime;
|
|
g_PlayerExtraInfo[i].radarflashes--;
|
|
}
|
|
}
|
|
else g_PlayerExtraInfo[i].radarflashon = 0;
|
|
|
|
if( g_PlayerExtraInfo[i].nextflash )
|
|
{
|
|
if( zdiff < 20 && zdiff > -20 )
|
|
{
|
|
DrawRadarDot( pos.x, pos.y, 4, r, g, b, 255 );
|
|
}
|
|
else if( gHUD.m_vecOrigin.z > g_PlayerExtraInfo[i].origin.z )
|
|
{
|
|
DrawFlippedT( pos.x, pos.y, 2, r, g, b, 255);
|
|
}
|
|
else
|
|
{
|
|
DrawT( pos.x, pos.y, 2, r, g, b, 255 );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Terrorist specific code( C4 Bomb )
|
|
if( g_PlayerExtraInfo[gHUD.m_Scoreboard.m_iPlayerNum].teamnumber == TEAM_TERRORIST && g_PlayerExtraInfo[33].radarflashon)
|
|
{
|
|
Vector2D pos = WorldToRadar(gHUD.m_vecOrigin, g_PlayerExtraInfo[33].origin, gHUD.m_vecAngles);
|
|
if( g_PlayerExtraInfo[33].radarflashes )
|
|
{
|
|
float timer = (flTime - g_PlayerExtraInfo[33].radarflash);
|
|
if( timer > 0.5f )
|
|
{
|
|
g_PlayerExtraInfo[33].nextflash = !g_PlayerExtraInfo[33].nextflash;
|
|
g_PlayerExtraInfo[33].radarflash = flTime;
|
|
g_PlayerExtraInfo[33].radarflashes--;
|
|
}
|
|
}
|
|
else g_PlayerExtraInfo[33].radarflashon = 0;
|
|
if( g_PlayerExtraInfo[33].nextflash )
|
|
{
|
|
if( g_PlayerExtraInfo[33].playerclass )
|
|
{
|
|
DrawCross( pos.x, pos.y, 2, 255, 0, 0, 255);
|
|
}
|
|
else
|
|
{
|
|
DrawRadarDot( pos.x, pos.y, 4, 255, 0, 0, 255 );
|
|
}
|
|
}
|
|
}
|
|
|
|
// Counter-Terrorist specific code( hostages )
|
|
if( g_PlayerExtraInfo[gHUD.m_Scoreboard.m_iPlayerNum].teamnumber == TEAM_CT )
|
|
{
|
|
// draw hostages for CT
|
|
for( int i = 0; i < MAX_HOSTAGES; i++ )
|
|
{
|
|
if( !g_HostageInfo[i].radarflashon || g_HostageInfo[i].dead )
|
|
continue;
|
|
|
|
Vector2D pos = WorldToRadar(gHUD.m_vecOrigin, g_HostageInfo[i].origin, gHUD.m_vecAngles);
|
|
if( g_HostageInfo[i].radarflashes )
|
|
{
|
|
float timer = (flTime - g_HostageInfo[i].radarflash);
|
|
if( timer > 0.5f )
|
|
{
|
|
g_HostageInfo[i].nextflash = !g_HostageInfo[i].nextflash;
|
|
g_HostageInfo[i].radarflash = flTime;
|
|
g_HostageInfo[i].radarflashes--;
|
|
}
|
|
}
|
|
else g_HostageInfo[i].radarflashon = 0;
|
|
if( g_HostageInfo[i].nextflash )
|
|
{
|
|
DrawRadarDot( pos.x, pos.y, 4, 255, 0, 0, 255 );
|
|
}
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void CHudRadar::DrawPlayerLocation()
|
|
{
|
|
DrawUtils::DrawConsoleString( 30, 30, g_PlayerExtraInfo[gHUD.m_Scoreboard.m_iPlayerNum].location );
|
|
}
|
|
|
|
void CHudRadar::DrawRadarDot(int x, int y, int size, int r, int g, int b, int a)
|
|
{
|
|
FillRGBA(62.5f + x - size/2.0f, 62.5f + y - size/2.0f, size, size, r, g, b, a);
|
|
}
|
|
|
|
void CHudRadar::DrawCross(int x, int y, int size, int r, int g, int b, int a)
|
|
{
|
|
FillRGBA(62.5f + x, 62.5f + y, size, size, r, g, b, a);
|
|
FillRGBA(62.5f + x - size, 62.5f + y - size, size, size, r, g, b, a);
|
|
FillRGBA(62.5f + x - size, 62.5f + y + size, size, size, r, g, b, a);
|
|
FillRGBA(62.5f + x + size, 62.5f + y - size, size, size, r, g, b, a);
|
|
FillRGBA(62.5f + x + size, 62.5f + y + size, size, size, r, g, b, a);
|
|
|
|
}
|
|
|
|
void CHudRadar::DrawT(int x, int y, int size, int r, int g, int b, int a)
|
|
{
|
|
FillRGBA( 62.5f + x - size, 62.5 + y - size, 3*size, size, r, g, b, a);
|
|
FillRGBA( 62.5f + x, 62.5 + y, size, 2*size, r, g, b, a);
|
|
}
|
|
|
|
void CHudRadar::DrawFlippedT(int x, int y, int size, int r, int g, int b, int a)
|
|
{
|
|
FillRGBA( 62.5f + x, 62.5 + y - size, size, 2*size, r, g, b, a);
|
|
FillRGBA( 62.5f + x - size, 62.5 + y + size, 3*size, size, r, g, b, a);
|
|
}
|
|
|
|
Vector2D CHudRadar::WorldToRadar(const Vector vPlayerOrigin, const Vector vObjectOrigin, const Vector vAngles )
|
|
{
|
|
Vector2D diff = vObjectOrigin.Make2D() - vPlayerOrigin.Make2D();
|
|
|
|
// Supply epsilon values to avoid divide-by-zero
|
|
if(diff.x == 0)
|
|
diff.x = 0.00001f;
|
|
if(diff.y == 0)
|
|
diff.y = 0.00001f;
|
|
|
|
int iMaxRadius = (m_hRadar.rect.right - m_hRadar.rect.left) / 2.0f;
|
|
|
|
float flOffset = atan(diff.y / diff.x) * 180.0f / M_PI;
|
|
|
|
if ((diff.x < 0) && (diff.y >= 0))
|
|
flOffset += 180;
|
|
else if ((diff.x < 0) && (diff.y < 0))
|
|
flOffset += 180;
|
|
else if ((diff.x >= 0) && (diff.y < 0))
|
|
flOffset += 360;
|
|
|
|
// this magic 32.0f just scales position on radar
|
|
float iRadius = -diff.Length() / 32.0f;
|
|
if( -iRadius > iMaxRadius)
|
|
iRadius = -iMaxRadius;
|
|
|
|
flOffset = (vAngles.y - flOffset) * M_PI / 180.0f;
|
|
|
|
// transform origin difference to radar source
|
|
Vector2D new_diff;
|
|
new_diff.x = -iRadius * sin(flOffset);
|
|
new_diff.y = iRadius * cos(flOffset);
|
|
|
|
return new_diff;
|
|
}
|