From: terencehill Date: Mon, 1 Apr 2024 10:21:10 +0000 (+0000) Subject: Merge branch 'terencehill/custom_gametype_stuff' into 'master' X-Git-Url: https://git.xonotic.org/?a=commitdiff_plain;h=f73f6db19157cdd7f67ebbadfe616eb5bab1bc6e;hp=e357f4f2cc566737d482e2b510fd0078c0f3c926;p=xonotic%2Fxonotic-data.pk3dir.git Merge branch 'terencehill/custom_gametype_stuff' into 'master' Fix / improve custom gametype handling See merge request xonotic/xonotic-data.pk3dir!1269 --- diff --git a/qcsrc/client/hud/panel/scoreboard.qc b/qcsrc/client/hud/panel/scoreboard.qc index 35227ffab..de5a0d809 100644 --- a/qcsrc/client/hud/panel/scoreboard.qc +++ b/qcsrc/client/hud/panel/scoreboard.qc @@ -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(); diff --git a/qcsrc/client/main.qc b/qcsrc/client/main.qc index 90917341a..4bc3d8007 100644 --- a/qcsrc/client/main.qc +++ b/qcsrc/client/main.qc @@ -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, { diff --git a/qcsrc/client/main.qh b/qcsrc/client/main.qh index 7929a450e..34c8fc63b 100644 --- a/qcsrc/client/main.qh +++ b/qcsrc/client/main.qh @@ -30,6 +30,7 @@ string minimapname; bool postinit; entity gametype; +string gametype_custom_name; // temporary hack #define ISGAMETYPE(NAME) (gametype == MAPINFO_TYPE_##NAME) diff --git a/qcsrc/common/util.qh b/qcsrc/common/util.qh index 01933cb34..1a1ebdba7 100644 --- a/qcsrc/common/util.qh +++ b/qcsrc/common/util.qh @@ -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); diff --git a/qcsrc/server/command/sv_cmd.qc b/qcsrc/server/command/sv_cmd.qc index ab360bc35..bb6074517 100644 --- a/qcsrc/server/command/sv_cmd.qc +++ b/qcsrc/server/command/sv_cmd.qc @@ -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"); diff --git a/qcsrc/server/mapvoting.qc b/qcsrc/server/mapvoting.qc index 995fd6002..b9d19f611 100644 --- a/qcsrc/server/mapvoting.qc +++ b/qcsrc/server/mapvoting.qc @@ -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; diff --git a/qcsrc/server/mapvoting.qh b/qcsrc/server/mapvoting.qh index 36578740c..f2515bdad 100644 --- a/qcsrc/server/mapvoting.qh +++ b/qcsrc/server/mapvoting.qh @@ -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); diff --git a/qcsrc/server/scores.qc b/qcsrc/server/scores.qc index c067fac8a..40bbec644 100644 --- a/qcsrc/server/scores.qc +++ b/qcsrc/server/scores.qc @@ -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)); diff --git a/qcsrc/server/world.qc b/qcsrc/server/world.qc index ad40a3895..b6fbe0d85 100644 --- a/qcsrc/server/world.qc +++ b/qcsrc/server/world.qc @@ -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) { diff --git a/qcsrc/server/world.qh b/qcsrc/server/world.qh index a7301dc79..6348c72f6 100644 --- a/qcsrc/server/world.qh +++ b/qcsrc/server/world.qh @@ -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;