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