diff --git a/OpenRa.Game/GameRules/FieldLoader.cs b/OpenRa.Game/GameRules/FieldLoader.cs index dc5107be51..55731a6445 100755 --- a/OpenRa.Game/GameRules/FieldLoader.cs +++ b/OpenRa.Game/GameRules/FieldLoader.cs @@ -16,6 +16,15 @@ namespace OpenRa.Game.GameRules } } + public static void Load(object self, MiniYaml my) + { + foreach (var x in my.Nodes) + { + var field = self.GetType().GetField(x.Key.Trim()); + field.SetValue(self, GetValue(field.FieldType, x.Value.Value.Trim())); + } + } + public static void CheckYaml( object self, Dictionary d ) { //foreach( var x in d ) diff --git a/OpenRa.Game/GameRules/NewUnitInfo.cs b/OpenRa.Game/GameRules/NewUnitInfo.cs index dd37e7115c..4b660ad71d 100755 --- a/OpenRa.Game/GameRules/NewUnitInfo.cs +++ b/OpenRa.Game/GameRules/NewUnitInfo.cs @@ -2,13 +2,14 @@ using System.Collections.Generic; using System.Linq; using OpenRa.FileFormats; +using OpenRa.Game.Traits; namespace OpenRa.Game.GameRules { class NewUnitInfo { public readonly string Parent; - public readonly Dictionary Traits = new Dictionary(); + public readonly Dictionary Traits; public NewUnitInfo( MiniYaml node ) { @@ -18,7 +19,22 @@ namespace OpenRa.Game.GameRules Parent = inherit.Value; node.Nodes.Remove( "Inherits" ); } - Traits = node.Nodes; + + Traits = node.Nodes.ToDictionary( + a => a.Key, + a => LoadTraitInfo( a.Key, a.Value )); + } + + static ITraitInfo LoadTraitInfo(string traitName, MiniYaml my) + { + var fullTypeName = typeof(ITraitInfo).Namespace + "." + traitName + "Info"; + var info = (ITraitInfo)typeof(ITraitInfo).Assembly.CreateInstance(fullTypeName); + + if (info == null) + throw new NotImplementedException("Missing traitinfo type `{0}`".F(fullTypeName)); + + FieldLoader.Load(info, my); + return info; } } } diff --git a/OpenRa.Game/GameRules/Rules.cs b/OpenRa.Game/GameRules/Rules.cs index ae9bf199f7..46a53ee424 100755 --- a/OpenRa.Game/GameRules/Rules.cs +++ b/OpenRa.Game/GameRules/Rules.cs @@ -4,6 +4,7 @@ using System.Linq; using IjwFramework.Types; using OpenRa.FileFormats; using OpenRa.Game.GameRules; +using OpenRa.Game.Traits; namespace OpenRa.Game { @@ -97,10 +98,6 @@ namespace OpenRa.Game NewUnitInfo = new Dictionary(); foreach( var kv in MiniYaml.FromFile( "ra.yaml" ) ) NewUnitInfo.Add( kv.Key.ToLowerInvariant(), new NewUnitInfo( kv.Value ) ); - - foreach( var unit in NewUnitInfo ) - foreach( var trait in unit.Value.Traits.Values ) - FieldLoader.CheckYaml( UnitInfo[ unit.Key.ToLowerInvariant() ], trait.Nodes ); } static void LoadCategories(params string[] types) diff --git a/OpenRa.Game/GameRules/UnitInfo.cs b/OpenRa.Game/GameRules/UnitInfo.cs index 6054874fe0..1b13fa1883 100755 --- a/OpenRa.Game/GameRules/UnitInfo.cs +++ b/OpenRa.Game/GameRules/UnitInfo.cs @@ -67,16 +67,16 @@ namespace OpenRa.Game.GameRules public UnitInfo(string name) { Name = name; } } - public class MobileInfo : UnitInfo + public class LegacyMobileInfo : UnitInfo { public readonly int Speed = 0; public readonly bool NoMovingFire = false; public readonly string Voice = "GenericVoice"; - public MobileInfo(string name) : base(name) { } + public LegacyMobileInfo(string name) : base(name) { } } - public class InfantryInfo : MobileInfo + public class InfantryInfo : LegacyMobileInfo { public readonly bool C4 = false; public readonly bool FraidyCat = false; @@ -87,7 +87,7 @@ namespace OpenRa.Game.GameRules public InfantryInfo(string name) : base(name) { } } - public class VehicleInfo : MobileInfo + public class VehicleInfo : LegacyMobileInfo { public readonly bool Tracked = false; diff --git a/OpenRa.Game/Sound.cs b/OpenRa.Game/Sound.cs index 537d4b59f6..84c637fa02 100644 --- a/OpenRa.Game/Sound.cs +++ b/OpenRa.Game/Sound.cs @@ -92,7 +92,7 @@ namespace OpenRa.Game { if (voicedUnit == null) return; - var mi = voicedUnit.Info as MobileInfo; + var mi = voicedUnit.Info as LegacyMobileInfo; if (mi == null) return; var vi = Rules.VoiceInfo[mi.Voice]; diff --git a/OpenRa.Game/Traits/Mobile.cs b/OpenRa.Game/Traits/Mobile.cs index de1f0dca25..7645d36cab 100644 --- a/OpenRa.Game/Traits/Mobile.cs +++ b/OpenRa.Game/Traits/Mobile.cs @@ -5,6 +5,14 @@ using OpenRa.Game.GameRules; namespace OpenRa.Game.Traits { + class MobileInfo : ITraitInfo + { + public readonly int Sight; + public readonly int ROT; + public readonly int Speed; + public object Create(Actor self) { return new Mobile(self); } + } + class Mobile : IIssueOrder, IResolveOrder, IOccupySpace, IMovement { readonly Actor self; diff --git a/OpenRa.Game/Traits/TraitsInterfaces.cs b/OpenRa.Game/Traits/TraitsInterfaces.cs index 849679042b..7a6c05611b 100644 --- a/OpenRa.Game/Traits/TraitsInterfaces.cs +++ b/OpenRa.Game/Traits/TraitsInterfaces.cs @@ -69,4 +69,6 @@ namespace OpenRa.Game.Traits public Renderable WithZOffset(int newOffset) { return new Renderable(Sprite, Pos, Palette, newOffset); } public Renderable WithPos(float2 newPos) { return new Renderable(Sprite, newPos, Palette, ZOffset); } } + + interface ITraitInfo { object Create(Actor self); } } diff --git a/OpenRa.Game/Traits/Util.cs b/OpenRa.Game/Traits/Util.cs index fa918b337d..3a71fb98ae 100755 --- a/OpenRa.Game/Traits/Util.cs +++ b/OpenRa.Game/Traits/Util.cs @@ -127,7 +127,7 @@ namespace OpenRa.Game.Traits public static float GetEffectiveSpeed(Actor self) { - var mi = self.Info as MobileInfo; + var mi = self.Info as LegacyMobileInfo; if (mi == null) return 0f; var modifier = self.traits