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