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