So I hear you like Production (to be a trait) :D

This commit is contained in:
Bob
2009-11-26 13:31:57 +13:00
parent 6044ac79d9
commit 9166029fc8
6 changed files with 95 additions and 63 deletions

View File

@@ -289,7 +289,7 @@ namespace OpenRa.Game
new VoicePool("ackno", "affirm1", "noprob", "overout", "ritaway", "roger", "ugotit"), new VoicePool("ackno", "affirm1", "noprob", "overout", "ritaway", "roger", "ugotit"),
new VoicePool("await1", "ready", "report1", "yessir1")); 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<Traits.Building>()); var tiles = Footprint.Tiles(a, a.traits.Get<Traits.Building>());
var min = tiles.Aggregate(int2.Min) - new int2(1, 1); 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) 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 var producer = world.Actors
.FirstOrDefault(a => a.unitInfo != null .Where( x => producerTypes.Contains( x.unitInfo ) && x.Owner == player )
&& producerTypes.Contains(a.unitInfo.Name) && a.Owner == player); .FirstOrDefault();
if (producer == null) if (producer == null)
{ {
player.CancelProduction(Rules.UnitCategory[name]); player.CancelProduction(Rules.UnitCategory[name]);
return; return;
} }
Actor newActor; if( producer.traits.WithInterface<IProducer>().Any( p => p.Produce( producer, newUnitType ) ) )
player.FinishProduction(Rules.UnitCategory[name]);
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>();
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<RallyPoint>();
var dest = rp != null ? rp.rallyPoint : (newActor.Location + new int2(0, 3));
var unit = newActor.traits.Get<Unit>();
var mobile = newActor.traits.GetOrDefault<Mobile>();
if( mobile != null )
{
unit.Facing = 128;
newActor.QueueActivity(new Traits.Activities.Move(dest, 1));
}
var heli = newActor.traits.GetOrDefault<Helicopter>();
if (heli != null)
{
unit.Facing = 20;
heli.targetLocation = dest;
}
}
world.Add(newActor);
player.FinishProduction(Rules.UnitCategory[name]);
if (producer.traits.Contains<RenderWarFactory>())
producer.traits.Get<RenderWarFactory>().EjectUnit();
} }
} }
} }

View File

@@ -8,7 +8,7 @@ namespace OpenRa.Game.GameRules
{ {
class TechTree class TechTree
{ {
readonly Cache<string, List<UnitInfo.BuildingInfo>> producesIndex = new Cache<string, List<UnitInfo.BuildingInfo>>( x => new List<UnitInfo.BuildingInfo>() ); readonly Cache<string, List<UnitInfo>> producesIndex = new Cache<string, List<UnitInfo>>( x => new List<UnitInfo>() );
public TechTree() 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) */ .Where(x => Rules.UnitInfo[x].Owner.Contains(player.Race)); /* todo: fix for dual-race scenarios (captured buildings) */
} }
public IEnumerable<string> UnitBuiltAt( UnitInfo info ) public IEnumerable<UnitInfo> UnitBuiltAt( UnitInfo info )
{ {
if( info.BuiltAt.Length != 0 ) if( info.BuiltAt.Length != 0 )
return info.BuiltAt.Select( x => x.ToLowerInvariant() ); return info.BuiltAt.Select( x => Rules.UnitInfo[ x.ToLowerInvariant() ] );
else else
return producesIndex[ Rules.UnitCategory[ info.Name ] ].Select( x => x.Name.ToLowerInvariant() ); return producesIndex[ Rules.UnitCategory[ info.Name ] ];
} }
} }
} }

View File

@@ -146,6 +146,7 @@
<Compile Include="Traits\InfantrySquad.cs" /> <Compile Include="Traits\InfantrySquad.cs" />
<Compile Include="Traits\McvDeploy.cs" /> <Compile Include="Traits\McvDeploy.cs" />
<Compile Include="Traits\Mobile.cs" /> <Compile Include="Traits\Mobile.cs" />
<Compile Include="Traits\Production.cs" />
<Compile Include="Traits\RallyPoint.cs" /> <Compile Include="Traits\RallyPoint.cs" />
<Compile Include="Traits\RenderBuilding.cs" /> <Compile Include="Traits\RenderBuilding.cs" />
<Compile Include="Traits\RenderBuildingOre.cs" /> <Compile Include="Traits\RenderBuildingOre.cs" />

View File

@@ -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<Helicopter>() )
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<Unit>().Facing = CreationFacing( self, newUnit ); ;
var rp = self.traits.GetOrDefault<RallyPoint>();
if( rp != null )
{
var mobile = newUnit.traits.GetOrDefault<Mobile>();
if( mobile != null )
newUnit.QueueActivity( new Traits.Activities.Move( rp.rallyPoint, 1 ) );
var heli = newUnit.traits.GetOrDefault<Helicopter>();
if( heli != null )
heli.targetLocation = rp.rallyPoint; // TODO: make Activity.Move work for helis.
}
Game.world.Add( newUnit );
if( self.traits.Contains<RenderWarFactory>() )
self.traits.Get<RenderWarFactory>().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 );
}
}
}

View File

@@ -4,6 +4,7 @@ using System.Linq;
using System.Text; using System.Text;
using OpenRa.Game.Graphics; using OpenRa.Game.Graphics;
using IjwFramework.Types; using IjwFramework.Types;
using OpenRa.Game.GameRules;
namespace OpenRa.Game.Traits namespace OpenRa.Game.Traits
{ {
@@ -19,4 +20,5 @@ namespace OpenRa.Game.Traits
Order IssueOrder( Actor self, int2 xy, bool lmb, Actor underCursor ); Order IssueOrder( Actor self, int2 xy, bool lmb, Actor underCursor );
void ResolveOrder( Actor self, Order order ); void ResolveOrder( Actor self, Order order );
} }
interface IProducer { bool Produce( Actor self, UnitInfo produceee ); }
} }

View File

@@ -211,20 +211,20 @@ Dimensions=2,2
Footprint=xx xx Footprint=xx xx
[WEAP] [WEAP]
Description=War Factory Description=War Factory
Traits=Building, RenderWarFactory, RallyPoint Traits=Building, RenderWarFactory, RallyPoint, Production
Dimensions=3,2 Dimensions=3,2
Footprint=xxx xxx Footprint=xxx xxx
Produces=Vehicle Produces=Vehicle
RallyPoint=1,3 RallyPoint=1,3
[SYRD] [SYRD]
Description=Shipyard Description=Shipyard
Traits=Building, RenderBuilding Traits=Building, RenderBuilding, ProductionSurround
Dimensions=3,3 Dimensions=3,3
Footprint=xxx xxx xxx Footprint=xxx xxx xxx
Produces=Ship Produces=Ship
[SPEN] [SPEN]
Description=Sub Pen Description=Sub Pen
Traits=Building, RenderBuilding Traits=Building, RenderBuilding, ProductionSurround
Dimensions=3,3 Dimensions=3,3
Footprint=xxx xxx xxx Footprint=xxx xxx xxx
Produces=Ship Produces=Ship
@@ -276,7 +276,7 @@ Dimensions=1,1
Footprint=x Footprint=x
[HPAD] [HPAD]
Description=Helipad Description=Helipad
Traits=Building, RenderBuilding Traits=Building, RenderBuilding, Production
Dimensions=2,2 Dimensions=2,2
Footprint=xx xx Footprint=xx xx
Produces=Plane Produces=Plane
@@ -302,7 +302,7 @@ Dimensions=2,1
Footprint=xx Footprint=xx
[AFLD] [AFLD]
Description=Airstrip Description=Airstrip
Traits=Building, RenderBuilding Traits=Building, RenderBuilding, Production
Dimensions=3,2 Dimensions=3,2
Footprint=xxx xxx Footprint=xxx xxx
Produces=Plane Produces=Plane
@@ -323,21 +323,21 @@ Dimensions=3,2
Footprint=xxx xxx Footprint=xxx xxx
[BARR] [BARR]
Description=Soviet Barracks Description=Soviet Barracks
Traits=Building, RenderBuilding, RallyPoint Traits=Building, RenderBuilding, RallyPoint, Production
Dimensions=2,2 Dimensions=2,2
Footprint=xx xx Footprint=xx xx
Produces=Infantry Produces=Infantry
RallyPoint=1,3 RallyPoint=1,3
[TENT] [TENT]
Description=Allied Barracks Description=Allied Barracks
Traits=Building, RenderBuilding, RallyPoint Traits=Building, RenderBuilding, RallyPoint, Production
Dimensions=2,2 Dimensions=2,2
Footprint=xx xx Footprint=xx xx
Produces=Infantry Produces=Infantry
RallyPoint=1,3 RallyPoint=1,3
[KENN] [KENN]
Description=Kennel Description=Kennel
Traits=Building, RenderBuilding, RallyPoint Traits=Building, RenderBuilding, RallyPoint, Production
Dimensions=1,1 Dimensions=1,1
Footprint=x Footprint=x
RallyPoint=1,2 RallyPoint=1,2