diff --git a/OpenRA.Game/Orders/UnitOrderGenerator.cs b/OpenRA.Game/Orders/UnitOrderGenerator.cs index 26f1a79ece..d322129ffe 100644 --- a/OpenRA.Game/Orders/UnitOrderGenerator.cs +++ b/OpenRA.Game/Orders/UnitOrderGenerator.cs @@ -24,8 +24,20 @@ namespace OpenRA.Orders .OrderByDescending(a => a.Info.SelectionPriority()) .FirstOrDefault(); + Target target; + if (underCursor != null) + target = Target.FromActor(underCursor); + else + { + var frozen = world.FindFrozenActorsAtMouse(mi.Location) + .Where(a => a.Info.Traits.Contains()) + .OrderByDescending(a => a.Info.SelectionPriority()) + .FirstOrDefault(); + target = frozen != null ? Target.FromFrozenActor(frozen) : Target.FromCell(xy); + } + var orders = world.Selection.Actors - .Select(a => OrderForUnit(a, xy, mi, underCursor)) + .Select(a => OrderForUnit(a, target, mi)) .Where(o => o != null) .ToArray(); @@ -61,8 +73,20 @@ namespace OpenRA.Orders useSelect = true; } + Target target; + if (underCursor != null) + target = Target.FromActor(underCursor); + else + { + var frozen = world.FindFrozenActorsAtMouse(mi.Location) + .Where(a => a.Info.Traits.Contains()) + .OrderByDescending(a => a.Info.SelectionPriority()) + .FirstOrDefault(); + target = frozen != null ? Target.FromFrozenActor(frozen) : Target.FromCell(xy); + } + var orders = world.Selection.Actors - .Select(a => OrderForUnit(a, xy, mi, underCursor)) + .Select(a => OrderForUnit(a, target, mi)) .Where(o => o != null) .ToArray(); @@ -70,12 +94,12 @@ namespace OpenRA.Orders return cursorName ?? (useSelect ? "select" : "default"); } - static UnitOrderResult OrderForUnit(Actor self, CPos xy, MouseInput mi, Actor underCursor) + static UnitOrderResult OrderForUnit(Actor self, Target target, MouseInput mi) { if (self.Owner != self.World.LocalPlayer) return null; - if (self.Destroyed) + if (self.Destroyed || target.Type == TargetType.Invalid) return null; if (mi.Button == Game.mouseButtonPreference.Action) @@ -85,7 +109,7 @@ namespace OpenRA.Orders .Select(x => new { Trait = trait, Order = x } )) .OrderByDescending(x => x.Order.OrderPriority)) { - var actorsAt = self.World.ActorMap.GetUnitsAt(xy).ToList(); + var actorsAt = self.World.ActorMap.GetUnitsAt(target.CenterPosition.ToCPos()).ToList(); var modifiers = TargetModifiers.None; if (mi.Modifiers.HasModifier(Modifiers.Ctrl)) @@ -96,7 +120,6 @@ namespace OpenRA.Orders modifiers |= TargetModifiers.ForceMove; string cursor = null; - 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.Mods.RA/Captures.cs b/OpenRA.Mods.RA/Captures.cs index cc8242fd68..6d7117bc33 100644 --- a/OpenRA.Mods.RA/Captures.cs +++ b/OpenRA.Mods.RA/Captures.cs @@ -98,13 +98,12 @@ namespace OpenRA.Mods.RA { var canTargetActor = useCaptureCursor(target); cursor = canTargetActor ? "ability" : "move-blocked"; + return canTargetActor; + } - if (canTargetActor) - { - IsQueued = modifiers.HasModifier(TargetModifiers.ForceQueue); - return true; - } - + public override bool CanTargetFrozenActor(Actor self, FrozenActor target, TargetModifiers modifiers, ref string cursor) + { + // TODO: Not yet supported return false; } } diff --git a/OpenRA.Mods.RA/EngineerRepair.cs b/OpenRA.Mods.RA/EngineerRepair.cs index 9d2c6671b3..ab77693cb1 100644 --- a/OpenRA.Mods.RA/EngineerRepair.cs +++ b/OpenRA.Mods.RA/EngineerRepair.cs @@ -65,13 +65,17 @@ namespace OpenRA.Mods.RA if (self.Owner.Stances[target.Owner] != Stance.Ally) return false; - IsQueued = modifiers.HasModifier(TargetModifiers.ForceQueue); - if (target.GetDamageState() == DamageState.Undamaged) cursor = "goldwrench-blocked"; return true; } + + public override bool CanTargetFrozenActor(Actor self, FrozenActor target, TargetModifiers modifiers, ref string cursor) + { + // TODO: Not yet supported + return false; + } } } diff --git a/OpenRA.Mods.RA/Infiltrates.cs b/OpenRA.Mods.RA/Infiltrates.cs index d7ae411874..d315cccd9c 100644 --- a/OpenRA.Mods.RA/Infiltrates.cs +++ b/OpenRA.Mods.RA/Infiltrates.cs @@ -103,6 +103,12 @@ namespace OpenRA.Mods.RA return true; } + + public override bool CanTargetFrozenActor(Actor self, FrozenActor target, TargetModifiers modifiers, ref string cursor) + { + // TODO: Not yet supported + return false; + } } } } diff --git a/OpenRA.Mods.RA/LegacyCaptures.cs b/OpenRA.Mods.RA/LegacyCaptures.cs index 5c393fa796..e07b75afeb 100644 --- a/OpenRA.Mods.RA/LegacyCaptures.cs +++ b/OpenRA.Mods.RA/LegacyCaptures.cs @@ -104,13 +104,18 @@ namespace OpenRA.Mods.RA cursor = lowEnoughHealth ? "enter" : "capture"; - IsQueued = modifiers.HasModifier(TargetModifiers.ForceQueue); return true; } cursor = "enter-blocked"; return false; } + + public override bool CanTargetFrozenActor(Actor self, FrozenActor target, TargetModifiers modifiers, ref string cursor) + { + // TODO: Not yet supported + return false; + } } } } diff --git a/OpenRA.Mods.RA/Orders/EnterBuildingOrderTargeter.cs b/OpenRA.Mods.RA/Orders/EnterBuildingOrderTargeter.cs index 26f151a64c..f8792a1871 100755 --- a/OpenRA.Mods.RA/Orders/EnterBuildingOrderTargeter.cs +++ b/OpenRA.Mods.RA/Orders/EnterBuildingOrderTargeter.cs @@ -29,15 +29,17 @@ namespace OpenRA.Mods.RA.Orders public override bool CanTargetActor(Actor self, Actor target, TargetModifiers modifiers, ref string cursor) { - if (!target.HasTrait()) - return false; - - if (!canTarget(target)) + if (!target.HasTrait() || !canTarget(target)) return false; cursor = useEnterCursor(target) ? "enter" : "enter-blocked"; - IsQueued = modifiers.HasModifier(TargetModifiers.ForceQueue); return true; } + + public override bool CanTargetFrozenActor(Actor self, FrozenActor target, TargetModifiers modifiers, ref string cursor) + { + // TODO: Not yet supported + return false; + } } } diff --git a/OpenRA.Mods.RA/Orders/UnitOrderTargeter.cs b/OpenRA.Mods.RA/Orders/UnitOrderTargeter.cs index 52e51121a6..3ed8ae752e 100755 --- a/OpenRA.Mods.RA/Orders/UnitOrderTargeter.cs +++ b/OpenRA.Mods.RA/Orders/UnitOrderTargeter.cs @@ -20,7 +20,7 @@ namespace OpenRA.Mods.RA.Orders readonly string cursor; readonly bool targetEnemyUnits, targetAllyUnits; - public UnitOrderTargeter( string order, int priority, string cursor, bool targetEnemyUnits, bool targetAllyUnits ) + public UnitOrderTargeter(string order, int priority, string cursor, bool targetEnemyUnits, bool targetAllyUnits) { this.OrderID = order; this.OrderPriority = priority; @@ -34,23 +34,32 @@ namespace OpenRA.Mods.RA.Orders public bool? ForceAttack = null; public abstract bool CanTargetActor(Actor self, Actor target, TargetModifiers modifiers, ref string cursor); + public abstract bool CanTargetFrozenActor(Actor self, FrozenActor 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) + var type = target.Type; + if (type != TargetType.Actor && type != TargetType.FrozenActor) return false; cursor = this.cursor; IsQueued = modifiers.HasModifier(TargetModifiers.ForceQueue); - if (ForceAttack != null && modifiers.HasModifier(TargetModifiers.ForceAttack) != ForceAttack) return false; + if (ForceAttack != null && modifiers.HasModifier(TargetModifiers.ForceAttack) != ForceAttack) + return false; - var playerRelationship = self.Owner.Stances[target.Actor.Owner]; + var owner = type == TargetType.FrozenActor ? target.FrozenActor.Owner : target.Actor.Owner; + var playerRelationship = self.Owner.Stances[owner]; - if (!modifiers.HasModifier(TargetModifiers.ForceAttack) && playerRelationship == Stance.Ally && !targetAllyUnits) return false; - if (!modifiers.HasModifier(TargetModifiers.ForceAttack) && playerRelationship == Stance.Enemy && !targetEnemyUnits) return false; + if (!modifiers.HasModifier(TargetModifiers.ForceAttack) && playerRelationship == Stance.Ally && !targetAllyUnits) + return false; - return CanTargetActor(self, target.Actor, modifiers, ref cursor); + if (!modifiers.HasModifier(TargetModifiers.ForceAttack) && playerRelationship == Stance.Enemy && !targetEnemyUnits) + return false; + + return type == TargetType.FrozenActor ? + CanTargetFrozenActor(self, target.FrozenActor, modifiers, ref cursor) : + CanTargetActor(self, target.Actor, modifiers, ref cursor); } public virtual bool IsQueued { get; protected set; } @@ -68,12 +77,12 @@ namespace OpenRA.Mods.RA.Orders public override bool CanTargetActor(Actor self, Actor target, TargetModifiers modifiers, ref string cursor) { - if (!target.TraitsImplementing().Any(t => t.TargetTypes.Contains(targetType))) - return false; + return target.TraitsImplementing().Any(t => t.TargetTypes.Contains(targetType)); + } - IsQueued = modifiers.HasModifier(TargetModifiers.ForceQueue); - - return true; + public override bool CanTargetFrozenActor(Actor self, FrozenActor target, TargetModifiers modifiers, ref string cursor) + { + return target.Info.Traits.WithInterface().Any(t => t.GetTargetTypes().Contains(targetType)); } } } diff --git a/OpenRA.Mods.RA/RepairsBridges.cs b/OpenRA.Mods.RA/RepairsBridges.cs index 27024629b7..b95ba0f8ad 100644 --- a/OpenRA.Mods.RA/RepairsBridges.cs +++ b/OpenRA.Mods.RA/RepairsBridges.cs @@ -80,14 +80,18 @@ namespace OpenRA.Mods.RA if (!modifiers.HasModifier(TargetModifiers.ForceAttack) && damage != DamageState.Dead) return false; - IsQueued = modifiers.HasModifier(TargetModifiers.ForceQueue); - // Can't repair an undamaged bridge if (damage == DamageState.Undamaged) cursor = "goldwrench-blocked"; return true; } + + public override bool CanTargetFrozenActor(Actor self, FrozenActor target, TargetModifiers modifiers, ref string cursor) + { + // TODO: Bridges don't yet support FrozenUnderFog. + return false; + } } } } diff --git a/OpenRA.Mods.RA/SupplyTruck.cs b/OpenRA.Mods.RA/SupplyTruck.cs index 7e591a3795..a35c98d448 100644 --- a/OpenRA.Mods.RA/SupplyTruck.cs +++ b/OpenRA.Mods.RA/SupplyTruck.cs @@ -72,14 +72,13 @@ namespace OpenRA.Mods.RA public override bool CanTargetActor(Actor self, Actor target, TargetModifiers modifiers, ref string cursor) { - if (target.AppearsHostileTo(self)) - return false; + return target.HasTrait(); + } - if (!target.HasTrait()) - return false; - - IsQueued = modifiers.HasModifier(TargetModifiers.ForceQueue); - return true; + public override bool CanTargetFrozenActor(Actor self, FrozenActor target, TargetModifiers modifiers, ref string cursor) + { + // TODO: Not yet supported + return false; } } }