diff --git a/OpenRa.Game/GameRules/NewUnitInfo.cs b/OpenRa.Game/GameRules/NewUnitInfo.cs index 3c44f45762..ec966e037d 100755 --- a/OpenRa.Game/GameRules/NewUnitInfo.cs +++ b/OpenRa.Game/GameRules/NewUnitInfo.cs @@ -20,19 +20,27 @@ namespace OpenRa.Game.GameRules Traits.Add( LoadTraitInfo( t.Key, t.Value ) ); } - static MiniYaml MergeWithParent( MiniYaml node, Dictionary allUnits ) + static MiniYaml GetParent( MiniYaml node, Dictionary allUnits ) { MiniYaml inherits; node.Nodes.TryGetValue( "Inherits", out inherits ); if( inherits == null || string.IsNullOrEmpty( inherits.Value ) ) - return node; + return null; MiniYaml parent; allUnits.TryGetValue( inherits.Value, out parent ); if( parent == null ) - return node; + return null; - return MiniYaml.Merge( node, MergeWithParent( parent, allUnits ) ); + return parent; + } + + static MiniYaml MergeWithParent( MiniYaml node, Dictionary allUnits ) + { + var parent = GetParent( node, allUnits ); + if( parent != null ) + return MiniYaml.Merge( node, MergeWithParent( parent, allUnits ) ); + return node; } static ITraitInfo LoadTraitInfo(string traitName, MiniYaml my) diff --git a/OpenRa.Game/GameRules/Rules.cs b/OpenRa.Game/GameRules/Rules.cs index d926f488a4..3983385775 100755 --- a/OpenRa.Game/GameRules/Rules.cs +++ b/OpenRa.Game/GameRules/Rules.cs @@ -90,7 +90,7 @@ namespace OpenRa.Game SupportPowerInfo = new InfoLoader( Pair.New>("SupportPower", _ => new SupportPowerInfo())); - var yamlRules = MiniYaml.FromFile("ra.yaml"); + var yamlRules = MiniYaml.Merge( MiniYaml.FromFile( "ra.yaml" ), MiniYaml.FromFile( "defaults.yaml" ) ); if( useAftermath ) yamlRules = MiniYaml.Merge( MiniYaml.FromFile( "aftermath.yaml" ), yamlRules ); diff --git a/OpenRa.Game/GameRules/TechTree.cs b/OpenRa.Game/GameRules/TechTree.cs index d403192261..7e1eef92b6 100755 --- a/OpenRa.Game/GameRules/TechTree.cs +++ b/OpenRa.Game/GameRules/TechTree.cs @@ -62,10 +62,11 @@ namespace OpenRa.Game.GameRules .Where(x => Rules.UnitInfo[x].Owner.Contains(player.Race)); /* todo: fix for dual-race scenarios (captured buildings) */ } - public IEnumerable UnitBuiltAt( LegacyUnitInfo info ) + public IEnumerable UnitBuiltAt( NewUnitInfo info ) { - if( info.BuiltAt.Length != 0 ) - return info.BuiltAt.Select( x => Rules.NewUnitInfo[ x.ToLowerInvariant() ] ); + var builtAt = info.Traits.Get().BuiltAt; + if( builtAt.Length != 0 ) + return builtAt.Select( x => Rules.NewUnitInfo[ x.ToLowerInvariant() ] ); else return producesIndex[ Rules.UnitCategory[ info.Name ] ]; } diff --git a/RulesConverter/MiniYamlExts.cs b/RulesConverter/MiniYamlExts.cs index 415e024a25..ce7825beea 100755 --- a/RulesConverter/MiniYamlExts.cs +++ b/RulesConverter/MiniYamlExts.cs @@ -13,7 +13,7 @@ namespace RulesConverter { public static void WriteToFile( this MiniYamlNodes y, string filename ) { - File.WriteAllLines( filename, y.ToLines( true ).ToArray() ); + File.WriteAllLines( filename, y.ToLines( true ).Select( x => x.TrimEnd() ).ToArray() ); } public static IEnumerable ToLines( this MiniYamlNodes y, bool lowest ) diff --git a/RulesConverter/Program.cs b/RulesConverter/Program.cs index e9cda7e9f1..714deb0797 100644 --- a/RulesConverter/Program.cs +++ b/RulesConverter/Program.cs @@ -41,7 +41,8 @@ namespace RulesConverter { "Armor", "Armor" }, { "Crewed", "Crewed" }, { "InitialFacing", "InitialFacing" }, - { "Sight", "Sight" } } + { "Sight", "Sight" }, + { "WaterBound", "WaterBound" } } }, { "Selectable", new PL { @@ -205,6 +206,10 @@ namespace RulesConverter } catch { } } + + var yaml = MiniYaml.FromFile( outputFile ); + yaml.OptimizeInherits( MiniYaml.FromFile( "defaults.yaml" ) ); + yaml.WriteToFile( outputFile ); } } } diff --git a/RulesConverter/RulesConverter.csproj b/RulesConverter/RulesConverter.csproj index f23f869d56..4669eb6b9d 100644 --- a/RulesConverter/RulesConverter.csproj +++ b/RulesConverter/RulesConverter.csproj @@ -52,6 +52,7 @@ + diff --git a/aftermath.yaml b/aftermath.yaml index 05fe317ae1..cef2b7f987 100644 --- a/aftermath.yaml +++ b/aftermath.yaml @@ -1,13 +1,10 @@ STNK: Inherits: DefaultVehicle - Selectable: - Voice: VehicleVoice Unit: HP: 200 Armor: heavy Sight: 5 Mobile: - ROT: 5 Speed: 10 Turreted: AttackTurreted: @@ -15,7 +12,6 @@ STNK: Recoil: 2 RenderUnitTurreted: Cloak: - Chronoshiftable: TTNK: Inherits: DefaultVehicle @@ -26,20 +22,16 @@ TTNK: Owner: soviet Cost: 1500 Description: "Tesla Tank" - Selectable: - Voice: VehicleVoice Unit: HP: 110 Armor: light Crewed: yes Sight: 7 Mobile: - ROT: 5 Speed: 8 AttackBase: PrimaryWeapon: TTankZap RenderUnitSpinner: - Chronoshiftable: CTNK: Inherits: DefaultVehicle @@ -50,20 +42,16 @@ CTNK: Owner: allies Cost: 2400 Description: "Chrono Tank" - Selectable: - Voice: VehicleVoice Unit: HP: 350 Armor: light Sight: 5 Mobile: - ROT: 5 Speed: 5 AttackBase: PrimaryWeapon: APTusk RenderUnit: ChronoshiftDeploy: - Chronoshiftable: DTRK: Inherits: DefaultVehicle @@ -74,14 +62,11 @@ DTRK: Owner: allies,soviet Cost: 2400 Description: "Demo Truck" - Selectable: - Voice: VehicleVoice Unit: HP: 110 Armor: light Sight: 3 Mobile: - ROT: 5 Speed: 8 AttackBase: PrimaryWeapon: Democharge @@ -97,18 +82,14 @@ QTNK: Owner: soviet Cost: 2300 Description: "M.A.D. Tank" - Selectable: - Voice: VehicleVoice Unit: HP: 300 Armor: heavy Crewed: no Sight: 6 Mobile: - ROT: 5 Speed: 3 RenderUnit: - Chronoshiftable: MSUB: Inherits: DefaultShip @@ -125,6 +106,7 @@ MSUB: HP: 150 Armor: light Sight: 6 + WaterBound: yes Mobile: ROT: 7 Speed: 5 diff --git a/aftermathUnits.ini b/aftermathUnits.ini index 9e07413c2c..7a9879ecb2 100755 --- a/aftermathUnits.ini +++ b/aftermathUnits.ini @@ -7,28 +7,28 @@ QTNK [STNK] Description=Stealth Tank -Traits=Unit, Mobile, Turreted, AttackTurreted, RenderUnitTurreted, Cloak, Chronoshiftable +Traits=Unit, Mobile, Turreted, AttackTurreted, RenderUnitTurreted, Cloak, Repairable, Chronoshiftable, Passenger, IronCurtainable Recoil=2 Voice=VehicleVoice [TTNK] Description=Tesla Tank -Traits=Unit, Mobile, AttackBase, RenderUnitSpinner, Chronoshiftable +Traits=Unit, Mobile, AttackBase, RenderUnitSpinner, Repairable, Chronoshiftable, Passenger, IronCurtainable Voice=VehicleVoice [CTNK] Description=Chrono Tank -Traits=Unit, Mobile, AttackBase, RenderUnit, ChronoshiftDeploy, Chronoshiftable +Traits=Unit, Mobile, AttackBase, RenderUnit, ChronoshiftDeploy, Repairable, Chronoshiftable, Passenger, IronCurtainable Voice=VehicleVoice [DTRK] Description=Demo Truck -Traits=Unit, Mobile, AttackBase, RenderUnit, DemoTruck +Traits=Unit, Mobile, AttackBase, RenderUnit, DemoTruck, Repairable, Chronoshiftable, Passenger, IronCurtainable Voice=VehicleVoice [QTNK] Description=M.A.D. Tank -Traits=Unit, Mobile, RenderUnit, Chronoshiftable +Traits=Unit, Mobile, RenderUnit, Repairable, Chronoshiftable, Passenger, IronCurtainable Voice=VehicleVoice @@ -102,4 +102,4 @@ Attack=jburn1,jcrisp1,jshock1,jlight1 [MechVoice] Select=mhowdy1,mhotdig1,mhuh1 Move=mlaff1,mhotdig1,mhear1,mboss1,myeehaw1 -Attack=mwrench1,mrise1,mboss1,myeehaw1 \ No newline at end of file +Attack=mwrench1,mrise1,mboss1,myeehaw1 diff --git a/campaignUnits.ini b/campaignUnits.ini index 15d37bd3f7..13ae1b8008 100755 --- a/campaignUnits.ini +++ b/campaignUnits.ini @@ -238,4 +238,6 @@ SelectionPriority=0 TRUK [TRUK] -Traits=Unit, Mobile, RenderUnit \ No newline at end of file +Traits=Unit, Mobile, RenderUnit, Repairable, Chronoshiftable, Passenger, IronCurtainable +Voice=VehicleVoice + diff --git a/defaults.yaml b/defaults.yaml new file mode 100644 index 0000000000..4f3a4bc637 --- /dev/null +++ b/defaults.yaml @@ -0,0 +1,10 @@ +DefaultVehicle: + Mobile: + ROT: 5 + Selectable: + Voice: VehicleVoice + Repairable: + Chronoshiftable: + Passenger: + IronCurtainable: + diff --git a/ra.yaml b/ra.yaml index 73332b05b2..0baafddc40 100644 --- a/ra.yaml +++ b/ra.yaml @@ -8,24 +8,17 @@ V2RL: Cost: 700 Description: "V2 Rocket" LongDesc: "Long-range rocket artillery.\n Strong vs Infantry, Buildings\n Weak vs Tanks, Aircraft" - Selectable: - Voice: VehicleVoice Unit: HP: 150 Armor: light Crewed: yes Sight: 5 Mobile: - ROT: 5 Speed: 7 AttackBase: PrimaryWeapon: SCUD RenderUnitReload: AutoTarget: - Repairable: - Chronoshiftable: - Passenger: - IronCurtainable: 1TNK: Inherits: DefaultVehicle @@ -37,15 +30,12 @@ V2RL: Cost: 700 Description: "Light Tank" LongDesc: "Light Tank, good for scouting.\n Strong vs Light Vehicles\n Weak vs Tanks, Aircraft" - Selectable: - Voice: VehicleVoice Unit: HP: 300 Armor: heavy Crewed: yes Sight: 4 Mobile: - ROT: 5 Speed: 9 Turreted: AttackTurreted: @@ -53,10 +43,6 @@ V2RL: Recoil: 2 RenderUnitTurreted: AutoTarget: - Repairable: - Chronoshiftable: - Passenger: - IronCurtainable: 2TNK: Inherits: DefaultVehicle @@ -68,15 +54,12 @@ V2RL: Cost: 800 Description: "Medium Tank" LongDesc: "Allied Main Battle Tank.\n Strong vs Tanks, Light Vehicles\n Weak vs Infantry, Aircraft" - Selectable: - Voice: VehicleVoice Unit: HP: 400 Armor: heavy Crewed: yes Sight: 5 Mobile: - ROT: 5 Speed: 8 Turreted: AttackTurreted: @@ -84,10 +67,6 @@ V2RL: Recoil: 3 RenderUnitTurreted: AutoTarget: - Repairable: - Chronoshiftable: - Passenger: - IronCurtainable: 3TNK: Inherits: DefaultVehicle @@ -99,15 +78,12 @@ V2RL: Cost: 950 Description: "Heavy Tank" LongDesc: "Soviet Main Battle Tank, with dual cannons\n Strong vs Tanks, Light Vehicles\n Weak vs Infantry, Aircraft" - Selectable: - Voice: VehicleVoice Unit: HP: 400 Armor: heavy Crewed: yes Sight: 5 Mobile: - ROT: 5 Speed: 7 Turreted: AttackTurreted: @@ -115,10 +91,6 @@ V2RL: Recoil: 3 RenderUnitTurreted: AutoTarget: - Repairable: - Chronoshiftable: - Passenger: - IronCurtainable: 4TNK: Inherits: DefaultVehicle @@ -130,15 +102,12 @@ V2RL: Cost: 1700 Description: "Mammoth Tank" LongDesc: "Big and slow tank, with anti-air capability.\n Strong vs Tanks, Aircraft\n Weak vs Infantry" - Selectable: - Voice: VehicleVoice Unit: HP: 600 Armor: heavy Crewed: yes Sight: 6 Mobile: - ROT: 5 Speed: 4 Turreted: AttackTurreted: @@ -148,10 +117,6 @@ V2RL: Recoil: 4 RenderUnitTurreted: AutoTarget: - Repairable: - Chronoshiftable: - Passenger: - IronCurtainable: MRJ: Inherits: DefaultVehicle @@ -165,21 +130,15 @@ MRJ: LongDesc: "Hides nearby units on the enemy's minimap.\n Unarmed" Selectable: Priority: 3 - Voice: VehicleVoice Unit: HP: 110 Armor: light Crewed: yes Sight: 7 Mobile: - ROT: 5 Speed: 9 RenderUnitSpinner: Offset: 0,4,0,-6 - Repairable: - Chronoshiftable: - Passenger: - IronCurtainable: MGG: Inherits: DefaultVehicle @@ -193,21 +152,15 @@ MGG: LongDesc: "Regenerates Fog of War in a small area \naround the unit.\n Unarmed" Selectable: Priority: 3 - Voice: VehicleVoice Unit: HP: 110 Armor: light Crewed: yes Sight: 4 Mobile: - ROT: 5 Speed: 9 RenderUnitSpinner: Offset: 0,6,0,-3 - Repairable: - Chronoshiftable: - Passenger: - IronCurtainable: ARTY: Inherits: DefaultVehicle @@ -219,25 +172,18 @@ ARTY: Cost: 600 Description: "Artillery" LongDesc: "Long-range artillery.\n Strong vs Infantry, Buildings\n Weak vs Tanks, Aircraft" - Selectable: - Voice: VehicleVoice Unit: HP: 75 Armor: light Crewed: yes Sight: 5 Mobile: - ROT: 2 Speed: 6 AttackBase: PrimaryWeapon: 155mm RenderUnit: Explodes: AutoTarget: - Repairable: - Chronoshiftable: - Passenger: - IronCurtainable: HARV: Inherits: DefaultVehicle @@ -251,7 +197,6 @@ HARV: LongDesc: "Collects Ore and Gems for processing.\n Unarmed" Selectable: Priority: 7 - Voice: VehicleVoice Harvester: Unit: HP: 600 @@ -259,13 +204,8 @@ HARV: Crewed: yes Sight: 4 Mobile: - ROT: 5 Speed: 6 RenderUnit: - Repairable: - Chronoshiftable: - Passenger: - IronCurtainable: MCV: Inherits: DefaultVehicle @@ -279,21 +219,15 @@ MCV: LongDesc: "Deploys into another Construction Yard.\n Unarmed" Selectable: Priority: 3 - Voice: VehicleVoice Unit: HP: 600 Armor: light Crewed: yes Sight: 4 Mobile: - ROT: 5 Speed: 6 McvDeploy: RenderUnit: - Repairable: - Chronoshiftable: - Passenger: - IronCurtainable: JEEP: Inherits: DefaultVehicle @@ -305,15 +239,12 @@ JEEP: Cost: 600 Description: "Ranger" LongDesc: "Fast scout & anti-infantry vehicle.\n Strong vs Infantry\n Weak vs Tanks, Aircraft" - Selectable: - Voice: VehicleVoice Unit: HP: 150 Armor: light Crewed: yes Sight: 6 Mobile: - ROT: 10 Speed: 10 Turreted: AttackTurreted: @@ -322,10 +253,6 @@ JEEP: MuzzleFlash: yes RenderUnitTurreted: AutoTarget: - Repairable: - Chronoshiftable: - Passenger: - IronCurtainable: APC: Inherits: DefaultVehicle @@ -337,14 +264,11 @@ APC: Cost: 800 Description: "Armored Personnel Carrier" LongDesc: "Tough infantry transport.\n Strong vs Infantry, Light Vehicles\n Weak vs Tanks, Aircraft" - Selectable: - Voice: VehicleVoice Unit: HP: 200 Armor: heavy Sight: 5 Mobile: - ROT: 5 Speed: 10 AttackBase: PrimaryWeapon: M60mg @@ -352,14 +276,10 @@ APC: MuzzleFlash: yes RenderUnitMuzzleFlash: AutoTarget: - Repairable: - Chronoshiftable: Cargo: PassengerTypes: Foot Passengers: 5 UnloadFacing: 220 - Passenger: - IronCurtainable: MNLY.AP: Inherits: DefaultVehicle @@ -372,26 +292,19 @@ MNLY.AP: Icon: MNLYICON Description: "Minelayer (Anti-Personnel)" LongDesc: "Lays mines to destroy unwary enemy units.\n Unarmed" - Selectable: - Voice: VehicleVoice Unit: HP: 100 Armor: heavy Crewed: yes Sight: 5 Mobile: - ROT: 5 Speed: 9 RenderUnit: Image: MNLY Minelayer: MineImmune: - Repairable: LimitedAmmo: Ammo: 5 - Chronoshiftable: - Passenger: - IronCurtainable: MNLY.AT: Inherits: DefaultVehicle @@ -404,36 +317,27 @@ MNLY.AT: Icon: MNLYICON Description: "Minelayer (Anti-Tank)" LongDesc: "Lays mines to destroy unwary enemy units.\n Unarmed" - Selectable: - Voice: VehicleVoice Unit: HP: 100 Armor: heavy Crewed: yes Sight: 5 Mobile: - ROT: 5 Speed: 9 RenderUnit: Image: MNLY Minelayer: MineImmune: - Repairable: LimitedAmmo: Ammo: 5 - Chronoshiftable: - Passenger: - IronCurtainable: TRUK: Inherits: DefaultVehicle - Selectable: Unit: HP: 110 Armor: light Sight: 3 Mobile: - ROT: 5 Speed: 10 RenderUnit: @@ -453,6 +357,7 @@ SS: HP: 120 Armor: light Sight: 6 + WaterBound: yes Mobile: ROT: 7 Speed: 6 @@ -480,6 +385,7 @@ DD: HP: 400 Armor: heavy Sight: 6 + WaterBound: yes Mobile: ROT: 7 Speed: 6 @@ -508,6 +414,7 @@ CA: HP: 700 Armor: heavy Sight: 7 + WaterBound: yes Mobile: ROT: 5 Speed: 4 @@ -536,6 +443,7 @@ LST: HP: 350 Armor: heavy Sight: 6 + WaterBound: yes Mobile: ROT: 10 Speed: 14 @@ -561,6 +469,7 @@ PT: HP: 200 Armor: heavy Sight: 7 + WaterBound: yes Mobile: ROT: 7 Speed: 9