Xonotic
powerups.qc
Go to the documentation of this file.
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 
28 
30 {
31  entity item;
32  for(item = powerupItems; item; item = item.chain)
33  item.count = 0;
34 
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 
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 
76 {
77  // Initialize items
79  {
81  return;
82  if(STAT(HEALTH) <= 0 && autocvar_hud_panel_powerups_hide_ondeath)
83  return;
84  }
85 
86  // Add items to linked list
88 
89  MUTATOR_CALLHOOK(HUD_Powerups_add);
90 
92  return;
93 
94  // Draw panel background
96 
99  else
102 
103  // Set drawing area
104  vector pos = panel_pos;
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 
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
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
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  }
210 }
vector color
bool autocvar_hud_panel_powerups
Definition: powerups.qh:4
#define draw_endBoldFont()
Definition: draw.qh:5
float panel_fg_alpha
Definition: hud.qh:166
int autocvar_hud_panel_powerups_baralign
Definition: powerups.qh:5
void HUD_Panel_DrawProgressBar(vector theOrigin, vector theSize, string pic, float length_ratio, bool vertical, float baralign, vector theColor, float theAlpha, int drawflag)
Definition: hud.qc:270
void HUD_Powerups()
Definition: powerups.qc:75
vector colormod
Definition: powerups.qc:21
bool autocvar__hud_configure
Definition: hud_config.qh:3
int powerupItemsCount
Definition: powerups.qc:27
#define draw_beginBoldFont()
Definition: draw.qh:4
void HUD_Powerups_Export(int fh)
Definition: powerups.qc:9
vector panel_size
Definition: hud.qh:160
entity() spawn
bool autocvar_hud_panel_powerups_hide_ondeath
Definition: powerups.qh:7
int autocvar_hud_panel_powerups_iconalign
Definition: powerups.qh:8
string netname
Definition: powerups.qc:20
void DrawNumIcon(vector myPos, vector mySize, float theTime, string icon, bool vertical, bool isInfinite, int icon_right_align, vector color, float theAlpha)
Definition: hud.qc:479
bool autocvar_hud_panel_powerups_progressbar
Definition: powerups.qh:9
void HUD_Scale_Disable()
Definition: hud.qc:83
vector size
Definition: csprogsdefs.qc:114
void addPowerupItem(string name, string icon, vector color, float currentTime, float lifeTime, bool isInfinite)
Definition: powerups.qc:38
int getPowerupItemAlign(int align, int column, int row, int columns, int rows, bool isVertical)
Definition: powerups.qc:58
#define HUD_Panel_DrawBg()
Definition: hud.qh:54
float lifetime
Definition: powerups.qc:23
void HUD_Scale_Enable()
Definition: hud.qc:90
float cnt
Definition: powerups.qc:24
bool autocvar_hud_panel_powerups_text
Definition: powerups.qh:10
string message
Definition: powerups.qc:19
const float DRAWFLAG_NORMAL
Definition: csprogsdefs.qc:317
#define TC(T, sym)
Definition: _all.inc:82
void DrawNumIcon_expanding(vector myPos, vector mySize, float theTime, string icon, bool vertical, bool isInfinite, int icon_right_align, vector color, float theAlpha, float fadelerp)
Definition: hud.qc:398
vector panel_pos
Definition: hud.qh:159
vector(float skel, float bonenum) _skel_get_boneabs_hidden
entity powerupItems
Definition: powerups.qc:26
float spectatee_status
Definition: main.qh:166
bool autocvar_hud_panel_powerups_dynamichud
Definition: powerups.qh:6
float count
Definition: powerups.qc:22
#define MUTATOR_CALLHOOK(id,...)
Definition: base.qh:140
#define vec2(...)
Definition: vector.qh:90
void resetPowerupItems()
Definition: powerups.qc:29
float autocvar_hud_progressbar_alpha
Definition: hud.qh:201
#define HUD_Write_Cvar(cvar)
Definition: hud_config.qh:38
void HUD_Panel_LoadCvars()
Definition: hud.qc:216
float panel_bg_padding
Definition: hud.qh:171