Restructuring orders.
This commit is contained in:
@@ -15,13 +15,22 @@ namespace OpenRa.Game
|
|||||||
|
|
||||||
void ApplyOrders(float2 xy, bool left)
|
void ApplyOrders(float2 xy, bool left)
|
||||||
{
|
{
|
||||||
var doVoice = true;
|
var doVoice = null as Actor;
|
||||||
if (orderGenerator != null)
|
if (orderGenerator != null)
|
||||||
foreach( var order in orderGenerator.Order( xy.ToInt2(), left ) )
|
foreach( var order in orderGenerator.Order( xy.ToInt2(), left ) )
|
||||||
{
|
{
|
||||||
order.Apply(doVoice);
|
UnitOrders.ProcessOrder( order );
|
||||||
doVoice = false;
|
if( order.Subject != null && order.Player == Game.LocalPlayer )
|
||||||
|
doVoice = order.Subject;
|
||||||
}
|
}
|
||||||
|
if( doVoice != null )
|
||||||
|
Game.PlaySound( Game.SovietVoices.First.GetNext() + GetVoiceSuffix( doVoice ), false );
|
||||||
|
}
|
||||||
|
|
||||||
|
static string GetVoiceSuffix( Actor unit )
|
||||||
|
{
|
||||||
|
var suffixes = new[] { ".r01", ".r03" };
|
||||||
|
return suffixes[ unit.traits.Get<Traits.Mobile>().Voice ];
|
||||||
}
|
}
|
||||||
|
|
||||||
float2 dragStart, dragEnd;
|
float2 dragStart, dragEnd;
|
||||||
|
|||||||
@@ -1,45 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Text;
|
|
||||||
using System.Linq;
|
|
||||||
using OpenRa.Game.Traits;
|
|
||||||
|
|
||||||
namespace OpenRa.Game
|
|
||||||
{
|
|
||||||
abstract class Order
|
|
||||||
{
|
|
||||||
public abstract void Apply(bool doVoice);
|
|
||||||
}
|
|
||||||
|
|
||||||
class MoveOrder : Order
|
|
||||||
{
|
|
||||||
public readonly Actor Unit;
|
|
||||||
public readonly int2 Destination;
|
|
||||||
|
|
||||||
public MoveOrder(Actor unit, int2 destination)
|
|
||||||
{
|
|
||||||
this.Unit = unit;
|
|
||||||
this.Destination = destination;
|
|
||||||
}
|
|
||||||
|
|
||||||
string GetVoiceSuffix()
|
|
||||||
{
|
|
||||||
var suffixes = new[] { ".r01", ".r03" };
|
|
||||||
return suffixes[Unit.traits.Get<Traits.Mobile>().Voice];
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Apply(bool doVoice)
|
|
||||||
{
|
|
||||||
if (doVoice && Game.LocalPlayer == Unit.Owner)
|
|
||||||
Game.PlaySound(Game.SovietVoices.First.GetNext() + GetVoiceSuffix(), false);
|
|
||||||
|
|
||||||
var mobile = Unit.traits.Get<Mobile>();
|
|
||||||
mobile.Cancel(Unit);
|
|
||||||
mobile.QueueActivity(new Mobile.MoveTo(Destination));
|
|
||||||
|
|
||||||
var attackBase = Unit.traits.WithInterface<AttackBase>().FirstOrDefault();
|
|
||||||
if (attackBase != null)
|
|
||||||
attackBase.target = null; /* move cancels attack order */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -74,6 +74,7 @@
|
|||||||
<Reference Include="System.Xml" />
|
<Reference Include="System.Xml" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<Compile Include="Traits\Activities\DeployMcv.cs" />
|
||||||
<Compile Include="Actor.cs" />
|
<Compile Include="Actor.cs" />
|
||||||
<Compile Include="Bullet.cs" />
|
<Compile Include="Bullet.cs" />
|
||||||
<Compile Include="Controller.cs" />
|
<Compile Include="Controller.cs" />
|
||||||
@@ -97,7 +98,6 @@
|
|||||||
<Compile Include="BuildingInfluenceMap.cs" />
|
<Compile Include="BuildingInfluenceMap.cs" />
|
||||||
<Compile Include="IOrderGenerator.cs" />
|
<Compile Include="IOrderGenerator.cs" />
|
||||||
<Compile Include="PlaceBuilding.cs" />
|
<Compile Include="PlaceBuilding.cs" />
|
||||||
<Compile Include="PlaceBuildingOrder.cs" />
|
|
||||||
<Compile Include="TechTree\Item.cs" />
|
<Compile Include="TechTree\Item.cs" />
|
||||||
<Compile Include="Network\Packet.cs" />
|
<Compile Include="Network\Packet.cs" />
|
||||||
<Compile Include="Player.cs" />
|
<Compile Include="Player.cs" />
|
||||||
@@ -108,7 +108,7 @@
|
|||||||
<Compile Include="Network\Network.cs" />
|
<Compile Include="Network\Network.cs" />
|
||||||
<Compile Include="PathFinder.cs" />
|
<Compile Include="PathFinder.cs" />
|
||||||
<Compile Include="Graphics\Sequence.cs" />
|
<Compile Include="Graphics\Sequence.cs" />
|
||||||
<Compile Include="MoveOrder.cs" />
|
<Compile Include="Order.cs" />
|
||||||
<Compile Include="Graphics\Region.cs" />
|
<Compile Include="Graphics\Region.cs" />
|
||||||
<Compile Include="Graphics\SequenceProvider.cs" />
|
<Compile Include="Graphics\SequenceProvider.cs" />
|
||||||
<Compile Include="Graphics\SheetBuilder.cs" />
|
<Compile Include="Graphics\SheetBuilder.cs" />
|
||||||
@@ -143,6 +143,7 @@
|
|||||||
<Compile Include="Traits\TraitsInterfaces.cs" />
|
<Compile Include="Traits\TraitsInterfaces.cs" />
|
||||||
<Compile Include="Traits\Tree.cs" />
|
<Compile Include="Traits\Tree.cs" />
|
||||||
<Compile Include="Traits\Turreted.cs" />
|
<Compile Include="Traits\Turreted.cs" />
|
||||||
|
<Compile Include="UnitOrders.cs" />
|
||||||
<Compile Include="Traits\Util.cs" />
|
<Compile Include="Traits\Util.cs" />
|
||||||
<Compile Include="UiOverlay.cs" />
|
<Compile Include="UiOverlay.cs" />
|
||||||
<Compile Include="Graphics\UnitSheetBuilder.cs" />
|
<Compile Include="Graphics\UnitSheetBuilder.cs" />
|
||||||
|
|||||||
50
OpenRa.Game/Order.cs
Normal file
50
OpenRa.Game/Order.cs
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
using System.Linq;
|
||||||
|
using OpenRa.Game.Traits;
|
||||||
|
|
||||||
|
namespace OpenRa.Game
|
||||||
|
{
|
||||||
|
sealed class Order
|
||||||
|
{
|
||||||
|
public readonly Player Player;
|
||||||
|
public readonly string OrderString;
|
||||||
|
public readonly Actor Subject;
|
||||||
|
public readonly Actor TargetActor;
|
||||||
|
public readonly int2 TargetLocation;
|
||||||
|
public readonly string TargetString;
|
||||||
|
|
||||||
|
private Order( Player player, string orderString, Actor subject, Actor targetActor, int2 targetLocation, string targetString )
|
||||||
|
{
|
||||||
|
this.Player = player;
|
||||||
|
this.OrderString = orderString;
|
||||||
|
this.Subject = subject;
|
||||||
|
this.TargetActor = targetActor;
|
||||||
|
this.TargetLocation = targetLocation;
|
||||||
|
this.TargetString = targetString;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: serialize / deserialize
|
||||||
|
|
||||||
|
public static Order Attack( Actor subject, Actor target )
|
||||||
|
{
|
||||||
|
return new Order( subject.Owner, "Attack", subject, target, int2.Zero, null );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Order Move( Actor subject, int2 target )
|
||||||
|
{
|
||||||
|
return new Order( subject.Owner, "Move", subject, null, target, null );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Order DeployMcv( Actor subject )
|
||||||
|
{
|
||||||
|
return new Order( subject.Owner, "DeployMcv", subject, null, int2.Zero, null );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Order PlaceBuilding( Player subject, int2 target, string buildingName )
|
||||||
|
{
|
||||||
|
return new Order( subject, "PlaceBuilding", null, null, target, buildingName );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -33,7 +33,7 @@ namespace OpenRa.Game
|
|||||||
t => Game.GetDistanceToBase( t, Owner ) < maxDistance ) )
|
t => Game.GetDistanceToBase( t, Owner ) < maxDistance ) )
|
||||||
yield break;
|
yield break;
|
||||||
|
|
||||||
yield return new PlaceBuildingOrder( this, xy );
|
yield return OpenRa.Game.Order.PlaceBuilding( Owner, xy, Name );
|
||||||
}
|
}
|
||||||
else // rmb
|
else // rmb
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,33 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace OpenRa.Game
|
|
||||||
{
|
|
||||||
class PlaceBuildingOrder : Order
|
|
||||||
{
|
|
||||||
PlaceBuilding building;
|
|
||||||
int2 xy;
|
|
||||||
|
|
||||||
public PlaceBuildingOrder( PlaceBuilding building, int2 xy )
|
|
||||||
{
|
|
||||||
this.building = building;
|
|
||||||
this.xy = xy;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Apply(bool doVoice)
|
|
||||||
{
|
|
||||||
Game.world.AddFrameEndTask( _ =>
|
|
||||||
{
|
|
||||||
Log.Write( "Player \"{0}\" builds {1}", building.Owner.PlayerName, building.Name );
|
|
||||||
|
|
||||||
//Adjust placement for cursor to be in middle
|
|
||||||
Game.world.Add( new Actor( building.Name, xy - GameRules.Footprint.AdjustForBuildingSize( building.Name ), building.Owner ) );
|
|
||||||
|
|
||||||
Game.controller.orderGenerator = null;
|
|
||||||
Game.worldRenderer.uiOverlay.KillOverlay();
|
|
||||||
} );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
27
OpenRa.Game/Traits/Activities/DeployMcv.cs
Executable file
27
OpenRa.Game/Traits/Activities/DeployMcv.cs
Executable file
@@ -0,0 +1,27 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace OpenRa.Game.Traits.Activities
|
||||||
|
{
|
||||||
|
class DeployMcv : Mobile.CurrentActivity
|
||||||
|
{
|
||||||
|
public Mobile.CurrentActivity NextActivity { get; set; }
|
||||||
|
|
||||||
|
public void Tick( Actor self, Mobile mobile )
|
||||||
|
{
|
||||||
|
Game.world.AddFrameEndTask( _ =>
|
||||||
|
{
|
||||||
|
Game.world.Remove( self );
|
||||||
|
Game.world.Add( new Actor( "fact", self.Location - new int2( 1, 1 ), self.Owner ) );
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Cancel( Actor self, Mobile mobile )
|
||||||
|
{
|
||||||
|
// Cancel can't happen between this being moved to the head of the list, and it being Ticked.
|
||||||
|
throw new InvalidOperationException( "DeployMcvAction: Cancel() should never occur." );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -56,7 +56,7 @@ namespace OpenRa.Game.Traits
|
|||||||
|
|
||||||
if( underCursor.Owner == self.Owner ) return null;
|
if( underCursor.Owner == self.Owner ) return null;
|
||||||
|
|
||||||
return new AttackOrder( self, underCursor );
|
return OpenRa.Game.Order.Attack( self, underCursor );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,36 +76,4 @@ namespace OpenRa.Game.Traits
|
|||||||
DoAttack( self );
|
DoAttack( self );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class AttackOrder : Order
|
|
||||||
{
|
|
||||||
public readonly Actor Attacker;
|
|
||||||
public readonly Actor Target;
|
|
||||||
|
|
||||||
const int RangeTolerance = 1; /* how far inside our maximum range we should try to sit */
|
|
||||||
|
|
||||||
public AttackOrder( Actor attacker, Actor target )
|
|
||||||
{
|
|
||||||
this.Attacker = attacker;
|
|
||||||
this.Target = target;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Apply( bool doVoice )
|
|
||||||
{
|
|
||||||
var mobile = Attacker.traits.GetOrDefault<Mobile>();
|
|
||||||
if (mobile != null)
|
|
||||||
{
|
|
||||||
var weapon = Attacker.unitInfo.Primary ?? Attacker.unitInfo.Secondary;
|
|
||||||
/* todo: choose the appropriate weapon, when only one works against this target */
|
|
||||||
var range = Rules.WeaponInfo[weapon].Range;
|
|
||||||
|
|
||||||
mobile.Cancel(Attacker);
|
|
||||||
mobile.QueueActivity(
|
|
||||||
new Mobile.MoveTo(Target,
|
|
||||||
Math.Max(0, (int)range - RangeTolerance)));
|
|
||||||
}
|
|
||||||
|
|
||||||
Attacker.traits.Get<AttackTurreted>().target = Target;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,48 +17,9 @@ namespace OpenRa.Game.Traits
|
|||||||
|
|
||||||
// TODO: check that there's enough space at the destination.
|
// TODO: check that there's enough space at the destination.
|
||||||
if( xy == self.Location )
|
if( xy == self.Location )
|
||||||
return new DeployMcvOrder( self, xy );
|
return OpenRa.Game.Order.DeployMcv( self );
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class DeployMcvOrder : Order
|
|
||||||
{
|
|
||||||
Actor Unit;
|
|
||||||
int2 Location;
|
|
||||||
|
|
||||||
public DeployMcvOrder( Actor unit, int2 location )
|
|
||||||
{
|
|
||||||
Unit = unit;
|
|
||||||
Location = location;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Apply( bool doVoice )
|
|
||||||
{
|
|
||||||
var mobile = Unit.traits.Get<Mobile>();
|
|
||||||
mobile.QueueActivity( new Mobile.Turn( 96 ) );
|
|
||||||
mobile.QueueActivity( new DeployAction() );
|
|
||||||
}
|
|
||||||
|
|
||||||
class DeployAction : Mobile.CurrentActivity
|
|
||||||
{
|
|
||||||
public Mobile.CurrentActivity NextActivity { get; set; }
|
|
||||||
|
|
||||||
public void Tick( Actor self, Mobile mobile )
|
|
||||||
{
|
|
||||||
Game.world.AddFrameEndTask( _ =>
|
|
||||||
{
|
|
||||||
Game.world.Remove( self );
|
|
||||||
Game.world.Add( new Actor( "fact", self.Location - new int2( 1, 1 ), self.Owner ) );
|
|
||||||
} );
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Cancel( Actor self, Mobile mobile )
|
|
||||||
{
|
|
||||||
// Cancel can't happen between this being moved to the head of the list, and it being Ticked.
|
|
||||||
throw new InvalidOperationException( "DeployMcvAction: Cancel() should never occur." );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ namespace OpenRa.Game.Traits
|
|||||||
return null;
|
return null;
|
||||||
|
|
||||||
if( xy != toCell )
|
if( xy != toCell )
|
||||||
return new MoveOrder(self, xy);
|
return OpenRa.Game.Order.Move( self, xy );
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
73
OpenRa.Game/UnitOrders.cs
Executable file
73
OpenRa.Game/UnitOrders.cs
Executable file
@@ -0,0 +1,73 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using OpenRa.Game.Traits;
|
||||||
|
|
||||||
|
namespace OpenRa.Game
|
||||||
|
{
|
||||||
|
static class UnitOrders
|
||||||
|
{
|
||||||
|
public static void ProcessOrder( Order order )
|
||||||
|
{
|
||||||
|
switch( order.OrderString )
|
||||||
|
{
|
||||||
|
case "Move":
|
||||||
|
{
|
||||||
|
var mobile = order.Subject.traits.Get<Mobile>();
|
||||||
|
mobile.Cancel( order.Subject );
|
||||||
|
mobile.QueueActivity( new Mobile.MoveTo( order.TargetLocation ) );
|
||||||
|
|
||||||
|
var attackBase = order.Subject.traits.WithInterface<AttackBase>().FirstOrDefault();
|
||||||
|
if( attackBase != null )
|
||||||
|
attackBase.target = null; /* move cancels attack order */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "Attack":
|
||||||
|
{
|
||||||
|
const int RangeTolerance = 1; /* how far inside our maximum range we should try to sit */
|
||||||
|
var mobile = order.Subject.traits.GetOrDefault<Mobile>();
|
||||||
|
var weapon = order.Subject.unitInfo.Primary ?? order.Subject.unitInfo.Secondary;
|
||||||
|
|
||||||
|
mobile.Cancel( order.Subject );
|
||||||
|
// TODO: this block should be a separate activity; "MoveNear", maybe?
|
||||||
|
{
|
||||||
|
/* todo: choose the appropriate weapon, when only one works against this target */
|
||||||
|
var range = Rules.WeaponInfo[ weapon ].Range;
|
||||||
|
|
||||||
|
mobile.QueueActivity(
|
||||||
|
new Mobile.MoveTo( order.TargetActor,
|
||||||
|
Math.Max( 0, (int)range - RangeTolerance ) ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
order.Subject.traits.Get<AttackTurreted>().target = order.TargetActor;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "DeployMcv":
|
||||||
|
{
|
||||||
|
var mobile = order.Subject.traits.Get<Mobile>();
|
||||||
|
mobile.QueueActivity( new Mobile.Turn( 96 ) );
|
||||||
|
mobile.QueueActivity( new Traits.Activities.DeployMcv() );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "PlaceBuilding":
|
||||||
|
{
|
||||||
|
Game.world.AddFrameEndTask( _ =>
|
||||||
|
{
|
||||||
|
var building = Rules.UnitInfo[ order.TargetString ];
|
||||||
|
Log.Write( "Player \"{0}\" builds {1}", order.Player.PlayerName, building.Name );
|
||||||
|
|
||||||
|
//Adjust placement for cursor to be in middle
|
||||||
|
Game.world.Add( new Actor( building.Name, order.TargetLocation - GameRules.Footprint.AdjustForBuildingSize( building.Name ), order.Player ) );
|
||||||
|
|
||||||
|
Game.controller.orderGenerator = null;
|
||||||
|
Game.worldRenderer.uiOverlay.KillOverlay();
|
||||||
|
} );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user