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