mirror of
https://github.com/nillerusr/source-engine.git
synced 2025-03-13 06:01:53 +00:00
1735 lines
56 KiB
C++
1735 lines
56 KiB
C++
|
|
#include "cbase.h"
|
|
#include "hud.h"
|
|
#include "hud_macros.h"
|
|
#include "view.h"
|
|
//#include "kbutton.h"
|
|
#include "input.h"
|
|
#include "iclientmode.h"
|
|
|
|
#define PAIN_NAME "sprites/%d_pain.vmt"
|
|
|
|
#include <KeyValues.h>
|
|
#include <vgui/ISurface.h>
|
|
#include <vgui/ISystem.h>
|
|
#include <vgui_controls/AnimationController.h>
|
|
#include <vgui_controls/ImagePanel.h>
|
|
|
|
#include <vgui/ILocalize.h>
|
|
|
|
using namespace vgui;
|
|
|
|
#include "filesystem.h"
|
|
#include <keyvalues.h>
|
|
#include "asw_hud_minimap.h"
|
|
#include "c_asw_player.h"
|
|
#include "c_asw_marine.h"
|
|
#include "asw_marine_profile.h"
|
|
#include "c_asw_marine_resource.h"
|
|
#include "c_asw_game_resource.h"
|
|
#include "c_asw_scanner_info.h"
|
|
#include "vgui/ISurface.h"
|
|
#include <vgui/IInput.h>
|
|
#include "fx.h"
|
|
#include "tier0/vprof.h"
|
|
#include "asw_gamerules.h"
|
|
#include "ScanLinePanel.h"
|
|
#include "c_asw_scanner_noise.h"
|
|
#include "SoftLine.h"
|
|
#include "c_asw_objective.h"
|
|
|
|
#include "ConVar.h"
|
|
|
|
// memdbgon must be the last include file in a .cpp file!!!
|
|
#include "tier0/memdbgon.h"
|
|
|
|
extern ConVar asw_draw_hud;
|
|
extern ConVar asw_hud_alpha;
|
|
extern ConVar asw_hud_scale;
|
|
ConVar asw_map_range("asw_map_range", "1200", FCVAR_CHEAT, "Range in world units of the minimap");
|
|
ConVar asw_scanner_ring_scale("asw_scanner_ring_scale", "1.0f", FCVAR_CHEAT, "Overdraw in the scanner ring size from the blip boundary");
|
|
ConVar asw_scanner_pitch_change("asw_scanner_pitch_change", "0.2f", FCVAR_NONE, "Change in pitch (from 0 to 1.0) of scanner blips depending on distance from the tech marine");
|
|
ConVar asw_scanner_pitch_base("asw_scanner_pitch_base", "1.2f", FCVAR_NONE, "Starting pitch");
|
|
ConVar asw_scanner_warning_volume("asw_scanner_warning_volume", "0.3f", FCVAR_NONE, "Volume of scanner warning beeps");
|
|
ConVar asw_scanner_idle_volume("asw_scanner_idle_volume", "0.4f", FCVAR_NONE, "Volume of scanner idle loop");
|
|
ConVar asw_scanner_scanline_alpha("asw_scanner_scanline_alpha", "80", 0, "Alpha of scanlines on the scanner");
|
|
ConVar asw_scanner_scanline_double("asw_scanner_scanline_double", "0", 0, "Whether scanlines should be single or double pixel");
|
|
ConVar asw_scanner_interlace_alpha("asw_scanner_interlace_alpha", "0", 0, "Alpha of interlace effect on the scanner");
|
|
ConVar asw_scanner_noise_alpha("asw_scanner_noise_alpha", "0", 0, "Alpha of noise effect on the scanner");
|
|
ConVar asw_scanner_idle_sound("asw_scanner_idle_sound", "3", 0, "Which scanner idle sound is used (from 1 to 4)");
|
|
ConVar asw_scanner_warning_sound("asw_scanner_warning_sound", "1", 0, "Which scanner warning sound is used (from 1 to 3)");
|
|
ConVar asw_debug_scanner_sound("asw_debug_scanner_sound", "0", FCVAR_CHEAT, "Prints debug output on scanner pulses");
|
|
ConVar asw_minimap_clicks("asw_minimap_clicks", "1", FCVAR_ARCHIVE, "Is enabled, clicking on the minimap will draw on it. If disabled, clicking there will fire your weapon as normal");
|
|
ConVar asw_scanner_background("asw_scanner_background", "1", FCVAR_NONE, "Draw black background behind minimap" );
|
|
ConVar asw_scanner_classic("asw_scanner_classic", "0", FCVAR_NONE, "Scanner has white blips, is always pinging." );
|
|
|
|
// was 0.75f..
|
|
#define ASW_SCREENSHOT_SCALE 1.0f
|
|
|
|
MapLine::MapLine()
|
|
{
|
|
worldpos.Init(0,0);
|
|
player_index = 0;
|
|
linkpos.Init(0,0);
|
|
created_time = 0;
|
|
bSetLinkBlipCentre = false;
|
|
bSetBlipCentre = false;
|
|
blipcentre.Init(0,0);
|
|
linkblipcentre.Init(0,0);
|
|
bLink = false;
|
|
}
|
|
|
|
class CASWHudMinimap;
|
|
|
|
class CASWHudMinimapLinePanel : public vgui::Panel
|
|
{
|
|
DECLARE_CLASS_SIMPLE( CASWHudMinimapLinePanel, vgui::Panel );
|
|
public:
|
|
CASWHudMinimapLinePanel(Panel *parent, const char *panelName, CASWHudMinimap* pMap);
|
|
void TextureToLinePanel(CASWHudMinimap* pMap, const Vector2D &blip_centre, float &x, float &y);
|
|
virtual void Paint();
|
|
|
|
void PaintFollowLine(C_BaseEntity *pMarine, C_BaseEntity *pTarget);
|
|
void PaintFollowLines();
|
|
virtual void PaintScannerRing();
|
|
|
|
CPanelAnimationVarAliasType( int, m_nScannerRingTexture, "ScannerRingTexture", "vgui/swarm/HUD/ScannerRing", "textureid" );
|
|
|
|
CASWHudMinimap* m_pMap;
|
|
};
|
|
|
|
class CASWHudMinimapFramePanel : public vgui::Panel
|
|
{
|
|
DECLARE_CLASS_SIMPLE( CASWHudMinimapFramePanel, vgui::Panel );
|
|
public:
|
|
CASWHudMinimapFramePanel(Panel *parent, const char *panelName);
|
|
virtual void Paint();
|
|
};
|
|
|
|
|
|
DECLARE_HUDELEMENT( CASWHudMinimap );
|
|
|
|
CASWHudMinimapLinePanel::CASWHudMinimapLinePanel(Panel *parent, const char *panelName, CASWHudMinimap* pMap) :
|
|
vgui::Panel(parent, panelName),
|
|
m_pMap(pMap)
|
|
{
|
|
|
|
}
|
|
|
|
CASWHudMinimapFramePanel::CASWHudMinimapFramePanel(Panel *parent, const char *panelName) :
|
|
vgui::Panel(parent, panelName)
|
|
{
|
|
}
|
|
|
|
void MsgFunc_ASWMapLine(bf_read &msg)
|
|
{
|
|
int linetype = msg.ReadByte();
|
|
int player_index = msg.ReadByte();
|
|
int world_x = msg.ReadLong();
|
|
int world_y = msg.ReadLong();
|
|
|
|
C_ASW_Player *local = C_ASW_Player::GetLocalASWPlayer();
|
|
if ( local )
|
|
{
|
|
// figure out the position of this map line dot
|
|
Vector vecMapLinePos = vec3_origin;
|
|
vecMapLinePos.x = world_x;
|
|
vecMapLinePos.y = world_y;
|
|
|
|
CASWHudMinimap *pMiniMap = GET_HUDELEMENT(CASWHudMinimap);
|
|
if (!pMiniMap)
|
|
return;
|
|
|
|
// make the HUD store it
|
|
MapLine line;
|
|
line.player_index = player_index;
|
|
line.worldpos.x = world_x;
|
|
line.worldpos.y = world_y;
|
|
line.created_time = gpGlobals->curtime;
|
|
if (linetype == 1) // links to a previous
|
|
{
|
|
line.bLink = true;
|
|
}
|
|
else
|
|
{
|
|
if (gpGlobals->curtime > pMiniMap->m_fLastMinimapDrawSound + 5.0f)
|
|
{
|
|
CLocalPlayerFilter filter;
|
|
C_BaseEntity::EmitSound( filter, -1, "ASWScanner.Drawing" );
|
|
pMiniMap->m_fLastMinimapDrawSound = gpGlobals->curtime;
|
|
}
|
|
}
|
|
pMiniMap->m_MapLines.AddToTail(line);
|
|
}
|
|
}
|
|
|
|
//////////
|
|
// CASWMap
|
|
//////////
|
|
|
|
// converts a world coord into map texture coords (0->1023)
|
|
Vector2D CASWMap::WorldToMapTexture( const Vector &worldpos )
|
|
{
|
|
if ( !m_pMinimap )
|
|
{
|
|
m_pMinimap = GET_HUDELEMENT( CASWHudMinimap );
|
|
|
|
if ( !m_pMinimap )
|
|
{
|
|
return vec2_origin;
|
|
}
|
|
}
|
|
|
|
Vector2D offset( worldpos.x - m_pMinimap->m_MapOrigin.x, worldpos.y - m_pMinimap->m_MapOrigin.y);
|
|
|
|
offset.x /= m_pMinimap->m_fMapScale;
|
|
offset.y /= -m_pMinimap->m_fMapScale;
|
|
|
|
offset.x -= 128; // I'd be lying if I knew why this needs to be here
|
|
|
|
return offset;
|
|
}
|
|
|
|
void CASWMap::AddBlip( const MapBlip_t &blip )
|
|
{
|
|
m_MapBlips.AddToTail( blip );
|
|
}
|
|
|
|
void CASWMap::ClearBlips( void )
|
|
{
|
|
m_MapBlips.RemoveAll();
|
|
}
|
|
|
|
void CASWMap::PaintMarineBlips()
|
|
{
|
|
C_ASW_Game_Resource *pGameResource = ASWGameResource();
|
|
if ( pGameResource )
|
|
{
|
|
// paint the blips
|
|
for ( int i= 0; i < ASW_MAX_MARINE_RESOURCES; i++ )
|
|
{
|
|
C_ASW_Marine_Resource *pMR = pGameResource->GetMarineResource(i);
|
|
if ( pMR )
|
|
{
|
|
C_ASW_Marine *pMarine = pMR->GetMarineEntity();
|
|
if ( pMarine && pMarine->GetHealth() > 0 )
|
|
{
|
|
PaintWorldBlip( pMarine->GetAbsOrigin(), pMarine->GetBlipStrength(), Color(0,192,0,255) );
|
|
PaintWorldFacingArc(pMarine->GetAbsOrigin(), pMarine->ASWEyeAngles().y, Color(0,192,0,255 - 127.0f * pMarine->GetBlipStrength()));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void CASWMap::PaintExtraBlips()
|
|
{
|
|
for ( int i= 0; i < m_MapBlips.Count(); i++ )
|
|
{
|
|
PaintWorldBlip( m_MapBlips[ i ].vWorldPos, sinf( gpGlobals->curtime * 8.0f ) * 0.25 + 0.25f, m_MapBlips[ i ].rgbaColor, m_MapBlips[ i ].nTextureType );
|
|
}
|
|
}
|
|
|
|
void CASWMap::PaintWorldBlip(const Vector &worldpos, float fBlipStrength, Color BlipColor, MapBlipTexture_t nBlipTexture /*= MAP_BLIP_TEXTURE_NORMAL*/ )
|
|
{
|
|
int nStrengthIndex = clamp<int>( fBlipStrength * 7, 0, 7 );
|
|
|
|
if ( nStrengthIndex >= 7 || !m_nBlipTexture[ nStrengthIndex ] )
|
|
return;
|
|
|
|
Vector2D blip_centre = WorldToMapTexture(worldpos); // convert from world coords to the pixel on the 0->1023 map texture
|
|
//blip_centre = blip_centre - m_MapCentre + m_MapCentreInPanel;
|
|
blip_centre = MapTextureToPanel(blip_centre); // convert from the map texture to its position on the panel
|
|
|
|
Vector2D vMapCornerInPanel = GetMapCornerInPanel();
|
|
|
|
// don't draw out of bounds
|
|
if ( blip_centre.x < vMapCornerInPanel.x || blip_centre.x > vMapCornerInPanel.x + GetMapSize() ||
|
|
blip_centre.y < vMapCornerInPanel.y || blip_centre.y > vMapCornerInPanel.y + GetMapSize() )
|
|
return;
|
|
|
|
surface()->DrawSetColor( BlipColor );
|
|
|
|
int nTextureID;
|
|
int iBlipSize = GetBlipSize();
|
|
|
|
switch ( nBlipTexture )
|
|
{
|
|
case MAP_BLIP_TEXTURE_USABLE:
|
|
nTextureID = m_nTriBlipTexture[ nStrengthIndex ];
|
|
break;
|
|
|
|
case MAP_BLIP_TEXTURE_DEATH:
|
|
nTextureID = m_nBlipTextureDeath;
|
|
iBlipSize *= 1.5;
|
|
break;
|
|
|
|
case MAP_BLIP_TEXTURE_NORMAL:
|
|
default:
|
|
nTextureID = m_nBlipTexture[ nStrengthIndex ];
|
|
break;
|
|
}
|
|
|
|
surface()->DrawSetTexture( nTextureID );
|
|
|
|
float Dest1X = blip_centre.x - (iBlipSize * 0.5f);
|
|
float Dest1Y = blip_centre.y - (iBlipSize * 0.5f);
|
|
float Dest2X = Dest1X + iBlipSize;
|
|
float Dest2Y = Dest1Y + iBlipSize;
|
|
|
|
Vertex_t points[4] =
|
|
{
|
|
Vertex_t( Vector2D(Dest1X, Dest1Y), Vector2D(0,0) ),
|
|
Vertex_t( Vector2D(Dest2X, Dest1Y), Vector2D(1,0) ),
|
|
Vertex_t( Vector2D(Dest2X, Dest2Y), Vector2D(1,1) ),
|
|
Vertex_t( Vector2D(Dest1X, Dest2Y), Vector2D(0,1) )
|
|
};
|
|
surface()->DrawTexturedPolygon( 4, points );
|
|
}
|
|
|
|
void CASWMap::PaintWorldFacingArc(const Vector &worldpos, float fFacingYaw, Color FacingColor)
|
|
{
|
|
if ( GetFacingArcTexture() == -1)
|
|
return;
|
|
|
|
Vector2D blip_centre = WorldToMapTexture(worldpos); // convert from world coords to the pixel on the 0->1023 map texture
|
|
blip_centre = MapTextureToPanel(blip_centre); // convert from the map texture to its position on the panel
|
|
|
|
Vector2D vMapCornerInPanel = GetMapCornerInPanel();
|
|
|
|
// don't draw out of bounds
|
|
if ( blip_centre.x < vMapCornerInPanel.x || blip_centre.y < vMapCornerInPanel.y ||
|
|
blip_centre.x > vMapCornerInPanel.x + GetMapSize() || blip_centre.y > vMapCornerInPanel.y + GetMapSize() )
|
|
return;
|
|
|
|
int iFacingSize = GetArcSize();
|
|
|
|
// set up a square to the right
|
|
int xoffset = -2; // temp? to make the arc look nice next to blips..
|
|
int yoffset = 1;
|
|
Vector vecCornerTL(xoffset, iFacingSize * -0.5f + yoffset, 0);
|
|
Vector vecCornerTR(iFacingSize + xoffset, iFacingSize * -0.5f+ yoffset, 0);
|
|
Vector vecCornerBR(iFacingSize + xoffset, iFacingSize * 0.5f+ yoffset, 0);
|
|
Vector vecCornerBL(xoffset, iFacingSize * 0.5f+ yoffset, 0);
|
|
Vector vecCornerTL_rotated, vecCornerTR_rotated, vecCornerBL_rotated, vecCornerBR_rotated;
|
|
|
|
// rotate it by our facing yaw
|
|
QAngle angFacing(0, -fFacingYaw, 0);
|
|
VectorRotate(vecCornerTL, angFacing, vecCornerTL_rotated);
|
|
VectorRotate(vecCornerTR, angFacing, vecCornerTR_rotated);
|
|
VectorRotate(vecCornerBR, angFacing, vecCornerBR_rotated);
|
|
VectorRotate(vecCornerBL, angFacing, vecCornerBL_rotated);
|
|
|
|
surface()->DrawSetColor(FacingColor);
|
|
surface()->DrawSetTexture( GetFacingArcTexture() );
|
|
//surface()->DrawTexturedRect(Dest1X,Dest1Y,Dest2X,Dest2Y);
|
|
Vertex_t points[4] =
|
|
{
|
|
Vertex_t( Vector2D(blip_centre.x + vecCornerTL_rotated.x, blip_centre.y + vecCornerTL_rotated.y), Vector2D(0,0) ),
|
|
Vertex_t( Vector2D(blip_centre.x + vecCornerTR_rotated.x, blip_centre.y + vecCornerTR_rotated.y), Vector2D(1,0) ),
|
|
Vertex_t( Vector2D(blip_centre.x + vecCornerBR_rotated.x, blip_centre.y + vecCornerBR_rotated.y), Vector2D(1,1) ),
|
|
Vertex_t( Vector2D(blip_centre.x + vecCornerBL_rotated.x, blip_centre.y + vecCornerBL_rotated.y), Vector2D(0,1) )
|
|
};
|
|
surface()->DrawTexturedPolygon( 4, points );
|
|
}
|
|
|
|
void CASWMap::LoadBlipTextures()
|
|
{
|
|
char buffer[64];
|
|
for (int i=0;i<7;i++)
|
|
{
|
|
m_nBlipTexture[i] = vgui::surface()->CreateNewTextureID();
|
|
Q_snprintf(buffer, sizeof(buffer), "%s%d", "vgui/swarm/HUD/blip", i+1);
|
|
vgui::surface()->DrawSetTextureFile( m_nBlipTexture[i], buffer, true, false);
|
|
|
|
m_nTriBlipTexture[i] = vgui::surface()->CreateNewTextureID();
|
|
Q_snprintf(buffer, sizeof(buffer), "%s%d", "vgui/swarm/HUD/triblip", i+1);
|
|
vgui::surface()->DrawSetTextureFile( m_nTriBlipTexture[i], buffer, true, false);
|
|
}
|
|
|
|
m_nBlipTextureDeath = vgui::surface()->CreateNewTextureID();
|
|
vgui::surface()->DrawSetTextureFile( m_nBlipTextureDeath, "vgui/swarm/Briefing/deadmarine", true, false);
|
|
|
|
m_nBlipTextureFriendlyDamage = m_nBlipTextureKill = m_nBlipTextureHeal = m_nBlipTextureFoundAmmo = m_nBlipTextureNoAmmo = m_nBlipTexture[ 0 ];
|
|
}
|
|
|
|
|
|
CASWHudMinimap::CASWHudMinimap( const char *pElementName ) : CASW_HudElement( pElementName ), CHudNumericDisplay(NULL, "ASWHudMinimap"), CASW_VGUI_Ingame_Panel()
|
|
{
|
|
SetHiddenBits( HIDEHUD_PLAYERDEAD | HIDEHUD_REMOTE_TURRET);
|
|
vgui::HScheme scheme = vgui::scheme()->LoadSchemeFromFile("resource/SwarmSchemeNew.res", "SwarmSchemeNew");
|
|
SetScheme(scheme);
|
|
|
|
m_pLinePanel = new CASWHudMinimapLinePanel(this, "CASWHudMinimapLinePanel", this);
|
|
//m_pFramePanel = new CASWHudMinimapFramePanel(this, "CASWHudMinimapFramePanel");
|
|
|
|
m_nWhiteTexture = vgui::surface()->CreateNewTextureID();
|
|
vgui::surface()->DrawSetTextureFile( m_nWhiteTexture, "vgui/white" , true, false);
|
|
|
|
m_pScanLinePanel = new ScanLinePanel(this, "ScanlinePanel", false);
|
|
m_pInterlacePanel = new vgui::ImagePanel(this, "InterlacePanel");
|
|
m_pNoisePanel = new vgui::ImagePanel(this, "NoisePanel");
|
|
|
|
if ( asw_scanner_background.GetBool() )
|
|
{
|
|
m_pBackdrop = new CASWHudMinimap_Border(GetParent(), "MapBackdrop", this);
|
|
}
|
|
else
|
|
{
|
|
m_pBackdrop = NULL;
|
|
}
|
|
|
|
if (m_pBackdrop)
|
|
{
|
|
m_pBackdrop->SetPaintBackgroundEnabled(true);
|
|
m_pBackdrop->SetPaintBackgroundType(0);
|
|
m_pBackdrop->SetBgColor(Color(0,0,0,asw_hud_alpha.GetInt()));
|
|
MoveToFront();
|
|
}
|
|
m_bHasOverview = false;
|
|
m_szServerName[0] = '\0';
|
|
|
|
Q_snprintf(m_szMissionTitle, sizeof(m_szMissionTitle), "");
|
|
}
|
|
|
|
CASWHudMinimap::~CASWHudMinimap()
|
|
{
|
|
if ( m_MapKeyValues )
|
|
m_MapKeyValues->deleteThis();
|
|
if (m_pLinePanel)
|
|
m_pLinePanel->MarkForDeletion();
|
|
}
|
|
|
|
void CASWHudMinimap::PerformLayout()
|
|
{
|
|
BaseClass::PerformLayout();
|
|
|
|
int wide, tall, x, y;
|
|
GetBounds(x, y, wide, tall);
|
|
int ox, oy;
|
|
GetScaledOffset(ox, oy);
|
|
wide *= asw_hud_scale.GetFloat();
|
|
tall *= asw_hud_scale.GetFloat();
|
|
m_iMapSize = wide * 0.7f;
|
|
m_MapCornerInPanel.x = int(wide - m_iMapSize) + ox;
|
|
m_MapCornerInPanel.y = int(tall - m_iMapSize) + oy;
|
|
int black_border = m_iMapSize * 0.0455f;
|
|
if (m_pBackdrop)
|
|
{
|
|
m_pBackdrop->SetBounds(x + m_MapCornerInPanel.x - black_border, y + m_MapCornerInPanel.y - black_border,
|
|
m_iMapSize + black_border * 2 + 1, m_iMapSize + black_border * 2 + 1);
|
|
m_pBackdrop->SetBgColor(Color(0,0,0,asw_hud_alpha.GetInt()));
|
|
}
|
|
|
|
m_pScanLinePanel->SetBounds(m_MapCornerInPanel.x, m_MapCornerInPanel.y, m_iMapSize, m_iMapSize);
|
|
m_pInterlacePanel->SetBounds(m_MapCornerInPanel.x, m_MapCornerInPanel.y, m_iMapSize, m_iMapSize);
|
|
m_pNoisePanel->SetBounds(m_MapCornerInPanel.x, m_MapCornerInPanel.y, m_iMapSize, m_iMapSize);
|
|
}
|
|
|
|
void CASWHudMinimap::Init()
|
|
{
|
|
gameeventmanager->AddListener(this, "game_newmap", false );
|
|
gameeventmanager->AddListener(this, "server_spawn", false);
|
|
|
|
m_pMinimap = this;
|
|
|
|
m_nMapTextureID = -1;
|
|
m_bHasOverview = false;
|
|
m_MapKeyValues = NULL;
|
|
m_bDrawingMapLines = false;
|
|
|
|
m_MapOrigin = Vector( 0, 0, 0 );
|
|
m_fMapScale = 1.0f;
|
|
m_fLastMapLine = 0;
|
|
m_fLastBlipSpeechTime = -100.0f;
|
|
m_fLastBlipHitTime = 0.0f;
|
|
m_MapCentre = Vector2D( 0, 0 );
|
|
m_MapCentreInPanel = Vector2D( 0, 0 );
|
|
Reset();
|
|
|
|
usermessages->HookMessage( "ASWMapLine", MsgFunc_ASWMapLine );
|
|
}
|
|
|
|
void CASWHudMinimap::Reset()
|
|
{
|
|
SetLabelText(L" ");
|
|
m_bDrawingMapLines = false;
|
|
m_fLastMapLine = 0;
|
|
m_fLastMinimapDrawSound = 0;
|
|
|
|
SetShouldDisplayValue(false);
|
|
}
|
|
|
|
void CASWHudMinimap::VidInit()
|
|
{
|
|
Reset();
|
|
}
|
|
|
|
void CASWHudMinimap::OnThink()
|
|
{
|
|
VPROF_BUDGET( "CASWHudMinimap::OnThink", VPROF_BUDGETGROUP_ASW_CLIENT );
|
|
|
|
if (m_pScanLinePanel)
|
|
{
|
|
m_pScanLinePanel->SetAlpha(asw_scanner_scanline_alpha.GetInt());
|
|
m_pScanLinePanel->m_bDouble = asw_scanner_scanline_double.GetBool();
|
|
}
|
|
if (m_pInterlacePanel)
|
|
{
|
|
m_pInterlacePanel->SetAlpha(asw_scanner_interlace_alpha.GetInt());
|
|
}
|
|
|
|
// remove any map lines that have faded out
|
|
for (int i=0;i<m_MapLines.Count();i++)
|
|
{
|
|
if (gpGlobals->curtime - m_MapLines[i].created_time > MAP_LINE_SOLID_TIME + MAP_LINE_FADE_TIME)
|
|
m_MapLines.Remove(i);
|
|
}
|
|
|
|
C_ASW_Player *local = C_ASW_Player::GetLocalASWPlayer();
|
|
if ( local )
|
|
{
|
|
if (m_bDrawingMapLines && gpGlobals->curtime >= m_fLastMapLine + MAP_LINE_INTERVAL)
|
|
{
|
|
if (IsWithinMapBounds(m_iMouseX,m_iMouseY))
|
|
{
|
|
int ox, oy;
|
|
GetScaledOffset(ox, oy);
|
|
SendMapLine(m_iMouseX + ox,m_iMouseY + oy,false);
|
|
}
|
|
else
|
|
{
|
|
m_bDrawingMapLines = false;
|
|
}
|
|
}
|
|
C_ASW_Marine *marine = local->GetMarine();
|
|
if (marine)
|
|
{
|
|
if (m_pNoisePanel)
|
|
{
|
|
float fScannerNoise = g_pScannerNoise ? g_pScannerNoise->GetScannerNoiseAt(marine->GetAbsOrigin()) : 0;
|
|
m_pNoisePanel->SetAlpha(float(asw_scanner_noise_alpha.GetInt()) * fScannerNoise);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
m_pNoisePanel->SetAlpha(0);
|
|
}
|
|
}
|
|
}
|
|
|
|
void CASWHudMinimap::ApplySchemeSettings(IScheme *pScheme)
|
|
{
|
|
BaseClass::ApplySchemeSettings(pScheme);
|
|
SetBgColor(Color(255,255,255,0));
|
|
|
|
m_pInterlacePanel->SetImage("swarm/Computer/ComputerCameraBlack");
|
|
m_pInterlacePanel->SetShouldScaleImage(true);
|
|
|
|
m_pNoisePanel->SetImage("swarm/Computer/TVNoise");
|
|
m_pNoisePanel->SetShouldScaleImage(true);
|
|
}
|
|
|
|
void CASWHudMinimapFramePanel::Paint()
|
|
{
|
|
VPROF_BUDGET( "CASWHudMinimapFramePanel::Paint", VPROF_BUDGETGROUP_ASW_CLIENT );
|
|
if (ASWGameRules())
|
|
{
|
|
if (ASWGameRules()->IsIntroMap() || ASWGameRules()->IsOutroMap())
|
|
return;
|
|
}
|
|
CASWHudMinimap *m_pMap = dynamic_cast<CASWHudMinimap*>(GetParent());
|
|
if ( !m_pMap || !asw_draw_hud.GetBool() )
|
|
return;
|
|
|
|
int x, y, wide, tall;
|
|
m_pMap->GetBounds(x,y,wide,tall);
|
|
wide *= asw_hud_scale.GetFloat();
|
|
tall *= asw_hud_scale.GetFloat();
|
|
int ox, oy;
|
|
m_pMap->GetScaledOffset(ox, oy);
|
|
SetPos(ox,oy);
|
|
SetSize(wide, tall);
|
|
|
|
//if ( m_pMap->m_nFrameTexture == -1 )
|
|
//return;
|
|
|
|
//surface()->DrawSetColor(m_pMap->GetBgColor());
|
|
//surface()->DrawSetTexture(m_pMap->m_nFrameTexture);
|
|
//surface()->DrawTexturedRect(0, 0, wide, tall);
|
|
}
|
|
|
|
void CASWHudMinimap::GetScaledOffset(int &ox, int &oy)
|
|
{
|
|
int wide, tall;
|
|
GetSize(wide,tall);
|
|
int scaled_wide = wide * asw_hud_scale.GetFloat();
|
|
int scaled_tall = tall * asw_hud_scale.GetFloat();
|
|
|
|
ox = wide - scaled_wide;
|
|
oy = tall - scaled_tall;
|
|
}
|
|
|
|
void CASWHudMinimap::PaintMapSection()
|
|
{
|
|
int wide, tall;
|
|
GetSize(wide,tall);
|
|
wide *= asw_hud_scale.GetFloat();
|
|
tall *= asw_hud_scale.GetFloat();
|
|
|
|
int ox, oy;
|
|
GetScaledOffset(ox, oy);
|
|
m_iMapSize = wide * 0.7f;
|
|
m_MapCornerInPanel.x = int(wide - m_iMapSize) + ox;
|
|
m_MapCornerInPanel.y = int(tall - m_iMapSize) + oy;
|
|
m_MapCentreInPanel.x = m_MapCornerInPanel.x + m_iMapSize * 0.5f;
|
|
m_MapCentreInPanel.y = m_MapCornerInPanel.y + m_iMapSize * 0.5f;
|
|
|
|
m_pLinePanel->SetBounds(m_MapCornerInPanel.x, m_MapCornerInPanel.y,
|
|
m_MapCornerInPanel.x + m_iMapSize, m_MapCornerInPanel.y + m_iMapSize);
|
|
|
|
C_ASW_Player *local = C_ASW_Player::GetLocalASWPlayer();
|
|
if ( local )
|
|
{
|
|
C_ASW_Marine *marine = local->GetMarine();
|
|
if (marine)
|
|
{
|
|
m_MapCentre = WorldToMapTexture(marine->GetAbsOrigin());
|
|
//Msg("Centering minimap at %f,%f\n", m_MapCentre.x, m_MapCentre.y);
|
|
|
|
if ( m_nMapTextureID == -1 )
|
|
return;
|
|
|
|
// source should be a fixed number of world units around the centre
|
|
float source_size = asw_map_range.GetFloat() * ASW_SCREENSHOT_SCALE / m_fMapScale;
|
|
|
|
int map_left = m_MapCornerInPanel.x;
|
|
int map_right = wide + ox;
|
|
int map_top = m_MapCornerInPanel.y;
|
|
int map_bottom = tall + oy;
|
|
|
|
if (m_bHasOverview) // draw a section of the minimap
|
|
{
|
|
float Source1X = m_MapCentre.x - source_size;
|
|
float Source1Y = m_MapCentre.y - source_size;
|
|
float Source2X = m_MapCentre.x + source_size;
|
|
float Source2Y = m_MapCentre.y + source_size;
|
|
// if we're off an edge of the map texture, pull in our draw coords so we don't get stretching
|
|
if (Source1X < 0)
|
|
{
|
|
map_left -= (Source1X / source_size) * (m_iMapSize * 0.5f);
|
|
}
|
|
if (Source2X > 1023)
|
|
{
|
|
map_right -= ((Source2X - 1023) / source_size) * (m_iMapSize * 0.5f);
|
|
}
|
|
if (Source1Y < 0)
|
|
{
|
|
map_top -= (Source1Y / source_size) * (m_iMapSize * 0.5f);
|
|
}
|
|
if (Source2Y > 1023)
|
|
{
|
|
map_bottom -= ((Source2Y - 1023) / source_size) * (m_iMapSize * 0.5f);
|
|
}
|
|
|
|
// clamp uvs
|
|
Source1X = MAX(0, Source1X);
|
|
Source1Y = MAX(0, Source1Y);
|
|
Source2X = MIN(1024, Source2X);
|
|
Source2Y = MIN(1024, Source2Y);
|
|
|
|
surface()->DrawSetColor(Color(255,255,255,255));
|
|
surface()->DrawSetTexture(m_nMapTextureID);
|
|
|
|
Vertex_t points[4] =
|
|
{
|
|
Vertex_t( Vector2D(map_left, map_top), Vector2D(Source1X/1024.0f,Source1Y/1024.0f) ),
|
|
Vertex_t( Vector2D(map_right, map_top), Vector2D(Source2X/1024.0f,Source1Y/1024.0f) ),
|
|
Vertex_t( Vector2D(map_right, map_bottom), Vector2D(Source2X/1024.0f,Source2Y/1024.0f) ),
|
|
Vertex_t( Vector2D(map_left, map_bottom), Vector2D(Source1X/1024.0f,Source2Y/1024.0f) )
|
|
};
|
|
surface()->DrawTexturedPolygon( 4, points );
|
|
}
|
|
else
|
|
{
|
|
// no overview, we're just drawing our scanner texture
|
|
surface()->DrawSetColor(Color(255,255,255,255));
|
|
surface()->DrawSetTexture(m_nMapTextureID);
|
|
|
|
Vertex_t points[4] =
|
|
{
|
|
Vertex_t( Vector2D(map_left, map_top), Vector2D(0,0) ),
|
|
Vertex_t( Vector2D(map_right, map_top), Vector2D(1,0) ),
|
|
Vertex_t( Vector2D(map_right, map_bottom), Vector2D(1,1) ),
|
|
Vertex_t( Vector2D(map_left, map_bottom), Vector2D(0,1) )
|
|
};
|
|
surface()->DrawTexturedPolygon( 4, points );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void CASWHudMinimap::Paint()
|
|
{
|
|
VPROF_BUDGET( "CASWHudMinimap::Paint", VPROF_BUDGETGROUP_ASW_CLIENT );
|
|
|
|
BaseClass::Paint();
|
|
PaintMapSection();
|
|
|
|
PaintObjectiveMarkers();
|
|
|
|
if (ASWGameRules() && ASWGameRules()->GetGameState() == ASW_GS_INGAME)
|
|
{
|
|
// hack to make our child panel draw the follow lines underneath the marine blips painted by this panel
|
|
if (m_pLinePanel)
|
|
{
|
|
vgui::VPANEL vpanel = m_pLinePanel->GetVPanel();
|
|
vgui::surface()->PushMakeCurrent( vpanel, true );
|
|
m_pLinePanel->PaintFollowLines();
|
|
vgui::surface()->PopMakeCurrent( vpanel );
|
|
}
|
|
PaintBlips();
|
|
}
|
|
else
|
|
{
|
|
C_ASW_Game_Resource* pGameResource = ASWGameResource();
|
|
if (!pGameResource)
|
|
return;
|
|
|
|
C_ASW_Scanner_Info* pScanner = pGameResource->GetScannerInfo();
|
|
if (!pScanner)
|
|
return;
|
|
|
|
// fade blips out
|
|
pScanner->CopyServerBlips();
|
|
pScanner->FadeBlips();
|
|
}
|
|
//PaintFrame();
|
|
}
|
|
|
|
|
|
void CASWHudMinimap::PaintObjectiveMarkers()
|
|
{
|
|
const int nMaxMarks = 3;
|
|
ObjectiveMapMark *(pMarks[ nMaxMarks ]);
|
|
float fMarkDistances[ nMaxMarks ];
|
|
int nMarks = 0;
|
|
|
|
for ( int nObjective = 0; nObjective < ASW_MAX_OBJECTIVES; ++nObjective )
|
|
{
|
|
C_ASW_Objective *pObjective = ASWGameResource()->GetObjective( nObjective );
|
|
if ( pObjective )
|
|
{
|
|
if ( pObjective->IsObjectiveComplete() || pObjective->IsObjectiveFailed() || pObjective->IsObjectiveHidden() || pObjective->IsObjectiveDummy() )
|
|
{
|
|
continue;
|
|
}
|
|
|
|
int iNumMapMarks = pObjective->GetMapMarkingsCount();
|
|
ObjectiveMapMark *m_pMapMarks = pObjective->GetMapMarkings();
|
|
|
|
for ( int i = 0; i < iNumMapMarks; ++i )
|
|
{
|
|
if ( m_pMapMarks[ i ].bComplete || !m_pMapMarks[ i ].bEnabled )
|
|
{
|
|
// Don't draw completed or hidden ones
|
|
continue;
|
|
}
|
|
|
|
float fDist = m_MapCentre.DistTo( Vector2D( m_pMapMarks[ i ].x + m_pMapMarks[ i ].w / 2, m_pMapMarks[ i ].y + m_pMapMarks[ i ].h / 2 ) );
|
|
|
|
if ( nMarks < nMaxMarks )
|
|
{
|
|
pMarks[ nMarks ] = &( m_pMapMarks[ i ] );
|
|
fMarkDistances[ nMarks ] = fDist;
|
|
++nMarks;
|
|
}
|
|
else
|
|
{
|
|
int nFarthest = 0;
|
|
float fFarthestDist = fMarkDistances[ 0 ];
|
|
|
|
for ( int nMark = 1; nMark < nMarks; ++nMark )
|
|
{
|
|
if ( fFarthestDist < fMarkDistances[ nMark ] )
|
|
{
|
|
fFarthestDist = fMarkDistances[ nMark ];
|
|
nFarthest = nMark;
|
|
}
|
|
}
|
|
|
|
if ( fDist < fMarkDistances[ nFarthest ] )
|
|
{
|
|
pMarks[ nFarthest ] = &( m_pMapMarks[ i ] );
|
|
fMarkDistances[ nFarthest ] = fDist;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
int nAlpha = 50.0f + 100.0f * ( sinf( gpGlobals->curtime * 5.0f ) + 2.0f ) * 0.5f;
|
|
|
|
for ( int nMark = 0; nMark < nMarks; ++nMark )
|
|
{
|
|
PaintRect( pMarks[ nMark ]->x, pMarks[ nMark ]->y, pMarks[ nMark ]->w, pMarks[ nMark ]->h, Color( 230, 192, 0, nAlpha ) );
|
|
}
|
|
}
|
|
|
|
void CASWHudMinimap::PaintBlips()
|
|
{
|
|
PaintMarineBlips();
|
|
PaintScannerBlips();
|
|
}
|
|
|
|
void CASWHudMinimap::PaintScannerBlips()
|
|
{
|
|
C_ASW_Game_Resource* pGameResource = ASWGameResource();
|
|
if (!pGameResource)
|
|
return;
|
|
|
|
C_ASW_Scanner_Info* pScanner = pGameResource->GetScannerInfo();
|
|
if (!pScanner)
|
|
return;
|
|
|
|
// draw blips blindly from server for now
|
|
pScanner->CopyServerBlips();
|
|
pScanner->FadeBlips();
|
|
Color red(250,110,110,255);
|
|
Color blue(66,142,192,255);
|
|
Color white(255,255,255,255);
|
|
for (int i=0;i<ASW_SCANNER_MAX_BLIPS;i++) //todo: draw overflow blips
|
|
{
|
|
if (pScanner->m_ClientBlipIndex[i] != 0)
|
|
{
|
|
Vector vecWorldPos(0,0,0);
|
|
C_BaseEntity* pClientEnt = C_BaseEntity::Instance(pScanner->m_ClientBlipIndex[i]);
|
|
if (pClientEnt)
|
|
{
|
|
vecWorldPos.x = pClientEnt->GetAbsOrigin().x;
|
|
vecWorldPos.y = pClientEnt->GetAbsOrigin().y;
|
|
}
|
|
else
|
|
{
|
|
vecWorldPos.x = pScanner->m_fClientBlipX[i];
|
|
vecWorldPos.y = pScanner->m_fClientBlipY[i];
|
|
}
|
|
//float f = abs(0.5f - pScanner->m_fBlipStrength[i]) * 2.0f; // fade in/out
|
|
float f = 1.0f - pScanner->m_fBlipStrength[i]; // just fade out
|
|
|
|
PaintWorldBlip( vecWorldPos, f,
|
|
( pScanner->m_BlipType[i] == 1 ) ? blue : ( asw_scanner_classic.GetBool() ? white : red ),
|
|
MapBlipTexture_t( pScanner->m_BlipType[ i ] ) ); // draw the blip in blue triangle if it's a computer/button panel
|
|
}
|
|
}
|
|
}
|
|
|
|
// paints the scanner ring and strengthens any blips the ring passes
|
|
#define ASW_SCANNER_MAX_SOUND_DIST 1324
|
|
void CASWHudMinimapLinePanel::PaintScannerRing()
|
|
{
|
|
// skip scanner ring if we're not ingame
|
|
if (!ASWGameRules() || ASWGameRules()->GetGameState() != ASW_GS_INGAME)
|
|
return;
|
|
|
|
if (m_nScannerRingTexture == -1)
|
|
return;
|
|
|
|
C_ASW_Player* pPlayer = C_ASW_Player::GetLocalASWPlayer();
|
|
if (!pPlayer)
|
|
return;
|
|
|
|
C_ASW_Game_Resource* pGameResource = ASWGameResource();
|
|
if (!pGameResource)
|
|
return;
|
|
|
|
C_ASW_Scanner_Info* pScanner = pGameResource->GetScannerInfo();
|
|
if (!pScanner)
|
|
return;
|
|
|
|
// each tech marine has his own time and ring, so go through them
|
|
for (int i=0;i<pGameResource->GetMaxMarineResources();i++)
|
|
{
|
|
C_ASW_Marine_Resource* pMR = pGameResource->GetMarineResource(i);
|
|
if (pMR && pMR->GetProfile() && pMR->GetProfile()->CanScanner() && pMR->GetMarineEntity() && pMR->GetHealthPercent() > 0)
|
|
{
|
|
bool bCheckRing = (pMR->m_fScannerTime <= 1.0f);
|
|
|
|
pMR->m_fScannerTime += gpGlobals->frametime * 2.2f;
|
|
if (bCheckRing)
|
|
{
|
|
float fScannerRangeWorldUnits = MarineSkills()->GetSkillBasedValueByMarineResource(pMR, ASW_MARINE_SKILL_SCANNER); // asw_scanner_range.GetFloat()
|
|
float scanner_range = m_pMap->WorldDistanceToPixelDistance(fScannerRangeWorldUnits) * pMR->m_fScannerTime * asw_scanner_ring_scale.GetFloat();
|
|
|
|
Vector2D marine_pos(0,0);
|
|
Vector marine_world_pos = pMR->GetMarineEntity()->GetAbsOrigin();
|
|
// check for refreshing the strength of any blips the ring just passed
|
|
float ring_world_distance = fScannerRangeWorldUnits * MIN(pMR->m_fScannerTime, 1.0f) * asw_scanner_ring_scale.GetFloat();
|
|
float ring_world_distance_sq = ring_world_distance * ring_world_distance; // square it to save doing any square roots below
|
|
for (int k=0;k<ASW_SCANNER_MAX_BLIPS;k++)
|
|
{
|
|
if (pScanner->m_ClientBlipIndex[k] != 0 && pScanner->m_fBlipStrength[k]==0)
|
|
{
|
|
float xdiff = pScanner->m_fClientBlipX[k] - marine_world_pos.x;
|
|
float ydiff = pScanner->m_fClientBlipY[k] - marine_world_pos.y;
|
|
float dist = xdiff * xdiff + ydiff * ydiff;
|
|
if (dist < ring_world_distance_sq)
|
|
{
|
|
// our ring is outside this dot, so refresh it
|
|
pScanner->m_fBlipStrength[k] = 1.0f;
|
|
// check for making the first blip sound
|
|
if (!pMR->m_bPlayedBlipSound && pScanner->m_BlipType[k] != 1) // don't blip on computers/buttons
|
|
{
|
|
pMR->m_bPlayedBlipSound = true;
|
|
CLocalPlayerFilter filter;
|
|
EmitSound_t ep;
|
|
ep.m_nChannel = CHAN_AUTO;
|
|
static char szWarningSound[32];
|
|
Q_snprintf(szWarningSound, sizeof(szWarningSound), "ASWScanner.Warning%d", asw_scanner_warning_sound.GetInt());
|
|
ep.m_pSoundName = szWarningSound;
|
|
ep.m_flVolume = asw_scanner_warning_volume.GetFloat();
|
|
ep.m_SoundLevel = SNDLVL_NORM;
|
|
ep.m_nFlags |= SND_CHANGE_PITCH;
|
|
ep.m_nFlags |= SND_CHANGE_VOL;
|
|
float max_ring_dist = fScannerRangeWorldUnits * asw_scanner_ring_scale.GetFloat();
|
|
if (max_ring_dist <= 0)
|
|
ep.m_nPitch = 1.0f * 100.0f;
|
|
else
|
|
{
|
|
float fPitchScale = (asw_scanner_pitch_base.GetFloat() - asw_scanner_pitch_change.GetFloat() * (sqrt(dist)/max_ring_dist));
|
|
ep.m_nPitch = fPitchScale * 100.0f;
|
|
}
|
|
//Msg("Pitch is = %d\n", ep.m_nPitch);
|
|
// adjust volume by distance to tech marine
|
|
if (pPlayer->GetMarine())
|
|
{
|
|
float dist_to_tech = pPlayer->GetMarine()->GetAbsOrigin().DistTo(marine_world_pos);
|
|
float fraction = dist_to_tech / ASW_SCANNER_MAX_SOUND_DIST;
|
|
if (fraction > 0.3f) // give a buffer of max volume
|
|
ep.m_flVolume *= (1.0f - ((fraction-0.3f)*0.7f));
|
|
}
|
|
if (ep.m_flVolume>0)
|
|
{
|
|
m_pMap->m_fLastBlipHitTime = gpGlobals->curtime;
|
|
|
|
C_BaseEntity::EmitSound( filter, -1 /*SOUND_FROM_LOCAL_PLAYER*/, ep);
|
|
// if the tech is ours, then check for saying something about the incoming aliens
|
|
if (pPlayer->entindex() == pMR->GetCommanderIndex() && m_pMap && pScanner->m_BlipType[k] == 0) // only do the speech when it's an alien, not a door
|
|
{
|
|
//Msg("client checking blip speech %d\n", i);
|
|
m_pMap->CheckBlipSpeech(i);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if ( pMR->m_fScannerTime <= 1.0f && ( gpGlobals->curtime < m_pMap->m_fLastBlipHitTime + 3.0f || asw_scanner_classic.GetBool() ) )
|
|
{
|
|
// fade the ring out at the ends
|
|
if (pMR->m_fScannerTime < 0.5f)
|
|
surface()->DrawSetColor(Color(255,255,255,255));
|
|
else
|
|
{
|
|
float f = (1.0f - pMR->m_fScannerTime) * 2;
|
|
surface()->DrawSetColor(Color(255,255,255,255.0f * f));
|
|
}
|
|
surface()->DrawSetTexture(m_nScannerRingTexture);
|
|
|
|
marine_pos = m_pMap->WorldToMapTexture(marine_world_pos);
|
|
float ring_center_x = 0;
|
|
float ring_center_y = 0;
|
|
TextureToLinePanel(m_pMap, marine_pos, ring_center_x, ring_center_y);
|
|
Vertex_t points[4] =
|
|
{
|
|
Vertex_t( Vector2D(ring_center_x - scanner_range, ring_center_y - scanner_range), Vector2D(0,0) ),
|
|
Vertex_t( Vector2D(ring_center_x + scanner_range, ring_center_y - scanner_range), Vector2D(1,0) ),
|
|
Vertex_t( Vector2D(ring_center_x + scanner_range, ring_center_y + scanner_range), Vector2D(1,1) ),
|
|
Vertex_t( Vector2D(ring_center_x - scanner_range, ring_center_y + scanner_range), Vector2D(0,1) )
|
|
};
|
|
surface()->DrawTexturedPolygon( 4, points );
|
|
}
|
|
}
|
|
// check for resetting the ring to center again
|
|
if (pMR->m_fScannerTime > 2.2f)
|
|
{
|
|
// play idle sound
|
|
pMR->m_iScannerSoundSkip++;
|
|
//if ((pMR->m_iScannerSoundSkip % 4) == 0)
|
|
{
|
|
if (asw_debug_scanner_sound.GetBool())
|
|
Msg("%f: Playing scanner sound! (not mod 4).\n", gpGlobals->curtime);
|
|
|
|
pMR->m_iScannerSoundSkip = 0;
|
|
|
|
if ( asw_scanner_classic.GetBool() || gpGlobals->curtime < m_pMap->m_fLastBlipHitTime + 3.0f )
|
|
{
|
|
CLocalPlayerFilter filter;
|
|
EmitSound_t ep;
|
|
ep.m_nChannel = CHAN_AUTO;
|
|
static char szIdleSound[32];
|
|
Q_snprintf(szIdleSound, sizeof(szIdleSound), "ASWScanner.Idle%d", asw_scanner_idle_sound.GetInt());
|
|
ep.m_pSoundName = szIdleSound;
|
|
|
|
ep.m_flVolume = asw_scanner_idle_volume.GetFloat();
|
|
ep.m_nFlags |= SND_CHANGE_VOL;
|
|
ep.m_SoundLevel = SNDLVL_NORM;
|
|
// adjust volume by distance to tech marine
|
|
if (pPlayer->GetMarine())
|
|
{
|
|
float dist_to_tech = pPlayer->GetMarine()->GetAbsOrigin().DistTo(pMR->GetMarineEntity()->GetAbsOrigin());
|
|
float fraction = dist_to_tech / ASW_SCANNER_MAX_SOUND_DIST;
|
|
if (fraction > 0.3f) // give a buffer of max volume
|
|
ep.m_flVolume *= (1.0f - ((fraction-0.3f)*0.7f));
|
|
}
|
|
if (ep.m_flVolume > 0)
|
|
{
|
|
if (asw_debug_scanner_sound.GetBool())
|
|
Msg("emitting scanner idle sound with volume %f\n", ep.m_flVolume);
|
|
C_BaseEntity::StopSound( -1, ep.m_pSoundName );
|
|
C_BaseEntity::EmitSound( filter, -1 /*SOUND_FROM_LOCAL_PLAYER*/, ep );
|
|
}
|
|
}
|
|
}
|
|
|
|
pMR->m_bPlayedBlipSound = false; //todo: what effect does this have with multi tech marines?
|
|
pMR->m_fScannerTime = 0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void CASWHudMinimapLinePanel::Paint()
|
|
{
|
|
//CASWHudMinimap *m_pMap = dynamic_cast<CASWHudMinimap*>(GetParent());
|
|
if (!m_pMap)
|
|
return;
|
|
if (!ASWGameRules() && ASWGameRules()->GetGameState() < ASW_GS_INGAME)
|
|
return;
|
|
// paint a black outline over the lines
|
|
for (int i=0;i<m_pMap->m_MapLines.Count();i++)
|
|
{
|
|
float x,y;
|
|
if (!m_pMap->m_MapLines[i].bSetBlipCentre)
|
|
{
|
|
Vector vecBlipPos;
|
|
vecBlipPos.x = m_pMap->m_MapLines[i].worldpos.x;
|
|
vecBlipPos.y = m_pMap->m_MapLines[i].worldpos.y;
|
|
vecBlipPos.z = 0;
|
|
m_pMap->m_MapLines[i].blipcentre = m_pMap->WorldToMapTexture(vecBlipPos);
|
|
m_pMap->m_MapLines[i].bSetBlipCentre = true;
|
|
}
|
|
Vector2D vecBlipCentre = m_pMap->m_MapLines[i].blipcentre;
|
|
TextureToLinePanel(m_pMap, vecBlipCentre, x, y);
|
|
if (m_pMap->m_MapLines[i].bLink)
|
|
{
|
|
bool bFound = false;
|
|
if (i>1)
|
|
{
|
|
for (int k=i-1; k>0; k--) // find the previous line from this player, if any
|
|
{
|
|
if (m_pMap->m_MapLines[i].player_index == m_pMap->m_MapLines[k].player_index)
|
|
{
|
|
m_pMap->m_MapLines[i].linkpos = m_pMap->m_MapLines[k].worldpos;
|
|
bFound = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (bFound)
|
|
{
|
|
float x2,y2;
|
|
if (!m_pMap->m_MapLines[i].bSetLinkBlipCentre)
|
|
{
|
|
Vector vecBlipPos2;
|
|
vecBlipPos2.x = m_pMap->m_MapLines[i].linkpos.x;
|
|
vecBlipPos2.y = m_pMap->m_MapLines[i].linkpos.y;
|
|
vecBlipPos2.z = 0;
|
|
m_pMap->m_MapLines[i].linkblipcentre = m_pMap->WorldToMapTexture(vecBlipPos2);
|
|
m_pMap->m_MapLines[i].bSetLinkBlipCentre = true;
|
|
}
|
|
Vector2D vecBlipCentre2 = m_pMap->m_MapLines[i].linkblipcentre;
|
|
TextureToLinePanel(m_pMap, vecBlipCentre2, x2, y2);
|
|
float t = gpGlobals->curtime - m_pMap->m_MapLines[i].created_time;
|
|
int alpha = 255;
|
|
if (t < MAP_LINE_SOLID_TIME)
|
|
{
|
|
|
|
}
|
|
else if (t < MAP_LINE_SOLID_TIME + MAP_LINE_FADE_TIME)
|
|
{
|
|
alpha = 255 - ((t - MAP_LINE_SOLID_TIME) / MAP_LINE_FADE_TIME) * 255.0f;
|
|
}
|
|
else
|
|
{
|
|
continue;
|
|
}
|
|
|
|
surface()->DrawSetTexture(m_pMap->m_nWhiteTexture);
|
|
vgui::Vertex_t start, end;
|
|
|
|
// draw black outline around the line to give it some softness
|
|
surface()->DrawSetColor(Color(0,0,0, alpha));
|
|
|
|
start.Init(Vector2D(x - 1.50f,y - 1.50f), Vector2D(0,0));
|
|
end.Init(Vector2D(x2 - 1.50f,y2 - 1.50f), Vector2D(1,1));
|
|
SoftLine::DrawPolygonLine(start, end);
|
|
|
|
start.Init(Vector2D(x + 1.50f,y - 1.50f), Vector2D(0,0));
|
|
end.Init(Vector2D(x2 + 1.50f,y2 - 1.50f), Vector2D(1,1));
|
|
SoftLine::DrawPolygonLine(start, end);
|
|
|
|
start.Init(Vector2D(x - 1.50f,y + 1.50f), Vector2D(0,0));
|
|
end.Init(Vector2D(x2 - 1.50f,y2 + 1.50f), Vector2D(1,1));
|
|
SoftLine::DrawPolygonLine(start, end);
|
|
|
|
start.Init(Vector2D(x + 1.50f,y + 1.50f), Vector2D(0,0));
|
|
end.Init(Vector2D(x2 + 1.50f,y2 + 1.50f), Vector2D(1,1));
|
|
SoftLine::DrawPolygonLine(start, end);
|
|
}
|
|
}
|
|
}
|
|
|
|
// paint map line dots
|
|
for (int i=0;i<m_pMap->m_MapLines.Count();i++)
|
|
{
|
|
//m_pMap->PaintWorldBlip(vecBlipPos, 0.5f, Color(0,255,0,255));
|
|
float x,y;
|
|
if (!m_pMap->m_MapLines[i].bSetBlipCentre)
|
|
{
|
|
Vector vecBlipPos;
|
|
vecBlipPos.x = m_pMap->m_MapLines[i].worldpos.x;
|
|
vecBlipPos.y = m_pMap->m_MapLines[i].worldpos.y;
|
|
vecBlipPos.z = 0;
|
|
m_pMap->m_MapLines[i].blipcentre = m_pMap->WorldToMapTexture(vecBlipPos);
|
|
m_pMap->m_MapLines[i].bSetBlipCentre = true;
|
|
}
|
|
Vector2D vecBlipCentre = m_pMap->m_MapLines[i].blipcentre;
|
|
TextureToLinePanel(m_pMap, vecBlipCentre, x, y);
|
|
if (m_pMap->m_MapLines[i].bLink)
|
|
{
|
|
bool bFound = false;
|
|
if (i>1)
|
|
{
|
|
for (int k=i-1; k>0; k--) // find the previous line from this player, if any
|
|
{
|
|
if (m_pMap->m_MapLines[i].player_index == m_pMap->m_MapLines[k].player_index)
|
|
{
|
|
m_pMap->m_MapLines[i].linkpos = m_pMap->m_MapLines[k].worldpos;
|
|
bFound = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (bFound)
|
|
{
|
|
|
|
float x2,y2;
|
|
if (!m_pMap->m_MapLines[i].bSetLinkBlipCentre)
|
|
{
|
|
Vector vecBlipPos2;
|
|
vecBlipPos2.x = m_pMap->m_MapLines[i].linkpos.x;
|
|
vecBlipPos2.y = m_pMap->m_MapLines[i].linkpos.y;
|
|
vecBlipPos2.z = 0;
|
|
m_pMap->m_MapLines[i].linkblipcentre = m_pMap->WorldToMapTexture(vecBlipPos2);
|
|
m_pMap->m_MapLines[i].bSetLinkBlipCentre = true;
|
|
}
|
|
Vector2D vecBlipCentre2 = m_pMap->m_MapLines[i].linkblipcentre;
|
|
TextureToLinePanel(m_pMap, vecBlipCentre2, x2, y2);
|
|
float t = gpGlobals->curtime - m_pMap->m_MapLines[i].created_time;
|
|
int alpha = 255;
|
|
if (t < MAP_LINE_SOLID_TIME)
|
|
{
|
|
//surface()->DrawSetColor(Color(255,255,255,255));
|
|
//surface()->DrawLine(x,y,x2,y2);
|
|
}
|
|
else if (t < MAP_LINE_SOLID_TIME + MAP_LINE_FADE_TIME)
|
|
{
|
|
alpha = 255 - ((t - MAP_LINE_SOLID_TIME) / MAP_LINE_FADE_TIME) * 255.0f;
|
|
}
|
|
else
|
|
{
|
|
continue;
|
|
}
|
|
|
|
surface()->DrawSetTexture(m_pMap->m_nWhiteTexture);
|
|
vgui::Vertex_t start, end;
|
|
|
|
// draw main line
|
|
surface()->DrawSetColor(Color(DRAWING_LINE_R, DRAWING_LINE_G, DRAWING_LINE_B, 0.5f * alpha));
|
|
//surface()->DrawLine(x,y,x2,y2);
|
|
start.Init(Vector2D(x,y), Vector2D(0,0));
|
|
end.Init(Vector2D(x2,y2), Vector2D(1,1));
|
|
SoftLine::DrawPolygonLine(start, end);
|
|
|
|
// draw translucent ones around it to give it some softness
|
|
surface()->DrawSetColor(Color(DRAWING_LINE_R, DRAWING_LINE_G, DRAWING_LINE_B, 0.5f * alpha));
|
|
|
|
start.Init(Vector2D(x - 0.50f,y - 0.50f), Vector2D(0,0));
|
|
end.Init(Vector2D(x2 - 0.50f,y2 - 0.50f), Vector2D(1,1));
|
|
SoftLine::DrawPolygonLine(start, end);
|
|
|
|
start.Init(Vector2D(x + 0.50f,y - 0.50f), Vector2D(0,0));
|
|
end.Init(Vector2D(x2 + 0.50f,y2 - 0.50f), Vector2D(1,1));
|
|
SoftLine::DrawPolygonLine(start, end);
|
|
|
|
start.Init(Vector2D(x - 0.50f,y + 0.50f), Vector2D(0,0));
|
|
end.Init(Vector2D(x2 - 0.50f,y2 + 0.50f), Vector2D(1,1));
|
|
SoftLine::DrawPolygonLine(start, end);
|
|
|
|
start.Init(Vector2D(x + 0.50f,y + 0.50f), Vector2D(0,0));
|
|
end.Init(Vector2D(x2 + 0.50f,y2 + 0.50f), Vector2D(1,1));
|
|
SoftLine::DrawPolygonLine(start, end);
|
|
}
|
|
}
|
|
}
|
|
|
|
// paint the frame over the top
|
|
//int wide, tall;
|
|
//m_pMap->GetSize(wide,tall);
|
|
|
|
//if ( m_pMap->m_nFrameTexture == -1 )
|
|
//return;
|
|
|
|
//surface()->DrawSetColor(m_pMap->GetBgColor());
|
|
//surface()->DrawSetTexture(m_pMap->m_nFrameTexture);
|
|
//surface()->DrawTexturedRect(-20, -20, wide, tall);
|
|
//surface()->DrawTexturedSubRect(0, 0, wide, tall,);
|
|
//-m_pMap->m_MapCornerInPanel.x*2, -m_pMap->m_MapCornerInPanel.y*2, wide, tall);
|
|
|
|
//surface()->DrawTexturedSubRect(m_MapCornerInPanel.x, m_MapCornerInPanel.y, wide, tall,
|
|
//Source1X/1024.0, Source1Y/1024.0, Source2X/1024.0, Source2Y/1024.0);
|
|
PaintScannerRing();
|
|
}
|
|
|
|
void CASWHudMinimapLinePanel::PaintFollowLines()
|
|
{
|
|
C_ASW_Game_Resource* pGameResource = ASWGameResource();
|
|
if (!pGameResource)
|
|
return;
|
|
|
|
// paint follow lines
|
|
for (int i=0;i<ASW_MAX_MARINE_RESOURCES;i++)
|
|
{
|
|
C_ASW_Marine_Resource* pMR = pGameResource->GetMarineResource(i);
|
|
if (pMR && pMR->GetMarineEntity())
|
|
{
|
|
C_ASW_Marine* pMarine = pMR->GetMarineEntity();
|
|
if (pMarine && pMarine->m_hMarineFollowTarget && !pMarine->IsInhabited())
|
|
{
|
|
PaintFollowLine(pMarine, pMarine->m_hMarineFollowTarget);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void CASWHudMinimap::PaintRect( int nX, int nY, int nWidth, int nHeight, Color color )
|
|
{
|
|
Vector2D rectCorner1;
|
|
Vector2D rectCorner2;
|
|
|
|
rectCorner1.x = nX;
|
|
rectCorner1.y = nY;
|
|
rectCorner2.x = nX + nWidth;
|
|
rectCorner2.y = nY + nHeight;
|
|
|
|
rectCorner1 = MapTextureToPanel( rectCorner1 );
|
|
rectCorner2 = MapTextureToPanel( rectCorner2 );
|
|
|
|
if ( rectCorner1.x > m_MapCornerInPanel.x + m_iMapSize || rectCorner1.y > m_MapCornerInPanel.y + m_iMapSize ||
|
|
rectCorner2.x < m_MapCornerInPanel.x || rectCorner2.y < m_MapCornerInPanel.y )
|
|
{
|
|
// Out of bounds
|
|
Vector2D vArrowCenter = Vector2D( ( rectCorner1.x + rectCorner2.x ) / 2, ( rectCorner1.y + rectCorner2.y ) / 2 );
|
|
Vector2D vPanelCenter = Vector2D( m_MapCornerInPanel.x + m_iMapSize / 2, m_MapCornerInPanel.y + m_iMapSize / 2 );
|
|
|
|
Vector2D vDirection = vArrowCenter - vPanelCenter;
|
|
Vector2DNormalize( vDirection );
|
|
|
|
float fFacingYaw = RAD2DEG( atanf( vDirection.y / vDirection.x ) ) - ( vDirection.x < 0.0f ? 0.0f : 180.0f );
|
|
|
|
int iFacingSize = GetWide() * 0.05f * asw_hud_scale.GetFloat();
|
|
|
|
vArrowCenter.x = clamp( vArrowCenter.x, m_MapCornerInPanel.x, m_MapCornerInPanel.x + m_iMapSize - iFacingSize / 2 );
|
|
vArrowCenter.y = clamp( vArrowCenter.y, m_MapCornerInPanel.y, m_MapCornerInPanel.y + m_iMapSize - iFacingSize / 2 );
|
|
|
|
vArrowCenter -= vDirection * 4.0f * ( sinf( gpGlobals->curtime * 7.0f ) + 1.0f );
|
|
|
|
// set up a square to the right
|
|
int xoffset = -2; // temp? to make the arc look nice next to blips..
|
|
int yoffset = 1;
|
|
Vector vecCornerTL(xoffset, iFacingSize * -0.5f + yoffset, 0);
|
|
Vector vecCornerTR(iFacingSize + xoffset, iFacingSize * -0.5f+ yoffset, 0);
|
|
Vector vecCornerBR(iFacingSize + xoffset, iFacingSize * 0.5f+ yoffset, 0);
|
|
Vector vecCornerBL(xoffset, iFacingSize * 0.5f+ yoffset, 0);
|
|
Vector vecCornerTL_rotated, vecCornerTR_rotated, vecCornerBL_rotated, vecCornerBR_rotated;
|
|
|
|
// rotate it by our facing yaw
|
|
QAngle angFacing( 0, fFacingYaw, 0 );
|
|
VectorRotate(vecCornerTL, angFacing, vecCornerTL_rotated);
|
|
VectorRotate(vecCornerTR, angFacing, vecCornerTR_rotated);
|
|
VectorRotate(vecCornerBR, angFacing, vecCornerBR_rotated);
|
|
VectorRotate(vecCornerBL, angFacing, vecCornerBL_rotated);
|
|
|
|
surface()->DrawSetColor( color );
|
|
surface()->DrawSetTexture(m_nFacingArcTexture);
|
|
//surface()->DrawTexturedRect(Dest1X,Dest1Y,Dest2X,Dest2Y);
|
|
Vertex_t points[4] =
|
|
{
|
|
Vertex_t( Vector2D(vArrowCenter.x + vecCornerTL_rotated.x, vArrowCenter.y + vecCornerTL_rotated.y), Vector2D(0,0) ),
|
|
Vertex_t( Vector2D(vArrowCenter.x + vecCornerTR_rotated.x, vArrowCenter.y + vecCornerTR_rotated.y), Vector2D(1,0) ),
|
|
Vertex_t( Vector2D(vArrowCenter.x + vecCornerBR_rotated.x, vArrowCenter.y + vecCornerBR_rotated.y), Vector2D(1,1) ),
|
|
Vertex_t( Vector2D(vArrowCenter.x + vecCornerBL_rotated.x, vArrowCenter.y + vecCornerBL_rotated.y), Vector2D(0,1) )
|
|
};
|
|
surface()->DrawTexturedPolygon( 4, points );
|
|
}
|
|
else
|
|
{
|
|
rectCorner1.x = MAX( rectCorner1.x, m_MapCornerInPanel.x );
|
|
rectCorner1.y = MAX( rectCorner1.y, m_MapCornerInPanel.y );
|
|
|
|
rectCorner2.x = MIN( rectCorner2.x, m_MapCornerInPanel.x + m_iMapSize );
|
|
rectCorner2.y = MIN( rectCorner2.y, m_MapCornerInPanel.y + m_iMapSize );
|
|
|
|
surface()->DrawSetColor( color );
|
|
surface()->DrawOutlinedRect( rectCorner1.x, rectCorner1.y, rectCorner2.x, rectCorner2.y );
|
|
|
|
color[ 3 ] /= 8;
|
|
|
|
surface()->DrawSetColor( color );
|
|
surface()->DrawFilledRect( rectCorner1.x, rectCorner1.y, rectCorner2.x, rectCorner2.y );
|
|
}
|
|
}
|
|
|
|
// fixme: blips should be sent from the server.. per player?
|
|
// so as to be sent information about things you can't see (i.e. to give the tracker some range)
|
|
// change networking to send entities to players if they're near his current marine
|
|
// (and perhaps near any he's controlling?)
|
|
// then we can send blips from server->client only if they're outside this range
|
|
// these blips will be static
|
|
// we'll also drops blips of every alien/marine entity the client knows about, these can move
|
|
//void CASWHudMinimap::CreateBlips()
|
|
//{
|
|
//m_iNumBlips = 0;
|
|
|
|
//#define MAX_BLIPS 64
|
|
//int m_iBlipX[MAX_BLIPS];
|
|
//int m_iBlipY[MAX_BLIPS];
|
|
//int m_iNumBlips;
|
|
//}
|
|
|
|
float CASWHudMinimap::WorldDistanceToPixelDistance(float fWorldDistance)
|
|
{
|
|
// convert to texture scale
|
|
float result = fWorldDistance / m_fMapScale;
|
|
result *= ASW_SCREENSHOT_SCALE;
|
|
// find how many pixels on the texture correspond to the map panel halfwidth:
|
|
float source_size = asw_map_range.GetFloat() * ASW_SCREENSHOT_SCALE / m_fMapScale;
|
|
// find what fraction our offset is compared to the full texture width of the map:
|
|
result /= source_size;
|
|
// multiply that out by the pixel halfwidth of this panel:
|
|
result *= (m_iMapSize * 0.5f);
|
|
|
|
return result;
|
|
}
|
|
|
|
|
|
// loads in the script file for a particular map to set scale/origin
|
|
void CASWHudMinimap::SetMap(const char * levelname)
|
|
{
|
|
// load new KeyValues
|
|
//Msg("minimap SetMap: %s\n", levelname);
|
|
if ( m_MapKeyValues && Q_strcmp( levelname, m_MapKeyValues->GetName() ) == 0 )
|
|
{
|
|
return; // map didn't change
|
|
}
|
|
|
|
if ( m_MapKeyValues )
|
|
m_MapKeyValues->deleteThis();
|
|
|
|
m_MapKeyValues = new KeyValues( levelname );
|
|
|
|
char tempfile[MAX_PATH];
|
|
Q_snprintf( tempfile, sizeof( tempfile ), "resource/overviews/%s.txt", levelname );
|
|
|
|
if ( !m_MapKeyValues->LoadFromFile( filesystem, tempfile, "GAME" ) )
|
|
{
|
|
// try to load it directly from the maps folder
|
|
Q_snprintf( tempfile, sizeof( tempfile ), "maps/%s.txt", levelname );
|
|
if ( !m_MapKeyValues->LoadFromFile( filesystem, tempfile, "GAME" ) )
|
|
{
|
|
//DevMsg( 1, "CASWHudMinimap::SetMap: couldn't load overview file for map %s.\n", levelname );
|
|
m_nMapTextureID = surface()->CreateNewTextureID();
|
|
surface()->DrawSetTextureFile( m_nMapTextureID, "vgui/swarm/hud/scanner", true, false);
|
|
// put in some default numbers so the scanner works
|
|
m_MapOrigin.x = 0;
|
|
m_MapOrigin.y = 0;
|
|
m_fMapScale = 25.0f;
|
|
Q_snprintf(m_szMissionTitle, sizeof(m_szMissionTitle), "Unnamed Mission");
|
|
m_bHasOverview = false;
|
|
return;
|
|
}
|
|
}
|
|
|
|
// TODO release old texture ?
|
|
|
|
m_nMapTextureID = surface()->CreateNewTextureID();
|
|
|
|
//if we have not uploaded yet, lets go ahead and do so
|
|
surface()->DrawSetTextureFile( m_nMapTextureID, m_MapKeyValues->GetString("material"), true, false);
|
|
|
|
m_MapOrigin.x = m_MapKeyValues->GetInt("pos_x");
|
|
m_MapOrigin.y = m_MapKeyValues->GetInt("pos_y");
|
|
m_fMapScale = m_MapKeyValues->GetFloat("scale", 1.0f);
|
|
Q_snprintf(m_szMissionTitle, sizeof(m_szMissionTitle),m_MapKeyValues->GetString("missiontitle"));
|
|
m_bHasOverview = true;
|
|
|
|
}
|
|
|
|
void CASWHudMinimap::FireGameEvent( IGameEvent * event )
|
|
{
|
|
const char * type = event->GetName();
|
|
//Msg("Minimap firegameevent %s\n", type);
|
|
if ( Q_strcmp(type, "game_newmap") == 0 )
|
|
{
|
|
SetMap( event->GetString("mapname") );
|
|
m_MapLines.RemoveAll();
|
|
m_fLastBlipSpeechTime = -100.0f;
|
|
}
|
|
else if ( Q_strcmp(type, "server_spawn") == 0 )
|
|
{
|
|
const char *hostname = event->GetString( "hostname" );
|
|
Q_snprintf(m_szServerName, sizeof(m_szServerName), "%s", hostname);
|
|
}
|
|
CASW_HudElement::FireGameEvent(event);
|
|
}
|
|
|
|
bool CASWHudMinimap::MouseClick(int x, int y, bool bRightClick, bool bDown)
|
|
{
|
|
if (!ShouldDraw() || !asw_minimap_clicks.GetBool())
|
|
return false;
|
|
|
|
if (!bDown)
|
|
{
|
|
m_bDrawingMapLines = false;
|
|
return false;
|
|
}
|
|
|
|
if (bRightClick)
|
|
return false;
|
|
|
|
if (!IsWithinMapBounds(x,y))
|
|
return false;
|
|
|
|
int ox, oy;
|
|
GetScaledOffset(ox, oy);
|
|
|
|
SendMapLine(x+ox,y+oy,true);
|
|
m_bDrawingMapLines = true;
|
|
|
|
return true;
|
|
}
|
|
|
|
bool CASWHudMinimap::IsWithinMapBounds(int x, int y)
|
|
{
|
|
//int wide, tall;
|
|
int posx, posy;
|
|
if (m_nMapTextureID == -1)
|
|
return false;
|
|
GetPos(posx,posy);
|
|
//int ox, oy;
|
|
//GetScaledOffset(ox, oy);
|
|
//posx += ox;
|
|
//posy += oy;
|
|
//GetSize(wide,tall);
|
|
//wide *= asw_hud_scale.GetFloat();
|
|
//tall *= asw_hud_scale.GetFloat();
|
|
x -= posx;
|
|
y -= posy;
|
|
return (x >= m_MapCornerInPanel.x
|
|
&& y >= m_MapCornerInPanel.y
|
|
&& x <= (m_MapCornerInPanel.x + m_iMapSize)
|
|
&& y <= (m_MapCornerInPanel.y + m_iMapSize));
|
|
}
|
|
|
|
void CASWHudMinimap::ClipToMapBounds(int &x, int &y)
|
|
{
|
|
int wide, tall;
|
|
int posx, posy;
|
|
GetPos(posx,posy);
|
|
int ox, oy;
|
|
GetScaledOffset(ox, oy);
|
|
posx += ox;
|
|
posy += oy;
|
|
GetSize(wide,tall);
|
|
wide *= asw_hud_scale.GetFloat();
|
|
tall *= asw_hud_scale.GetFloat();
|
|
if (x > m_MapCornerInPanel.x + posx + wide)
|
|
x = m_MapCornerInPanel.x + posx + wide;
|
|
if (x < m_MapCornerInPanel.x + posx)
|
|
x = m_MapCornerInPanel.x + posx;
|
|
if (y > m_MapCornerInPanel.y + posy + tall)
|
|
y = m_MapCornerInPanel.y + posy + tall;
|
|
if (y < m_MapCornerInPanel.y + posy)
|
|
y = m_MapCornerInPanel.y + posy;
|
|
}
|
|
|
|
// drawing a map line at point x and y on the hud element
|
|
void CASWHudMinimap::SendMapLine(int x, int y, bool bInitial)
|
|
{
|
|
C_ASW_Player *local = C_ASW_Player::GetLocalASWPlayer();
|
|
if ( local )
|
|
{
|
|
C_ASW_Marine *marine = local->GetMarine();
|
|
if (marine)
|
|
{
|
|
int wide, tall, posx, posy;
|
|
GetSize(wide,tall);
|
|
wide *= asw_hud_scale.GetFloat();
|
|
tall *= asw_hud_scale.GetFloat();
|
|
GetPos(posx, posy);
|
|
int ox, oy;
|
|
GetScaledOffset(ox, oy);
|
|
posx += ox;
|
|
posy += oy;
|
|
x -= posx;
|
|
y -= posy;
|
|
|
|
Vector vecMapCentre = marine->GetAbsOrigin();
|
|
|
|
// pixel difference between where we clicked and the centre of the panel
|
|
int diff_x = x - m_MapCentreInPanel.x;
|
|
int diff_y = m_MapCentreInPanel.y - y;
|
|
|
|
// find the world position we clicked on
|
|
Vector vecMapLinePos;
|
|
// world difference should be: ( diff_x / panel size ) * map range
|
|
vecMapLinePos.x = vecMapCentre.x + (diff_x / (m_iMapSize*0.5f)) * asw_map_range.GetFloat();
|
|
vecMapLinePos.y = vecMapCentre.y + (diff_y / (m_iMapSize*0.5f)) * asw_map_range.GetFloat();
|
|
//vecMapLinePos.x = vecMapCentre.x + (diff_x * m_fMapScale / ASW_SCREENSHOT_SCALE);
|
|
//vecMapLinePos.y = vecMapCentre.y + (diff_y * m_fMapScale / ASW_SCREENSHOT_SCALE);
|
|
vecMapLinePos.z = marine->GetAbsOrigin().z;
|
|
//Msg("vecMapCentre = %f %f\n", vecMapCentre.x, vecMapCentre.y);
|
|
//Msg("VecMapLinePos = %f %f %f\n", vecMapLinePos.x, vecMapLinePos.y, vecMapLinePos.z);
|
|
|
|
//FX_MicroExplosion(vecMapLinePos, Vector(0,0,1));
|
|
|
|
// notify the server of this!
|
|
char buffer[64];
|
|
int linetype = bInitial ? 0 : 1;
|
|
Q_snprintf(buffer, sizeof(buffer), "cl_mapline %d %d %d", linetype, (int) vecMapLinePos.x, (int) vecMapLinePos.y);
|
|
engine->ClientCmd(buffer);
|
|
|
|
m_fLastMapLine = gpGlobals->curtime;
|
|
|
|
// short circuit add it to your own list
|
|
MapLine line;
|
|
line.player_index = local->entindex();
|
|
line.worldpos.x = (int) vecMapLinePos.x;
|
|
line.worldpos.y = (int) vecMapLinePos.y;
|
|
line.created_time = gpGlobals->curtime;
|
|
if (linetype == 1) // links to a previous
|
|
{
|
|
line.bLink = true;
|
|
}
|
|
else
|
|
{
|
|
if (gpGlobals->curtime > m_fLastMinimapDrawSound + 5.0f)
|
|
{
|
|
CLocalPlayerFilter filter;
|
|
C_BaseEntity::EmitSound( filter, -1, "ASWScanner.Drawing" );
|
|
m_fLastMinimapDrawSound = gpGlobals->curtime;
|
|
}
|
|
}
|
|
m_MapLines.AddToTail(line);
|
|
}
|
|
}
|
|
}
|
|
|
|
// converts a coord from 0->1023 map texture into x+y in this panel
|
|
Vector2D CASWHudMinimap::MapTextureToPanel( const Vector2D &texturepos )
|
|
{
|
|
if ( !m_pMinimap )
|
|
{
|
|
m_pMinimap = GET_HUDELEMENT( CASWHudMinimap );
|
|
|
|
if ( !m_pMinimap )
|
|
{
|
|
return vec2_origin;
|
|
}
|
|
}
|
|
|
|
Vector2D offset(texturepos);
|
|
|
|
// find how many pixels on the texture correspond to the map panel halfwidth:
|
|
float source_size = asw_map_range.GetFloat() * ASW_SCREENSHOT_SCALE / m_pMinimap->m_fMapScale;
|
|
|
|
// convert our tex coords to an offset from the map pixel at the centre of the panel:
|
|
offset -= m_pMinimap->m_MapCentre;
|
|
|
|
// find what fraction our offset is compared to the full texture width of the map:
|
|
offset /= source_size;
|
|
|
|
// multiply that out by the pixel halfwidth of this panel:
|
|
offset *= (GetMapSize() * 0.5f);
|
|
|
|
offset += m_pMinimap->m_MapCentreInPanel;
|
|
|
|
return offset;
|
|
}
|
|
|
|
int CASWHudMinimap::GetArcSize( void )
|
|
{
|
|
return GetWidth() * 0.1f * asw_hud_scale.GetFloat();
|
|
}
|
|
|
|
|
|
//void CASWHudMinimapLinePanel::TextureToLinePanel(CASWHudMinimap* pMap, const Vector &worldpos, int &x, int &y)
|
|
// converts a 0->1024 map texture coord to the x/y in the panel coord
|
|
void CASWHudMinimapLinePanel::TextureToLinePanel(CASWHudMinimap* pMap, const Vector2D &blip_centre, float &x, float &y)
|
|
{
|
|
if (!pMap)
|
|
return;
|
|
Vector2D result = pMap->MapTextureToPanel(blip_centre);
|
|
int wx, wy;
|
|
GetPos(wx,wy);
|
|
int ox, oy;
|
|
pMap->GetScaledOffset(ox, oy);
|
|
//wx += ox;
|
|
//wy += oy;
|
|
|
|
x = result.x - wx;
|
|
y = result.y - wy;
|
|
//int w, t;
|
|
//GetSize(w, t);
|
|
//Vector2D blip_centre = pMap->WorldToMapTexture(worldpos);
|
|
//float source_size = asw_map_range.GetFloat() * ASW_SCREENSHOT_SCALE / pMap->m_fMapScale;
|
|
//x = blip_centre.x - pMap->m_MapCentre.x + source_size;
|
|
//y = blip_centre.y - pMap->m_MapCentre.y + source_size;
|
|
//x = blip_centre.x - pMap->m_MapCentre.x + pMap->m_iMapSize * 0.5f;
|
|
//y = blip_centre.y - pMap->m_MapCentre.y + pMap->m_iMapSize * 0.5f;
|
|
}
|
|
|
|
bool CASWHudMinimap::UseDrawCrosshair(float x, float y)
|
|
{
|
|
C_ASW_Player *pPlayer = C_ASW_Player::GetLocalASWPlayer();
|
|
if (!pPlayer || !pPlayer->GetMarine() || !asw_minimap_clicks.GetBool())
|
|
return false;
|
|
return IsWithinMapBounds(x,y);
|
|
}
|
|
|
|
void CASWHudMinimap::CheckBlipSpeech(int iMarine)
|
|
{
|
|
// check if it's been a while since we had any movement
|
|
if (gpGlobals->curtime - m_fLastBlipSpeechTime > ASW_BLIP_SPEECH_INTERVAL)
|
|
{
|
|
C_ASW_Player *pPlayer = C_ASW_Player::GetLocalASWPlayer();
|
|
pPlayer->SendBlipSpeech(iMarine);
|
|
}
|
|
m_fLastBlipSpeechTime = gpGlobals->curtime; // bump the time to current evne if we didn't say anything, so we don't continually say movement when there are blips all the time
|
|
}
|
|
|
|
void CASWHudMinimapLinePanel::PaintFollowLine(C_BaseEntity *pMarine, C_BaseEntity *pTarget)
|
|
{
|
|
if (!pMarine || !pTarget)
|
|
return;
|
|
surface()->DrawSetTexture(m_pMap->m_nWhiteTexture);
|
|
vgui::Vertex_t start, end;
|
|
|
|
Vector2D startTexturePos = m_pMap->WorldToMapTexture(pMarine->GetAbsOrigin());
|
|
Vector2D endTexturePos = m_pMap->WorldToMapTexture(pTarget->GetAbsOrigin());
|
|
Vector2D start2D, end2D;
|
|
TextureToLinePanel(m_pMap, startTexturePos, start2D.x, start2D.y);
|
|
TextureToLinePanel(m_pMap, endTexturePos, end2D.x, end2D.y);
|
|
//Vector2D start2D = m_pMap->MapTextureToPanel(startTexturePos);
|
|
//Vector2D end2D = m_pMap->MapTextureToPanel(endTexturePos);
|
|
|
|
float x, y, x2,y2;
|
|
x = start2D.x;
|
|
y = start2D.y;
|
|
x2 = end2D.x;
|
|
y2 = end2D.y;
|
|
float alpha = 255;
|
|
|
|
// draw black outline around the line to give it some softness
|
|
surface()->DrawSetColor(Color(0,0,0, alpha));
|
|
|
|
start.Init(Vector2D(x - 1.50f,y - 1.50f), Vector2D(0,0));
|
|
end.Init(Vector2D(x2 - 1.50f,y2 - 1.50f), Vector2D(1,1));
|
|
SoftLine::DrawPolygonLine(start, end);
|
|
|
|
start.Init(Vector2D(x + 1.50f,y - 1.50f), Vector2D(0,0));
|
|
end.Init(Vector2D(x2 + 1.50f,y2 - 1.50f), Vector2D(1,1));
|
|
SoftLine::DrawPolygonLine(start, end);
|
|
|
|
start.Init(Vector2D(x - 1.50f,y + 1.50f), Vector2D(0,0));
|
|
end.Init(Vector2D(x2 - 1.50f,y2 + 1.50f), Vector2D(1,1));
|
|
SoftLine::DrawPolygonLine(start, end);
|
|
|
|
start.Init(Vector2D(x + 1.50f,y + 1.50f), Vector2D(0,0));
|
|
end.Init(Vector2D(x2 + 1.50f,y2 + 1.50f), Vector2D(1,1));
|
|
SoftLine::DrawPolygonLine(start, end);
|
|
|
|
// draw main line
|
|
surface()->DrawSetColor(Color(255,0,0, 0.5f * alpha));
|
|
//surface()->DrawLine(x,y,x2,y2);
|
|
start.Init(Vector2D(x,y), Vector2D(0,0));
|
|
end.Init(Vector2D(x2,y2), Vector2D(1,1));
|
|
SoftLine::DrawPolygonLine(start, end);
|
|
|
|
// draw translucent ones around it to give it some softness
|
|
surface()->DrawSetColor(Color(255,0,0, 0.5f * alpha));
|
|
|
|
start.Init(Vector2D(x - 0.50f,y - 0.50f), Vector2D(0,0));
|
|
end.Init(Vector2D(x2 - 0.50f,y2 - 0.50f), Vector2D(1,1));
|
|
SoftLine::DrawPolygonLine(start, end);
|
|
|
|
start.Init(Vector2D(x + 0.50f,y - 0.50f), Vector2D(0,0));
|
|
end.Init(Vector2D(x2 + 0.50f,y2 - 0.50f), Vector2D(1,1));
|
|
SoftLine::DrawPolygonLine(start, end);
|
|
|
|
start.Init(Vector2D(x - 0.50f,y + 0.50f), Vector2D(0,0));
|
|
end.Init(Vector2D(x2 - 0.50f,y2 + 0.50f), Vector2D(1,1));
|
|
SoftLine::DrawPolygonLine(start, end);
|
|
|
|
start.Init(Vector2D(x + 0.50f,y + 0.50f), Vector2D(0,0));
|
|
end.Init(Vector2D(x2 + 0.50f,y2 + 0.50f), Vector2D(1,1));
|
|
SoftLine::DrawPolygonLine(start, end);
|
|
}
|
|
|
|
CASWHudMinimap_Border::CASWHudMinimap_Border(vgui::Panel *pParent, const char *pElementName, CASWHudMinimap *pMinimap) :
|
|
vgui::Panel(pParent, pElementName)
|
|
{
|
|
m_pMinimap = pMinimap;
|
|
}
|
|
|
|
void CASWHudMinimap_Border::PaintBackground()
|
|
{
|
|
if (ASWGameRules())
|
|
{
|
|
if (ASWGameRules()->IsIntroMap() || ASWGameRules()->IsOutroMap())
|
|
return;
|
|
}
|
|
if (m_pMinimap && !m_pMinimap->ShouldDraw())
|
|
return;
|
|
|
|
if ( !asw_draw_hud.GetBool() || m_nBlackBarTexture == -1 )
|
|
{
|
|
return;
|
|
}
|
|
if ( !asw_scanner_background.GetBool() )
|
|
return;
|
|
//BaseClass::PaintBackground();
|
|
|
|
vgui::surface()->DrawSetColor(Color(255,255,255,asw_hud_alpha.GetInt()));
|
|
vgui::surface()->DrawSetTexture(m_nBlackBarTexture);
|
|
vgui::Vertex_t points[4] =
|
|
{
|
|
vgui::Vertex_t( Vector2D(0, 0), Vector2D(0,0) ),
|
|
vgui::Vertex_t( Vector2D(GetWide(), 0), Vector2D(1,0) ),
|
|
vgui::Vertex_t( Vector2D(GetWide(), GetTall()), Vector2D(1,1) ),
|
|
vgui::Vertex_t( Vector2D(0, GetTall()), Vector2D(0,1) )
|
|
};
|
|
vgui::surface()->DrawTexturedPolygon( 4, points );
|
|
}
|