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