518 lines
11 KiB
Plaintext
518 lines
11 KiB
Plaintext
/*
|
|
* Copyright (c) 2016-2021 Marco Cawthorne <marco@icculus.org>
|
|
*
|
|
* Permission to use, copy, modify, and distribute this software for any
|
|
* purpose with or without fee is hereby granted, provided that the above
|
|
* copyright notice and this permission notice appear in all copies.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
|
|
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
|
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
*/
|
|
|
|
void HUD_DrawWeaponSelect(void);
|
|
|
|
/* Use first frame for drawing (needs precache) */
|
|
#define NUMSIZE_X 24/256
|
|
#define NUMSIZE_Y 24/128
|
|
#define HUD_ALPHA 0.5
|
|
|
|
float spr_hudnum[10] = {
|
|
0 / 256,
|
|
24 / 256,
|
|
(24*2) / 256,
|
|
(24*3) / 256,
|
|
(24*4) / 256,
|
|
(24*5) / 256,
|
|
(24*6) / 256,
|
|
(24*7) / 256,
|
|
(24*8) / 256,
|
|
(24*9) / 256
|
|
};
|
|
|
|
/* pre-calculated sprite definitions */
|
|
float spr_health[4] = {
|
|
80 / 256, // pos x
|
|
24 / 128, // pos u
|
|
32 / 256, // size x
|
|
32 / 128 // size y
|
|
};
|
|
|
|
float spr_suit1[4] = {
|
|
0 / 256, // pos x
|
|
24 / 128, // pos u
|
|
40 / 256, // size x
|
|
40 / 128 // size y
|
|
};
|
|
|
|
float spr_suit2[4] = {
|
|
40 / 256, // pos x
|
|
24 / 128, // pos u
|
|
40 / 256, // size x
|
|
40 / 128 // size y
|
|
};
|
|
|
|
float spr_flash1[4] = {
|
|
160 / 256, // pos x
|
|
24 / 128, // pos u
|
|
32 / 256, // size x
|
|
32 / 128 // size y
|
|
};
|
|
|
|
float spr_flash2[4] = {
|
|
112 / 256, // pos x
|
|
24 / 128, // pos u
|
|
48 / 256, // size x
|
|
32 / 128 // size y
|
|
};
|
|
|
|
/* precaches */
|
|
void
|
|
HUD_Init(void)
|
|
{
|
|
g_cross_spr = spriteframe("sprites/crosshairs.spr", 0, 0.0f);
|
|
g_laser_spr = spriteframe("sprites/laserdot.spr", 0, 0.0f);
|
|
g_hud1_spr = spriteframe("sprites/640hud1.spr", 0, 0.0f);
|
|
g_hud2_spr = spriteframe("sprites/640hud2.spr", 0, 0.0f);
|
|
g_hud3_spr = spriteframe("sprites/640hud3.spr", 0, 0.0f);
|
|
g_hud4_spr = spriteframe("sprites/640hud4.spr", 0, 0.0f);
|
|
g_hud5_spr = spriteframe("sprites/640hud5.spr", 0, 0.0f);
|
|
g_hud6_spr = spriteframe("sprites/640hud6.spr", 0, 0.0f);
|
|
g_hud7_spr = spriteframe("sprites/640hud7.spr", 0, 0.0f);
|
|
HUD_AmmoNotify_Init();
|
|
HUD_DamageNotify_Init();
|
|
HUD_ItemNotify_Init();
|
|
}
|
|
|
|
/* seperator for mainly ammo */
|
|
void
|
|
HUD_DrawSeperator(vector pos)
|
|
{
|
|
drawsubpic(pos,
|
|
[2,24],
|
|
g_hud7_spr,
|
|
[240/256, 0],
|
|
[2/256, 24/128],
|
|
g_hud_color,
|
|
HUD_ALPHA,
|
|
DRAWFLAG_ADDITIVE
|
|
);
|
|
}
|
|
|
|
/* handle single/multiple digits */
|
|
void
|
|
HUD_DrawNumber(int iNumber, vector vecPos, float fAlpha, vector vColor)
|
|
{
|
|
drawsubpic(vecPos,
|
|
[24,24],
|
|
g_hud7_spr,
|
|
[spr_hudnum[iNumber], 0],
|
|
[NUMSIZE_X, NUMSIZE_Y],
|
|
vColor,
|
|
fAlpha,
|
|
DRAWFLAG_ADDITIVE
|
|
);
|
|
}
|
|
|
|
void
|
|
HUD_DrawNums(float fNumber, vector vecPos, float fAlpha, vector vColor)
|
|
{
|
|
int i = fNumber;
|
|
if (i > 0) {
|
|
while (i > 0) {
|
|
HUD_DrawNumber((float)i % 10.0f, vecPos, fAlpha, vColor);
|
|
i = i / 10;
|
|
vecPos[0] -= 20;
|
|
}
|
|
} else {
|
|
HUD_DrawNumber(0, vecPos, fAlpha, vColor);
|
|
}
|
|
}
|
|
|
|
/* health */
|
|
void
|
|
HUD_DrawHealth(void)
|
|
{
|
|
vector pos;
|
|
player pl = (player)pSeat->m_ePlayer;
|
|
|
|
if (pl.health != pSeatLocal->m_iHealthOld) {
|
|
pSeatLocal->m_flHealthAlpha = 1.0;
|
|
}
|
|
|
|
if (pSeatLocal->m_flHealthAlpha >= HUD_ALPHA) {
|
|
pSeatLocal->m_flHealthAlpha -= clframetime * 0.5;
|
|
} else {
|
|
pSeatLocal->m_flHealthAlpha = HUD_ALPHA;
|
|
}
|
|
|
|
pos = g_hudmins + [88, g_hudres[1] - 42];
|
|
if (pl.health > 25) {
|
|
drawsubpic(
|
|
pos + [-72,-4],
|
|
[32,32],
|
|
g_hud7_spr,
|
|
[spr_health[0], spr_health[1]],
|
|
[spr_health[2], spr_health[3]],
|
|
g_hud_color,
|
|
pSeatLocal->m_flHealthAlpha,
|
|
DRAWFLAG_ADDITIVE
|
|
);
|
|
HUD_DrawNums(pl.health, pos, pSeatLocal->m_flHealthAlpha, g_hud_color);
|
|
} else {
|
|
drawsubpic(
|
|
pos + [-72,-4],
|
|
[32,32],
|
|
g_hud7_spr,
|
|
[spr_health[0], spr_health[1]],
|
|
[spr_health[2], spr_health[3]],
|
|
[1,0,0],
|
|
pSeatLocal->m_flHealthAlpha,
|
|
DRAWFLAG_ADDITIVE
|
|
);
|
|
HUD_DrawNums(pl.health, pos, pSeatLocal->m_flHealthAlpha, [1,0,0]);
|
|
}
|
|
|
|
pSeatLocal->m_iHealthOld = pl.health;
|
|
}
|
|
|
|
/* armor/suit charge */
|
|
void
|
|
HUD_DrawArmor(void)
|
|
{
|
|
vector pos;
|
|
player pl = (player)pSeat->m_ePlayer;
|
|
|
|
pos = g_hudmins + [198, g_hudres[1] - 42];
|
|
|
|
if (pl.armor != pSeatLocal->m_iArmorOld) {
|
|
pSeatLocal->m_flArmorAlpha = 1.0;
|
|
}
|
|
|
|
if (pSeatLocal->m_flArmorAlpha >= HUD_ALPHA) {
|
|
pSeatLocal->m_flArmorAlpha -= clframetime * 0.5;
|
|
} else {
|
|
pSeatLocal->m_flArmorAlpha = HUD_ALPHA;
|
|
}
|
|
|
|
drawsubpic(
|
|
pos + [-80,-9],
|
|
[40,40],
|
|
g_hud7_spr,
|
|
[spr_suit2[0], spr_suit2[1]],
|
|
[spr_suit2[2], spr_suit2[3]],
|
|
g_hud_color,
|
|
pSeatLocal->m_flArmorAlpha,
|
|
DRAWFLAG_ADDITIVE
|
|
);
|
|
|
|
if (pl.armor > 0) {
|
|
float perc = (pl.armor / 100);
|
|
drawsubpic(
|
|
pos + [-80,-9] + [0, 40 * (1.0-perc)],
|
|
[40, 40 * perc],
|
|
g_hud7_spr,
|
|
[spr_suit1[0],spr_suit1[1] + spr_suit1[3] * (1.0-perc)],
|
|
[spr_suit1[2], spr_suit1[3] * perc],
|
|
g_hud_color,
|
|
pSeatLocal->m_flArmorAlpha,
|
|
DRAWFLAG_ADDITIVE
|
|
);
|
|
}
|
|
|
|
HUD_DrawNums(pl.armor, pos, pSeatLocal->m_flArmorAlpha, g_hud_color);
|
|
pSeatLocal->m_iArmorOld = pl.armor;
|
|
}
|
|
|
|
/* magazine/clip ammo */
|
|
void
|
|
HUD_DrawAmmo1(void)
|
|
{
|
|
player pl = (player)pSeat->m_ePlayer;
|
|
vector pos;
|
|
|
|
if (pl.a_ammo1 != pSeatLocal->m_iAmmo1Old) {
|
|
pSeatLocal->m_flAmmo1Alpha = 1.0;
|
|
pSeatLocal->m_iAmmo1Old = pl.a_ammo1;
|
|
}
|
|
|
|
if (pSeatLocal->m_flAmmo1Alpha >= HUD_ALPHA) {
|
|
pSeatLocal->m_flAmmo1Alpha -= clframetime * 0.5;
|
|
} else {
|
|
pSeatLocal->m_flAmmo1Alpha = HUD_ALPHA;
|
|
}
|
|
|
|
pos = g_hudmins + [g_hudres[0] - 152, g_hudres[1] - 42];
|
|
HUD_DrawNums(pl.a_ammo1, pos, pSeatLocal->m_flAmmo1Alpha, g_hud_color);
|
|
HUD_DrawSeperator(pos + [30,0]);
|
|
}
|
|
|
|
/* leftover type ammo */
|
|
void
|
|
HUD_DrawAmmo2(void)
|
|
{
|
|
player pl = (player)pSeat->m_ePlayer;
|
|
vector pos;
|
|
|
|
if (pl.a_ammo2 != pSeatLocal->m_iAmmo2Old) {
|
|
pSeatLocal->m_flAmmo2Alpha = 1.0;
|
|
pSeatLocal->m_iAmmo2Old = pl.a_ammo2;
|
|
}
|
|
|
|
if (pSeatLocal->m_flAmmo2Alpha >= HUD_ALPHA) {
|
|
pSeatLocal->m_flAmmo2Alpha -= clframetime * 0.5;
|
|
} else {
|
|
pSeatLocal->m_flAmmo2Alpha = HUD_ALPHA;
|
|
}
|
|
|
|
pos = g_hudmins + [g_hudres[0] - 72, g_hudres[1] - 42];
|
|
HUD_DrawNums(pl.a_ammo2, pos, pSeatLocal->m_flAmmo2Alpha, g_hud_color);
|
|
}
|
|
|
|
/* special ammo */
|
|
void
|
|
HUD_DrawAmmo3(void)
|
|
{
|
|
player pl = (player)pSeat->m_ePlayer;
|
|
vector pos;
|
|
|
|
if (pl.a_ammo3 != pSeatLocal->m_iAmmo3Old) {
|
|
pSeatLocal->m_flAmmo3Alpha = 1.0;
|
|
pSeatLocal->m_iAmmo3Old = pl.a_ammo3;
|
|
}
|
|
|
|
if (pSeatLocal->m_flAmmo3Alpha >= HUD_ALPHA) {
|
|
pSeatLocal->m_flAmmo3Alpha -= clframetime * 0.5;
|
|
} else {
|
|
pSeatLocal->m_flAmmo3Alpha = HUD_ALPHA;
|
|
}
|
|
|
|
pos = g_hudmins + [g_hudres[0] - 72, g_hudres[1] - 74];
|
|
HUD_DrawNums(pl.a_ammo3, pos, pSeatLocal->m_flAmmo3Alpha, g_hud_color);
|
|
}
|
|
|
|
/* ammo bar */
|
|
void
|
|
HUD_DrawAmmoBar(vector pos, float val, float max, float a)
|
|
{
|
|
if (val <= 0)
|
|
return;
|
|
|
|
float perc;
|
|
perc = val / max;
|
|
drawfill(pos + [10,0], [20,4], g_hud_color, a, DRAWFLAG_NORMAL);
|
|
drawfill(pos + [10,0], [20 * perc,4], [0,1,0], a, DRAWFLAG_NORMAL);
|
|
}
|
|
|
|
/* flashlight/torch indicator */
|
|
void
|
|
HUD_DrawFlashlight(void)
|
|
{
|
|
vector pos;
|
|
player pl = (player)pSeat->m_ePlayer;
|
|
pos = g_hudmins + [g_hudres[0] - 48, 16];
|
|
|
|
/* both on, draw both sprites at full intensity */
|
|
if (pl.gflags & GF_FLASHLIGHT) {
|
|
drawsubpic(
|
|
pos,
|
|
[32,32],
|
|
g_hud7_spr,
|
|
[spr_flash1[0], spr_flash1[1]],
|
|
[spr_flash1[2], spr_flash1[3]],
|
|
g_hud_color,
|
|
1.0f,
|
|
DRAWFLAG_ADDITIVE
|
|
);
|
|
|
|
drawsubpic(
|
|
pos,
|
|
[48,32],
|
|
g_hud7_spr,
|
|
[spr_flash2[0], spr_flash2[1]],
|
|
[spr_flash2[2], spr_flash2[3]],
|
|
g_hud_color,
|
|
1.0f,
|
|
DRAWFLAG_ADDITIVE
|
|
);
|
|
} else {
|
|
drawsubpic(
|
|
pos,
|
|
[32,32],
|
|
g_hud7_spr,
|
|
[spr_flash1[0], spr_flash1[1]],
|
|
[spr_flash1[2], spr_flash1[3]],
|
|
g_hud_color,
|
|
HUD_ALPHA,
|
|
DRAWFLAG_ADDITIVE
|
|
);
|
|
}
|
|
}
|
|
|
|
/* logo animation used during e3 1998 */
|
|
void
|
|
HUD_DrawLogo(void)
|
|
{
|
|
vector pos;
|
|
static int f;
|
|
static float frame_timer;
|
|
|
|
frame_timer -= clframetime;
|
|
pos = [g_hudres[0] - 262, 48];
|
|
|
|
drawpic(
|
|
pos,
|
|
sprintf("sprites/640_logo.spr_%i.tga", f),
|
|
[256,48],
|
|
[1,1,1],
|
|
1.0f,
|
|
DRAWFLAG_ADDITIVE
|
|
);
|
|
|
|
if (frame_timer > 0) {
|
|
return;
|
|
}
|
|
|
|
frame_timer = 0.1f;
|
|
|
|
f++;
|
|
if (f == 31) {
|
|
f = 0;
|
|
}
|
|
}
|
|
|
|
/* weapon/ammo pickup notifications */
|
|
void
|
|
HUD_DrawNotify(void)
|
|
{
|
|
player pl = (player)self;
|
|
vector pos;
|
|
float a;
|
|
|
|
pos = g_hudmins + [g_hudres[0] - 192, g_hudres[1] - 128];
|
|
|
|
if (pSeatLocal->m_flPickupAlpha <= 0.0f) {
|
|
pos[1] += 48;
|
|
HUD_ItemNotify_Draw(pos);
|
|
HUD_AmmoNotify_Draw(pos);
|
|
return;
|
|
}
|
|
|
|
a = bound(0.0, pSeatLocal->m_flPickupAlpha, 1.0);
|
|
pos[1] += 48 * (1.0 - a);
|
|
Weapons_HUDPic(pl, pSeatLocal->m_iPickupWeapon, 1, pos, a);
|
|
HUD_ItemNotify_Draw(pos);
|
|
HUD_AmmoNotify_Draw(pos);
|
|
pSeatLocal->m_flPickupAlpha -= (clframetime * 0.5);
|
|
}
|
|
|
|
void
|
|
HUD_WeaponPickupNotify(int w)
|
|
{
|
|
#if defined (VALVE) || defined (GEARBOX)
|
|
switch (w) {
|
|
case WEAPON_SNARK:
|
|
case WEAPON_SATCHEL:
|
|
case WEAPON_HANDGRENADE:
|
|
case WEAPON_TRIPMINE:
|
|
#if defined(GEARBOX)
|
|
case WEAPON_PENGUIN:
|
|
#endif
|
|
return;
|
|
default:
|
|
}
|
|
#endif
|
|
|
|
pSeatLocal->m_iPickupWeapon = w;
|
|
pSeatLocal->m_flPickupAlpha = 2.5f;
|
|
}
|
|
|
|
void
|
|
HUD_DrawDamageIndicator(void)
|
|
{
|
|
vector cross_pos;
|
|
|
|
if (pSeatLocal->m_flDamageIndicator <= 0.0)
|
|
return;
|
|
|
|
cross_pos = g_hudmins + (g_hudres / 2) + [-12,-12];
|
|
|
|
/*drawsubpic(
|
|
cross_pos,
|
|
[24,24],
|
|
g_cross_spr,
|
|
[0.0, 72/128],
|
|
[0.1875, 0.1875],
|
|
[1,1,1] * pSeatLocal->m_flDamageIndicator,
|
|
1.0f,
|
|
DRAWFLAG_ADDITIVE
|
|
);*/
|
|
|
|
pSeatLocal->m_flDamageIndicator -= clframetime;
|
|
}
|
|
|
|
/* main entry */
|
|
void
|
|
HUD_Draw(void)
|
|
{
|
|
player pl = (player)pSeat->m_ePlayer;
|
|
|
|
g_hud_color = autocvar_con_color * (1 / 255);
|
|
|
|
/* little point in not drawing these, even if you don't have a suit */
|
|
Weapons_DrawCrosshair(pl);
|
|
HUD_DrawDamageIndicator();
|
|
HUD_DrawWeaponSelect();
|
|
Obituary_Draw();
|
|
Textmenu_Draw();
|
|
|
|
if (!(pl.g_items & ITEM_SUIT)) {
|
|
return;
|
|
}
|
|
|
|
HUD_DamageNotify_Draw();
|
|
HUD_DrawHealth();
|
|
HUD_DrawArmor();
|
|
HUD_DrawFlashlight();
|
|
HUD_DrawNotify();
|
|
Damage_Draw();
|
|
}
|
|
|
|
string g_specmodes[] = {
|
|
"Free Camera",
|
|
"Third Person",
|
|
"First Person"
|
|
};
|
|
|
|
/* specatator main entry */
|
|
void
|
|
HUD_DrawSpectator(void)
|
|
{
|
|
Textmenu_Draw();
|
|
|
|
NSClientSpectator spec = (NSClientSpectator)pSeat->m_ePlayer;
|
|
|
|
drawfont = Font_GetID(FONT_20);
|
|
vector vecPos = [0.0f, 0.0f, 0.0f];
|
|
string strText = __NULL__;
|
|
float palpha = 1.0f;
|
|
|
|
if (spec.spec_mode == SPECMODE_FREE) {
|
|
palpha = 0.5f;
|
|
}
|
|
|
|
strText = sprintf("Tracking: %s", getplayerkeyvalue(spec.spec_ent - 1, "name"));
|
|
vecPos[0] = g_hudmins[0] + (g_hudres[0] / 2) - (stringwidth(strText, TRUE, [20,20]) / 2);
|
|
vecPos[1] = g_hudmins[1] + g_hudres[1] - 60;
|
|
drawstring(vecPos, strText, [20,20], [1,1,1], palpha, DRAWFLAG_ADDITIVE);
|
|
|
|
strText = sprintf("Mode: %s", g_specmodes[spec.spec_mode]);
|
|
vecPos[0] = g_hudmins[0] + (g_hudres[0] / 2) - (stringwidth(strText, TRUE, [20,20]) / 2);
|
|
vecPos[1] = g_hudmins[1] + g_hudres[1] - 40;
|
|
drawstring(vecPos, strText, [20,20], [1,1,1], 1.0f, DRAWFLAG_ADDITIVE);
|
|
}
|