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