From 9166029fc80e1da52dbbf4dced220becde23ee76 Mon Sep 17 00:00:00 2001 From: Bob Date: Thu, 26 Nov 2009 13:31:57 +1300 Subject: [PATCH] So I hear you like Production (to be a trait) :D --- OpenRa.Game/Game.cs | 61 ++++------------------ OpenRa.Game/GameRules/TechTree.cs | 8 +-- OpenRa.Game/OpenRa.Game.csproj | 1 + OpenRa.Game/Traits/Production.cs | 70 ++++++++++++++++++++++++++ OpenRa.Game/Traits/TraitsInterfaces.cs | 2 + units.ini | 16 +++--- 6 files changed, 95 insertions(+), 63 deletions(-) create mode 100755 OpenRa.Game/Traits/Production.cs diff --git a/OpenRa.Game/Game.cs b/OpenRa.Game/Game.cs index 2bddbf1530..3b3c6716eb 100644 --- a/OpenRa.Game/Game.cs +++ b/OpenRa.Game/Game.cs @@ -289,7 +289,7 @@ namespace OpenRa.Game new VoicePool("ackno", "affirm1", "noprob", "overout", "ritaway", "roger", "ugotit"), new VoicePool("await1", "ready", "report1", "yessir1")); - static int2? FindAdjacentTile(Actor a, UnitMovementType umt) + public static int2? FindAdjacentTile(Actor a, UnitMovementType umt) { var tiles = Footprint.Tiles(a, a.traits.Get()); var min = tiles.Aggregate(int2.Min) - new int2(1, 1); @@ -341,62 +341,21 @@ namespace OpenRa.Game public static void BuildUnit(Player player, string name) { - var producerTypes = Rules.TechTree.UnitBuiltAt(Rules.UnitInfo[name]); + var newUnitType = Rules.UnitInfo[ name ]; + var producerTypes = Rules.TechTree.UnitBuiltAt( newUnitType ); + // TODO: choose producer based on "primary building" var producer = world.Actors - .FirstOrDefault(a => a.unitInfo != null - && producerTypes.Contains(a.unitInfo.Name) && a.Owner == player); + .Where( x => producerTypes.Contains( x.unitInfo ) && x.Owner == player ) + .FirstOrDefault(); if (producer == null) { - player.CancelProduction(Rules.UnitCategory[name]); - return; + player.CancelProduction(Rules.UnitCategory[name]); + return; } - Actor newActor; - - if (producerTypes.Contains("spen") || producerTypes.Contains("syrd")) - { - var space = FindAdjacentTile(producer, Rules.UnitInfo[name].WaterBound ? - UnitMovementType.Float : UnitMovementType.Wheel); /* hackety hack */ - - if (space == null) - return; - - newActor = new Actor(name, space.Value, player); - var unit = newActor.traits.Get(); - unit.Facing = SharedRandom.Next(256); - } - else - { - var productionPoint = (1 / 24f * producer.CenterLocation).ToInt2(); - if (UnitInfluence.GetUnitAt(productionPoint) != null) - return; - - newActor = new Actor(name, (1 / 24f * producer.CenterLocation).ToInt2(), player); - var rp = producer.traits.GetOrDefault(); - var dest = rp != null ? rp.rallyPoint : (newActor.Location + new int2(0, 3)); - - var unit = newActor.traits.Get(); - var mobile = newActor.traits.GetOrDefault(); - if( mobile != null ) - { - unit.Facing = 128; - newActor.QueueActivity(new Traits.Activities.Move(dest, 1)); - } - - var heli = newActor.traits.GetOrDefault(); - if (heli != null) - { - unit.Facing = 20; - heli.targetLocation = dest; - } - } - - world.Add(newActor); - player.FinishProduction(Rules.UnitCategory[name]); - - if (producer.traits.Contains()) - producer.traits.Get().EjectUnit(); + if( producer.traits.WithInterface().Any( p => p.Produce( producer, newUnitType ) ) ) + player.FinishProduction(Rules.UnitCategory[name]); } } } diff --git a/OpenRa.Game/GameRules/TechTree.cs b/OpenRa.Game/GameRules/TechTree.cs index 4a697e0415..3376d98a60 100755 --- a/OpenRa.Game/GameRules/TechTree.cs +++ b/OpenRa.Game/GameRules/TechTree.cs @@ -8,7 +8,7 @@ namespace OpenRa.Game.GameRules { class TechTree { - readonly Cache> producesIndex = new Cache>( x => new List() ); + readonly Cache> producesIndex = new Cache>( x => new List() ); public TechTree() { @@ -60,12 +60,12 @@ namespace OpenRa.Game.GameRules .Where(x => Rules.UnitInfo[x].Owner.Contains(player.Race)); /* todo: fix for dual-race scenarios (captured buildings) */ } - public IEnumerable UnitBuiltAt( UnitInfo info ) + public IEnumerable UnitBuiltAt( UnitInfo info ) { if( info.BuiltAt.Length != 0 ) - return info.BuiltAt.Select( x => x.ToLowerInvariant() ); + return info.BuiltAt.Select( x => Rules.UnitInfo[ x.ToLowerInvariant() ] ); else - return producesIndex[ Rules.UnitCategory[ info.Name ] ].Select( x => x.Name.ToLowerInvariant() ); + return producesIndex[ Rules.UnitCategory[ info.Name ] ]; } } } diff --git a/OpenRa.Game/OpenRa.Game.csproj b/OpenRa.Game/OpenRa.Game.csproj index f30036b979..48302621b6 100644 --- a/OpenRa.Game/OpenRa.Game.csproj +++ b/OpenRa.Game/OpenRa.Game.csproj @@ -146,6 +146,7 @@ + diff --git a/OpenRa.Game/Traits/Production.cs b/OpenRa.Game/Traits/Production.cs new file mode 100755 index 0000000000..cf1e5856a6 --- /dev/null +++ b/OpenRa.Game/Traits/Production.cs @@ -0,0 +1,70 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using OpenRa.Game.GameRules; + +namespace OpenRa.Game.Traits +{ + class Production : IProducer + { + public Production( Actor self ) { } + + public virtual int2? CreationLocation( Actor self, UnitInfo producee ) + { + return ( 1 / 24f * self.CenterLocation ).ToInt2(); + } + + public virtual int CreationFacing( Actor self, Actor newUnit ) + { + if( newUnit.traits.Contains() ) + return 20; + return 128; + } + + public bool Produce( Actor self, UnitInfo producee ) + { + var location = CreationLocation( self, producee ); + if( location == null || Game.UnitInfluence.GetUnitAt( location.Value ) != null ) + return false; + + var newUnit = new Actor( producee.Name, location.Value, self.Owner ); + newUnit.traits.Get().Facing = CreationFacing( self, newUnit ); ; + + var rp = self.traits.GetOrDefault(); + if( rp != null ) + { + var mobile = newUnit.traits.GetOrDefault(); + if( mobile != null ) + newUnit.QueueActivity( new Traits.Activities.Move( rp.rallyPoint, 1 ) ); + + var heli = newUnit.traits.GetOrDefault(); + if( heli != null ) + heli.targetLocation = rp.rallyPoint; // TODO: make Activity.Move work for helis. + } + + Game.world.Add( newUnit ); + + if( self.traits.Contains() ) + self.traits.Get().EjectUnit(); + + return true; + } + } + + class ProductionSurround : Production + { + public ProductionSurround( Actor self ) : base( self ) { } + + public override int2? CreationLocation( Actor self, UnitInfo producee ) + { + return Game.FindAdjacentTile( self, producee.WaterBound ? + UnitMovementType.Float : UnitMovementType.Wheel); /* hackety hack */ + } + + public override int CreationFacing( Actor self, Actor newUnit ) + { + return Util.GetFacing( newUnit.CenterLocation - self.CenterLocation, 128 ); + } + } +} diff --git a/OpenRa.Game/Traits/TraitsInterfaces.cs b/OpenRa.Game/Traits/TraitsInterfaces.cs index 767fcf6f77..a05ddf72aa 100644 --- a/OpenRa.Game/Traits/TraitsInterfaces.cs +++ b/OpenRa.Game/Traits/TraitsInterfaces.cs @@ -4,6 +4,7 @@ using System.Linq; using System.Text; using OpenRa.Game.Graphics; using IjwFramework.Types; +using OpenRa.Game.GameRules; namespace OpenRa.Game.Traits { @@ -19,4 +20,5 @@ namespace OpenRa.Game.Traits Order IssueOrder( Actor self, int2 xy, bool lmb, Actor underCursor ); void ResolveOrder( Actor self, Order order ); } + interface IProducer { bool Produce( Actor self, UnitInfo produceee ); } } diff --git a/units.ini b/units.ini index 6e994f3513..59961a59c2 100755 --- a/units.ini +++ b/units.ini @@ -211,20 +211,20 @@ Dimensions=2,2 Footprint=xx xx [WEAP] Description=War Factory -Traits=Building, RenderWarFactory, RallyPoint +Traits=Building, RenderWarFactory, RallyPoint, Production Dimensions=3,2 Footprint=xxx xxx Produces=Vehicle RallyPoint=1,3 [SYRD] Description=Shipyard -Traits=Building, RenderBuilding +Traits=Building, RenderBuilding, ProductionSurround Dimensions=3,3 Footprint=xxx xxx xxx Produces=Ship [SPEN] Description=Sub Pen -Traits=Building, RenderBuilding +Traits=Building, RenderBuilding, ProductionSurround Dimensions=3,3 Footprint=xxx xxx xxx Produces=Ship @@ -276,7 +276,7 @@ Dimensions=1,1 Footprint=x [HPAD] Description=Helipad -Traits=Building, RenderBuilding +Traits=Building, RenderBuilding, Production Dimensions=2,2 Footprint=xx xx Produces=Plane @@ -302,7 +302,7 @@ Dimensions=2,1 Footprint=xx [AFLD] Description=Airstrip -Traits=Building, RenderBuilding +Traits=Building, RenderBuilding, Production Dimensions=3,2 Footprint=xxx xxx Produces=Plane @@ -323,21 +323,21 @@ Dimensions=3,2 Footprint=xxx xxx [BARR] Description=Soviet Barracks -Traits=Building, RenderBuilding, RallyPoint +Traits=Building, RenderBuilding, RallyPoint, Production Dimensions=2,2 Footprint=xx xx Produces=Infantry RallyPoint=1,3 [TENT] Description=Allied Barracks -Traits=Building, RenderBuilding, RallyPoint +Traits=Building, RenderBuilding, RallyPoint, Production Dimensions=2,2 Footprint=xx xx Produces=Infantry RallyPoint=1,3 [KENN] Description=Kennel -Traits=Building, RenderBuilding, RallyPoint +Traits=Building, RenderBuilding, RallyPoint, Production Dimensions=1,1 Footprint=x RallyPoint=1,2