diff --git a/OpenRA.Game/GameRules/ActorInfo.cs b/OpenRA.Game/GameRules/ActorInfo.cs index 1c0e74c42b..1d7a79e1d9 100644 --- a/OpenRA.Game/GameRules/ActorInfo.cs +++ b/OpenRA.Game/GameRules/ActorInfo.cs @@ -31,7 +31,7 @@ namespace OpenRA readonly TypeDictionary traits = new TypeDictionary(); List constructOrderCache = null; - public ActorInfo(string name, MiniYaml node, Dictionary allUnits) + public ActorInfo(ObjectCreator creator, string name, MiniYaml node, Dictionary allUnits) { try { @@ -48,7 +48,7 @@ namespace OpenRA if (t.Key != "Inherits" && !t.Key.StartsWith("Inherits@")) try { - traits.Add(LoadTraitInfo(t.Key.Split('@')[0], t.Value)); + traits.Add(LoadTraitInfo(creator, t.Key.Split('@')[0], t.Value)); } catch (FieldLoader.MissingFieldsException e) { @@ -99,12 +99,12 @@ namespace OpenRA return node; } - static ITraitInfo LoadTraitInfo(string traitName, MiniYaml my) + static ITraitInfo LoadTraitInfo(ObjectCreator creator, string traitName, MiniYaml my) { if (!string.IsNullOrEmpty(my.Value)) throw new YamlException("Junk value `{0}` on trait node {1}" .F(my.Value, traitName)); - var info = Game.CreateObject(traitName + "Info"); + var info = creator.CreateObject(traitName + "Info"); try { FieldLoader.Load(info, my); diff --git a/OpenRA.Game/GameRules/RulesetCache.cs b/OpenRA.Game/GameRules/RulesetCache.cs index b5d53936c0..19cb3d83c7 100644 --- a/OpenRA.Game/GameRules/RulesetCache.cs +++ b/OpenRA.Game/GameRules/RulesetCache.cs @@ -61,7 +61,7 @@ namespace OpenRA using (new PerfTimer("Actors")) actors = LoadYamlRules(actorCache, m.Rules, map != null ? map.RuleDefinitions : NoMapRules, - (k, y) => new ActorInfo(k.Key.ToLowerInvariant(), k.Value, y)); + (k, y) => new ActorInfo(Game.ModData.ObjectCreator, k.Key.ToLowerInvariant(), k.Value, y)); using (new PerfTimer("Weapons")) weapons = LoadYamlRules(weaponCache, m.Weapons, diff --git a/OpenRA.Game/ModData.cs b/OpenRA.Game/ModData.cs index 3bca6729ec..bfd345619e 100644 --- a/OpenRA.Game/ModData.cs +++ b/OpenRA.Game/ModData.cs @@ -12,6 +12,7 @@ using System; using System.Collections.Generic; using System.IO; using System.Linq; +using System.Reflection; using OpenRA.FileSystem; using OpenRA.Graphics; using OpenRA.Widgets; @@ -38,7 +39,12 @@ namespace OpenRA { Languages = new string[0]; Manifest = new Manifest(mod); - ObjectCreator = new ObjectCreator(Manifest); + + // Allow mods to load types from the core Game assembly, and any additional assemblies they specify. + var assemblies = + new[] { typeof(Game).Assembly }.Concat( + Manifest.Assemblies.Select(path => Assembly.LoadFrom(Platform.ResolvePath(path)))); + ObjectCreator = new ObjectCreator(assemblies); Manifest.LoadCustomData(ObjectCreator); if (useLoadScreen) diff --git a/OpenRA.Game/ObjectCreator.cs b/OpenRA.Game/ObjectCreator.cs index e28636d6a4..ded80b27b2 100644 --- a/OpenRA.Game/ObjectCreator.cs +++ b/OpenRA.Game/ObjectCreator.cs @@ -22,24 +22,11 @@ namespace OpenRA readonly Cache ctorCache; readonly Pair[] assemblies; - public ObjectCreator(Manifest manifest) + public ObjectCreator(IEnumerable sourceAssemblies) { typeCache = new Cache(FindType); ctorCache = new Cache(GetCtor); - - // All the core namespaces - var asms = typeof(Game).Assembly.GetNamespaces() // Game - .Select(c => Pair.New(typeof(Game).Assembly, c)) - .ToList(); - - // Namespaces from each mod assembly - foreach (var a in manifest.Assemblies) - { - var asm = Assembly.LoadFile(Platform.ResolvePath(a)); - asms.AddRange(asm.GetNamespaces().Select(ns => Pair.New(asm, ns))); - } - - assemblies = asms.ToArray(); + assemblies = sourceAssemblies.SelectMany(asm => asm.GetNamespaces().Select(ns => Pair.New(asm, ns))).ToArray(); } public static Action MissingTypeAction =