2010-08-25 14:15:59 +00:00
# include <stdio.h>
2010-05-29 07:25:38 +00:00
# include <engine/graphics.h>
# include <engine/textrender.h>
2010-08-25 14:15:59 +00:00
# include <engine/demo.h>
2010-05-29 07:25:38 +00:00
# include <engine/shared/config.h>
2010-08-25 14:15:59 +00:00
# include <engine/serverbrowser.h>
2010-05-29 07:25:38 +00:00
# include <game/generated/protocol.h>
# include <game/generated/client_data.h>
# include <game/layers.h>
# include <game/client/gameclient.h>
# include <game/client/animstate.h>
# include <game/client/render.h>
# include "controls.h"
# include "camera.h"
# include "hud.h"
# include "voting.h"
# include "binds.h"
2010-08-25 14:15:59 +00:00
# include "menus.h"
# include "race_demo.h"
2010-05-29 07:25:38 +00:00
CHud : : CHud ( )
2008-08-27 15:48:50 +00:00
{
2010-05-29 07:25:38 +00:00
// won't work if zero
m_AverageFPS = 1.0f ;
2010-08-25 14:15:59 +00:00
OnReset ( ) ;
2008-08-27 15:48:50 +00:00
}
2010-05-29 07:25:38 +00:00
void CHud : : OnReset ( )
2008-08-27 15:48:50 +00:00
{
2010-08-25 14:15:59 +00:00
m_CheckpointTick = 0 ;
m_CheckpointDiff = 0 ;
m_RaceTime = 0 ;
m_Record = 0 ;
m_LocalRecord = - 1.0f ;
m_LastReceivedTimeTick = - 1 ;
2008-08-27 15:48:50 +00:00
}
2010-05-30 12:01:11 +00:00
void CHud : : RenderGameTimer ( )
2008-08-27 15:48:50 +00:00
{
2010-05-30 12:01:11 +00:00
float Half = 300.0f * Graphics ( ) - > ScreenAspect ( ) / 2.0f ;
Graphics ( ) - > MapScreen ( 0 , 0 , 300.0f * Graphics ( ) - > ScreenAspect ( ) , 300.0f ) ;
2008-08-27 15:48:50 +00:00
2010-05-29 07:25:38 +00:00
if ( ! m_pClient - > m_Snap . m_pGameobj - > m_SuddenDeath )
2008-08-27 15:48:50 +00:00
{
2010-05-29 07:25:38 +00:00
char Buf [ 32 ] ;
int Time = 0 ;
if ( m_pClient - > m_Snap . m_pGameobj - > m_TimeLimit )
2008-08-27 15:48:50 +00:00
{
2010-05-29 07:25:38 +00:00
Time = m_pClient - > m_Snap . m_pGameobj - > m_TimeLimit * 60 - ( ( Client ( ) - > GameTick ( ) - m_pClient - > m_Snap . m_pGameobj - > m_RoundStartTick ) / Client ( ) - > GameTickSpeed ( ) ) ;
2008-08-27 15:48:50 +00:00
2010-05-29 07:25:38 +00:00
if ( m_pClient - > m_Snap . m_pGameobj - > m_GameOver )
Time = 0 ;
2008-08-27 15:48:50 +00:00
}
else
2010-05-29 07:25:38 +00:00
Time = ( Client ( ) - > GameTick ( ) - m_pClient - > m_Snap . m_pGameobj - > m_RoundStartTick ) / Client ( ) - > GameTickSpeed ( ) ;
2008-08-27 15:48:50 +00:00
2010-05-30 12:01:11 +00:00
str_format ( Buf , sizeof ( Buf ) , " %d:%02d " , Time / 60 , Time % 60 ) ;
float FontSize = 10.0f ;
float w = TextRender ( ) - > TextWidth ( 0 , FontSize , Buf , - 1 ) ;
TextRender ( ) - > Text ( 0 , Half - w / 2 , 2 , FontSize , Buf , - 1 ) ;
2008-08-27 15:48:50 +00:00
}
2010-05-30 12:01:11 +00:00
}
2008-08-27 15:48:50 +00:00
2010-05-30 12:01:11 +00:00
void CHud : : RenderSuddenDeath ( )
{
2010-05-29 07:25:38 +00:00
if ( m_pClient - > m_Snap . m_pGameobj - > m_SuddenDeath )
2008-08-27 15:48:50 +00:00
{
2010-05-30 12:01:11 +00:00
float Half = 300.0f * Graphics ( ) - > ScreenAspect ( ) / 2.0f ;
2010-06-03 09:30:05 +00:00
const char * pText = Localize ( " Sudden Death " ) ;
2010-05-30 12:01:11 +00:00
float FontSize = 12.0f ;
float w = TextRender ( ) - > TextWidth ( 0 , FontSize , pText , - 1 ) ;
TextRender ( ) - > Text ( 0 , Half - w / 2 , 2 , FontSize , pText , - 1 ) ;
2008-08-27 15:48:50 +00:00
}
2010-05-30 12:01:11 +00:00
}
2008-08-27 15:48:50 +00:00
2010-05-30 12:01:11 +00:00
void CHud : : RenderScoreHud ( )
{
int GameFlags = m_pClient - > m_Snap . m_pGameobj - > m_Flags ;
float Whole = 300 * Graphics ( ) - > ScreenAspect ( ) ;
2008-08-27 15:48:50 +00:00
// render small score hud
2010-08-25 14:15:59 +00:00
if ( ! m_pClient - > m_IsRace & & ! ( m_pClient - > m_Snap . m_pGameobj & & m_pClient - > m_Snap . m_pGameobj - > m_GameOver ) & & ( GameFlags & GAMEFLAG_TEAMS ) )
2008-08-27 15:48:50 +00:00
{
2010-06-22 19:27:58 +00:00
char aScoreTeam [ 2 ] [ 32 ] ;
str_format ( aScoreTeam [ 0 ] , sizeof ( aScoreTeam ) / 2 , " %d " , m_pClient - > m_Snap . m_pGameobj - > m_TeamscoreRed ) ;
str_format ( aScoreTeam [ 1 ] , sizeof ( aScoreTeam ) / 2 , " %d " , m_pClient - > m_Snap . m_pGameobj - > m_TeamscoreBlue ) ;
float aScoreTeamWidth [ 2 ] = { TextRender ( ) - > TextWidth ( 0 , 14.0f , aScoreTeam [ 0 ] , - 1 ) , TextRender ( ) - > TextWidth ( 0 , 14.0f , aScoreTeam [ 1 ] , - 1 ) } ;
float ScoreWidthMax = max ( max ( aScoreTeamWidth [ 0 ] , aScoreTeamWidth [ 1 ] ) , TextRender ( ) - > TextWidth ( 0 , 14.0f , " 100 " , - 1 ) ) ;
float Split = 3.0f ;
float ImageSize = GameFlags & GAMEFLAG_FLAGS ? 16.0f : Split ;
2008-08-27 15:48:50 +00:00
for ( int t = 0 ; t < 2 ; t + + )
{
2010-06-22 19:27:58 +00:00
// draw box
2009-10-27 14:38:53 +00:00
Graphics ( ) - > BlendNormal ( ) ;
Graphics ( ) - > TextureSet ( - 1 ) ;
Graphics ( ) - > QuadsBegin ( ) ;
2008-08-27 15:48:50 +00:00
if ( t = = 0 )
2010-06-22 19:27:58 +00:00
Graphics ( ) - > SetColor ( 1.0f , 0.0f , 0.0f , 0.25f ) ;
2008-08-27 15:48:50 +00:00
else
2010-06-22 19:27:58 +00:00
Graphics ( ) - > SetColor ( 0.0f , 0.0f , 1.0f , 0.25f ) ;
RenderTools ( ) - > DrawRoundRectExt ( Whole - ScoreWidthMax - ImageSize - 2 * Split , 245.0f + t * 20 , ScoreWidthMax + ImageSize + 2 * Split , 18.0f , 5.0f , CUI : : CORNER_L ) ;
2009-10-27 14:38:53 +00:00
Graphics ( ) - > QuadsEnd ( ) ;
2008-08-27 15:48:50 +00:00
2010-06-22 19:27:58 +00:00
// draw score
TextRender ( ) - > Text ( 0 , Whole - ScoreWidthMax + ( ScoreWidthMax - aScoreTeamWidth [ t ] ) / 2 - Split , 245.0f + t * 20 , 14.0f , aScoreTeam [ t ] , - 1 ) ;
if ( GameFlags & GAMEFLAG_FLAGS & & m_pClient - > m_Snap . m_paFlags [ t ] )
2008-08-27 15:48:50 +00:00
{
2010-06-22 19:27:58 +00:00
if ( m_pClient - > m_Snap . m_paFlags [ t ] - > m_CarriedBy = = - 2 | | ( m_pClient - > m_Snap . m_paFlags [ t ] - > m_CarriedBy = = - 1 & & ( ( Client ( ) - > GameTick ( ) / 10 ) & 1 ) ) )
{
// draw flag
Graphics ( ) - > BlendNormal ( ) ;
Graphics ( ) - > TextureSet ( g_pData - > m_aImages [ IMAGE_GAME ] . m_Id ) ;
Graphics ( ) - > QuadsBegin ( ) ;
RenderTools ( ) - > SelectSprite ( t = = 0 ? SPRITE_FLAG_RED : SPRITE_FLAG_BLUE ) ;
IGraphics : : CQuadItem QuadItem ( Whole - ScoreWidthMax - ImageSize , 246.0f + t * 20 , ImageSize / 2 , ImageSize ) ;
Graphics ( ) - > QuadsDrawTL ( & QuadItem , 1 ) ;
Graphics ( ) - > QuadsEnd ( ) ;
}
else if ( m_pClient - > m_Snap . m_paFlags [ t ] - > m_CarriedBy > = 0 )
2008-08-27 15:48:50 +00:00
{
2010-06-22 19:27:58 +00:00
// draw name of the flag holder
int Id = m_pClient - > m_Snap . m_paFlags [ t ] - > m_CarriedBy % MAX_CLIENTS ;
const char * pName = m_pClient - > m_aClients [ Id ] . m_aName ;
float w = TextRender ( ) - > TextWidth ( 0 , 10.0f , pName , - 1 ) ;
TextRender ( ) - > Text ( 0 , Whole - ScoreWidthMax - ImageSize - 3 * Split - w , 247.0f + t * 20 , 10.0f , pName , - 1 ) ;
2008-08-27 15:48:50 +00:00
2010-06-22 19:27:58 +00:00
// draw tee of the flag holder
CTeeRenderInfo Info = m_pClient - > m_aClients [ Id ] . m_RenderInfo ;
Info . m_Size = 18.0f ;
RenderTools ( ) - > RenderTee ( CAnimState : : GetIdle ( ) , & Info , EMOTE_NORMAL , vec2 ( 1 , 0 ) ,
vec2 ( Whole - ScoreWidthMax - Info . m_Size / 2 - Split , 246.0f + Info . m_Size / 2 + t * 20 ) ) ;
2008-08-27 15:48:50 +00:00
}
}
}
}
2010-05-30 12:01:11 +00:00
}
2008-08-27 15:48:50 +00:00
2010-05-30 12:01:11 +00:00
void CHud : : RenderWarmupTimer ( )
{
2008-08-27 15:48:50 +00:00
// render warmup timer
2010-05-29 07:25:38 +00:00
if ( m_pClient - > m_Snap . m_pGameobj - > m_Warmup )
2008-08-27 15:48:50 +00:00
{
2010-05-29 07:25:38 +00:00
char Buf [ 256 ] ;
2010-05-30 12:01:11 +00:00
float FontSize = 20.0f ;
2010-06-03 09:30:05 +00:00
float w = TextRender ( ) - > TextWidth ( 0 , FontSize , Localize ( " Warmup " ) , - 1 ) ;
TextRender ( ) - > Text ( 0 , 150 * Graphics ( ) - > ScreenAspect ( ) + - w / 2 , 50 , FontSize , Localize ( " Warmup " ) , - 1 ) ;
2008-08-27 15:48:50 +00:00
2010-05-29 07:25:38 +00:00
int Seconds = m_pClient - > m_Snap . m_pGameobj - > m_Warmup / SERVER_TICK_SPEED ;
if ( Seconds < 5 )
str_format ( Buf , sizeof ( Buf ) , " %d.%d " , Seconds , ( m_pClient - > m_Snap . m_pGameobj - > m_Warmup * 10 / SERVER_TICK_SPEED ) % 10 ) ;
2008-08-27 15:48:50 +00:00
else
2010-05-29 07:25:38 +00:00
str_format ( Buf , sizeof ( Buf ) , " %d " , Seconds ) ;
2010-05-30 12:01:11 +00:00
w = TextRender ( ) - > TextWidth ( 0 , FontSize , Buf , - 1 ) ;
TextRender ( ) - > Text ( 0 , 150 * Graphics ( ) - > ScreenAspect ( ) + - w / 2 , 75 , FontSize , Buf , - 1 ) ;
2008-08-27 15:48:50 +00:00
}
}
2010-05-29 07:25:38 +00:00
void CHud : : MapscreenToGroup ( float CenterX , float CenterY , CMapItemGroup * pGroup )
2008-08-27 15:48:50 +00:00
{
2010-05-29 07:25:38 +00:00
float Points [ 4 ] ;
RenderTools ( ) - > MapscreenToWorld ( CenterX , CenterY , pGroup - > m_ParallaxX / 100.0f , pGroup - > m_ParallaxY / 100.0f ,
pGroup - > m_OffsetX , pGroup - > m_OffsetY , Graphics ( ) - > ScreenAspect ( ) , 1.0f , Points ) ;
Graphics ( ) - > MapScreen ( Points [ 0 ] , Points [ 1 ] , Points [ 2 ] , Points [ 3 ] ) ;
2008-08-27 15:48:50 +00:00
}
2010-05-29 07:25:38 +00:00
void CHud : : RenderFps ( )
2008-08-27 15:48:50 +00:00
{
2010-05-29 07:25:38 +00:00
if ( g_Config . m_ClShowfps )
2008-08-27 15:48:50 +00:00
{
2010-05-29 07:25:38 +00:00
// calculate avg. fps
float FPS = 1.0f / Client ( ) - > FrameTime ( ) ;
m_AverageFPS = ( m_AverageFPS * ( 1.0f - ( 1.0f / m_AverageFPS ) ) ) + ( FPS * ( 1.0f / m_AverageFPS ) ) ;
char Buf [ 512 ] ;
str_format ( Buf , sizeof ( Buf ) , " %d " , ( int ) m_AverageFPS ) ;
TextRender ( ) - > Text ( 0 , m_Width - 10 - TextRender ( ) - > TextWidth ( 0 , 12 , Buf , - 1 ) , 5 , 12 , Buf , - 1 ) ;
2008-08-27 15:48:50 +00:00
}
}
2010-05-29 07:25:38 +00:00
void CHud : : RenderConnectionWarning ( )
2008-08-27 15:48:50 +00:00
{
2010-05-29 07:25:38 +00:00
if ( Client ( ) - > ConnectionProblems ( ) )
2008-08-27 15:48:50 +00:00
{
2010-06-03 09:30:05 +00:00
const char * pText = Localize ( " Connection Problems... " ) ;
2010-05-29 07:25:38 +00:00
float w = TextRender ( ) - > TextWidth ( 0 , 24 , pText , - 1 ) ;
TextRender ( ) - > Text ( 0 , 150 * Graphics ( ) - > ScreenAspect ( ) - w / 2 , 50 , 24 , pText , - 1 ) ;
2008-08-27 15:48:50 +00:00
}
}
2010-05-29 07:25:38 +00:00
void CHud : : RenderTeambalanceWarning ( )
2008-09-01 18:17:01 +00:00
{
// render prompt about team-balance
2010-05-29 07:25:38 +00:00
bool Flash = time_get ( ) / ( time_freq ( ) / 2 ) % 2 = = 0 ;
if ( m_pClient - > m_Snap . m_pGameobj & & ( m_pClient - > m_Snap . m_pGameobj - > m_Flags & GAMEFLAG_TEAMS ) ! = 0 )
2008-09-01 18:17:01 +00:00
{
2010-05-29 07:25:38 +00:00
int TeamDiff = m_pClient - > m_Snap . m_aTeamSize [ 0 ] - m_pClient - > m_Snap . m_aTeamSize [ 1 ] ;
if ( g_Config . m_ClWarningTeambalance & & ( TeamDiff > = 2 | | TeamDiff < = - 2 ) )
2008-09-01 18:17:01 +00:00
{
2010-06-03 09:30:05 +00:00
const char * pText = Localize ( " Please balance teams! " ) ;
2010-05-29 07:25:38 +00:00
if ( Flash )
TextRender ( ) - > TextColor ( 1 , 1 , 0.5f , 1 ) ;
2008-09-01 18:17:01 +00:00
else
2010-05-29 07:25:38 +00:00
TextRender ( ) - > TextColor ( 0.7f , 0.7f , 0.2f , 1.0f ) ;
TextRender ( ) - > Text ( 0x0 , 5 , 50 , 6 , pText , - 1 ) ;
TextRender ( ) - > TextColor ( 1 , 1 , 1 , 1 ) ;
2008-09-01 18:17:01 +00:00
}
}
}
2008-09-25 14:04:02 +00:00
2010-05-29 07:25:38 +00:00
void CHud : : RenderVoting ( )
2008-09-25 14:04:02 +00:00
{
2010-05-29 07:25:38 +00:00
if ( ! m_pClient - > m_pVoting - > IsVoting ( ) )
2008-09-25 14:04:02 +00:00
return ;
2009-10-27 14:38:53 +00:00
Graphics ( ) - > TextureSet ( - 1 ) ;
Graphics ( ) - > QuadsBegin ( ) ;
Graphics ( ) - > SetColor ( 0 , 0 , 0 , 0.40f ) ;
2010-05-29 07:25:38 +00:00
RenderTools ( ) - > DrawRoundRect ( - 10 , 60 - 2 , 100 + 10 + 4 + 5 , 28 , 5.0f ) ;
2009-10-27 14:38:53 +00:00
Graphics ( ) - > QuadsEnd ( ) ;
2009-01-21 21:17:25 +00:00
2010-05-29 07:25:38 +00:00
TextRender ( ) - > TextColor ( 1 , 1 , 1 , 1 ) ;
2009-01-21 21:17:25 +00:00
2010-05-29 07:25:38 +00:00
char Buf [ 512 ] ;
2010-06-03 09:30:05 +00:00
str_format ( Buf , sizeof ( Buf ) , Localize ( " %ds left " ) , m_pClient - > m_pVoting - > SecondsLeft ( ) ) ;
2010-05-29 07:25:38 +00:00
float tw = TextRender ( ) - > TextWidth ( 0x0 , 6 , Buf , - 1 ) ;
2010-09-12 11:18:11 +00:00
CTextCursor Cursor ;
TextRender ( ) - > SetCursor ( & Cursor , 5.0f , 60.0f , 6.0f , TEXTFLAG_RENDER | TEXTFLAG_STOP_AT_END ) ;
Cursor . m_LineWidth = 100 - tw ;
TextRender ( ) - > TextEx ( & Cursor , m_pClient - > m_pVoting - > VoteDescription ( ) , - 1 ) ;
2010-05-29 07:25:38 +00:00
TextRender ( ) - > Text ( 0x0 , 5 + 100 - tw , 60 , 6 , Buf , - 1 ) ;
2009-01-21 21:17:25 +00:00
2010-05-29 07:25:38 +00:00
CUIRect Base = { 5 , 70 , 100 , 4 } ;
m_pClient - > m_pVoting - > RenderBars ( Base , false ) ;
2008-09-25 14:04:02 +00:00
2010-05-29 07:25:38 +00:00
const char * pYesKey = m_pClient - > m_pBinds - > GetKey ( " vote yes " ) ;
const char * pNoKey = m_pClient - > m_pBinds - > GetKey ( " vote no " ) ;
str_format ( Buf , sizeof ( Buf ) , " %s - Vote Yes " , pYesKey ) ;
Base . y + = Base . h + 1 ;
UI ( ) - > DoLabel ( & Base , Buf , 6.0f , - 1 ) ;
str_format ( Buf , sizeof ( Buf ) , " Vote No - %s " , pNoKey ) ;
UI ( ) - > DoLabel ( & Base , Buf , 6.0f , 1 ) ;
2008-09-25 14:04:02 +00:00
}
2010-05-29 07:25:38 +00:00
void CHud : : RenderCursor ( )
2008-08-27 15:48:50 +00:00
{
2010-09-08 00:07:36 +00:00
if ( ! m_pClient - > m_Snap . m_pLocalCharacter | | Client ( ) - > State ( ) = = IClient : : STATE_DEMOPLAYBACK )
2008-08-31 13:36:30 +00:00
return ;
2010-05-29 07:25:38 +00:00
MapscreenToGroup ( m_pClient - > m_pCamera - > m_Center . x , m_pClient - > m_pCamera - > m_Center . y , Layers ( ) - > GameGroup ( ) ) ;
Graphics ( ) - > TextureSet ( g_pData - > m_aImages [ IMAGE_GAME ] . m_Id ) ;
2009-10-27 14:38:53 +00:00
Graphics ( ) - > QuadsBegin ( ) ;
2008-08-27 15:48:50 +00:00
// render cursor
2010-05-29 07:25:38 +00:00
RenderTools ( ) - > SelectSprite ( g_pData - > m_Weapons . m_aId [ m_pClient - > m_Snap . m_pLocalCharacter - > m_Weapon % NUM_WEAPONS ] . m_pSpriteCursor ) ;
float CursorSize = 64 ;
RenderTools ( ) - > DrawSprite ( m_pClient - > m_pControls - > m_TargetPos . x , m_pClient - > m_pControls - > m_TargetPos . y , CursorSize ) ;
2009-10-27 14:38:53 +00:00
Graphics ( ) - > QuadsEnd ( ) ;
2008-08-27 15:48:50 +00:00
}
2010-05-29 07:25:38 +00:00
void CHud : : RenderHealthAndAmmo ( )
2008-08-27 15:48:50 +00:00
{
//mapscreen_to_group(gacenter_x, center_y, layers_game_group());
float x = 5 ;
float y = 5 ;
// render ammo count
// render gui stuff
2008-08-27 20:18:50 +00:00
2010-05-29 07:25:38 +00:00
Graphics ( ) - > TextureSet ( g_pData - > m_aImages [ IMAGE_GAME ] . m_Id ) ;
Graphics ( ) - > MapScreen ( 0 , 0 , m_Width , 300 ) ;
2008-08-27 15:48:50 +00:00
2009-10-27 14:38:53 +00:00
Graphics ( ) - > QuadsBegin ( ) ;
2008-08-27 20:18:50 +00:00
2008-08-27 15:48:50 +00:00
// if weaponstage is active, put a "glow" around the stage ammo
2010-05-29 07:25:38 +00:00
RenderTools ( ) - > SelectSprite ( g_pData - > m_Weapons . m_aId [ m_pClient - > m_Snap . m_pLocalCharacter - > m_Weapon % NUM_WEAPONS ] . m_pSpriteProj ) ;
IGraphics : : CQuadItem Array [ 10 ] ;
int i ;
for ( i = 0 ; i < min ( m_pClient - > m_Snap . m_pLocalCharacter - > m_AmmoCount , 10 ) ; i + + )
Array [ i ] = IGraphics : : CQuadItem ( x + i * 12 , y + 24 , 10 , 10 ) ;
Graphics ( ) - > QuadsDrawTL ( Array , i ) ;
2009-10-27 14:38:53 +00:00
Graphics ( ) - > QuadsEnd ( ) ;
2008-08-27 15:48:50 +00:00
2009-10-27 14:38:53 +00:00
Graphics ( ) - > QuadsBegin ( ) ;
2008-08-27 15:48:50 +00:00
int h = 0 ;
// render health
2010-05-29 07:25:38 +00:00
RenderTools ( ) - > SelectSprite ( SPRITE_HEALTH_FULL ) ;
for ( ; h < min ( m_pClient - > m_Snap . m_pLocalCharacter - > m_Health , 10 ) ; h + + )
Array [ h ] = IGraphics : : CQuadItem ( x + h * 12 , y , 10 , 10 ) ;
Graphics ( ) - > QuadsDrawTL ( Array , h ) ;
2008-08-27 15:48:50 +00:00
2010-05-29 07:25:38 +00:00
i = 0 ;
RenderTools ( ) - > SelectSprite ( SPRITE_HEALTH_EMPTY ) ;
2008-08-27 15:48:50 +00:00
for ( ; h < 10 ; h + + )
2010-05-29 07:25:38 +00:00
Array [ i + + ] = IGraphics : : CQuadItem ( x + h * 12 , y , 10 , 10 ) ;
Graphics ( ) - > QuadsDrawTL ( Array , i ) ;
2008-08-27 15:48:50 +00:00
// render armor meter
h = 0 ;
2010-05-29 07:25:38 +00:00
RenderTools ( ) - > SelectSprite ( SPRITE_ARMOR_FULL ) ;
for ( ; h < min ( m_pClient - > m_Snap . m_pLocalCharacter - > m_Armor , 10 ) ; h + + )
Array [ h ] = IGraphics : : CQuadItem ( x + h * 12 , y + 12 , 10 , 10 ) ;
Graphics ( ) - > QuadsDrawTL ( Array , h ) ;
2008-08-27 15:48:50 +00:00
2010-05-29 07:25:38 +00:00
i = 0 ;
RenderTools ( ) - > SelectSprite ( SPRITE_ARMOR_EMPTY ) ;
2008-08-27 15:48:50 +00:00
for ( ; h < 10 ; h + + )
2010-05-29 07:25:38 +00:00
Array [ i + + ] = IGraphics : : CQuadItem ( x + h * 12 , y + 12 , 10 , 10 ) ;
Graphics ( ) - > QuadsDrawTL ( Array , i ) ;
2009-10-27 14:38:53 +00:00
Graphics ( ) - > QuadsEnd ( ) ;
2008-08-27 15:48:50 +00:00
}
2010-08-25 14:15:59 +00:00
void CHud : : RenderSpeedmeter ( )
{
if ( ! g_Config . m_ClRenderSpeedmeter )
return ;
// We calculate the speed instead of getting it from character.velocity cause it's buggy when
// walking in front of a wall or when using the ninja sword
static float Speed ;
static vec2 OldPos ;
static const int SMOOTH_TABLE_SIZE = 16 ;
static const int ACCEL_THRESHOLD = 25 ;
static float SmoothTable [ SMOOTH_TABLE_SIZE ] ;
static int SmoothIndex = 0 ;
SmoothTable [ SmoothIndex ] = distance ( m_pClient - > m_LocalCharacterPos , OldPos ) / Client ( ) - > FrameTime ( ) ;
if ( Client ( ) - > State ( ) = = IClient : : STATE_DEMOPLAYBACK )
{
float Mult = DemoPlayer ( ) - > BaseInfo ( ) - > m_Speed ;
SmoothTable [ SmoothIndex ] / = Mult ;
}
SmoothIndex = ( SmoothIndex + 1 ) % SMOOTH_TABLE_SIZE ;
OldPos = m_pClient - > m_LocalCharacterPos ;
Speed = 0 ;
for ( int i = 0 ; i < SMOOTH_TABLE_SIZE ; i + + )
Speed + = SmoothTable [ i ] ;
Speed / = SMOOTH_TABLE_SIZE ;
int t = ( ! m_pClient - > m_IsRace & & ( m_pClient - > m_Snap . m_pGameobj - > m_Flags & GAMEFLAG_TEAMS ) ) ? - 1 : 1 ;
int LastIndex = SmoothIndex - 1 ;
if ( LastIndex < 0 )
LastIndex = SMOOTH_TABLE_SIZE - 1 ;
Graphics ( ) - > BlendNormal ( ) ;
Graphics ( ) - > TextureSet ( - 1 ) ;
Graphics ( ) - > QuadsBegin ( ) ;
if ( g_Config . m_ClSpeedmeterAccel & & Speed - SmoothTable [ LastIndex ] > ACCEL_THRESHOLD )
Graphics ( ) - > SetColor ( 0.6f , 0.1f , 0.1f , 0.25f ) ;
else if ( g_Config . m_ClSpeedmeterAccel & & Speed - SmoothTable [ LastIndex ] < - ACCEL_THRESHOLD )
Graphics ( ) - > SetColor ( 0.1f , 0.6f , 0.1f , 0.25f ) ;
else
Graphics ( ) - > SetColor ( 0.1 , 0.1 , 0.1 , 0.25 ) ;
RenderTools ( ) - > DrawRoundRect ( m_Width - 45 , 245 + t * 20 , 55 , 18 , 5.0f ) ;
Graphics ( ) - > QuadsEnd ( ) ;
char aBuf [ 16 ] ;
str_format ( aBuf , sizeof ( aBuf ) , " %.0f " , Speed / 10 ) ;
TextRender ( ) - > Text ( 0 , m_Width - 5 - TextRender ( ) - > TextWidth ( 0 , 12 , aBuf , - 1 ) , 246 + t * 20 , 12 , aBuf , - 1 ) ;
}
void CHud : : RenderTime ( )
{
if ( ! m_pClient - > m_IsRace )
return ;
// check racestate
if ( m_pClient - > m_pRaceDemo - > GetRaceState ( ) ! = CRaceDemo : : RACE_FINISHED & & m_LastReceivedTimeTick + Client ( ) - > GameTickSpeed ( ) * 2 < Client ( ) - > GameTick ( ) )
{
m_pClient - > m_pRaceDemo - > m_RaceState = CRaceDemo : : RACE_NONE ;
return ;
}
if ( m_RaceTime )
{
if ( ! m_FinishTime & & m_pClient - > m_pRaceDemo - > GetRaceState ( ) = = CRaceDemo : : RACE_FINISHED )
m_FinishTime = m_pClient - > m_pRaceDemo - > GetFinishTime ( ) ;
char aBuf [ 64 ] ;
if ( m_FinishTime )
{
str_format ( aBuf , sizeof ( aBuf ) , " Finish time: %02d:%05.2f " , ( int ) m_FinishTime / 60 , m_FinishTime - ( ( int ) m_FinishTime / 60 * 60 ) ) ;
TextRender ( ) - > Text ( 0 , 150 * Graphics ( ) - > ScreenAspect ( ) - TextRender ( ) - > TextWidth ( 0 , 12 , aBuf , - 1 ) / 2 , 20 , 12 , aBuf , - 1 ) ;
}
else if ( m_pClient - > m_pRaceDemo - > GetRaceState ( ) = = CRaceDemo : : RACE_STARTED )
{
str_format ( aBuf , sizeof ( aBuf ) , " %02d:%02d.%d " , m_RaceTime / 60 , m_RaceTime % 60 , m_RaceTick / 10 ) ;
TextRender ( ) - > Text ( 0 , 150 * Graphics ( ) - > ScreenAspect ( ) - TextRender ( ) - > TextWidth ( 0 , 12 , " 00:00.00 " , - 1 ) / 2 , 20 , 12 , aBuf , - 1 ) ; // use fixed value for text width so its not shaky
}
if ( g_Config . m_ClShowCheckpointDiff & & m_CheckpointTick + Client ( ) - > GameTickSpeed ( ) * 6 > Client ( ) - > GameTick ( ) )
{
str_format ( aBuf , sizeof ( aBuf ) , " %+5.2f " , m_CheckpointDiff ) ;
// calculate alpha (4 sec 1 than get lower the next 2 sec)
float a = 1.0f ;
if ( m_CheckpointTick + Client ( ) - > GameTickSpeed ( ) * 4 < Client ( ) - > GameTick ( ) & & m_CheckpointTick + Client ( ) - > GameTickSpeed ( ) * 6 > Client ( ) - > GameTick ( ) )
{
// lower the alpha slowly to blend text out
a = ( ( float ) ( m_CheckpointTick + Client ( ) - > GameTickSpeed ( ) * 6 ) - ( float ) Client ( ) - > GameTick ( ) ) / ( float ) ( Client ( ) - > GameTickSpeed ( ) * 2 ) ;
}
if ( m_CheckpointDiff > 0 )
TextRender ( ) - > TextColor ( 1.0f , 0.5f , 0.5f , a ) ; // red
else if ( m_CheckpointDiff < 0 )
TextRender ( ) - > TextColor ( 0.5f , 1.0f , 0.5f , a ) ; // green
else if ( ! m_CheckpointDiff )
TextRender ( ) - > TextColor ( 1 , 1 , 1 , a ) ; // white
TextRender ( ) - > Text ( 0 , 150 * Graphics ( ) - > ScreenAspect ( ) - TextRender ( ) - > TextWidth ( 0 , 10 , aBuf , - 1 ) / 2 , 33 , 10 , aBuf , - 1 ) ;
TextRender ( ) - > TextColor ( 1 , 1 , 1 , 1 ) ;
}
}
m_RaceTick + = 100 / Client ( ) - > GameTickSpeed ( ) ;
if ( m_RaceTick > = 100 )
m_RaceTick = 0 ;
}
void CHud : : RenderRecord ( )
{
if ( ! m_pClient - > m_IsRace )
return ;
if ( m_Record > 0 & & g_Config . m_ClShowServerRecord & & g_Config . m_ClShowRecords )
{
char aBuf [ 64 ] ;
str_format ( aBuf , sizeof ( aBuf ) , " Server best: " ) ;
TextRender ( ) - > Text ( 0 , 5 , 40 , 6 , aBuf , - 1 ) ;
str_format ( aBuf , sizeof ( aBuf ) , " %02d:%05.2f " , ( int ) m_Record / 60 , m_Record - ( ( int ) m_Record / 60 * 60 ) ) ;
TextRender ( ) - > Text ( 0 , 53 , 40 , 6 , aBuf , - 1 ) ;
}
2010-09-26 21:31:33 +00:00
if ( m_pClient - > m_pRaceDemo - > m_Time & & ( m_LocalRecord = = - 1 | | m_LocalRecord > m_pClient - > m_pRaceDemo - > m_Time ) )
m_LocalRecord = m_pClient - > m_pRaceDemo - > m_Time ;
2010-08-25 14:15:59 +00:00
if ( m_LocalRecord > 0 & & g_Config . m_ClShowLocalRecord & & g_Config . m_ClShowRecords )
{
char aBuf [ 64 ] ;
str_format ( aBuf , sizeof ( aBuf ) , " Personal best: " ) ;
TextRender ( ) - > Text ( 0 , 5 , 47 , 6 , aBuf , - 1 ) ;
str_format ( aBuf , sizeof ( aBuf ) , " %02d:%05.2f " , ( int ) m_LocalRecord / 60 , m_LocalRecord - ( ( int ) m_LocalRecord / 60 * 60 ) ) ;
TextRender ( ) - > Text ( 0 , 53 , 47 , 6 , aBuf , - 1 ) ;
}
}
2010-05-29 07:25:38 +00:00
void CHud : : OnRender ( )
2008-08-27 15:48:50 +00:00
{
2010-05-29 07:25:38 +00:00
if ( ! m_pClient - > m_Snap . m_pGameobj )
2008-08-27 15:48:50 +00:00
return ;
2010-05-29 07:25:38 +00:00
m_Width = 300 * Graphics ( ) - > ScreenAspect ( ) ;
2008-08-27 15:48:50 +00:00
2010-05-29 07:25:38 +00:00
bool Spectate = false ;
if ( m_pClient - > m_Snap . m_pLocalInfo & & m_pClient - > m_Snap . m_pLocalInfo - > m_Team = = - 1 )
Spectate = true ;
2008-08-27 15:48:50 +00:00
2010-05-29 07:25:38 +00:00
if ( m_pClient - > m_Snap . m_pLocalCharacter & & ! Spectate & & ! ( m_pClient - > m_Snap . m_pGameobj & & m_pClient - > m_Snap . m_pGameobj - > m_GameOver ) )
2010-08-25 14:15:59 +00:00
{
2010-05-29 07:25:38 +00:00
RenderHealthAndAmmo ( ) ;
2010-08-25 14:15:59 +00:00
RenderSpeedmeter ( ) ;
RenderTime ( ) ;
}
2010-05-29 07:25:38 +00:00
2010-05-30 12:01:11 +00:00
RenderGameTimer ( ) ;
RenderSuddenDeath ( ) ;
RenderScoreHud ( ) ;
RenderWarmupTimer ( ) ;
2010-05-29 07:25:38 +00:00
RenderFps ( ) ;
if ( Client ( ) - > State ( ) ! = IClient : : STATE_DEMOPLAYBACK )
RenderConnectionWarning ( ) ;
RenderTeambalanceWarning ( ) ;
RenderVoting ( ) ;
2010-08-25 14:15:59 +00:00
RenderRecord ( ) ;
2010-05-29 07:25:38 +00:00
RenderCursor ( ) ;
2008-08-27 15:48:50 +00:00
}
2010-08-25 14:15:59 +00:00
void CHud : : OnMessage ( int MsgType , void * pRawMsg )
{
if ( MsgType = = NETMSGTYPE_SV_RACETIME )
{
// activate racestate just in case
m_pClient - > m_pRaceDemo - > m_RaceState = CRaceDemo : : RACE_STARTED ;
CNetMsg_Sv_RaceTime * pMsg = ( CNetMsg_Sv_RaceTime * ) pRawMsg ;
m_RaceTime = pMsg - > m_Time ;
m_RaceTick = 0 ;
m_LastReceivedTimeTick = Client ( ) - > GameTick ( ) ;
if ( m_FinishTime )
m_FinishTime = 0 ;
if ( pMsg - > m_Check )
{
m_CheckpointDiff = ( float ) pMsg - > m_Check / 100 ;
m_CheckpointTick = Client ( ) - > GameTick ( ) ;
}
}
else if ( MsgType = = NETMSGTYPE_SV_KILLMSG )
{
CNetMsg_Sv_KillMsg * pMsg = ( CNetMsg_Sv_KillMsg * ) pRawMsg ;
if ( pMsg - > m_Victim = = m_pClient - > m_Snap . m_LocalCid )
{
m_CheckpointTick = 0 ;
m_RaceTime = 0 ;
}
}
else if ( MsgType = = NETMSGTYPE_SV_RECORD )
{
CNetMsg_Sv_Record * pMsg = ( CNetMsg_Sv_Record * ) pRawMsg ;
m_Record = ( float ) pMsg - > m_Time / 100 ;
}
}