diff --git a/OpenRA.FileFormats/Manifest.cs b/OpenRA.FileFormats/Manifest.cs index 7103737467..be1cfe2e86 100644 --- a/OpenRA.FileFormats/Manifest.cs +++ b/OpenRA.FileFormats/Manifest.cs @@ -21,7 +21,8 @@ namespace OpenRA.FileFormats Mods, Folders, Packages, Rules, Sequences, Cursors, Chrome, Assemblies, ChromeLayout, Weapons, Voices, Music, Movies, TileSets; - + public string[] LocalRules = new string[0]; + public string[] LocalAssemblies = new string[0]; public readonly string ShellmapUid, LoadScreen; public readonly int TileSize = 24; diff --git a/OpenRA.Game/GameRules/Rules.cs b/OpenRA.Game/GameRules/Rules.cs index 94686e8693..4f038c2b69 100755 --- a/OpenRA.Game/GameRules/Rules.cs +++ b/OpenRA.Game/GameRules/Rules.cs @@ -27,7 +27,9 @@ namespace OpenRA public static void LoadRules(Manifest m, Map map) { - Info = LoadYamlRules(m.Rules, map.Rules, (k, y) => new ActorInfo(k.Key.ToLowerInvariant(), k.Value, y)); + // Added support to extend the list of rules (add it to m.LocalRules) + // Should only be used to add ITraitNoSync traits! (otherwise BOOM) + Info = LoadYamlRules(m.Rules.Concat(m.LocalRules).ToArray(), map.Rules, (k, y) => new ActorInfo(k.Key.ToLowerInvariant(), k.Value, y)); Weapons = LoadYamlRules(m.Weapons, new List(), (k, _) => new WeaponInfo(k.Key.ToLowerInvariant(), k.Value)); Voices = LoadYamlRules(m.Voices, new List(), (k, _) => new VoiceInfo(k.Value)); Music = LoadYamlRules(m.Music, new List(), (k, _) => new MusicInfo(k.Key, k.Value)); diff --git a/OpenRA.Game/ObjectCreator.cs b/OpenRA.Game/ObjectCreator.cs index 136bfc062f..bdc2337af7 100755 --- a/OpenRA.Game/ObjectCreator.cs +++ b/OpenRA.Game/ObjectCreator.cs @@ -19,7 +19,7 @@ namespace OpenRA .ToList(); // Namespaces from each mod assembly - foreach (var a in manifest.Assemblies) + foreach (var a in manifest.Assemblies.Concat(manifest.LocalAssemblies)) { var asm = Assembly.LoadFile(Path.GetFullPath(a)); asms.AddRange(asm.GetNamespaces().Select(ns => Pair.New(asm, ns)));