Add force-move

This commit is contained in:
Scott_NZ
2013-05-18 17:52:36 +12:00
parent cfcccb590d
commit ac430bd3bc
16 changed files with 77 additions and 59 deletions

View File

@@ -87,13 +87,19 @@ namespace OpenRA.Orders
{ {
var actorsAt = self.World.ActorMap.GetUnitsAt(xy).ToList(); var actorsAt = self.World.ActorMap.GetUnitsAt(xy).ToList();
var forceAttack = mi.Modifiers.HasModifier(Modifiers.Ctrl); var modifiers = TargetModifiers.None;
var forceQueue = mi.Modifiers.HasModifier(Modifiers.Shift); 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; string cursor = null;
if (underCursor != 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)); 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)); return new UnitOrderResult(self, o.Order, o.Trait, cursor, Target.FromCell(xy));
} }
} }

View File

@@ -44,12 +44,19 @@ namespace OpenRA.Traits
Order IssueOrder(Actor self, IOrderTargeter order, Target target, bool queued); 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 public interface IOrderTargeter
{ {
string OrderID { get; } string OrderID { get; }
int OrderPriority { get; } int OrderPriority { get; }
bool CanTargetActor(Actor self, Actor target, 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, bool forceAttack, bool forceQueue, ref string cursor); bool CanTargetLocation(Actor self, CPos location, List<Actor> actorsAtLocation, TargetModifiers modifiers, ref string cursor);
bool IsQueued { get; } bool IsQueued { get; }
} }

View File

@@ -217,14 +217,14 @@ namespace OpenRA.Mods.RA.Air
public string OrderID { get { return "Move"; } } public string OrderID { get { return "Move"; } }
public int OrderPriority { get { return 4; } } 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; 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"; cursor = self.World.Map.IsInMap(location) ? "move" : "move-blocked";
return true; return true;
} }

View File

@@ -169,9 +169,9 @@ namespace OpenRA.Mods.RA
public string OrderID { get; private set; } public string OrderID { get; private set; }
public int OrderPriority { 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; cursor = self.Info.Traits.Get<AttackBaseInfo>().Cursor;
@@ -181,20 +181,23 @@ namespace OpenRA.Mods.RA
if (!self.Trait<AttackBase>().HasAnyValidWeapons(Target.FromActor(target))) if (!self.Trait<AttackBase>().HasAnyValidWeapons(Target.FromActor(target)))
return false; return false;
if (forceAttack) if (modifiers.HasModifier(TargetModifiers.ForceAttack))
return true; return true;
if (modifiers.HasModifier(TargetModifiers.ForceMove))
return false;
var targetableRelationship = negativeDamage ? Stance.Ally : Stance.Enemy; var targetableRelationship = negativeDamage ? Stance.Ally : Stance.Enemy;
return self.Owner.Stances[target.Owner] == targetableRelationship; 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)) if (!self.World.Map.IsInMap(location))
return false; return false;
IsQueued = forceQueued; IsQueued = modifiers.HasModifier(TargetModifiers.ForceQueue);
cursor = self.Info.Traits.Get<AttackBaseInfo>().Cursor; cursor = self.Info.Traits.Get<AttackBaseInfo>().Cursor;
@@ -204,7 +207,7 @@ namespace OpenRA.Mods.RA
if (!self.Trait<AttackBase>().HasAnyValidWeapons(Target.FromCell(location))) if (!self.Trait<AttackBase>().HasAnyValidWeapons(Target.FromCell(location)))
return false; return false;
if (forceAttack) if (modifiers.HasModifier(TargetModifiers.ForceAttack))
if (self.Info.Traits.Get<AttackBaseInfo>().CanAttackGround) if (self.Info.Traits.Get<AttackBaseInfo>().CanAttackGround)
return true; return true;

View File

@@ -93,9 +93,9 @@ namespace OpenRA.Mods.RA
this.useEnterCursor = useEnterCursor; 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; return false;
var ci = target.Info.Traits.GetOrDefault<CapturableInfo>(); var ci = target.Info.Traits.GetOrDefault<CapturableInfo>();
@@ -112,7 +112,7 @@ namespace OpenRA.Mods.RA
if (playerRelationship == Stance.Neutral && !ci.AllowNeutral) if (playerRelationship == Stance.Neutral && !ci.AllowNeutral)
return false; return false;
IsQueued = forceQueued; IsQueued = modifiers.HasModifier(TargetModifiers.ForceQueue);
var Info = self.Info.Traits.Get<CapturesInfo>(); var Info = self.Info.Traits.Get<CapturesInfo>();
if (captureTypes.Contains(ci.Type)) if (captureTypes.Contains(ci.Type))

View File

@@ -57,9 +57,9 @@ namespace OpenRA.Mods.RA
public EngineerRepairOrderTargeter() public EngineerRepairOrderTargeter()
: base("EngineerRepair", 6, "goldwrench", false, true) { } : 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; return false;
if (!target.HasTrait<EngineerRepairable>()) if (!target.HasTrait<EngineerRepairable>())
@@ -68,7 +68,7 @@ namespace OpenRA.Mods.RA
if (self.Owner.Stances[target.Owner] != Stance.Ally) if (self.Owner.Stances[target.Owner] != Stance.Ally)
return false; return false;
IsQueued = forceQueued; IsQueued = modifiers.HasModifier(TargetModifiers.ForceQueue);
if (target.GetDamageState() == DamageState.Undamaged) if (target.GetDamageState() == DamageState.Undamaged)
cursor = "goldwrench-blocked"; cursor = "goldwrench-blocked";

View File

@@ -417,12 +417,12 @@ namespace OpenRA.Mods.RA
public int OrderPriority { get { return 10; } } public int OrderPriority { get { return 10; } }
public bool IsQueued { get; protected set; } 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; 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 // Don't leak info about resources under the shroud
if (!self.Owner.Shroud.IsExplored(location)) return false; if (!self.Owner.Shroud.IsExplored(location)) return false;
@@ -433,7 +433,7 @@ namespace OpenRA.Mods.RA
if (res == null) return false; if (res == null) return false;
if (!info.Resources.Contains(res.info.Name)) return false; if (!info.Resources.Contains(res.info.Name)) return false;
cursor = "harvest"; cursor = "harvest";
IsQueued = forceQueued; IsQueued = modifiers.HasModifier(TargetModifiers.ForceQueue);
return true; return true;
} }

View File

@@ -99,9 +99,9 @@ namespace OpenRA.Mods.RA
this.useEnterCursor = useEnterCursor; 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; return false;
if (!target.HasTrait<IAcceptInfiltrator>()) if (!target.HasTrait<IAcceptInfiltrator>())

View File

@@ -157,20 +157,20 @@ namespace OpenRA.Mods.RA
public string OrderID { get { return "BeginMinefield"; } } public string OrderID { get { return "BeginMinefield"; } }
public int OrderPriority { get { return 5; } } 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; 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)) if (!self.World.Map.IsInMap(location))
return false; return false;
cursor = "ability"; 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; } public bool IsQueued { get; protected set; }
} }

View File

@@ -476,14 +476,14 @@ namespace OpenRA.Mods.RA.Move
public int OrderPriority { get { return 4; } } public int OrderPriority { get { return 4; } }
public bool IsQueued { get; protected set; } 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; 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"; cursor = "move";
if (self.Owner.Shroud.IsExplored(location)) if (self.Owner.Shroud.IsExplored(location))

View File

@@ -35,14 +35,14 @@ namespace OpenRA.Mods.RA.Orders
public string OrderID { get; private set; } public string OrderID { get; private set; }
public int OrderPriority { 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"; cursor = useDeployCursor() ? "deploy" : "deploy-blocked";
return self == target; 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; return false;
} }

View File

@@ -9,6 +9,7 @@
#endregion #endregion
using System; using System;
using OpenRA.Traits;
namespace OpenRA.Mods.RA.Orders namespace OpenRA.Mods.RA.Orders
{ {
@@ -25,9 +26,9 @@ namespace OpenRA.Mods.RA.Orders
this.useEnterCursor = useEnterCursor; 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; return false;
if (!target.HasTrait<T>()) if (!target.HasTrait<T>())
@@ -37,7 +38,7 @@ namespace OpenRA.Mods.RA.Orders
return false; return false;
cursor = useEnterCursor(target) ? "enter" : "enter-blocked"; cursor = useEnterCursor(target) ? "enter" : "enter-blocked";
IsQueued = forceQueued; IsQueued = modifiers.HasModifier(TargetModifiers.ForceQueue);
return true; return true;
} }
} }

View File

@@ -33,28 +33,29 @@ namespace OpenRA.Mods.RA.Orders
public int OrderPriority { get; private set; } public int OrderPriority { get; private set; }
public bool? ForceAttack = null; 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( self == null ) throw new ArgumentNullException( "self" );
if( target == null ) throw new ArgumentNullException( "target" ); if( target == null ) throw new ArgumentNullException( "target" );
cursor = this.cursor; 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 (!modifiers.HasModifier(TargetModifiers.ForceAttack) && playerRelationship == Stance.Ally && !targetAllyUnits) return false;
if( !forceAttack && playerRelationship == Stance.Enemy && !targetEnemyUnits ) return false; if (!modifiers.HasModifier(TargetModifiers.ForceAttack) && playerRelationship == Stance.Enemy && !targetEnemyUnits) return false;
return true; 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; return false;
} }
public virtual bool IsQueued { get; protected set; } public virtual bool IsQueued { get; protected set; }
} }
@@ -68,15 +69,15 @@ namespace OpenRA.Mods.RA.Orders
this.targetType = targetType; 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; return false;
if (!target.TraitsImplementing<ITargetable>().Any(t => t.TargetTypes.Contains(targetType))) if (!target.TraitsImplementing<ITargetable>().Any(t => t.TargetTypes.Contains(targetType)))
return false; return false;
IsQueued = forceQueued; IsQueued = modifiers.HasModifier(TargetModifiers.ForceQueue);
return true; return true;
} }

View File

@@ -58,12 +58,12 @@ namespace OpenRA.Mods.RA
public string OrderID { get { return "SetRallyPoint"; } } public string OrderID { get { return "SetRallyPoint"; } }
public int OrderPriority { get { return 0; } } 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; 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)) if (self.World.Map.IsInMap(location))
{ {

View File

@@ -69,9 +69,9 @@ namespace OpenRA.Mods.RA
public RepairBridgeOrderTargeter() public RepairBridgeOrderTargeter()
: base("RepairBridge", 6, "goldwrench", true, true) { } : 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; return false;
var bridge = target.TraitOrDefault<BridgeHut>(); var bridge = target.TraitOrDefault<BridgeHut>();
@@ -80,10 +80,10 @@ namespace OpenRA.Mods.RA
// Require force attack to heal partially damaged bridges to avoid unnecessary cursor noise // Require force attack to heal partially damaged bridges to avoid unnecessary cursor noise
var damage = bridge.BridgeDamageState; var damage = bridge.BridgeDamageState;
if (!forceAttack && damage != DamageState.Dead) if (!modifiers.HasModifier(TargetModifiers.ForceAttack) && damage != DamageState.Dead)
return false; return false;
IsQueued = forceQueued; IsQueued = modifiers.HasModifier(TargetModifiers.ForceQueue);
// Can't repair an undamaged bridge // Can't repair an undamaged bridge
if (damage == DamageState.Undamaged) if (damage == DamageState.Undamaged)

View File

@@ -70,9 +70,9 @@ namespace OpenRA.Mods.RA
{ {
} }
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; return false;
if (target.AppearsHostileTo(self)) if (target.AppearsHostileTo(self))
@@ -81,7 +81,7 @@ namespace OpenRA.Mods.RA
if (!target.HasTrait<AcceptsSupplies>()) if (!target.HasTrait<AcceptsSupplies>())
return false; return false;
IsQueued = forceQueued; IsQueued = modifiers.HasModifier(TargetModifiers.ForceQueue);
return true; return true;
} }
} }