]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/client/hud/panel/powerups.qc
Update default video settings
[xonotic/xonotic-data.pk3dir.git] / qcsrc / client / hud / panel / powerups.qc
1 #include "powerups.qh"
2
3 #include <client/draw.qh>
4 #include <common/items/_mod.qh>
5 #include <common/util.qh>
6
7 // Powerups (#2)
8
9 void HUD_Powerups_Export(int fh)
10 {
11         // allow saving cvars that aesthetically change the panel into hud skin files
12         HUD_Write_Cvar("hud_panel_powerups_iconalign");
13         HUD_Write_Cvar("hud_panel_powerups_baralign");
14         HUD_Write_Cvar("hud_panel_powerups_progressbar");
15         HUD_Write_Cvar("hud_panel_powerups_text");
16 }
17
18 // Powerup item fields (reusing existing fields)
19 .string message;  // Human readable name
20 .string netname;  // Icon name
21 .vector colormod; // Color
22 .float count;     // Time left
23 .float lifetime;  // Maximum time
24 .float cnt;       // Infinite timer
25
26 entity powerupItems;
27 int powerupItemsCount;
28
29 void resetPowerupItems()
30 {
31         entity item;
32         for(item = powerupItems; item; item = item.chain)
33                 item.count = 0;
34
35         powerupItemsCount = 0;
36 }
37
38 void addPowerupItem(string name, string icon, vector color, float currentTime, float lifeTime, bool isInfinite)
39 {
40         if(!powerupItems)
41                 powerupItems = spawn();
42
43         entity item;
44         for(item = powerupItems; item.count; item = item.chain)
45                 if(!item.chain)
46                         item.chain = spawn();
47
48         item.message  = name;
49         item.netname  = icon;
50         item.colormod = color;
51         item.count    = currentTime;
52         item.lifetime = lifeTime;
53         item.cnt      = isInfinite;
54
55         ++powerupItemsCount;
56 }
57
58 int getPowerupItemAlign(int align, int column, int row, int columns, int rows, bool isVertical)
59 {
60         TC(int, align); TC(int, column); TC(int, row); TC(int, columns); TC(int, rows); TC(bool, isVertical);
61         if(align < 2)
62                 return align;
63
64         bool isTop    =  isVertical && rows > 1 && row == 0;
65         bool isBottom =  isVertical && rows > 1 && row == rows-1;
66         bool isLeft   = !isVertical && columns > 1 && column == 0;
67         bool isRight  = !isVertical && columns > 1 && column == columns-1;
68
69         if(isTop    || isLeft)  return (align == 2) ? 1 : 0;
70         if(isBottom || isRight) return (align == 2) ? 0 : 1;
71
72         return 2;
73 }
74
75 void HUD_Powerups()
76 {
77         // Initialize items
78         if(!autocvar__hud_configure)
79         {
80                 if((!autocvar_hud_panel_powerups) || (spectatee_status == -1))
81                         return;
82                 if(STAT(HEALTH) <= 0 && autocvar_hud_panel_powerups_hide_ondeath)
83                         return;
84         }
85
86         // Add items to linked list
87         resetPowerupItems();
88
89         MUTATOR_CALLHOOK(HUD_Powerups_add);
90
91         if(!powerupItemsCount)
92                 return;
93
94         // Draw panel background
95         HUD_Panel_LoadCvars();
96
97         if (autocvar_hud_panel_powerups_dynamichud)
98                 HUD_Scale_Enable();
99         else
100                 HUD_Scale_Disable();
101         HUD_Panel_DrawBg();
102
103         // Set drawing area
104         vector pos = panel_pos;
105         vector size = panel_size;
106         bool isVertical = size.y > size.x;
107
108         if(panel_bg_padding)
109         {
110                 pos += '1 1 0' * panel_bg_padding;
111                 size -= '2 2 0' * panel_bg_padding;
112         }
113
114         // Find best partitioning of the drawing area
115         const float DESIRED_ASPECT = 6;
116         float aspect = 0, a;
117         int columns = 0, c;
118         int rows = 0, r;
119         int i = 1;
120
121         do
122         {
123                 c = floor(powerupItemsCount / i);
124                 r = ceil(powerupItemsCount / c);
125                 a = isVertical ? (size.y/r) / (size.x/c) : (size.x/c) / (size.y/r);
126
127                 if(i == 1 || fabs(DESIRED_ASPECT - a) < fabs(DESIRED_ASPECT - aspect))
128                 {
129                         aspect = a;
130                         columns = c;
131                         rows = r;
132                 }
133         }
134         while(++i <= powerupItemsCount);
135
136         // Prevent single items from getting too wide
137         if(powerupItemsCount == 1 && aspect > DESIRED_ASPECT)
138         {
139                 if(isVertical)
140                 {
141                         size.y *= 0.5;
142                         pos.y += size.y * 0.5;
143                 }
144                 else
145                 {
146                         size.x *= 0.5;
147                         pos.x += size.x * 0.5;
148                 }
149         }
150
151         // Draw items from linked list
152         vector itemPos = pos;
153         vector itemSize = vec2(size.x / columns, size.y / rows);
154         vector textColor = '1 1 1';
155
156         int fullSeconds = 0;
157         int align = 0;
158         int column = 0;
159         int row = 0;
160
161         draw_beginBoldFont();
162         for(entity item = powerupItems; item.count; item = item.chain)
163         {
164                 itemPos = vec2(pos.x + column * itemSize.x, pos.y + row * itemSize.y);
165
166                 // Draw progressbar
167                 if(autocvar_hud_panel_powerups_progressbar)
168                 {
169                         align = getPowerupItemAlign(autocvar_hud_panel_powerups_baralign, column, row, columns, rows, isVertical);
170                         HUD_Panel_DrawProgressBar(itemPos, itemSize, "progressbar", item.count / item.lifetime, isVertical, align, item.colormod, autocvar_hud_progressbar_alpha * panel_fg_alpha, DRAWFLAG_NORMAL);
171                 }
172
173                 // Draw icon and text
174                 if(autocvar_hud_panel_powerups_text)
175                 {
176                         align = getPowerupItemAlign(autocvar_hud_panel_powerups_iconalign, column, row, columns, rows, isVertical);
177                         fullSeconds = ceil(item.count);
178                         textColor = '0.6 0.6 0.6' + (item.colormod * 0.4);
179
180                         if(item.cnt)
181                                 DrawNumIcon(itemPos, itemSize, fullSeconds, item.netname, isVertical, true, align, textColor, panel_fg_alpha);
182                         else
183                         {
184                                 if(item.count > 1)
185                                         DrawNumIcon(itemPos, itemSize, fullSeconds, item.netname, isVertical, false, align, textColor, panel_fg_alpha);
186                                 if(item.count <= 5)
187                                         DrawNumIcon_expanding(itemPos, itemSize, fullSeconds, item.netname, isVertical, false, align, textColor, panel_fg_alpha, bound(0, (fullSeconds - item.count) / 0.5, 1));
188                         }
189                 }
190
191                 // Determine next section
192                 if(isVertical)
193                 {
194                         if(++column >= columns)
195                         {
196                                 column = 0;
197                                 ++row;
198                         }
199                 }
200                 else
201                 {
202                         if(++row >= rows)
203                         {
204                                 row = 0;
205                                 ++column;
206                         }
207                 }
208         }
209         draw_endBoldFont();
210 }