From 80bcd23ba7f57c21c602519f4c8dbf7c2cf04094 Mon Sep 17 00:00:00 2001 From: Bob Date: Tue, 20 Oct 2009 18:17:08 +1300 Subject: [PATCH] Traits is now data-driven. Actor.cs is now SMALL. (win) - FieldLoader can now handle arrays. This might be useful for Prerequisites, Owner fields. --- OpenRa.DataStructures/TypeDictionary.cs | 7 +- OpenRa.Game/Actor.cs | 113 +++--------------------- OpenRa.Game/GameRules/FieldLoader.cs | 48 ++++++---- OpenRa.Game/GameRules/UnitInfo.cs | 2 + OpenRa.Game/TechTree/Item.cs | 1 - campaignUnits.ini | 2 +- units.ini | 64 ++++++++++++-- 7 files changed, 108 insertions(+), 129 deletions(-) diff --git a/OpenRa.DataStructures/TypeDictionary.cs b/OpenRa.DataStructures/TypeDictionary.cs index 8880755bd1..d68146a056 100755 --- a/OpenRa.DataStructures/TypeDictionary.cs +++ b/OpenRa.DataStructures/TypeDictionary.cs @@ -8,9 +8,14 @@ namespace OpenRa { Dictionary inner = new Dictionary(); + public void Add( Type t, object val ) + { + inner.Add( t, val ); + } + public void Add( T val ) { - inner.Add( typeof( T ), val ); + Add( typeof( T ), val ); } public void Remove() diff --git a/OpenRa.Game/Actor.cs b/OpenRa.Game/Actor.cs index fc46fc9bf7..24d6768a4b 100755 --- a/OpenRa.Game/Actor.cs +++ b/OpenRa.Game/Actor.cs @@ -24,106 +24,19 @@ namespace OpenRa.Game unitInfo = Rules.UnitInfo[ name ]; Location = location; CenterLocation = new float2( 12, 12 ) + Game.CellSize * (float2)Location; - Owner = owner; - - switch( name ) - { - ///// vehicles ///// - case "mcv": - traits.Add( new Traits.Mobile( this ) ); - traits.Add( new Traits.RenderUnit( this ) ); - traits.Add( new Traits.McvDeploy( this ) ); - break; - case "mnly": - case "apc": - case "v2rl": - case "arty": - traits.Add( new Traits.Mobile( this ) ); - traits.Add( new Traits.RenderUnit( this ) ); - break; - case "jeep": - case "1tnk": - case "2tnk": - case "3tnk": - case "4tnk": - traits.Add( new Traits.Mobile( this ) ); - traits.Add( new Traits.Turreted( this ) ); - traits.Add( new Traits.AttackTurreted( this ) ); - traits.Add( new Traits.RenderUnitTurreted( this ) ); - break; - case "mrj": - case "mgg": - // TODO: these aren't actually turreted; they just have spinning-things - traits.Add( new Traits.Mobile( this ) ); - traits.Add( new Traits.Turreted( this ) ); - traits.Add( new Traits.RenderUnitTurreted( this ) ); - break; - case "harv": - traits.Add( new Traits.Mobile( this ) ); - traits.Add( new Traits.RenderUnit( this ) ); - break; - ///// TODO: infantry ///// - - ///// TODO: boats ///// - - ///// TODO: planes ///// - - ///// buildings ///// - //TODO: SBAG, BRIK, FENC, etc - case "iron": - case "pdox": - case "mslo": - case "atek": - case "stek": - case "fact": - case "proc": - case "hpad": - case "afld": - case "dome": - case "powr": - case "apwr": - case "barr": - case "tent": - case "kenn": - case "fix": - case "spen": - case "syrd": - case "gap": - case "pbox": - case "hbox": - case "tsla": - case "ftur": - case "facf": - case "syrf": - case "spef": - case "domf": - traits.Add( new Traits.Building( this ) ); - traits.Add( new Traits.RenderBuilding( this ) ); - break; - case "weap": - case "weaf": - traits.Add( new Traits.Building( this ) ); - traits.Add( new Traits.RenderWarFactory( this ) ); - break; - case "gun": - case "agun": - case "sam": - traits.Add( new Traits.Building( this ) ); - traits.Add( new Traits.Turreted( this ) ); - traits.Add( new Traits.RenderBuildingTurreted( this ) ); - break; - case "silo": - traits.Add(new Traits.Building(this)); - traits.Add(new Traits.RenderBuildingOre(this)); - break; - - case "fcom": - traits.Add( new Traits.Building( this ) ); - traits.Add( new Traits.RenderBuilding( this ) ); - break; - default: - throw new NotImplementedException( "Actor traits for " + name ); - } + Owner = owner; + + if( unitInfo.Traits != null ) + { + foreach( var traitName in unitInfo.Traits ) + { + var type = typeof( Traits.Mobile ).Assembly.GetType( typeof( Traits.Mobile ).Namespace + "." + traitName, true, false ); + var ctor = type.GetConstructor( new Type[] { typeof( Actor ) } ); + traits.Add( type, ctor.Invoke( new object[] { this } ) ); + } + } + else + throw new InvalidOperationException( "No Actor traits for " + unitInfo.Name + "; add Traits= to units.ini for appropriate unit" ); } public Actor( TreeReference tree, TreeCache treeRenderer, int2 mapOffset ) diff --git a/OpenRa.Game/GameRules/FieldLoader.cs b/OpenRa.Game/GameRules/FieldLoader.cs index 9c7b17d8af..2822ec7c83 100755 --- a/OpenRa.Game/GameRules/FieldLoader.cs +++ b/OpenRa.Game/GameRules/FieldLoader.cs @@ -13,26 +13,40 @@ namespace OpenRa.Game.GameRules foreach( var x in ini ) { var field = self.GetType().GetField( x.Key ); - if( field.FieldType == typeof( int ) ) - field.SetValue( self, int.Parse( x.Value ) ); - - else if( field.FieldType == typeof( float ) ) - field.SetValue( self, float.Parse( x.Value ) ); - - else if( field.FieldType == typeof( string ) ) - field.SetValue( self, x.Value.ToLowerInvariant() ); - - else if( field.FieldType.IsEnum ) - field.SetValue( self, Enum.Parse( field.FieldType, x.Value ) ); - - else if( field.FieldType == typeof( bool ) ) - field.SetValue( self, ParseYesNo( x.Value ) ); - - else - do { } while( false ); + field.SetValue( self, GetValue( field.FieldType, x.Value ) ); } } + static object GetValue( Type fieldType, string x ) + { + if( fieldType == typeof( int ) ) + return int.Parse( x ); + + else if( fieldType == typeof( float ) ) + return float.Parse( x ); + + else if( fieldType == typeof( string ) ) + return x;//.ToLowerInvariant(); + + else if( fieldType.IsEnum ) + return Enum.Parse( fieldType, x ); + + else if( fieldType == typeof( bool ) ) + return ParseYesNo( x ); + + else if( fieldType.IsArray ) + { + var parts = x.Split( new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries ); + + var ret = Array.CreateInstance( fieldType.GetElementType(), parts.Length ); + for (int i = 0; i < parts.Length; i++) + ret.SetValue( GetValue( fieldType.GetElementType(), parts[ i ].Trim() ), i ); + return ret; + } + else + throw new InvalidOperationException( "FieldLoader: don't know how to load field of type " + fieldType.ToString() ); + } + static bool ParseYesNo( string p ) { p = p.ToLowerInvariant(); diff --git a/OpenRa.Game/GameRules/UnitInfo.cs b/OpenRa.Game/GameRules/UnitInfo.cs index 45d9c14ea3..d4893ac17c 100755 --- a/OpenRa.Game/GameRules/UnitInfo.cs +++ b/OpenRa.Game/GameRules/UnitInfo.cs @@ -19,7 +19,9 @@ namespace OpenRa.Game.GameRules } public readonly string Name; + public readonly string Description = ""; + public readonly string[] Traits; public readonly int Ammo = -1; public readonly ArmorType Armor = ArmorType.none; diff --git a/OpenRa.Game/TechTree/Item.cs b/OpenRa.Game/TechTree/Item.cs index 0d17dc2a8a..cf09781cd7 100755 --- a/OpenRa.Game/TechTree/Item.cs +++ b/OpenRa.Game/TechTree/Item.cs @@ -2,7 +2,6 @@ using System; using System.Collections.Generic; using OpenRa.FileFormats; using OpenRa.Game.GameRules; -using System.Diagnostics; namespace OpenRa.TechTree { diff --git a/campaignUnits.ini b/campaignUnits.ini index c7f46c8d7d..18e879edf1 100755 --- a/campaignUnits.ini +++ b/campaignUnits.ini @@ -3,4 +3,4 @@ FCOM [FCOM] Description=Forward Command Post - +Traits=Building, RenderBuilding diff --git a/units.ini b/units.ini index f3cd2365e9..871fc63b94 100755 --- a/units.ini +++ b/units.ini @@ -15,30 +15,43 @@ MNLY [V2RL] Description=V2 Rocket +Traits=Mobile, RenderUnit [1TNK] Description=Light Tank +Traits=Mobile, Turreted, AttackTurreted, RenderUnitTurreted [2TNK] Description=Medium Tank +Traits=Mobile, Turreted, AttackTurreted, RenderUnitTurreted [3TNK] Description=Heavy Tank +Traits=Mobile, Turreted, AttackTurreted, RenderUnitTurreted [4TNK] Description=Mammoth Tank +Traits=Mobile, Turreted, AttackTurreted, RenderUnitTurreted [MRJ] Description=Radar Jammer +Traits=Mobile, Turreted, RenderUnitTurreted ; temporary. It's not a turret, it's a spinney-thing [MGG] Description=Mobile Gap Generator +Traits=Mobile, Turreted, RenderUnitTurreted ; temporary. It's not a turret, it's a spinney-thing [ARTY] Description=Artillery +Traits=Mobile, RenderUnit [HARV] Description=Ore Truck +Traits=Mobile, RenderUnit [MCV] Description=Mobile Construction Vehicle +Traits=Mobile, McvDeploy, RenderUnit [JEEP] Description=Ranger +Traits=Mobile, Turreted, AttackTurreted, RenderUnitTurreted [APC] Description=Armored Personnel Carrier +Traits=Mobile, RenderUnit [MNLY] Description=Minelayer +Traits=Mobile, RenderUnit @@ -120,9 +133,9 @@ BARR TENT KENN FIX -SBAG -BRIK -FENC +; SBAG +; BRIK +; FENC FACF WEAF SYRF @@ -132,76 +145,109 @@ DOMF [IRON] Description=Iron Curtain +Traits=Building, RenderBuilding [ATEK] Description=Allied Tech Center +Traits=Building, RenderBuilding [PDOX] Description=Chronosphere +Traits=Building, RenderBuilding [WEAP] Description=War Factory +Traits=Building, RenderWarFactory [SYRD] Description=Shipyard +Traits=Building, RenderBuilding [SPEN] Description=Sub Pen +Traits=Building, RenderBuilding [PBOX] Description=Pillbox +Traits=Building, RenderBuilding [HBOX] Description=Camo Pillbox +Traits=Building, RenderBuilding [TSLA] Description=Tesla Coil +Traits=Building, RenderBuilding [GUN] Description=Turret +Traits=Building, Turreted, RenderBuildingTurreted [AGUN] Description=AA Gun +Traits=Building, Turreted, RenderBuildingTurreted [FTUR] Description=Flame Turret +Traits=Building, RenderBuilding [FACT] Description=Construction Yard +Traits=Building, RenderBuilding [PROC] Description=Ore Refinery +Traits=Building, RenderBuilding [SILO] Description=Silo +Traits=Building, RenderBuildingOre [HPAD] Description=Helipad +Traits=Building, RenderBuilding [DOME] Description=Radar Dome +Traits=Building, RenderBuilding [GAP] Description=Gap Generator +Traits=Building, RenderBuilding [SAM] Description=SAM Site +Traits=Building, Turreted, RenderBuildingTurreted [MSLO] Description=Missile Silo +Traits=Building, RenderBuilding [AFLD] Description=Airstrip +Traits=Building, RenderBuilding [POWR] Description=Power Plant +Traits=Building, RenderBuilding [APWR] Description=Advanced Power Plant +Traits=Building, RenderBuilding [STEK] Description=Soviet Tech Center +Traits=Building, RenderBuilding [BARR] Description=Soviet Barracks +Traits=Building, RenderBuilding [TENT] Description=Allied Barracks +Traits=Building, RenderBuilding [KENN] Description=Kennel +Traits=Building, RenderBuilding [FIX] Description=Service Depot -[SBAG] -Description=Sandbags -[BRIK] -Description=Concrete Wall -[FENC] -Description=Wire Fence +Traits=Building, RenderBuilding [FACF] Description=Fake Construction Yard +Traits=Building, RenderBuilding [WEAF] Description=Fake War Factory +Traits=Building, RenderWarFactory [SYRF] Description=Fake Shipyard +Traits=Building, RenderBuilding [SPEF] Description=Fake Sub Pen +Traits=Building, RenderBuilding [DOMF] Description=Fake Radar Dome +Traits=Building, RenderBuilding +;[SBAG] +;Description=Sandbags +;[BRIK] +;Description=Concrete Wall +;[FENC] +;Description=Wire Fence