diff --git a/OpenRA.Game/GameRules/RulesetCache.cs b/OpenRA.Game/GameRules/RulesetCache.cs index d15aed6600..715ea41f63 100644 --- a/OpenRA.Game/GameRules/RulesetCache.cs +++ b/OpenRA.Game/GameRules/RulesetCache.cs @@ -11,6 +11,7 @@ using System; using System.Collections.Generic; using System.Linq; +using OpenRA.FileSystem; using OpenRA.GameRules; using OpenRA.Graphics; using OpenRA.Support; @@ -47,7 +48,7 @@ namespace OpenRA /// Cache and return the Ruleset for a given map. /// If a map isn't specified then return the default mod Ruleset. /// - public Ruleset Load(Map map = null) + public Ruleset Load(IReadOnlyFileSystem fileSystem, Map map = null) { var m = modData.Manifest; @@ -59,38 +60,38 @@ namespace OpenRA Dictionary tileSets; using (new PerfTimer("Actors")) - actors = LoadYamlRules(actorCache, m.Rules, + actors = LoadYamlRules(fileSystem, actorCache, m.Rules, map != null ? map.RuleDefinitions : NoMapRules, k => new ActorInfo(Game.ModData.ObjectCreator, k.Key.ToLowerInvariant(), k.Value)); using (new PerfTimer("Weapons")) - weapons = LoadYamlRules(weaponCache, m.Weapons, + weapons = LoadYamlRules(fileSystem, weaponCache, m.Weapons, map != null ? map.WeaponDefinitions : NoMapRules, k => new WeaponInfo(k.Key.ToLowerInvariant(), k.Value)); using (new PerfTimer("Voices")) - voices = LoadYamlRules(voiceCache, m.Voices, + voices = LoadYamlRules(fileSystem, voiceCache, m.Voices, map != null ? map.VoiceDefinitions : NoMapRules, k => new SoundInfo(k.Value)); using (new PerfTimer("Notifications")) - notifications = LoadYamlRules(notificationCache, m.Notifications, + notifications = LoadYamlRules(fileSystem, notificationCache, m.Notifications, map != null ? map.NotificationDefinitions : NoMapRules, k => new SoundInfo(k.Value)); using (new PerfTimer("Music")) - music = LoadYamlRules(musicCache, m.Music, + music = LoadYamlRules(fileSystem, musicCache, m.Music, map != null ? map.MusicDefinitions : NoMapRules, k => new MusicInfo(k.Key, k.Value)); using (new PerfTimer("TileSets")) - tileSets = LoadTileSets(tileSetCache, sequenceCaches, m.TileSets); + tileSets = LoadTileSets(fileSystem, tileSetCache, sequenceCaches, m.TileSets); - var sequences = sequenceCaches.ToDictionary(kvp => kvp.Key, kvp => new SequenceProvider(kvp.Value, map)); + var sequences = sequenceCaches.ToDictionary(kvp => kvp.Key, kvp => new SequenceProvider(fileSystem, kvp.Value, map)); return new Ruleset(actors, weapons, voices, notifications, music, tileSets, sequences); } - Dictionary LoadYamlRules( + Dictionary LoadYamlRules(IReadOnlyFileSystem fileSystem, Dictionary itemCache, string[] files, List nodes, Func f) @@ -112,7 +113,7 @@ namespace OpenRA return t; }; - var tree = MiniYaml.Merge(files.Select(s => MiniYaml.FromStream(modData.ModFiles.Open(s))).Append(nodes)) + var tree = MiniYaml.Merge(files.Select(s => MiniYaml.FromStream(fileSystem.Open(s))).Append(nodes)) .ToDictionaryWithConflictLog(n => n.Key, n => n.Value, "LoadYamlRules", null, null); RaiseProgress(); @@ -121,7 +122,7 @@ namespace OpenRA return itemSet; } - Dictionary LoadTileSets(Dictionary itemCache, Dictionary sequenceCaches, string[] files) + Dictionary LoadTileSets(IReadOnlyFileSystem fileSystem, Dictionary itemCache, Dictionary sequenceCaches, string[] files) { var items = new Dictionary(); @@ -136,7 +137,7 @@ namespace OpenRA itemCache.Add(file, t); // every time we load a tile set, we create a sequence cache for it - var sc = new SequenceCache(modData, t); + var sc = new SequenceCache(modData, fileSystem, t); sequenceCaches.Add(t.Id, sc); items.Add(t.Id, t); diff --git a/OpenRA.Game/Graphics/CursorProvider.cs b/OpenRA.Game/Graphics/CursorProvider.cs index 1d69d65f1c..100d8033f3 100644 --- a/OpenRA.Game/Graphics/CursorProvider.cs +++ b/OpenRA.Game/Graphics/CursorProvider.cs @@ -21,8 +21,9 @@ namespace OpenRA.Graphics public CursorProvider(ModData modData) { + var fileSystem = modData.DefaultFileSystem; var sequenceYaml = MiniYaml.Merge(modData.Manifest.Cursors.Select( - s => MiniYaml.FromStream(modData.ModFiles.Open(s)))); + s => MiniYaml.FromStream(fileSystem.Open(s)))); var shadowIndex = new int[] { }; @@ -36,11 +37,11 @@ namespace OpenRA.Graphics var palettes = new Dictionary(); foreach (var p in nodesDict["Palettes"].Nodes) - palettes.Add(p.Key, new ImmutablePalette(modData.ModFiles.Open(p.Value.Value), shadowIndex)); + palettes.Add(p.Key, new ImmutablePalette(fileSystem.Open(p.Value.Value), shadowIndex)); Palettes = palettes.AsReadOnly(); - var frameCache = new FrameCache(modData.SpriteLoaders); + var frameCache = new FrameCache(fileSystem, modData.SpriteLoaders); var cursors = new Dictionary(); foreach (var s in nodesDict["Cursors"].Nodes) foreach (var sequence in s.Value.Nodes) diff --git a/OpenRA.Game/Graphics/SequenceProvider.cs b/OpenRA.Game/Graphics/SequenceProvider.cs index ce8ebd460e..21d62b9311 100644 --- a/OpenRA.Game/Graphics/SequenceProvider.cs +++ b/OpenRA.Game/Graphics/SequenceProvider.cs @@ -11,6 +11,7 @@ using System; using System.Collections.Generic; using System.Linq; +using OpenRA.FileSystem; namespace OpenRA.Graphics { @@ -46,9 +47,9 @@ namespace OpenRA.Graphics readonly Lazy sequences; public readonly SpriteCache SpriteCache; - public SequenceProvider(SequenceCache cache, Map map) + public SequenceProvider(IReadOnlyFileSystem fileSystem, SequenceCache cache, Map map) { - sequences = Exts.Lazy(() => cache.LoadSequences(map)); + sequences = Exts.Lazy(() => cache.LoadSequences(fileSystem, map)); SpriteCache = cache.SpriteCache; } @@ -106,25 +107,25 @@ namespace OpenRA.Graphics readonly Dictionary sequenceCache = new Dictionary(); - public SequenceCache(ModData modData, TileSet tileSet) + public SequenceCache(ModData modData, IReadOnlyFileSystem fileSystem, TileSet tileSet) { this.modData = modData; this.tileSet = tileSet; // Every time we load a tile set, we create a sequence cache for it - spriteCache = Exts.Lazy(() => new SpriteCache(modData.SpriteLoaders, new SheetBuilder(SheetType.Indexed))); + spriteCache = Exts.Lazy(() => new SpriteCache(fileSystem, modData.SpriteLoaders, new SheetBuilder(SheetType.Indexed))); } - public Sequences LoadSequences(Map map) + public Sequences LoadSequences(IReadOnlyFileSystem fileSystem, Map map) { using (new Support.PerfTimer("LoadSequences")) - return Load(map != null ? map.SequenceDefinitions : new List()); + return Load(fileSystem, map != null ? map.SequenceDefinitions : new List()); } - Sequences Load(List sequenceNodes) + Sequences Load(IReadOnlyFileSystem fileSystem, List sequenceNodes) { var nodes = MiniYaml.Merge(modData.Manifest.Sequences - .Select(s => MiniYaml.FromStream(modData.ModFiles.Open(s))) + .Select(s => MiniYaml.FromStream(fileSystem.Open(s))) .Append(sequenceNodes)); var items = new Dictionary(); diff --git a/OpenRA.Game/Graphics/SpriteLoader.cs b/OpenRA.Game/Graphics/SpriteLoader.cs index beffa6501d..3399d512a8 100644 --- a/OpenRA.Game/Graphics/SpriteLoader.cs +++ b/OpenRA.Game/Graphics/SpriteLoader.cs @@ -11,6 +11,7 @@ using System.Drawing; using System.IO; using System.Linq; +using OpenRA.FileSystem; using OpenRA.Primitives; namespace OpenRA.Graphics @@ -34,11 +35,11 @@ namespace OpenRA.Graphics public readonly SheetBuilder SheetBuilder; readonly Cache sprites; - public SpriteCache(ISpriteLoader[] loaders, SheetBuilder sheetBuilder) + public SpriteCache(IReadOnlyFileSystem fileSystem, ISpriteLoader[] loaders, SheetBuilder sheetBuilder) { SheetBuilder = sheetBuilder; - sprites = new Cache(filename => SpriteLoader.GetSprites(filename, loaders, sheetBuilder)); + sprites = new Cache(filename => SpriteLoader.GetSprites(fileSystem, filename, loaders, sheetBuilder)); } public Sprite[] this[string filename] { get { return sprites[filename]; } } @@ -48,9 +49,9 @@ namespace OpenRA.Graphics { readonly Cache frames; - public FrameCache(ISpriteLoader[] loaders) + public FrameCache(IReadOnlyFileSystem fileSystem, ISpriteLoader[] loaders) { - frames = new Cache(filename => SpriteLoader.GetFrames(filename, loaders)); + frames = new Cache(filename => SpriteLoader.GetFrames(fileSystem, filename, loaders)); } public ISpriteFrame[] this[string filename] { get { return frames[filename]; } } @@ -58,14 +59,14 @@ namespace OpenRA.Graphics public static class SpriteLoader { - public static Sprite[] GetSprites(string filename, ISpriteLoader[] loaders, SheetBuilder sheetBuilder) + public static Sprite[] GetSprites(IReadOnlyFileSystem fileSystem, string filename, ISpriteLoader[] loaders, SheetBuilder sheetBuilder) { - return GetFrames(filename, loaders).Select(a => sheetBuilder.Add(a)).ToArray(); + return GetFrames(fileSystem, filename, loaders).Select(a => sheetBuilder.Add(a)).ToArray(); } - public static ISpriteFrame[] GetFrames(string filename, ISpriteLoader[] loaders) + public static ISpriteFrame[] GetFrames(IReadOnlyFileSystem fileSystem, string filename, ISpriteLoader[] loaders) { - using (var stream = Game.ModData.ModFiles.Open(filename)) + using (var stream = fileSystem.Open(filename)) { ISpriteFrame[] frames; foreach (var loader in loaders) diff --git a/OpenRA.Game/Graphics/Theater.cs b/OpenRA.Game/Graphics/Theater.cs index 948a89a307..bfbe2da013 100644 --- a/OpenRA.Game/Graphics/Theater.cs +++ b/OpenRA.Game/Graphics/Theater.cs @@ -56,7 +56,7 @@ namespace OpenRA.Graphics sheetBuilder = new SheetBuilder(type, allocate); random = new MersenneTwister(); - var frameCache = new FrameCache(Game.ModData.SpriteLoaders); + var frameCache = new FrameCache(Game.ModData.DefaultFileSystem, Game.ModData.SpriteLoaders); foreach (var t in tileset.Templates) { var variants = new List(); diff --git a/OpenRA.Game/Map/Map.cs b/OpenRA.Game/Map/Map.cs index 98ec38609a..f89442f0e9 100644 --- a/OpenRA.Game/Map/Map.cs +++ b/OpenRA.Game/Map/Map.cs @@ -372,7 +372,7 @@ namespace OpenRA { try { - return Game.ModData.RulesetCache.Load(this); + return Game.ModData.RulesetCache.Load(Game.ModData.DefaultFileSystem, this); } catch (Exception e) { diff --git a/OpenRA.Game/ModData.cs b/OpenRA.Game/ModData.cs index 64fcafb742..996694d1d6 100644 --- a/OpenRA.Game/ModData.cs +++ b/OpenRA.Game/ModData.cs @@ -72,7 +72,7 @@ namespace OpenRA SpriteSequenceLoader = (ISpriteSequenceLoader)ctor.Invoke(new[] { this }); SpriteSequenceLoader.OnMissingSpriteError = s => Log.Write("debug", s); - defaultRules = Exts.Lazy(() => RulesetCache.Load()); + defaultRules = Exts.Lazy(() => RulesetCache.Load(DefaultFileSystem)); initialThreadId = System.Threading.Thread.CurrentThread.ManagedThreadId; } diff --git a/OpenRA.Mods.Common/UtilityCommands/CheckSequenceSprites.cs b/OpenRA.Mods.Common/UtilityCommands/CheckSequenceSprites.cs index 6fb0967cbb..b56bb80e31 100644 --- a/OpenRA.Mods.Common/UtilityCommands/CheckSequenceSprites.cs +++ b/OpenRA.Mods.Common/UtilityCommands/CheckSequenceSprites.cs @@ -36,8 +36,8 @@ namespace OpenRA.Mods.Common.UtilityCommands { var ts = new TileSet(modData, t); Console.WriteLine("Tileset: " + ts.Name); - var sc = new SpriteCache(modData.SpriteLoaders, new SheetBuilder(SheetType.Indexed)); - var nodes = MiniYaml.Merge(modData.Manifest.Sequences.Select(s => MiniYaml.FromStream(modData.ModFiles.Open(s)))); + var sc = new SpriteCache(modData.DefaultFileSystem, modData.SpriteLoaders, new SheetBuilder(SheetType.Indexed)); + var nodes = MiniYaml.Merge(modData.Manifest.Sequences.Select(s => MiniYaml.FromStream(modData.DefaultFileSystem.Open(s)))); foreach (var n in nodes) modData.SpriteSequenceLoader.ParseSequences(modData, ts, sc, n); } diff --git a/OpenRA.Mods.Common/UtilityCommands/CheckYaml.cs b/OpenRA.Mods.Common/UtilityCommands/CheckYaml.cs index e00e712621..7b6897920e 100644 --- a/OpenRA.Mods.Common/UtilityCommands/CheckYaml.cs +++ b/OpenRA.Mods.Common/UtilityCommands/CheckYaml.cs @@ -56,17 +56,17 @@ namespace OpenRA.Mods.Common.UtilityCommands var maps = new List(); if (args.Length < 2) { - Console.WriteLine("Testing mod: {0}".F(Game.ModData.Manifest.Mod.Title)); + Console.WriteLine("Testing mod: {0}".F(modData.Manifest.Mod.Title)); // Run all rule checks on the default mod rules. - CheckRules(Game.ModData.DefaultRules); + CheckRules(modData, modData.DefaultRules); // Run all generic (not mod-level) checks here. - foreach (var customPassType in Game.ModData.ObjectCreator.GetTypesImplementing()) + foreach (var customPassType in modData.ObjectCreator.GetTypesImplementing()) { try { - var customPass = (ILintPass)Game.ModData.ObjectCreator.CreateBasic(customPassType); + var customPass = (ILintPass)modData.ObjectCreator.CreateBasic(customPassType); customPass.Run(EmitError, EmitWarning); } catch (Exception e) @@ -75,8 +75,8 @@ namespace OpenRA.Mods.Common.UtilityCommands } } - Game.ModData.MapCache.LoadMaps(); - maps.AddRange(Game.ModData.MapCache + modData.MapCache.LoadMaps(); + maps.AddRange(modData.MapCache .Where(m => m.Status == MapStatus.Available) .Select(m => new Map(m.Path))); } @@ -90,14 +90,14 @@ namespace OpenRA.Mods.Common.UtilityCommands // Run all rule checks on the map if it defines custom rules. if (testMap.RuleDefinitions.Any() || testMap.VoiceDefinitions.Any() || testMap.WeaponDefinitions.Any()) - CheckRules(testMap.Rules, testMap); + CheckRules(modData, testMap.Rules, testMap); // Run all map-level checks here. - foreach (var customMapPassType in Game.ModData.ObjectCreator.GetTypesImplementing()) + foreach (var customMapPassType in modData.ObjectCreator.GetTypesImplementing()) { try { - var customMapPass = (ILintMapPass)Game.ModData.ObjectCreator.CreateBasic(customMapPassType); + var customMapPass = (ILintMapPass)modData.ObjectCreator.CreateBasic(customMapPassType); customMapPass.Run(EmitError, EmitWarning, testMap); } catch (Exception e) @@ -120,14 +120,14 @@ namespace OpenRA.Mods.Common.UtilityCommands } } - void CheckRules(Ruleset rules, Map map = null) + void CheckRules(ModData modData, Ruleset rules, Map map = null) { - foreach (var customRulesPassType in Game.ModData.ObjectCreator.GetTypesImplementing()) + foreach (var customRulesPassType in modData.ObjectCreator.GetTypesImplementing()) { try { - Game.ModData.RulesetCache.Load(map); - var customRulesPass = (ILintRulesPass)Game.ModData.ObjectCreator.CreateBasic(customRulesPassType); + modData.RulesetCache.Load(modData.DefaultFileSystem, map); + var customRulesPass = (ILintRulesPass)modData.ObjectCreator.CreateBasic(customRulesPassType); customRulesPass.Run(EmitError, EmitWarning, rules); } catch (Exception e) diff --git a/OpenRA.Mods.Common/UtilityCommands/ConvertSpriteToPngCommand.cs b/OpenRA.Mods.Common/UtilityCommands/ConvertSpriteToPngCommand.cs index 04401a8469..87b1ea5e74 100644 --- a/OpenRA.Mods.Common/UtilityCommands/ConvertSpriteToPngCommand.cs +++ b/OpenRA.Mods.Common/UtilityCommands/ConvertSpriteToPngCommand.cs @@ -46,7 +46,7 @@ namespace OpenRA.Mods.Common.UtilityCommands var palette = new ImmutablePalette(args[2], shadowIndex); - var frames = SpriteLoader.GetFrames(src, modData.SpriteLoaders); + var frames = SpriteLoader.GetFrames(modData.DefaultFileSystem, src, modData.SpriteLoaders); var usePadding = !args.Contains("--nopadding"); var count = 0; diff --git a/OpenRA.Mods.Common/UtilityCommands/ExtractLanguageStringsCommand.cs b/OpenRA.Mods.Common/UtilityCommands/ExtractLanguageStringsCommand.cs index be19d4fccd..b43879818c 100644 --- a/OpenRA.Mods.Common/UtilityCommands/ExtractLanguageStringsCommand.cs +++ b/OpenRA.Mods.Common/UtilityCommands/ExtractLanguageStringsCommand.cs @@ -29,13 +29,13 @@ namespace OpenRA.Mods.Common.UtilityCommands { // HACK: The engine code assumes that Game.modData is set. Game.ModData = modData; - Game.ModData.RulesetCache.Load(); + modData.RulesetCache.Load(modData.DefaultFileSystem); var types = Game.ModData.ObjectCreator.GetTypes(); var translatableFields = types.SelectMany(t => t.GetFields()) .Where(f => f.HasAttribute()).Distinct(); - foreach (var filename in Game.ModData.Manifest.ChromeLayout) + foreach (var filename in modData.Manifest.ChromeLayout) { Console.WriteLine("# {0}:", filename); var yaml = MiniYaml.FromFile(filename); diff --git a/OpenRA.Mods.Common/UtilityCommands/FixClassicTilesets.cs b/OpenRA.Mods.Common/UtilityCommands/FixClassicTilesets.cs index 44b8066c3d..a02145962f 100644 --- a/OpenRA.Mods.Common/UtilityCommands/FixClassicTilesets.cs +++ b/OpenRA.Mods.Common/UtilityCommands/FixClassicTilesets.cs @@ -31,7 +31,7 @@ namespace OpenRA.Mods.Common.UtilityCommands { // HACK: The engine code assumes that Game.modData is set. Game.ModData = modData; - modData.ModFiles.LoadFromManifest(Game.ModData.Manifest); + modData.ModFiles.LoadFromManifest(modData.Manifest); var imageField = typeof(TerrainTemplateInfo).GetField("Image"); var pickAnyField = typeof(TerrainTemplateInfo).GetField("PickAny"); @@ -43,10 +43,10 @@ namespace OpenRA.Mods.Common.UtilityCommands var single = new int2(1, 1); var exts = new[] { "" }.Concat(args[1].Split(',')); - foreach (var t in Game.ModData.Manifest.TileSets) + foreach (var t in modData.Manifest.TileSets) { - var ts = new TileSet(Game.ModData, t); - var frameCache = new FrameCache(Game.ModData.SpriteLoaders); + var ts = new TileSet(modData, t); + var frameCache = new FrameCache(modData.DefaultFileSystem, modData.SpriteLoaders); Console.WriteLine("Tileset: " + ts.Name); foreach (var template in ts.Templates.Values) diff --git a/OpenRA.Mods.Common/UtilityCommands/ImportLegacyMapCommand.cs b/OpenRA.Mods.Common/UtilityCommands/ImportLegacyMapCommand.cs index 5f21e83729..d7b539af93 100644 --- a/OpenRA.Mods.Common/UtilityCommands/ImportLegacyMapCommand.cs +++ b/OpenRA.Mods.Common/UtilityCommands/ImportLegacyMapCommand.cs @@ -45,10 +45,10 @@ namespace OpenRA.Mods.Common.UtilityCommands // HACK: The engine code assumes that Game.modData is set. Game.ModData = modData; - Rules = Game.ModData.RulesetCache.Load(); + Rules = modData.RulesetCache.Load(modData.DefaultFileSystem); var filename = args[1]; - using (var stream = Game.ModData.ModFiles.Open(filename)) + using (var stream = modData.ModFiles.Open(filename)) { var file = new IniFile(stream); var basic = file.GetSection("Basic"); @@ -66,7 +66,7 @@ namespace OpenRA.Mods.Common.UtilityCommands Map.Description = ExtractBriefing(file); - Map.RequiresMod = Game.ModData.Manifest.Mod.Id; + Map.RequiresMod = modData.Manifest.Mod.Id; SetBounds(Map, mapSection); diff --git a/OpenRA.Mods.Common/UtilityCommands/RemapShpCommand.cs b/OpenRA.Mods.Common/UtilityCommands/RemapShpCommand.cs index e592fcff2b..231341d02d 100644 --- a/OpenRA.Mods.Common/UtilityCommands/RemapShpCommand.cs +++ b/OpenRA.Mods.Common/UtilityCommands/RemapShpCommand.cs @@ -38,17 +38,17 @@ namespace OpenRA.Mods.Common.UtilityCommands remap[i] = i; var srcMod = args[1].Split(':')[0]; + var srcModData = new ModData(srcMod); + Game.ModData = srcModData; - Game.ModData = new ModData(srcMod); - Game.ModData.ModFiles.LoadFromManifest(Game.ModData.Manifest); - var srcRules = Game.ModData.RulesetCache.Load(); + var srcRules = srcModData.RulesetCache.Load(srcModData.DefaultFileSystem); var srcPaletteInfo = srcRules.Actors["player"].TraitInfo(); var srcRemapIndex = srcPaletteInfo.RemapIndex; var destMod = args[2].Split(':')[0]; - Game.ModData = new ModData(destMod); - Game.ModData.ModFiles.LoadFromManifest(Game.ModData.Manifest); - var destRules = Game.ModData.RulesetCache.Load(); + var destModData = new ModData(destMod); + Game.ModData = destModData; + var destRules = destModData.RulesetCache.Load(destModData.DefaultFileSystem); var destPaletteInfo = destRules.Actors["player"].TraitInfo(); var destRemapIndex = destPaletteInfo.RemapIndex; var shadowIndex = new int[] { }; diff --git a/OpenRA.Mods.D2k/UtilityCommands/ImportD2kMapCommand.cs b/OpenRA.Mods.D2k/UtilityCommands/ImportD2kMapCommand.cs index 5b6e596151..7656189501 100644 --- a/OpenRA.Mods.D2k/UtilityCommands/ImportD2kMapCommand.cs +++ b/OpenRA.Mods.D2k/UtilityCommands/ImportD2kMapCommand.cs @@ -28,7 +28,7 @@ namespace OpenRA.Mods.D2k.UtilityCommands // HACK: The engine code assumes that Game.modData is set. Game.ModData = modData; - var rules = Game.ModData.RulesetCache.Load(); + var rules = modData.RulesetCache.Load(modData.DefaultFileSystem); var map = D2kMapImporter.Import(args[1], modData.Manifest.Mod.Id, args[2], rules);