From 06a35e3a8e44186509138a64b1c93060cd51c210 Mon Sep 17 00:00:00 2001 From: Mario Date: Mon, 17 Jul 2017 01:52:00 +1000 Subject: [PATCH] Reimplement CTS self checkpoints on the client side and include an option to always show them --- defaultXonotic.cfg | 1 + qcsrc/client/autocvars.qh | 2 + qcsrc/client/defs.qh | 2 + qcsrc/client/hud/hud.qh | 2 +- qcsrc/client/hud/panel/racetimer.qc | 63 ++++++++++++++++++++--------- qcsrc/client/main.qc | 45 +++++++++------------ qcsrc/server/race.qc | 30 +++----------- qcsrc/server/race.qh | 4 -- 8 files changed, 73 insertions(+), 76 deletions(-) diff --git a/defaultXonotic.cfg b/defaultXonotic.cfg index ba8bdb228..bd4be43c5 100644 --- a/defaultXonotic.cfg +++ b/defaultXonotic.cfg @@ -1102,6 +1102,7 @@ seta cl_autoscreenshot 1 "Take a screenshot upon the end of a match... 0 = Disab seta cl_jetpack_jump 1 "Activate jetpack by pressing jump in the air. 0 = Disable, 1 = Stop when touching ground, 2 = Enable" +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" // must be at the bottom of this file: diff --git a/qcsrc/client/autocvars.qh b/qcsrc/client/autocvars.qh index d95958392..34efcb4b1 100644 --- a/qcsrc/client/autocvars.qh +++ b/qcsrc/client/autocvars.qh @@ -445,3 +445,5 @@ float autocvar_g_jetpack_attenuation; bool autocvar_cl_showspectators; int autocvar_cl_nade_timer; bool autocvar_r_drawviewmodel; +bool autocvar_cl_race_cptimes_onlyself; +bool autocvar_cl_race_cptimes_showself = true; diff --git a/qcsrc/client/defs.qh b/qcsrc/client/defs.qh index c520a2f1e..d36994ec3 100644 --- a/qcsrc/client/defs.qh +++ b/qcsrc/client/defs.qh @@ -36,9 +36,11 @@ float race_time; float race_laptime; float race_checkpointtime; float race_previousbesttime; +float race_mypreviousbesttime; string race_previousbestname; float race_nextcheckpoint; float race_nextbesttime; +float race_mybesttime; string race_nextbestname; float race_penaltyaccumulator; // qualifying: total penalty time in tenths float race_penaltyeventtime; // time when the player got the penalty diff --git a/qcsrc/client/hud/hud.qh b/qcsrc/client/hud/hud.qh index 1418dff83..d070dce38 100644 --- a/qcsrc/client/hud/hud.qh +++ b/qcsrc/client/hud/hud.qh @@ -61,7 +61,7 @@ void HUD_Reset (); void HUD_Main (); int race_CheckName(string net_name); -string MakeRaceString(int cp, float mytime, float theirtime, float lapdelta, string theirname); +string MakeRaceString(int cp, float mytime, float theirtime, float othertime, float lapdelta, string theirname); int vote_yescount; int vote_nocount; diff --git a/qcsrc/client/hud/panel/racetimer.qc b/qcsrc/client/hud/panel/racetimer.qc index 2f54e2a37..7ad7f943d 100644 --- a/qcsrc/client/hud/panel/racetimer.qc +++ b/qcsrc/client/hud/panel/racetimer.qc @@ -5,14 +5,12 @@ // Race timer (#6) // return the string of the onscreen race timer -string MakeRaceString(int cp, float mytime, float theirtime, float lapdelta, string theirname) +string MakeRaceString(int cp, float mytime, float theirtime, float othertime, float lapdelta, string theirname) { TC(int, cp); - string col; - string timestr; - string cpname; - string lapstr; - lapstr = ""; + string cpname, lapstr = "", timestr = "", col = "^7", othercol = "^7", othertimestr = ""; + if(theirname == "" || !autocvar_cl_race_cptimes_showself) + othertime = 0; // don't count personal time if(theirtime == 0) // goal hit { @@ -32,6 +30,22 @@ string MakeRaceString(int cp, float mytime, float theirtime, float lapdelta, str col = "^2"; } + if(othertime > 0) + { + othertimestr = strcat("+", ftos_decimals(+othertime, TIME_DECIMALS)); + othercol = "^1"; + } + else if(othertime == 0) + { + othertimestr = "+0.0"; + othercol = "^3"; + } + else + { + othertimestr = strcat("-", ftos_decimals(-othertime, TIME_DECIMALS)); + othercol = "^2"; + } + if(lapdelta > 0) { lapstr = sprintf(_(" (-%dL)"), lapdelta); @@ -50,11 +64,11 @@ string MakeRaceString(int cp, float mytime, float theirtime, float lapdelta, str else timestr = TIME_ENCODED_TOSTRING(TIME_ENCODE(theirtime)); col = "^3"; - } - else - { - col = "^7"; - timestr = ""; + if(mytime >= othertime) + othertimestr = strcat("+", ftos_decimals(mytime - othertime, TIME_DECIMALS)); + else + othertimestr = TIME_ENCODED_TOSTRING(TIME_ENCODE(othertime)); + othercol = "^3"; } if(cp == 254) @@ -70,6 +84,8 @@ string MakeRaceString(int cp, float mytime, float theirtime, float lapdelta, str return strcat(col, cpname); else if(theirname == "") return strcat(col, sprintf("%s (%s)", cpname, timestr)); + else if(othertime) + return strcat(col, sprintf("%s %s(%s)%s (%s %s)", cpname, othercol, othertimestr, col, timestr, strcat(ColorTranslateRGB(theirname), col, lapstr))); else return strcat(col, sprintf("%s (%s %s)", cpname, timestr, strcat(ColorTranslateRGB(theirname), col, lapstr))); } @@ -146,20 +162,29 @@ void HUD_RaceTimer () if(race_checkpoint != 254) { if(race_time && race_previousbesttime) - s = MakeRaceString(race_checkpoint, TIME_DECODE(race_time) - TIME_DECODE(race_previousbesttime), 0, 0, race_previousbestname); + 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, race_previousbestname); + s = MakeRaceString(race_checkpoint, 0, -1, 0, 0, race_previousbestname); if(race_time) forcetime = TIME_ENCODED_TOSTRING(race_time); } } else { - if(race_laptime && race_nextbesttime && race_nextcheckpoint != 254) + if(race_laptime && race_nextcheckpoint != 254) { - a = bound(0, 2 - ((race_laptime + TIME_DECODE(race_nextbesttime)) - (time + TIME_DECODE(race_penaltyaccumulator))), 1); - if(a > 0) // next one? - s = MakeRaceString(race_nextcheckpoint, (time + TIME_DECODE(race_penaltyaccumulator)) - race_laptime, TIME_DECODE(race_nextbesttime), 0, race_nextbestname); + if(race_nextbesttime) + { + a = bound(0, 2 - ((race_laptime + TIME_DECODE(race_nextbesttime)) - (time + TIME_DECODE(race_penaltyaccumulator))), 1); + float a2 = bound(0, 2 - ((race_laptime + TIME_DECODE(race_mybesttime)) - (time + TIME_DECODE(race_penaltyaccumulator))), 1); + if(a > 0) // next one? + 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); + else if(a2 > 0) + { + a = a2; + s = MakeRaceString(race_nextcheckpoint, (time + TIME_DECODE(race_penaltyaccumulator)) - race_laptime, TIME_DECODE(race_mybesttime), 0, 0, ""); + } + } } } @@ -205,14 +230,14 @@ void HUD_RaceTimer () if(race_mycheckpointtime) { a = bound(0, 2 - (time - race_mycheckpointtime), 1); - s = MakeRaceString(race_mycheckpoint, TIME_DECODE(race_mycheckpointdelta), -(race_mycheckpointenemy == ""), race_mycheckpointlapsdelta, race_mycheckpointenemy); + s = MakeRaceString(race_mycheckpoint, TIME_DECODE(race_mycheckpointdelta), -(race_mycheckpointenemy == ""), 0, race_mycheckpointlapsdelta, race_mycheckpointenemy); str_pos = pos + vec2(0.5 * (mySize.x - stringwidth(s, true, '1 1 0' * 0.2 * mySize.y)), 0.6 * mySize.y); drawcolorcodedstring(str_pos, s, '1 1 0' * 0.2 * mySize.y, panel_fg_alpha * a, DRAWFLAG_NORMAL); } if(race_othercheckpointtime && race_othercheckpointenemy != "") { a = bound(0, 2 - (time - race_othercheckpointtime), 1); - s = MakeRaceString(race_othercheckpoint, -TIME_DECODE(race_othercheckpointdelta), -(race_othercheckpointenemy == ""), race_othercheckpointlapsdelta, race_othercheckpointenemy); + s = MakeRaceString(race_othercheckpoint, -TIME_DECODE(race_othercheckpointdelta), -(race_othercheckpointenemy == ""), 0, race_othercheckpointlapsdelta, race_othercheckpointenemy); str_pos = pos + vec2(0.5 * (mySize.x - stringwidth(s, true, '1 1 0' * 0.2 * mySize.y)), 0.6 * mySize.y); drawcolorcodedstring(str_pos, s, '1 1 0' * 0.2 * mySize.y, panel_fg_alpha * a, DRAWFLAG_NORMAL); } diff --git a/qcsrc/client/main.qc b/qcsrc/client/main.qc index bf82ccb34..1467a99cc 100644 --- a/qcsrc/client/main.qc +++ b/qcsrc/client/main.qc @@ -132,8 +132,6 @@ void CSQC_Init() registercvar("cl_spawn_near_teammate", "1"); - registercvar("cl_race_cptimes_onlyself", "0"); - if(autocvar_cl_lockview) cvar_set("cl_lockview", "0"); @@ -1036,25 +1034,18 @@ NET_HANDLE(TE_CSQC_RACE, bool isNew) race_checkpoint = ReadByte(); race_time = ReadInt24_t(); race_previousbesttime = ReadInt24_t(); + race_mypreviousbesttime = ReadInt24_t(); if(race_previousbestname) strunzone(race_previousbestname); - race_previousbestname = strzone(ReadString()); - - race_checkpointtime = time; - - if(race_checkpoint == 0 || race_checkpoint == 254) + string pbestname = ReadString(); + if(autocvar_cl_race_cptimes_onlyself) { - race_penaltyaccumulator = 0; - race_laptime = time; // valid + race_previousbesttime = race_mypreviousbesttime; + race_mypreviousbesttime = 0; + race_previousbestname = strzone(""); } - break; - case RACE_NET_CHECKPOINT_HIT_SELF_QUALIFYING: - race_checkpoint = ReadByte(); - race_time = ReadInt24_t(); - race_previousbesttime = ReadInt24_t(); - if(race_previousbestname) - strunzone(race_previousbestname); - race_previousbestname = strzone(""); // handled by MakeRaceString + else + race_previousbestname = strzone(pbestname); race_checkpointtime = time; @@ -1078,18 +1069,18 @@ NET_HANDLE(TE_CSQC_RACE, bool isNew) race_nextcheckpoint = ReadByte(); race_nextbesttime = ReadInt24_t(); + race_mybesttime = ReadInt24_t(); if(race_nextbestname) strunzone(race_nextbestname); - race_nextbestname = strzone(ReadString()); - break; - - case RACE_NET_CHECKPOINT_NEXT_SELF_QUALIFYING: - race_nextcheckpoint = ReadByte(); - - race_nextbesttime = ReadInt24_t(); - if(race_nextbestname) - strunzone(race_nextbestname); - race_nextbestname = strzone(""); // handled by MakeRaceString + string newname = ReadString(); + if(autocvar_cl_race_cptimes_onlyself) + { + race_nextbesttime = race_mybesttime; + race_mybesttime = 0; + race_nextbestname = strzone(""); + } + else + race_nextbestname = strzone(newname); break; case RACE_NET_CHECKPOINT_HIT_RACE: diff --git a/qcsrc/server/race.qc b/qcsrc/server/race.qc index 80023e76a..154722c87 100644 --- a/qcsrc/server/race.qc +++ b/qcsrc/server/race.qc @@ -165,6 +165,7 @@ void race_SendNextCheckpoint(entity e, float spec) // qualifying only int cp = e.race_checkpoint; float recordtime = race_checkpoint_records[cp]; + float myrecordtime = e.race_checkpoint_record[cp]; string recordholder = race_checkpoint_recordholders[cp]; if(recordholder == e.netname) recordholder = ""; @@ -172,7 +173,7 @@ void race_SendNextCheckpoint(entity e, float spec) // qualifying only if(!IS_REAL_CLIENT(e)) return; - if(!spec && !e.cvar_cl_race_cptimes_onlyself) // don't show spectators the player's personal time + if(!spec) msg_entity = e; WRITESPECTATABLE_MSG_ONE(msg_entity, { WriteHeader(MSG_ONE, TE_CSQC_RACE); @@ -186,20 +187,10 @@ void race_SendNextCheckpoint(entity e, float spec) // qualifying only WriteByte(MSG_ONE, RACE_NET_CHECKPOINT_NEXT_QUALIFYING); WriteByte(MSG_ONE, race_CheckpointNetworkID(cp)); // checkpoint the player will be at next WriteInt24_t(MSG_ONE, recordtime); + if(!spec) + WriteInt24_t(MSG_ONE, myrecordtime); WriteString(MSG_ONE, recordholder); }); - - if(!spec && e.cvar_cl_race_cptimes_onlyself) // don't send to spectators! - { - recordtime = e.race_checkpoint_record[cp]; - - // not spectatable - msg_entity = e; - WriteHeader(MSG_ONE, TE_CSQC_RACE); - WriteByte(MSG_ONE, RACE_NET_CHECKPOINT_NEXT_SELF_QUALIFYING); - WriteByte(MSG_ONE, race_CheckpointNetworkID(cp)); // checkpoint the player will be at next - WriteInt24_t(MSG_ONE, recordtime); - } } void race_send_recordtime(float msg) @@ -471,25 +462,14 @@ void race_SendTime(entity e, float cp, float t, float tvalid) if(g_race_qualifying) { WRITESPECTATABLE_MSG_ONE(e, { - if(it == e && e.cvar_cl_race_cptimes_onlyself) - continue; WriteHeader(MSG_ONE, TE_CSQC_RACE); WriteByte(MSG_ONE, RACE_NET_CHECKPOINT_HIT_QUALIFYING); WriteByte(MSG_ONE, race_CheckpointNetworkID(cp)); // checkpoint the player now is at WriteInt24_t(MSG_ONE, t); // time to that intermediate WriteInt24_t(MSG_ONE, recordtime); // previously best time + WriteInt24_t(MSG_ONE, myrecordtime); // previously best time WriteString(MSG_ONE, recordholder); // record holder }); - - if(e.cvar_cl_race_cptimes_onlyself) - { - msg_entity = e; - WriteHeader(MSG_ONE, TE_CSQC_RACE); - WriteByte(MSG_ONE, RACE_NET_CHECKPOINT_HIT_SELF_QUALIFYING); - WriteByte(MSG_ONE, race_CheckpointNetworkID(cp)); // checkpoint the player now is at - WriteInt24_t(MSG_ONE, t); // time to that intermediate - WriteInt24_t(MSG_ONE, myrecordtime); // previously best time - } } } } diff --git a/qcsrc/server/race.qh b/qcsrc/server/race.qh index 7f6a194f2..472827efa 100644 --- a/qcsrc/server/race.qh +++ b/qcsrc/server/race.qh @@ -66,7 +66,3 @@ void race_SendRankings(float pos, float prevpos, float del, float msg); void race_RetractPlayer(entity this); void race_InitSpectator(); - -.bool cvar_cl_race_cptimes_onlyself; - -REPLICATE(cvar_cl_race_cptimes_onlyself, bool, "cl_race_cptimes_onlyself"); -- 2.39.2