]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/client/hud/panel/racetimer.qc
Add a mutator hook to indicate whether the physics HUD panel should be shown when...
[xonotic/xonotic-data.pk3dir.git] / qcsrc / client / hud / panel / racetimer.qc
1 #include "racetimer.qh"
2
3 #include <client/autocvars.qh>
4 #include <client/defs.qh>
5 #include <client/miscfunctions.qh>
6 #include <common/gamemodes/_mod.qh>
7 #include <common/mapinfo.qh>
8
9 // Race timer (#8)
10
11 void HUD_RaceTimer_Export(int fh)
12 {
13         // allow saving cvars that aesthetically change the panel into hud skin files
14 }
15
16 // return the string of the onscreen race timer
17 string MakeRaceString(int cp, float mytime, float theirtime, float othertime, float lapdelta, string theirname)
18 {
19         TC(int, cp);
20         string cpname, lapstr = "", timestr = "", col = "^7", othercol = "^7", othertimestr = "";
21         if(theirname == "" || !autocvar_cl_race_cptimes_showself)
22                 othertime = 0; // don't count personal time
23
24         if(theirtime == 0) // goal hit
25         {
26                 if(mytime > 0)
27                 {
28                         timestr = strcat("+", ftos_decimals(+mytime, TIME_DECIMALS));
29                         col = "^1";
30                 }
31                 else if(mytime == 0)
32                 {
33                         timestr = "+0.0";
34                         col = "^3";
35                 }
36                 else
37                 {
38                         timestr = strcat("-", ftos_decimals(-mytime, TIME_DECIMALS));
39                         col = "^2";
40                 }
41
42                 if(othertime > 0)
43                 {
44                         othertimestr = strcat("+", ftos_decimals(+othertime, TIME_DECIMALS));
45                         othercol = "^1";
46                 }
47                 else if(othertime == 0)
48                 {
49                         othertimestr = "+0.0";
50                         othercol = "^3";
51                 }
52                 else
53                 {
54                         othertimestr = strcat("-", ftos_decimals(-othertime, TIME_DECIMALS));
55                         othercol = "^2";
56                 }
57
58                 if(lapdelta > 0)
59                 {
60                         lapstr = sprintf(_(" (-%dL)"), lapdelta);
61                         col = "^2";
62                 }
63                 else if(lapdelta < 0)
64                 {
65                         lapstr = sprintf(_(" (+%dL)"), -lapdelta);
66                         col = "^1";
67                 }
68         }
69         else if(theirtime > 0) // anticipation
70         {
71                 if(mytime >= theirtime)
72                         timestr = strcat("+", ftos_decimals(mytime - theirtime, TIME_DECIMALS));
73                 else
74                         timestr = TIME_ENCODED_TOSTRING(TIME_ENCODE(theirtime));
75                 col = "^3";
76                 if(mytime >= othertime)
77                         othertimestr = strcat("+", ftos_decimals(mytime - othertime, TIME_DECIMALS));
78                 else
79                         othertimestr = TIME_ENCODED_TOSTRING(TIME_ENCODE(othertime));
80                 othercol = "^7";
81         }
82
83         if(cp == 254)
84                 cpname = _("Start line");
85         else if(cp == 255)
86                 cpname = _("Finish line");
87         else if(cp)
88                 cpname = sprintf(_("Intermediate %d"), cp);
89         else
90                 cpname = _("Finish line");
91
92         if(theirtime < 0)
93                 return strcat(col, cpname);
94         else if(theirname == "")
95                 return strcat(col, sprintf("%s (%s)", cpname, timestr));
96         else if(othertime)
97                 return strcat(col, sprintf("%s %s(%s)%s (%s %s)", cpname, othercol, othertimestr, col, timestr, strcat(ColorTranslateRGB(theirname), col, lapstr)));
98         else
99                 return strcat(col, sprintf("%s (%s %s)", cpname, timestr, strcat(ColorTranslateRGB(theirname), col, lapstr)));
100 }
101
102 void HUD_RaceTimer ()
103 {
104         if(!autocvar__hud_configure)
105         {
106                 if(!autocvar_hud_panel_racetimer) return;
107                 if(!(ISGAMETYPE(RACE) || ISGAMETYPE(CTS))) return;
108                 if(spectatee_status == -1) return;
109         }
110
111         HUD_Panel_LoadCvars();
112
113         vector pos, mySize;
114         pos = panel_pos;
115         mySize = panel_size;
116
117         if (autocvar_hud_panel_racetimer_dynamichud)
118                 HUD_Scale_Enable();
119         else
120                 HUD_Scale_Disable();
121         HUD_Panel_DrawBg();
122         if(panel_bg_padding)
123         {
124                 pos += '1 1 0' * panel_bg_padding;
125                 mySize -= '2 2 0' * panel_bg_padding;
126         }
127
128         // always force 4:1 aspect
129         vector newSize = '0 0 0';
130         if(mySize.x/mySize.y > 4)
131         {
132                 newSize.x = 4 * mySize.y;
133                 newSize.y = mySize.y;
134
135                 pos.x = pos.x + (mySize.x - newSize.x) / 2;
136         }
137         else
138         {
139                 newSize.y = 1/4 * mySize.x;
140                 newSize.x = mySize.x;
141
142                 pos.y = pos.y + (mySize.y - newSize.y) / 2;
143         }
144         mySize = newSize;
145
146         float a, t;
147         string s, forcetime;
148         vector str_pos;
149
150         if(autocvar__hud_configure)
151         {
152                 s = "0:13:37";
153                 draw_beginBoldFont();
154                 str_pos = pos + eX * 0.5 * (mySize.x - stringwidth(s, false, '1 1 0' * 0.6 * mySize.y));
155                 drawstring(str_pos, s, '1 1 0' * 0.6 * mySize.y, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
156                 draw_endBoldFont();
157                 s = strcat("^1", sprintf(_("Intermediate %d"), 1), " (+15.42)");
158                 str_pos = pos + vec2(0.5 * (mySize.x - stringwidth(s, true, '1 1 0' * 0.2 * mySize.y)), 0.6 * mySize.y);
159                 drawcolorcodedstring(str_pos, s, '1 1 0' * 0.2 * mySize.y, panel_fg_alpha, DRAWFLAG_NORMAL);
160                 s = sprintf(_("PENALTY: %.1f (%s)"), 2, _("missing a checkpoint"));
161                 s = strcat("^1", s);
162                 str_pos = pos + vec2(0.5 * (mySize.x - stringwidth(s, true, '1 1 0' * 0.2 * mySize.y)), 0.8 * mySize.y);
163                 drawcolorcodedstring(str_pos, s, '1 1 0' * 0.2 * mySize.y, panel_fg_alpha, DRAWFLAG_NORMAL);
164         }
165         else if(race_checkpointtime)
166         {
167                 a = bound(0, 2 - (time - race_checkpointtime), 1);
168                 s = "";
169                 forcetime = "";
170                 if(a > 0) // just hit a checkpoint?
171                 {
172                         if(race_checkpoint != 254)
173                         {
174                                 if(race_time && race_previousbesttime)
175                                         s = MakeRaceString(race_checkpoint, TIME_DECODE(race_time) - TIME_DECODE(race_previousbesttime), 0, ((race_mypreviousbesttime) ? TIME_DECODE(race_time) - TIME_DECODE(race_mypreviousbesttime) : 0), 0, race_previousbestname);
176                                 else
177                                         s = MakeRaceString(race_checkpoint, 0, -1, 0, 0, race_previousbestname);
178                                 if(race_time)
179                                         forcetime = TIME_ENCODED_TOSTRING(race_time);
180                         }
181                 }
182                 else
183                 {
184                         if(race_laptime && race_nextcheckpoint != 254)
185                         {
186                                 if(race_nextbesttime)
187                                 {
188                                         a = bound(0, 2 - ((race_laptime + TIME_DECODE(race_nextbesttime)) - (time + TIME_DECODE(race_penaltyaccumulator))), 1);
189                                         float a2 = ((race_mybesttime) ? bound(0, 2 - ((race_laptime + TIME_DECODE(race_mybesttime)) - (time + TIME_DECODE(race_penaltyaccumulator))), 1) : 0);
190                                         if(a > 0) // next one?
191                                                 s = MakeRaceString(race_nextcheckpoint, (time + TIME_DECODE(race_penaltyaccumulator)) - race_laptime, TIME_DECODE(race_nextbesttime), ((a2 > 0) ? TIME_DECODE(race_mybesttime) : 0), 0, race_nextbestname);
192                                 }
193                         }
194                 }
195
196                 if(s != "" && a > 0)
197                 {
198                         str_pos = pos + vec2(0.5 * (mySize.x - stringwidth(s, true, '1 1 0' * 0.2 * mySize.y)), 0.6 * mySize.y);
199                         drawcolorcodedstring(str_pos, s, '1 1 0' * 0.2 * mySize.y, panel_fg_alpha * a, DRAWFLAG_NORMAL);
200                 }
201
202                 if(race_penaltytime)
203                 {
204                         a = bound(0, 2 - (time - race_penaltyeventtime), 1);
205                         if(a > 0)
206                         {
207                                 s = sprintf(_("PENALTY: %.1f (%s)"), race_penaltytime * 0.1, race_penaltyreason);
208                                 s = strcat("^1", s);
209                                 str_pos = pos + vec2(0.5 * (mySize.x - stringwidth(s, true, '1 1 0' * 0.2 * mySize.y)), 0.8 * mySize.y);
210                                 drawcolorcodedstring(str_pos, s, '1 1 0' * 0.2 * mySize.y, panel_fg_alpha * a, DRAWFLAG_NORMAL);
211                         }
212                 }
213
214                 draw_beginBoldFont();
215
216                 if(forcetime != "")
217                 {
218                         a = bound(0, (time - race_checkpointtime) / 0.5, 1);
219                         str_pos = pos + eX * 0.5 * (mySize.x - stringwidth(forcetime, false, '1 1 0' * 0.6 * mySize.y));
220                         drawstring_expanding(str_pos, forcetime, '1 1 0' * 0.6 * mySize.y, '1 1 1', panel_fg_alpha, 0, a);
221                 }
222                 else
223                         a = 1;
224
225                 if(race_laptime && race_checkpoint != 255)
226                 {
227                         s = TIME_ENCODED_TOSTRING(TIME_ENCODE(time + TIME_DECODE(race_penaltyaccumulator) - race_laptime));
228                         str_pos = pos + eX * 0.5 * (mySize.x - stringwidth(s, false, '0.6 0.6 0' * mySize.y));
229                         drawstring(str_pos, s, '0.6 0.6 0' * mySize.y, '1 1 1', panel_fg_alpha * a, DRAWFLAG_NORMAL);
230                 }
231
232                 draw_endBoldFont();
233         }
234         else
235         {
236                 if(race_mycheckpointtime)
237                 {
238                         a = bound(0, 2 - (time - race_mycheckpointtime), 1);
239                         s = MakeRaceString(race_mycheckpoint, TIME_DECODE(race_mycheckpointdelta), -(race_mycheckpointenemy == ""), 0, race_mycheckpointlapsdelta, race_mycheckpointenemy);
240                         str_pos = pos + vec2(0.5 * (mySize.x - stringwidth(s, true, '1 1 0' * 0.2 * mySize.y)), 0.6 * mySize.y);
241                         drawcolorcodedstring(str_pos, s, '1 1 0' * 0.2 * mySize.y, panel_fg_alpha * a, DRAWFLAG_NORMAL);
242                 }
243                 if(race_othercheckpointtime && race_othercheckpointenemy != "")
244                 {
245                         a = bound(0, 2 - (time - race_othercheckpointtime), 1);
246                         s = MakeRaceString(race_othercheckpoint, -TIME_DECODE(race_othercheckpointdelta), -(race_othercheckpointenemy == ""), 0, race_othercheckpointlapsdelta, race_othercheckpointenemy);
247                         str_pos = pos + vec2(0.5 * (mySize.x - stringwidth(s, true, '1 1 0' * 0.2 * mySize.y)), 0.6 * mySize.y);
248                         drawcolorcodedstring(str_pos, s, '1 1 0' * 0.2 * mySize.y, panel_fg_alpha * a, DRAWFLAG_NORMAL);
249                 }
250
251                 if(race_penaltytime && !race_penaltyaccumulator)
252                 {
253                         t = race_penaltytime * 0.1 + race_penaltyeventtime;
254                         a = bound(0, (1 + t - time), 1);
255                         if(a > 0)
256                         {
257                                 string col;
258                                 if(time < t)
259                                 {
260                                         t = (t - time) * 0.1;
261                                         col = "^1";
262                                 }
263                                 else
264                                 {
265                                         t = 0;
266                                         col = "^2";
267                                 }
268                                 s = sprintf(_("PENALTY: %.1f (%s)"), t, race_penaltyreason);
269                                 s = strcat(col, s);
270                                 str_pos = pos + vec2(0.5 * (mySize.x - stringwidth(s, true, '1 1 0' * 0.2 * mySize.y)), 0.6 * mySize.y);
271                                 drawcolorcodedstring(str_pos, s, '1 1 0' * 0.2 * mySize.y, panel_fg_alpha * a, DRAWFLAG_NORMAL);
272                         }
273                 }
274         }
275 }