Skip to content

Commit

Permalink
Merge pull request #3312 from ScottNZ/forcemove
Browse files Browse the repository at this point in the history
Add force-move
  • Loading branch information
chrisforbes committed May 26, 2013
2 parents 5af277d + ac430bd commit 33376b5
Show file tree
Hide file tree
Showing 16 changed files with 77 additions and 59 deletions.
14 changes: 10 additions & 4 deletions OpenRA.Game/Orders/UnitOrderGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -87,13 +87,19 @@ static UnitOrderResult OrderForUnit(Actor self, CPos xy, MouseInput mi, Actor un
{
var actorsAt = self.World.ActorMap.GetUnitsAt(xy).ToList();

var forceAttack = mi.Modifiers.HasModifier(Modifiers.Ctrl);
var forceQueue = mi.Modifiers.HasModifier(Modifiers.Shift);
var modifiers = TargetModifiers.None;
if (mi.Modifiers.HasModifier(Modifiers.Ctrl))
modifiers |= TargetModifiers.ForceAttack;
if (mi.Modifiers.HasModifier(Modifiers.Shift))
modifiers |= TargetModifiers.ForceQueue;
if (mi.Modifiers.HasModifier(Modifiers.Alt))
modifiers |= TargetModifiers.ForceMove;

string cursor = null;
if (underCursor != null)
if (o.Order.CanTargetActor(self, underCursor, forceAttack, forceQueue, ref cursor))
if (o.Order.CanTargetActor(self, underCursor, modifiers, ref cursor))
return new UnitOrderResult(self, o.Order, o.Trait, cursor, Target.FromActor(underCursor));
if (o.Order.CanTargetLocation(self, xy, actorsAt, forceAttack, forceQueue, ref cursor))
if (o.Order.CanTargetLocation(self, xy, actorsAt, modifiers, ref cursor))
return new UnitOrderResult(self, o.Order, o.Trait, cursor, Target.FromCell(xy));
}
}
Expand Down
11 changes: 9 additions & 2 deletions OpenRA.Game/Traits/TraitsInterfaces.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,19 @@ public interface IIssueOrder
Order IssueOrder(Actor self, IOrderTargeter order, Target target, bool queued);
}

[Flags] public enum TargetModifiers { None = 0, ForceAttack = 1, ForceQueue = 2, ForceMove = 4 };

public static class TargetModifiersExts
{
public static bool HasModifier(this TargetModifiers self, TargetModifiers m) { return (self & m) == m; }
}

public interface IOrderTargeter
{
string OrderID { get; }
int OrderPriority { get; }
bool CanTargetActor(Actor self, Actor target, bool forceAttack, bool forceQueue, ref string cursor);
bool CanTargetLocation(Actor self, CPos location, List<Actor> actorsAtLocation, bool forceAttack, bool forceQueue, ref string cursor);
bool CanTargetActor(Actor self, Actor target, TargetModifiers modifiers, ref string cursor);
bool CanTargetLocation(Actor self, CPos location, List<Actor> actorsAtLocation, TargetModifiers modifiers, ref string cursor);
bool IsQueued { get; }
}

Expand Down
6 changes: 3 additions & 3 deletions OpenRA.Mods.RA/Air/Aircraft.cs
Original file line number Diff line number Diff line change
Expand Up @@ -217,14 +217,14 @@ class AircraftMoveOrderTargeter : IOrderTargeter
public string OrderID { get { return "Move"; } }
public int OrderPriority { get { return 4; } }

public bool CanTargetActor(Actor self, Actor target, bool forceAttack, bool forceQueued, ref string cursor)
public bool CanTargetActor(Actor self, Actor target, TargetModifiers modifiers, ref string cursor)
{
return false;
}

public bool CanTargetLocation(Actor self, CPos location, List<Actor> actorsAtLocation, bool forceAttack, bool forceQueued, ref string cursor)
public bool CanTargetLocation(Actor self, CPos location, List<Actor> actorsAtLocation, TargetModifiers modifiers, ref string cursor)
{
IsQueued = forceQueued;
IsQueued = modifiers.HasModifier(TargetModifiers.ForceQueue);
cursor = self.World.Map.IsInMap(location) ? "move" : "move-blocked";
return true;
}
Expand Down
15 changes: 9 additions & 6 deletions OpenRA.Mods.RA/Attack/AttackBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -169,9 +169,9 @@ public AttackOrderTargeter(string order, int priority, bool negativeDamage)
public string OrderID { get; private set; }
public int OrderPriority { get; private set; }

public bool CanTargetActor(Actor self, Actor target, bool forceAttack, bool forceQueued, ref string cursor)
public bool CanTargetActor(Actor self, Actor target, TargetModifiers modifiers, ref string cursor)
{
IsQueued = forceQueued;
IsQueued = modifiers.HasModifier(TargetModifiers.ForceQueue);

cursor = self.Info.Traits.Get<AttackBaseInfo>().Cursor;

Expand All @@ -181,20 +181,23 @@ public bool CanTargetActor(Actor self, Actor target, bool forceAttack, bool forc
if (!self.Trait<AttackBase>().HasAnyValidWeapons(Target.FromActor(target)))
return false;

if (forceAttack)
if (modifiers.HasModifier(TargetModifiers.ForceAttack))
return true;

if (modifiers.HasModifier(TargetModifiers.ForceMove))
return false;

var targetableRelationship = negativeDamage ? Stance.Ally : Stance.Enemy;

return self.Owner.Stances[target.Owner] == targetableRelationship;
}

public bool CanTargetLocation(Actor self, CPos location, List<Actor> actorsAtLocation, bool forceAttack, bool forceQueued, ref string cursor)
public bool CanTargetLocation(Actor self, CPos location, List<Actor> actorsAtLocation, TargetModifiers modifiers, ref string cursor)
{
if (!self.World.Map.IsInMap(location))
return false;

IsQueued = forceQueued;
IsQueued = modifiers.HasModifier(TargetModifiers.ForceQueue);

cursor = self.Info.Traits.Get<AttackBaseInfo>().Cursor;

Expand All @@ -204,7 +207,7 @@ public bool CanTargetLocation(Actor self, CPos location, List<Actor> actorsAtLoc
if (!self.Trait<AttackBase>().HasAnyValidWeapons(Target.FromCell(location)))
return false;

if (forceAttack)
if (modifiers.HasModifier(TargetModifiers.ForceAttack))
if (self.Info.Traits.Get<AttackBaseInfo>().CanAttackGround)
return true;

Expand Down
6 changes: 3 additions & 3 deletions OpenRA.Mods.RA/Captures.cs
Original file line number Diff line number Diff line change
Expand Up @@ -93,9 +93,9 @@ public CaptureOrderTargeter(string[] captureTypes, Func<Actor, bool> useEnterCur
this.useEnterCursor = useEnterCursor;
}

public override bool CanTargetActor(Actor self, Actor target, bool forceAttack, bool forceQueued, ref string cursor)
public override bool CanTargetActor(Actor self, Actor target, TargetModifiers modifiers, ref string cursor)
{
if (!base.CanTargetActor(self, target, forceAttack, forceQueued, ref cursor))
if (!base.CanTargetActor(self, target, modifiers, ref cursor))
return false;

var ci = target.Info.Traits.GetOrDefault<CapturableInfo>();
Expand All @@ -112,7 +112,7 @@ public override bool CanTargetActor(Actor self, Actor target, bool forceAttack,
if (playerRelationship == Stance.Neutral && !ci.AllowNeutral)
return false;

IsQueued = forceQueued;
IsQueued = modifiers.HasModifier(TargetModifiers.ForceQueue);

var Info = self.Info.Traits.Get<CapturesInfo>();
if (captureTypes.Contains(ci.Type))
Expand Down
6 changes: 3 additions & 3 deletions OpenRA.Mods.RA/EngineerRepair.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,9 @@ class EngineerRepairOrderTargeter : UnitOrderTargeter
public EngineerRepairOrderTargeter()
: base("EngineerRepair", 6, "goldwrench", false, true) { }

public override bool CanTargetActor(Actor self, Actor target, bool forceAttack, bool forceQueued, ref string cursor)
public override bool CanTargetActor(Actor self, Actor target, TargetModifiers modifiers, ref string cursor)
{
if (!base.CanTargetActor(self, target, forceAttack, forceQueued, ref cursor))
if (!base.CanTargetActor(self, target, modifiers, ref cursor))
return false;

if (!target.HasTrait<EngineerRepairable>())
Expand All @@ -68,7 +68,7 @@ public override bool CanTargetActor(Actor self, Actor target, bool forceAttack,
if (self.Owner.Stances[target.Owner] != Stance.Ally)
return false;

IsQueued = forceQueued;
IsQueued = modifiers.HasModifier(TargetModifiers.ForceQueue);

if (target.GetDamageState() == DamageState.Undamaged)
cursor = "goldwrench-blocked";
Expand Down
6 changes: 3 additions & 3 deletions OpenRA.Mods.RA/Harvester.cs
Original file line number Diff line number Diff line change
Expand Up @@ -417,12 +417,12 @@ class HarvestOrderTargeter : IOrderTargeter
public int OrderPriority { get { return 10; } }
public bool IsQueued { get; protected set; }

public bool CanTargetActor(Actor self, Actor target, bool forceAttack, bool forceQueued, ref string cursor)
public bool CanTargetActor(Actor self, Actor target, TargetModifiers modifiers, ref string cursor)
{
return false;
}

public bool CanTargetLocation(Actor self, CPos location, List<Actor> actorsAtLocation, bool forceAttack, bool forceQueued, ref string cursor)
public bool CanTargetLocation(Actor self, CPos location, List<Actor> actorsAtLocation, TargetModifiers modifiers, ref string cursor)
{
// Don't leak info about resources under the shroud
if (!self.Owner.Shroud.IsExplored(location)) return false;
Expand All @@ -433,7 +433,7 @@ public bool CanTargetLocation(Actor self, CPos location, List<Actor> actorsAtLoc
if (res == null) return false;
if (!info.Resources.Contains(res.info.Name)) return false;
cursor = "harvest";
IsQueued = forceQueued;
IsQueued = modifiers.HasModifier(TargetModifiers.ForceQueue);

return true;
}
Expand Down
6 changes: 3 additions & 3 deletions OpenRA.Mods.RA/Infiltrates.cs
Original file line number Diff line number Diff line change
Expand Up @@ -98,10 +98,10 @@ public InfiltratorOrderTargeter(Func<Actor, bool> useEnterCursor)
ForceAttack = false;
this.useEnterCursor = useEnterCursor;
}
public override bool CanTargetActor(Actor self, Actor target, bool forceAttack, bool forceQueued, ref string cursor)

public override bool CanTargetActor(Actor self, Actor target, TargetModifiers modifiers, ref string cursor)
{
if (!base.CanTargetActor(self, target, forceAttack, forceQueued, ref cursor))
if (!base.CanTargetActor(self, target, modifiers, ref cursor))
return false;

if (!target.HasTrait<IAcceptInfiltrator>())
Expand Down
8 changes: 4 additions & 4 deletions OpenRA.Mods.RA/Minelayer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -157,20 +157,20 @@ class BeginMinefieldOrderTargeter : IOrderTargeter
public string OrderID { get { return "BeginMinefield"; } }
public int OrderPriority { get { return 5; } }

public bool CanTargetActor(Actor self, Actor target, bool forceAttack, bool forceQueued, ref string cursor)
public bool CanTargetActor(Actor self, Actor target, TargetModifiers modifiers, ref string cursor)
{
return false;
}

public bool CanTargetLocation(Actor self, CPos location, List<Actor> actorsAtLocation, bool forceAttack, bool forceQueued, ref string cursor)
public bool CanTargetLocation(Actor self, CPos location, List<Actor> actorsAtLocation, TargetModifiers modifiers, ref string cursor)
{
if (!self.World.Map.IsInMap(location))
return false;

cursor = "ability";
IsQueued = forceQueued;
IsQueued = modifiers.HasModifier(TargetModifiers.ForceQueue);

return (actorsAtLocation.Count == 0 && forceAttack);
return (actorsAtLocation.Count == 0 && modifiers.HasModifier(TargetModifiers.ForceAttack));
}
public bool IsQueued { get; protected set; }
}
Expand Down
6 changes: 3 additions & 3 deletions OpenRA.Mods.RA/Move/Mobile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -476,14 +476,14 @@ public MoveOrderTargeter(MobileInfo unitType)
public int OrderPriority { get { return 4; } }
public bool IsQueued { get; protected set; }

public bool CanTargetActor(Actor self, Actor target, bool forceAttack, bool forceQueued, ref string cursor)
public bool CanTargetActor(Actor self, Actor target, TargetModifiers modifiers, ref string cursor)
{
return false;
}

public bool CanTargetLocation(Actor self, CPos location, List<Actor> actorsAtLocation, bool forceAttack, bool forceQueued, ref string cursor)
public bool CanTargetLocation(Actor self, CPos location, List<Actor> actorsAtLocation, TargetModifiers modifiers, ref string cursor)
{
IsQueued = forceQueued;
IsQueued = modifiers.HasModifier(TargetModifiers.ForceQueue);
cursor = "move";

if (self.Owner.Shroud.IsExplored(location))
Expand Down
6 changes: 3 additions & 3 deletions OpenRA.Mods.RA/Orders/DeployOrderTargeter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,14 @@ public DeployOrderTargeter( string order, int priority, Func<bool> useDeployCurs
public string OrderID { get; private set; }
public int OrderPriority { get; private set; }

public bool CanTargetActor( Actor self, Actor target, bool forceAttack, bool forceQueued, ref string cursor )
public bool CanTargetActor(Actor self, Actor target, TargetModifiers modifiers, ref string cursor)
{
IsQueued = forceQueued;
IsQueued = modifiers.HasModifier(TargetModifiers.ForceQueue);
cursor = useDeployCursor() ? "deploy" : "deploy-blocked";
return self == target;
}

public bool CanTargetLocation(Actor self, CPos location, List<Actor> actorsAtLocation, bool forceAttack, bool forceQueued, ref string cursor)
public bool CanTargetLocation(Actor self, CPos location, List<Actor> actorsAtLocation, TargetModifiers modifiers, ref string cursor)
{
return false;
}
Expand Down
7 changes: 4 additions & 3 deletions OpenRA.Mods.RA/Orders/EnterBuildingOrderTargeter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#endregion

using System;
using OpenRA.Traits;

namespace OpenRA.Mods.RA.Orders
{
Expand All @@ -25,9 +26,9 @@ public class EnterOrderTargeter<T> : UnitOrderTargeter
this.useEnterCursor = useEnterCursor;
}

public override bool CanTargetActor(Actor self, Actor target, bool forceAttack, bool forceQueued, ref string cursor)
public override bool CanTargetActor(Actor self, Actor target, TargetModifiers modifiers, ref string cursor)
{
if (!base.CanTargetActor(self, target, forceAttack, forceQueued, ref cursor))
if (!base.CanTargetActor(self, target, modifiers, ref cursor))
return false;

if (!target.HasTrait<T>())
Expand All @@ -37,7 +38,7 @@ public override bool CanTargetActor(Actor self, Actor target, bool forceAttack,
return false;

cursor = useEnterCursor(target) ? "enter" : "enter-blocked";
IsQueued = forceQueued;
IsQueued = modifiers.HasModifier(TargetModifiers.ForceQueue);
return true;
}
}
Expand Down
21 changes: 11 additions & 10 deletions OpenRA.Mods.RA/Orders/UnitOrderTargeter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,28 +33,29 @@ public UnitOrderTargeter( string order, int priority, string cursor, bool target
public int OrderPriority { get; private set; }
public bool? ForceAttack = null;

public virtual bool CanTargetActor(Actor self, Actor target, bool forceAttack, bool forceQueued, ref string cursor)
public virtual bool CanTargetActor(Actor self, Actor target, TargetModifiers modifiers, ref string cursor)
{
if( self == null ) throw new ArgumentNullException( "self" );
if( target == null ) throw new ArgumentNullException( "target" );

cursor = this.cursor;
IsQueued = forceQueued;
IsQueued = modifiers.HasModifier(TargetModifiers.ForceQueue);

if (ForceAttack != null && forceAttack != ForceAttack) return false;
if (ForceAttack != null && modifiers.HasModifier(TargetModifiers.ForceAttack) != ForceAttack) return false;

var playerRelationship = self.Owner.Stances[ target.Owner ];
var playerRelationship = self.Owner.Stances[target.Owner];

if( !forceAttack && playerRelationship == Stance.Ally && !targetAllyUnits ) return false;
if( !forceAttack && playerRelationship == Stance.Enemy && !targetEnemyUnits ) return false;
if (!modifiers.HasModifier(TargetModifiers.ForceAttack) && playerRelationship == Stance.Ally && !targetAllyUnits) return false;
if (!modifiers.HasModifier(TargetModifiers.ForceAttack) && playerRelationship == Stance.Enemy && !targetEnemyUnits) return false;

return true;
}

public virtual bool CanTargetLocation(Actor self, CPos location, List<Actor> actorsAtLocation, bool forceAttack, bool forceQueued, ref string cursor)
public virtual bool CanTargetLocation(Actor self, CPos location, List<Actor> actorsAtLocation, TargetModifiers modifiers, ref string cursor)
{
return false;
}

public virtual bool IsQueued { get; protected set; }
}

Expand All @@ -68,15 +69,15 @@ public TargetTypeOrderTargeter(string targetType, string order, int priority, st
this.targetType = targetType;
}

public override bool CanTargetActor(Actor self, Actor target, bool forceAttack, bool forceQueued, ref string cursor)
public override bool CanTargetActor(Actor self, Actor target, TargetModifiers modifiers, ref string cursor)
{
if (!base.CanTargetActor(self, target, forceAttack, forceQueued, ref cursor))
if (!base.CanTargetActor(self, target, modifiers, ref cursor))
return false;

if (!target.TraitsImplementing<ITargetable>().Any(t => t.TargetTypes.Contains(targetType)))
return false;

IsQueued = forceQueued;
IsQueued = modifiers.HasModifier(TargetModifiers.ForceQueue);

return true;
}
Expand Down
4 changes: 2 additions & 2 deletions OpenRA.Mods.RA/RallyPoint.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,12 @@ class RallyPointOrderTargeter : IOrderTargeter
public string OrderID { get { return "SetRallyPoint"; } }
public int OrderPriority { get { return 0; } }

public bool CanTargetActor(Actor self, Actor target, bool forceAttack, bool forceQueued, ref string cursor)
public bool CanTargetActor(Actor self, Actor target, TargetModifiers modifiers, ref string cursor)
{
return false;
}

public bool CanTargetLocation(Actor self, CPos location, List<Actor> actorsAtLocation, bool forceAttack, bool forceQueued, ref string cursor)
public bool CanTargetLocation(Actor self, CPos location, List<Actor> actorsAtLocation, TargetModifiers modifiers, ref string cursor)
{
if (self.World.Map.IsInMap(location))
{
Expand Down
8 changes: 4 additions & 4 deletions OpenRA.Mods.RA/RepairsBridges.cs
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,9 @@ class RepairBridgeOrderTargeter : UnitOrderTargeter
public RepairBridgeOrderTargeter()
: base("RepairBridge", 6, "goldwrench", true, true) { }

public override bool CanTargetActor(Actor self, Actor target, bool forceAttack, bool forceQueued, ref string cursor)
public override bool CanTargetActor(Actor self, Actor target, TargetModifiers modifiers, ref string cursor)
{
if (!base.CanTargetActor(self, target, forceAttack, forceQueued, ref cursor))
if (!base.CanTargetActor(self, target, modifiers, ref cursor))
return false;

var bridge = target.TraitOrDefault<BridgeHut>();
Expand All @@ -80,10 +80,10 @@ public override bool CanTargetActor(Actor self, Actor target, bool forceAttack,

// Require force attack to heal partially damaged bridges to avoid unnecessary cursor noise
var damage = bridge.BridgeDamageState;
if (!forceAttack && damage != DamageState.Dead)
if (!modifiers.HasModifier(TargetModifiers.ForceAttack) && damage != DamageState.Dead)
return false;

IsQueued = forceQueued;
IsQueued = modifiers.HasModifier(TargetModifiers.ForceQueue);

// Can't repair an undamaged bridge
if (damage == DamageState.Undamaged)
Expand Down
6 changes: 3 additions & 3 deletions OpenRA.Mods.RA/SupplyTruck.cs
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,9 @@ public SupplyTruckOrderTargeter()
{
}

public override bool CanTargetActor(Actor self, Actor target, bool forceAttack, bool forceQueued, ref string cursor)
public override bool CanTargetActor(Actor self, Actor target, TargetModifiers modifiers, ref string cursor)
{
if (!base.CanTargetActor(self, target, forceAttack, forceQueued, ref cursor))
if (!base.CanTargetActor(self, target, modifiers, ref cursor))
return false;

if (target.AppearsHostileTo(self))
Expand All @@ -81,7 +81,7 @@ public override bool CanTargetActor(Actor self, Actor target, bool forceAttack,
if (!target.HasTrait<AcceptsSupplies>())
return false;

IsQueued = forceQueued;
IsQueued = modifiers.HasModifier(TargetModifiers.ForceQueue);
return true;
}
}
Expand Down

0 comments on commit 33376b5

Please sign in to comment.