Client: Add damage and item pickup notifications to the HUD. This is the

last stretch of the HUD stuff (now we only need the tracktrain UI!)
This commit is contained in:
Marco Cawthorne 2021-12-17 18:22:02 -08:00
parent 2f8bdaa32b
commit 3117e979d6
Signed by: eukara
GPG key ID: C196CD8BA993248A
7 changed files with 258 additions and 8 deletions

View file

@ -12,6 +12,7 @@ Damage_Precache(void)
g_damage_spr_l = spriteframe("sprites/640_pain.spr", 3, 0.0f);
}
void HUD_DamageNotify_Check();
void
Damage_Draw(void)
{
@ -24,6 +25,8 @@ Damage_Draw(void)
return;
}
HUD_DamageNotify_Check();
center = video_mins + (video_res / 2);
/* the pos relative to the player + view_dir determines which

View file

@ -84,6 +84,8 @@ HUD_Init(void)
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 */
@ -393,16 +395,16 @@ HUD_DrawNotify(void)
pos = g_hudmins + [g_hudres[0] - 192, g_hudres[1] - 128];
if (pSeatLocal->m_flPickupAlpha <= 0.0f) {
pos[0] += 148;
pos[1] += 16;
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(pSeatLocal->m_iPickupWeapon, 1, pos, a);
pos[0] += 148;
pos[1] -= 32;
HUD_ItemNotify_Draw(pos);
HUD_AmmoNotify_Draw(pos);
pSeatLocal->m_flPickupAlpha -= (clframetime * 0.5);
}
@ -446,6 +448,7 @@ HUD_Draw(void)
return;
}
HUD_DamageNotify_Draw();
HUD_DrawHealth();
HUD_DrawArmor();
HUD_DrawFlashlight();

View file

@ -43,9 +43,9 @@ HUD_AmmoNotify_Init(void)
}
void
HUD_AmmoNotify_Draw(vector startpos)
HUD_AmmoNotify_Draw(__inout vector pos)
{
vector pos = startpos;
pos[0] = g_hudmins[0] + g_hudres[0] - 40;
for (int i = 0; i < AMMO_COUNT; i++) {
vector srcpos;
@ -61,6 +61,8 @@ HUD_AmmoNotify_Draw(vector startpos)
srcpos = g_ammotype[i];
a = bound(0, g_ammonotify[i].alpha, 1.0);
/* we'll use the alpha to control the offset so it gently glides down when fading out */
pos -= [0, 32 * a]; /* go up a notch */
drawsubpic(pos,
[24,24],
g_ammo_spr,
@ -77,7 +79,6 @@ HUD_AmmoNotify_Draw(vector startpos)
drawstring(pos + [-offs - 8,4], sprintf("%i", g_ammonotify[i].count), [20,20], g_hud_color, a, DRAWFLAG_ADDITIVE);
g_ammonotify[i].alpha -= (clframetime * 0.5);
pos -= [0, 32]; /* go up a notch */
}
}

137
src/client/hud_dmgnotify.qc Normal file
View file

@ -0,0 +1,137 @@
#define DMG_COUNT 8
string g_dmg1_spr;
string g_dmg2_spr;
typedef struct
{
float alpha;
} dmgnote_t;
dmgnote_t g_dmgnotify[DMG_COUNT];
vector g_dmgtype[DMG_COUNT] = {
[0,0], // chemical
[0.25,0], // drown
[0.5,0], // poison
[0.75,0], // shock
[0,0], // nerve gas
[0.25,0], // freeze / slowfreeze
[0.5,0], // burn / slowburn
[0.75,0], // radiation?
};
void
HUD_DamageNotify_Init(void)
{
g_dmg1_spr = spriteframe("sprites/640hud8.spr", 0, 0.0f);
g_dmg2_spr = spriteframe("sprites/640hud9.spr", 0, 0.0f);
}
void
HUD_DamageNotify_Draw(void)
{
vector pos;
pos = g_hudmins + [16, g_hudres[1] - 128];
for (int i = 0; i < DMG_COUNT; i++) {
vector srcpos;
float a;
/* make sure we skip any faded entries, and also null them */
if (g_dmgnotify[i].alpha <= 0.0f) {
continue;
}
/* let's get the src img pos for our type */
srcpos = g_dmgtype[i];
a = (sin(cltime * 2.5) * 0.5) + 0.5;
a *= bound(0.0f, g_dmgnotify[i].alpha, 1.0);
if (i < 4)
drawsubpic(pos,
[64,64],
g_dmg1_spr,
srcpos,
[64/256, 64/64],
g_hud_color,
a,
DRAWFLAG_ADDITIVE
);
else
drawsubpic(pos,
[64,64],
g_dmg2_spr,
srcpos,
[64/256, 64/64],
g_hud_color,
a,
DRAWFLAG_ADDITIVE
);
g_dmgnotify[i].alpha -= (clframetime * 2.0);
pos -= [0, 64]; /* go up a notch */
}
}
typedef enum
{
DMGNOT_CHEMICAL,
DMGNOT_DROWN,
DMGNOT_POISON,
DMGNOT_SHOCK,
DMGNOT_NERVEGAS,
DMGNOT_FREEZE,
DMGNOT_BURN,
DMGNOT_RADIATION
} dmgnot_e;
#define DMG_NOTIFY_SET(x) g_dmgnotify[x].alpha = 10.0f
/* called whenever we should check for pickup updates */
void
HUD_DamageNotify_Check(void)
{
if (pSeat->m_iDamageFlags & DMG_CHEMICAL) {
pSeat->m_iDamageFlags &= ~DMG_CHEMICAL;
DMG_NOTIFY_SET(DMGNOT_CHEMICAL);
}
if (pSeat->m_iDamageFlags & DMG_BURN) {
pSeat->m_iDamageFlags &= ~DMG_BURN;
DMG_NOTIFY_SET(DMGNOT_BURN);
}
if (pSeat->m_iDamageFlags & DMG_SLOWBURN) {
pSeat->m_iDamageFlags &= ~DMG_SLOWBURN;
DMG_NOTIFY_SET(DMGNOT_BURN);
}
if (pSeat->m_iDamageFlags & DMG_ELECTRO) {
pSeat->m_iDamageFlags &= ~DMG_ELECTRO;
DMG_NOTIFY_SET(DMGNOT_SHOCK);
}
if (pSeat->m_iDamageFlags & DMG_DROWN) {
pSeat->m_iDamageFlags &= ~DMG_DROWN;
DMG_NOTIFY_SET(DMGNOT_DROWN);
}
if (pSeat->m_iDamageFlags & DMG_NERVEGAS) {
pSeat->m_iDamageFlags &= ~DMG_NERVEGAS;
DMG_NOTIFY_SET(DMGNOT_NERVEGAS);
}
if (pSeat->m_iDamageFlags & DMG_POISON) {
pSeat->m_iDamageFlags &= ~DMG_POISON;
DMG_NOTIFY_SET(DMGNOT_POISON);
}
if (pSeat->m_iDamageFlags & DMG_RADIATION) {
pSeat->m_iDamageFlags &= ~DMG_RADIATION;
DMG_NOTIFY_SET(DMGNOT_RADIATION);
}
if (pSeat->m_iDamageFlags & DMG_FREEZE) {
pSeat->m_iDamageFlags &= ~DMG_FREEZE;
DMG_NOTIFY_SET(DMGNOT_FREEZE);
}
if (pSeat->m_iDamageFlags & DMG_SLOWFREEZE) {
pSeat->m_iDamageFlags &= ~DMG_SLOWFREEZE;
DMG_NOTIFY_SET(DMGNOT_FREEZE);
}
}

View file

@ -0,0 +1,91 @@
#define ITEM_COUNT 3
string g_item_spr;
typedef struct
{
float alpha;
int count;
} itemnote_t;
itemnote_t g_itemnotify[ITEM_COUNT];
vector g_itemtype[ITEM_COUNT] = {
[176/256, 0/256], // battery
[176/256, 48/256], // medkit
[176/256, 96/256], // longjump
};
void
HUD_ItemNotify_Init(void)
{
g_item_spr = spriteframe("sprites/640hud2.spr", 0, 0.0f);
}
void
HUD_ItemNotify_Draw(__inout vector pos)
{
pos[0] = g_hudmins[0] + g_hudres[0] - 44;
for (int i = 0; i < ITEM_COUNT; i++) {
vector srcpos;
float a;
/* make sure we skip any faded entries, and also null them */
if (g_itemnotify[i].alpha <= 0.0f) {
g_itemnotify[i].count = 0;
continue;
}
/* let's get the src img pos for our type */
srcpos = g_itemtype[i];
a = bound(0, g_itemnotify[i].alpha, 1.0);
/* we'll use the alpha to control the offset so it gently glides down when fading out */
pos -= [0, 52 * a]; /* go up a notch */
drawsubpic(pos + [-20,0],
[44,44],
g_item_spr,
srcpos,
[44/256, 44/256],
g_hud_color,
a,
DRAWFLAG_ADDITIVE
);
if (g_itemnotify[i].count > 1) {
drawfont = Font_GetID(FONT_20);
string txt = sprintf("%i", g_itemnotify[i].count);
float offs = stringwidth(txt, FALSE, [20,20]) + 16;
drawstring(pos + [-offs - 8,12], sprintf("%i", g_itemnotify[i].count), [20,20], g_hud_color, a, DRAWFLAG_ADDITIVE);
}
g_itemnotify[i].alpha -= (clframetime * 0.5);
}
}
void
HUD_ItemNotify_Insert(int type, int count)
{
if (count <= 0)
return;
g_itemnotify[type].count += count;
g_itemnotify[type].alpha = 2.5f;
}
/* called whenever we should check for pickup updates */
void
HUD_ItemNotify_Check(player pl)
{
int healthdiff = bound(0, pl.health - pl.health_net, 100);
int armordiff = bound(0, pl.armor - pl.armor_net, 100);
int longjumpdiff = ((pl.g_items & ITEM_LONGJUMP) > (pl.g_items_net & ITEM_LONGJUMP)) == TRUE;
if (healthdiff > 1)
HUD_ItemNotify_Insert(1, 1);
if (armordiff > 1)
HUD_ItemNotify_Insert(0, 1);
if (longjumpdiff)
HUD_ItemNotify_Insert(2, 1);
}

View file

@ -32,6 +32,8 @@ game_event.qc
../../../valve/src/client/viewmodel.qc
view.qc
obituary.qc
hud_itemnotify.qc
hud_dmgnotify.qc
hud_ammonotify.qc
hud.qc
hud_weaponselect.qc

View file

@ -106,6 +106,7 @@ class player:base_player
#ifdef CLIENT
void Weapons_AmmoUpdate(entity);
void HUD_AmmoNotify_Check(player pl);
void HUD_ItemNotify_Check(player pl);
/*
=================
player::ReceiveEntity
@ -159,12 +160,24 @@ player::ReceiveEntity(float new, float fl)
mode_tempstate = readbyte();
}
setorigin(this, origin);
/* these only concern the current player */
CSQC_UpdateSeat();
if (this != pSeat->m_ePlayer)
return;
/* do not notify us of updates when spawning initially */
if (fl == UPDATE_ALL)
PredictPreFrame();
if (fl & PLAYER_AMMO1 || fl & PLAYER_AMMO2 || fl & PLAYER_AMMO3) {
Weapons_AmmoUpdate(this);
HUD_AmmoNotify_Check(this);
}
setorigin(this, origin);
if (fl & PLAYER_ITEMS || fl & PLAYER_HEALTH || fl & PLAYER_ARMOR)
HUD_ItemNotify_Check(this);
}
/*