forked from a1batross/Paranoia2_original
867 lines
24 KiB
C++
867 lines
24 KiB
C++
// ====================================
|
||
// Paranoia vgui hud
|
||
// written by BUzer.
|
||
// ====================================
|
||
|
||
#include "hud.h"
|
||
#include "cl_util.h"
|
||
#include "parsemsg.h"
|
||
#include "const.h"
|
||
#include "entity_types.h"
|
||
#include "cdll_int.h"
|
||
#include "vgui_TeamFortressViewport.h"
|
||
#include "vgui_hud.h"
|
||
#include "vgui_paranoiatext.h" // Wargon
|
||
#include "..\game_shared\vgui_loadtga.h"
|
||
#include<VGUI_TextImage.h>
|
||
|
||
#include "ammohistory.h"
|
||
#include "stringlib.h"
|
||
|
||
#define WEAPON_PAINKILLER 31 // should match server's index
|
||
|
||
|
||
#define HEALTH_RIGHT_OFFSET (XRES(10))
|
||
#define HEALTH_DOWN_OFFSET (YRES(15))
|
||
#define HEALTH_MIN_SPACE (YRES(3)) // minimum space between bars
|
||
#define HEALTH_FLASH_TIME 0.3
|
||
|
||
#define HEALTH_FADE_TIME 5
|
||
#define HEALTH_ZERO_ALPHA 150
|
||
#define HEALTH_ALPHA 70
|
||
|
||
// Wargon: Иконка юза.
|
||
#define USAGE_FADE_TIME 1
|
||
#define USAGE_ALPHA 70
|
||
|
||
static int resArray[] = { 320, 400, 512, 640, 800, 1024, 1152, 1280, 1600 };
|
||
|
||
// Wargon: Иконка юза.
|
||
int CanUseStatus;
|
||
int __MsgFunc_CanUse( const char *pszName, int iSize, void *pbuf )
|
||
{
|
||
BEGIN_READ( pbuf, iSize );
|
||
CanUseStatus = READ_BYTE();
|
||
return 1;
|
||
}
|
||
|
||
void CanUseInit( void )
|
||
{
|
||
HOOK_MESSAGE( CanUse );
|
||
}
|
||
|
||
BitmapTGA *LoadResolutionImage( const char *imgname )
|
||
{
|
||
BitmapTGA *pBitmap = NULL;
|
||
|
||
// resolution based image. Should contain %d substring
|
||
if( Q_stristr( imgname, "%d" ))
|
||
{
|
||
int resArrayIndex = 0;
|
||
int i = 0;
|
||
|
||
while(( resArray[i] <= ScreenWidth ) && ( i < ARRAYSIZE( resArray )))
|
||
{
|
||
resArrayIndex = i;
|
||
i++;
|
||
}
|
||
|
||
while( pBitmap == NULL && resArrayIndex >= 0 )
|
||
{
|
||
char imgName[256];
|
||
Q_snprintf( imgName, sizeof( imgName ), imgname, resArray[resArrayIndex] );
|
||
pBitmap = vgui_LoadTGA( imgName );
|
||
resArrayIndex--;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// try to load image directly
|
||
pBitmap = vgui_LoadTGA( imgname );
|
||
}
|
||
|
||
return pBitmap;
|
||
}
|
||
|
||
int ShouldDrawHUD()
|
||
{
|
||
if (!gHUD.m_pCvarDraw->value)
|
||
return FALSE;
|
||
|
||
if ((gHUD.m_iHideHUDDisplay & HIDEHUD_HEALTH) || gEngfuncs.IsSpectateOnly() )
|
||
return FALSE;
|
||
|
||
if (FBitSet( gHUD.m_iHideHUDDisplay, ITEM_SUIT ))
|
||
return TRUE;
|
||
|
||
return FALSE;
|
||
}
|
||
|
||
|
||
// simple class that owns pointer to a bitmap and draws it
|
||
class ImageHolder : public Panel
|
||
{
|
||
public:
|
||
ImageHolder(const char *imgname, Panel *parent) : Panel(0, 0, 10, 10)
|
||
{
|
||
m_pBitmap = LoadResolutionImage(imgname);
|
||
setParent(parent);
|
||
setPaintBackgroundEnabled(false);
|
||
setVisible(true);
|
||
if (m_pBitmap) m_pBitmap->setPos(0, 0);
|
||
}
|
||
|
||
~ImageHolder() {delete m_pBitmap;}
|
||
BitmapTGA *GetBitmap() {return m_pBitmap;}
|
||
|
||
protected:
|
||
virtual void paint()
|
||
{
|
||
if (ShouldDrawHUD())
|
||
{
|
||
if (m_pBitmap)
|
||
m_pBitmap->doPaint(this);
|
||
}
|
||
}
|
||
|
||
BitmapTGA *m_pBitmap;
|
||
};
|
||
|
||
|
||
class ShadowLabel : public Label
|
||
{
|
||
public:
|
||
ShadowLabel(const char* text,int x,int y) : Label(text, x, y) {}
|
||
|
||
protected:
|
||
virtual void paint()
|
||
{
|
||
int mr, mg, mb, ma;
|
||
int ix, iy;
|
||
getFgColor(mr, mg, mb, ma);
|
||
_textImage->getPos(ix, iy);
|
||
_textImage->setPos(ix+1, iy+1);
|
||
_textImage->setColor( Color(0, 0, 0, ma) );
|
||
_textImage->doPaint(this);
|
||
_textImage->setPos(ix, iy);
|
||
_textImage->setColor( Color(mr, mg, mb, ma) );
|
||
_textImage->doPaint(this);
|
||
}
|
||
};
|
||
|
||
void Hud2Init()
|
||
{
|
||
// gEngfuncs.pfnHookUserMsg("RadioIcon", MsgShowRadioIcon);
|
||
}
|
||
|
||
void CHud2::Initialize()
|
||
{
|
||
health = -1;
|
||
armor = -1;
|
||
stamina = 1;
|
||
m_fMedkitUpdateTime = 0;
|
||
m_fUsageUpdateTime = 0; // Wargon: Иконка юза.
|
||
}
|
||
|
||
CHud2::CHud2() : Panel(0, 0, XRES(640), YRES(480))
|
||
{
|
||
CSchemeManager *pSchemes = gViewPort->GetSchemeManager();
|
||
SchemeHandle_t hTextScheme = pSchemes->getSchemeHandle( "Default Text" );
|
||
Font *pFont = pSchemes->getFont( hTextScheme );
|
||
|
||
hTextScheme = pSchemes->getSchemeHandle( "impact" );
|
||
m_pFontDigits = pSchemes->getFont( hTextScheme );
|
||
|
||
//
|
||
// create medkits icon
|
||
//
|
||
int mediconypos = YRES(340);
|
||
m_pMedkitsIcon = new CImageLabel("painkiller", XRES(10), mediconypos);
|
||
if (!m_pMedkitsIcon->m_pTGA)
|
||
{
|
||
delete m_pMedkitsIcon;
|
||
m_pMedkitsIcon = NULL;
|
||
m_pMedkitsCount = NULL;
|
||
gEngfuncs.Con_Printf("Painkiller icon cannot be loaded\n");
|
||
}
|
||
else
|
||
{
|
||
m_pMedkitsIcon->setParent(this);
|
||
m_pMedkitsIcon->setPaintBackgroundEnabled(false);
|
||
m_pMedkitsIcon->setVisible(false);
|
||
|
||
int bw, bt;
|
||
m_pMedkitsIcon->m_pTGA->getSize(bw, bt);
|
||
m_pMedkitsIcon->setSize(bw, bt);
|
||
m_pMedkitsCount = new ShadowLabel("", XRES(15)+bw, (mediconypos+bt/2)-(m_pFontDigits->getTall()/2));
|
||
m_pMedkitsCount->setSize(XRES(200), YRES(200)); // ?
|
||
m_pMedkitsCount->setContentAlignment(Label::a_northwest); // ?
|
||
m_pMedkitsCount->setTextAlignment(Label::a_northwest); // ?
|
||
m_pMedkitsCount->setParent(this);
|
||
m_pMedkitsCount->setVisible(false);
|
||
m_pMedkitsCount->setFont(m_pFontDigits /*pFont*/);
|
||
m_pMedkitsCount->setFgColor(255, 255, 255, 0);
|
||
m_pMedkitsCount->setPaintBackgroundEnabled(false);
|
||
m_pMedkitsOldNum = 0;
|
||
m_fMedkitUpdateTime = 0;
|
||
}
|
||
|
||
//
|
||
// create head shield icon
|
||
//
|
||
mediconypos = YRES(300);
|
||
m_pShieldIcon = new CImageLabel( "shield", XRES( 10 ), mediconypos );
|
||
if (!m_pShieldIcon->m_pTGA)
|
||
{
|
||
delete m_pShieldIcon;
|
||
m_pShieldIcon = NULL;
|
||
ALERT( at_error, "Head Shield icon cannot be loaded\n" );
|
||
}
|
||
else
|
||
{
|
||
m_pShieldIcon->setParent(this);
|
||
m_pShieldIcon->setPaintBackgroundEnabled(false);
|
||
m_pShieldIcon->setVisible(false);
|
||
int bw, bt;
|
||
m_pShieldIcon->m_pTGA->getSize(bw, bt);
|
||
m_pShieldIcon->setSize(bw, bt);
|
||
}
|
||
|
||
//
|
||
// create head shield icon
|
||
//
|
||
mediconypos = YRES(260);
|
||
m_pGasMaskIcon = new CImageLabel( "gasmask", XRES( 10 ), mediconypos );
|
||
if (!m_pGasMaskIcon->m_pTGA)
|
||
{
|
||
delete m_pGasMaskIcon;
|
||
m_pGasMaskIcon = NULL;
|
||
ALERT( at_error, "Gas Mask icon cannot be loaded\n" );
|
||
}
|
||
else
|
||
{
|
||
m_pGasMaskIcon->setParent(this);
|
||
m_pGasMaskIcon->setPaintBackgroundEnabled(false);
|
||
m_pGasMaskIcon->setVisible(false);
|
||
int bw, bt;
|
||
m_pGasMaskIcon->m_pTGA->getSize(bw, bt);
|
||
m_pGasMaskIcon->setSize(bw, bt);
|
||
}
|
||
|
||
//
|
||
// load health bars
|
||
//
|
||
m_pBitmapHealthFull = new ImageHolder("gfx/vgui/%d_health_full.tga", this);
|
||
m_pBitmapHealthEmpty = new ImageHolder("gfx/vgui/%d_health_empty.tga", this);
|
||
m_pBitmapHealthFlash = new ImageHolder("gfx/vgui/%d_health_flash.tga", this);
|
||
if (m_pBitmapHealthFull->GetBitmap())
|
||
m_pBitmapHealthFull->GetBitmap()->getSize(m_iHealthBarWidth, m_iHealthBarHeight);
|
||
else
|
||
m_iHealthBarWidth = m_iHealthBarHeight = 0;
|
||
|
||
m_pBitmapArmorFull = new ImageHolder("gfx/vgui/%d_armor_full.tga", this);
|
||
m_pBitmapArmorEmpty = new ImageHolder("gfx/vgui/%d_armor_empty.tga", this);
|
||
m_pBitmapArmorFlash = new ImageHolder("gfx/vgui/%d_armor_flash.tga", this);
|
||
if (m_pBitmapArmorFull->GetBitmap())
|
||
m_pBitmapArmorFull->GetBitmap()->getSize(m_iArmorBarWidth, m_iArmorBarHeight);
|
||
else
|
||
m_iArmorBarWidth = m_iArmorBarHeight = 0;
|
||
|
||
m_pBitmapStaminaFull = new ImageHolder("gfx/vgui/%d_stamina_full.tga", this);
|
||
m_pBitmapStaminaEmpty = new ImageHolder("gfx/vgui/%d_stamina_empty.tga", this);
|
||
m_pBitmapStaminaFlash = new ImageHolder("gfx/vgui/%d_stamina_flash.tga", this);
|
||
if (m_pBitmapStaminaFull->GetBitmap())
|
||
m_pBitmapStaminaFull->GetBitmap()->getSize(m_iStaminaBarWidth, m_iStaminaBarHeight);
|
||
else
|
||
m_iStaminaBarWidth = m_iStaminaBarHeight = 0;
|
||
|
||
m_pHealthIcon = new ImageHolder("gfx/vgui/%d_health_icon.tga", this);
|
||
m_pArmorIcon = new ImageHolder("gfx/vgui/%d_armor_icon.tga", this);
|
||
m_pStaminaIcon = new ImageHolder("gfx/vgui/%d_stamina_icon.tga", this);
|
||
int healthiconwidth = 0, healthiconheight = 0;
|
||
int armoriconwidth = 0, armoriconheight = 0;
|
||
int staminaiconwidth = 0, staminaiconheight = 0;
|
||
if (m_pHealthIcon->GetBitmap())
|
||
{
|
||
m_pHealthIcon->GetBitmap()->getSize(healthiconwidth, healthiconheight);
|
||
m_pHealthIcon->setSize(healthiconwidth, healthiconheight);
|
||
}
|
||
|
||
if (m_pArmorIcon->GetBitmap())
|
||
{
|
||
m_pArmorIcon->GetBitmap()->getSize(armoriconwidth, armoriconheight);
|
||
m_pArmorIcon->setSize(armoriconwidth, armoriconheight);
|
||
}
|
||
|
||
if (m_pStaminaIcon->GetBitmap())
|
||
{
|
||
m_pStaminaIcon->GetBitmap()->getSize(staminaiconwidth, staminaiconheight);
|
||
m_pStaminaIcon->setSize(staminaiconwidth, staminaiconheight);
|
||
}
|
||
|
||
int line = ScreenHeight - HEALTH_DOWN_OFFSET;
|
||
if (m_pStaminaIcon->GetBitmap())
|
||
{
|
||
if (staminaiconheight > m_iStaminaBarHeight) line -= staminaiconheight/2;
|
||
else line -= m_iStaminaBarHeight/2;
|
||
|
||
m_pStaminaIcon->setPos(HEALTH_RIGHT_OFFSET, line - staminaiconheight/2);
|
||
m_iStaminaBarXpos = HEALTH_RIGHT_OFFSET + staminaiconwidth + YRES(5);
|
||
m_iStaminaBarYpos = line - m_iStaminaBarHeight/2;
|
||
|
||
if (staminaiconheight > m_iStaminaBarHeight) line = ScreenHeight - HEALTH_DOWN_OFFSET - staminaiconheight - HEALTH_MIN_SPACE;
|
||
//else line = ScreenHeight - HEALTH_DOWN_OFFSET - m_iStaminaBarHeight - HEALTH_MIN_SPACE;
|
||
else line -= m_iStaminaBarHeight - HEALTH_MIN_SPACE;
|
||
}
|
||
else
|
||
{
|
||
line -= m_iStaminaBarHeight;
|
||
m_iStaminaBarXpos = HEALTH_RIGHT_OFFSET + YRES(5);
|
||
m_iStaminaBarYpos = line;
|
||
line -= HEALTH_MIN_SPACE;
|
||
}
|
||
|
||
if (m_pArmorIcon->GetBitmap())
|
||
{
|
||
if (armoriconheight > m_iArmorBarHeight) line -= armoriconheight/2;
|
||
else line -= m_iArmorBarHeight/2;
|
||
|
||
m_pArmorIcon->setPos(HEALTH_RIGHT_OFFSET, line - armoriconheight/2);
|
||
m_iArmorBarXpos = HEALTH_RIGHT_OFFSET + armoriconwidth + YRES(5);
|
||
m_iArmorBarYpos = line - m_iArmorBarHeight/2;
|
||
|
||
if (armoriconheight > m_iArmorBarHeight) line = ScreenHeight - HEALTH_DOWN_OFFSET - armoriconheight - HEALTH_MIN_SPACE;
|
||
// else line = ScreenHeight - HEALTH_DOWN_OFFSET - m_iArmorBarHeight - HEALTH_MIN_SPACE;
|
||
else line -= m_iArmorBarHeight - HEALTH_MIN_SPACE;
|
||
}
|
||
else
|
||
{
|
||
line -= m_iArmorBarHeight;
|
||
m_iArmorBarXpos = HEALTH_RIGHT_OFFSET + YRES(5);
|
||
m_iArmorBarYpos = line;
|
||
line -= HEALTH_MIN_SPACE;
|
||
}
|
||
|
||
if (m_pHealthIcon->GetBitmap())
|
||
{
|
||
if (healthiconheight > m_iHealthBarHeight) line -= healthiconheight/2;
|
||
else line -= m_iHealthBarHeight/2;
|
||
|
||
m_pHealthIcon->setPos(HEALTH_RIGHT_OFFSET, line - healthiconheight/2);
|
||
m_iHealthBarXpos = HEALTH_RIGHT_OFFSET + healthiconwidth + YRES(5);
|
||
m_iHealthBarYpos = line - m_iHealthBarHeight/2;
|
||
}
|
||
else
|
||
{
|
||
line -= m_iHealthBarHeight;
|
||
m_iHealthBarXpos = HEALTH_RIGHT_OFFSET + YRES(5);
|
||
m_iHealthBarYpos = line;
|
||
}
|
||
|
||
m_iNumWeaponNames = 0;
|
||
|
||
char **filenames = NULL;
|
||
char token[256], *weapon_name;
|
||
int i = 0;
|
||
|
||
if( g_fXashEngine && g_fRenderInitialized )
|
||
filenames = FS_SEARCH( "gfx/vgui/ammo/*.tga", &m_iNumWeaponNames, FALSE );
|
||
|
||
if( m_iNumWeaponNames > NUM_WEAPON_ICONS )
|
||
{
|
||
ALERT( at_warning, "too many ammo images in gfx/vgui/ammo folder\n" );
|
||
m_iNumWeaponNames = NUM_WEAPON_ICONS;
|
||
}
|
||
|
||
// convert filepathes into weapon names
|
||
for( i = 0; i < m_iNumWeaponNames; i++ )
|
||
{
|
||
COM_FileBase( filenames[i], token );
|
||
weapon_name = Q_strchr( token, '_' ) + 1; // skip first _
|
||
m_pWeaponNames[i] = copystring( weapon_name );
|
||
}
|
||
|
||
//
|
||
// load ammo icons
|
||
//
|
||
for( i = 0; i < m_iNumWeaponNames; i++ )
|
||
{
|
||
char path[256] = "gfx/vgui/ammo/%d_";
|
||
Q_strcat( path, m_pWeaponNames[i] );
|
||
Q_strcat( path, ".tga" );
|
||
m_pWeaponIconsArray[i] = LoadResolutionImage( path );
|
||
|
||
if( !m_pWeaponIconsArray[i] ) // probably this is not possible but who knews...
|
||
ALERT( at_error, "Failed to load ammo icon [%s]\n", m_pWeaponNames[i] );
|
||
}
|
||
|
||
//
|
||
// Wargon: Иконка юза.
|
||
//
|
||
m_pUsageIcon = new CImageLabel( "usage", ScreenWidth / 2 - 12, ScreenHeight / 2 + 100 );
|
||
|
||
if( !m_pUsageIcon->m_pTGA )
|
||
{
|
||
delete m_pUsageIcon;
|
||
m_pUsageIcon = NULL;
|
||
ALERT( at_console, "Usage icon can't be loaded\n" );
|
||
}
|
||
else
|
||
{
|
||
int bw, bt;
|
||
m_pUsageIcon->setParent(this);
|
||
m_pUsageIcon->setPaintBackgroundEnabled(false);
|
||
m_pUsageIcon->setVisible(false);
|
||
m_pUsageIcon->m_pTGA->getSize(bw, bt);
|
||
m_pUsageIcon->setSize(bw, bt);
|
||
m_fUsageUpdateTime = 0;
|
||
}
|
||
}
|
||
|
||
CHud2 :: ~CHud2()
|
||
{
|
||
for (int i = 0; i < m_iNumWeaponNames; i++)
|
||
{
|
||
delete m_pWeaponNames[i];
|
||
delete m_pWeaponIconsArray[i];
|
||
}
|
||
}
|
||
|
||
void CHud2::paintBackground()
|
||
{
|
||
// Panel::paintBackground();
|
||
}
|
||
|
||
|
||
// buz: I dunno exactly, what solve() function does. I just wanna to find
|
||
// some function, who being called each frame, to put panels position setting in there.
|
||
// I've tried paintBackground, Chud::Redraw, CHud::Think, and some others, but
|
||
// health and armor bars sizes are jumping during interpolation and
|
||
// panels motion looks jerky (especially in steam version).
|
||
// Putting this in solve() seems to fix first problem.
|
||
void CHud2::solve()
|
||
{
|
||
float curtime = gEngfuncs.GetClientTime();
|
||
|
||
// Wargon: Иконка юза.
|
||
if (m_pUsageIcon)
|
||
{
|
||
m_fUsageUpdateTime = curtime;
|
||
if (CanUseStatus && gHUD.m_pCvarDraw->value && !(gViewPort && gViewPort->m_pParanoiaText && gViewPort->m_pParanoiaText->isVisible()))
|
||
{
|
||
m_pUsageIcon->setVisible(true);
|
||
if (m_fUsageUpdateTime > curtime)
|
||
m_fUsageUpdateTime = curtime;
|
||
float frac = curtime - m_fUsageUpdateTime;
|
||
int alpha = USAGE_ALPHA;
|
||
if (frac < USAGE_FADE_TIME)
|
||
{
|
||
frac = frac / USAGE_FADE_TIME;
|
||
alpha = (int)(frac * USAGE_ALPHA);
|
||
}
|
||
m_pUsageIcon->m_pTGA->setColor(Color(255, 255, 255, alpha));
|
||
}
|
||
else
|
||
m_pUsageIcon->setVisible(false);
|
||
}
|
||
|
||
// update medkits counter
|
||
if (m_pMedkitsIcon)
|
||
{
|
||
WEAPON *pPainkillers = gWR.GetWeapon( WEAPON_PAINKILLER );
|
||
int pkcount = gWR.CountAmmo( pPainkillers->iAmmoType );
|
||
if ( pkcount != m_pMedkitsOldNum )
|
||
{
|
||
char temp[16];
|
||
sprintf(temp, "%d", pkcount);
|
||
m_pMedkitsCount->setText(temp);
|
||
m_pMedkitsOldNum = pkcount;
|
||
m_fMedkitUpdateTime = curtime;
|
||
}
|
||
|
||
if (pkcount && ShouldDrawHUD())
|
||
{
|
||
m_pMedkitsIcon->setVisible(true);
|
||
m_pMedkitsCount->setVisible(true);
|
||
|
||
if (m_fMedkitUpdateTime > curtime) // fix possible map change bugs
|
||
m_fMedkitUpdateTime = curtime;
|
||
|
||
float frac = curtime - m_fMedkitUpdateTime;
|
||
int alpha = HEALTH_ALPHA;
|
||
if (frac < HEALTH_FADE_TIME)
|
||
{
|
||
frac = frac / HEALTH_FADE_TIME;
|
||
alpha = (int)(frac * HEALTH_ALPHA);
|
||
}
|
||
m_pMedkitsIcon->m_pTGA->setColor(Color(255, 255, 255, alpha));
|
||
m_pMedkitsCount->setFgColor(255, 255, 255, alpha);
|
||
}
|
||
else
|
||
{
|
||
m_pMedkitsIcon->setVisible(false);
|
||
m_pMedkitsCount->setVisible(false);
|
||
}
|
||
}
|
||
|
||
if (m_pShieldIcon)
|
||
{
|
||
if (FBitSet( gHUD.m_iHideHUDDisplay, ITEM_HEADSHIELD ) && ShouldDrawHUD())
|
||
{
|
||
m_pShieldIcon->setVisible(true);
|
||
m_pShieldIcon->m_pTGA->setColor(Color(255, 255, 255, 0 ));
|
||
}
|
||
else
|
||
{
|
||
m_pShieldIcon->setVisible(false);
|
||
}
|
||
}
|
||
|
||
if (m_pGasMaskIcon)
|
||
{
|
||
if (FBitSet( gHUD.m_iHideHUDDisplay, ITEM_GASMASK ) && ShouldDrawHUD())
|
||
{
|
||
m_pGasMaskIcon->setVisible(true);
|
||
m_pGasMaskIcon->m_pTGA->setColor(Color(255, 255, 255, 0 ));
|
||
}
|
||
else
|
||
{
|
||
m_pGasMaskIcon->setVisible(false);
|
||
}
|
||
}
|
||
|
||
//
|
||
// update health and armor bars
|
||
// (damn, it's so messy...)
|
||
|
||
int healthdiv;
|
||
//Stamina bar
|
||
if (m_pBitmapStaminaEmpty->GetBitmap() && m_pBitmapStaminaFull->GetBitmap())
|
||
{
|
||
m_pBitmapStaminaFlash->setVisible(false);
|
||
m_pBitmapStaminaEmpty->GetBitmap()->setColor(Color(255, 255, 255, 0));
|
||
m_pBitmapStaminaFull->GetBitmap()->setColor(Color(255, 255, 255, 0));
|
||
if (m_pStaminaIcon->GetBitmap())
|
||
m_pStaminaIcon->GetBitmap()->setColor(Color(255, 255, 255, 0));
|
||
if (curtime >= m_fStaminaUpdateTime + HEALTH_FLASH_TIME)
|
||
{
|
||
healthdiv = (int)((float)stamina/100 * m_iStaminaBarWidth);
|
||
float frac = curtime - m_fStaminaUpdateTime - HEALTH_FLASH_TIME;
|
||
int targetalpha = HEALTH_ALPHA;
|
||
if (stamina == 0) targetalpha = HEALTH_ZERO_ALPHA;
|
||
int alpha = targetalpha;
|
||
if (frac < HEALTH_FADE_TIME)
|
||
{
|
||
frac = frac / HEALTH_FADE_TIME;
|
||
alpha = (int)(frac * targetalpha);
|
||
}
|
||
m_pBitmapStaminaEmpty->GetBitmap()->setColor(Color(255, 255, 255, alpha));
|
||
m_pBitmapStaminaFull->GetBitmap()->setColor(Color(255, 255, 255, alpha));
|
||
if (m_pStaminaIcon->GetBitmap())
|
||
m_pStaminaIcon->GetBitmap()->setColor(Color(255, 255, 255, alpha));
|
||
}
|
||
else
|
||
{
|
||
float frac = (curtime - m_fStaminaUpdateTime) / HEALTH_FLASH_TIME;
|
||
if ((stamina < oldstamina) && m_pBitmapStaminaFlash->GetBitmap()) // we had take damage, make red flash
|
||
{
|
||
m_pBitmapStaminaFlash->setVisible(true);
|
||
m_pBitmapStaminaFlash->GetBitmap()->setColor(Color(255, 255, 255, 255*frac));
|
||
}
|
||
frac = 1 - frac;
|
||
frac *= frac;
|
||
healthdiv = stamina - (int)((float)(stamina - oldstamina)*frac);
|
||
healthdiv = (int)((float)healthdiv/100 * m_iStaminaBarWidth);
|
||
}
|
||
|
||
m_pBitmapStaminaFull->setBounds(m_iStaminaBarXpos, m_iStaminaBarYpos, healthdiv, m_iStaminaBarHeight);
|
||
m_pBitmapStaminaFlash->setBounds(m_iStaminaBarXpos, m_iStaminaBarYpos, healthdiv, m_iStaminaBarHeight);
|
||
|
||
m_pBitmapStaminaEmpty->setBounds(m_iStaminaBarXpos + healthdiv, m_iStaminaBarYpos,
|
||
m_iStaminaBarWidth - healthdiv, m_iStaminaBarHeight);
|
||
m_pBitmapStaminaEmpty->GetBitmap()->setPos( -healthdiv, 0 );
|
||
}
|
||
// health bar
|
||
if (m_pBitmapHealthEmpty->GetBitmap() && m_pBitmapHealthFull->GetBitmap())
|
||
{
|
||
m_pBitmapHealthFlash->setVisible(false);
|
||
m_pBitmapHealthEmpty->GetBitmap()->setColor(Color(255, 255, 255, 0));
|
||
m_pBitmapHealthFull->GetBitmap()->setColor(Color(255, 255, 255, 0));
|
||
if (m_pHealthIcon->GetBitmap())
|
||
m_pHealthIcon->GetBitmap()->setColor(Color(255, 255, 255, 0));
|
||
|
||
if (curtime >= m_fHealthUpdateTime + HEALTH_FLASH_TIME)
|
||
{
|
||
healthdiv = (int)((float)health/100 * m_iHealthBarWidth);
|
||
float frac = curtime - m_fHealthUpdateTime - HEALTH_FLASH_TIME;
|
||
int targetalpha = HEALTH_ALPHA;
|
||
if (health == 0) targetalpha = HEALTH_ZERO_ALPHA;
|
||
int alpha = targetalpha;
|
||
if (frac < HEALTH_FADE_TIME)
|
||
{
|
||
frac = frac / HEALTH_FADE_TIME;
|
||
alpha = (int)(frac * targetalpha);
|
||
}
|
||
m_pBitmapHealthEmpty->GetBitmap()->setColor(Color(255, 255, 255, alpha));
|
||
m_pBitmapHealthFull->GetBitmap()->setColor(Color(255, 255, 255, alpha));
|
||
if (m_pHealthIcon->GetBitmap())
|
||
m_pHealthIcon->GetBitmap()->setColor(Color(255, 255, 255, alpha));
|
||
|
||
}
|
||
else
|
||
{
|
||
float frac = (curtime - m_fHealthUpdateTime) / HEALTH_FLASH_TIME;
|
||
if ((health < oldhealth) && m_pBitmapHealthFlash->GetBitmap()) // we had take damage, make red flash
|
||
{
|
||
m_pBitmapHealthFlash->setVisible(true);
|
||
m_pBitmapHealthFlash->GetBitmap()->setColor(Color(255, 255, 255, 255*frac));
|
||
}
|
||
frac = 1 - frac;
|
||
frac *= frac;
|
||
healthdiv = health - (int)((float)(health - oldhealth)*frac);
|
||
healthdiv = (int)((float)healthdiv/100 * m_iHealthBarWidth);
|
||
}
|
||
|
||
m_pBitmapHealthFull->setBounds(m_iHealthBarXpos, m_iHealthBarYpos, healthdiv, m_iHealthBarHeight);
|
||
m_pBitmapHealthFlash->setBounds(m_iHealthBarXpos, m_iHealthBarYpos, healthdiv, m_iHealthBarHeight);
|
||
|
||
m_pBitmapHealthEmpty->setBounds(m_iHealthBarXpos + healthdiv, m_iHealthBarYpos,
|
||
m_iHealthBarWidth - healthdiv, m_iHealthBarHeight);
|
||
m_pBitmapHealthEmpty->GetBitmap()->setPos( -healthdiv, 0 );
|
||
}
|
||
|
||
// armor bar
|
||
if (m_pBitmapArmorEmpty->GetBitmap() && m_pBitmapArmorFull->GetBitmap())
|
||
{
|
||
m_pBitmapArmorFlash->setVisible(false);
|
||
m_pBitmapArmorEmpty->GetBitmap()->setColor(Color(255, 255, 255, 0));
|
||
m_pBitmapArmorFull->GetBitmap()->setColor(Color(255, 255, 255, 0));
|
||
if (m_pArmorIcon->GetBitmap())
|
||
m_pArmorIcon->GetBitmap()->setColor(Color(255, 255, 255, 0));
|
||
if (curtime >= m_fArmorUpdateTime + HEALTH_FLASH_TIME)
|
||
{
|
||
healthdiv = (int)((float)armor/100 * m_iArmorBarWidth);
|
||
float frac = curtime - m_fArmorUpdateTime - HEALTH_FLASH_TIME;
|
||
int targetalpha = HEALTH_ALPHA;
|
||
if (armor == 0) targetalpha = HEALTH_ZERO_ALPHA;
|
||
int alpha = targetalpha;
|
||
if (frac < HEALTH_FADE_TIME)
|
||
{
|
||
frac = frac / HEALTH_FADE_TIME;
|
||
alpha = (int)(frac * targetalpha);
|
||
}
|
||
m_pBitmapArmorEmpty->GetBitmap()->setColor(Color(255, 255, 255, alpha));
|
||
m_pBitmapArmorFull->GetBitmap()->setColor(Color(255, 255, 255, alpha));
|
||
if (m_pArmorIcon->GetBitmap())
|
||
m_pArmorIcon->GetBitmap()->setColor(Color(255, 255, 255, alpha));
|
||
}
|
||
else
|
||
{
|
||
float frac = (curtime - m_fArmorUpdateTime) / HEALTH_FLASH_TIME;
|
||
if ((armor < oldarmor) && m_pBitmapArmorFlash->GetBitmap()) // we had take damage, make red flash
|
||
{
|
||
m_pBitmapArmorFlash->setVisible(true);
|
||
m_pBitmapArmorFlash->GetBitmap()->setColor(Color(255, 255, 255, 255*frac));
|
||
}
|
||
frac = 1 - frac;
|
||
frac *= frac;
|
||
healthdiv = armor - (int)((float)(armor - oldarmor)*frac);
|
||
healthdiv = (int)((float)healthdiv/100 * m_iArmorBarWidth);
|
||
}
|
||
|
||
m_pBitmapArmorFull->setBounds(m_iArmorBarXpos, m_iArmorBarYpos, healthdiv, m_iArmorBarHeight);
|
||
m_pBitmapArmorFlash->setBounds(m_iArmorBarXpos, m_iArmorBarYpos, healthdiv, m_iArmorBarHeight);
|
||
|
||
m_pBitmapArmorEmpty->setBounds(m_iArmorBarXpos + healthdiv, m_iArmorBarYpos,
|
||
m_iArmorBarWidth - healthdiv, m_iArmorBarHeight);
|
||
m_pBitmapArmorEmpty->GetBitmap()->setPos( -healthdiv, 0 );
|
||
}
|
||
Panel::solve();
|
||
}
|
||
|
||
|
||
void CHud2::paint()
|
||
{
|
||
//
|
||
// draw ammo counters
|
||
//
|
||
if ( ShouldDrawHUD() ) // Wargon: Информация о патронах рисуется только если hud_draw = 1.
|
||
{
|
||
WEAPON *pw = gHUD.m_Ammo.m_pWeapon; // shorthand
|
||
if (gHUD.m_SpecTank_on)
|
||
{
|
||
int x = ScreenWidth - HEALTH_RIGHT_OFFSET;
|
||
int y = ScreenHeight - HEALTH_DOWN_OFFSET;
|
||
|
||
BitmapTGA* pImg = FindAmmoImageForWeapon("machinegun");
|
||
if (pImg)
|
||
{
|
||
int iw, ih;
|
||
pImg->getSize(iw, ih);
|
||
x -= iw;
|
||
pImg->setColor(Color(255, 255, 255, 0)); // TEST
|
||
pImg->setPos(x, y - ih);
|
||
pImg->doPaint(this);
|
||
x -= XRES(6); // make some space between icon and text
|
||
y -= 10;
|
||
}
|
||
|
||
if (gHUD.m_SpecTank_Ammo != -1)
|
||
{
|
||
// draw ammo count string
|
||
int tw, th;
|
||
char buf[256];
|
||
drawSetTextFont(m_pFontDigits);
|
||
drawSetTextColor(250, 250, 250, 0); // TEST
|
||
|
||
sprintf(buf, "%d", gHUD.m_SpecTank_Ammo);
|
||
m_pFontDigits->getTextSize(buf, tw, th);
|
||
x -= tw; y -= th;
|
||
drawSetTextPos(x, y); drawPrintText(buf, strlen(buf));
|
||
}
|
||
}
|
||
else if (pw)
|
||
{
|
||
int x = ScreenWidth - HEALTH_RIGHT_OFFSET;
|
||
int y = ScreenHeight - HEALTH_DOWN_OFFSET;
|
||
|
||
// Do we have secondary ammo?
|
||
if ((pw->iAmmo2Type > 0) && (gWR.CountAmmo(pw->iAmmo2Type) > 0))
|
||
{
|
||
// Draw the secondary ammo Icon
|
||
char buf[256];
|
||
sprintf(buf, "%s_sec", pw->szName);
|
||
BitmapTGA* pImg = FindAmmoImageForWeapon(buf);
|
||
if (pImg)
|
||
{
|
||
int iw, ih;
|
||
pImg->getSize(iw, ih);
|
||
x -= iw;
|
||
pImg->setColor(Color(255, 255, 255, 0)); // TEST
|
||
pImg->setPos(x, y - ih);
|
||
pImg->doPaint(this);
|
||
x -= XRES(6); // make some space between icon and text
|
||
y -= 10;
|
||
}
|
||
|
||
// draw ammo count string
|
||
int tw, th;
|
||
sprintf(buf, "%d", gWR.CountAmmo(pw->iAmmo2Type));
|
||
|
||
m_pFontDigits->getTextSize(buf, tw, th);
|
||
drawSetTextFont(m_pFontDigits);
|
||
drawSetTextColor(250, 250, 250, 0); // TEST
|
||
drawSetTextPos(x - tw, y - th);
|
||
drawPrintText(buf, strlen(buf));
|
||
x = ScreenWidth - HEALTH_RIGHT_OFFSET - XRES(100);
|
||
}
|
||
|
||
if (pw->iAmmoType > 0)
|
||
{
|
||
y = ScreenHeight - HEALTH_DOWN_OFFSET;
|
||
|
||
// Draw the ammo Icon
|
||
BitmapTGA* pImg = FindAmmoImageForWeapon(pw->szName);
|
||
if (pImg)
|
||
{
|
||
int iw, ih;
|
||
pImg->getSize(iw, ih);
|
||
x -= iw;
|
||
pImg->setColor(Color(255, 255, 255, 0)); // TEST
|
||
pImg->setPos(x, y - ih);
|
||
pImg->doPaint(this);
|
||
x -= XRES(6); // make some space between icon and text
|
||
y -= 10;
|
||
}
|
||
|
||
// draw ammo count string
|
||
int tw, th;
|
||
char buf[256];
|
||
drawSetTextFont(m_pFontDigits);
|
||
drawSetTextColor(250, 250, 250, 0); // TEST
|
||
|
||
sprintf(buf, "%d", gWR.CountAmmo(pw->iAmmoType));
|
||
m_pFontDigits->getTextSize(buf, tw, th);
|
||
x -= tw; y -= th;
|
||
drawSetTextPos(x, y); drawPrintText(buf, strlen(buf));
|
||
|
||
if (pw->iClip >= 0) // has clip?
|
||
{
|
||
x -= YRES(12);
|
||
drawSetTextPos(x, y); drawPrintText("/", 1);
|
||
|
||
sprintf(buf, "%d", pw->iClip);
|
||
m_pFontDigits->getTextSize(buf, tw, th);
|
||
x = x - tw - YRES(5);
|
||
drawSetTextPos(x, y); drawPrintText(buf, strlen(buf));
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
Panel::paint();
|
||
}
|
||
|
||
BitmapTGA* CHud2 :: FindAmmoImageForWeapon( const char *weapon )
|
||
{
|
||
for( int i = 0; i < m_iNumWeaponNames; i++ )
|
||
{
|
||
if( !Q_strcmp( weapon, m_pWeaponNames[i] ))
|
||
return m_pWeaponIconsArray[i];
|
||
}
|
||
|
||
return NULL;
|
||
}
|
||
|
||
void CHud2::UpdateHealth( int newhealth )
|
||
{
|
||
if (newhealth == health)
|
||
return;
|
||
|
||
if (health == -1) // first update, dont do effects
|
||
{
|
||
health = newhealth;
|
||
m_fHealthUpdateTime = -666;
|
||
return;
|
||
}
|
||
|
||
oldhealth = health;
|
||
health = newhealth;
|
||
m_fHealthUpdateTime = gEngfuncs.GetClientTime();
|
||
}
|
||
|
||
|
||
void CHud2::UpdateArmor( int newarmor )
|
||
{
|
||
if (newarmor == armor)
|
||
return;
|
||
|
||
if (armor == -1) // first update, dont do effects
|
||
{
|
||
armor = newarmor;
|
||
m_fArmorUpdateTime = -666;
|
||
return;
|
||
}
|
||
|
||
oldarmor = armor;
|
||
armor = newarmor;
|
||
m_fArmorUpdateTime = gEngfuncs.GetClientTime();
|
||
}
|
||
|
||
void CHud2::UpdateStamina( int newStamina )
|
||
{
|
||
if (newStamina == stamina)
|
||
return;
|
||
|
||
if (stamina == -1) // first update, dont do effects
|
||
{
|
||
stamina = newStamina;
|
||
m_fStaminaUpdateTime = -666;
|
||
return;
|
||
}
|
||
|
||
oldstamina = stamina;
|
||
stamina = newStamina;
|
||
m_fStaminaUpdateTime = gEngfuncs.GetClientTime();
|
||
}
|