Refactoring to remove static Rules & SequenceProvider
This commit is contained in:
@@ -18,6 +18,7 @@ using System.Text;
|
||||
using OpenRA.FileSystem;
|
||||
using OpenRA.Network;
|
||||
using OpenRA.Traits;
|
||||
using OpenRA.Graphics;
|
||||
|
||||
namespace OpenRA
|
||||
{
|
||||
@@ -94,13 +95,13 @@ namespace OpenRA
|
||||
[FieldLoader.Ignore] public Dictionary<string, PlayerReference> Players = new Dictionary<string, PlayerReference>();
|
||||
[FieldLoader.Ignore] public Lazy<List<SmudgeReference>> Smudges;
|
||||
|
||||
[FieldLoader.Ignore] public List<MiniYamlNode> Rules = new List<MiniYamlNode>();
|
||||
[FieldLoader.Ignore] public List<MiniYamlNode> Sequences = new List<MiniYamlNode>();
|
||||
[FieldLoader.Ignore] public List<MiniYamlNode> VoxelSequences = new List<MiniYamlNode>();
|
||||
[FieldLoader.Ignore] public List<MiniYamlNode> Weapons = new List<MiniYamlNode>();
|
||||
[FieldLoader.Ignore] public List<MiniYamlNode> Voices = new List<MiniYamlNode>();
|
||||
[FieldLoader.Ignore] public List<MiniYamlNode> Notifications = new List<MiniYamlNode>();
|
||||
[FieldLoader.Ignore] public List<MiniYamlNode> Translations = new List<MiniYamlNode>();
|
||||
[FieldLoader.Ignore] public List<MiniYamlNode> RuleDefinitions = new List<MiniYamlNode>();
|
||||
[FieldLoader.Ignore] public List<MiniYamlNode> SequenceDefinitions = new List<MiniYamlNode>();
|
||||
[FieldLoader.Ignore] public List<MiniYamlNode> VoxelSequenceDefinitions = new List<MiniYamlNode>();
|
||||
[FieldLoader.Ignore] public List<MiniYamlNode> WeaponDefinitions = new List<MiniYamlNode>();
|
||||
[FieldLoader.Ignore] public List<MiniYamlNode> VoiceDefinitions = new List<MiniYamlNode>();
|
||||
[FieldLoader.Ignore] public List<MiniYamlNode> NotificationDefinitions = new List<MiniYamlNode>();
|
||||
[FieldLoader.Ignore] public List<MiniYamlNode> TranslationDefinitions = new List<MiniYamlNode>();
|
||||
|
||||
// Binary map data
|
||||
[FieldLoader.Ignore] public byte TileFormat = 1;
|
||||
@@ -110,6 +111,10 @@ namespace OpenRA
|
||||
[FieldLoader.Ignore] public Lazy<TileReference<byte, byte>[,]> MapResources;
|
||||
[FieldLoader.Ignore] public string[,] CustomTerrain;
|
||||
|
||||
[FieldLoader.Ignore] Lazy<MapRuleset> rules;
|
||||
public MapRuleset Rules { get { return rules != null ? rules.Value : null; } }
|
||||
public SequenceProvider SequenceProvider { get; private set; }
|
||||
|
||||
public static Map FromTileset(TileSet tileset)
|
||||
{
|
||||
var tile = tileset.Templates.First();
|
||||
@@ -128,6 +133,7 @@ namespace OpenRA
|
||||
Actors = Exts.Lazy(() => new Dictionary<string, ActorReference>()),
|
||||
Smudges = Exts.Lazy(() => new List<SmudgeReference>())
|
||||
};
|
||||
map.PostInit();
|
||||
|
||||
return map;
|
||||
}
|
||||
@@ -210,13 +216,13 @@ namespace OpenRA
|
||||
return ret;
|
||||
});
|
||||
|
||||
Rules = MiniYaml.NodesOrEmpty(yaml, "Rules");
|
||||
Sequences = MiniYaml.NodesOrEmpty(yaml, "Sequences");
|
||||
VoxelSequences = MiniYaml.NodesOrEmpty(yaml, "VoxelSequences");
|
||||
Weapons = MiniYaml.NodesOrEmpty(yaml, "Weapons");
|
||||
Voices = MiniYaml.NodesOrEmpty(yaml, "Voices");
|
||||
Notifications = MiniYaml.NodesOrEmpty(yaml, "Notifications");
|
||||
Translations = MiniYaml.NodesOrEmpty(yaml, "Translations");
|
||||
RuleDefinitions = MiniYaml.NodesOrEmpty(yaml, "Rules");
|
||||
SequenceDefinitions = MiniYaml.NodesOrEmpty(yaml, "Sequences");
|
||||
VoxelSequenceDefinitions = MiniYaml.NodesOrEmpty(yaml, "VoxelSequences");
|
||||
WeaponDefinitions = MiniYaml.NodesOrEmpty(yaml, "Weapons");
|
||||
VoiceDefinitions = MiniYaml.NodesOrEmpty(yaml, "Voices");
|
||||
NotificationDefinitions = MiniYaml.NodesOrEmpty(yaml, "Notifications");
|
||||
TranslationDefinitions = MiniYaml.NodesOrEmpty(yaml, "Translations");
|
||||
|
||||
CustomTerrain = new string[MapSize.X, MapSize.Y];
|
||||
|
||||
@@ -233,6 +239,19 @@ namespace OpenRA
|
||||
|
||||
if (Container.Exists("map.png"))
|
||||
CustomPreview = new Bitmap(Container.GetContent("map.png"));
|
||||
|
||||
PostInit();
|
||||
}
|
||||
|
||||
void PostInit()
|
||||
{
|
||||
rules = Exts.Lazy(() => Game.modData.RulesetCache.LoadMapRules(this));
|
||||
SequenceProvider = new SequenceProvider(this);
|
||||
}
|
||||
|
||||
public MapRuleset PreloadRules()
|
||||
{
|
||||
return rules.Value;
|
||||
}
|
||||
|
||||
public CPos[] GetSpawnPoints()
|
||||
@@ -282,13 +301,13 @@ namespace OpenRA
|
||||
);
|
||||
|
||||
root.Add(new MiniYamlNode("Smudges", MiniYaml.FromList<SmudgeReference>(Smudges.Value)));
|
||||
root.Add(new MiniYamlNode("Rules", null, Rules));
|
||||
root.Add(new MiniYamlNode("Sequences", null, Sequences));
|
||||
root.Add(new MiniYamlNode("VoxelSequences", null, VoxelSequences));
|
||||
root.Add(new MiniYamlNode("Weapons", null, Weapons));
|
||||
root.Add(new MiniYamlNode("Voices", null, Voices));
|
||||
root.Add(new MiniYamlNode("Notifications", null, Notifications));
|
||||
root.Add(new MiniYamlNode("Translations", null, Translations));
|
||||
root.Add(new MiniYamlNode("Rules", null, RuleDefinitions));
|
||||
root.Add(new MiniYamlNode("Sequences", null, SequenceDefinitions));
|
||||
root.Add(new MiniYamlNode("VoxelSequences", null, VoxelSequenceDefinitions));
|
||||
root.Add(new MiniYamlNode("Weapons", null, WeaponDefinitions));
|
||||
root.Add(new MiniYamlNode("Voices", null, VoiceDefinitions));
|
||||
root.Add(new MiniYamlNode("Notifications", null, NotificationDefinitions));
|
||||
root.Add(new MiniYamlNode("Translations", null, TranslationDefinitions));
|
||||
|
||||
var entries = new Dictionary<string, byte[]>();
|
||||
entries.Add("map.bin", SaveBinaryData());
|
||||
@@ -452,7 +471,7 @@ namespace OpenRA
|
||||
|
||||
public void MakeDefaultPlayers()
|
||||
{
|
||||
var firstRace = OpenRA.Rules.Info["world"].Traits
|
||||
var firstRace = Rules.Actors["world"].Traits
|
||||
.WithInterface<CountryInfo>().First(c => c.Selectable).Race;
|
||||
|
||||
if (!Players.ContainsKey("Neutral"))
|
||||
@@ -489,10 +508,10 @@ namespace OpenRA
|
||||
});
|
||||
}
|
||||
|
||||
public void FixOpenAreas()
|
||||
public void FixOpenAreas(MapRuleset rules)
|
||||
{
|
||||
var r = new Random();
|
||||
var tileset = OpenRA.Rules.TileSets[Tileset];
|
||||
var tileset = rules.TileSets[Tileset];
|
||||
|
||||
for (var j = Bounds.Top; j < Bounds.Bottom; j++)
|
||||
{
|
||||
|
||||
14
OpenRA.Game/Map/MapCache.cs
Executable file → Normal file
14
OpenRA.Game/Map/MapCache.cs
Executable file → Normal file
@@ -27,30 +27,30 @@ namespace OpenRA
|
||||
{
|
||||
public static readonly MapPreview UnknownMap = new MapPreview(null, null);
|
||||
readonly Cache<string, MapPreview> previews;
|
||||
readonly Manifest manifest;
|
||||
readonly ModData modData;
|
||||
readonly SheetBuilder sheetBuilder;
|
||||
Thread previewLoaderThread;
|
||||
object syncRoot = new object();
|
||||
Queue<MapPreview> generateMinimap = new Queue<MapPreview>();
|
||||
|
||||
public MapCache(Manifest m)
|
||||
public MapCache(ModData modData)
|
||||
{
|
||||
manifest = m;
|
||||
this.modData = modData;
|
||||
previews = new Cache<string, MapPreview>(uid => new MapPreview(uid, this));
|
||||
sheetBuilder = new SheetBuilder(SheetType.BGRA);
|
||||
}
|
||||
|
||||
public void LoadMaps()
|
||||
{
|
||||
var paths = manifest.MapFolders.SelectMany(f => FindMapsIn(f));
|
||||
var paths = modData.Manifest.MapFolders.SelectMany(f => FindMapsIn(f));
|
||||
foreach (var path in paths)
|
||||
{
|
||||
try
|
||||
{
|
||||
using (new Support.PerfTimer(path))
|
||||
{
|
||||
var map = new Map(path, manifest.Mod.Id);
|
||||
if (manifest.MapCompatibility.Contains(map.RequiresMod))
|
||||
var map = new Map(path, modData.Manifest.Mod.Id);
|
||||
if (modData.Manifest.MapCompatibility.Contains(map.RequiresMod))
|
||||
previews[map.Uid].UpdateFromMap(map);
|
||||
}
|
||||
}
|
||||
@@ -149,7 +149,7 @@ namespace OpenRA
|
||||
// the next render cycle.
|
||||
// (d) Any partially written bytes from the next minimap is in an
|
||||
// unallocated area, and will be committed in the next cycle.
|
||||
var bitmap = p.CustomPreview ?? Minimap.RenderMapPreview(p.Map, true);
|
||||
var bitmap = p.CustomPreview ?? Minimap.RenderMapPreview(modData.ModRules.TileSets[p.Map.Tileset], p.Map, true);
|
||||
p.Minimap = sheetBuilder.Add(bitmap);
|
||||
|
||||
lock (syncRoot)
|
||||
|
||||
65
OpenRA.Game/Map/Ruleset.cs
Normal file
65
OpenRA.Game/Map/Ruleset.cs
Normal file
@@ -0,0 +1,65 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2014 The OpenRA Developers (see AUTHORS)
|
||||
* This file is part of OpenRA, which is free software. It is made
|
||||
* available to you under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation. For more information,
|
||||
* see COPYING.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using OpenRA.GameRules;
|
||||
|
||||
namespace OpenRA
|
||||
{
|
||||
public class ModRuleset
|
||||
{
|
||||
public readonly IReadOnlyDictionary<string, MusicInfo> Music;
|
||||
public readonly IReadOnlyDictionary<string, string> Movies;
|
||||
public readonly IReadOnlyDictionary<string, TileSet> TileSets;
|
||||
|
||||
public ModRuleset(ModRuleset other)
|
||||
{
|
||||
this.Music = other.Music;
|
||||
this.Movies = other.Movies;
|
||||
this.TileSets = other.TileSets;
|
||||
}
|
||||
|
||||
public ModRuleset(
|
||||
IDictionary<string, MusicInfo> music,
|
||||
IDictionary<string, string> movies,
|
||||
IDictionary<string, TileSet> tileSets)
|
||||
{
|
||||
this.Music = new ReadOnlyDictionary<string, MusicInfo>(music);
|
||||
this.Movies = new ReadOnlyDictionary<string, string>(movies);
|
||||
this.TileSets = new ReadOnlyDictionary<string, TileSet>(tileSets);
|
||||
}
|
||||
|
||||
public IEnumerable<KeyValuePair<string, MusicInfo>> InstalledMusic { get { return Music.Where(m => m.Value.Exists); } }
|
||||
}
|
||||
|
||||
public class MapRuleset : ModRuleset
|
||||
{
|
||||
public readonly IReadOnlyDictionary<string, ActorInfo> Actors;
|
||||
public readonly IReadOnlyDictionary<string, WeaponInfo> Weapons;
|
||||
public readonly IReadOnlyDictionary<string, SoundInfo> Voices;
|
||||
public readonly IReadOnlyDictionary<string, SoundInfo> Notifications;
|
||||
|
||||
public MapRuleset(
|
||||
ModRuleset modRuleset,
|
||||
IDictionary<string, ActorInfo> actors,
|
||||
IDictionary<string, WeaponInfo> weapons,
|
||||
IDictionary<string, SoundInfo> voices,
|
||||
IDictionary<string, SoundInfo> notifications)
|
||||
: base(modRuleset)
|
||||
{
|
||||
this.Actors = new ReadOnlyDictionary<string, ActorInfo>(actors);
|
||||
this.Weapons = new ReadOnlyDictionary<string, WeaponInfo>(weapons);
|
||||
this.Voices = new ReadOnlyDictionary<string, SoundInfo>(voices);
|
||||
this.Notifications = new ReadOnlyDictionary<string, SoundInfo>(notifications);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
|
||||
* Copyright 2007-2014 The OpenRA Developers (see AUTHORS)
|
||||
* This file is part of OpenRA, which is free software. It is made
|
||||
* available to you under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation. For more information,
|
||||
@@ -8,21 +8,23 @@
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using OpenRA.Graphics;
|
||||
|
||||
namespace OpenRA
|
||||
{
|
||||
public class TerrainTypeInfo
|
||||
{
|
||||
public string Type;
|
||||
public string[] TargetTypes = { };
|
||||
public string[] AcceptsSmudgeType = { };
|
||||
public bool IsWater = false; // TODO: Remove this
|
||||
public Color Color;
|
||||
public string CustomCursor;
|
||||
public readonly string Type;
|
||||
public readonly string[] TargetTypes = { };
|
||||
public readonly string[] AcceptsSmudgeType = { };
|
||||
public readonly bool IsWater = false; // TODO: Remove this
|
||||
public readonly Color Color;
|
||||
public readonly string CustomCursor;
|
||||
|
||||
public TerrainTypeInfo() { }
|
||||
public TerrainTypeInfo(MiniYaml my) { FieldLoader.Load(this, my); }
|
||||
@@ -32,19 +34,26 @@ namespace OpenRA
|
||||
|
||||
public class TileTemplate
|
||||
{
|
||||
public ushort Id;
|
||||
public string Image;
|
||||
public int[] Frames;
|
||||
public int2 Size;
|
||||
public bool PickAny;
|
||||
public string Category;
|
||||
public readonly ushort Id;
|
||||
public readonly string Image;
|
||||
public readonly int[] Frames;
|
||||
public readonly int2 Size;
|
||||
public readonly bool PickAny;
|
||||
public readonly string Category;
|
||||
|
||||
[FieldLoader.LoadUsing("LoadTiles")]
|
||||
public Dictionary<byte, string> Tiles = new Dictionary<byte, string>();
|
||||
public readonly Dictionary<byte, string> Tiles = new Dictionary<byte, string>();
|
||||
|
||||
public TileTemplate() { }
|
||||
public TileTemplate(MiniYaml my) { FieldLoader.Load(this, my); }
|
||||
|
||||
public TileTemplate(ushort id, string image, int2 size)
|
||||
{
|
||||
this.Id = id;
|
||||
this.Image = image;
|
||||
this.Size = size;
|
||||
}
|
||||
|
||||
static object LoadTiles(MiniYaml y)
|
||||
{
|
||||
return y.NodesDict["Tiles"].NodesDict.ToDictionary(
|
||||
@@ -73,24 +82,39 @@ namespace OpenRA
|
||||
}
|
||||
}
|
||||
|
||||
public class TileSetData
|
||||
{
|
||||
Lazy<SpriteLoader> spriteLoader;
|
||||
public SpriteLoader SpriteLoader { get { return spriteLoader.Value; } }
|
||||
|
||||
public readonly SequenceCache SequenceCache;
|
||||
|
||||
public TileSetData(ModData modData, TileSet tileSet)
|
||||
{
|
||||
spriteLoader = Exts.Lazy(() => new SpriteLoader(tileSet.Extensions, new SheetBuilder(SheetType.Indexed)));
|
||||
SequenceCache = new SequenceCache(modData, tileSet);
|
||||
}
|
||||
}
|
||||
|
||||
public class TileSet
|
||||
{
|
||||
public string Name;
|
||||
public string Id;
|
||||
public int SheetSize = 512;
|
||||
public string Palette;
|
||||
public string PlayerPalette;
|
||||
public string[] Extensions;
|
||||
public int WaterPaletteRotationBase = 0x60;
|
||||
public Dictionary<string, TerrainTypeInfo> Terrain = new Dictionary<string, TerrainTypeInfo>();
|
||||
public Dictionary<ushort, TileTemplate> Templates = new Dictionary<ushort, TileTemplate>();
|
||||
public string[] EditorTemplateOrder;
|
||||
public readonly string Name;
|
||||
public readonly string Id;
|
||||
public readonly int SheetSize = 512;
|
||||
public readonly string Palette;
|
||||
public readonly string PlayerPalette;
|
||||
public readonly string[] Extensions;
|
||||
public readonly int WaterPaletteRotationBase = 0x60;
|
||||
public readonly Dictionary<string, TerrainTypeInfo> Terrain = new Dictionary<string, TerrainTypeInfo>();
|
||||
public readonly Dictionary<ushort, TileTemplate> Templates = new Dictionary<ushort, TileTemplate>();
|
||||
public readonly string[] EditorTemplateOrder;
|
||||
|
||||
static readonly string[] Fields = { "Name", "Id", "SheetSize", "Palette", "Extensions" };
|
||||
|
||||
public TileSet() { }
|
||||
[FieldLoader.IgnoreAttribute]
|
||||
public readonly TileSetData Data;
|
||||
|
||||
public TileSet(string filepath)
|
||||
public TileSet(ModData modData, string filepath)
|
||||
{
|
||||
var yaml = MiniYaml.DictFromFile(filepath);
|
||||
|
||||
@@ -104,6 +128,16 @@ namespace OpenRA
|
||||
// Templates
|
||||
Templates = yaml["Templates"].NodesDict.Values
|
||||
.Select(y => new TileTemplate(y)).ToDictionary(t => t.Id);
|
||||
|
||||
Data = new TileSetData(modData, this);
|
||||
}
|
||||
|
||||
public TileSet(string name, string id, string palette, string[] extensions)
|
||||
{
|
||||
this.Name = name;
|
||||
this.Id = id;
|
||||
this.Palette = palette;
|
||||
this.Extensions = extensions;
|
||||
}
|
||||
|
||||
public void Save(string filepath)
|
||||
@@ -139,5 +173,7 @@ namespace OpenRA
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user