From 7a5678ec3929b55ca2d0f754d50574651e16087c Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Fri, 5 Feb 2016 08:23:16 +0000 Subject: [PATCH 1/9] Move MapVisibility to MapPreview. --- OpenRA.Game/Game.cs | 2 +- OpenRA.Game/Map/MapPreview.cs | 5 ++++- OpenRA.Game/Widgets/WidgetUtils.cs | 2 +- OpenRA.Mods.Common/Widgets/Logic/MainMenuLogic.cs | 2 +- OpenRA.Mods.Common/Widgets/Logic/MapChooserLogic.cs | 2 +- OpenRA.Mods.Common/Widgets/Logic/MissionBrowserLogic.cs | 2 +- 6 files changed, 9 insertions(+), 6 deletions(-) diff --git a/OpenRA.Game/Game.cs b/OpenRA.Game/Game.cs index f2bdf80ec7..61491cc9ef 100644 --- a/OpenRA.Game/Game.cs +++ b/OpenRA.Game/Game.cs @@ -445,7 +445,7 @@ namespace OpenRA static string ChooseShellmap() { var shellmaps = ModData.MapCache - .Where(m => m.Status == MapStatus.Available && m.Map.Visibility.HasFlag(MapVisibility.Shellmap)) + .Where(m => m.Status == MapStatus.Available && m.Visibility.HasFlag(MapVisibility.Shellmap)) .Select(m => m.Uid); if (!shellmaps.Any()) diff --git a/OpenRA.Game/Map/MapPreview.cs b/OpenRA.Game/Map/MapPreview.cs index f8c35c9b40..3f09a31418 100644 --- a/OpenRA.Game/Map/MapPreview.cs +++ b/OpenRA.Game/Map/MapPreview.cs @@ -68,6 +68,7 @@ namespace OpenRA public Map Map { get; private set; } public MapStatus Status { get; private set; } public MapClassification Class { get; private set; } + public MapVisibility Visibility { get; private set; } public bool SuitableForInitialMap { get; private set; } public MapRuleStatus RuleStatus { get; private set; } @@ -111,6 +112,7 @@ namespace OpenRA GridType = gridType; Status = MapStatus.Unavailable; Class = MapClassification.Unknown; + Visibility = MapVisibility.Lobby; } public void UpdateFromMap(Map m, MapClassification classification) @@ -126,6 +128,7 @@ namespace OpenRA CustomPreview = m.CustomPreview; Status = MapStatus.Available; Class = classification; + Visibility = m.Visibility; var players = new MapPlayers(m.PlayerDefinitions).Players; PlayerCount = players.Count(x => x.Value.Playable); @@ -135,7 +138,7 @@ namespace OpenRA bool EvaluateUserFriendliness(Dictionary players) { - if (Status != MapStatus.Available || !Map.Visibility.HasFlag(MapVisibility.Lobby)) + if (Status != MapStatus.Available || !Visibility.HasFlag(MapVisibility.Lobby)) return false; // Other map types may have confusing settings or gameplay diff --git a/OpenRA.Game/Widgets/WidgetUtils.cs b/OpenRA.Game/Widgets/WidgetUtils.cs index c0bc0e250c..a1fb0f0670 100644 --- a/OpenRA.Game/Widgets/WidgetUtils.cs +++ b/OpenRA.Game/Widgets/WidgetUtils.cs @@ -255,7 +255,7 @@ namespace OpenRA.Widgets if (string.IsNullOrEmpty(initialUid) || Game.ModData.MapCache[initialUid].Status != MapStatus.Available) { var selected = Game.ModData.MapCache.Where(x => x.SuitableForInitialMap).RandomOrDefault(Game.CosmeticRandom) ?? - Game.ModData.MapCache.First(m => m.Status == MapStatus.Available && m.Map.Visibility.HasFlag(MapVisibility.Lobby)); + Game.ModData.MapCache.First(m => m.Status == MapStatus.Available && m.Visibility.HasFlag(MapVisibility.Lobby)); return selected.Uid; } diff --git a/OpenRA.Mods.Common/Widgets/Logic/MainMenuLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/MainMenuLogic.cs index 7899d345a3..2d9d82bed4 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/MainMenuLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/MainMenuLogic.cs @@ -104,7 +104,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic var hasCampaign = Game.ModData.Manifest.Missions.Any(); var hasMissions = Game.ModData.MapCache - .Any(p => p.Status == MapStatus.Available && p.Map.Visibility.HasFlag(MapVisibility.MissionSelector)); + .Any(p => p.Status == MapStatus.Available && p.Visibility.HasFlag(MapVisibility.MissionSelector)); missionsButton.Disabled = !hasCampaign && !hasMissions; diff --git a/OpenRA.Mods.Common/Widgets/Logic/MapChooserLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/MapChooserLogic.cs index fa205533c8..1c35e3f63c 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/MapChooserLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/MapChooserLogic.cs @@ -143,7 +143,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic void RefreshMaps(MapClassification tab, MapVisibility filter) { tabMaps[tab] = Game.ModData.MapCache.Where(m => m.Status == MapStatus.Available && - m.Class == tab && (m.Map.Visibility & filter) != 0).ToArray(); + m.Class == tab && (m.Visibility & filter) != 0).ToArray(); } void SetupMapTab(MapClassification tab, MapVisibility filter, string tabButtonName, string tabContainerName, ScrollItemWidget itemTemplate) diff --git a/OpenRA.Mods.Common/Widgets/Logic/MissionBrowserLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/MissionBrowserLogic.cs index b87ce9c3d7..6038a25f3a 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/MissionBrowserLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/MissionBrowserLogic.cs @@ -114,7 +114,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic // Add an additional group for loose missions var looseMissions = modData.MapCache - .Where(p => p.Status == MapStatus.Available && p.Map.Visibility.HasFlag(MapVisibility.MissionSelector) && !allMaps.Contains(p.Map)) + .Where(p => p.Status == MapStatus.Available && p.Visibility.HasFlag(MapVisibility.MissionSelector) && !allMaps.Contains(p.Map)) .Select(p => p.Map); if (looseMissions.Any()) From 4ec3997be6700a0aeefea83fa41b0db0d4af32ba Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Fri, 5 Feb 2016 08:25:27 +0000 Subject: [PATCH 2/9] Rename LobbyPreview.Map to LobbyLogic.MapPreview. --- .../Widgets/Logic/Lobby/LobbyLogic.cs | 83 ++++++++--------- .../Logic/Lobby/LobbyMapPreviewLogic.cs | 92 ++++++++++--------- 2 files changed, 89 insertions(+), 86 deletions(-) diff --git a/OpenRA.Mods.Common/Widgets/Logic/Lobby/LobbyLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/Lobby/LobbyLogic.cs index 9f381f2e73..3dd98a0676 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/Lobby/LobbyLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/Lobby/LobbyLogic.cs @@ -26,7 +26,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic { static readonly Action DoNothing = () => { }; - public MapPreview Map = MapCache.UnknownMap; + public MapPreview MapPreview = MapCache.UnknownMap; readonly Action onStart; readonly Action onExit; @@ -168,7 +168,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic var onSelect = new Action(uid => { // Don't select the same map again - if (uid == Map.Uid) + if (uid == MapPreview.Uid) return; orderManager.IssueOrder(Order.Command("map " + uid)); @@ -178,7 +178,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic Ui.OpenWindow("MAPCHOOSER_PANEL", new WidgetArgs() { - { "initialMap", Map.Uid }, + { "initialMap", MapPreview.Uid }, { "initialTab", MapClassification.System }, { "onExit", DoNothing }, { "onSelect", Game.IsHost ? onSelect : null }, @@ -190,7 +190,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic var slotsButton = lobby.GetOrNull("SLOTS_DROPDOWNBUTTON"); if (slotsButton != null) { - slotsButton.IsDisabled = () => configurationDisabled() || panel != PanelType.Players || Map.RuleStatus != MapRuleStatus.Cached || + slotsButton.IsDisabled = () => configurationDisabled() || panel != PanelType.Players || MapPreview.RuleStatus != MapRuleStatus.Cached || (orderManager.LobbyInfo.Slots.Values.All(s => !s.AllowBots) && orderManager.LobbyInfo.Slots.Count(s => !s.Value.LockTeam && orderManager.LobbyInfo.ClientInSlot(s.Key) != null) == 0); @@ -294,7 +294,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic var optionsTab = lobby.Get("OPTIONS_TAB"); optionsTab.IsHighlighted = () => panel == PanelType.Options; - optionsTab.IsDisabled = () => Map.RuleStatus != MapRuleStatus.Cached || panel == PanelType.Kick || panel == PanelType.ForceStart; + optionsTab.IsDisabled = () => MapPreview.RuleStatus != MapRuleStatus.Cached || panel == PanelType.Kick || panel == PanelType.ForceStart; optionsTab.OnClick = () => panel = PanelType.Options; var playersTab = lobby.Get("PLAYERS_TAB"); @@ -317,9 +317,10 @@ namespace OpenRA.Mods.Common.Widgets.Logic var startGameButton = lobby.GetOrNull("START_GAME_BUTTON"); if (startGameButton != null) { - startGameButton.IsDisabled = () => configurationDisabled() || Map.RuleStatus != MapRuleStatus.Cached || + startGameButton.IsDisabled = () => configurationDisabled() || MapPreview.RuleStatus != MapRuleStatus.Cached || orderManager.LobbyInfo.Slots.Any(sl => sl.Value.Required && orderManager.LobbyInfo.ClientInSlot(sl.Key) == null) || (orderManager.LobbyInfo.GlobalSettings.DisableSingleplayer && orderManager.LobbyInfo.IsSinglePlayer); + startGameButton.OnClick = () => { // Bots and admins don't count @@ -341,7 +342,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic if (allowCheats != null) { allowCheats.IsChecked = () => orderManager.LobbyInfo.GlobalSettings.AllowCheats; - allowCheats.IsDisabled = () => Map.Status != MapStatus.Available || Map.Map.Options.Cheats.HasValue || configurationDisabled(); + allowCheats.IsDisabled = () => MapPreview.Status != MapStatus.Available || MapPreview.Map.Options.Cheats.HasValue || configurationDisabled(); allowCheats.OnClick = () => orderManager.IssueOrder(Order.Command( "allowcheats {0}".F(!orderManager.LobbyInfo.GlobalSettings.AllowCheats))); } @@ -350,7 +351,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic if (crates != null) { crates.IsChecked = () => orderManager.LobbyInfo.GlobalSettings.Crates; - crates.IsDisabled = () => Map.Status != MapStatus.Available || Map.Map.Options.Crates.HasValue || configurationDisabled(); + crates.IsDisabled = () => MapPreview.Status != MapStatus.Available || MapPreview.Map.Options.Crates.HasValue || configurationDisabled(); crates.OnClick = () => orderManager.IssueOrder(Order.Command( "crates {0}".F(!orderManager.LobbyInfo.GlobalSettings.Crates))); } @@ -359,7 +360,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic if (creeps != null) { creeps.IsChecked = () => orderManager.LobbyInfo.GlobalSettings.Creeps; - creeps.IsDisabled = () => Map.Status != MapStatus.Available || Map.Map.Options.Creeps.HasValue || configurationDisabled(); + creeps.IsDisabled = () => MapPreview.Status != MapStatus.Available || MapPreview.Map.Options.Creeps.HasValue || configurationDisabled(); creeps.OnClick = () => orderManager.IssueOrder(Order.Command( "creeps {0}".F(!orderManager.LobbyInfo.GlobalSettings.Creeps))); } @@ -368,7 +369,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic if (allybuildradius != null) { allybuildradius.IsChecked = () => orderManager.LobbyInfo.GlobalSettings.AllyBuildRadius; - allybuildradius.IsDisabled = () => Map.Status != MapStatus.Available || Map.Map.Options.AllyBuildRadius.HasValue || configurationDisabled(); + allybuildradius.IsDisabled = () => MapPreview.Status != MapStatus.Available || MapPreview.Map.Options.AllyBuildRadius.HasValue || configurationDisabled(); allybuildradius.OnClick = () => orderManager.IssueOrder(Order.Command( "allybuildradius {0}".F(!orderManager.LobbyInfo.GlobalSettings.AllyBuildRadius))); } @@ -377,7 +378,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic if (shortGame != null) { shortGame.IsChecked = () => orderManager.LobbyInfo.GlobalSettings.ShortGame; - shortGame.IsDisabled = () => Map.Status != MapStatus.Available || Map.Map.Options.ShortGame.HasValue || configurationDisabled(); + shortGame.IsDisabled = () => MapPreview.Status != MapStatus.Available || MapPreview.Map.Options.ShortGame.HasValue || configurationDisabled(); shortGame.OnClick = () => orderManager.IssueOrder(Order.Command( "shortgame {0}".F(!orderManager.LobbyInfo.GlobalSettings.ShortGame))); } @@ -385,12 +386,12 @@ namespace OpenRA.Mods.Common.Widgets.Logic var difficulty = optionsBin.GetOrNull("DIFFICULTY_DROPDOWNBUTTON"); if (difficulty != null) { - difficulty.IsVisible = () => Map.Status == MapStatus.Available && Map.Map.Options.Difficulties.Any(); - difficulty.IsDisabled = () => Map.Status != MapStatus.Available || configurationDisabled(); + difficulty.IsVisible = () => MapPreview.Status == MapStatus.Available && MapPreview.Map.Options.Difficulties.Any(); + difficulty.IsDisabled = () => MapPreview.Status != MapStatus.Available || configurationDisabled(); difficulty.GetText = () => orderManager.LobbyInfo.GlobalSettings.Difficulty; difficulty.OnMouseDown = _ => { - var options = Map.Map.Options.Difficulties.Select(d => new DropDownOption + var options = MapPreview.Map.Options.Difficulties.Select(d => new DropDownOption { Title = d, IsSelected = () => orderManager.LobbyInfo.GlobalSettings.Difficulty == d, @@ -419,10 +420,10 @@ namespace OpenRA.Mods.Common.Widgets.Logic return selectedClass != null ? selectedClass : c; }; - startingUnits.IsDisabled = () => Map.Status != MapStatus.Available || - !Map.Map.Options.ConfigurableStartingUnits || configurationDisabled(); - startingUnits.GetText = () => Map.Status != MapStatus.Available || - !Map.Map.Options.ConfigurableStartingUnits ? "Not Available" : className(orderManager.LobbyInfo.GlobalSettings.StartingUnitsClass); + startingUnits.IsDisabled = () => MapPreview.Status != MapStatus.Available || + !MapPreview.Map.Options.ConfigurableStartingUnits || configurationDisabled(); + startingUnits.GetText = () => MapPreview.Status != MapStatus.Available || + !MapPreview.Map.Options.ConfigurableStartingUnits ? "Not Available" : className(orderManager.LobbyInfo.GlobalSettings.StartingUnitsClass); startingUnits.OnMouseDown = _ => { var options = classes.Select(c => new DropDownOption @@ -448,10 +449,10 @@ namespace OpenRA.Mods.Common.Widgets.Logic var startingCash = optionsBin.GetOrNull("STARTINGCASH_DROPDOWNBUTTON"); if (startingCash != null) { - startingCash.IsDisabled = () => Map.Status != MapStatus.Available || - Map.Map.Options.StartingCash.HasValue || configurationDisabled(); - startingCash.GetText = () => Map.Status != MapStatus.Available || - Map.Map.Options.StartingCash.HasValue ? "Not Available" : "${0}".F(orderManager.LobbyInfo.GlobalSettings.StartingCash); + startingCash.IsDisabled = () => MapPreview.Status != MapStatus.Available || + MapPreview.Map.Options.StartingCash.HasValue || configurationDisabled(); + startingCash.GetText = () => MapPreview.Status != MapStatus.Available || + MapPreview.Map.Options.StartingCash.HasValue ? "Not Available" : "${0}".F(orderManager.LobbyInfo.GlobalSettings.StartingCash); startingCash.OnMouseDown = _ => { var options = modRules.Actors["player"].TraitInfo().SelectableCash.Select(c => new DropDownOption @@ -482,10 +483,10 @@ namespace OpenRA.Mods.Common.Widgets.Logic if (techLevelDescription != null) techLevelDescription.IsVisible = () => techTraits.Count > 0; - techLevel.IsDisabled = () => Map.Status != MapStatus.Available || - Map.Map.Options.TechLevel != null || configurationDisabled() || techTraits.Count <= 1; - techLevel.GetText = () => Map.Status != MapStatus.Available || - Map.Map.Options.TechLevel != null ? "Not Available" : "{0}".F(orderManager.LobbyInfo.GlobalSettings.TechLevel); + techLevel.IsDisabled = () => MapPreview.Status != MapStatus.Available || + MapPreview.Map.Options.TechLevel != null || configurationDisabled() || techTraits.Count <= 1; + techLevel.GetText = () => MapPreview.Status != MapStatus.Available || + MapPreview.Map.Options.TechLevel != null ? "Not Available" : "{0}".F(orderManager.LobbyInfo.GlobalSettings.TechLevel); techLevel.OnMouseDown = _ => { var options = techTraits.Select(c => new DropDownOption @@ -511,10 +512,10 @@ namespace OpenRA.Mods.Common.Widgets.Logic { var speeds = Game.ModData.Manifest.Get().Speeds; - gameSpeed.IsDisabled = () => Map.Status != MapStatus.Available || configurationDisabled(); + gameSpeed.IsDisabled = () => MapPreview.Status != MapStatus.Available || configurationDisabled(); gameSpeed.GetText = () => { - if (Map.Status != MapStatus.Available) + if (MapPreview.Status != MapStatus.Available) return "Not Available"; GameSpeed speed; @@ -548,7 +549,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic if (exploredMap != null) { exploredMap.IsChecked = () => !orderManager.LobbyInfo.GlobalSettings.Shroud; - exploredMap.IsDisabled = () => Map.Status != MapStatus.Available || Map.Map.Options.Shroud.HasValue || configurationDisabled(); + exploredMap.IsDisabled = () => MapPreview.Status != MapStatus.Available || MapPreview.Map.Options.Shroud.HasValue || configurationDisabled(); exploredMap.OnClick = () => orderManager.IssueOrder(Order.Command( "shroud {0}".F(!orderManager.LobbyInfo.GlobalSettings.Shroud))); } @@ -557,7 +558,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic if (enableFog != null) { enableFog.IsChecked = () => orderManager.LobbyInfo.GlobalSettings.Fog; - enableFog.IsDisabled = () => Map.Status != MapStatus.Available || Map.Map.Options.Fog.HasValue || configurationDisabled(); + enableFog.IsDisabled = () => MapPreview.Status != MapStatus.Available || MapPreview.Map.Options.Fog.HasValue || configurationDisabled(); enableFog.OnClick = () => orderManager.IssueOrder(Order.Command( "fog {0}".F(!orderManager.LobbyInfo.GlobalSettings.Fog))); } @@ -733,31 +734,31 @@ namespace OpenRA.Mods.Common.Widgets.Logic void UpdateCurrentMap() { var uid = orderManager.LobbyInfo.GlobalSettings.Map; - if (Map.Uid == uid) + if (MapPreview.Uid == uid) return; - Map = Game.ModData.MapCache[uid]; - if (Map.Status == MapStatus.Available) + MapPreview = Game.ModData.MapCache[uid]; + if (MapPreview.Status == MapStatus.Available) { // Maps need to be validated and pre-loaded before they can be accessed new Thread(_ => { - var map = Map; - map.CacheRules(); + var mapPreview = MapPreview; + mapPreview.CacheRules(); Game.RunAfterTick(() => { // Map may have changed in the meantime - if (map != Map) + if (mapPreview != MapPreview) return; - if (map.RuleStatus != MapRuleStatus.Invalid) + if (mapPreview.RuleStatus != MapRuleStatus.Invalid) { // Tell the server that we have the map orderManager.IssueOrder(Order.Command("state {0}".F(Session.ClientState.NotReady))); // Restore default starting cash if the last map set it to something invalid var pri = modRules.Actors["player"].TraitInfo(); - if (!Map.Map.Options.StartingCash.HasValue && !pri.SelectableCash.Contains(orderManager.LobbyInfo.GlobalSettings.StartingCash)) + if (!MapPreview.Map.Options.StartingCash.HasValue && !pri.SelectableCash.Contains(orderManager.LobbyInfo.GlobalSettings.StartingCash)) orderManager.IssueOrder(Order.Command("startingcash {0}".F(pri.DefaultCash))); } }); @@ -816,9 +817,9 @@ namespace OpenRA.Mods.Common.Widgets.Logic LobbyUtils.SetupEditableColorWidget(template, slot, client, orderManager, shellmapWorld, colorPreview); LobbyUtils.SetupEditableFactionWidget(template, slot, client, orderManager, factions); - LobbyUtils.SetupEditableTeamWidget(template, slot, client, orderManager, Map); - LobbyUtils.SetupEditableSpawnWidget(template, slot, client, orderManager, Map); - LobbyUtils.SetupEditableReadyWidget(template, slot, client, orderManager, Map); + LobbyUtils.SetupEditableTeamWidget(template, slot, client, orderManager, MapPreview); + LobbyUtils.SetupEditableSpawnWidget(template, slot, client, orderManager, MapPreview); + LobbyUtils.SetupEditableReadyWidget(template, slot, client, orderManager, MapPreview); } else { diff --git a/OpenRA.Mods.Common/Widgets/Logic/Lobby/LobbyMapPreviewLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/Lobby/LobbyMapPreviewLogic.cs index 5c0952ef05..36a6b934bc 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/Lobby/LobbyMapPreviewLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/Lobby/LobbyMapPreviewLogic.cs @@ -25,79 +25,80 @@ namespace OpenRA.Mods.Common.Widgets.Logic var available = widget.GetOrNull("MAP_AVAILABLE"); if (available != null) { - available.IsVisible = () => lobby.Map.Status == MapStatus.Available && lobby.Map.RuleStatus == MapRuleStatus.Cached; + available.IsVisible = () => lobby.MapPreview.Status == MapStatus.Available && lobby.MapPreview.RuleStatus == MapRuleStatus.Cached; var preview = available.Get("MAP_PREVIEW"); - preview.Preview = () => lobby.Map; - preview.OnMouseDown = mi => LobbyUtils.SelectSpawnPoint(orderManager, preview, lobby.Map, mi); - preview.SpawnOccupants = () => LobbyUtils.GetSpawnOccupants(orderManager.LobbyInfo, lobby.Map); + preview.Preview = () => lobby.MapPreview; + preview.OnMouseDown = mi => LobbyUtils.SelectSpawnPoint(orderManager, preview, lobby.MapPreview, mi); + preview.SpawnOccupants = () => LobbyUtils.GetSpawnOccupants(orderManager.LobbyInfo, lobby.MapPreview); var titleLabel = available.GetOrNull("MAP_TITLE"); if (titleLabel != null) { var font = Game.Renderer.Fonts[titleLabel.Font]; var title = new CachedTransform(m => WidgetUtils.TruncateText(m.Title, titleLabel.Bounds.Width, font)); - titleLabel.GetText = () => title.Update(lobby.Map); + titleLabel.GetText = () => title.Update(lobby.MapPreview); } var typeLabel = available.GetOrNull("MAP_TYPE"); if (typeLabel != null) - typeLabel.GetText = () => lobby.Map.Type; + typeLabel.GetText = () => lobby.MapPreview.Type; var authorLabel = available.GetOrNull("MAP_AUTHOR"); if (authorLabel != null) { var font = Game.Renderer.Fonts[authorLabel.Font]; - var author = new CachedTransform(m => WidgetUtils.TruncateText("Created by {0}".F(lobby.Map.Author), authorLabel.Bounds.Width, font)); - authorLabel.GetText = () => author.Update(lobby.Map); + var author = new CachedTransform( + m => WidgetUtils.TruncateText("Created by {0}".F(lobby.MapPreview.Author), authorLabel.Bounds.Width, font)); + authorLabel.GetText = () => author.Update(lobby.MapPreview); } } var invalid = widget.GetOrNull("MAP_INVALID"); if (invalid != null) { - invalid.IsVisible = () => lobby.Map.Status == MapStatus.Available && lobby.Map.RuleStatus == MapRuleStatus.Invalid; + invalid.IsVisible = () => lobby.MapPreview.Status == MapStatus.Available && lobby.MapPreview.RuleStatus == MapRuleStatus.Invalid; var preview = invalid.Get("MAP_PREVIEW"); - preview.Preview = () => lobby.Map; - preview.OnMouseDown = mi => LobbyUtils.SelectSpawnPoint(orderManager, preview, lobby.Map, mi); - preview.SpawnOccupants = () => LobbyUtils.GetSpawnOccupants(orderManager.LobbyInfo, lobby.Map); + preview.Preview = () => lobby.MapPreview; + preview.OnMouseDown = mi => LobbyUtils.SelectSpawnPoint(orderManager, preview, lobby.MapPreview, mi); + preview.SpawnOccupants = () => LobbyUtils.GetSpawnOccupants(orderManager.LobbyInfo, lobby.MapPreview); var title = invalid.GetOrNull("MAP_TITLE"); if (title != null) - title.GetText = () => lobby.Map.Title; + title.GetText = () => lobby.MapPreview.Title; var type = invalid.GetOrNull("MAP_TYPE"); if (type != null) - type.GetText = () => lobby.Map.Type; + type.GetText = () => lobby.MapPreview.Type; } var download = widget.GetOrNull("MAP_DOWNLOADABLE"); if (download != null) { - download.IsVisible = () => lobby.Map.Status == MapStatus.DownloadAvailable; + download.IsVisible = () => lobby.MapPreview.Status == MapStatus.DownloadAvailable; var preview = download.Get("MAP_PREVIEW"); - preview.Preview = () => lobby.Map; - preview.OnMouseDown = mi => LobbyUtils.SelectSpawnPoint(orderManager, preview, lobby.Map, mi); - preview.SpawnOccupants = () => LobbyUtils.GetSpawnOccupants(orderManager.LobbyInfo, lobby.Map); + preview.Preview = () => lobby.MapPreview; + preview.OnMouseDown = mi => LobbyUtils.SelectSpawnPoint(orderManager, preview, lobby.MapPreview, mi); + preview.SpawnOccupants = () => LobbyUtils.GetSpawnOccupants(orderManager.LobbyInfo, lobby.MapPreview); var title = download.GetOrNull("MAP_TITLE"); if (title != null) - title.GetText = () => lobby.Map.Title; + title.GetText = () => lobby.MapPreview.Title; var type = download.GetOrNull("MAP_TYPE"); if (type != null) - type.GetText = () => lobby.Map.Type; + type.GetText = () => lobby.MapPreview.Type; var author = download.GetOrNull("MAP_AUTHOR"); if (author != null) - author.GetText = () => "Created by {0}".F(lobby.Map.Author); + author.GetText = () => "Created by {0}".F(lobby.MapPreview.Author); var install = download.GetOrNull("MAP_INSTALL"); if (install != null) { - install.OnClick = () => lobby.Map.Install(); + install.OnClick = () => lobby.MapPreview.Install(); install.IsHighlighted = () => installHighlighted; } } @@ -106,71 +107,72 @@ namespace OpenRA.Mods.Common.Widgets.Logic if (progress != null) { progress.IsVisible = () => - (lobby.Map.Status != MapStatus.Available || lobby.Map.RuleStatus == MapRuleStatus.Unknown) && - lobby.Map.Status != MapStatus.DownloadAvailable; + (lobby.MapPreview.Status != MapStatus.Available || lobby.MapPreview.RuleStatus == MapRuleStatus.Unknown) && + lobby.MapPreview.Status != MapStatus.DownloadAvailable; var preview = progress.Get("MAP_PREVIEW"); - preview.Preview = () => lobby.Map; - preview.OnMouseDown = mi => LobbyUtils.SelectSpawnPoint(orderManager, preview, lobby.Map, mi); - preview.SpawnOccupants = () => LobbyUtils.GetSpawnOccupants(orderManager.LobbyInfo, lobby.Map); + preview.Preview = () => lobby.MapPreview; + preview.OnMouseDown = mi => LobbyUtils.SelectSpawnPoint(orderManager, preview, lobby.MapPreview, mi); + preview.SpawnOccupants = () => LobbyUtils.GetSpawnOccupants(orderManager.LobbyInfo, lobby.MapPreview); var title = progress.GetOrNull("MAP_TITLE"); if (title != null) - title.GetText = () => lobby.Map.Title; + title.GetText = () => lobby.MapPreview.Title; var type = progress.GetOrNull("MAP_TYPE"); if (type != null) - type.GetText = () => lobby.Map.Type; + type.GetText = () => lobby.MapPreview.Type; var statusSearching = progress.GetOrNull("MAP_STATUS_SEARCHING"); if (statusSearching != null) - statusSearching.IsVisible = () => lobby.Map.Status == MapStatus.Searching; + statusSearching.IsVisible = () => lobby.MapPreview.Status == MapStatus.Searching; var statusUnavailable = progress.GetOrNull("MAP_STATUS_UNAVAILABLE"); if (statusUnavailable != null) - statusUnavailable.IsVisible = () => lobby.Map.Status == MapStatus.Unavailable; + statusUnavailable.IsVisible = () => lobby.MapPreview.Status == MapStatus.Unavailable; var statusError = progress.GetOrNull("MAP_STATUS_ERROR"); if (statusError != null) - statusError.IsVisible = () => lobby.Map.Status == MapStatus.DownloadError; + statusError.IsVisible = () => lobby.MapPreview.Status == MapStatus.DownloadError; var statusDownloading = progress.GetOrNull("MAP_STATUS_DOWNLOADING"); if (statusDownloading != null) { - statusDownloading.IsVisible = () => lobby.Map.Status == MapStatus.Downloading; + statusDownloading.IsVisible = () => lobby.MapPreview.Status == MapStatus.Downloading; statusDownloading.GetText = () => { - if (lobby.Map.DownloadBytes == 0) + if (lobby.MapPreview.DownloadBytes == 0) return "Connecting..."; // Server does not provide the total file length - if (lobby.Map.DownloadPercentage == 0) - return "Downloading {0} kB".F(lobby.Map.DownloadBytes / 1024); + if (lobby.MapPreview.DownloadPercentage == 0) + return "Downloading {0} kB".F(lobby.MapPreview.DownloadBytes / 1024); - return "Downloading {0} kB ({1}%)".F(lobby.Map.DownloadBytes / 1024, lobby.Map.DownloadPercentage); + return "Downloading {0} kB ({1}%)".F(lobby.MapPreview.DownloadBytes / 1024, lobby.MapPreview.DownloadPercentage); }; } var retry = progress.GetOrNull("MAP_RETRY"); if (retry != null) { - retry.IsVisible = () => (lobby.Map.Status == MapStatus.DownloadError || lobby.Map.Status == MapStatus.Unavailable) && lobby.Map != MapCache.UnknownMap; + retry.IsVisible = () => (lobby.MapPreview.Status == MapStatus.DownloadError || lobby.MapPreview.Status == MapStatus.Unavailable) && + lobby.MapPreview != MapCache.UnknownMap; retry.OnClick = () => { - if (lobby.Map.Status == MapStatus.DownloadError) - lobby.Map.Install(); - else if (lobby.Map.Status == MapStatus.Unavailable) - Game.ModData.MapCache.QueryRemoteMapDetails(new[] { lobby.Map.Uid }); + if (lobby.MapPreview.Status == MapStatus.DownloadError) + lobby.MapPreview.Install(); + else if (lobby.MapPreview.Status == MapStatus.Unavailable) + Game.ModData.MapCache.QueryRemoteMapDetails(new[] { lobby.MapPreview.Uid }); }; - retry.GetText = () => lobby.Map.Status == MapStatus.DownloadError ? "Retry Install" : "Retry Search"; + retry.GetText = () => lobby.MapPreview.Status == MapStatus.DownloadError ? "Retry Install" : "Retry Search"; } var progressbar = progress.GetOrNull("MAP_PROGRESSBAR"); if (progressbar != null) { - progressbar.IsIndeterminate = () => lobby.Map.DownloadPercentage == 0; - progressbar.GetPercentage = () => lobby.Map.DownloadPercentage; + progressbar.IsIndeterminate = () => lobby.MapPreview.DownloadPercentage == 0; + progressbar.GetPercentage = () => lobby.MapPreview.DownloadPercentage; progressbar.IsVisible = () => !retry.IsVisible(); } } From 6628bc046f6a7c759c42949ba6277c51a133f3f5 Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Fri, 5 Feb 2016 08:30:01 +0000 Subject: [PATCH 3/9] Add a Map reference to LobbyLogic. --- .../Widgets/Logic/Lobby/LobbyLogic.cs | 54 ++++++++++--------- 1 file changed, 28 insertions(+), 26 deletions(-) diff --git a/OpenRA.Mods.Common/Widgets/Logic/Lobby/LobbyLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/Lobby/LobbyLogic.cs index 3dd98a0676..18bc17085a 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/Lobby/LobbyLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/Lobby/LobbyLogic.cs @@ -26,7 +26,8 @@ namespace OpenRA.Mods.Common.Widgets.Logic { static readonly Action DoNothing = () => { }; - public MapPreview MapPreview = MapCache.UnknownMap; + public MapPreview MapPreview { get; private set; } + public Map Map { get; private set; } readonly Action onStart; readonly Action onExit; @@ -111,6 +112,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic internal LobbyLogic(Widget widget, WorldRenderer worldRenderer, OrderManager orderManager, Action onExit, Action onStart, bool skirmishMode, Ruleset modRules) { + MapPreview = MapCache.UnknownMap; lobby = widget; this.orderManager = orderManager; this.onStart = onStart; @@ -156,6 +158,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic var gameStarting = false; Func configurationDisabled = () => !Game.IsHost || gameStarting || panel == PanelType.Kick || panel == PanelType.ForceStart || + Map == null || Map.InvalidCustomRules || orderManager.LocalClient == null || orderManager.LocalClient.IsReady; var mapButton = lobby.GetOrNull("CHANGEMAP_BUTTON"); @@ -190,7 +193,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic var slotsButton = lobby.GetOrNull("SLOTS_DROPDOWNBUTTON"); if (slotsButton != null) { - slotsButton.IsDisabled = () => configurationDisabled() || panel != PanelType.Players || MapPreview.RuleStatus != MapRuleStatus.Cached || + slotsButton.IsDisabled = () => configurationDisabled() || panel != PanelType.Players || (orderManager.LobbyInfo.Slots.Values.All(s => !s.AllowBots) && orderManager.LobbyInfo.Slots.Count(s => !s.Value.LockTeam && orderManager.LobbyInfo.ClientInSlot(s.Key) != null) == 0); @@ -294,7 +297,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic var optionsTab = lobby.Get("OPTIONS_TAB"); optionsTab.IsHighlighted = () => panel == PanelType.Options; - optionsTab.IsDisabled = () => MapPreview.RuleStatus != MapRuleStatus.Cached || panel == PanelType.Kick || panel == PanelType.ForceStart; + optionsTab.IsDisabled = () => Map == null || Map.InvalidCustomRules || panel == PanelType.Kick || panel == PanelType.ForceStart; optionsTab.OnClick = () => panel = PanelType.Options; var playersTab = lobby.Get("PLAYERS_TAB"); @@ -317,7 +320,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic var startGameButton = lobby.GetOrNull("START_GAME_BUTTON"); if (startGameButton != null) { - startGameButton.IsDisabled = () => configurationDisabled() || MapPreview.RuleStatus != MapRuleStatus.Cached || + startGameButton.IsDisabled = () => configurationDisabled() || orderManager.LobbyInfo.Slots.Any(sl => sl.Value.Required && orderManager.LobbyInfo.ClientInSlot(sl.Key) == null) || (orderManager.LobbyInfo.GlobalSettings.DisableSingleplayer && orderManager.LobbyInfo.IsSinglePlayer); @@ -342,7 +345,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic if (allowCheats != null) { allowCheats.IsChecked = () => orderManager.LobbyInfo.GlobalSettings.AllowCheats; - allowCheats.IsDisabled = () => MapPreview.Status != MapStatus.Available || MapPreview.Map.Options.Cheats.HasValue || configurationDisabled(); + allowCheats.IsDisabled = () => configurationDisabled() || Map.Options.Cheats.HasValue; allowCheats.OnClick = () => orderManager.IssueOrder(Order.Command( "allowcheats {0}".F(!orderManager.LobbyInfo.GlobalSettings.AllowCheats))); } @@ -351,7 +354,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic if (crates != null) { crates.IsChecked = () => orderManager.LobbyInfo.GlobalSettings.Crates; - crates.IsDisabled = () => MapPreview.Status != MapStatus.Available || MapPreview.Map.Options.Crates.HasValue || configurationDisabled(); + crates.IsDisabled = () => configurationDisabled() || Map.Options.Crates.HasValue; crates.OnClick = () => orderManager.IssueOrder(Order.Command( "crates {0}".F(!orderManager.LobbyInfo.GlobalSettings.Crates))); } @@ -360,7 +363,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic if (creeps != null) { creeps.IsChecked = () => orderManager.LobbyInfo.GlobalSettings.Creeps; - creeps.IsDisabled = () => MapPreview.Status != MapStatus.Available || MapPreview.Map.Options.Creeps.HasValue || configurationDisabled(); + creeps.IsDisabled = () => configurationDisabled() || Map.Options.Creeps.HasValue; creeps.OnClick = () => orderManager.IssueOrder(Order.Command( "creeps {0}".F(!orderManager.LobbyInfo.GlobalSettings.Creeps))); } @@ -369,7 +372,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic if (allybuildradius != null) { allybuildradius.IsChecked = () => orderManager.LobbyInfo.GlobalSettings.AllyBuildRadius; - allybuildradius.IsDisabled = () => MapPreview.Status != MapStatus.Available || MapPreview.Map.Options.AllyBuildRadius.HasValue || configurationDisabled(); + allybuildradius.IsDisabled = () => configurationDisabled() || Map.Options.AllyBuildRadius.HasValue; allybuildradius.OnClick = () => orderManager.IssueOrder(Order.Command( "allybuildradius {0}".F(!orderManager.LobbyInfo.GlobalSettings.AllyBuildRadius))); } @@ -378,7 +381,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic if (shortGame != null) { shortGame.IsChecked = () => orderManager.LobbyInfo.GlobalSettings.ShortGame; - shortGame.IsDisabled = () => MapPreview.Status != MapStatus.Available || MapPreview.Map.Options.ShortGame.HasValue || configurationDisabled(); + shortGame.IsDisabled = () => configurationDisabled() || Map.Options.ShortGame.HasValue; shortGame.OnClick = () => orderManager.IssueOrder(Order.Command( "shortgame {0}".F(!orderManager.LobbyInfo.GlobalSettings.ShortGame))); } @@ -386,12 +389,12 @@ namespace OpenRA.Mods.Common.Widgets.Logic var difficulty = optionsBin.GetOrNull("DIFFICULTY_DROPDOWNBUTTON"); if (difficulty != null) { - difficulty.IsVisible = () => MapPreview.Status == MapStatus.Available && MapPreview.Map.Options.Difficulties.Any(); - difficulty.IsDisabled = () => MapPreview.Status != MapStatus.Available || configurationDisabled(); + difficulty.IsVisible = () => Map != null && Map.Options.Difficulties.Any(); + difficulty.IsDisabled = configurationDisabled; difficulty.GetText = () => orderManager.LobbyInfo.GlobalSettings.Difficulty; difficulty.OnMouseDown = _ => { - var options = MapPreview.Map.Options.Difficulties.Select(d => new DropDownOption + var options = Map.Options.Difficulties.Select(d => new DropDownOption { Title = d, IsSelected = () => orderManager.LobbyInfo.GlobalSettings.Difficulty == d, @@ -420,10 +423,9 @@ namespace OpenRA.Mods.Common.Widgets.Logic return selectedClass != null ? selectedClass : c; }; - startingUnits.IsDisabled = () => MapPreview.Status != MapStatus.Available || - !MapPreview.Map.Options.ConfigurableStartingUnits || configurationDisabled(); + startingUnits.IsDisabled = () => configurationDisabled() || !Map.Options.ConfigurableStartingUnits; startingUnits.GetText = () => MapPreview.Status != MapStatus.Available || - !MapPreview.Map.Options.ConfigurableStartingUnits ? "Not Available" : className(orderManager.LobbyInfo.GlobalSettings.StartingUnitsClass); + Map == null || !Map.Options.ConfigurableStartingUnits ? "Not Available" : className(orderManager.LobbyInfo.GlobalSettings.StartingUnitsClass); startingUnits.OnMouseDown = _ => { var options = classes.Select(c => new DropDownOption @@ -449,10 +451,9 @@ namespace OpenRA.Mods.Common.Widgets.Logic var startingCash = optionsBin.GetOrNull("STARTINGCASH_DROPDOWNBUTTON"); if (startingCash != null) { - startingCash.IsDisabled = () => MapPreview.Status != MapStatus.Available || - MapPreview.Map.Options.StartingCash.HasValue || configurationDisabled(); + startingCash.IsDisabled = () => configurationDisabled() || Map.Options.StartingCash.HasValue; startingCash.GetText = () => MapPreview.Status != MapStatus.Available || - MapPreview.Map.Options.StartingCash.HasValue ? "Not Available" : "${0}".F(orderManager.LobbyInfo.GlobalSettings.StartingCash); + Map == null || Map.Options.StartingCash.HasValue ? "Not Available" : "${0}".F(orderManager.LobbyInfo.GlobalSettings.StartingCash); startingCash.OnMouseDown = _ => { var options = modRules.Actors["player"].TraitInfo().SelectableCash.Select(c => new DropDownOption @@ -483,10 +484,9 @@ namespace OpenRA.Mods.Common.Widgets.Logic if (techLevelDescription != null) techLevelDescription.IsVisible = () => techTraits.Count > 0; - techLevel.IsDisabled = () => MapPreview.Status != MapStatus.Available || - MapPreview.Map.Options.TechLevel != null || configurationDisabled() || techTraits.Count <= 1; + techLevel.IsDisabled = () => configurationDisabled() || Map.Options.TechLevel != null || techTraits.Count <= 1; techLevel.GetText = () => MapPreview.Status != MapStatus.Available || - MapPreview.Map.Options.TechLevel != null ? "Not Available" : "{0}".F(orderManager.LobbyInfo.GlobalSettings.TechLevel); + Map == null || Map.Options.TechLevel != null ? "Not Available" : "{0}".F(orderManager.LobbyInfo.GlobalSettings.TechLevel); techLevel.OnMouseDown = _ => { var options = techTraits.Select(c => new DropDownOption @@ -512,7 +512,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic { var speeds = Game.ModData.Manifest.Get().Speeds; - gameSpeed.IsDisabled = () => MapPreview.Status != MapStatus.Available || configurationDisabled(); + gameSpeed.IsDisabled = configurationDisabled; gameSpeed.GetText = () => { if (MapPreview.Status != MapStatus.Available) @@ -549,7 +549,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic if (exploredMap != null) { exploredMap.IsChecked = () => !orderManager.LobbyInfo.GlobalSettings.Shroud; - exploredMap.IsDisabled = () => MapPreview.Status != MapStatus.Available || MapPreview.Map.Options.Shroud.HasValue || configurationDisabled(); + exploredMap.IsDisabled = () => configurationDisabled() || Map.Options.Shroud.HasValue; exploredMap.OnClick = () => orderManager.IssueOrder(Order.Command( "shroud {0}".F(!orderManager.LobbyInfo.GlobalSettings.Shroud))); } @@ -558,7 +558,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic if (enableFog != null) { enableFog.IsChecked = () => orderManager.LobbyInfo.GlobalSettings.Fog; - enableFog.IsDisabled = () => MapPreview.Status != MapStatus.Available || MapPreview.Map.Options.Fog.HasValue || configurationDisabled(); + enableFog.IsDisabled = () => configurationDisabled() || Map.Options.Fog.HasValue; enableFog.OnClick = () => orderManager.IssueOrder(Order.Command( "fog {0}".F(!orderManager.LobbyInfo.GlobalSettings.Fog))); } @@ -738,17 +738,19 @@ namespace OpenRA.Mods.Common.Widgets.Logic return; MapPreview = Game.ModData.MapCache[uid]; + Map = null; if (MapPreview.Status == MapStatus.Available) { // Maps need to be validated and pre-loaded before they can be accessed new Thread(_ => { + var currentMap = Map = MapPreview.Map; var mapPreview = MapPreview; mapPreview.CacheRules(); Game.RunAfterTick(() => { // Map may have changed in the meantime - if (mapPreview != MapPreview) + if (currentMap != Map) return; if (mapPreview.RuleStatus != MapRuleStatus.Invalid) @@ -758,7 +760,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic // Restore default starting cash if the last map set it to something invalid var pri = modRules.Actors["player"].TraitInfo(); - if (!MapPreview.Map.Options.StartingCash.HasValue && !pri.SelectableCash.Contains(orderManager.LobbyInfo.GlobalSettings.StartingCash)) + if (!currentMap.Options.StartingCash.HasValue && !pri.SelectableCash.Contains(orderManager.LobbyInfo.GlobalSettings.StartingCash)) orderManager.IssueOrder(Order.Command("startingcash {0}".F(pri.DefaultCash))); } }); From d5e3fbf452caf6b6b1e5eb5ec7bec45907e84f83 Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Fri, 5 Feb 2016 21:29:23 +0000 Subject: [PATCH 4/9] Store map path in MapPreview. --- OpenRA.Game/Map/MapPreview.cs | 5 ++++- OpenRA.Game/ModData.cs | 2 +- OpenRA.Mods.Common/Widgets/Logic/MapChooserLogic.cs | 2 +- OpenRA.Mods.Common/Widgets/Logic/MissionBrowserLogic.cs | 2 +- 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/OpenRA.Game/Map/MapPreview.cs b/OpenRA.Game/Map/MapPreview.cs index 3f09a31418..2726f16a79 100644 --- a/OpenRA.Game/Map/MapPreview.cs +++ b/OpenRA.Game/Map/MapPreview.cs @@ -57,6 +57,8 @@ namespace OpenRA MapCache cache; public readonly string Uid; + public string Path { get; private set; } + public string Title { get; private set; } public string Type { get; private set; } public string Author { get; private set; } @@ -118,6 +120,7 @@ namespace OpenRA public void UpdateFromMap(Map m, MapClassification classification) { Map = m; + Path = m.Path; Title = m.Title; Type = m.Type; Type = m.Type; @@ -231,7 +234,7 @@ namespace OpenRA return; } - mapPath = Path.Combine(baseMapPath, res.Headers["Content-Disposition"].Replace("attachment; filename = ", "")); + mapPath = System.IO.Path.Combine(baseMapPath, res.Headers["Content-Disposition"].Replace("attachment; filename = ", "")); } Action onDownloadProgress = i => { DownloadBytes = i.BytesReceived; DownloadPercentage = i.ProgressPercentage; }; diff --git a/OpenRA.Game/ModData.cs b/OpenRA.Game/ModData.cs index e6ad5fd73f..3fee14ee7e 100644 --- a/OpenRA.Game/ModData.cs +++ b/OpenRA.Game/ModData.cs @@ -166,7 +166,7 @@ namespace OpenRA throw new InvalidDataException("Invalid map uid: {0}".F(uid)); // Operate on a copy of the map to avoid gameplay state leaking into the cache - var map = new Map(MapCache[uid].Map.Path); + var map = new Map(MapCache[uid].Path); LoadTranslations(map); diff --git a/OpenRA.Mods.Common/Widgets/Logic/MapChooserLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/MapChooserLogic.cs index 1c35e3f63c..2a8b44e900 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/MapChooserLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/MapChooserLogic.cs @@ -284,7 +284,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic string DeleteMap(string map) { - var path = Game.ModData.MapCache[map].Map.Path; + var path = Game.ModData.MapCache[map].Path; try { if (File.Exists(path)) diff --git a/OpenRA.Mods.Common/Widgets/Logic/MissionBrowserLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/MissionBrowserLogic.cs index 6038a25f3a..0165fe7f15 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/MissionBrowserLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/MissionBrowserLogic.cs @@ -103,7 +103,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic var missionMapPaths = kv.Value.Nodes.Select(n => Path.GetFullPath(n.Key)).ToList(); var maps = modData.MapCache - .Where(p => p.Status == MapStatus.Available && missionMapPaths.Contains(Path.GetFullPath(p.Map.Path))) + .Where(p => p.Status == MapStatus.Available && missionMapPaths.Contains(Path.GetFullPath(p.Path))) .Select(p => p.Map) .OrderBy(m => missionMapPaths.IndexOf(Path.GetFullPath(m.Path))); From e13e0792f6a9d7b407a5964d11ed1be867c87f8a Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Fri, 5 Feb 2016 21:31:17 +0000 Subject: [PATCH 5/9] Remove unnecessary Map usage from MainMenuLogic. --- OpenRA.Mods.Common/Widgets/Logic/MainMenuLogic.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/OpenRA.Mods.Common/Widgets/Logic/MainMenuLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/MainMenuLogic.cs index 2d9d82bed4..65afcae84c 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/MainMenuLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/MainMenuLogic.cs @@ -167,7 +167,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic var onSelect = new Action(uid => { RemoveShellmapUI(); - LoadMapIntoEditor(Game.ModData.MapCache[uid].Map); + LoadMapIntoEditor(Game.ModData.MapCache[uid].Uid); }); var newMapButton = widget.Get("NEW_MAP_BUTTON"); @@ -242,12 +242,12 @@ namespace OpenRA.Mods.Common.Widgets.Logic }); } - void LoadMapIntoEditor(Map map) + void LoadMapIntoEditor(string uid) { ConnectionLogic.Connect(IPAddress.Loopback.ToString(), - Game.CreateLocalServer(map.Uid), + Game.CreateLocalServer(uid), "", - () => { Game.LoadEditor(map.Uid); }, + () => { Game.LoadEditor(uid); }, () => { Game.CloseServer(); SwitchMenu(MenuType.MapEditor); }); } From 4328f24276aa361e2cfef6ddeb4ea96cb7c94b26 Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Fri, 5 Feb 2016 21:35:21 +0000 Subject: [PATCH 6/9] Remove unnecessary Map usage from MissionBrowserLogic. --- OpenRA.Mods.Common/Widgets/Logic/MissionBrowserLogic.cs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/OpenRA.Mods.Common/Widgets/Logic/MissionBrowserLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/MissionBrowserLogic.cs index 0165fe7f15..5600281d3c 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/MissionBrowserLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/MissionBrowserLogic.cs @@ -40,6 +40,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic readonly ScrollItemWidget template; MapPreview selectedMapPreview; + Map selectedMap; PlayingVideo playingVideo; @@ -161,16 +162,17 @@ namespace OpenRA.Mods.Common.Widgets.Logic void SelectMap(Map map) { + selectedMap = map; selectedMapPreview = Game.ModData.MapCache[map.Uid]; // Cache the rules on a background thread to avoid jank new Thread(selectedMapPreview.CacheRules).Start(); - var briefingVideo = selectedMapPreview.Map.Videos.Briefing; + var briefingVideo = map.Videos.Briefing; var briefingVideoVisible = briefingVideo != null; var briefingVideoDisabled = !(briefingVideoVisible && Game.ModData.ModFiles.Exists(briefingVideo)); - var infoVideo = selectedMapPreview.Map.Videos.BackgroundInfo; + var infoVideo = map.Videos.BackgroundInfo; var infoVideoVisible = infoVideo != null; var infoVideoDisabled = !(infoVideoVisible && Game.ModData.ModFiles.Exists(infoVideo)); @@ -291,7 +293,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic if (selectedMapPreview.RuleStatus != MapRuleStatus.Cached) return; - var gameStartVideo = selectedMapPreview.Map.Videos.GameStart; + var gameStartVideo = selectedMap.Videos.GameStart; if (gameStartVideo != null && Game.ModData.ModFiles.Exists(gameStartVideo)) { var fsPlayer = fullscreenVideoPlayer.Get("PLAYER"); From 3708a7649d14e575014215c7fddd43bc597b67e3 Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Fri, 5 Feb 2016 22:03:56 +0000 Subject: [PATCH 7/9] Remove MapPreview.CacheRules. --- OpenRA.Game/Map/MapPreview.cs | 19 +------------------ .../Widgets/Logic/Lobby/LobbyLogic.cs | 9 ++++----- .../Logic/Lobby/LobbyMapPreviewLogic.cs | 7 +++---- .../Widgets/Logic/Lobby/LobbyUtils.cs | 4 ++-- .../Widgets/Logic/MissionBrowserLogic.cs | 6 +++--- 5 files changed, 13 insertions(+), 32 deletions(-) diff --git a/OpenRA.Game/Map/MapPreview.cs b/OpenRA.Game/Map/MapPreview.cs index 2726f16a79..363ee31180 100644 --- a/OpenRA.Game/Map/MapPreview.cs +++ b/OpenRA.Game/Map/MapPreview.cs @@ -73,8 +73,6 @@ namespace OpenRA public MapVisibility Visibility { get; private set; } public bool SuitableForInitialMap { get; private set; } - public MapRuleStatus RuleStatus { get; private set; } - Download download; public long DownloadBytes { get; private set; } public int DownloadPercentage { get; private set; } @@ -174,7 +172,6 @@ namespace OpenRA if (!r.downloading) { Status = MapStatus.Unavailable; - RuleStatus = MapRuleStatus.Invalid; return; } @@ -252,11 +249,7 @@ namespace OpenRA } Log.Write("debug", "Downloaded map to '{0}'", mapPath); - Game.RunAfterTick(() => - { - UpdateFromMap(new Map(mapPath), MapClassification.User); - CacheRules(); - }); + Game.RunAfterTick(() => UpdateFromMap(new Map(mapPath), MapClassification.User)); }; download = new Download(mapUrl, mapPath, onDownloadProgress, onDownloadComplete); @@ -278,19 +271,9 @@ namespace OpenRA download = null; } - public void CacheRules() - { - if (RuleStatus != MapRuleStatus.Unknown) - return; - - Map.PreloadRules(); - RuleStatus = Map.InvalidCustomRules ? MapRuleStatus.Invalid : MapRuleStatus.Cached; - } - public void Invalidate() { Status = MapStatus.Unavailable; - RuleStatus = MapRuleStatus.Unknown; } } } diff --git a/OpenRA.Mods.Common/Widgets/Logic/Lobby/LobbyLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/Lobby/LobbyLogic.cs index 18bc17085a..24978d7f22 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/Lobby/LobbyLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/Lobby/LobbyLogic.cs @@ -744,16 +744,15 @@ namespace OpenRA.Mods.Common.Widgets.Logic // Maps need to be validated and pre-loaded before they can be accessed new Thread(_ => { - var currentMap = Map = MapPreview.Map; - var mapPreview = MapPreview; - mapPreview.CacheRules(); + var currentMap = Map = new Map(MapPreview.Path); + currentMap.PreloadRules(); Game.RunAfterTick(() => { // Map may have changed in the meantime if (currentMap != Map) return; - if (mapPreview.RuleStatus != MapRuleStatus.Invalid) + if (!currentMap.InvalidCustomRules) { // Tell the server that we have the map orderManager.IssueOrder(Order.Command("state {0}".F(Session.ClientState.NotReady))); @@ -821,7 +820,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic LobbyUtils.SetupEditableFactionWidget(template, slot, client, orderManager, factions); LobbyUtils.SetupEditableTeamWidget(template, slot, client, orderManager, MapPreview); LobbyUtils.SetupEditableSpawnWidget(template, slot, client, orderManager, MapPreview); - LobbyUtils.SetupEditableReadyWidget(template, slot, client, orderManager, MapPreview); + LobbyUtils.SetupEditableReadyWidget(template, slot, client, orderManager, MapPreview, Map == null || Map.InvalidCustomRules); } else { diff --git a/OpenRA.Mods.Common/Widgets/Logic/Lobby/LobbyMapPreviewLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/Lobby/LobbyMapPreviewLogic.cs index 36a6b934bc..74dca76b8e 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/Lobby/LobbyMapPreviewLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/Lobby/LobbyMapPreviewLogic.cs @@ -25,7 +25,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic var available = widget.GetOrNull("MAP_AVAILABLE"); if (available != null) { - available.IsVisible = () => lobby.MapPreview.Status == MapStatus.Available && lobby.MapPreview.RuleStatus == MapRuleStatus.Cached; + available.IsVisible = () => lobby.MapPreview.Status == MapStatus.Available && (lobby.Map == null || !lobby.Map.InvalidCustomRules); var preview = available.Get("MAP_PREVIEW"); preview.Preview = () => lobby.MapPreview; @@ -57,7 +57,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic var invalid = widget.GetOrNull("MAP_INVALID"); if (invalid != null) { - invalid.IsVisible = () => lobby.MapPreview.Status == MapStatus.Available && lobby.MapPreview.RuleStatus == MapRuleStatus.Invalid; + invalid.IsVisible = () => lobby.MapPreview.Status == MapStatus.Available && lobby.Map != null && lobby.Map.InvalidCustomRules; var preview = invalid.Get("MAP_PREVIEW"); preview.Preview = () => lobby.MapPreview; @@ -106,8 +106,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic var progress = widget.GetOrNull("MAP_PROGRESS"); if (progress != null) { - progress.IsVisible = () => - (lobby.MapPreview.Status != MapStatus.Available || lobby.MapPreview.RuleStatus == MapRuleStatus.Unknown) && + progress.IsVisible = () => lobby.MapPreview.Status != MapStatus.Available && lobby.MapPreview.Status != MapStatus.DownloadAvailable; var preview = progress.Get("MAP_PREVIEW"); diff --git a/OpenRA.Mods.Common/Widgets/Logic/Lobby/LobbyUtils.cs b/OpenRA.Mods.Common/Widgets/Logic/Lobby/LobbyUtils.cs index 27b88dbabf..672f7621bb 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/Lobby/LobbyUtils.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/Lobby/LobbyUtils.cs @@ -455,12 +455,12 @@ namespace OpenRA.Mods.Common.Widgets.Logic parent.Get("SPAWN").GetText = () => (c.SpawnPoint == 0) ? "-" : Convert.ToChar('A' - 1 + c.SpawnPoint).ToString(); } - public static void SetupEditableReadyWidget(Widget parent, Session.Slot s, Session.Client c, OrderManager orderManager, MapPreview map) + public static void SetupEditableReadyWidget(Widget parent, Session.Slot s, Session.Client c, OrderManager orderManager, MapPreview map, bool forceDisable) { var status = parent.Get("STATUS_CHECKBOX"); status.IsChecked = () => orderManager.LocalClient.IsReady || c.Bot != null; status.IsVisible = () => true; - status.IsDisabled = () => c.Bot != null || map.Status != MapStatus.Available || map.RuleStatus != MapRuleStatus.Cached; + status.IsDisabled = () => c.Bot != null || map.Status != MapStatus.Available || forceDisable; var state = orderManager.LocalClient.IsReady ? Session.ClientState.NotReady : Session.ClientState.Ready; status.OnClick = () => orderManager.IssueOrder(Order.Command("state {0}".F(state))); diff --git a/OpenRA.Mods.Common/Widgets/Logic/MissionBrowserLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/MissionBrowserLogic.cs index 5600281d3c..3b50f68acd 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/MissionBrowserLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/MissionBrowserLogic.cs @@ -129,7 +129,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic var startButton = widget.Get("STARTGAME_BUTTON"); startButton.OnClick = StartMissionClicked; - startButton.IsDisabled = () => selectedMapPreview == null || selectedMapPreview.RuleStatus != MapRuleStatus.Cached; + startButton.IsDisabled = () => selectedMap == null || selectedMap.InvalidCustomRules; widget.Get("BACK_BUTTON").OnClick = () => { @@ -166,7 +166,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic selectedMapPreview = Game.ModData.MapCache[map.Uid]; // Cache the rules on a background thread to avoid jank - new Thread(selectedMapPreview.CacheRules).Start(); + new Thread(() => selectedMap.PreloadRules()).Start(); var briefingVideo = map.Videos.Briefing; var briefingVideoVisible = briefingVideo != null; @@ -290,7 +290,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic { StopVideo(videoPlayer); - if (selectedMapPreview.RuleStatus != MapRuleStatus.Cached) + if (selectedMap.InvalidCustomRules) return; var gameStartVideo = selectedMap.Videos.GameStart; From 7b00da04ca309a2ddb5509b928015656ec73c489 Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Fri, 5 Feb 2016 22:04:06 +0000 Subject: [PATCH 8/9] Remove MapPreview.Map. --- OpenRA.Game/Map/MapCache.cs | 3 ++- OpenRA.Game/Map/MapPreview.cs | 2 -- OpenRA.Mods.Common/ServerTraits/LobbyCommands.cs | 2 +- OpenRA.Mods.Common/UtilityCommands/CheckYaml.cs | 2 +- OpenRA.Mods.Common/UtilityCommands/UpgradeModCommand.cs | 2 +- OpenRA.Mods.Common/Widgets/Logic/MissionBrowserLogic.cs | 6 +++--- 6 files changed, 8 insertions(+), 9 deletions(-) diff --git a/OpenRA.Game/Map/MapCache.cs b/OpenRA.Game/Map/MapCache.cs index da0eace73c..bd6e01b0ff 100644 --- a/OpenRA.Game/Map/MapCache.cs +++ b/OpenRA.Game/Map/MapCache.cs @@ -174,7 +174,8 @@ namespace OpenRA if (bitmap == null) { createdPreview = true; - bitmap = Minimap.RenderMapPreview(modData.DefaultRules.TileSets[p.Map.Tileset], p.Map, modData.DefaultRules, true); + var map = new Map(p.Path); + bitmap = Minimap.RenderMapPreview(modData.DefaultRules.TileSets[map.Tileset], map, modData.DefaultRules, true); } Game.RunAfterTick(() => diff --git a/OpenRA.Game/Map/MapPreview.cs b/OpenRA.Game/Map/MapPreview.cs index 363ee31180..11b0908e3a 100644 --- a/OpenRA.Game/Map/MapPreview.cs +++ b/OpenRA.Game/Map/MapPreview.cs @@ -67,7 +67,6 @@ namespace OpenRA public MapGridType GridType { get; private set; } public Rectangle Bounds { get; private set; } public Bitmap CustomPreview { get; private set; } - public Map Map { get; private set; } public MapStatus Status { get; private set; } public MapClassification Class { get; private set; } public MapVisibility Visibility { get; private set; } @@ -117,7 +116,6 @@ namespace OpenRA public void UpdateFromMap(Map m, MapClassification classification) { - Map = m; Path = m.Path; Title = m.Title; Type = m.Type; diff --git a/OpenRA.Mods.Common/ServerTraits/LobbyCommands.cs b/OpenRA.Mods.Common/ServerTraits/LobbyCommands.cs index 12c695b705..21581d2c40 100644 --- a/OpenRA.Mods.Common/ServerTraits/LobbyCommands.cs +++ b/OpenRA.Mods.Common/ServerTraits/LobbyCommands.cs @@ -926,7 +926,7 @@ namespace OpenRA.Mods.Common.Server static void LoadMap(S server) { - server.Map = server.ModData.MapCache[server.LobbyInfo.GlobalSettings.Map].Map; + server.Map = new Map(server.ModData.MapCache[server.LobbyInfo.GlobalSettings.Map].Path); server.MapPlayers = new MapPlayers(server.Map.PlayerDefinitions); server.LobbyInfo.Slots = server.MapPlayers.Players diff --git a/OpenRA.Mods.Common/UtilityCommands/CheckYaml.cs b/OpenRA.Mods.Common/UtilityCommands/CheckYaml.cs index 57aa5497a5..e00e712621 100644 --- a/OpenRA.Mods.Common/UtilityCommands/CheckYaml.cs +++ b/OpenRA.Mods.Common/UtilityCommands/CheckYaml.cs @@ -78,7 +78,7 @@ namespace OpenRA.Mods.Common.UtilityCommands Game.ModData.MapCache.LoadMaps(); maps.AddRange(Game.ModData.MapCache .Where(m => m.Status == MapStatus.Available) - .Select(m => m.Map)); + .Select(m => new Map(m.Path))); } else maps.Add(new Map(args[1])); diff --git a/OpenRA.Mods.Common/UtilityCommands/UpgradeModCommand.cs b/OpenRA.Mods.Common/UtilityCommands/UpgradeModCommand.cs index 99cab44484..1b35b63570 100644 --- a/OpenRA.Mods.Common/UtilityCommands/UpgradeModCommand.cs +++ b/OpenRA.Mods.Common/UtilityCommands/UpgradeModCommand.cs @@ -101,7 +101,7 @@ namespace OpenRA.Mods.Common.UtilityCommands Console.WriteLine("Processing Maps:"); var maps = Game.ModData.MapCache .Where(m => m.Status == MapStatus.Available) - .Select(m => m.Map); + .Select(m => new Map(m.Path)); foreach (var map in maps) { diff --git a/OpenRA.Mods.Common/Widgets/Logic/MissionBrowserLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/MissionBrowserLogic.cs index 3b50f68acd..34a19ea172 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/MissionBrowserLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/MissionBrowserLogic.cs @@ -105,7 +105,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic var maps = modData.MapCache .Where(p => p.Status == MapStatus.Available && missionMapPaths.Contains(Path.GetFullPath(p.Path))) - .Select(p => p.Map) + .Select(p => new Map(p.Path)) .OrderBy(m => missionMapPaths.IndexOf(Path.GetFullPath(m.Path))); CreateMissionGroup(kv.Key, maps); @@ -115,8 +115,8 @@ namespace OpenRA.Mods.Common.Widgets.Logic // Add an additional group for loose missions var looseMissions = modData.MapCache - .Where(p => p.Status == MapStatus.Available && p.Visibility.HasFlag(MapVisibility.MissionSelector) && !allMaps.Contains(p.Map)) - .Select(p => p.Map); + .Where(p => p.Status == MapStatus.Available && p.Visibility.HasFlag(MapVisibility.MissionSelector) && !allMaps.Any(m => m.Uid == p.Uid)) + .Select(p => new Map(p.Path)); if (looseMissions.Any()) { From 8b5592e1dd6d894b96ed148f726db3db9725c20b Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Fri, 5 Feb 2016 22:46:12 +0000 Subject: [PATCH 9/9] Reduce jank in the mission chooser. --- .../Widgets/Logic/MissionBrowserLogic.cs | 65 ++++++++++--------- 1 file changed, 36 insertions(+), 29 deletions(-) diff --git a/OpenRA.Mods.Common/Widgets/Logic/MissionBrowserLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/MissionBrowserLogic.cs index 34a19ea172..a7c3f78db4 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/MissionBrowserLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/MissionBrowserLogic.cs @@ -14,6 +14,7 @@ using System.IO; using System.Linq; using System.Threading; using OpenRA.Graphics; +using OpenRA.Primitives; using OpenRA.Widgets; namespace OpenRA.Mods.Common.Widgets.Logic @@ -38,6 +39,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic readonly ScrollPanelWidget missionList; readonly ScrollItemWidget headerTemplate; readonly ScrollItemWidget template; + readonly Cache mapCache = new Cache(p => new Map(p.Path)); MapPreview selectedMapPreview; Map selectedMap; @@ -90,7 +92,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic stopInfoVideoButton.IsVisible = () => playingVideo == PlayingVideo.Info; stopInfoVideoButton.OnClick = () => StopVideo(videoPlayer); - var allMaps = new List(); + var allPreviews = new List(); missionList.RemoveChildren(); // Add a group for each campaign @@ -103,29 +105,34 @@ namespace OpenRA.Mods.Common.Widgets.Logic { var missionMapPaths = kv.Value.Nodes.Select(n => Path.GetFullPath(n.Key)).ToList(); - var maps = modData.MapCache + var previews = modData.MapCache .Where(p => p.Status == MapStatus.Available && missionMapPaths.Contains(Path.GetFullPath(p.Path))) - .Select(p => new Map(p.Path)) - .OrderBy(m => missionMapPaths.IndexOf(Path.GetFullPath(m.Path))); + .OrderBy(p => missionMapPaths.IndexOf(Path.GetFullPath(p.Path))); - CreateMissionGroup(kv.Key, maps); - allMaps.AddRange(maps); + CreateMissionGroup(kv.Key, previews); + allPreviews.AddRange(previews); } } // Add an additional group for loose missions - var looseMissions = modData.MapCache - .Where(p => p.Status == MapStatus.Available && p.Visibility.HasFlag(MapVisibility.MissionSelector) && !allMaps.Any(m => m.Uid == p.Uid)) - .Select(p => new Map(p.Path)); + var loosePreviews = modData.MapCache + .Where(p => p.Status == MapStatus.Available && p.Visibility.HasFlag(MapVisibility.MissionSelector) && !allPreviews.Any(a => a.Uid == p.Uid)); - if (looseMissions.Any()) + if (loosePreviews.Any()) { - CreateMissionGroup("Missions", looseMissions); - allMaps.AddRange(looseMissions); + CreateMissionGroup("Missions", loosePreviews); + allPreviews.AddRange(loosePreviews); } - if (allMaps.Any()) - SelectMap(allMaps.First()); + if (allPreviews.Any()) + SelectMap(allPreviews.First()); + + // Preload map and preview data to reduce jank + new Thread(() => + { + foreach (var p in allPreviews) + modData.MapCache[mapCache[p].Uid].GetMinimap(); + }).Start(); var startButton = widget.Get("STARTGAME_BUTTON"); startButton.OnClick = StartMissionClicked; @@ -140,39 +147,39 @@ namespace OpenRA.Mods.Common.Widgets.Logic }; } - void CreateMissionGroup(string title, IEnumerable maps) + void CreateMissionGroup(string title, IEnumerable previews) { var header = ScrollItemWidget.Setup(headerTemplate, () => true, () => { }); header.Get("LABEL").GetText = () => title; missionList.AddChild(header); - foreach (var m in maps) + foreach (var p in previews) { - var map = m; + var preview = p; var item = ScrollItemWidget.Setup(template, - () => selectedMapPreview != null && selectedMapPreview.Uid == map.Uid, - () => SelectMap(map), + () => selectedMapPreview != null && selectedMapPreview.Uid == preview.Uid, + () => SelectMap(preview), StartMissionClicked); - item.Get("TITLE").GetText = () => map.Title; + item.Get("TITLE").GetText = () => preview.Title; missionList.AddChild(item); } } - void SelectMap(Map map) + void SelectMap(MapPreview preview) { - selectedMap = map; - selectedMapPreview = Game.ModData.MapCache[map.Uid]; + selectedMap = mapCache[preview]; + selectedMapPreview = preview; // Cache the rules on a background thread to avoid jank new Thread(() => selectedMap.PreloadRules()).Start(); - var briefingVideo = map.Videos.Briefing; + var briefingVideo = selectedMap.Videos.Briefing; var briefingVideoVisible = briefingVideo != null; var briefingVideoDisabled = !(briefingVideoVisible && Game.ModData.ModFiles.Exists(briefingVideo)); - var infoVideo = map.Videos.BackgroundInfo; + var infoVideo = selectedMap.Videos.BackgroundInfo; var infoVideoVisible = infoVideo != null; var infoVideoDisabled = !(infoVideoVisible && Game.ModData.ModFiles.Exists(infoVideo)); @@ -184,7 +191,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic startInfoVideoButton.IsDisabled = () => infoVideoDisabled || playingVideo != PlayingVideo.None; startInfoVideoButton.OnClick = () => PlayVideo(videoPlayer, infoVideo, PlayingVideo.Info, () => StopVideo(videoPlayer)); - var text = map.Description != null ? map.Description.Replace("\\n", "\n") : ""; + var text = selectedMap.Description != null ? selectedMap.Description.Replace("\\n", "\n") : ""; text = WidgetUtils.WrapText(text, description.Bounds.Width, descriptionFont); description.Text = text; description.Bounds.Height = descriptionFont.Measure(text).Y; @@ -193,13 +200,13 @@ namespace OpenRA.Mods.Common.Widgets.Logic if (difficultyButton != null) { - difficultyButton.IsDisabled = () => !map.Options.Difficulties.Any(); + difficultyButton.IsDisabled = () => !selectedMap.Options.Difficulties.Any(); - difficulty = map.Options.Difficulties.FirstOrDefault(); + difficulty = selectedMap.Options.Difficulties.FirstOrDefault(); difficultyButton.GetText = () => difficulty ?? "Normal"; difficultyButton.OnMouseDown = _ => { - var options = map.Options.Difficulties.Select(d => new DropDownOption + var options = selectedMap.Options.Difficulties.Select(d => new DropDownOption { Title = d, IsSelected = () => difficulty == d,