Merge pull request #10697 from pchote/map-cleanup-part-2

Remove Map references from MapPreview.
This commit is contained in:
Oliver Brakmann
2016-02-07 15:47:37 +01:00
14 changed files with 158 additions and 158 deletions

View File

@@ -445,7 +445,7 @@ namespace OpenRA
static string ChooseShellmap() static string ChooseShellmap()
{ {
var shellmaps = ModData.MapCache 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); .Select(m => m.Uid);
if (!shellmaps.Any()) if (!shellmaps.Any())

View File

@@ -174,7 +174,8 @@ namespace OpenRA
if (bitmap == null) if (bitmap == null)
{ {
createdPreview = true; 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(() => Game.RunAfterTick(() =>

View File

@@ -57,6 +57,8 @@ namespace OpenRA
MapCache cache; MapCache cache;
public readonly string Uid; public readonly string Uid;
public string Path { get; private set; }
public string Title { get; private set; } public string Title { get; private set; }
public string Type { get; private set; } public string Type { get; private set; }
public string Author { get; private set; } public string Author { get; private set; }
@@ -65,13 +67,11 @@ namespace OpenRA
public MapGridType GridType { get; private set; } public MapGridType GridType { get; private set; }
public Rectangle Bounds { get; private set; } public Rectangle Bounds { get; private set; }
public Bitmap CustomPreview { get; private set; } public Bitmap CustomPreview { get; private set; }
public Map Map { get; private set; }
public MapStatus Status { get; private set; } public MapStatus Status { get; private set; }
public MapClassification Class { get; private set; } public MapClassification Class { get; private set; }
public MapVisibility Visibility { get; private set; }
public bool SuitableForInitialMap { get; private set; } public bool SuitableForInitialMap { get; private set; }
public MapRuleStatus RuleStatus { get; private set; }
Download download; Download download;
public long DownloadBytes { get; private set; } public long DownloadBytes { get; private set; }
public int DownloadPercentage { get; private set; } public int DownloadPercentage { get; private set; }
@@ -111,11 +111,12 @@ namespace OpenRA
GridType = gridType; GridType = gridType;
Status = MapStatus.Unavailable; Status = MapStatus.Unavailable;
Class = MapClassification.Unknown; Class = MapClassification.Unknown;
Visibility = MapVisibility.Lobby;
} }
public void UpdateFromMap(Map m, MapClassification classification) public void UpdateFromMap(Map m, MapClassification classification)
{ {
Map = m; Path = m.Path;
Title = m.Title; Title = m.Title;
Type = m.Type; Type = m.Type;
Type = m.Type; Type = m.Type;
@@ -126,6 +127,7 @@ namespace OpenRA
CustomPreview = m.CustomPreview; CustomPreview = m.CustomPreview;
Status = MapStatus.Available; Status = MapStatus.Available;
Class = classification; Class = classification;
Visibility = m.Visibility;
var players = new MapPlayers(m.PlayerDefinitions).Players; var players = new MapPlayers(m.PlayerDefinitions).Players;
PlayerCount = players.Count(x => x.Value.Playable); PlayerCount = players.Count(x => x.Value.Playable);
@@ -135,7 +137,7 @@ namespace OpenRA
bool EvaluateUserFriendliness(Dictionary<string, PlayerReference> players) bool EvaluateUserFriendliness(Dictionary<string, PlayerReference> players)
{ {
if (Status != MapStatus.Available || !Map.Visibility.HasFlag(MapVisibility.Lobby)) if (Status != MapStatus.Available || !Visibility.HasFlag(MapVisibility.Lobby))
return false; return false;
// Other map types may have confusing settings or gameplay // Other map types may have confusing settings or gameplay
@@ -168,7 +170,6 @@ namespace OpenRA
if (!r.downloading) if (!r.downloading)
{ {
Status = MapStatus.Unavailable; Status = MapStatus.Unavailable;
RuleStatus = MapRuleStatus.Invalid;
return; return;
} }
@@ -228,7 +229,7 @@ namespace OpenRA
return; 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<DownloadProgressChangedEventArgs> onDownloadProgress = i => { DownloadBytes = i.BytesReceived; DownloadPercentage = i.ProgressPercentage; }; Action<DownloadProgressChangedEventArgs> onDownloadProgress = i => { DownloadBytes = i.BytesReceived; DownloadPercentage = i.ProgressPercentage; };
@@ -246,11 +247,7 @@ namespace OpenRA
} }
Log.Write("debug", "Downloaded map to '{0}'", mapPath); Log.Write("debug", "Downloaded map to '{0}'", mapPath);
Game.RunAfterTick(() => Game.RunAfterTick(() => UpdateFromMap(new Map(mapPath), MapClassification.User));
{
UpdateFromMap(new Map(mapPath), MapClassification.User);
CacheRules();
});
}; };
download = new Download(mapUrl, mapPath, onDownloadProgress, onDownloadComplete); download = new Download(mapUrl, mapPath, onDownloadProgress, onDownloadComplete);
@@ -272,19 +269,9 @@ namespace OpenRA
download = null; download = null;
} }
public void CacheRules()
{
if (RuleStatus != MapRuleStatus.Unknown)
return;
Map.PreloadRules();
RuleStatus = Map.InvalidCustomRules ? MapRuleStatus.Invalid : MapRuleStatus.Cached;
}
public void Invalidate() public void Invalidate()
{ {
Status = MapStatus.Unavailable; Status = MapStatus.Unavailable;
RuleStatus = MapRuleStatus.Unknown;
} }
} }
} }

View File

@@ -166,7 +166,7 @@ namespace OpenRA
throw new InvalidDataException("Invalid map uid: {0}".F(uid)); throw new InvalidDataException("Invalid map uid: {0}".F(uid));
// Operate on a copy of the map to avoid gameplay state leaking into the cache // 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); LoadTranslations(map);

View File

@@ -255,7 +255,7 @@ namespace OpenRA.Widgets
if (string.IsNullOrEmpty(initialUid) || Game.ModData.MapCache[initialUid].Status != MapStatus.Available) if (string.IsNullOrEmpty(initialUid) || Game.ModData.MapCache[initialUid].Status != MapStatus.Available)
{ {
var selected = Game.ModData.MapCache.Where(x => x.SuitableForInitialMap).RandomOrDefault(Game.CosmeticRandom) ?? 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; return selected.Uid;
} }

View File

@@ -926,7 +926,7 @@ namespace OpenRA.Mods.Common.Server
static void LoadMap(S 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.MapPlayers = new MapPlayers(server.Map.PlayerDefinitions);
server.LobbyInfo.Slots = server.MapPlayers.Players server.LobbyInfo.Slots = server.MapPlayers.Players

View File

@@ -78,7 +78,7 @@ namespace OpenRA.Mods.Common.UtilityCommands
Game.ModData.MapCache.LoadMaps(); Game.ModData.MapCache.LoadMaps();
maps.AddRange(Game.ModData.MapCache maps.AddRange(Game.ModData.MapCache
.Where(m => m.Status == MapStatus.Available) .Where(m => m.Status == MapStatus.Available)
.Select(m => m.Map)); .Select(m => new Map(m.Path)));
} }
else else
maps.Add(new Map(args[1])); maps.Add(new Map(args[1]));

View File

@@ -101,7 +101,7 @@ namespace OpenRA.Mods.Common.UtilityCommands
Console.WriteLine("Processing Maps:"); Console.WriteLine("Processing Maps:");
var maps = Game.ModData.MapCache var maps = Game.ModData.MapCache
.Where(m => m.Status == MapStatus.Available) .Where(m => m.Status == MapStatus.Available)
.Select(m => m.Map); .Select(m => new Map(m.Path));
foreach (var map in maps) foreach (var map in maps)
{ {

View File

@@ -26,7 +26,8 @@ namespace OpenRA.Mods.Common.Widgets.Logic
{ {
static readonly Action DoNothing = () => { }; static readonly Action DoNothing = () => { };
public MapPreview Map = MapCache.UnknownMap; public MapPreview MapPreview { get; private set; }
public Map Map { get; private set; }
readonly Action onStart; readonly Action onStart;
readonly Action onExit; readonly Action onExit;
@@ -111,6 +112,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
internal LobbyLogic(Widget widget, WorldRenderer worldRenderer, OrderManager orderManager, internal LobbyLogic(Widget widget, WorldRenderer worldRenderer, OrderManager orderManager,
Action onExit, Action onStart, bool skirmishMode, Ruleset modRules) Action onExit, Action onStart, bool skirmishMode, Ruleset modRules)
{ {
MapPreview = MapCache.UnknownMap;
lobby = widget; lobby = widget;
this.orderManager = orderManager; this.orderManager = orderManager;
this.onStart = onStart; this.onStart = onStart;
@@ -156,6 +158,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
var gameStarting = false; var gameStarting = false;
Func<bool> configurationDisabled = () => !Game.IsHost || gameStarting || Func<bool> configurationDisabled = () => !Game.IsHost || gameStarting ||
panel == PanelType.Kick || panel == PanelType.ForceStart || panel == PanelType.Kick || panel == PanelType.ForceStart ||
Map == null || Map.InvalidCustomRules ||
orderManager.LocalClient == null || orderManager.LocalClient.IsReady; orderManager.LocalClient == null || orderManager.LocalClient.IsReady;
var mapButton = lobby.GetOrNull<ButtonWidget>("CHANGEMAP_BUTTON"); var mapButton = lobby.GetOrNull<ButtonWidget>("CHANGEMAP_BUTTON");
@@ -168,7 +171,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
var onSelect = new Action<string>(uid => var onSelect = new Action<string>(uid =>
{ {
// Don't select the same map again // Don't select the same map again
if (uid == Map.Uid) if (uid == MapPreview.Uid)
return; return;
orderManager.IssueOrder(Order.Command("map " + uid)); orderManager.IssueOrder(Order.Command("map " + uid));
@@ -178,7 +181,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
Ui.OpenWindow("MAPCHOOSER_PANEL", new WidgetArgs() Ui.OpenWindow("MAPCHOOSER_PANEL", new WidgetArgs()
{ {
{ "initialMap", Map.Uid }, { "initialMap", MapPreview.Uid },
{ "initialTab", MapClassification.System }, { "initialTab", MapClassification.System },
{ "onExit", DoNothing }, { "onExit", DoNothing },
{ "onSelect", Game.IsHost ? onSelect : null }, { "onSelect", Game.IsHost ? onSelect : null },
@@ -190,7 +193,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
var slotsButton = lobby.GetOrNull<DropDownButtonWidget>("SLOTS_DROPDOWNBUTTON"); var slotsButton = lobby.GetOrNull<DropDownButtonWidget>("SLOTS_DROPDOWNBUTTON");
if (slotsButton != null) if (slotsButton != null)
{ {
slotsButton.IsDisabled = () => configurationDisabled() || panel != PanelType.Players || Map.RuleStatus != MapRuleStatus.Cached || slotsButton.IsDisabled = () => configurationDisabled() || panel != PanelType.Players ||
(orderManager.LobbyInfo.Slots.Values.All(s => !s.AllowBots) && (orderManager.LobbyInfo.Slots.Values.All(s => !s.AllowBots) &&
orderManager.LobbyInfo.Slots.Count(s => !s.Value.LockTeam && orderManager.LobbyInfo.ClientInSlot(s.Key) != null) == 0); 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<ButtonWidget>("OPTIONS_TAB"); var optionsTab = lobby.Get<ButtonWidget>("OPTIONS_TAB");
optionsTab.IsHighlighted = () => panel == PanelType.Options; optionsTab.IsHighlighted = () => panel == PanelType.Options;
optionsTab.IsDisabled = () => Map.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; optionsTab.OnClick = () => panel = PanelType.Options;
var playersTab = lobby.Get<ButtonWidget>("PLAYERS_TAB"); var playersTab = lobby.Get<ButtonWidget>("PLAYERS_TAB");
@@ -317,9 +320,10 @@ namespace OpenRA.Mods.Common.Widgets.Logic
var startGameButton = lobby.GetOrNull<ButtonWidget>("START_GAME_BUTTON"); var startGameButton = lobby.GetOrNull<ButtonWidget>("START_GAME_BUTTON");
if (startGameButton != null) if (startGameButton != null)
{ {
startGameButton.IsDisabled = () => configurationDisabled() || Map.RuleStatus != MapRuleStatus.Cached || startGameButton.IsDisabled = () => configurationDisabled() ||
orderManager.LobbyInfo.Slots.Any(sl => sl.Value.Required && orderManager.LobbyInfo.ClientInSlot(sl.Key) == null) || orderManager.LobbyInfo.Slots.Any(sl => sl.Value.Required && orderManager.LobbyInfo.ClientInSlot(sl.Key) == null) ||
(orderManager.LobbyInfo.GlobalSettings.DisableSingleplayer && orderManager.LobbyInfo.IsSinglePlayer); (orderManager.LobbyInfo.GlobalSettings.DisableSingleplayer && orderManager.LobbyInfo.IsSinglePlayer);
startGameButton.OnClick = () => startGameButton.OnClick = () =>
{ {
// Bots and admins don't count // Bots and admins don't count
@@ -341,7 +345,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
if (allowCheats != null) if (allowCheats != null)
{ {
allowCheats.IsChecked = () => orderManager.LobbyInfo.GlobalSettings.AllowCheats; allowCheats.IsChecked = () => orderManager.LobbyInfo.GlobalSettings.AllowCheats;
allowCheats.IsDisabled = () => Map.Status != MapStatus.Available || Map.Map.Options.Cheats.HasValue || configurationDisabled(); allowCheats.IsDisabled = () => configurationDisabled() || Map.Options.Cheats.HasValue;
allowCheats.OnClick = () => orderManager.IssueOrder(Order.Command( allowCheats.OnClick = () => orderManager.IssueOrder(Order.Command(
"allowcheats {0}".F(!orderManager.LobbyInfo.GlobalSettings.AllowCheats))); "allowcheats {0}".F(!orderManager.LobbyInfo.GlobalSettings.AllowCheats)));
} }
@@ -350,7 +354,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
if (crates != null) if (crates != null)
{ {
crates.IsChecked = () => orderManager.LobbyInfo.GlobalSettings.Crates; crates.IsChecked = () => orderManager.LobbyInfo.GlobalSettings.Crates;
crates.IsDisabled = () => Map.Status != MapStatus.Available || Map.Map.Options.Crates.HasValue || configurationDisabled(); crates.IsDisabled = () => configurationDisabled() || Map.Options.Crates.HasValue;
crates.OnClick = () => orderManager.IssueOrder(Order.Command( crates.OnClick = () => orderManager.IssueOrder(Order.Command(
"crates {0}".F(!orderManager.LobbyInfo.GlobalSettings.Crates))); "crates {0}".F(!orderManager.LobbyInfo.GlobalSettings.Crates)));
} }
@@ -359,7 +363,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
if (creeps != null) if (creeps != null)
{ {
creeps.IsChecked = () => orderManager.LobbyInfo.GlobalSettings.Creeps; creeps.IsChecked = () => orderManager.LobbyInfo.GlobalSettings.Creeps;
creeps.IsDisabled = () => Map.Status != MapStatus.Available || Map.Map.Options.Creeps.HasValue || configurationDisabled(); creeps.IsDisabled = () => configurationDisabled() || Map.Options.Creeps.HasValue;
creeps.OnClick = () => orderManager.IssueOrder(Order.Command( creeps.OnClick = () => orderManager.IssueOrder(Order.Command(
"creeps {0}".F(!orderManager.LobbyInfo.GlobalSettings.Creeps))); "creeps {0}".F(!orderManager.LobbyInfo.GlobalSettings.Creeps)));
} }
@@ -368,7 +372,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
if (allybuildradius != null) if (allybuildradius != null)
{ {
allybuildradius.IsChecked = () => orderManager.LobbyInfo.GlobalSettings.AllyBuildRadius; allybuildradius.IsChecked = () => orderManager.LobbyInfo.GlobalSettings.AllyBuildRadius;
allybuildradius.IsDisabled = () => Map.Status != MapStatus.Available || Map.Map.Options.AllyBuildRadius.HasValue || configurationDisabled(); allybuildradius.IsDisabled = () => configurationDisabled() || Map.Options.AllyBuildRadius.HasValue;
allybuildradius.OnClick = () => orderManager.IssueOrder(Order.Command( allybuildradius.OnClick = () => orderManager.IssueOrder(Order.Command(
"allybuildradius {0}".F(!orderManager.LobbyInfo.GlobalSettings.AllyBuildRadius))); "allybuildradius {0}".F(!orderManager.LobbyInfo.GlobalSettings.AllyBuildRadius)));
} }
@@ -377,7 +381,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
if (shortGame != null) if (shortGame != null)
{ {
shortGame.IsChecked = () => orderManager.LobbyInfo.GlobalSettings.ShortGame; shortGame.IsChecked = () => orderManager.LobbyInfo.GlobalSettings.ShortGame;
shortGame.IsDisabled = () => Map.Status != MapStatus.Available || Map.Map.Options.ShortGame.HasValue || configurationDisabled(); shortGame.IsDisabled = () => configurationDisabled() || Map.Options.ShortGame.HasValue;
shortGame.OnClick = () => orderManager.IssueOrder(Order.Command( shortGame.OnClick = () => orderManager.IssueOrder(Order.Command(
"shortgame {0}".F(!orderManager.LobbyInfo.GlobalSettings.ShortGame))); "shortgame {0}".F(!orderManager.LobbyInfo.GlobalSettings.ShortGame)));
} }
@@ -385,12 +389,12 @@ namespace OpenRA.Mods.Common.Widgets.Logic
var difficulty = optionsBin.GetOrNull<DropDownButtonWidget>("DIFFICULTY_DROPDOWNBUTTON"); var difficulty = optionsBin.GetOrNull<DropDownButtonWidget>("DIFFICULTY_DROPDOWNBUTTON");
if (difficulty != null) if (difficulty != null)
{ {
difficulty.IsVisible = () => Map.Status == MapStatus.Available && Map.Map.Options.Difficulties.Any(); difficulty.IsVisible = () => Map != null && Map.Options.Difficulties.Any();
difficulty.IsDisabled = () => Map.Status != MapStatus.Available || configurationDisabled(); difficulty.IsDisabled = configurationDisabled;
difficulty.GetText = () => orderManager.LobbyInfo.GlobalSettings.Difficulty; difficulty.GetText = () => orderManager.LobbyInfo.GlobalSettings.Difficulty;
difficulty.OnMouseDown = _ => difficulty.OnMouseDown = _ =>
{ {
var options = Map.Map.Options.Difficulties.Select(d => new DropDownOption var options = Map.Options.Difficulties.Select(d => new DropDownOption
{ {
Title = d, Title = d,
IsSelected = () => orderManager.LobbyInfo.GlobalSettings.Difficulty == d, IsSelected = () => orderManager.LobbyInfo.GlobalSettings.Difficulty == d,
@@ -419,10 +423,9 @@ namespace OpenRA.Mods.Common.Widgets.Logic
return selectedClass != null ? selectedClass : c; return selectedClass != null ? selectedClass : c;
}; };
startingUnits.IsDisabled = () => Map.Status != MapStatus.Available || startingUnits.IsDisabled = () => configurationDisabled() || !Map.Options.ConfigurableStartingUnits;
!Map.Map.Options.ConfigurableStartingUnits || configurationDisabled(); startingUnits.GetText = () => MapPreview.Status != MapStatus.Available ||
startingUnits.GetText = () => Map.Status != MapStatus.Available || Map == null || !Map.Options.ConfigurableStartingUnits ? "Not Available" : className(orderManager.LobbyInfo.GlobalSettings.StartingUnitsClass);
!Map.Map.Options.ConfigurableStartingUnits ? "Not Available" : className(orderManager.LobbyInfo.GlobalSettings.StartingUnitsClass);
startingUnits.OnMouseDown = _ => startingUnits.OnMouseDown = _ =>
{ {
var options = classes.Select(c => new DropDownOption var options = classes.Select(c => new DropDownOption
@@ -448,10 +451,9 @@ namespace OpenRA.Mods.Common.Widgets.Logic
var startingCash = optionsBin.GetOrNull<DropDownButtonWidget>("STARTINGCASH_DROPDOWNBUTTON"); var startingCash = optionsBin.GetOrNull<DropDownButtonWidget>("STARTINGCASH_DROPDOWNBUTTON");
if (startingCash != null) if (startingCash != null)
{ {
startingCash.IsDisabled = () => Map.Status != MapStatus.Available || startingCash.IsDisabled = () => configurationDisabled() || Map.Options.StartingCash.HasValue;
Map.Map.Options.StartingCash.HasValue || configurationDisabled(); startingCash.GetText = () => MapPreview.Status != MapStatus.Available ||
startingCash.GetText = () => Map.Status != MapStatus.Available || Map == null || Map.Options.StartingCash.HasValue ? "Not Available" : "${0}".F(orderManager.LobbyInfo.GlobalSettings.StartingCash);
Map.Map.Options.StartingCash.HasValue ? "Not Available" : "${0}".F(orderManager.LobbyInfo.GlobalSettings.StartingCash);
startingCash.OnMouseDown = _ => startingCash.OnMouseDown = _ =>
{ {
var options = modRules.Actors["player"].TraitInfo<PlayerResourcesInfo>().SelectableCash.Select(c => new DropDownOption var options = modRules.Actors["player"].TraitInfo<PlayerResourcesInfo>().SelectableCash.Select(c => new DropDownOption
@@ -482,10 +484,9 @@ namespace OpenRA.Mods.Common.Widgets.Logic
if (techLevelDescription != null) if (techLevelDescription != null)
techLevelDescription.IsVisible = () => techTraits.Count > 0; techLevelDescription.IsVisible = () => techTraits.Count > 0;
techLevel.IsDisabled = () => Map.Status != MapStatus.Available || techLevel.IsDisabled = () => configurationDisabled() || Map.Options.TechLevel != null || techTraits.Count <= 1;
Map.Map.Options.TechLevel != null || configurationDisabled() || techTraits.Count <= 1; techLevel.GetText = () => MapPreview.Status != MapStatus.Available ||
techLevel.GetText = () => Map.Status != MapStatus.Available || Map == null || Map.Options.TechLevel != null ? "Not Available" : "{0}".F(orderManager.LobbyInfo.GlobalSettings.TechLevel);
Map.Map.Options.TechLevel != null ? "Not Available" : "{0}".F(orderManager.LobbyInfo.GlobalSettings.TechLevel);
techLevel.OnMouseDown = _ => techLevel.OnMouseDown = _ =>
{ {
var options = techTraits.Select(c => new DropDownOption var options = techTraits.Select(c => new DropDownOption
@@ -511,10 +512,10 @@ namespace OpenRA.Mods.Common.Widgets.Logic
{ {
var speeds = Game.ModData.Manifest.Get<GameSpeeds>().Speeds; var speeds = Game.ModData.Manifest.Get<GameSpeeds>().Speeds;
gameSpeed.IsDisabled = () => Map.Status != MapStatus.Available || configurationDisabled(); gameSpeed.IsDisabled = configurationDisabled;
gameSpeed.GetText = () => gameSpeed.GetText = () =>
{ {
if (Map.Status != MapStatus.Available) if (MapPreview.Status != MapStatus.Available)
return "Not Available"; return "Not Available";
GameSpeed speed; GameSpeed speed;
@@ -548,7 +549,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
if (exploredMap != null) if (exploredMap != null)
{ {
exploredMap.IsChecked = () => !orderManager.LobbyInfo.GlobalSettings.Shroud; exploredMap.IsChecked = () => !orderManager.LobbyInfo.GlobalSettings.Shroud;
exploredMap.IsDisabled = () => Map.Status != MapStatus.Available || Map.Map.Options.Shroud.HasValue || configurationDisabled(); exploredMap.IsDisabled = () => configurationDisabled() || Map.Options.Shroud.HasValue;
exploredMap.OnClick = () => orderManager.IssueOrder(Order.Command( exploredMap.OnClick = () => orderManager.IssueOrder(Order.Command(
"shroud {0}".F(!orderManager.LobbyInfo.GlobalSettings.Shroud))); "shroud {0}".F(!orderManager.LobbyInfo.GlobalSettings.Shroud)));
} }
@@ -557,7 +558,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
if (enableFog != null) if (enableFog != null)
{ {
enableFog.IsChecked = () => orderManager.LobbyInfo.GlobalSettings.Fog; enableFog.IsChecked = () => orderManager.LobbyInfo.GlobalSettings.Fog;
enableFog.IsDisabled = () => Map.Status != MapStatus.Available || Map.Map.Options.Fog.HasValue || configurationDisabled(); enableFog.IsDisabled = () => configurationDisabled() || Map.Options.Fog.HasValue;
enableFog.OnClick = () => orderManager.IssueOrder(Order.Command( enableFog.OnClick = () => orderManager.IssueOrder(Order.Command(
"fog {0}".F(!orderManager.LobbyInfo.GlobalSettings.Fog))); "fog {0}".F(!orderManager.LobbyInfo.GlobalSettings.Fog)));
} }
@@ -733,31 +734,32 @@ namespace OpenRA.Mods.Common.Widgets.Logic
void UpdateCurrentMap() void UpdateCurrentMap()
{ {
var uid = orderManager.LobbyInfo.GlobalSettings.Map; var uid = orderManager.LobbyInfo.GlobalSettings.Map;
if (Map.Uid == uid) if (MapPreview.Uid == uid)
return; return;
Map = Game.ModData.MapCache[uid]; MapPreview = Game.ModData.MapCache[uid];
if (Map.Status == MapStatus.Available) Map = null;
if (MapPreview.Status == MapStatus.Available)
{ {
// Maps need to be validated and pre-loaded before they can be accessed // Maps need to be validated and pre-loaded before they can be accessed
new Thread(_ => new Thread(_ =>
{ {
var map = Map; var currentMap = Map = new Map(MapPreview.Path);
map.CacheRules(); currentMap.PreloadRules();
Game.RunAfterTick(() => Game.RunAfterTick(() =>
{ {
// Map may have changed in the meantime // Map may have changed in the meantime
if (map != Map) if (currentMap != Map)
return; return;
if (map.RuleStatus != MapRuleStatus.Invalid) if (!currentMap.InvalidCustomRules)
{ {
// Tell the server that we have the map // Tell the server that we have the map
orderManager.IssueOrder(Order.Command("state {0}".F(Session.ClientState.NotReady))); orderManager.IssueOrder(Order.Command("state {0}".F(Session.ClientState.NotReady)));
// Restore default starting cash if the last map set it to something invalid // Restore default starting cash if the last map set it to something invalid
var pri = modRules.Actors["player"].TraitInfo<PlayerResourcesInfo>(); var pri = modRules.Actors["player"].TraitInfo<PlayerResourcesInfo>();
if (!Map.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))); orderManager.IssueOrder(Order.Command("startingcash {0}".F(pri.DefaultCash)));
} }
}); });
@@ -816,9 +818,9 @@ namespace OpenRA.Mods.Common.Widgets.Logic
LobbyUtils.SetupEditableColorWidget(template, slot, client, orderManager, shellmapWorld, colorPreview); LobbyUtils.SetupEditableColorWidget(template, slot, client, orderManager, shellmapWorld, colorPreview);
LobbyUtils.SetupEditableFactionWidget(template, slot, client, orderManager, factions); LobbyUtils.SetupEditableFactionWidget(template, slot, client, orderManager, factions);
LobbyUtils.SetupEditableTeamWidget(template, slot, client, orderManager, Map); LobbyUtils.SetupEditableTeamWidget(template, slot, client, orderManager, MapPreview);
LobbyUtils.SetupEditableSpawnWidget(template, slot, client, orderManager, Map); LobbyUtils.SetupEditableSpawnWidget(template, slot, client, orderManager, MapPreview);
LobbyUtils.SetupEditableReadyWidget(template, slot, client, orderManager, Map); LobbyUtils.SetupEditableReadyWidget(template, slot, client, orderManager, MapPreview, Map == null || Map.InvalidCustomRules);
} }
else else
{ {

View File

@@ -25,79 +25,80 @@ namespace OpenRA.Mods.Common.Widgets.Logic
var available = widget.GetOrNull("MAP_AVAILABLE"); var available = widget.GetOrNull("MAP_AVAILABLE");
if (available != null) if (available != null)
{ {
available.IsVisible = () => lobby.Map.Status == MapStatus.Available && lobby.Map.RuleStatus == MapRuleStatus.Cached; available.IsVisible = () => lobby.MapPreview.Status == MapStatus.Available && (lobby.Map == null || !lobby.Map.InvalidCustomRules);
var preview = available.Get<MapPreviewWidget>("MAP_PREVIEW"); var preview = available.Get<MapPreviewWidget>("MAP_PREVIEW");
preview.Preview = () => lobby.Map; preview.Preview = () => lobby.MapPreview;
preview.OnMouseDown = mi => LobbyUtils.SelectSpawnPoint(orderManager, preview, lobby.Map, mi); preview.OnMouseDown = mi => LobbyUtils.SelectSpawnPoint(orderManager, preview, lobby.MapPreview, mi);
preview.SpawnOccupants = () => LobbyUtils.GetSpawnOccupants(orderManager.LobbyInfo, lobby.Map); preview.SpawnOccupants = () => LobbyUtils.GetSpawnOccupants(orderManager.LobbyInfo, lobby.MapPreview);
var titleLabel = available.GetOrNull<LabelWidget>("MAP_TITLE"); var titleLabel = available.GetOrNull<LabelWidget>("MAP_TITLE");
if (titleLabel != null) if (titleLabel != null)
{ {
var font = Game.Renderer.Fonts[titleLabel.Font]; var font = Game.Renderer.Fonts[titleLabel.Font];
var title = new CachedTransform<MapPreview, string>(m => WidgetUtils.TruncateText(m.Title, titleLabel.Bounds.Width, font)); var title = new CachedTransform<MapPreview, string>(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<LabelWidget>("MAP_TYPE"); var typeLabel = available.GetOrNull<LabelWidget>("MAP_TYPE");
if (typeLabel != null) if (typeLabel != null)
typeLabel.GetText = () => lobby.Map.Type; typeLabel.GetText = () => lobby.MapPreview.Type;
var authorLabel = available.GetOrNull<LabelWidget>("MAP_AUTHOR"); var authorLabel = available.GetOrNull<LabelWidget>("MAP_AUTHOR");
if (authorLabel != null) if (authorLabel != null)
{ {
var font = Game.Renderer.Fonts[authorLabel.Font]; var font = Game.Renderer.Fonts[authorLabel.Font];
var author = new CachedTransform<MapPreview, string>(m => WidgetUtils.TruncateText("Created by {0}".F(lobby.Map.Author), authorLabel.Bounds.Width, font)); var author = new CachedTransform<MapPreview, string>(
authorLabel.GetText = () => author.Update(lobby.Map); 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"); var invalid = widget.GetOrNull("MAP_INVALID");
if (invalid != null) if (invalid != null)
{ {
invalid.IsVisible = () => lobby.Map.Status == MapStatus.Available && lobby.Map.RuleStatus == MapRuleStatus.Invalid; invalid.IsVisible = () => lobby.MapPreview.Status == MapStatus.Available && lobby.Map != null && lobby.Map.InvalidCustomRules;
var preview = invalid.Get<MapPreviewWidget>("MAP_PREVIEW"); var preview = invalid.Get<MapPreviewWidget>("MAP_PREVIEW");
preview.Preview = () => lobby.Map; preview.Preview = () => lobby.MapPreview;
preview.OnMouseDown = mi => LobbyUtils.SelectSpawnPoint(orderManager, preview, lobby.Map, mi); preview.OnMouseDown = mi => LobbyUtils.SelectSpawnPoint(orderManager, preview, lobby.MapPreview, mi);
preview.SpawnOccupants = () => LobbyUtils.GetSpawnOccupants(orderManager.LobbyInfo, lobby.Map); preview.SpawnOccupants = () => LobbyUtils.GetSpawnOccupants(orderManager.LobbyInfo, lobby.MapPreview);
var title = invalid.GetOrNull<LabelWidget>("MAP_TITLE"); var title = invalid.GetOrNull<LabelWidget>("MAP_TITLE");
if (title != null) if (title != null)
title.GetText = () => lobby.Map.Title; title.GetText = () => lobby.MapPreview.Title;
var type = invalid.GetOrNull<LabelWidget>("MAP_TYPE"); var type = invalid.GetOrNull<LabelWidget>("MAP_TYPE");
if (type != null) if (type != null)
type.GetText = () => lobby.Map.Type; type.GetText = () => lobby.MapPreview.Type;
} }
var download = widget.GetOrNull("MAP_DOWNLOADABLE"); var download = widget.GetOrNull("MAP_DOWNLOADABLE");
if (download != null) if (download != null)
{ {
download.IsVisible = () => lobby.Map.Status == MapStatus.DownloadAvailable; download.IsVisible = () => lobby.MapPreview.Status == MapStatus.DownloadAvailable;
var preview = download.Get<MapPreviewWidget>("MAP_PREVIEW"); var preview = download.Get<MapPreviewWidget>("MAP_PREVIEW");
preview.Preview = () => lobby.Map; preview.Preview = () => lobby.MapPreview;
preview.OnMouseDown = mi => LobbyUtils.SelectSpawnPoint(orderManager, preview, lobby.Map, mi); preview.OnMouseDown = mi => LobbyUtils.SelectSpawnPoint(orderManager, preview, lobby.MapPreview, mi);
preview.SpawnOccupants = () => LobbyUtils.GetSpawnOccupants(orderManager.LobbyInfo, lobby.Map); preview.SpawnOccupants = () => LobbyUtils.GetSpawnOccupants(orderManager.LobbyInfo, lobby.MapPreview);
var title = download.GetOrNull<LabelWidget>("MAP_TITLE"); var title = download.GetOrNull<LabelWidget>("MAP_TITLE");
if (title != null) if (title != null)
title.GetText = () => lobby.Map.Title; title.GetText = () => lobby.MapPreview.Title;
var type = download.GetOrNull<LabelWidget>("MAP_TYPE"); var type = download.GetOrNull<LabelWidget>("MAP_TYPE");
if (type != null) if (type != null)
type.GetText = () => lobby.Map.Type; type.GetText = () => lobby.MapPreview.Type;
var author = download.GetOrNull<LabelWidget>("MAP_AUTHOR"); var author = download.GetOrNull<LabelWidget>("MAP_AUTHOR");
if (author != null) 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<ButtonWidget>("MAP_INSTALL"); var install = download.GetOrNull<ButtonWidget>("MAP_INSTALL");
if (install != null) if (install != null)
{ {
install.OnClick = () => lobby.Map.Install(); install.OnClick = () => lobby.MapPreview.Install();
install.IsHighlighted = () => installHighlighted; install.IsHighlighted = () => installHighlighted;
} }
} }
@@ -105,72 +106,72 @@ namespace OpenRA.Mods.Common.Widgets.Logic
var progress = widget.GetOrNull("MAP_PROGRESS"); var progress = widget.GetOrNull("MAP_PROGRESS");
if (progress != null) if (progress != null)
{ {
progress.IsVisible = () => progress.IsVisible = () => lobby.MapPreview.Status != MapStatus.Available &&
(lobby.Map.Status != MapStatus.Available || lobby.Map.RuleStatus == MapRuleStatus.Unknown) && lobby.MapPreview.Status != MapStatus.DownloadAvailable;
lobby.Map.Status != MapStatus.DownloadAvailable;
var preview = progress.Get<MapPreviewWidget>("MAP_PREVIEW"); var preview = progress.Get<MapPreviewWidget>("MAP_PREVIEW");
preview.Preview = () => lobby.Map; preview.Preview = () => lobby.MapPreview;
preview.OnMouseDown = mi => LobbyUtils.SelectSpawnPoint(orderManager, preview, lobby.Map, mi); preview.OnMouseDown = mi => LobbyUtils.SelectSpawnPoint(orderManager, preview, lobby.MapPreview, mi);
preview.SpawnOccupants = () => LobbyUtils.GetSpawnOccupants(orderManager.LobbyInfo, lobby.Map); preview.SpawnOccupants = () => LobbyUtils.GetSpawnOccupants(orderManager.LobbyInfo, lobby.MapPreview);
var title = progress.GetOrNull<LabelWidget>("MAP_TITLE"); var title = progress.GetOrNull<LabelWidget>("MAP_TITLE");
if (title != null) if (title != null)
title.GetText = () => lobby.Map.Title; title.GetText = () => lobby.MapPreview.Title;
var type = progress.GetOrNull<LabelWidget>("MAP_TYPE"); var type = progress.GetOrNull<LabelWidget>("MAP_TYPE");
if (type != null) if (type != null)
type.GetText = () => lobby.Map.Type; type.GetText = () => lobby.MapPreview.Type;
var statusSearching = progress.GetOrNull("MAP_STATUS_SEARCHING"); var statusSearching = progress.GetOrNull("MAP_STATUS_SEARCHING");
if (statusSearching != null) if (statusSearching != null)
statusSearching.IsVisible = () => lobby.Map.Status == MapStatus.Searching; statusSearching.IsVisible = () => lobby.MapPreview.Status == MapStatus.Searching;
var statusUnavailable = progress.GetOrNull("MAP_STATUS_UNAVAILABLE"); var statusUnavailable = progress.GetOrNull("MAP_STATUS_UNAVAILABLE");
if (statusUnavailable != null) if (statusUnavailable != null)
statusUnavailable.IsVisible = () => lobby.Map.Status == MapStatus.Unavailable; statusUnavailable.IsVisible = () => lobby.MapPreview.Status == MapStatus.Unavailable;
var statusError = progress.GetOrNull("MAP_STATUS_ERROR"); var statusError = progress.GetOrNull("MAP_STATUS_ERROR");
if (statusError != null) if (statusError != null)
statusError.IsVisible = () => lobby.Map.Status == MapStatus.DownloadError; statusError.IsVisible = () => lobby.MapPreview.Status == MapStatus.DownloadError;
var statusDownloading = progress.GetOrNull<LabelWidget>("MAP_STATUS_DOWNLOADING"); var statusDownloading = progress.GetOrNull<LabelWidget>("MAP_STATUS_DOWNLOADING");
if (statusDownloading != null) if (statusDownloading != null)
{ {
statusDownloading.IsVisible = () => lobby.Map.Status == MapStatus.Downloading; statusDownloading.IsVisible = () => lobby.MapPreview.Status == MapStatus.Downloading;
statusDownloading.GetText = () => statusDownloading.GetText = () =>
{ {
if (lobby.Map.DownloadBytes == 0) if (lobby.MapPreview.DownloadBytes == 0)
return "Connecting..."; return "Connecting...";
// Server does not provide the total file length // Server does not provide the total file length
if (lobby.Map.DownloadPercentage == 0) if (lobby.MapPreview.DownloadPercentage == 0)
return "Downloading {0} kB".F(lobby.Map.DownloadBytes / 1024); 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<ButtonWidget>("MAP_RETRY"); var retry = progress.GetOrNull<ButtonWidget>("MAP_RETRY");
if (retry != null) 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 = () => retry.OnClick = () =>
{ {
if (lobby.Map.Status == MapStatus.DownloadError) if (lobby.MapPreview.Status == MapStatus.DownloadError)
lobby.Map.Install(); lobby.MapPreview.Install();
else if (lobby.Map.Status == MapStatus.Unavailable) else if (lobby.MapPreview.Status == MapStatus.Unavailable)
Game.ModData.MapCache.QueryRemoteMapDetails(new[] { lobby.Map.Uid }); 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<ProgressBarWidget>("MAP_PROGRESSBAR"); var progressbar = progress.GetOrNull<ProgressBarWidget>("MAP_PROGRESSBAR");
if (progressbar != null) if (progressbar != null)
{ {
progressbar.IsIndeterminate = () => lobby.Map.DownloadPercentage == 0; progressbar.IsIndeterminate = () => lobby.MapPreview.DownloadPercentage == 0;
progressbar.GetPercentage = () => lobby.Map.DownloadPercentage; progressbar.GetPercentage = () => lobby.MapPreview.DownloadPercentage;
progressbar.IsVisible = () => !retry.IsVisible(); progressbar.IsVisible = () => !retry.IsVisible();
} }
} }

View File

@@ -455,12 +455,12 @@ namespace OpenRA.Mods.Common.Widgets.Logic
parent.Get<LabelWidget>("SPAWN").GetText = () => (c.SpawnPoint == 0) ? "-" : Convert.ToChar('A' - 1 + c.SpawnPoint).ToString(); parent.Get<LabelWidget>("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<CheckboxWidget>("STATUS_CHECKBOX"); var status = parent.Get<CheckboxWidget>("STATUS_CHECKBOX");
status.IsChecked = () => orderManager.LocalClient.IsReady || c.Bot != null; status.IsChecked = () => orderManager.LocalClient.IsReady || c.Bot != null;
status.IsVisible = () => true; 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; var state = orderManager.LocalClient.IsReady ? Session.ClientState.NotReady : Session.ClientState.Ready;
status.OnClick = () => orderManager.IssueOrder(Order.Command("state {0}".F(state))); status.OnClick = () => orderManager.IssueOrder(Order.Command("state {0}".F(state)));

View File

@@ -104,7 +104,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
var hasCampaign = Game.ModData.Manifest.Missions.Any(); var hasCampaign = Game.ModData.Manifest.Missions.Any();
var hasMissions = Game.ModData.MapCache 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; missionsButton.Disabled = !hasCampaign && !hasMissions;
@@ -167,7 +167,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
var onSelect = new Action<string>(uid => var onSelect = new Action<string>(uid =>
{ {
RemoveShellmapUI(); RemoveShellmapUI();
LoadMapIntoEditor(Game.ModData.MapCache[uid].Map); LoadMapIntoEditor(Game.ModData.MapCache[uid].Uid);
}); });
var newMapButton = widget.Get<ButtonWidget>("NEW_MAP_BUTTON"); var newMapButton = widget.Get<ButtonWidget>("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(), ConnectionLogic.Connect(IPAddress.Loopback.ToString(),
Game.CreateLocalServer(map.Uid), Game.CreateLocalServer(uid),
"", "",
() => { Game.LoadEditor(map.Uid); }, () => { Game.LoadEditor(uid); },
() => { Game.CloseServer(); SwitchMenu(MenuType.MapEditor); }); () => { Game.CloseServer(); SwitchMenu(MenuType.MapEditor); });
} }

View File

@@ -143,7 +143,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
void RefreshMaps(MapClassification tab, MapVisibility filter) void RefreshMaps(MapClassification tab, MapVisibility filter)
{ {
tabMaps[tab] = Game.ModData.MapCache.Where(m => m.Status == MapStatus.Available && 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) void SetupMapTab(MapClassification tab, MapVisibility filter, string tabButtonName, string tabContainerName, ScrollItemWidget itemTemplate)
@@ -284,7 +284,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
string DeleteMap(string map) string DeleteMap(string map)
{ {
var path = Game.ModData.MapCache[map].Map.Path; var path = Game.ModData.MapCache[map].Path;
try try
{ {
if (File.Exists(path)) if (File.Exists(path))

View File

@@ -14,6 +14,7 @@ using System.IO;
using System.Linq; using System.Linq;
using System.Threading; using System.Threading;
using OpenRA.Graphics; using OpenRA.Graphics;
using OpenRA.Primitives;
using OpenRA.Widgets; using OpenRA.Widgets;
namespace OpenRA.Mods.Common.Widgets.Logic namespace OpenRA.Mods.Common.Widgets.Logic
@@ -38,8 +39,10 @@ namespace OpenRA.Mods.Common.Widgets.Logic
readonly ScrollPanelWidget missionList; readonly ScrollPanelWidget missionList;
readonly ScrollItemWidget headerTemplate; readonly ScrollItemWidget headerTemplate;
readonly ScrollItemWidget template; readonly ScrollItemWidget template;
readonly Cache<MapPreview, Map> mapCache = new Cache<MapPreview, Map>(p => new Map(p.Path));
MapPreview selectedMapPreview; MapPreview selectedMapPreview;
Map selectedMap;
PlayingVideo playingVideo; PlayingVideo playingVideo;
@@ -89,7 +92,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
stopInfoVideoButton.IsVisible = () => playingVideo == PlayingVideo.Info; stopInfoVideoButton.IsVisible = () => playingVideo == PlayingVideo.Info;
stopInfoVideoButton.OnClick = () => StopVideo(videoPlayer); stopInfoVideoButton.OnClick = () => StopVideo(videoPlayer);
var allMaps = new List<Map>(); var allPreviews = new List<MapPreview>();
missionList.RemoveChildren(); missionList.RemoveChildren();
// Add a group for each campaign // Add a group for each campaign
@@ -102,33 +105,38 @@ namespace OpenRA.Mods.Common.Widgets.Logic
{ {
var missionMapPaths = kv.Value.Nodes.Select(n => Path.GetFullPath(n.Key)).ToList(); 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.Map.Path))) .Where(p => p.Status == MapStatus.Available && missionMapPaths.Contains(Path.GetFullPath(p.Path)))
.Select(p => p.Map) .OrderBy(p => missionMapPaths.IndexOf(Path.GetFullPath(p.Path)));
.OrderBy(m => missionMapPaths.IndexOf(Path.GetFullPath(m.Path)));
CreateMissionGroup(kv.Key, maps); CreateMissionGroup(kv.Key, previews);
allMaps.AddRange(maps); allPreviews.AddRange(previews);
} }
} }
// Add an additional group for loose missions // Add an additional group for loose missions
var looseMissions = modData.MapCache var loosePreviews = 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) && !allPreviews.Any(a => a.Uid == p.Uid));
.Select(p => p.Map);
if (looseMissions.Any()) if (loosePreviews.Any())
{ {
CreateMissionGroup("Missions", looseMissions); CreateMissionGroup("Missions", loosePreviews);
allMaps.AddRange(looseMissions); allPreviews.AddRange(loosePreviews);
} }
if (allMaps.Any()) if (allPreviews.Any())
SelectMap(allMaps.First()); 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<ButtonWidget>("STARTGAME_BUTTON"); var startButton = widget.Get<ButtonWidget>("STARTGAME_BUTTON");
startButton.OnClick = StartMissionClicked; startButton.OnClick = StartMissionClicked;
startButton.IsDisabled = () => selectedMapPreview == null || selectedMapPreview.RuleStatus != MapRuleStatus.Cached; startButton.IsDisabled = () => selectedMap == null || selectedMap.InvalidCustomRules;
widget.Get<ButtonWidget>("BACK_BUTTON").OnClick = () => widget.Get<ButtonWidget>("BACK_BUTTON").OnClick = () =>
{ {
@@ -139,38 +147,39 @@ namespace OpenRA.Mods.Common.Widgets.Logic
}; };
} }
void CreateMissionGroup(string title, IEnumerable<Map> maps) void CreateMissionGroup(string title, IEnumerable<MapPreview> previews)
{ {
var header = ScrollItemWidget.Setup(headerTemplate, () => true, () => { }); var header = ScrollItemWidget.Setup(headerTemplate, () => true, () => { });
header.Get<LabelWidget>("LABEL").GetText = () => title; header.Get<LabelWidget>("LABEL").GetText = () => title;
missionList.AddChild(header); missionList.AddChild(header);
foreach (var m in maps) foreach (var p in previews)
{ {
var map = m; var preview = p;
var item = ScrollItemWidget.Setup(template, var item = ScrollItemWidget.Setup(template,
() => selectedMapPreview != null && selectedMapPreview.Uid == map.Uid, () => selectedMapPreview != null && selectedMapPreview.Uid == preview.Uid,
() => SelectMap(map), () => SelectMap(preview),
StartMissionClicked); StartMissionClicked);
item.Get<LabelWidget>("TITLE").GetText = () => map.Title; item.Get<LabelWidget>("TITLE").GetText = () => preview.Title;
missionList.AddChild(item); missionList.AddChild(item);
} }
} }
void SelectMap(Map map) void SelectMap(MapPreview preview)
{ {
selectedMapPreview = Game.ModData.MapCache[map.Uid]; selectedMap = mapCache[preview];
selectedMapPreview = preview;
// Cache the rules on a background thread to avoid jank // Cache the rules on a background thread to avoid jank
new Thread(selectedMapPreview.CacheRules).Start(); new Thread(() => selectedMap.PreloadRules()).Start();
var briefingVideo = selectedMapPreview.Map.Videos.Briefing; var briefingVideo = selectedMap.Videos.Briefing;
var briefingVideoVisible = briefingVideo != null; var briefingVideoVisible = briefingVideo != null;
var briefingVideoDisabled = !(briefingVideoVisible && Game.ModData.ModFiles.Exists(briefingVideo)); var briefingVideoDisabled = !(briefingVideoVisible && Game.ModData.ModFiles.Exists(briefingVideo));
var infoVideo = selectedMapPreview.Map.Videos.BackgroundInfo; var infoVideo = selectedMap.Videos.BackgroundInfo;
var infoVideoVisible = infoVideo != null; var infoVideoVisible = infoVideo != null;
var infoVideoDisabled = !(infoVideoVisible && Game.ModData.ModFiles.Exists(infoVideo)); var infoVideoDisabled = !(infoVideoVisible && Game.ModData.ModFiles.Exists(infoVideo));
@@ -182,7 +191,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
startInfoVideoButton.IsDisabled = () => infoVideoDisabled || playingVideo != PlayingVideo.None; startInfoVideoButton.IsDisabled = () => infoVideoDisabled || playingVideo != PlayingVideo.None;
startInfoVideoButton.OnClick = () => PlayVideo(videoPlayer, infoVideo, PlayingVideo.Info, () => StopVideo(videoPlayer)); 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); text = WidgetUtils.WrapText(text, description.Bounds.Width, descriptionFont);
description.Text = text; description.Text = text;
description.Bounds.Height = descriptionFont.Measure(text).Y; description.Bounds.Height = descriptionFont.Measure(text).Y;
@@ -191,13 +200,13 @@ namespace OpenRA.Mods.Common.Widgets.Logic
if (difficultyButton != null) 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.GetText = () => difficulty ?? "Normal";
difficultyButton.OnMouseDown = _ => difficultyButton.OnMouseDown = _ =>
{ {
var options = map.Options.Difficulties.Select(d => new DropDownOption var options = selectedMap.Options.Difficulties.Select(d => new DropDownOption
{ {
Title = d, Title = d,
IsSelected = () => difficulty == d, IsSelected = () => difficulty == d,
@@ -288,10 +297,10 @@ namespace OpenRA.Mods.Common.Widgets.Logic
{ {
StopVideo(videoPlayer); StopVideo(videoPlayer);
if (selectedMapPreview.RuleStatus != MapRuleStatus.Cached) if (selectedMap.InvalidCustomRules)
return; return;
var gameStartVideo = selectedMapPreview.Map.Videos.GameStart; var gameStartVideo = selectedMap.Videos.GameStart;
if (gameStartVideo != null && Game.ModData.ModFiles.Exists(gameStartVideo)) if (gameStartVideo != null && Game.ModData.ModFiles.Exists(gameStartVideo))
{ {
var fsPlayer = fullscreenVideoPlayer.Get<VqaPlayerWidget>("PLAYER"); var fsPlayer = fullscreenVideoPlayer.Get<VqaPlayerWidget>("PLAYER");