From c1a10b36bea450fa9c0363eb74903d025bf21cdb Mon Sep 17 00:00:00 2001 From: Sheldon Johnson Date: Sun, 7 Apr 2024 20:08:31 +1000 Subject: [PATCH] Add play to completion admin option --- README.md | 1 + csqc/csextradefs.qc | 1 + csqc/events.qc | 1 + csqc/menu.qc | 28 +++++++++++++++++++++++++--- ssqc/client.qc | 3 +++ ssqc/commands.qc | 8 ++++++++ ssqc/csmenu.qc | 8 +++++--- ssqc/quadmode.qc | 2 +- ssqc/qw.qc | 1 + 9 files changed, 46 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index f720e71f..506f3b04 100644 --- a/README.md +++ b/README.md @@ -71,6 +71,7 @@ sound files are found in `fortress/sound/hitaudio/` and `fortress/sound/announc * Website backend for match results, stats. Get a token at fortressone.org, connect to a FortressOne server, and `login `. +* `localinfo play_to_completion 0` set to 1 to allow quad to continue to round end even after required score exceeded. * `localinfo pipecooldown_time ` time in seconds for demo pipe cooldown * `localinfo allpipes_cooldown on/off` whether cooldown is applied to individual pipes or all pipes. i.e. with this on the demo can not det any of his pipes immediately after firing. (default off) * `localinfo discord_channel_id ` to specify discord_channel. Required for autoreporting. diff --git a/csqc/csextradefs.qc b/csqc/csextradefs.qc index 6aff7a82..e9027f88 100644 --- a/csqc/csextradefs.qc +++ b/csqc/csextradefs.qc @@ -333,6 +333,7 @@ typedef struct { float quad_round_time; float fo_login_required; float fo_matchrated; + float play_to_completion; float captainmode; float timelimit; float fraglimit; diff --git a/csqc/events.qc b/csqc/events.qc index fb1fc752..ce995b99 100644 --- a/csqc/events.qc +++ b/csqc/events.qc @@ -267,6 +267,7 @@ void() CSQC_Parse_Event = { SERVER_ADMIN.quad_round_time = readfloat(); SERVER_ADMIN.fo_login_required = readfloat(); SERVER_ADMIN.fo_matchrated = readfloat(); + SERVER_ADMIN.play_to_completion = readfloat(); SERVER_ADMIN.timelimit = readfloat(); SERVER_ADMIN.fraglimit = readfloat(); SERVER_ADMIN.clanmode = readfloat(); diff --git a/csqc/menu.qc b/csqc/menu.qc index 2f746daa..17b341d2 100644 --- a/csqc/menu.qc +++ b/csqc/menu.qc @@ -7,6 +7,7 @@ void (float force) FO_Menu_Admin_Timelimit; void (float force) FO_Menu_Admin_Fraglimit; void (float force) FO_Menu_Admin_QuadTimelimit; void (float force) FO_Menu_Admin_FoMatchRated; +void (float force) FO_Menu_Admin_PlayToCompletion; void (float force) FO_Menu_Admin_NewBalance; void (float force) FO_Menu_Spy; void (float force) FO_Menu_Spy_Skin; @@ -443,6 +444,7 @@ var fo_menu FO_MENU_ADMIN_MODES = { {"7","Rated/Unrated","","Will player ratings be affected?",FO_MENU_STATE_NORMAL,{FO_Menu_Admin_FoMatchRated(TRUE);},MENU_BORDER_WARNING}, {"8","New Balance","","New Balance Test",FO_MENU_STATE_NORMAL,{localcmd("cmd new_balance");},MENU_BORDER_WARNING}, {"9","Force Start","","Skip prematch and start the game\nPlease use sparingly",FO_MENU_STATE_NORMAL,{localcmd("cmd forcestart\n");},MENU_BORDER_WARNING}, + MenuSpacer, {"0","Close Menu","","",FO_MENU_STATE_NORMAL,{Menu_Cancel();},MENU_BUTTON}, {"+","Next - Settings","","",FO_MENU_STATE_NORMAL,{Menu_Cancel(); FO_Menu_Admin_Settings(TRUE);},MENU_BUTTON}, {"-","Prev - Main","","",FO_MENU_STATE_NORMAL,{Menu_Cancel(); FO_Menu_Admin_Main(TRUE);},MENU_BUTTON}, @@ -463,9 +465,7 @@ var fo_menu FO_MENU_ADMIN_SETTINGS = { {"2","Fraglimit","","",FO_MENU_STATE_NORMAL,{FO_Menu_Admin_Fraglimit(TRUE);},MENU_BORDER_WARNING}, {"3","Quad Rounds...","","Number of rounds in Quad mode. Usually 2",FO_MENU_STATE_NORMAL,{FO_Menu_Admin_Rounds(TRUE);},MENU_BORDER_WARNING}, {"4","Quad Round Time...","","Round time for each quad round",FO_MENU_STATE_NORMAL,{FO_Menu_Admin_QuadTimelimit(TRUE);},MENU_BORDER_WARNING}, - MenuSpacer, - MenuSpacer, - MenuSpacer, + {"5","Play To Completion","","Play match to end of round even if result decided",FO_MENU_STATE_NORMAL,{FO_Menu_Admin_PlayToCompletion(TRUE);},MENU_BORDER_WARNING}, MenuSpacer, MenuSpacer, MenuSpacer, @@ -479,6 +479,7 @@ var fo_menu FO_MENU_ADMIN_SETTINGS = { FO_MENU_ADMIN_SETTINGS.options[1].value = ftos(SERVER_ADMIN.fraglimit); FO_MENU_ADMIN_SETTINGS.options[2].value = ftos(SERVER_ADMIN.quad_rounds); FO_MENU_ADMIN_SETTINGS.options[3].value = ftos(SERVER_ADMIN.quad_round_time); + FO_MENU_ADMIN_SETTINGS.options[4].value = modeStatus(SERVER_ADMIN.play_to_completion); } }; var void execute_admin_players(float choice, float page) { @@ -620,6 +621,20 @@ var fo_menu FO_MENU_ADMIN_QUAD_TIMELIMIT = { {"0","Back to Main Menu","","",FO_MENU_STATE_NORMAL,{Menu_Cancel();FO_Menu_Admin_Modes(TRUE);},MENU_BUTTON}, }, 11, TRUE }; +var fo_menu FO_MENU_ADMIN_PLAY_TO_COMPLETION = { + [0,0], [300,200], "Play to completion?", FO_MENU_FLAG_USE_MOUSE | FO_MENU_FLAG_CENTER | FO_MENU_FLAG_SHOW_SHORTCUTS | FO_MENU_FLAG_SHOW_VALUES | FO_MENU_FLAG_WARNING | FO_MENU_FLAG_ALLOW_INTERMISSION, { + {"1","No","","Match will end as soon as the winner is known",FO_MENU_STATE_NORMAL,{localcmd("cmd play_to_completion 0\n");FO_Menu_Admin_Settings(TRUE);},MENU_BORDER_WARNING}, + {"2","Yes","","Match will end at the end of the final round",FO_MENU_STATE_NORMAL,{localcmd("cmd play_to_completion 1\n");FO_Menu_Admin_Settings(TRUE);},MENU_BORDER_WARNING}, + MenuSpacer, + MenuSpacer, + MenuSpacer, + MenuSpacer, + MenuSpacer, + MenuSpacer, + MenuSpacer, + {"0","Back to Main Menu","","",FO_MENU_STATE_NORMAL,{Menu_Cancel();FO_Menu_Admin_Modes(TRUE);},MENU_BUTTON}, + }, 10, TRUE +}; var fo_menu FO_MENU_ADMIN_MATCH_RATED = { [0,0], [300,200], "Match Rated?", FO_MENU_FLAG_USE_MOUSE | FO_MENU_FLAG_CENTER | FO_MENU_FLAG_SHOW_SHORTCUTS | FO_MENU_FLAG_SHOW_VALUES | FO_MENU_FLAG_WARNING | FO_MENU_FLAG_ALLOW_INTERMISSION, { {"1","Rated","","Match result will affect player ratings",FO_MENU_STATE_NORMAL,{localcmd("cmd fo_matchrated 1\n");FO_Menu_Admin_Modes(TRUE);},MENU_BORDER_WARNING}, @@ -1215,6 +1230,12 @@ void FO_Menu_Admin_QuadTimelimit(float force) = { CurrentMenu = &FO_MENU_ADMIN_QUAD_TIMELIMIT; fo_hud_menu_active = TRUE; } +void FO_Menu_Admin_PlayToCompletion(float force) = { + if(fo_hud_menu_active && !force) + return; + CurrentMenu = &FO_MENU_ADMIN_PLAY_TO_COMPLETION; + fo_hud_menu_active = TRUE; +} void FO_Menu_Admin_FoMatchRated(float force) = { if(fo_hud_menu_active && !force) return; @@ -1401,6 +1422,7 @@ void FO_Hud_Init() { INIT_MENU_IDS(FO_MENU_ADMIN_ROUNDS); INIT_MENU_IDS(FO_MENU_ADMIN_QUAD_TIMELIMIT); INIT_MENU_IDS(FO_MENU_ADMIN_MATCH_RATED); + INIT_MENU_IDS(FO_MENU_ADMIN_PLAY_TO_COMPLETION); INIT_MENU_IDS(FO_MENU_ADMIN_TIMELIMIT); INIT_MENU_IDS(FO_MENU_ADMIN_FRAGLIMIT); INIT_MENU_IDS(FO_MENU_VOTE); diff --git a/ssqc/client.qc b/ssqc/client.qc index 5d12ebbb..38f61bfc 100644 --- a/ssqc/client.qc +++ b/ssqc/client.qc @@ -779,6 +779,9 @@ void () DecodeLevelParms = { map_restart_time = CF_GetSetting("map_restart_Time", "mrt", "120"); + // if 1, quad round will not finish immediately if result is determined [off] + play_to_completion = CF_GetSetting("ptc", "play_to_completion", "0"); + // enforces login loginRequired = CF_GetSetting("loginrequired", "logreq", "0"); diff --git a/ssqc/commands.qc b/ssqc/commands.qc index 2cbcbf7d..a0e9451e 100644 --- a/ssqc/commands.qc +++ b/ssqc/commands.qc @@ -1296,6 +1296,14 @@ float (string arg1, string arg2, string arg3) ParseCmds = { UpdateAllAdmins(); } break; + case "play_to_completion": + if(arg2 != "0" && arg2 != "1") + return; + + processedCmd = TRUE; + localcmd ("localinfo play_to_completion ",arg2,"\n"); + UpdateAllAdmins(); + break; case "captainmode": processedCmd = TRUE; if(arg2 && arg3) { diff --git a/ssqc/csmenu.qc b/ssqc/csmenu.qc index 7f9988bc..9d1816a7 100644 --- a/ssqc/csmenu.qc +++ b/ssqc/csmenu.qc @@ -168,10 +168,11 @@ void Update_ServerAdminInfo(entity pl) = { if(!infokeyf(pl, INFOKEY_P_CSQCACTIVE)) return; msg_entity = pl; - local float cm = CF_GetSetting("c", "clan", "off"), - qm = CF_GetSetting("quadmode", "quadmode", "off"), + local float cm = CF_GetSetting("c", "clan", "off"), + qm = CF_GetSetting("quadmode", "quadmode", "off"), dm = CF_GetSetting("duelmode", "duelmode", "off"), - flr = CF_GetSetting("flr", "fologinrequired", "off"); + flr = CF_GetSetting("flr", "fologinrequired", "off"), + ptc = CF_GetSetting("ptc", "play_to_completion", "off"); WriteByte(MSG_MULTICAST, SVC_CGAMEPACKET); WriteByte(MSG_MULTICAST, MSG_SERVER_ADMIN_INFO); WriteByte(MSG_MULTICAST, is_paused || cease_fire); @@ -179,6 +180,7 @@ void Update_ServerAdminInfo(entity pl) = { WriteFloat(MSG_MULTICAST, infokeyf(world, "round_time")); WriteFloat(MSG_MULTICAST, (fo_login_required?1:0) + (flr?2:0)); WriteFloat(MSG_MULTICAST, CF_GetSetting("mra", "fo_matchrated", "2")); + WriteFloat(MSG_MULTICAST, (play_to_completion?1:0) + (ptc?2:0)); WriteFloat(MSG_MULTICAST, infokeyf(world, "timelimit")); WriteFloat(MSG_MULTICAST, infokeyf(world, "fraglimit")); WriteFloat(MSG_MULTICAST, (clanbattle?1:0) + (cm?2:0)); diff --git a/ssqc/quadmode.qc b/ssqc/quadmode.qc index 4e4be652..1e430e87 100644 --- a/ssqc/quadmode.qc +++ b/ssqc/quadmode.qc @@ -388,7 +388,7 @@ void () QuadRoundThink = { local float fl; if (rounds < 2) { - if (CheckWinningTeam() != 0) { + if (CheckWinningTeam() != 0 && !play_to_completion) { if (quad_winner != CheckWinningTeam()) { quad_winner = CheckWinningTeam(); self.think = QuadRoundOver; diff --git a/ssqc/qw.qc b/ssqc/qw.qc index 01778f4f..07600659 100644 --- a/ssqc/qw.qc +++ b/ssqc/qw.qc @@ -470,6 +470,7 @@ float round_delay_time; float round_start_time; float round_end_time; float map_restart_time; +float play_to_completion; float gametime; float is_countdown; float duelmode;