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