diff --git a/OpenRa.FileFormats/MiniYaml.cs b/OpenRa.FileFormats/MiniYaml.cs index 3b51b27e72..b26b69d9b1 100755 --- a/OpenRa.FileFormats/MiniYaml.cs +++ b/OpenRa.FileFormats/MiniYaml.cs @@ -54,5 +54,37 @@ namespace OpenRa.FileFormats } return levels[ 0 ]; } + + public static Dictionary Merge( Dictionary a, Dictionary b ) + { + if( a.Count == 0 ) + return b; + if( b.Count == 0 ) + return a; + + var ret = new Dictionary(); + + var keys = a.Keys.Union( b.Keys ).ToList(); + + foreach( var key in keys ) + { + MiniYaml aa, bb; + a.TryGetValue( key, out aa ); + b.TryGetValue( key, out bb ); + ret.Add( key, Merge( aa, bb ) ); + } + + return ret; + } + + public static MiniYaml Merge( MiniYaml a, MiniYaml b ) + { + if( a == null ) + return b; + if( b == null ) + return a; + + return new MiniYaml( a.Value ?? b.Value, Merge( a.Nodes, b.Nodes ) ); + } } } diff --git a/OpenRa.Game/GameRules/NewUnitInfo.cs b/OpenRa.Game/GameRules/NewUnitInfo.cs index 62cee867be..1f84bce4e0 100755 --- a/OpenRa.Game/GameRules/NewUnitInfo.cs +++ b/OpenRa.Game/GameRules/NewUnitInfo.cs @@ -8,24 +8,31 @@ namespace OpenRa.Game.GameRules { class NewUnitInfo { - public readonly string Parent; public readonly TypeDictionary Traits = new TypeDictionary(); public readonly string Name; - public NewUnitInfo( string name, MiniYaml node ) + public NewUnitInfo( string name, MiniYaml node, Dictionary allUnits ) { Name = name; - // todo: make inheritance actually work - MiniYaml inherit; - if( node.Nodes.TryGetValue( "Inherits", out inherit ) ) - { - Parent = inherit.Value; - node.Nodes.Remove( "Inherits" ); - } + foreach( var t in MergeWithParent( node, allUnits ).Nodes ) + if( t.Key != "Inherits" ) + Traits.Add( LoadTraitInfo( t.Key, t.Value ) ); + } - foreach (var t in node.Nodes) - Traits.Add(LoadTraitInfo(t.Key, t.Value)); + static MiniYaml MergeWithParent( MiniYaml node, Dictionary allUnits ) + { + MiniYaml inherits; + node.Nodes.TryGetValue( "Inherits", out inherits ); + if( inherits.Value == null || string.IsNullOrEmpty( inherits.Value ) ) + return node; + + MiniYaml parent; + allUnits.TryGetValue( inherits.Value, out parent ); + if( parent == null ) + return node; + + return MiniYaml.Merge( node, MergeWithParent( parent, allUnits ) ); } static ITraitInfo LoadTraitInfo(string traitName, MiniYaml my) diff --git a/OpenRa.Game/GameRules/Rules.cs b/OpenRa.Game/GameRules/Rules.cs index 87eb755a35..d926f488a4 100755 --- a/OpenRa.Game/GameRules/Rules.cs +++ b/OpenRa.Game/GameRules/Rules.cs @@ -90,9 +90,13 @@ namespace OpenRa.Game SupportPowerInfo = new InfoLoader( Pair.New>("SupportPower", _ => new SupportPowerInfo())); + var yamlRules = MiniYaml.FromFile("ra.yaml"); + if( useAftermath ) + yamlRules = MiniYaml.Merge( MiniYaml.FromFile( "aftermath.yaml" ), yamlRules ); + NewUnitInfo = new Dictionary(); - foreach (var kv in MiniYaml.FromFile("ra.yaml")) - NewUnitInfo.Add(kv.Key.ToLowerInvariant(), new NewUnitInfo(kv.Key.ToLowerInvariant(), kv.Value)); + foreach( var kv in yamlRules ) + NewUnitInfo.Add(kv.Key.ToLowerInvariant(), new NewUnitInfo(kv.Key.ToLowerInvariant(), kv.Value, yamlRules)); TechTree = new TechTree(); Map = new Map( AllRules );