]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/client/hud/panel/ammo.qc
Make it pass compilation unit tests
[xonotic/xonotic-data.pk3dir.git] / qcsrc / client / hud / panel / ammo.qc
1 #include "ammo.qh"
2
3 #include "scoreboard.qh"
4 #include <common/t_items.qh>
5
6 // Ammo (#1)
7
8 void DrawNadeProgressBar(vector myPos, vector mySize, float progress, vector color)
9 {
10         HUD_Panel_DrawProgressBar(
11                 myPos + eX * autocvar_hud_panel_ammo_progressbar_xoffset * mySize.x,
12                 mySize - eX * autocvar_hud_panel_ammo_progressbar_xoffset * mySize.x,
13                 autocvar_hud_panel_ammo_progressbar_name,
14                 progress, 0, 0, color,
15                 autocvar_hud_progressbar_alpha * panel_fg_alpha, DRAWFLAG_NORMAL);
16 }
17
18 void DrawAmmoNades(vector myPos, vector mySize, bool draw_expanding, float expand_time); // TODO: mutator
19
20 void DrawAmmoItem(vector myPos, vector mySize, .int ammoType, bool isCurrent, bool isInfinite)
21 {
22     TC(bool, isCurrent); TC(bool, isInfinite);
23         if(ammoType == ammo_none)
24                 return;
25
26         // Initialize variables
27
28         int ammo;
29         if(autocvar__hud_configure)
30         {
31                 isCurrent = (ammoType == ammo_rockets); // Rockets always current
32                 ammo = 60;
33         }
34         else
35                 ammo = getstati(GetAmmoStat(ammoType));
36
37         if(!isCurrent)
38         {
39                 float scale = bound(0, autocvar_hud_panel_ammo_noncurrent_scale, 1);
40                 myPos = myPos + (mySize - mySize * scale) * 0.5;
41                 mySize = mySize * scale;
42         }
43
44         vector iconPos, textPos;
45         if(autocvar_hud_panel_ammo_iconalign)
46         {
47                 iconPos = myPos + eX * 2 * mySize.y;
48                 textPos = myPos;
49         }
50         else
51         {
52                 iconPos = myPos;
53                 textPos = myPos + eX * mySize.y;
54         }
55
56         bool isShadowed = (ammo <= 0 && !isCurrent && !isInfinite);
57
58         vector iconColor = isShadowed ? '0 0 0' : '1 1 1';
59         vector textColor;
60         if(isInfinite)
61                 textColor = '0.2 0.95 0';
62         else if(isShadowed)
63                 textColor = '0 0 0';
64         else if(ammo < 10)
65                 textColor = '0.8 0.04 0';
66         else
67                 textColor = '1 1 1';
68
69         float alpha;
70         if(isCurrent)
71                 alpha = panel_fg_alpha;
72         else if(isShadowed)
73                 alpha = panel_fg_alpha * bound(0, autocvar_hud_panel_ammo_noncurrent_alpha, 1) * 0.5;
74         else
75                 alpha = panel_fg_alpha * bound(0, autocvar_hud_panel_ammo_noncurrent_alpha, 1);
76
77         string text = isInfinite ? "\xE2\x88\x9E" : ftos(ammo); // Use infinity symbol (U+221E)
78
79         // Draw item
80
81         if(isCurrent)
82                 drawpic_aspect_skin(myPos, "ammo_current_bg", mySize, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
83
84         if(ammo > 0 && autocvar_hud_panel_ammo_progressbar)
85                 HUD_Panel_DrawProgressBar(myPos + eX * autocvar_hud_panel_ammo_progressbar_xoffset * mySize.x, mySize - eX * autocvar_hud_panel_ammo_progressbar_xoffset * mySize.x, autocvar_hud_panel_ammo_progressbar_name, ammo/autocvar_hud_panel_ammo_maxammo, 0, 0, textColor, autocvar_hud_progressbar_alpha * alpha, DRAWFLAG_NORMAL);
86
87         if(autocvar_hud_panel_ammo_text)
88                 drawstring_aspect(textPos, text, eX * (2/3) * mySize.x + eY * mySize.y, textColor, alpha, DRAWFLAG_NORMAL);
89
90         drawpic_aspect_skin(iconPos, GetAmmoPicture(ammoType), '1 1 0' * mySize.y, iconColor, alpha, DRAWFLAG_NORMAL);
91 }
92
93 int nade_prevstatus;
94 int nade_prevframe;
95 float nade_statuschange_time;
96
97 void HUD_Ammo()
98 {
99         if(hud != HUD_NORMAL) return;
100         if(!autocvar__hud_configure)
101         {
102                 if((!autocvar_hud_panel_ammo) || (spectatee_status == -1))
103                         return;
104                 if(STAT(HEALTH) < 1 && autocvar_hud_panel_ammo_hide_ondeath)
105                         return;
106         }
107
108         if(1 - scoreboard_fade_alpha <= 0)
109                 return;
110         HUD_Panel_UpdateCvars(1 - scoreboard_fade_alpha);
111
112         draw_beginBoldFont();
113
114         vector pos, mySize;
115         pos = panel_pos;
116         mySize = panel_size;
117
118         if (autocvar_hud_panel_ammo_dynamichud)
119                 HUD_Scale_Enable();
120         else
121                 HUD_Scale_Disable();
122         HUD_Panel_DrawBg();
123         if(panel_bg_padding)
124         {
125                 pos += '1 1 0' * panel_bg_padding;
126                 mySize -= '2 2 0' * panel_bg_padding;
127         }
128
129         int rows = 0, columns, row, column;
130         float nade_cnt = STAT(NADE_BONUS), nade_score = STAT(NADE_BONUS_SCORE);
131         bool draw_nades = (nade_cnt > 0 || nade_score > 0);
132         float nade_statuschange_elapsedtime;
133         int total_ammo_count;
134
135         vector ammo_size;
136         if (autocvar_hud_panel_ammo_onlycurrent)
137                 total_ammo_count = 1;
138         else
139                 total_ammo_count = AMMO_COUNT;
140
141         if(draw_nades)
142         {
143                 ++total_ammo_count;
144                 if (nade_cnt != nade_prevframe)
145                 {
146                         nade_statuschange_time = time;
147                         nade_prevstatus = nade_prevframe;
148                         nade_prevframe = nade_cnt;
149                 }
150         }
151         else
152                 nade_prevstatus = nade_prevframe = nade_statuschange_time = 0;
153
154         rows = HUD_GetRowCount(total_ammo_count, mySize, 3);
155         columns = ceil((total_ammo_count)/rows);
156         ammo_size = eX * mySize.x*(1/columns) + eY * mySize.y*(1/rows);
157
158         vector offset = '0 0 0';
159         float newSize;
160         if(ammo_size.x/ammo_size.y > 3)
161         {
162                 newSize = 3 * ammo_size.y;
163                 offset.x = ammo_size.x - newSize;
164                 pos.x += offset.x/2;
165                 ammo_size.x = newSize;
166         }
167         else
168         {
169                 newSize = 1/3 * ammo_size.x;
170                 offset.y = ammo_size.y - newSize;
171                 pos.y += offset.y/2;
172                 ammo_size.y = newSize;
173         }
174
175         Weapon wep = switchweapon;
176         int i;
177         bool infinite_ammo = (STAT(ITEMS) & IT_UNLIMITED_WEAPON_AMMO);
178         row = column = 0;
179         if(autocvar_hud_panel_ammo_onlycurrent)
180         {
181                 if(autocvar__hud_configure)
182                 {
183                         DrawAmmoItem(pos, ammo_size, ammo_rockets, true, false);
184                 }
185                 else
186                 {
187                         DrawAmmoItem(
188                                 pos,
189                                 ammo_size,
190                                 wep.ammo_field,
191                                 true,
192                                 infinite_ammo
193                         );
194                 }
195
196                 ++row;
197                 if(row >= rows)
198                 {
199                         row = 0;
200                         column = column + 1;
201                 }
202         }
203         else
204         {
205                 .int ammotype;
206                 row = column = 0;
207                 for(i = 0; i < AMMO_COUNT; ++i)
208                 {
209                         ammotype = GetAmmoFieldFromNum(i);
210                         DrawAmmoItem(
211                                 pos + eX * column * (ammo_size.x + offset.x) + eY * row * (ammo_size.y + offset.y),
212                                 ammo_size,
213                                 ammotype,
214                                 (wep.ammo_field == ammotype),
215                                 infinite_ammo
216                         );
217
218                         ++row;
219                         if(row >= rows)
220                         {
221                                 row = 0;
222                                 column = column + 1;
223                         }
224                 }
225         }
226
227         if (draw_nades)
228         {
229                 nade_statuschange_elapsedtime = time - nade_statuschange_time;
230
231                 float f = bound(0, nade_statuschange_elapsedtime*2, 1);
232
233                 DrawAmmoNades(pos + eX * column * (ammo_size.x + offset.x) + eY * row * (ammo_size.y + offset.y), ammo_size, nade_prevstatus < nade_cnt && nade_cnt != 0 && f < 1, f);
234         }
235
236         draw_endBoldFont();
237 }