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("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 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>();
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();
if( producer.traits.WithInterface<IProducer>().Any( p => p.Produce( producer, newUnitType ) ) )
player.FinishProduction(Rules.UnitCategory[name]);
}
}
}

View File

@@ -8,7 +8,7 @@ namespace OpenRa.Game.GameRules
{
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()
{
@@ -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<string> UnitBuiltAt( UnitInfo info )
public IEnumerable<UnitInfo> 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 ] ];
}
}
}

View File

@@ -146,6 +146,7 @@
<Compile Include="Traits\InfantrySquad.cs" />
<Compile Include="Traits\McvDeploy.cs" />
<Compile Include="Traits\Mobile.cs" />
<Compile Include="Traits\Production.cs" />
<Compile Include="Traits\RallyPoint.cs" />
<Compile Include="Traits\RenderBuilding.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 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 ); }
}

View File

@@ -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