Xonotic QuakeC
The free, fast arena FPS with crisp movement and a wide array of weapons
healtharmor.qc
Go to the documentation of this file.
1#include "healtharmor.qh"
2
3#include <client/draw.qh>
5
6// Health/armor (#3)
7
9{
10 // allow saving cvars that aesthetically change the panel into hud skin files
11 HUD_Write_Cvar("hud_panel_healtharmor_combined");
12 HUD_Write_Cvar("hud_panel_healtharmor_flip");
13 HUD_Write_Cvar("hud_panel_healtharmor_iconalign");
14 HUD_Write_Cvar("hud_panel_healtharmor_baralign");
15 HUD_Write_Cvar("hud_panel_healtharmor_progressbar");
16 HUD_Write_Cvar("hud_panel_healtharmor_progressbar_health");
17 HUD_Write_Cvar("hud_panel_healtharmor_progressbar_armor");
18 HUD_Write_Cvar("hud_panel_healtharmor_progressbar_gfx");
19 HUD_Write_Cvar("hud_panel_healtharmor_progressbar_gfx_smooth");
20 HUD_Write_Cvar("hud_panel_healtharmor_text");
21}
22
23void HUD_HealthArmor(bool should_draw)
24{
25 static float health_damagetime, armor_damagetime;
26 static int health_beforedamage, armor_beforedamage;
27 // old_p_* vars keep track of previous values when smoothing value changes of the progressbar
28 static int old_p_health, old_p_armor;
29 static float old_p_healthtime, old_p_armortime;
30
31 int health, armor, fuel, air_time, p_health, p_armor;
33 {
35 return;
36 if (hud != HUD_NORMAL)
37 return;
38
39 // update values
40 health = STAT(HEALTH);
41 armor = STAT(ARMOR);
42 fuel = STAT(FUEL);
43 air_time = bound(0, STAT(AIR_FINISHED) - time, 10);
44 if (health <= 0)
45 {
46 health = 0;
47 prev_health = -1;
49 should_draw = false;
50 }
51
52 // code to check for spectatee_status changes is in ENT_CLIENT_CLIENTDATA
53 // prev_p_health and prev_health can be set to -1 there
54 if (prev_p_health == -1)
55 {
56 // no effect
57 health_beforedamage = 0;
58 armor_beforedamage = 0;
59 health_damagetime = 0;
60 armor_damagetime = 0;
62 prev_armor = armor;
63 old_p_health = health;
64 old_p_armor = armor;
66 prev_p_armor = armor;
67 }
68 else if (prev_health == -1)
69 {
70 // start the load effect
71 health_damagetime = 0;
72 armor_damagetime = 0;
73 prev_health = 0;
74 prev_armor = 0;
75 }
76
77 // update caches
78 p_health = health;
79 p_armor = armor;
81 {
83 {
84 #define HEALTHARMOR_GFX_SMOOTH(stat) \
85 if (fabs(prev_##stat - stat) >= autocvar_hud_panel_healtharmor_progressbar_gfx_smooth) \
86 { \
87 if (time - old_p_##stat##time < 1) \
88 old_p_##stat = prev_p_##stat; \
89 else \
90 old_p_##stat = prev_##stat; \
91 old_p_##stat##time = time; \
92 } \
93 if (time - old_p_##stat##time < 1) \
94 { \
95 p_##stat += (old_p_##stat - stat) * (1 - (time - old_p_##stat##time)); \
96 prev_p_##stat = p_##stat; \
97 }
100 #undef HEALTHARMOR_GFX_SMOOTH
101 }
103 {
104 #define HEALTHARMOR_GFX_DAMAGE(stat) \
105 if (prev_##stat - stat >= autocvar_hud_panel_healtharmor_progressbar_gfx_damage) \
106 { \
107 if (time - stat##_damagetime >= 1) \
108 stat##_beforedamage = prev_##stat; \
109 stat##_damagetime = time; \
110 }
113 #undef HEALTHARMOR_GFX_DAMAGE
114 }
116 prev_armor = armor;
117 }
118
119 if (!should_draw)
120 return;
121 }
122 else
123 {
124 if (!should_draw)
125 return;
126
127 p_health = health = 150;
128 p_armor = armor = 75;
129 fuel = 20;
130 air_time = 6;
131 }
132
134
136
137 vector pos = panel_pos;
138 vector mySize = panel_size;
139
142 else
146 {
147 pos += '1 1 0' * panel_bg_padding;
148 mySize -= '2 2 0' * panel_bg_padding;
149 }
150
151 float air_alpha;
152 if (!STAT(AIR_FINISHED))
153 air_alpha = 0;
154 else if (time > STAT(AIR_FINISHED))
155 {
156 air_alpha = blink_synced(0.5, 0.5, 7, STAT(AIR_FINISHED), -1);
157 air_time = 10;
158 }
159 else
160 {
161 float fade_time = 10 / 2;
163 float f = (STAT(AIR_FINISHED) - time - fade_time) / fade_time;
164 air_alpha = bound(0, start_alpha + (1 - start_alpha) * (1 - f), 1);
165 }
166
167 float fuel_alpha;
168 if (!fuel)
169 fuel_alpha = 0;
170 else
171 {
173 float f = (100 - fuel) / 50;
174 fuel_alpha = bound(0, start_alpha + (1 - start_alpha) * f, 1);
175 }
176
179
182 if (autocvar_hud_panel_healtharmor_combined) // combined health and armor display
183 {
184 vector v = healtharmor_maxdamage(health, armor, armorblockpercent, DEATH_WEAPON.m_id);
185 float hp = floor(v.x + 1);
186
187 float maxtotal = maxhealth + maxarmor;
188 string biggercount;
189 if (v.z) // NOT fully armored
190 {
191 biggercount = "health";
195 drawpic_aspect_skin(pos + eX * mySize.x - eX * 0.5 * mySize.y, "armor", '0.5 0.5 0' * mySize.y, '1 1 1', panel_fg_alpha * armor / health, DRAWFLAG_NORMAL);
196 }
197 else
198 {
199 biggercount = "armor";
203 drawpic_aspect_skin(pos + eX * mySize.x - eX * 0.5 * mySize.y, "health", '0.5 0.5 0' * mySize.y, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
204 }
206 DrawNumIcon(pos, mySize, hp, biggercount, false, false, iconalign, HUD_Get_Num_Color(hp, maxtotal, true), 1);
207
208 if (fuel)
209 HUD_Panel_DrawProgressBar(pos, vec2(mySize.x, 0.2 * mySize.y), "progressbar", fuel / 100, 0, (baralign == 1 || baralign == 3), autocvar_hud_progressbar_fuel_color, fuel_alpha * panel_fg_alpha * 0.8, DRAWFLAG_NORMAL);
210 if (air_time)
211 HUD_Panel_DrawProgressBar(pos + eY * 0.8 * mySize.y, vec2(mySize.x, 0.2 * mySize.y), "progressbar", air_time / 10, 0, (baralign == 1 || baralign == 3), autocvar_hud_progressbar_oxygen_color, air_alpha * panel_fg_alpha * 0.8, DRAWFLAG_NORMAL);
212 }
213 else
214 {
215 float panel_ar = mySize.x / mySize.y;
216 bool is_vertical = panel_ar < 1;
217 vector health_offset = '0 0 0', armor_offset = '0 0 0';
218 if (panel_ar >= 4 || (panel_ar >= 1/4 && panel_ar < 1))
219 {
220 mySize.x *= 0.5;
222 health_offset.x = mySize.x;
223 else
224 armor_offset.x = mySize.x;
225 }
226 else
227 {
228 mySize.y *= 0.5;
230 health_offset.y = mySize.y;
231 else
232 armor_offset.y = mySize.y;
233 }
234
235 bool health_baralign, armor_baralign, fuel_baralign, air_align;
236 bool health_iconalign, armor_iconalign;
238 {
241 air_align = fuel_baralign = health_baralign;
244 }
245 else
246 {
249 air_align = fuel_baralign = armor_baralign;
252 }
253
254 //if (health)
255 {
257 {
258 float pain_health_alpha = 1;
260 {
262 && time - health_damagetime < 1)
263 {
264 float health_damagealpha = 1 - (time - health_damagetime) * (time - health_damagetime);
265 HUD_Panel_DrawProgressBar(pos + health_offset, mySize, autocvar_hud_panel_healtharmor_progressbar_health, health_beforedamage / maxhealth, is_vertical, health_baralign, autocvar_hud_progressbar_health_color, autocvar_hud_progressbar_alpha * panel_fg_alpha * health_damagealpha, DRAWFLAG_NORMAL);
266 }
268 pain_health_alpha = blink(0.85, 0.15, 9);
269 }
270 HUD_Panel_DrawProgressBar(pos + health_offset, mySize, autocvar_hud_panel_healtharmor_progressbar_health, p_health / maxhealth, is_vertical, health_baralign, autocvar_hud_progressbar_health_color, autocvar_hud_progressbar_alpha * panel_fg_alpha * pain_health_alpha, DRAWFLAG_NORMAL);
271 }
273 DrawNumIcon(pos + health_offset, mySize, health, "health", is_vertical, false, health_iconalign, HUD_Get_Num_Color(health, maxhealth, true), 1);
274 }
275
276 //if (armor)
277 {
279 {
281 {
283 && time - armor_damagetime < 1)
284 {
285 float armor_damagealpha = 1 - (time - armor_damagetime) * (time - armor_damagetime);
286 HUD_Panel_DrawProgressBar(pos + armor_offset, mySize, autocvar_hud_panel_healtharmor_progressbar_armor, armor_beforedamage / maxarmor, is_vertical, armor_baralign, autocvar_hud_progressbar_armor_color, autocvar_hud_progressbar_alpha * panel_fg_alpha * armor_damagealpha, DRAWFLAG_NORMAL);
287 }
288 }
289 if (p_armor)
291 }
293 DrawNumIcon(pos + armor_offset, mySize, armor, "armor", is_vertical, false, armor_iconalign, HUD_Get_Num_Color(armor, maxarmor, true), 1);
294 }
295
296 vector cell_size = mySize;
297 if (fuel || air_time)
298 {
299 if (is_vertical)
300 mySize.x *= 0.2 / 2; //if vertical always halve x to not cover too much numbers with 3 digits
301 else
302 mySize.y *= 0.2;
303 if (panel_ar >= 4)
304 mySize.x *= 2; //restore full panel size
305 else if (panel_ar < 1/4)
306 mySize.y *= 2; //restore full panel size
307 if (fuel)
308 HUD_Panel_DrawProgressBar(pos, mySize, "progressbar", fuel / 100, is_vertical, fuel_baralign, autocvar_hud_progressbar_fuel_color, fuel_alpha * panel_fg_alpha * 0.8, DRAWFLAG_NORMAL);
309 if (air_time)
310 {
311 if (panel_ar > 1 && panel_ar < 4)
312 pos.y += cell_size.y;
313 else if (panel_ar > 1/4 && panel_ar <= 1)
314 pos.x += cell_size.x;
315 if (is_vertical)
316 pos.x += cell_size.x - mySize.x;
317 else
318 pos.y += cell_size.y - mySize.y;
319 HUD_Panel_DrawProgressBar(pos, mySize, "progressbar", air_time / 10, is_vertical, air_align, autocvar_hud_progressbar_oxygen_color, air_alpha * panel_fg_alpha * 0.8, DRAWFLAG_NORMAL);
320 }
321 }
322 }
323
325}
#define drawpic_aspect_skin(pos, pic, sz, color, theAlpha, drawflag)
Definition draw.qh:78
#define draw_beginBoldFont()
Definition draw.qh:4
#define draw_endBoldFont()
Definition draw.qh:5
float armorblockpercent
Definition main.qh:160
int spectatee_status
the -1 disables HUD panels before CSQC receives necessary data
Definition main.qh:197
int hud
Definition main.qh:173
vector healtharmor_maxdamage(float h, float a, float armorblock, int deathtype)
Definition util.qc:1389
ERASEABLE float blink_synced(float base, float range, float freq, float start_time, int start_pos)
Definition util.qc:2262
ERASEABLE float blink(float base, float range, float freq)
Definition util.qc:2274
const int HUD_NORMAL
Definition constants.qh:47
const float DRAWFLAG_NORMAL
float time
void HUD_HealthArmor(bool should_draw)
#define HEALTHARMOR_GFX_DAMAGE(stat)
void HUD_HealthArmor_Export(int fh)
Definition healtharmor.qc:8
#define HEALTHARMOR_GFX_SMOOTH(stat)
int autocvar_hud_panel_healtharmor_iconalign
float autocvar_hud_panel_healtharmor_progressbar_gfx_smooth
bool autocvar_hud_panel_healtharmor_hide_ondeath
Definition healtharmor.qh:9
bool autocvar_hud_panel_healtharmor
Definition healtharmor.qh:4
int autocvar_hud_panel_healtharmor_baralign
Definition healtharmor.qh:5
vector autocvar_hud_progressbar_oxygen_color
float autocvar_hud_panel_healtharmor_fuelbar_startalpha
bool autocvar_hud_panel_healtharmor_progressbar_gfx
vector autocvar_hud_progressbar_fuel_color
bool autocvar_hud_panel_healtharmor_dynamichud
Definition healtharmor.qh:7
float autocvar_hud_panel_healtharmor_progressbar_gfx_damage
bool autocvar_hud_panel_healtharmor_flip
Definition healtharmor.qh:8
bool autocvar_hud_panel_healtharmor_progressbar
string autocvar_hud_panel_healtharmor_progressbar_health
float autocvar_hud_panel_healtharmor_oxygenbar_startalpha
float autocvar_hud_panel_healtharmor_progressbar_gfx_lowhealth
int autocvar_hud_panel_healtharmor_text
vector autocvar_hud_progressbar_armor_color
int autocvar_hud_panel_healtharmor_maxhealth
vector autocvar_hud_progressbar_health_color
int autocvar_hud_panel_healtharmor_maxarmor
string autocvar_hud_panel_healtharmor_progressbar_armor
bool autocvar_hud_panel_healtharmor_combined
Definition healtharmor.qh:6
void HUD_Panel_DrawProgressBar(vector theOrigin, vector theSize, string pic, float length_ratio, bool vertical, float baralign, vector theColor, float theAlpha, int drawflag)
Definition hud.qc:269
void HUD_Panel_LoadCvars()
Definition hud.qc:215
void DrawNumIcon(vector myPos, vector mySize, float theTime, string icon, bool vertical, bool isInfinite, int icon_right_align, vector color, float theAlpha)
Definition hud.qc:474
void HUD_Scale_Enable()
Definition hud.qc:91
vector HUD_Get_Num_Color(float hp, float maxvalue, bool blink)
Definition hud.qc:123
void HUD_Scale_Disable()
Definition hud.qc:84
float autocvar_hud_progressbar_alpha
Definition hud.qh:204
vector panel_size
Definition hud.qh:163
float panel_fg_alpha
Definition hud.qh:169
float panel_bg_padding
Definition hud.qh:174
int prev_armor
Definition hud.qh:243
int prev_health
Definition hud.qh:243
int prev_p_armor
Definition hud.qh:246
#define HUD_Panel_DrawBg()
Definition hud.qh:55
vector panel_pos
Definition hud.qh:162
int prev_p_health
Definition hud.qh:246
#define HUD_Write_Cvar(cvar)
Definition hud_config.qh:40
bool autocvar__hud_configure
Definition hud_config.qh:3
#define STAT(...)
Definition stats.qh:82
float bound(float min, float value, float max)
float floor(float f)
float health
Legacy fields for the resources. To be removed.
Definition resources.qh:9
vector
Definition self.qh:92
float fade_time
Definition common.qh:23
const vector eY
Definition vector.qh:45
const vector eX
Definition vector.qh:44
#define vec2(...)
Definition vector.qh:90