]> git.rm.cloudns.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Add optional split times in infomessage hud, and print_cptimes command to display...
authorDes - <gitlab@damianv.com.ar>
Mon, 2 Sep 2024 16:33:12 +0000 (16:33 +0000)
committerterencehill <piuntn@gmail.com>
Mon, 2 Sep 2024 16:33:12 +0000 (16:33 +0000)
qcsrc/client/command/cl_cmd.qc
qcsrc/client/hud/panel/infomessages.qc
qcsrc/client/hud/panel/racetimer.qc
qcsrc/client/hud/panel/racetimer.qh
qcsrc/client/main.qc
qcsrc/client/main.qh
xonotic-client.cfg

index 45f15d3a191a373b11cda9fa34ac0cf6a2d4ad2a..2cbc02568e020269ba1454d72a11bcdfae766d44 100644 (file)
@@ -427,26 +427,50 @@ void LocalCommand_sendcvar(int request, int argc)
        }
 }
 
+void LocalCommand_print_cptimes(int request)
+{
+       switch(request)
+       {
+               case CMD_REQUEST_COMMAND:
+               {
+                       LOG_HELP(_("Checkpoint times:"));
+                       for (int i = 0; i <= 255; ++i)
+                       {
+                               if (race_checkpoint_splits[i])
+                                       LOG_HELP(race_checkpoint_splits[i]);
+                       }
+                       return;
+               }
+               default:
+               case CMD_REQUEST_USAGE:
+               {
+                       LOG_HELP("Usage:^3 cl_cmd print_cptimes");
+                       LOG_HELP("  No arguments required, will show current or last run checkpoint times.");
+                       return;
+               }
+       }
+}
+
 /* use this when creating a new command, making sure to place it in alphabetical order... also,
 ** ADD ALL NEW COMMANDS TO commands.cfg WITH PROPER ALIASES IN THE SAME FASHION!
 void LocalCommand_(int request)
 {
-    switch(request)
-    {
-        case CMD_REQUEST_COMMAND:
-        {
-
-            return;
-        }
-
-        default:
-        case CMD_REQUEST_USAGE:
-        {
-            LOG_HELP("Usage:^3 cl_cmd ");
-            LOG_HELP("  No arguments required.");
-            return;
-        }
-    }
+       switch(request)
+       {
+               case CMD_REQUEST_COMMAND:
+               {
+
+                       return;
+               }
+
+               default:
+               case CMD_REQUEST_USAGE:
+               {
+                       LOG_HELP("Usage:^3 cl_cmd ");
+                       LOG_HELP("  No arguments required.");
+                       return;
+               }
+       }
 }
 */
 
@@ -464,6 +488,7 @@ CLIENT_COMMAND(handlevote, "System to handle selecting a vote or option") { Loca
 CLIENT_COMMAND(hud, "Commands regarding/controlling the HUD system") { LocalCommand_hud(request, arguments); }
 CLIENT_COMMAND(localprint, "Create your own centerprint sent to yourself") { LocalCommand_localprint(request, arguments); }
 CLIENT_COMMAND(mv_download, "Retrieve mapshot picture from the server") { LocalCommand_mv_download(request, arguments); }
+CLIENT_COMMAND(print_cptimes, "Print the stored checkpoint times for current or last run") { LocalCommand_print_cptimes(request); }
 CLIENT_COMMAND(sendcvar, "Send a cvar to the server (like cl_weaponpriority)") { LocalCommand_sendcvar(request, arguments); }
 
 void LocalCommand_macro_help()
index 2774d64983b31eec4325821072f0014c74ac0831..5866271ef97c6944f64fd22aaece9099bc765190 100644 (file)
@@ -1,4 +1,6 @@
 #include "infomessages.qh"
+#include "racetimer.qh" // for race_checkpoint_splits
+#include <common/gamemodes/gamemode/race/race.qh> // for ISGAMETYPE(RACE)
 
 #include <client/draw.qh>
 #include <common/ent_cs.qh>
@@ -228,6 +230,37 @@ void HUD_InfoMessages()
                                InfoMessage(s);
                        }
                }
+               if(autocvar_cl_race_checkpoint_splits_hud && !spectatee_status) {
+                       int lines[6];
+                       int ln = 5;
+                       // show up to race_nextcheckpoint (not including) or everything
+                       // if you are before start (0 or 254)
+                       // (except race_laptime != 0 for race, means next is
+                       // start+finish so don't show previous lap finish)
+                       int i;
+                       if (race_checkpoint != 0 && race_checkpoint != 254)
+                       { // middle of run/race
+                               i = race_checkpoint;
+                       }
+                       else if (ISGAMETYPE(RACE) && race_nextcheckpoint == 0)
+                       { // before start, but on race, so don't keep old finish visible
+                               i = 253;
+                       }
+                       else
+                       { // before start, not on race (cts), keep old run cps visible
+                               i = 255;
+                       }
+                       for (; ln >= 0 && i >= 0; --i)
+                       {
+                               if (race_checkpoint_splits[i])
+                               {
+                                       lines[ln] = i;
+                                       --ln;
+                               }
+                       }
+                       for (int j = 0; j < 6; ++j)
+                               InfoMessage(race_checkpoint_splits[lines[j]]);
+               }
        }
        else
        {
index 072e6a0d1466a9201b703e5bff94302f6aba9e15..4a76dbbd55d5fe3b211d0b474ef6cc3e3833c892 100644 (file)
@@ -3,6 +3,12 @@
 #include <client/draw.qh>
 #include <common/ent_cs.qh>
 
+// used for caching the string after passing through a checkpoint
+float racetimer_lastcheckpoint;
+string racetimer_checkpoint_comparison;
+string racetimer_checkpoint_time;
+bool racetimer_have_stored_splits;
+
 // Race timer (#8)
 
 void HUD_RaceTimer_Export(int fh)
@@ -96,6 +102,41 @@ string MakeRaceString(int cp, float mytime, float theirtime, float othertime, fl
                return strcat(col, sprintf("%s (%s %s)", cpname, timestr, strcat(ColorTranslateRGB(theirname), col, lapstr)));
 }
 
+void ClearRaceSplits() {
+       bool once = true;
+       racetimer_lastcheckpoint = 0;
+       for (int i = 0; i <= 255; ++i)
+       {
+               if(race_checkpoint_splits[i]
+               && autocvar_cl_race_checkpoint_splits_console)
+               {
+                       if(once)
+                       {
+                               LOG_HELP(_("Checkpoint times:"));
+                               once = false;
+                       }
+                       LOG_HELP(race_checkpoint_splits[i]);
+               }
+               strfree(race_checkpoint_splits[i]);
+       }
+       racetimer_have_stored_splits = false;
+}
+
+void StoreRaceSplits(float race_checkpoint, string forcetime, string s) {
+       // store checkpoint splits string for later printing
+       if (!entcs_IsSpectating(player_localnum))
+       {
+               // 0 or 255 go to 255 as finish, strcpy does the free if needed
+               strcpy(race_checkpoint_splits[race_checkpoint ? race_checkpoint : 255], (forcetime != "") ? sprintf("%s %s", forcetime, s) : s);
+       }
+
+       // cache
+       racetimer_lastcheckpoint = race_checkpoint;
+       strcpy(racetimer_checkpoint_comparison, s);
+       strcpy(racetimer_checkpoint_time, forcetime);
+       racetimer_have_stored_splits = true;
+}
+
 void HUD_RaceTimer ()
 {
        if(!autocvar__hud_configure)
@@ -164,36 +205,35 @@ void HUD_RaceTimer ()
                a = bound(0, 2 - (time - race_checkpointtime), 1);
                s = "";
                forcetime = "";
-               if(a > 0) // just hit a checkpoint?
+               if(a > 0) // display a frozen split for the just reached checkpoint
                {
-                       if(race_checkpoint != 254)
+                       if(race_checkpoint != 254 && race_time != 0)
                        {
-                               if(race_time && race_previousbesttime)
-                                       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);
+                               if (race_checkpoint == racetimer_lastcheckpoint)
+                               {
+                                       // use cached strings
+                                       s = racetimer_checkpoint_comparison;
+                                       forcetime = racetimer_checkpoint_time;
+                               }
                                else
-                                       s = MakeRaceString(race_checkpoint, 0, -1, 0, 0, race_previousbestname);
-                               if(race_time)
-                                       forcetime = TIME_ENCODED_TOSTRING(race_time, false);
-
-                               // store checkpoint splits string for later printing
-                               // check if we advanced to next cp
-                               if (!entcs_IsSpectating(player_localnum) && race_checkpoint_splits_previous != race_checkpoint)
                                {
-                                       // are we somehow overwriting something? how?
-                                       if (race_checkpoint_splits[race_checkpoint_splits_previous+1])
-                                       {
-                                               LOG_WARNF("race_checkpoint_splits: overwriting #%f %s\n",
-                                                       race_checkpoint_splits_previous+1,
-                                                       race_checkpoint_splits[race_checkpoint_splits_previous+1]);
-                                               strfree(race_checkpoint_splits[race_checkpoint_splits_previous+1]);
-                                       }
-
-                                       strcpy(race_checkpoint_splits[race_checkpoint_splits_previous+1], sprintf("%s %s", forcetime, s));
+                                       // build checkpoint split strings
+                                       if(race_time && race_previousbesttime)
+                                               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);
+                                       else
+                                               s = MakeRaceString(race_checkpoint, 0, -1, 0, 0, race_previousbestname);
+                                       if(race_time)
+                                               forcetime = TIME_ENCODED_TOSTRING(race_time, false);
 
-                                       // don't use ++ in case that checkpoints have jumps like 10th to 20th
-                                       race_checkpoint_splits_previous = race_checkpoint;
+                                       StoreRaceSplits(race_checkpoint, forcetime, s);
                                }
                        }
+                       else
+                       {
+                               // clean cp splits on start
+                               if(racetimer_have_stored_splits && race_time == 0)
+                                       ClearRaceSplits();
+                       }
                }
                else
                {
@@ -249,6 +289,9 @@ void HUD_RaceTimer ()
        }
        else
        {
+               if(racetimer_have_stored_splits && (race_time == 0 || time < STAT(GAMESTARTTIME)))
+                       ClearRaceSplits();
+
                if(race_mycheckpointtime)
                {
                        a = bound(0, 2 - (time - race_mycheckpointtime), 1);
index 2efcd08150431b7d8044841e22d44fc99c46ddee..d213584df1eb74b437d3fb12a8ad76a6f8a227fc 100644 (file)
@@ -9,8 +9,7 @@ float race_checkpoint;
 float race_time;
 float race_laptime;
 float race_checkpointtime;
-string race_checkpoint_splits[255];
-int race_checkpoint_splits_previous = 0;
+string race_checkpoint_splits[256];
 float race_previousbesttime;
 float race_mypreviousbesttime;
 string race_previousbestname;
index 95469177996192a69b767e9f1c7c9a6925caa8bd..9cf0185ed268b7d01e4bdbe35b4221ab3d4b72f2 100644 (file)
@@ -1197,30 +1197,6 @@ NET_HANDLE(TE_CSQC_RACE, bool isNew)
                                race_penaltyaccumulator = 0;
                                race_laptime = time; // valid
                        }
-
-                       // show checkpoint splits after a run
-                       // specs can switch players for confusing splits, deny service
-                       // if hit 255 finish line or if finish line is 0 or if restarted
-                       if (!entcs_IsSpectating(player_localnum)
-                       && (race_checkpoint == 255
-                       || race_checkpoint < race_checkpoint_splits_previous))
-                       {
-                               LOG_HELP(_("Checkpoint times:"));
-                               for (int i = 0; i < 255; ++i)
-                               {
-                                       // does this index have a split?
-                                       if (race_checkpoint_splits[i])
-                                       {
-                                               // print it if enabled and free it
-                                               if (autocvar_cl_race_checkpoint_splits_console)
-                                                       LOG_HELP(race_checkpoint_splits[i]);
-                                               strfree(race_checkpoint_splits[i]);
-                                       }
-                               }
-
-                               // allow registering 0th cp in case we start at 254 start line
-                               race_checkpoint_splits_previous = 0;
-                       }
                        break;
 
                case RACE_NET_CHECKPOINT_CLEAR:
index e7972edc4ad69dd4907e9ffd5b69eb11028a858e..8b96b0833e2a9229931b05ca8519d4513c57ec98 100644 (file)
@@ -22,8 +22,10 @@ bool autocvar_developer_csqcentities;
 // or the release after it to support the old-stable release
 // this can't be done now as players would lack these from their configs then
 bool autocvar_cl_race_checkpoint_splits_console;
+bool autocvar_cl_race_checkpoint_splits_hud;
 #else
 AUTOCVAR_SAVE(cl_race_checkpoint_splits_console, bool, 1, "Print checkpoint splits to console");
+AUTOCVAR_SAVE(cl_race_checkpoint_splits_hud, bool, 1, "Show race checkpoint splits on HUD in infomessages");
 #endif
 bool autocvar_cl_race_cptimes_onlyself; // TODO: move to race gamemode
 bool autocvar_cl_race_cptimes_showself = false;
index 4f36583a7ea617ebf8a84e23c4a9eab844c7ab41..f61cb22cab6d9c50f2e2d647605296b0668182bb 100644 (file)
@@ -712,6 +712,7 @@ seta cl_jetpack_jump 1 "Activate jetpack by pressing jump in the air. 0 = Disabl
 seta cl_race_cptimes_showself 1 "Always show your own times as well as the current best on checkpoints in Race/CTS"
 seta cl_race_cptimes_onlyself 0 "Only show your own times on checkpoints in Race/CTS. Can be forced on by the server via g_race_cptimes_onlyself"
 seta cl_race_checkpoint_splits_console 1 "Print checkpoint splits to console"
+seta cl_race_checkpoint_splits_hud 1 "Show race checkpoint splits on HUD in infomessages"
 
 seta cl_cts_noautoswitch 0 "Prevent forced switching to new weapons in CTS"