1dc0e52c03baf727622c44287330fd2802bcee7c
[xonotic/xonotic-data.pk3dir.git] / qcsrc / client / hud / panel / healtharmor.qc
1 #include "healtharmor.qh"
2
3 #include <client/defs.qh>
4 #include <client/miscfunctions.qh>
5
6 #include <common/deathtypes/all.qh>
7
8 // Health/armor (#3)
9
10 void HUD_HealthArmor()
11 {
12         int armor, health, fuel, air_time;
13         if(!autocvar__hud_configure)
14         {
15                 if((!autocvar_hud_panel_healtharmor) || (spectatee_status == -1))
16                         return;
17                 if(hud != HUD_NORMAL) return;
18
19                 health = STAT(HEALTH);
20                 if(health <= 0)
21                 {
22                         health = 0;
23                         prev_health = -1;
24                         if(autocvar_hud_panel_healtharmor_hide_ondeath)
25                                 return;
26                 }
27                 armor = STAT(ARMOR);
28
29                 // code to check for spectatee_status changes is in ENT_CLIENT_CLIENTDATA
30                 // prev_p_health and prev_health can be set to -1 there
31
32                 if (prev_p_health == -1)
33                 {
34                         // no effect
35                         health_beforedamage = 0;
36                         armor_beforedamage = 0;
37                         health_damagetime = 0;
38                         armor_damagetime = 0;
39                         prev_health = health;
40                         prev_armor = armor;
41                         old_p_health = health;
42                         old_p_armor = armor;
43                         prev_p_health = health;
44                         prev_p_armor = armor;
45                 }
46                 else if (prev_health == -1)
47                 {
48                         //start the load effect
49                         health_damagetime = 0;
50                         armor_damagetime = 0;
51                         prev_health = 0;
52                         prev_armor = 0;
53                 }
54                 fuel = STAT(FUEL);
55                 air_time = bound(0, STAT(AIR_FINISHED) - time, 10);
56         }
57         else
58         {
59                 health = 150;
60                 armor = 75;
61                 fuel = 20;
62                 air_time = 6;
63         }
64
65         HUD_Panel_LoadCvars();
66
67         draw_beginBoldFont();
68
69         vector pos, mySize;
70         pos = panel_pos;
71         mySize = panel_size;
72
73         if (autocvar_hud_panel_healtharmor_dynamichud)
74                 HUD_Scale_Enable();
75         else
76                 HUD_Scale_Disable();
77         HUD_Panel_DrawBg();
78         if(panel_bg_padding)
79         {
80                 pos += '1 1 0' * panel_bg_padding;
81                 mySize -= '2 2 0' * panel_bg_padding;
82         }
83
84         float BLINK_FACTOR = 0.5;
85         float BLINK_BASE = 0.5;
86         float BLINK_FREQ = 7;
87         float air_alpha = 1;
88         if (STAT(AIR_FINISHED) && time > STAT(AIR_FINISHED))
89         {
90                 air_alpha = BLINK_BASE + BLINK_FACTOR * cos(time * BLINK_FREQ);
91                 air_time = 10;
92         }
93
94         int baralign = autocvar_hud_panel_healtharmor_baralign;
95         int iconalign = autocvar_hud_panel_healtharmor_iconalign;
96
97         int maxhealth = autocvar_hud_panel_healtharmor_maxhealth;
98         int maxarmor = autocvar_hud_panel_healtharmor_maxarmor;
99         if(autocvar_hud_panel_healtharmor_combined) // combined health and armor display
100         {
101                 vector v = healtharmor_maxdamage(health, armor, armorblockpercent, DEATH_WEAPON.m_id);
102                 float hp = floor(v.x + 1);
103
104                 float maxtotal = maxhealth + maxarmor;
105                 string biggercount;
106                 if(v.z) // NOT fully armored
107                 {
108                         biggercount = "health";
109                         if(autocvar_hud_panel_healtharmor_progressbar)
110                                 HUD_Panel_DrawProgressBar(pos, mySize, autocvar_hud_panel_healtharmor_progressbar_health, hp/maxtotal, 0, (baralign == 1 || baralign == 2), autocvar_hud_progressbar_health_color, autocvar_hud_progressbar_alpha * panel_fg_alpha, DRAWFLAG_NORMAL);
111                         if(armor && autocvar_hud_panel_healtharmor_text)
112                                 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);
113                 }
114                 else
115                 {
116                         biggercount = "armor";
117                         if(autocvar_hud_panel_healtharmor_progressbar)
118                                 HUD_Panel_DrawProgressBar(pos, mySize, autocvar_hud_panel_healtharmor_progressbar_armor, hp/maxtotal, 0, (baralign == 1 || baralign == 2), autocvar_hud_progressbar_armor_color, autocvar_hud_progressbar_alpha * panel_fg_alpha, DRAWFLAG_NORMAL);
119                         if(health && autocvar_hud_panel_healtharmor_text)
120                                 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);
121                 }
122                 if(autocvar_hud_panel_healtharmor_text)
123                         DrawNumIcon(pos, mySize, hp, biggercount, 0, iconalign, HUD_Get_Num_Color(hp, maxtotal), 1);
124
125                 if(fuel)
126                         HUD_Panel_DrawProgressBar(pos, vec2(mySize.x, 0.2 * mySize.y), "progressbar", fuel/100, 0, (baralign == 1 || baralign == 3), autocvar_hud_progressbar_fuel_color, panel_fg_alpha * 0.8, DRAWFLAG_NORMAL);
127                 if(air_time)
128                         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);
129         }
130         else
131         {
132                 float panel_ar = mySize.x/mySize.y;
133                 bool is_vertical = (panel_ar < 1);
134                 vector health_offset = '0 0 0', armor_offset = '0 0 0';
135                 if (panel_ar >= 4 || (panel_ar >= 1/4 && panel_ar < 1))
136                 {
137                         mySize.x *= 0.5;
138                         if (autocvar_hud_panel_healtharmor_flip)
139                                 health_offset.x = mySize.x;
140                         else
141                                 armor_offset.x = mySize.x;
142                 }
143                 else
144                 {
145                         mySize.y *= 0.5;
146                         if (autocvar_hud_panel_healtharmor_flip)
147                                 health_offset.y = mySize.y;
148                         else
149                                 armor_offset.y = mySize.y;
150                 }
151
152                 bool health_baralign, armor_baralign, fuel_baralign, air_align;
153                 bool health_iconalign, armor_iconalign;
154                 if (autocvar_hud_panel_healtharmor_flip)
155                 {
156                         armor_baralign = (autocvar_hud_panel_healtharmor_baralign == 2 || autocvar_hud_panel_healtharmor_baralign == 1);
157                         health_baralign = (autocvar_hud_panel_healtharmor_baralign == 3 || autocvar_hud_panel_healtharmor_baralign == 1);
158                         air_align = fuel_baralign = health_baralign;
159                         armor_iconalign = (autocvar_hud_panel_healtharmor_iconalign == 2 || autocvar_hud_panel_healtharmor_iconalign == 1);
160                         health_iconalign = (autocvar_hud_panel_healtharmor_iconalign == 3 || autocvar_hud_panel_healtharmor_iconalign == 1);
161                 }
162                 else
163                 {
164                         health_baralign = (autocvar_hud_panel_healtharmor_baralign == 2 || autocvar_hud_panel_healtharmor_baralign == 1);
165                         armor_baralign = (autocvar_hud_panel_healtharmor_baralign == 3 || autocvar_hud_panel_healtharmor_baralign == 1);
166                         air_align = fuel_baralign = armor_baralign;
167                         health_iconalign = (autocvar_hud_panel_healtharmor_iconalign == 2 || autocvar_hud_panel_healtharmor_iconalign == 1);
168                         armor_iconalign = (autocvar_hud_panel_healtharmor_iconalign == 3 || autocvar_hud_panel_healtharmor_iconalign == 1);
169                 }
170
171                 //if(health)
172                 {
173                         if(autocvar_hud_panel_healtharmor_progressbar)
174                         {
175                                 float p_health, pain_health_alpha;
176                                 p_health = health;
177                                 pain_health_alpha = 1;
178                                 if (autocvar_hud_panel_healtharmor_progressbar_gfx)
179                                 {
180                                         if (autocvar_hud_panel_healtharmor_progressbar_gfx_smooth > 0)
181                                         {
182                                                 if (fabs(prev_health - health) >= autocvar_hud_panel_healtharmor_progressbar_gfx_smooth)
183                                                 {
184                                                         if (time - old_p_healthtime < 1)
185                                                                 old_p_health = prev_p_health;
186                                                         else
187                                                                 old_p_health = prev_health;
188                                                         old_p_healthtime = time;
189                                                 }
190                                                 if (time - old_p_healthtime < 1)
191                                                 {
192                                                         p_health += (old_p_health - health) * (1 - (time - old_p_healthtime));
193                                                         prev_p_health = p_health;
194                                                 }
195                                         }
196                                         if (autocvar_hud_panel_healtharmor_progressbar_gfx_damage > 0)
197                                         {
198                                                 if (prev_health - health >= autocvar_hud_panel_healtharmor_progressbar_gfx_damage)
199                                                 {
200                                                         if (time - health_damagetime >= 1)
201                                                                 health_beforedamage = prev_health;
202                                                         health_damagetime = time;
203                                                 }
204                                                 if (time - health_damagetime < 1)
205                                                 {
206                                                         float health_damagealpha = 1 - (time - health_damagetime)*(time - health_damagetime);
207                                                         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);
208                                                 }
209                                         }
210                                         prev_health = health;
211
212                                         if (health <= autocvar_hud_panel_healtharmor_progressbar_gfx_lowhealth)
213                                         {
214                                                 float BLINK_FACTOR = 0.15;
215                                                 float BLINK_BASE = 0.85;
216                                                 float BLINK_FREQ = 9;
217                                                 pain_health_alpha = BLINK_BASE + BLINK_FACTOR * cos(time * BLINK_FREQ);
218                                         }
219                                 }
220                                 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);
221                         }
222                         if(autocvar_hud_panel_healtharmor_text)
223                                 DrawNumIcon(pos + health_offset, mySize, health, "health", is_vertical, health_iconalign, HUD_Get_Num_Color(health, maxhealth), 1);
224                 }
225
226                 //if(armor)
227                 {
228                         float p_armor = armor;
229                         if(autocvar_hud_panel_healtharmor_progressbar)
230                         {
231                                 if (autocvar_hud_panel_healtharmor_progressbar_gfx)
232                                 {
233                                         if (autocvar_hud_panel_healtharmor_progressbar_gfx_smooth > 0)
234                                         {
235                                                 if (fabs(prev_armor - armor) >= autocvar_hud_panel_healtharmor_progressbar_gfx_smooth)
236                                                 {
237                                                         if (time - old_p_armortime < 1)
238                                                                 old_p_armor = prev_p_armor;
239                                                         else
240                                                                 old_p_armor = prev_armor;
241                                                         old_p_armortime = time;
242                                                 }
243                                                 if (time - old_p_armortime < 1)
244                                                 {
245                                                         p_armor += (old_p_armor - armor) * (1 - (time - old_p_armortime));
246                                                         prev_p_armor = p_armor;
247                                                 }
248                                         }
249                                         if (autocvar_hud_panel_healtharmor_progressbar_gfx_damage > 0)
250                                         {
251                                                 if (prev_armor - armor >= autocvar_hud_panel_healtharmor_progressbar_gfx_damage)
252                                                 {
253                                                         if (time - armor_damagetime >= 1)
254                                                                 armor_beforedamage = prev_armor;
255                                                         armor_damagetime = time;
256                                                 }
257                                                 if (time - armor_damagetime < 1)
258                                                 {
259                                                         float armor_damagealpha = 1 - (time - armor_damagetime)*(time - armor_damagetime);
260                                                         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);
261                                                 }
262                                         }
263                                         prev_armor = armor;
264                                 }
265                                 if(p_armor)
266                                         HUD_Panel_DrawProgressBar(pos + armor_offset, mySize, autocvar_hud_panel_healtharmor_progressbar_armor, p_armor/maxarmor, is_vertical, armor_baralign, autocvar_hud_progressbar_armor_color, autocvar_hud_progressbar_alpha * panel_fg_alpha, DRAWFLAG_NORMAL);
267                         }
268                         if(!autocvar_hud_panel_healtharmor_progressbar || p_armor)
269                         if(autocvar_hud_panel_healtharmor_text)
270                                 DrawNumIcon(pos + armor_offset, mySize, armor, "armor", is_vertical, armor_iconalign, HUD_Get_Num_Color(armor, maxarmor), 1);
271                 }
272
273                 vector cell_size = mySize;
274                 if (fuel || air_time)
275                 {
276                         if (is_vertical)
277                                 mySize.x *= 0.2 / 2; //if vertical always halve x to not cover too much numbers with 3 digits
278                         else
279                                 mySize.y *= 0.2;
280                         if (panel_ar >= 4)
281                                 mySize.x *= 2; //restore full panel size
282                         else if (panel_ar < 1/4)
283                                 mySize.y *= 2; //restore full panel size
284                         if (fuel)
285                                 HUD_Panel_DrawProgressBar(pos, mySize, "progressbar", fuel/100, is_vertical, fuel_baralign, autocvar_hud_progressbar_fuel_color, panel_fg_alpha * 0.8, DRAWFLAG_NORMAL);
286                         if (air_time)
287                         {
288                                 if (panel_ar > 1 && panel_ar < 4)
289                                         pos.y += cell_size.y;
290                                 else if (panel_ar > 1/4 && panel_ar <= 1)
291                                         pos.x += cell_size.x;
292                                 if (is_vertical)
293                                         pos.x += cell_size.x - mySize.x;
294                                 else
295                                         pos.y += cell_size.y - mySize.y;
296                                 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);
297                         }
298                 }
299         }
300
301         draw_endBoldFont();
302 }