diff --git a/OpenRA.Game/Orders/UnitOrderGenerator.cs b/OpenRA.Game/Orders/UnitOrderGenerator.cs index 2c2a75950d..7ee5e66689 100644 --- a/OpenRA.Game/Orders/UnitOrderGenerator.cs +++ b/OpenRA.Game/Orders/UnitOrderGenerator.cs @@ -96,11 +96,9 @@ namespace OpenRA.Orders modifiers |= TargetModifiers.ForceMove; string cursor = null; - if (underCursor != null) - 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, modifiers, ref cursor)) - return new UnitOrderResult(self, o.Order, o.Trait, cursor, Target.FromCell(xy)); + var target = underCursor != null ? Target.FromActor(underCursor) : Target.FromCell(xy); + if (o.Order.CanTarget(self, target, actorsAt, modifiers, ref cursor)) + return new UnitOrderResult(self, o.Order, o.Trait, cursor, target); } } diff --git a/OpenRA.Game/Traits/TraitsInterfaces.cs b/OpenRA.Game/Traits/TraitsInterfaces.cs index 251b2ddbe3..6b434464e7 100755 --- a/OpenRA.Game/Traits/TraitsInterfaces.cs +++ b/OpenRA.Game/Traits/TraitsInterfaces.cs @@ -55,8 +55,7 @@ namespace OpenRA.Traits { string OrderID { get; } int OrderPriority { get; } - bool CanTargetActor(Actor self, Actor target, TargetModifiers modifiers, ref string cursor); - bool CanTargetLocation(Actor self, CPos location, List actorsAtLocation, TargetModifiers modifiers, ref string cursor); + bool CanTarget(Actor self, Target target, List othersAtTarget, TargetModifiers modifiers, ref string cursor); bool IsQueued { get; } } diff --git a/OpenRA.Mods.RA/Air/Aircraft.cs b/OpenRA.Mods.RA/Air/Aircraft.cs index b9b407b1c4..9240cb9b3e 100755 --- a/OpenRA.Mods.RA/Air/Aircraft.cs +++ b/OpenRA.Mods.RA/Air/Aircraft.cs @@ -217,15 +217,13 @@ namespace OpenRA.Mods.RA.Air public string OrderID { get { return "Move"; } } public int OrderPriority { get { return 4; } } - public bool CanTargetActor(Actor self, Actor target, TargetModifiers modifiers, ref string cursor) + public bool CanTarget(Actor self, Target target, List othersAtTarget, TargetModifiers modifiers, ref string cursor) { - return false; - } + if (target.Type != TargetType.Terrain) + return false; - public bool CanTargetLocation(Actor self, CPos location, List actorsAtLocation, TargetModifiers modifiers, ref string cursor) - { IsQueued = modifiers.HasModifier(TargetModifiers.ForceQueue); - cursor = self.World.Map.IsInMap(location) ? "move" : "move-blocked"; + cursor = self.World.Map.IsInMap(target.CenterPosition.ToCPos()) ? "move" : "move-blocked"; return true; } diff --git a/OpenRA.Mods.RA/Attack/AttackBase.cs b/OpenRA.Mods.RA/Attack/AttackBase.cs index 94f2b5d8d0..7406e0be06 100644 --- a/OpenRA.Mods.RA/Attack/AttackBase.cs +++ b/OpenRA.Mods.RA/Attack/AttackBase.cs @@ -169,7 +169,7 @@ namespace OpenRA.Mods.RA public string OrderID { get; private set; } public int OrderPriority { get; private set; } - public bool CanTargetActor(Actor self, Actor target, TargetModifiers modifiers, ref string cursor) + bool CanTargetActor(Actor self, Actor target, TargetModifiers modifiers, ref string cursor) { IsQueued = modifiers.HasModifier(TargetModifiers.ForceQueue); @@ -192,7 +192,7 @@ namespace OpenRA.Mods.RA return self.Owner.Stances[target.Owner] == targetableRelationship; } - public bool CanTargetLocation(Actor self, CPos location, List actorsAtLocation, TargetModifiers modifiers, ref string cursor) + bool CanTargetLocation(Actor self, CPos location, List actorsAtLocation, TargetModifiers modifiers, ref string cursor) { if (!self.World.Map.IsInMap(location)) return false; @@ -214,6 +214,17 @@ namespace OpenRA.Mods.RA return false; } + public bool CanTarget(Actor self, Target target, List othersAtTarget, TargetModifiers modifiers, ref string cursor) + { + if (target.Type == TargetType.Actor) + return CanTargetActor(self, target.Actor, modifiers, ref cursor); + + if (target.Type == TargetType.Terrain) + return CanTargetLocation(self, target.CenterPosition.ToCPos(), othersAtTarget, modifiers, ref cursor); + + return false; + } + public bool IsQueued { get; protected set; } } } diff --git a/OpenRA.Mods.RA/Captures.cs b/OpenRA.Mods.RA/Captures.cs index 093bfec04a..cc8242fd68 100644 --- a/OpenRA.Mods.RA/Captures.cs +++ b/OpenRA.Mods.RA/Captures.cs @@ -96,9 +96,6 @@ namespace OpenRA.Mods.RA public override bool CanTargetActor(Actor self, Actor target, TargetModifiers modifiers, ref string cursor) { - if (!base.CanTargetActor(self, target, modifiers, ref cursor)) - return false; - var canTargetActor = useCaptureCursor(target); cursor = canTargetActor ? "ability" : "move-blocked"; diff --git a/OpenRA.Mods.RA/EngineerRepair.cs b/OpenRA.Mods.RA/EngineerRepair.cs index 785c5029a6..9d2c6671b3 100644 --- a/OpenRA.Mods.RA/EngineerRepair.cs +++ b/OpenRA.Mods.RA/EngineerRepair.cs @@ -59,9 +59,6 @@ namespace OpenRA.Mods.RA public override bool CanTargetActor(Actor self, Actor target, TargetModifiers modifiers, ref string cursor) { - if (!base.CanTargetActor(self, target, modifiers, ref cursor)) - return false; - if (!target.HasTrait()) return false; diff --git a/OpenRA.Mods.RA/Harvester.cs b/OpenRA.Mods.RA/Harvester.cs index ec1860261d..a2126cda1d 100644 --- a/OpenRA.Mods.RA/Harvester.cs +++ b/OpenRA.Mods.RA/Harvester.cs @@ -419,16 +419,15 @@ namespace OpenRA.Mods.RA public int OrderPriority { get { return 10; } } public bool IsQueued { get; protected set; } - public bool CanTargetActor(Actor self, Actor target, TargetModifiers modifiers, ref string cursor) + public bool CanTarget(Actor self, Target target, List othersAtTarget, TargetModifiers modifiers, ref string cursor) { - return false; - } + if (target.Type != TargetType.Terrain) + return false; - public bool CanTargetLocation(Actor self, CPos location, List actorsAtLocation, TargetModifiers modifiers, ref string cursor) - { if (modifiers.HasModifier(TargetModifiers.ForceMove)) return false; + var location = target.CenterPosition.ToCPos(); // Don't leak info about resources under the shroud if (!self.Owner.Shroud.IsExplored(location)) return false; diff --git a/OpenRA.Mods.RA/Infiltrates.cs b/OpenRA.Mods.RA/Infiltrates.cs index 195b355fde..d7ae411874 100644 --- a/OpenRA.Mods.RA/Infiltrates.cs +++ b/OpenRA.Mods.RA/Infiltrates.cs @@ -95,9 +95,6 @@ namespace OpenRA.Mods.RA public override bool CanTargetActor(Actor self, Actor target, TargetModifiers modifiers, ref string cursor) { - if (!base.CanTargetActor(self, target, modifiers, ref cursor)) - return false; - if (!target.HasTrait()) return false; diff --git a/OpenRA.Mods.RA/LegacyCaptures.cs b/OpenRA.Mods.RA/LegacyCaptures.cs index 32a0602bc4..5c393fa796 100644 --- a/OpenRA.Mods.RA/LegacyCaptures.cs +++ b/OpenRA.Mods.RA/LegacyCaptures.cs @@ -94,8 +94,6 @@ namespace OpenRA.Mods.RA public override bool CanTargetActor(Actor self, Actor target, TargetModifiers modifiers, ref string cursor) { - if (!base.CanTargetActor(self, target, modifiers, ref cursor)) return false; - var canTargetActor = useCaptureCursor(target); if (canTargetActor) diff --git a/OpenRA.Mods.RA/Minelayer.cs b/OpenRA.Mods.RA/Minelayer.cs index 2030368a42..a8f56b9913 100644 --- a/OpenRA.Mods.RA/Minelayer.cs +++ b/OpenRA.Mods.RA/Minelayer.cs @@ -156,21 +156,21 @@ namespace OpenRA.Mods.RA public string OrderID { get { return "BeginMinefield"; } } public int OrderPriority { get { return 5; } } - public bool CanTargetActor(Actor self, Actor target, TargetModifiers modifiers, ref string cursor) + public bool CanTarget(Actor self, Target target, List othersAtTarget, TargetModifiers modifiers, ref string cursor) { - return false; - } + if (target.Type != TargetType.Terrain) + return false; - public bool CanTargetLocation(Actor self, CPos location, List actorsAtLocation, TargetModifiers modifiers, ref string cursor) - { + var location = target.CenterPosition.ToCPos(); if (!self.World.Map.IsInMap(location)) return false; cursor = "ability"; IsQueued = modifiers.HasModifier(TargetModifiers.ForceQueue); - return (actorsAtLocation.Count == 0 && modifiers.HasModifier(TargetModifiers.ForceAttack)); + return !othersAtTarget.Any() && modifiers.HasModifier(TargetModifiers.ForceAttack); } + public bool IsQueued { get; protected set; } } } diff --git a/OpenRA.Mods.RA/Move/Mobile.cs b/OpenRA.Mods.RA/Move/Mobile.cs index 0da1ec50b1..1b9217f3d0 100755 --- a/OpenRA.Mods.RA/Move/Mobile.cs +++ b/OpenRA.Mods.RA/Move/Mobile.cs @@ -494,13 +494,12 @@ namespace OpenRA.Mods.RA.Move public int OrderPriority { get { return 4; } } public bool IsQueued { get; protected set; } - public bool CanTargetActor(Actor self, Actor target, TargetModifiers modifiers, ref string cursor) + public bool CanTarget(Actor self, Target target, List othersAtTarget, TargetModifiers modifiers, ref string cursor) { - return false; - } + if (!target.IsValid) + return false; - public bool CanTargetLocation(Actor self, CPos location, List actorsAtLocation, TargetModifiers modifiers, ref string cursor) - { + var location = target.CenterPosition.ToCPos(); IsQueued = modifiers.HasModifier(TargetModifiers.ForceQueue); cursor = "move"; diff --git a/OpenRA.Mods.RA/Orders/DeployOrderTargeter.cs b/OpenRA.Mods.RA/Orders/DeployOrderTargeter.cs index 88491e5e83..bd28e219af 100755 --- a/OpenRA.Mods.RA/Orders/DeployOrderTargeter.cs +++ b/OpenRA.Mods.RA/Orders/DeployOrderTargeter.cs @@ -35,16 +35,15 @@ namespace OpenRA.Mods.RA.Orders public string OrderID { get; private set; } public int OrderPriority { get; private set; } - public bool CanTargetActor(Actor self, Actor target, TargetModifiers modifiers, ref string cursor) + public bool CanTarget(Actor self, Target target, List othersAtTarget, TargetModifiers modifiers, ref string cursor) { + if (target.Type != TargetType.Actor) + return false; + IsQueued = modifiers.HasModifier(TargetModifiers.ForceQueue); cursor = useDeployCursor() ? "deploy" : "deploy-blocked"; - return self == target; - } - public bool CanTargetLocation(Actor self, CPos location, List actorsAtLocation, TargetModifiers modifiers, ref string cursor) - { - return false; + return self == target.Actor; } public bool IsQueued { get; protected set; } diff --git a/OpenRA.Mods.RA/Orders/EnterBuildingOrderTargeter.cs b/OpenRA.Mods.RA/Orders/EnterBuildingOrderTargeter.cs index e679830493..26f151a64c 100755 --- a/OpenRA.Mods.RA/Orders/EnterBuildingOrderTargeter.cs +++ b/OpenRA.Mods.RA/Orders/EnterBuildingOrderTargeter.cs @@ -9,6 +9,7 @@ #endregion using System; +using System.Collections.Generic; using OpenRA.Traits; namespace OpenRA.Mods.RA.Orders @@ -28,9 +29,6 @@ namespace OpenRA.Mods.RA.Orders public override bool CanTargetActor(Actor self, Actor target, TargetModifiers modifiers, ref string cursor) { - if (!base.CanTargetActor(self, target, modifiers, ref cursor)) - return false; - if (!target.HasTrait()) return false; diff --git a/OpenRA.Mods.RA/Orders/UnitOrderTargeter.cs b/OpenRA.Mods.RA/Orders/UnitOrderTargeter.cs index 2f19c71a2b..52e51121a6 100755 --- a/OpenRA.Mods.RA/Orders/UnitOrderTargeter.cs +++ b/OpenRA.Mods.RA/Orders/UnitOrderTargeter.cs @@ -15,7 +15,7 @@ using OpenRA.Traits; namespace OpenRA.Mods.RA.Orders { - public class UnitOrderTargeter : IOrderTargeter + public abstract class UnitOrderTargeter : IOrderTargeter { readonly string cursor; readonly bool targetEnemyUnits, targetAllyUnits; @@ -33,27 +33,24 @@ namespace OpenRA.Mods.RA.Orders public int OrderPriority { get; private set; } public bool? ForceAttack = null; - public virtual bool CanTargetActor(Actor self, Actor target, TargetModifiers modifiers, ref string cursor) + public abstract bool CanTargetActor(Actor self, Actor target, TargetModifiers modifiers, ref string cursor); + + public bool CanTarget(Actor self, Target target, List othersAtTarget, TargetModifiers modifiers, ref string cursor) { - if( self == null ) throw new ArgumentNullException( "self" ); - if( target == null ) throw new ArgumentNullException( "target" ); + if (target.Type != TargetType.Actor) + return false; cursor = this.cursor; IsQueued = modifiers.HasModifier(TargetModifiers.ForceQueue); if (ForceAttack != null && modifiers.HasModifier(TargetModifiers.ForceAttack) != ForceAttack) return false; - var playerRelationship = self.Owner.Stances[target.Owner]; + var playerRelationship = self.Owner.Stances[target.Actor.Owner]; 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 actorsAtLocation, TargetModifiers modifiers, ref string cursor) - { - return false; + return CanTargetActor(self, target.Actor, modifiers, ref cursor); } public virtual bool IsQueued { get; protected set; } @@ -71,9 +68,6 @@ namespace OpenRA.Mods.RA.Orders public override bool CanTargetActor(Actor self, Actor target, TargetModifiers modifiers, ref string cursor) { - if (!base.CanTargetActor(self, target, modifiers, ref cursor)) - return false; - if (!target.TraitsImplementing().Any(t => t.TargetTypes.Contains(targetType))) return false; diff --git a/OpenRA.Mods.RA/RallyPoint.cs b/OpenRA.Mods.RA/RallyPoint.cs index 1db32f3e2b..6d29981e99 100755 --- a/OpenRA.Mods.RA/RallyPoint.cs +++ b/OpenRA.Mods.RA/RallyPoint.cs @@ -58,13 +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, TargetModifiers modifiers, ref string cursor) + public bool CanTarget(Actor self, Target target, List othersAtTarget, TargetModifiers modifiers, ref string cursor) { - return false; - } + if (target.Type != TargetType.Terrain) + return false; - public bool CanTargetLocation(Actor self, CPos location, List actorsAtLocation, TargetModifiers modifiers, ref string cursor) - { + var location = target.CenterPosition.ToCPos(); if (self.World.Map.IsInMap(location)) { cursor = "ability"; diff --git a/OpenRA.Mods.RA/RepairsBridges.cs b/OpenRA.Mods.RA/RepairsBridges.cs index 2e8ab2cf14..27024629b7 100644 --- a/OpenRA.Mods.RA/RepairsBridges.cs +++ b/OpenRA.Mods.RA/RepairsBridges.cs @@ -71,9 +71,6 @@ namespace OpenRA.Mods.RA public override bool CanTargetActor(Actor self, Actor target, TargetModifiers modifiers, ref string cursor) { - if (!base.CanTargetActor(self, target, modifiers, ref cursor)) - return false; - var bridge = target.TraitOrDefault(); if (bridge == null) return false; diff --git a/OpenRA.Mods.RA/SupplyTruck.cs b/OpenRA.Mods.RA/SupplyTruck.cs index b7b779caef..7e591a3795 100644 --- a/OpenRA.Mods.RA/SupplyTruck.cs +++ b/OpenRA.Mods.RA/SupplyTruck.cs @@ -72,9 +72,6 @@ namespace OpenRA.Mods.RA public override bool CanTargetActor(Actor self, Actor target, TargetModifiers modifiers, ref string cursor) { - if (!base.CanTargetActor(self, target, modifiers, ref cursor)) - return false; - if (target.AppearsHostileTo(self)) return false;