1 #include "racetimer.qh"
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>
11 void HUD_RaceTimer_Export(int fh)
13 // allow saving cvars that aesthetically change the panel into hud skin files
16 // return the string of the onscreen race timer
17 string MakeRaceString(int cp, float mytime, float theirtime, float othertime, float lapdelta, string theirname)
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
24 if(theirtime == 0) // goal hit
28 timestr = strcat("+", ftos_decimals(+mytime, TIME_DECIMALS));
38 timestr = strcat("-", ftos_decimals(-mytime, TIME_DECIMALS));
44 othertimestr = strcat("+", ftos_decimals(+othertime, TIME_DECIMALS));
47 else if(othertime == 0)
49 othertimestr = "+0.0";
54 othertimestr = strcat("-", ftos_decimals(-othertime, TIME_DECIMALS));
60 lapstr = sprintf(_(" (-%dL)"), lapdelta);
65 lapstr = sprintf(_(" (+%dL)"), -lapdelta);
69 else if(theirtime > 0) // anticipation
71 if(mytime >= theirtime)
72 timestr = strcat("+", ftos_decimals(mytime - theirtime, TIME_DECIMALS));
74 timestr = TIME_ENCODED_TOSTRING(TIME_ENCODE(theirtime));
76 if(mytime >= othertime)
77 othertimestr = strcat("+", ftos_decimals(mytime - othertime, TIME_DECIMALS));
79 othertimestr = TIME_ENCODED_TOSTRING(TIME_ENCODE(othertime));
84 cpname = _("Start line");
86 cpname = _("Finish line");
88 cpname = sprintf(_("Intermediate %d"), cp);
90 cpname = _("Finish line");
93 return strcat(col, cpname);
94 else if(theirname == "")
95 return strcat(col, sprintf("%s (%s)", cpname, timestr));
97 return strcat(col, sprintf("%s %s(%s)%s (%s %s)", cpname, othercol, othertimestr, col, timestr, strcat(ColorTranslateRGB(theirname), col, lapstr)));
99 return strcat(col, sprintf("%s (%s %s)", cpname, timestr, strcat(ColorTranslateRGB(theirname), col, lapstr)));
102 void HUD_RaceTimer ()
104 if(!autocvar__hud_configure)
106 if(!autocvar_hud_panel_racetimer) return;
107 if(!MUTATOR_CALLHOOK(ShowRaceTimer)) return;
108 if(spectatee_status == -1) return;
111 HUD_Panel_LoadCvars();
117 if (autocvar_hud_panel_racetimer_dynamichud)
124 pos += '1 1 0' * panel_bg_padding;
125 mySize -= '2 2 0' * panel_bg_padding;
128 // always force 4:1 aspect
129 vector newSize = '0 0 0';
130 if(mySize.x/mySize.y > 4)
132 newSize.x = 4 * mySize.y;
133 newSize.y = mySize.y;
135 pos.x = pos.x + (mySize.x - newSize.x) / 2;
139 newSize.y = 1/4 * mySize.x;
140 newSize.x = mySize.x;
142 pos.y = pos.y + (mySize.y - newSize.y) / 2;
150 if(autocvar__hud_configure)
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);
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"));
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);
165 else if(race_checkpointtime)
167 a = bound(0, 2 - (time - race_checkpointtime), 1);
170 if(a > 0) // just hit a checkpoint?
172 if(race_checkpoint != 254)
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);
177 s = MakeRaceString(race_checkpoint, 0, -1, 0, 0, race_previousbestname);
179 forcetime = TIME_ENCODED_TOSTRING(race_time);
184 if(race_laptime && race_nextcheckpoint != 254)
186 if(race_nextbesttime)
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);
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);
204 a = bound(0, 2 - (time - race_penaltyeventtime), 1);
207 s = sprintf(_("PENALTY: %.1f (%s)"), race_penaltytime * 0.1, race_penaltyreason);
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);
214 draw_beginBoldFont();
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);
225 if(race_laptime && race_checkpoint != 255)
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);
236 if(race_mycheckpointtime)
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);
243 if(race_othercheckpointtime && race_othercheckpointenemy != "")
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);
251 if(race_penaltytime && !race_penaltyaccumulator)
253 t = race_penaltytime * 0.1 + race_penaltyeventtime;
254 a = bound(0, (1 + t - time), 1);
260 t = (t - time) * 0.1;
268 s = sprintf(_("PENALTY: %.1f (%s)"), t, race_penaltyreason);
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);