Add force-move
This commit is contained in:
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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; }
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -98,10 +98,10 @@ namespace OpenRA.Mods.RA
|
||||
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>())
|
||||
|
||||
@@ -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; }
|
||||
}
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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))
|
||||
{
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user