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()
{
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())

View File

@@ -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(() =>

View File

@@ -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; }
@@ -65,13 +67,11 @@ 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; }
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; }
@@ -111,11 +111,12 @@ namespace OpenRA
GridType = gridType;
Status = MapStatus.Unavailable;
Class = MapClassification.Unknown;
Visibility = MapVisibility.Lobby;
}
public void UpdateFromMap(Map m, MapClassification classification)
{
Map = m;
Path = m.Path;
Title = m.Title;
Type = m.Type;
Type = m.Type;
@@ -126,6 +127,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 +137,7 @@ namespace OpenRA
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;
// Other map types may have confusing settings or gameplay
@@ -168,7 +170,6 @@ namespace OpenRA
if (!r.downloading)
{
Status = MapStatus.Unavailable;
RuleStatus = MapRuleStatus.Invalid;
return;
}
@@ -228,7 +229,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<DownloadProgressChangedEventArgs> onDownloadProgress = i => { DownloadBytes = i.BytesReceived; DownloadPercentage = i.ProgressPercentage; };
@@ -246,11 +247,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);
@@ -272,19 +269,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;
}
}
}

View File

@@ -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);

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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]));

View File

@@ -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)
{

View File

@@ -26,7 +26,8 @@ namespace OpenRA.Mods.Common.Widgets.Logic
{
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 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<bool> configurationDisabled = () => !Game.IsHost || gameStarting ||
panel == PanelType.Kick || panel == PanelType.ForceStart ||
Map == null || Map.InvalidCustomRules ||
orderManager.LocalClient == null || orderManager.LocalClient.IsReady;
var mapButton = lobby.GetOrNull<ButtonWidget>("CHANGEMAP_BUTTON");
@@ -168,7 +171,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
var onSelect = new Action<string>(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 +181,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 +193,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
var slotsButton = lobby.GetOrNull<DropDownButtonWidget>("SLOTS_DROPDOWNBUTTON");
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.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");
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;
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");
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.GlobalSettings.DisableSingleplayer && orderManager.LobbyInfo.IsSinglePlayer);
startGameButton.OnClick = () =>
{
// Bots and admins don't count
@@ -341,7 +345,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 = () => configurationDisabled() || Map.Options.Cheats.HasValue;
allowCheats.OnClick = () => orderManager.IssueOrder(Order.Command(
"allowcheats {0}".F(!orderManager.LobbyInfo.GlobalSettings.AllowCheats)));
}
@@ -350,7 +354,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 = () => configurationDisabled() || Map.Options.Crates.HasValue;
crates.OnClick = () => orderManager.IssueOrder(Order.Command(
"crates {0}".F(!orderManager.LobbyInfo.GlobalSettings.Crates)));
}
@@ -359,7 +363,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 = () => configurationDisabled() || Map.Options.Creeps.HasValue;
creeps.OnClick = () => orderManager.IssueOrder(Order.Command(
"creeps {0}".F(!orderManager.LobbyInfo.GlobalSettings.Creeps)));
}
@@ -368,7 +372,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 = () => configurationDisabled() || Map.Options.AllyBuildRadius.HasValue;
allybuildradius.OnClick = () => orderManager.IssueOrder(Order.Command(
"allybuildradius {0}".F(!orderManager.LobbyInfo.GlobalSettings.AllyBuildRadius)));
}
@@ -377,7 +381,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 = () => configurationDisabled() || Map.Options.ShortGame.HasValue;
shortGame.OnClick = () => orderManager.IssueOrder(Order.Command(
"shortgame {0}".F(!orderManager.LobbyInfo.GlobalSettings.ShortGame)));
}
@@ -385,12 +389,12 @@ namespace OpenRA.Mods.Common.Widgets.Logic
var difficulty = optionsBin.GetOrNull<DropDownButtonWidget>("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 = () => Map != null && Map.Options.Difficulties.Any();
difficulty.IsDisabled = configurationDisabled;
difficulty.GetText = () => orderManager.LobbyInfo.GlobalSettings.Difficulty;
difficulty.OnMouseDown = _ =>
{
var options = Map.Map.Options.Difficulties.Select(d => new DropDownOption
var options = Map.Options.Difficulties.Select(d => new DropDownOption
{
Title = d,
IsSelected = () => orderManager.LobbyInfo.GlobalSettings.Difficulty == d,
@@ -419,10 +423,9 @@ 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 = () => configurationDisabled() || !Map.Options.ConfigurableStartingUnits;
startingUnits.GetText = () => MapPreview.Status != MapStatus.Available ||
Map == null || !Map.Options.ConfigurableStartingUnits ? "Not Available" : className(orderManager.LobbyInfo.GlobalSettings.StartingUnitsClass);
startingUnits.OnMouseDown = _ =>
{
var options = classes.Select(c => new DropDownOption
@@ -448,10 +451,9 @@ namespace OpenRA.Mods.Common.Widgets.Logic
var startingCash = optionsBin.GetOrNull<DropDownButtonWidget>("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 = () => configurationDisabled() || Map.Options.StartingCash.HasValue;
startingCash.GetText = () => MapPreview.Status != MapStatus.Available ||
Map == null || Map.Options.StartingCash.HasValue ? "Not Available" : "${0}".F(orderManager.LobbyInfo.GlobalSettings.StartingCash);
startingCash.OnMouseDown = _ =>
{
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)
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 = () => configurationDisabled() || Map.Options.TechLevel != null || techTraits.Count <= 1;
techLevel.GetText = () => MapPreview.Status != MapStatus.Available ||
Map == null || 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<GameSpeeds>().Speeds;
gameSpeed.IsDisabled = () => Map.Status != MapStatus.Available || configurationDisabled();
gameSpeed.IsDisabled = 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 = () => configurationDisabled() || Map.Options.Shroud.HasValue;
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 = () => configurationDisabled() || Map.Options.Fog.HasValue;
enableFog.OnClick = () => orderManager.IssueOrder(Order.Command(
"fog {0}".F(!orderManager.LobbyInfo.GlobalSettings.Fog)));
}
@@ -733,31 +734,32 @@ 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];
Map = null;
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 currentMap = Map = new Map(MapPreview.Path);
currentMap.PreloadRules();
Game.RunAfterTick(() =>
{
// Map may have changed in the meantime
if (map != Map)
if (currentMap != Map)
return;
if (map.RuleStatus != MapRuleStatus.Invalid)
if (!currentMap.InvalidCustomRules)
{
// 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<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)));
}
});
@@ -816,9 +818,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, Map == null || Map.InvalidCustomRules);
}
else
{

View File

@@ -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.Map == null || !lobby.Map.InvalidCustomRules);
var preview = available.Get<MapPreviewWidget>("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<LabelWidget>("MAP_TITLE");
if (titleLabel != null)
{
var font = Game.Renderer.Fonts[titleLabel.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");
if (typeLabel != null)
typeLabel.GetText = () => lobby.Map.Type;
typeLabel.GetText = () => lobby.MapPreview.Type;
var authorLabel = available.GetOrNull<LabelWidget>("MAP_AUTHOR");
if (authorLabel != null)
{
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));
authorLabel.GetText = () => author.Update(lobby.Map);
var author = new CachedTransform<MapPreview, string>(
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.Map != null && lobby.Map.InvalidCustomRules;
var preview = invalid.Get<MapPreviewWidget>("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<LabelWidget>("MAP_TITLE");
if (title != null)
title.GetText = () => lobby.Map.Title;
title.GetText = () => lobby.MapPreview.Title;
var type = invalid.GetOrNull<LabelWidget>("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<MapPreviewWidget>("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<LabelWidget>("MAP_TITLE");
if (title != null)
title.GetText = () => lobby.Map.Title;
title.GetText = () => lobby.MapPreview.Title;
var type = download.GetOrNull<LabelWidget>("MAP_TYPE");
if (type != null)
type.GetText = () => lobby.Map.Type;
type.GetText = () => lobby.MapPreview.Type;
var author = download.GetOrNull<LabelWidget>("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<ButtonWidget>("MAP_INSTALL");
if (install != null)
{
install.OnClick = () => lobby.Map.Install();
install.OnClick = () => lobby.MapPreview.Install();
install.IsHighlighted = () => installHighlighted;
}
}
@@ -105,72 +106,72 @@ namespace OpenRA.Mods.Common.Widgets.Logic
var progress = widget.GetOrNull("MAP_PROGRESS");
if (progress != null)
{
progress.IsVisible = () =>
(lobby.Map.Status != MapStatus.Available || lobby.Map.RuleStatus == MapRuleStatus.Unknown) &&
lobby.Map.Status != MapStatus.DownloadAvailable;
progress.IsVisible = () => lobby.MapPreview.Status != MapStatus.Available &&
lobby.MapPreview.Status != MapStatus.DownloadAvailable;
var preview = progress.Get<MapPreviewWidget>("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<LabelWidget>("MAP_TITLE");
if (title != null)
title.GetText = () => lobby.Map.Title;
title.GetText = () => lobby.MapPreview.Title;
var type = progress.GetOrNull<LabelWidget>("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<LabelWidget>("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<ButtonWidget>("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<ProgressBarWidget>("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();
}
}

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();
}
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");
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)));

View File

@@ -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;
@@ -167,7 +167,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
var onSelect = new Action<string>(uid =>
{
RemoveShellmapUI();
LoadMapIntoEditor(Game.ModData.MapCache[uid].Map);
LoadMapIntoEditor(Game.ModData.MapCache[uid].Uid);
});
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(),
Game.CreateLocalServer(map.Uid),
Game.CreateLocalServer(uid),
"",
() => { Game.LoadEditor(map.Uid); },
() => { Game.LoadEditor(uid); },
() => { Game.CloseServer(); SwitchMenu(MenuType.MapEditor); });
}

View File

@@ -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)
@@ -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))

View File

@@ -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,8 +39,10 @@ namespace OpenRA.Mods.Common.Widgets.Logic
readonly ScrollPanelWidget missionList;
readonly ScrollItemWidget headerTemplate;
readonly ScrollItemWidget template;
readonly Cache<MapPreview, Map> mapCache = new Cache<MapPreview, Map>(p => new Map(p.Path));
MapPreview selectedMapPreview;
Map selectedMap;
PlayingVideo playingVideo;
@@ -89,7 +92,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
stopInfoVideoButton.IsVisible = () => playingVideo == PlayingVideo.Info;
stopInfoVideoButton.OnClick = () => StopVideo(videoPlayer);
var allMaps = new List<Map>();
var allPreviews = new List<MapPreview>();
missionList.RemoveChildren();
// 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 maps = modData.MapCache
.Where(p => p.Status == MapStatus.Available && missionMapPaths.Contains(Path.GetFullPath(p.Map.Path)))
.Select(p => p.Map)
.OrderBy(m => missionMapPaths.IndexOf(Path.GetFullPath(m.Path)));
var previews = modData.MapCache
.Where(p => p.Status == MapStatus.Available && missionMapPaths.Contains(Path.GetFullPath(p.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.Map.Visibility.HasFlag(MapVisibility.MissionSelector) && !allMaps.Contains(p.Map))
.Select(p => p.Map);
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<ButtonWidget>("STARTGAME_BUTTON");
startButton.OnClick = StartMissionClicked;
startButton.IsDisabled = () => selectedMapPreview == null || selectedMapPreview.RuleStatus != MapRuleStatus.Cached;
startButton.IsDisabled = () => selectedMap == null || selectedMap.InvalidCustomRules;
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, () => { });
header.Get<LabelWidget>("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<LabelWidget>("TITLE").GetText = () => map.Title;
item.Get<LabelWidget>("TITLE").GetText = () => preview.Title;
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
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 briefingVideoDisabled = !(briefingVideoVisible && Game.ModData.ModFiles.Exists(briefingVideo));
var infoVideo = selectedMapPreview.Map.Videos.BackgroundInfo;
var infoVideo = selectedMap.Videos.BackgroundInfo;
var infoVideoVisible = infoVideo != null;
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.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;
@@ -191,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,
@@ -288,10 +297,10 @@ namespace OpenRA.Mods.Common.Widgets.Logic
{
StopVideo(videoPlayer);
if (selectedMapPreview.RuleStatus != MapRuleStatus.Cached)
if (selectedMap.InvalidCustomRules)
return;
var gameStartVideo = selectedMapPreview.Map.Videos.GameStart;
var gameStartVideo = selectedMap.Videos.GameStart;
if (gameStartVideo != null && Game.ModData.ModFiles.Exists(gameStartVideo))
{
var fsPlayer = fullscreenVideoPlayer.Get<VqaPlayerWidget>("PLAYER");