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