Load MapPreview data without initialising a full Map.
This commit is contained in:
@@ -44,20 +44,27 @@ namespace OpenRA
|
|||||||
|
|
||||||
public void LoadMaps()
|
public void LoadMaps()
|
||||||
{
|
{
|
||||||
|
// Utility mod that does not support maps
|
||||||
|
if (!modData.Manifest.Contains<MapGrid>())
|
||||||
|
return;
|
||||||
|
|
||||||
// Expand the dictionary (dir path, dir type) to a dictionary of (map path, dir type)
|
// Expand the dictionary (dir path, dir type) to a dictionary of (map path, dir type)
|
||||||
var mapPaths = modData.Manifest.MapFolders.SelectMany(kv =>
|
var mapPaths = modData.Manifest.MapFolders.SelectMany(kv =>
|
||||||
FindMapsIn(modData.ModFiles, kv.Key).ToDictionary(p => p, p => string.IsNullOrEmpty(kv.Value)
|
FindMapsIn(modData.ModFiles, kv.Key).ToDictionary(p => p, p => string.IsNullOrEmpty(kv.Value)
|
||||||
? MapClassification.Unknown : Enum<MapClassification>.Parse(kv.Value)));
|
? MapClassification.Unknown : Enum<MapClassification>.Parse(kv.Value)));
|
||||||
|
|
||||||
|
var mapGrid = modData.Manifest.Get<MapGrid>();
|
||||||
foreach (var path in mapPaths)
|
foreach (var path in mapPaths)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
using (new Support.PerfTimer(path.Key))
|
using (new Support.PerfTimer(path.Key))
|
||||||
{
|
{
|
||||||
var map = new Map(path.Key);
|
using (var package = modData.ModFiles.OpenPackage(path.Key))
|
||||||
if (modData.Manifest.MapCompatibility.Contains(map.RequiresMod))
|
{
|
||||||
previews[map.Uid].UpdateFromMap(map, path.Value);
|
var uid = Map.ComputeUID(package);
|
||||||
|
previews[uid].UpdateFromMap(package, path.Value, modData.Manifest.MapCompatibility, mapGrid.Type);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ using System.IO;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
using OpenRA.FileSystem;
|
||||||
using OpenRA.Graphics;
|
using OpenRA.Graphics;
|
||||||
|
|
||||||
namespace OpenRA
|
namespace OpenRA
|
||||||
@@ -92,7 +93,7 @@ namespace OpenRA
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetMinimap(Sprite minimap)
|
internal void SetMinimap(Sprite minimap)
|
||||||
{
|
{
|
||||||
this.minimap = minimap;
|
this.minimap = minimap;
|
||||||
generatingMinimap = false;
|
generatingMinimap = false;
|
||||||
@@ -114,26 +115,90 @@ namespace OpenRA
|
|||||||
Visibility = MapVisibility.Lobby;
|
Visibility = MapVisibility.Lobby;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UpdateFromMap(Map m, MapClassification classification)
|
public void UpdateFromMap(IReadOnlyPackage p, MapClassification classification, string[] mapCompatibility, MapGridType gridType)
|
||||||
{
|
{
|
||||||
Path = m.Path;
|
Dictionary<string, MiniYaml> yaml;
|
||||||
Title = m.Title;
|
using (var yamlStream = p.GetStream("map.yaml"))
|
||||||
Type = m.Type;
|
{
|
||||||
Type = m.Type;
|
if (yamlStream == null)
|
||||||
Author = m.Author;
|
throw new FileNotFoundException("Required file map.yaml not present in this map");
|
||||||
Bounds = m.Bounds;
|
|
||||||
SpawnPoints = m.SpawnPoints.Value;
|
yaml = new MiniYaml(null, MiniYaml.FromStream(yamlStream, "map.yaml")).ToDictionary();
|
||||||
GridType = m.Grid.Type;
|
}
|
||||||
CustomPreview = m.CustomPreview;
|
|
||||||
Status = MapStatus.Available;
|
Path = p.Name;
|
||||||
|
GridType = gridType;
|
||||||
Class = classification;
|
Class = classification;
|
||||||
Visibility = m.Visibility;
|
|
||||||
|
|
||||||
var players = new MapPlayers(m.PlayerDefinitions).Players;
|
MiniYaml temp;
|
||||||
|
if (yaml.TryGetValue("MapFormat", out temp))
|
||||||
|
{
|
||||||
|
var format = FieldLoader.GetValue<int>("MapFormat", temp.Value);
|
||||||
|
if (format != Map.SupportedMapFormat)
|
||||||
|
throw new InvalidDataException("Map format {0} is not supported.".F(format));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (yaml.TryGetValue("Title", out temp))
|
||||||
|
Title = temp.Value;
|
||||||
|
if (yaml.TryGetValue("Type", out temp))
|
||||||
|
Type = temp.Value;
|
||||||
|
if (yaml.TryGetValue("Author", out temp))
|
||||||
|
Author = temp.Value;
|
||||||
|
if (yaml.TryGetValue("Bounds", out temp))
|
||||||
|
Bounds = FieldLoader.GetValue<Rectangle>("Bounds", temp.Value);
|
||||||
|
if (yaml.TryGetValue("Visibility", out temp))
|
||||||
|
Visibility = FieldLoader.GetValue<MapVisibility>("Visibility", temp.Value);
|
||||||
|
|
||||||
|
string requiresMod = string.Empty;
|
||||||
|
if (yaml.TryGetValue("RequiresMod", out temp))
|
||||||
|
requiresMod = temp.Value;
|
||||||
|
|
||||||
|
Status = mapCompatibility == null || mapCompatibility.Contains(requiresMod) ? MapStatus.Available : MapStatus.Unavailable;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Actor definitions may change if the map format changes
|
||||||
|
MiniYaml actorDefinitions;
|
||||||
|
if (yaml.TryGetValue("Actors", out actorDefinitions))
|
||||||
|
{
|
||||||
|
var spawns = new List<CPos>();
|
||||||
|
foreach (var kv in actorDefinitions.Nodes.Where(d => d.Value.Value == "mpspawn"))
|
||||||
|
{
|
||||||
|
var s = new ActorReference(kv.Value.Value, kv.Value.ToDictionary());
|
||||||
|
spawns.Add(s.InitDict.Get<LocationInit>().Value(null));
|
||||||
|
}
|
||||||
|
|
||||||
|
SpawnPoints = spawns.ToArray();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
SpawnPoints = new CPos[0];
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
SpawnPoints = new CPos[0];
|
||||||
|
Status = MapStatus.Unavailable;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Player definitions may change if the map format changes
|
||||||
|
MiniYaml playerDefinitions;
|
||||||
|
if (yaml.TryGetValue("Players", out playerDefinitions))
|
||||||
|
{
|
||||||
|
var players = new MapPlayers(playerDefinitions.Nodes).Players;
|
||||||
PlayerCount = players.Count(x => x.Value.Playable);
|
PlayerCount = players.Count(x => x.Value.Playable);
|
||||||
|
|
||||||
SuitableForInitialMap = EvaluateUserFriendliness(players);
|
SuitableForInitialMap = EvaluateUserFriendliness(players);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
Status = MapStatus.Unavailable;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p.Contains("map.png"))
|
||||||
|
using (var dataStream = p.GetStream("map.png"))
|
||||||
|
CustomPreview = new Bitmap(dataStream);
|
||||||
|
}
|
||||||
|
|
||||||
bool EvaluateUserFriendliness(Dictionary<string, PlayerReference> players)
|
bool EvaluateUserFriendliness(Dictionary<string, PlayerReference> players)
|
||||||
{
|
{
|
||||||
@@ -210,6 +275,7 @@ namespace OpenRA
|
|||||||
if (!Directory.Exists(baseMapPath))
|
if (!Directory.Exists(baseMapPath))
|
||||||
Directory.CreateDirectory(baseMapPath);
|
Directory.CreateDirectory(baseMapPath);
|
||||||
|
|
||||||
|
var modData = Game.ModData;
|
||||||
new Thread(() =>
|
new Thread(() =>
|
||||||
{
|
{
|
||||||
// Request the filename from the server
|
// Request the filename from the server
|
||||||
@@ -247,7 +313,11 @@ namespace OpenRA
|
|||||||
}
|
}
|
||||||
|
|
||||||
Log.Write("debug", "Downloaded map to '{0}'", mapPath);
|
Log.Write("debug", "Downloaded map to '{0}'", mapPath);
|
||||||
Game.RunAfterTick(() => UpdateFromMap(new Map(mapPath), MapClassification.User));
|
Game.RunAfterTick(() =>
|
||||||
|
{
|
||||||
|
using (var package = modData.ModFiles.OpenPackage(mapPath))
|
||||||
|
UpdateFromMap(package, MapClassification.User, null, GridType);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
download = new Download(mapUrl, mapPath, onDownloadProgress, onDownloadComplete);
|
download = new Download(mapUrl, mapPath, onDownloadProgress, onDownloadComplete);
|
||||||
|
|||||||
@@ -168,7 +168,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
|||||||
|
|
||||||
// Update the map cache so it can be loaded without restarting the game
|
// Update the map cache so it can be loaded without restarting the game
|
||||||
var classification = mapDirectories[directoryDropdown.Text];
|
var classification = mapDirectories[directoryDropdown.Text];
|
||||||
modData.MapCache[map.Uid].UpdateFromMap(map, classification);
|
modData.MapCache[map.Uid].UpdateFromMap(map.Container, classification, null, map.Grid.Type);
|
||||||
|
|
||||||
Console.WriteLine("Saved current map at {0}", combinedPath);
|
Console.WriteLine("Saved current map at {0}", combinedPath);
|
||||||
Ui.CloseWindow();
|
Ui.CloseWindow();
|
||||||
|
|||||||
Reference in New Issue
Block a user