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 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));
}
}

View File

@@ -44,12 +44,19 @@ namespace OpenRA.Traits
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; }
}

View File

@@ -217,14 +217,14 @@ namespace OpenRA.Mods.RA.Air
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;
}

View File

@@ -169,9 +169,9 @@ namespace OpenRA.Mods.RA
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;
@@ -181,20 +181,23 @@ namespace OpenRA.Mods.RA
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;
@@ -204,7 +207,7 @@ namespace OpenRA.Mods.RA
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;

View File

@@ -93,9 +93,9 @@ namespace OpenRA.Mods.RA
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>();
@@ -112,7 +112,7 @@ namespace OpenRA.Mods.RA
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))

View File

@@ -57,9 +57,9 @@ namespace OpenRA.Mods.RA
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>())
@@ -68,7 +68,7 @@ namespace OpenRA.Mods.RA
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";

View File

@@ -417,12 +417,12 @@ namespace OpenRA.Mods.RA
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;
@@ -433,7 +433,7 @@ namespace OpenRA.Mods.RA
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;
}

View File

@@ -99,9 +99,9 @@ namespace OpenRA.Mods.RA
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>())

View File

@@ -157,20 +157,20 @@ namespace OpenRA.Mods.RA
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; }
}

View File

@@ -476,14 +476,14 @@ namespace OpenRA.Mods.RA.Move
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))

View File

@@ -35,14 +35,14 @@ namespace OpenRA.Mods.RA.Orders
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;
}

View File

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

View File

@@ -33,28 +33,29 @@ namespace OpenRA.Mods.RA.Orders
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; }
}
@@ -68,15 +69,15 @@ namespace OpenRA.Mods.RA.Orders
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;
}

View File

@@ -58,12 +58,12 @@ namespace OpenRA.Mods.RA
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))
{

View File

@@ -69,9 +69,9 @@ namespace OpenRA.Mods.RA
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>();
@@ -80,10 +80,10 @@ namespace OpenRA.Mods.RA
// 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)

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