]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/common/gamemodes/gamemode/race/cl_race.qc
Add a mutator hook to indicate whether rankings should be shown
[xonotic/xonotic-data.pk3dir.git] / qcsrc / common / gamemodes / gamemode / race / cl_race.qc
1 #include "cl_race.qh"
2
3 // Race/CTS HUD mod icons
4 float crecordtime_prev; // last remembered crecordtime
5 float crecordtime_change_time; // time when crecordtime last changed
6 float srecordtime_prev; // last remembered srecordtime
7 float srecordtime_change_time; // time when srecordtime last changed
8
9 float race_status_time;
10 int race_status_prev;
11 string race_status_name_prev;
12
13 // Check if the given name already exist in race rankings? In that case, where? (otherwise return 0)
14 int race_CheckName(string net_name)
15 {
16         int rank = 0;
17         string zoned_name = strzone(strdecolorize(entcs_GetName(player_localnum)));
18         for (int i = RANKINGS_CNT - 1; i >= 0; --i)
19                 if (strdecolorize(grecordholder[i]) == zoned_name)
20                 {
21                         rank = i + 1;
22                         break;
23                 }
24         strfree(zoned_name);
25         return rank;
26 }
27
28 void race_showTime(string text, vector pos, vector timeText_ofs, float theTime, vector textSize, float f)
29 {
30         drawstring_aspect(pos, text, textSize, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
31         drawstring_aspect(pos + timeText_ofs, TIME_ENCODED_TOSTRING(theTime), textSize, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
32         if (f < 1) {
33                 drawstring_aspect_expanding(pos, text, textSize, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL, f);
34                 drawstring_aspect_expanding(pos + timeText_ofs, TIME_ENCODED_TOSTRING(theTime), textSize, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL, f);
35         }
36 }
37
38 void HUD_Mod_Race(vector pos, vector mySize)
39 {
40         entity me = playerslots[player_localnum];
41         float score = me.(scores(ps_primary));
42
43         if(!(scores_flags(ps_primary) & SFL_TIME) || teamplay) // race/cts record display on HUD
44         {
45                 mod_active = 0; // hide it in this case!
46                 return; // no records in the actual race
47         }
48
49         mod_active = 1;
50
51         // clientside personal record
52         string rr;
53         if(ISGAMETYPE(CTS))
54                 rr = CTS_RECORD;
55         else
56                 rr = RACE_RECORD;
57         float t = stof(db_get(ClientProgsDB, strcat(shortmapname, rr, "time")));
58
59         if(score && (score < t || !t)) {
60                 db_put(ClientProgsDB, strcat(shortmapname, rr, "time"), ftos(score));
61                 if(autocvar_cl_autodemo_delete_keeprecords)
62                 {
63                         float f = autocvar_cl_autodemo_delete;
64                         f &= ~1;
65                         cvar_set("cl_autodemo_delete", ftos(f)); // don't delete demo with new record!
66                 }
67         }
68
69         if(t != crecordtime_prev) {
70                 crecordtime_prev = t;
71                 crecordtime_change_time = time;
72         }
73
74         vector textPos, medalPos;
75         float squareSize;
76         if(mySize.x > mySize.y) {
77                 // text on left side
78                 squareSize = min(mySize.y, mySize.x/2);
79                 vector ofs = vec2(0.5 * max(0, mySize.x/2 - squareSize), 0.5 * (mySize.y - squareSize));
80                 textPos = pos + ofs;
81                 ofs.x += 0.5 * mySize.x;
82                 medalPos = pos + ofs;
83         } else {
84                 // text on top
85                 squareSize = min(mySize.x, mySize.y/2);
86                 vector ofs = vec2(0.5 * (mySize.x - squareSize), 0.5 * max(0, mySize.y/2 - squareSize));
87                 textPos = pos + ofs;
88                 ofs.y += 0.5 * mySize.y;
89                 medalPos = pos + ofs;
90         }
91         vector textSize = vec2(squareSize, 0.25 * squareSize);
92
93         race_showTime(_("Personal best"), textPos, eY * 0.25 * squareSize, t, textSize, time - crecordtime_change_time);
94
95         // server record
96         t = race_server_record;
97         if(t != srecordtime_prev) {
98                 srecordtime_prev = t;
99                 srecordtime_change_time = time;
100         }
101
102         textPos += eY * 0.5 * squareSize;
103         race_showTime(_("Server best"), textPos, eY * 0.25 * squareSize, t, textSize, time - srecordtime_change_time);
104
105         if (race_status != race_status_prev || race_status_name != race_status_name_prev) {
106                 race_status_time = time + 5;
107                 race_status_prev = race_status;
108                 strcpy(race_status_name_prev, race_status_name);
109         }
110
111         // race "awards"
112         float a = bound(0, race_status_time - time, 1);
113         string s = textShortenToWidth(ColorTranslateRGB(race_status_name), squareSize, '1 1 0' * 0.1 * squareSize, stringwidth_colors);
114
115         float rank = 0;
116         if(race_status > 0)
117                 rank = race_CheckName(race_status_name);
118         string rankname = count_ordinal(rank);
119         vector namepos = medalPos + '0 0.8 0' * squareSize;
120         vector rankpos = medalPos + '0 0.15 0' * squareSize;
121
122         if(race_status == 0)
123                 drawpic_aspect_skin(medalPos, "race_newfail", '1 1 0' * squareSize, '1 1 1', panel_fg_alpha * a, DRAWFLAG_NORMAL);
124         else if(race_status == 1) {
125                 drawpic_aspect_skin(medalPos + '0.1 0 0' * squareSize, "race_newtime", '1 1 0' * 0.8 * squareSize, '1 1 1', panel_fg_alpha * a, DRAWFLAG_NORMAL);
126                 drawcolorcodedstring_aspect(namepos, s, '1 0.2 0' * squareSize, panel_fg_alpha * a, DRAWFLAG_NORMAL);
127                 drawstring_aspect(rankpos, rankname, '1 0.15 0' * squareSize, '1 1 1', panel_fg_alpha * a, DRAWFLAG_NORMAL);
128         } else if(race_status == 2) {
129                 if(strdecolorize(race_status_name) == strdecolorize(entcs_GetName(player_localnum)) || !race_myrank || race_myrank < rank)
130                         drawpic_aspect_skin(medalPos + '0.1 0 0' * squareSize, "race_newrankgreen", '1 1 0' * 0.8 * squareSize, '1 1 1', panel_fg_alpha * a, DRAWFLAG_NORMAL);
131                 else
132                         drawpic_aspect_skin(medalPos + '0.1 0 0' * squareSize, "race_newrankyellow", '1 1 0' * 0.8 * squareSize, '1 1 1', panel_fg_alpha * a, DRAWFLAG_NORMAL);
133                 drawcolorcodedstring_aspect(namepos, s, '1 0.2 0' * squareSize, panel_fg_alpha * a, DRAWFLAG_NORMAL);
134                 drawstring_aspect(rankpos, rankname, '1 0.15 0' * squareSize, '1 1 1', panel_fg_alpha * a, DRAWFLAG_NORMAL);
135         } else if(race_status == 3) {
136                 drawpic_aspect_skin(medalPos + '0.1 0 0' * squareSize, "race_newrecordserver", '1 1 0' * 0.8 * squareSize, '1 1 1', panel_fg_alpha * a, DRAWFLAG_NORMAL);
137                 drawcolorcodedstring_aspect(namepos, s, '1 0.2 0' * squareSize, panel_fg_alpha * a, DRAWFLAG_NORMAL);
138                 drawstring_aspect(rankpos, rankname, '1 0.15 0' * squareSize, '1 1 1', panel_fg_alpha * a, DRAWFLAG_NORMAL);
139         }
140
141         if (race_status_time - time <= 0) {
142                 race_status_prev = -1;
143                 race_status = -1;
144                 strfree(race_status_name);
145                 strfree(race_status_name_prev);
146         }
147 }
148
149 REGISTER_MUTATOR(cl_race, true);
150
151 MUTATOR_HOOKFUNCTION(cl_race, HUD_Physics_showoptional)
152 {
153         return ISGAMETYPE(RACE); // show the optional physics panel
154 }
155
156 MUTATOR_HOOKFUNCTION(cl_race, HUD_Score_show)
157 {
158         return spectatee_status == -1 && ISGAMETYPE(RACE); // hide the score panel while observing
159 }
160
161 MUTATOR_HOOKFUNCTION(cl_race, ShowRankings)
162 {
163         if(ISGAMETYPE(RACE))
164         {
165                 M_ARGV(0, string) = _("Rankings");
166                 return true;
167         }
168 }