Add Generate Map tab to the lobby map chooser.

This commit is contained in:
Paul Chote
2025-05-11 20:44:39 +01:00
committed by Gustas Kažukauskas
parent 979483b63c
commit 6ffd786d5b
11 changed files with 875 additions and 8 deletions

View File

@@ -12,6 +12,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using OpenRA.Mods.Common.Traits;
using OpenRA.Primitives;
using OpenRA.Widgets;
@@ -91,6 +92,9 @@ namespace OpenRA.Mods.Common.Widgets.Logic
[FluentReference]
const string RemoteMapsTab = "button-mapchooser-remote-maps-tab";
[FluentReference]
const string GeneratedMapsTab = "button-mapchooser-generated-maps-tab";
public static string MapSizeLabel(Size size)
{
var area = size.Width * size.Height;
@@ -124,6 +128,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
string selectedUid;
readonly Action<string> onSelect;
MapGenerationArgs generatedMap;
string category;
string mapFilter;
@@ -131,8 +136,8 @@ namespace OpenRA.Mods.Common.Widgets.Logic
Func<MapPreview, long> orderByFunc;
[ObjectCreator.UseCtor]
internal MapChooserLogic(Widget widget, ModData modData, string initialMap, HashSet<string> remoteMapPool,
MapClassification initialTab, Action onExit, Action<string> onSelect, MapVisibility filter)
internal MapChooserLogic(Widget widget, ModData modData, string initialMap, MapGenerationArgs initialGeneratedMap, HashSet<string> remoteMapPool,
MapClassification initialTab, Action onExit, Action<string> onSelect, Action<MapGenerationArgs> onSelectGenerated, MapVisibility filter)
{
this.widget = widget;
this.modData = modData;
@@ -145,13 +150,20 @@ namespace OpenRA.Mods.Common.Widgets.Logic
var approving = new Action(() =>
{
Ui.CloseWindow();
onSelect?.Invoke(selectedUid);
if (currentTab == MapClassification.Generated && generatedMap != null)
onSelectGenerated?.Invoke(generatedMap);
else
onSelect?.Invoke(selectedUid);
});
var canceling = new Action(() => { Ui.CloseWindow(); onExit(); });
var okButton = widget.Get<ButtonWidget>("BUTTON_OK");
okButton.Disabled = this.onSelect == null;
if (onSelect != null)
okButton.IsDisabled = () => currentTab == MapClassification.Generated && generatedMap == null;
else
okButton.Disabled = true;
okButton.OnClick = approving;
widget.Get<ButtonWidget>("BUTTON_CANCEL").OnClick = canceling;
@@ -162,6 +174,10 @@ namespace OpenRA.Mods.Common.Widgets.Logic
SetupOrderByDropdown();
var filterContainer = widget.GetOrNull("FILTER_ORDER_CONTROLS");
if (filterContainer != null)
filterContainer.IsVisible = () => currentTab != MapClassification.Generated;
var mapFilterInput = widget.GetOrNull<TextFieldWidget>("MAPFILTER_INPUT");
if (mapFilterInput != null)
{
@@ -196,6 +212,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
scrollpanels[currentTab].ScrollToItem(uid, smooth: true);
};
randomMapButton.IsDisabled = () => visibleMaps == null || visibleMaps.Length == 0;
randomMapButton.IsVisible = () => currentTab != MapClassification.Generated;
}
var deleteMapButton = widget.Get<ButtonWidget>("DELETE_MAP_BUTTON");
@@ -249,6 +266,10 @@ namespace OpenRA.Mods.Common.Widgets.Logic
SetupMapPanel(MapClassification.System, "SYSTEM_MAPS_TAB");
SetupMapPanel(MapClassification.Remote, "REMOTE_MAPS_TAB");
var hasGenerator = modData.DefaultRules.Actors[SystemActors.EditorWorld].HasTraitInfo<IEditorMapGeneratorInfo>();
if (onSelectGenerated != null && hasGenerator)
SetupGenerateMapPanel(MapClassification.Generated, "GENERATE_MAP_TAB", initialGeneratedMap);
// System and user map tabs are hidden when the server forces a restricted pool
if (remoteMapPool != null)
{
@@ -260,8 +281,15 @@ namespace OpenRA.Mods.Common.Widgets.Logic
{
tabLabels[MapClassification.System] = SystemMapsTab;
tabLabels[MapClassification.User] = UserMapsTab;
if (onSelectGenerated != null && hasGenerator)
tabLabels[MapClassification.Generated] = GeneratedMapsTab;
if (initialMap == null && tabMaps.TryGetValue(initialTab, out var map) && map.Length > 0)
if (initialMap != null && modData.MapCache[initialMap].Class == MapClassification.Generated && onSelectGenerated != null && hasGenerator)
{
currentTab = MapClassification.Generated;
selectedUid = modData.MapCache.ChooseInitialMap(null, Game.CosmeticRandom);
}
else if (initialMap == null && tabMaps.TryGetValue(initialTab, out var map) && map.Length > 0)
{
var uid = map.Select(mp => mp.Uid).First();
selectedUid = Game.ModData.MapCache.ChooseInitialMap(uid, Game.CosmeticRandom);
@@ -286,7 +314,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
void RefreshMaps(MapClassification tab)
{
if (tab != MapClassification.Remote)
if (tab == MapClassification.System || tab == MapClassification.User)
tabMaps[tab] = modData.MapCache.Where(m => m.Status == MapStatus.Available &&
m.Class == tab && (m.Visibility & filter) != 0).ToArray();
else if (remoteMapPool != null)
@@ -358,6 +386,18 @@ namespace OpenRA.Mods.Common.Widgets.Logic
RefreshMaps(tab);
}
void SetupGenerateMapPanel(MapClassification tab, string tabContainerName, MapGenerationArgs initialSettings)
{
var tabContainer = widget.Get<ContainerWidget>(tabContainerName);
tabContainer.IsVisible = () => currentTab == tab;
Ui.LoadWidget("MAPCHOOSER_GENERATE_PANEL", tabContainer, new WidgetArgs
{
{ "modData", modData },
{ "initialSettings", initialSettings },
{ "onGenerate", (Action<MapGenerationArgs>)(data => generatedMap = data) }
});
}
void SetupGameModeDropdown(MapClassification tab, DropDownButtonWidget gameModeDropdown)
{
if (gameModeDropdown != null)
@@ -443,6 +483,9 @@ namespace OpenRA.Mods.Common.Widgets.Logic
void EnumerateMaps(MapClassification tab)
{
if (tab == MapClassification.Generated)
return;
if (!int.TryParse(mapFilter, out var playerCountFilter))
playerCountFilter = -1;
@@ -532,7 +575,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
{
modData.MapCache[map].Delete();
if (selectedUid == map)
selectedUid = Game.ModData.MapCache.ChooseInitialMap(tabMaps[currentTab].Select(mp => mp.Uid).FirstOrDefault(),
selectedUid = modData.MapCache.ChooseInitialMap(tabMaps[currentTab].Select(mp => mp.Uid).FirstOrDefault(),
Game.CosmeticRandom);
}
catch (Exception ex)
@@ -569,7 +612,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
foreach (var map in maps)
DeleteMap(map);
after?.Invoke(Game.ModData.MapCache.ChooseInitialMap(null, Game.CosmeticRandom));
after?.Invoke(modData.MapCache.ChooseInitialMap(null, Game.CosmeticRandom));
},
confirmText: DeleteAllMapsAccept,
onCancel: () => { });