]> git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Merge branch 'terencehill/custom_gametype_stuff' into 'master'
authorterencehill <piuntn@gmail.com>
Mon, 1 Apr 2024 10:21:10 +0000 (10:21 +0000)
committerterencehill <piuntn@gmail.com>
Mon, 1 Apr 2024 10:21:10 +0000 (10:21 +0000)
Fix / improve custom gametype handling

See merge request xonotic/xonotic-data.pk3dir!1269

qcsrc/client/hud/panel/scoreboard.qc
qcsrc/client/main.qc
qcsrc/client/main.qh
qcsrc/common/util.qh
qcsrc/server/command/sv_cmd.qc
qcsrc/server/mapvoting.qc
qcsrc/server/mapvoting.qh
qcsrc/server/scores.qc
qcsrc/server/world.qc
qcsrc/server/world.qh

index 35227ffab524c63bb077dfb624b4005f19ed4032..de5a0d80956e638bd3913546414c03471efe8bc9 100644 (file)
@@ -2326,6 +2326,8 @@ void Scoreboard_Draw()
        // Game Info: Game Type
        if (scoreboard_ui_enabled == 2)
                str = _("Team Selection");
+       else if (gametype_custom_name != "")
+               str = gametype_custom_name;
        else
                str = MapInfo_Type_ToText(gametype);
        draw_beginBoldFont();
index 90917341a29a67bbc69e9f0cc74a05328015cd0c..4bc3d8007f334b51f65b58f5364584ef82cb7435 100644 (file)
@@ -198,6 +198,8 @@ void Shutdown()
 
        localcmd("\n-button12\n");
 
+       strfree(gametype_custom_name);
+
        deactivate_minigame();
        HUD_MinigameMenu_Close(NULL, NULL, NULL);
 
@@ -1089,6 +1091,7 @@ NET_HANDLE(ENT_CLIENT_SCORES_INFO, bool isnew)
 {
        make_pure(this);
        gametype = ReadRegistered(Gametypes);
+       strcpy(gametype_custom_name, ReadString());
        teamplay = _MapInfo_GetTeamPlayBool(gametype);
        HUD_ModIcons_SetFunc();
        FOREACH(Scores, true, {
index 7929a450e078d0a9bc339b3f583858e7aae3ab6d..34c8fc63be8bc5f08459b62e043275e0eccf6cc5 100644 (file)
@@ -30,6 +30,7 @@ string minimapname;
 
 bool postinit;
 entity gametype;
+string gametype_custom_name;
 // temporary hack
 #define ISGAMETYPE(NAME) (gametype == MAPINFO_TYPE_##NAME)
 
index 01933cb348323b7090b7b889c85ae2271d55e094..1a1ebdba7fb9593faebb5a13301fe0fc0c59c4e9 100644 (file)
@@ -143,6 +143,7 @@ string getWrappedLine_remaining;
 string getWrappedLine(float w, vector size, textLengthUpToWidth_widthFunction_t tw);
 string getWrappedLineLen(float w, textLengthUpToLength_lenFunction_t tw);
 
+// FIXME can't use Gametype gt because Gitlab compilation unit test fails
 float isGametypeInFilter(entity gt, float tp, float ts, string pattern);
 
 vector solve_shotdirection(vector myorg, vector myvel, vector eorg, vector evel, float spd, float newton_style);
index ab360bc35efbdd322667ce15fd65c3bd7641539e..bb6074517ebe517aa4d926fd84a237ffcb47430b 100644 (file)
@@ -778,7 +778,11 @@ void GameCommand_gametype(int request, int argc)
                                Gametype t = MapInfo_Type_FromString(s, false, false);
 
                                if (t)
-                                       GameTypeVote_SetGametype(t);
+                               {
+                                       // don't execute gametype hooks because they can change active
+                                       // gametype rules if executed during the game
+                                       GameTypeVote_SetGametype(t, "", false);
+                               }
                                else
                                        bprint("Failed to switch to ", s, ": this game type does not exist!\n");
 
index 995fd60029afdaf7a524a9ad0f28b74825aee91c..b9d19f611dfdd61f6beae00b05181161cd7872d6 100644 (file)
@@ -215,21 +215,6 @@ void MapVote_AddVotableMaps(int nmax, int smax)
                MapVote_AddVotable(GetNextMap(), false);
 }
 
-bool GameTypeVote_SetGametype(Gametype type);
-
-// gametype_name can be the name of a custom gametype based on Gametype type
-void GameTypeVote_ApplyGameType(Gametype type, string gametype_name)
-{
-       if (gametype_name == "")
-               gametype_name = MapInfo_Type_ToString(type);
-
-       localcmd("sv_vote_gametype_hook_all\n");
-       localcmd("sv_vote_gametype_hook_", gametype_name, "\n");
-
-       if (!GameTypeVote_SetGametype(type))
-               LOG_TRACE("Selected gametype is not supported by any map");
-}
-
 string voted_gametype_string;
 Gametype voted_gametype;
 Gametype match_gametype;
@@ -277,8 +262,11 @@ void MapVote_Init()
        // In this case apply back match_gametype here so that the "restart" command, if called,
        // properly restarts the map applying the current game type.
        // Applying voted_gametype before map vote start is needed to properly initialize map vote.
+       string gametype_custom_string = "";
+       if (gametype_custom_enabled)
+               gametype_custom_string = loaded_gametype_custom_string;
        if (match_gametype)
-               GameTypeVote_ApplyGameType(match_gametype, gametype_custom_string);
+               GameTypeVote_SetGametype(match_gametype, gametype_custom_string, true);
 }
 
 void MapVote_SendPicture(entity to, int id)
@@ -399,7 +387,12 @@ bool MapVote_SendEntity(entity this, entity to, int sf)
                {
                        // map vote but gametype has been chosen via voting screen
                        WriteByte(MSG_ENTITY, BIT(1)); // gametypevote_flags
-                       WriteString(MSG_ENTITY, MapInfo_Type_ToText(voted_gametype));
+                       string voted_gametype_name;
+                       if (voted_gametype_string == MapInfo_Type_ToString(voted_gametype))
+                               voted_gametype_name = MapInfo_Type_ToText(voted_gametype);
+                       else
+                               voted_gametype_name = cvar_string(strcat("sv_vote_gametype_", voted_gametype_string, "_name"));
+                       WriteString(MSG_ENTITY, voted_gametype_name);
                }
                else
                        WriteByte(MSG_ENTITY, 0); // map vote
@@ -559,11 +552,16 @@ bool MapVote_CheckRules_2()
        RandomSelection_Init();
        currentPlace = 0;
        currentVotes = -1;
+       string current_gametype_string;
+       if (gametype_custom_enabled)
+               current_gametype_string = loaded_gametype_custom_string;
+       else
+               current_gametype_string = MapInfo_Type_ToString(MapInfo_CurrentGametype());
        for(i = 0; i < mapvote_count_real; ++i)
                if ( mapvote_maps_flags[i] & GTV_AVAILABLE )
                {
                        RandomSelection_AddFloat(i, 1, mapvote_selections[i]);
-                       if ( gametypevote && mapvote_maps[i] == MapInfo_Type_ToString(MapInfo_CurrentGametype()) )
+                       if ( gametypevote && mapvote_maps[i] == current_gametype_string )
                        {
                                currentVotes = mapvote_selections[i];
                                currentPlace = i;
@@ -699,10 +697,10 @@ void MapVote_Think()
                {
                        if (voted_gametype)
                        {
-                               // clear match_gametype so that GameTypeVote_ApplyGameType
+                               // clear match_gametype so that GameTypeVote_SetGametype
                                // prints the game type switch message
                                match_gametype = NULL;
-                               GameTypeVote_ApplyGameType(voted_gametype, voted_gametype_string);
+                               GameTypeVote_SetGametype(voted_gametype, voted_gametype_string, true);
                        }
 
                        Map_Goto_SetStr(mapvote_maps[mapvote_winner]);
@@ -761,8 +759,25 @@ void MapVote_Think()
        MapVote_Tick();
 }
 
-bool GameTypeVote_SetGametype(Gametype type)
+// if gametype_string is "" then gametype_string is inferred from Gametype type
+// otherwise gametype_string is the string (short name) of a custom gametype
+bool GameTypeVote_SetGametype(Gametype type, string gametype_string, bool call_hooks)
 {
+       if (!call_hooks)
+       {
+               // custom gametype is disabled because gametype hooks can't be executed
+               gametype_custom_enabled = false;
+       }
+       else
+       {
+               if (gametype_string == "")
+                       gametype_string = MapInfo_Type_ToString(type);
+               gametype_custom_enabled = (gametype_string != MapInfo_Type_ToString(type));
+
+               localcmd("sv_vote_gametype_hook_all\n");
+               localcmd("sv_vote_gametype_hook_", gametype_string, "\n");
+       }
+
        if (MapInfo_CurrentGametype() == type)
                return true;
 
@@ -804,7 +819,7 @@ bool GameTypeVote_Finished(int pos)
        voted_gametype = GameTypeVote_Type_FromString(mapvote_maps[pos]);
        strcpy(voted_gametype_string, mapvote_maps[pos]);
 
-       GameTypeVote_ApplyGameType(voted_gametype, voted_gametype_string);
+       GameTypeVote_SetGametype(voted_gametype, voted_gametype_string, true);
 
        // save to a cvar so it can be applied back when gametype is temporary
        // changed on gametype vote end of the next game
@@ -872,7 +887,12 @@ bool GameTypeVote_Start()
        {
                if ( mapvote_count > 0 )
                        strunzone(mapvote_maps[0]);
-               mapvote_maps[0] = strzone(MapInfo_Type_ToString(MapInfo_CurrentGametype()));
+               string current_gametype_string;
+               if (gametype_custom_enabled)
+                       current_gametype_string = loaded_gametype_custom_string;
+               else
+                       current_gametype_string = MapInfo_Type_ToString(MapInfo_CurrentGametype());
+               mapvote_maps[0] = strzone(current_gametype_string);
                //GameTypeVote_Finished(0);
                MapVote_Finished(0);
                return false;
index 36578740c07fff735e11041ce9811d1284727484..f2515bdad099cb497ff7010b6cd84ba18310e75b 100644 (file)
@@ -30,7 +30,8 @@ void MapVote_Start();
 void MapVote_Spawn();
 void MapVote_Think();
 void MapVote_SendPicture(entity to, int id);
-bool GameTypeVote_SetGametype(entity type);
+// FIXME can't use Gametype type because Gitlab compilation unit test fails
+bool GameTypeVote_SetGametype(entity type, string gametype_string, bool call_hooks);
 float GameTypeVote_Start();
 float GameTypeVote_Finished(int pos);
 string GameTypeVote_MapInfo_FixName(string m);
index c067fac8a1287704818121767438d4072e30b776..40bbec64424689f94e11551dbbc6e3c4b284c969 100644 (file)
@@ -208,6 +208,10 @@ bool ScoreInfo_SendEntity(entity this, entity to, int sf)
        float i;
        WriteHeader(MSG_ENTITY, ENT_CLIENT_SCORES_INFO);
        WriteRegistered(Gametypes, MSG_ENTITY, MapInfo_LoadedGametype);
+       string gt_name = "";
+       if (loaded_gametype_custom_string != "")
+               gt_name = cvar_string(strcat("sv_vote_gametype_", loaded_gametype_custom_string, "_name"));
+       WriteString(MSG_ENTITY, gt_name);
        FOREACH(Scores, true, {
                WriteString(MSG_ENTITY, scores_label(it));
                WriteByte(MSG_ENTITY, scores_flags(it));
index ad40a389543bcb5698d2abc2a0ddd1068e1f0557..b6fbe0d85f3796c649a639dabcf31b2a9cb11c53 100644 (file)
@@ -736,7 +736,8 @@ void InitGameplayMode()
 
        MapInfo_ClearTemps();
 
-       strcpy(gametype_custom_string, autocvar__sv_vote_gametype_custom);
+       strcpy(loaded_gametype_custom_string, autocvar__sv_vote_gametype_custom);
+       gametype_custom_enabled = (loaded_gametype_custom_string != "");
        cvar_set("_sv_vote_gametype_custom", ""); // clear it immediately so it can't get stuck
 
        cache_mutatormsg = strzone("");
@@ -2645,7 +2646,7 @@ void Shutdown()
                MapInfo_Shutdown();
 
                strfree(sv_termsofservice_url_escaped);
-               strfree(gametype_custom_string);
+               strfree(loaded_gametype_custom_string);
        }
        else if(world_initialized == 0)
        {
index a7301dc799b1fa96bc5a3102d95bc71faa3bd167..6348c72f6072a5862fdcb0ede96c7b981f7d48f3 100644 (file)
@@ -49,7 +49,8 @@ float cvar_purechanges_count;
 string modname;
 
 string autocvar__sv_vote_gametype_custom;
-string gametype_custom_string;
+bool gametype_custom_enabled;
+string loaded_gametype_custom_string;
 
 string record_type;