]> git.rm.cloudns.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Show nextmap on HUD and rewrite nextmap from cvar to cmd
authorDr. Jaska <drjaska83@gmail.com>
Tue, 3 Sep 2024 10:57:07 +0000 (10:57 +0000)
committerDr. Jaska <drjaska83@gmail.com>
Tue, 3 Sep 2024 10:57:07 +0000 (10:57 +0000)
12 files changed:
commands.cfg
qcsrc/client/hud/panel/scoreboard.qc
qcsrc/client/hud/panel/scoreboard.qh
qcsrc/server/client.qc
qcsrc/server/command/sv_cmd.qc
qcsrc/server/command/vote.qh
qcsrc/server/intermission.qc
qcsrc/server/intermission.qh
qcsrc/server/mapvoting.qc
qcsrc/server/world.qc
xonotic-client.cfg
xonotic-server.cfg

index 8ff4e78b838aeecf71bdd36690509c7065e118cc..ae8719a0f5edd5743fa2a93093caac31d5a82c56 100644 (file)
@@ -249,6 +249,7 @@ alias gotomap              "qc_cmd_sv     gotomap              ${* ?}" // Simple
 alias lockteams            "qc_cmd_sv     lockteams            ${* ?}" // Disable the ability for players to switch or enter teams
 alias make_mapinfo         "qc_cmd_sv     make_mapinfo         ${* ?}" // Automatically rebuild mapinfo files
 alias moveplayer           "qc_cmd_sv     moveplayer           ${* ?}" // Change the team/status of a player
+alias nextmap              "qc_cmd_sv     nextmap              ${* ?}" // Set/Query the next map
 alias nospectators         "qc_cmd_sv     nospectators         ${* ?}" // Automatically remove spectators from a match
 alias printstats           "qc_cmd_sv     printstats           ${* ?}" // Dump eventlog player stats and other score information
 alias radarmap             "qc_cmd_sv     radarmap             ${* ?}" // Generate a radar image of the map
index d59ed97fe38b31fdb511b8801227cc1a887eecea..49a5fac1ee227d8bf8070030899a14d32ad6fa89 100644 (file)
@@ -2439,6 +2439,14 @@ void Scoreboard_Draw()
        sb_gameinfo_type_fontsize = hud_fontsize * 2.5;
        sb_gameinfo_detail_fontsize = hud_fontsize * 1.3;
 
+       if (GET_NEXTMAP() != "")
+       {
+               // NOTE: nextmap is drawn before title to avoid covering title in case of long map name
+               str = strcat("^7", _("Next map:"), " ^9", GET_NEXTMAP());
+               drawcolorcodedstring(pos + vec2(hud_fontsize.x * 0.5, sb_gameinfo_type_fontsize.y - hud_fontsize.y * 1.25),
+                       str, hud_fontsize, panel_fg_alpha, DRAWFLAG_NORMAL);
+       }
+
        // Game Info: Game Type
        if (scoreboard_ui_enabled == 2)
                str = _("Team Selection");
index a7cb2b553927a2896b8c317a782ca15f9753e4ac..fae09910b328ab1b74eecf8d8c543b87f291ed70 100644 (file)
@@ -5,6 +5,11 @@ bool autocvar_cl_deathscoreboard;
 string autocvar_scoreboard_columns;
 float autocvar_hud_panel_scoreboard_namesize = 15;
 
+string autocvar__nextmap;
+// no reason for get_nextmap to be a function for now
+// macro to not have an unnecessary function call stackframe
+#define GET_NEXTMAP() autocvar__nextmap
+
 bool sb_showscores; // set by +showscores engine command
 
 bool scoreboard_active;
index c5dd182685cdb8faf359371949415bacd69f737f..00d4c03937709545dae39c8058cf22d255f5a410 100644 (file)
@@ -1222,6 +1222,9 @@ void ClientConnect(entity this)
                        setpause(0);
                localcmd("\nsv_hook_firstjoin\n");
        }
+
+       if (get_nextmap() != "")
+               Send_NextMap_To_Player(this);
 }
 
 .string shootfromfixedorigin;
index 475f7eb5a9381c3e2d00c2035085a60e16f7c7a5..7398329eead3aab6f171d81e633ab824e31d4f86 100644 (file)
@@ -1169,6 +1169,42 @@ void GameCommand_moveplayer(int request, int argc)
        }
 }
 
+void GameCommand_nextmap(int request, int argc)
+{
+       switch (request)
+       {
+               case CMD_REQUEST_COMMAND:
+               {
+                       if (argc >= 2) // nextmap with mapname arg
+                       {
+                               if (argc > 2)
+                                       LOG_HELP("Warning: nextmap only takes 1 argument");
+
+                               string map = ValidateMap(argv(1), NULL);
+                               if (map != "" && map != get_nextmap())
+                                       Set_NextMap(map);
+                       }
+                       else // nextmap without args
+                       {
+                               if (get_nextmap() != "")
+                                       LOG_HELP(get_nextmap());
+                               else
+                                       LOG_HELP("none");
+                       }
+                       return;  // never fall through to usage
+               }
+
+               default:
+               case CMD_REQUEST_USAGE:
+               {
+                       LOG_HELP("Usage:^3 sv_cmd nextmap [<mapname>]");
+                       LOG_HELP("  Without arguments it prints current nextmap if one is set");
+                       LOG_HELP("  With arguments it attempts to set nextmap");
+                       return;
+               }
+       }
+}
+
 void GameCommand_nospectators(int request)
 {
        switch (request)
@@ -1757,6 +1793,7 @@ SERVER_COMMAND(gotomap, "Simple command to switch to another map") { GameCommand
 SERVER_COMMAND(lockteams, "Disable the ability for players to switch or enter teams") { GameCommand_lockteams(request); }
 SERVER_COMMAND(make_mapinfo, "Automatically rebuild mapinfo files") { GameCommand_make_mapinfo(request); }
 SERVER_COMMAND(moveplayer, "Change the team/status of a player") { GameCommand_moveplayer(request, arguments); }
+SERVER_COMMAND(nextmap, "Set/Query the next map") { GameCommand_nextmap(request, arguments); }
 SERVER_COMMAND(nospectators, "Automatically remove spectators from a match") { GameCommand_nospectators(request); }
 SERVER_COMMAND(printstats, "Dump eventlog player stats and other score information") { GameCommand_printstats(request); }
 SERVER_COMMAND(radarmap, "Generate a radar image of the map") { GameCommand_radarmap(request, arguments); }
index 509d4d233ab559f2b590ca54b9fda25a93d2c7e3..98dec6b7d3bd56a3e31291bf2207ef13d960c68d 100644 (file)
@@ -59,6 +59,7 @@ string vote_parsed_display; // visual string which is fixed after being parsed
 void VoteThink();
 void VoteReset(bool verbose);
 void VoteCommand(int request, entity caller, int argc, string vote_command);
+string ValidateMap(string validated_map, entity caller);
 
 // warmup and nagger stuff
 const float RESTART_COUNTDOWN = 10;
index 7f11112c1133dd898123da259a89ecbecbef8e10..21d3b98316f0f6943b5edd7f6d584332e2fe6323 100644 (file)
 #include <server/scores_rules.qh>
 #include <server/world.qh>
 
+void Send_NextMap_To_Player(entity pl)
+{
+       stuffcmd(pl, sprintf("\nsettemp _nextmap %s\n", get_nextmap()));
+}
+
+void Set_NextMap(string mapname)
+{
+       if (mapname != "")
+               strcpy(_nextmap, mapname);
+       else
+               strfree(_nextmap);
+
+       FOREACH_CLIENT(IS_REAL_CLIENT(it), { Send_NextMap_To_Player(it); });
+}
+
 string GetGametype()
 {
        return MapInfo_Type_ToString(MapInfo_LoadedGametype);
@@ -356,11 +371,12 @@ float DoNextMapOverride(float reinit)
                alreadychangedlevel = true;
                return true;
        }
-       if(autocvar_nextmap != "")
+       if(get_nextmap() != "")
        {
                string m;
-               m = GameTypeVote_MapInfo_FixName(autocvar_nextmap);
-               cvar_set("nextmap",m);
+               m = GameTypeVote_MapInfo_FixName(get_nextmap());
+               if (m != get_nextmap())
+                       Set_NextMap(m);
 
                if(!m || gametypevote)
                        return false;
@@ -411,12 +427,13 @@ string GotoMap(string m)
        if (!m)
                return "The map you suggested is not available on this server.";
        if (!autocvar_sv_vote_gametype)
-       if(!MapInfo_CheckMap(m))
+       if (!MapInfo_CheckMap(m))
                return "The map you suggested does not support the current game mode.";
-       cvar_set("nextmap", m);
+       if (m != get_nextmap())
+               Set_NextMap(m);
        if (!intermission_running)
                cvar_set("_endmatch", "1");
-       if(mapvote_initialized || alreadychangedlevel)
+       if (mapvote_initialized || alreadychangedlevel)
        {
                if(DoNextMapOverride(0))
                        return "Map switch initiated.";
index 44a5a2da8384e09b58b0f34928afa2893299ea73..e1fb0ec8d6032d706e453a7d1ff556096c2dee14 100644 (file)
@@ -1,7 +1,15 @@
 #pragma once
 
 bool autocvar_lastlevel;
-string autocvar_nextmap;
+
+string _nextmap;
+void Send_NextMap_To_Player(entity pl);
+void Set_NextMap(string mapname);
+
+// no reason for get_nextmap to be a function for now
+// macro to not have an unnecessary function call stackframe
+#define get_nextmap() _nextmap
+
 bool autocvar_samelevel;
 bool autocvar_sv_autoscreenshot;
 string autocvar_sv_intermission_cdtrack;
index b52f4518d978c3084504a19c9e12b55dccdf55df..d94cb1ffa0507ff802eecbd93ec5fd9dbb4b37bd 100644 (file)
@@ -69,9 +69,9 @@ int GameTypeVote_AvailabilityStatus(string type_name)
        if( type == NULL )
                return flag;
 
-       if ( autocvar_nextmap != "" )
+       if ( get_nextmap() != "" )
        {
-               if ( !MapInfo_Get_ByName(autocvar_nextmap, false, NULL) )
+               if ( !MapInfo_Get_ByName(get_nextmap(), false, NULL) )
                        return flag;
                if (!(MapInfo_Map_supportedGametypes & type.gametype_flags))
                        return flag;
@@ -384,7 +384,7 @@ bool MapVote_SendEntity(entity this, entity to, int sf)
                {
                        // gametype vote
                        WriteByte(MSG_ENTITY, BIT(0)); // gametypevote_flags
-                       WriteString(MSG_ENTITY, autocvar_nextmap);
+                       WriteString(MSG_ENTITY, get_nextmap());
                }
                else if ( autocvar_sv_vote_gametype )
                {
@@ -496,9 +496,9 @@ bool MapVote_Finished(int mappos)
                if ( GameTypeVote_Finished(mappos) )
                {
                        gametypevote = false;
-                       if(autocvar_nextmap != "")
+                       if(get_nextmap() != "")
                        {
-                               Map_Goto_SetStr(autocvar_nextmap);
+                               Map_Goto_SetStr(get_nextmap());
                                Map_Goto(0);
                                alreadychangedlevel = true;
                                strfree(voted_gametype_string);
@@ -756,7 +756,7 @@ void MapVote_Think()
                }
 
                if(autocvar_sv_vote_gametype) { GameTypeVote_Start(); }
-               else if(autocvar_nextmap == "") { MapVote_Init(); }
+               else if(get_nextmap() == "") { MapVote_Init(); }
        }
 
        MapVote_Tick();
index effc4d51d407b28b783cae9f0dcbb8e3cbc30a36..0aee165f15dea1f02aef8ba16b9c54ee173de023 100644 (file)
@@ -310,7 +310,6 @@ void cvar_changes_init()
                BADCVAR("g_tmayhem_teams");
                BADCVAR("g_vip");
                BADCVAR("leadlimit");
-               BADCVAR("nextmap");
                BADCVAR("teamplay");
                BADCVAR("timelimit");
                BADCVAR("g_mapinfo_q3compat");
@@ -920,8 +919,6 @@ spawnfunc(worldspawn)
        if(autocvar_sv_eventlog)
                GameLogInit(); // requires matchid to be set
 
-       cvar_set("nextmap", "");
-
        SetDefaultAlpha();
 
        if(autocvar_g_campaign)
index 4f36583a7ea617ebf8a84e23c4a9eab844c7ab41..4a0b31314d124da16c2bd33904749176c9fa494d 100644 (file)
@@ -532,6 +532,8 @@ con_textsize 10
 
 seta sbar_info_pos 0 "Y-axis distance from lower right corner for engine info prints"
 
+set _nextmap "" "internal cvar, automatically synced with server's nextmap"
+
 // scoreboard
 seta scoreboard_columns default
 
index 91a54e09a94cafb0586290a221df72b046a55054..67f9be443c87211ac1b3b13e850ed5ee47e9332a 100644 (file)
@@ -337,7 +337,6 @@ set sv_eventlog_files_nameprefix xonotic "prefix of individual log file names"
 set sv_eventlog_files_namesuffix .log "suffix of individual log file names"
 set sv_eventlog_ipv6_delimiter 0 "use a _ delimiter for IPV6 IPs, so that they can be easily detected in scripts"
 
-set nextmap "" "override the maplist when switching to the next map"
 set lastlevel "" "for singleplayer use, shows the menu once the match has ended"
 set quit_when_empty 0 "set to 1, then the server exits when the next level would start but is empty"
 set quit_and_redirect "" "set to an IP to redirect all players at the end of the match to another server. Set to \"self\" to let all players reconnect at the end of the match (use it to make seamless engine updates)"