3 #include <client/draw.qh>
4 #include <common/mutators/base.qh>
6 // Race/CTS HUD mod icons
7 float crecordtime_prev; // last remembered crecordtime
8 float crecordtime_change_time; // time when crecordtime last changed
9 float srecordtime_prev; // last remembered srecordtime
10 float srecordtime_change_time; // time when srecordtime last changed
12 float race_status_time;
14 string race_status_name_prev;
16 // Check if the given name already exist in race rankings? In that case, where? (otherwise return 0)
17 int race_CheckName(string net_name)
20 string zoned_name = strzone(strdecolorize(entcs_GetName(player_localnum)));
21 for (int i = RANKINGS_CNT - 1; i >= 0; --i)
22 if (strdecolorize(grecordholder[i]) == zoned_name)
31 void race_showTime(string text, vector pos, vector timeText_ofs, float theTime, vector textSize, float f)
33 drawstring_aspect(pos, text, textSize, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
34 drawstring_aspect(pos + timeText_ofs, TIME_ENCODED_TOSTRING(theTime, false), textSize, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
36 drawstring_aspect_expanding(pos, text, textSize, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL, f);
37 drawstring_aspect_expanding(pos + timeText_ofs, TIME_ENCODED_TOSTRING(theTime, false), textSize, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL, f);
41 void HUD_Mod_Race(vector pos, vector mySize)
43 entity me = playerslots[player_localnum];
44 float score = me.(scores(ps_primary));
46 if(!(scores_flags(ps_primary) & SFL_TIME) || teamplay) // race/cts record display on HUD
48 mod_active = 0; // hide it in this case!
49 return; // no records in the actual race
54 // clientside personal record
60 float t = stof(db_get(ClientProgsDB, strcat(shortmapname, rr, "time")));
62 if(score && (score < t || !t)) {
63 db_put(ClientProgsDB, strcat(shortmapname, rr, "time"), ftos(score));
64 if(autocvar_cl_autodemo_delete_keeprecords)
66 float f = autocvar_cl_autodemo_delete;
68 cvar_set("cl_autodemo_delete", ftos(f)); // don't delete demo with new record!
72 if(t != crecordtime_prev) {
74 crecordtime_change_time = time;
77 vector textPos, medalPos;
79 if(mySize.x > mySize.y) {
81 squareSize = min(mySize.y, mySize.x/2);
82 vector ofs = vec2(0.5 * max(0, mySize.x/2 - squareSize), 0.5 * (mySize.y - squareSize));
84 ofs.x += 0.5 * mySize.x;
88 squareSize = min(mySize.x, mySize.y/2);
89 vector ofs = vec2(0.5 * (mySize.x - squareSize), 0.5 * max(0, mySize.y/2 - squareSize));
91 ofs.y += 0.5 * mySize.y;
94 vector textSize = vec2(squareSize, 0.25 * squareSize);
96 race_showTime(_("Personal best"), textPos, eY * 0.25 * squareSize, t, textSize, time - crecordtime_change_time);
99 t = race_server_record;
100 if(t != srecordtime_prev) {
101 srecordtime_prev = t;
102 srecordtime_change_time = time;
105 textPos += eY * 0.5 * squareSize;
106 race_showTime(_("Server best"), textPos, eY * 0.25 * squareSize, t, textSize, time - srecordtime_change_time);
108 if (race_status != race_status_prev || race_status_name != race_status_name_prev) {
109 race_status_time = time + 5;
110 race_status_prev = race_status;
111 strcpy(race_status_name_prev, race_status_name);
115 float a = bound(0, race_status_time - time, 1);
116 string s = textShortenToWidth(ColorTranslateRGB(race_status_name), squareSize, '1 1 0' * 0.1 * squareSize, stringwidth_colors);
120 rank = race_CheckName(race_status_name);
121 string rankname = count_ordinal(rank);
122 vector namepos = medalPos + '0 0.8 0' * squareSize;
123 vector rankpos = medalPos + '0 0.15 0' * squareSize;
126 drawpic_aspect_skin(medalPos, "race_newfail", '1 1 0' * squareSize, '1 1 1', panel_fg_alpha * a, DRAWFLAG_NORMAL);
127 else if(race_status == 1) {
128 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);
129 drawcolorcodedstring_aspect(namepos, s, '1 0.2 0' * squareSize, panel_fg_alpha * a, DRAWFLAG_NORMAL);
130 drawstring_aspect(rankpos, rankname, '1 0.15 0' * squareSize, '1 1 1', panel_fg_alpha * a, DRAWFLAG_NORMAL);
131 } else if(race_status == 2) {
132 if(strdecolorize(race_status_name) == strdecolorize(entcs_GetName(player_localnum)) || !race_myrank || race_myrank < rank)
133 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);
135 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);
136 drawcolorcodedstring_aspect(namepos, s, '1 0.2 0' * squareSize, panel_fg_alpha * a, DRAWFLAG_NORMAL);
137 drawstring_aspect(rankpos, rankname, '1 0.15 0' * squareSize, '1 1 1', panel_fg_alpha * a, DRAWFLAG_NORMAL);
138 } else if(race_status == 3) {
139 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);
140 drawcolorcodedstring_aspect(namepos, s, '1 0.2 0' * squareSize, panel_fg_alpha * a, DRAWFLAG_NORMAL);
141 drawstring_aspect(rankpos, rankname, '1 0.15 0' * squareSize, '1 1 1', panel_fg_alpha * a, DRAWFLAG_NORMAL);
144 if (race_status_time - time <= 0) {
145 race_status_prev = -1;
147 strfree(race_status_name);
148 strfree(race_status_name_prev);
152 REGISTER_MUTATOR(cl_race, true);
154 MUTATOR_HOOKFUNCTION(cl_race, HUD_Physics_showoptional)
156 return ISGAMETYPE(RACE); // show the optional physics panel
159 MUTATOR_HOOKFUNCTION(cl_race, HUD_StrafeHUD_showoptional)
161 return ISGAMETYPE(RACE); // show the optional strafehud
164 MUTATOR_HOOKFUNCTION(cl_race, HUD_Score_show)
166 return spectatee_status == -1 && ISGAMETYPE(RACE); // hide the score panel while observing
169 MUTATOR_HOOKFUNCTION(cl_race, DrawScoreboardItemStats)
171 return ISGAMETYPE(RACE); // hide the item stats panel
174 MUTATOR_HOOKFUNCTION(cl_race, ShowRankings)
178 M_ARGV(0, string) = _("Rankings");
183 MUTATOR_HOOKFUNCTION(cl_race, DrawScoreboardAccuracy)
185 return ISGAMETYPE(RACE); // accuracy is not a factor in this gamemode
188 MUTATOR_HOOKFUNCTION(cl_race, ShowRaceTimer)
190 return ISGAMETYPE(RACE); // show the race timer panel
193 MUTATOR_HOOKFUNCTION(cl_race, TeamRadar_Draw)
195 return ISGAMETYPE(RACE); // show all competitors in a race