diff --git a/OpenRA.Game/Activities/Activity.cs b/OpenRA.Game/Activities/Activity.cs index ac70e573f8..1e6245267c 100644 --- a/OpenRA.Game/Activities/Activity.cs +++ b/OpenRA.Game/Activities/Activity.cs @@ -12,12 +12,27 @@ using System; using System.Collections.Generic; using System.Linq; +using OpenRA.Primitives; using OpenRA.Traits; namespace OpenRA.Activities { public enum ActivityState { Queued, Active, Canceling, Done } + public class TargetLineNode + { + public readonly Target Target; + public readonly Color Color; + + public TargetLineNode(Target target, Color color) + { + // Note: Not all activities are drawable. In that case, pass Target.Invalid as target, + // if "yield break" in TargetLineNode(Actor self) is not feasible. + Target = target; + Color = color; + } + } + /* * Things to be aware of when writing activities: * @@ -204,6 +219,11 @@ namespace OpenRA.Activities yield break; } + public virtual IEnumerable TargetLineNodes(Actor self) + { + yield break; + } + public IEnumerable DebugLabelComponents() { var act = this; diff --git a/OpenRA.Game/Graphics/TargetLineRenderable.cs b/OpenRA.Game/Graphics/TargetLineRenderable.cs index de34310663..5e8b6032bd 100644 --- a/OpenRA.Game/Graphics/TargetLineRenderable.cs +++ b/OpenRA.Game/Graphics/TargetLineRenderable.cs @@ -19,11 +19,15 @@ namespace OpenRA.Graphics { readonly IEnumerable waypoints; readonly Color color; + readonly int width; + readonly int markerSize; - public TargetLineRenderable(IEnumerable waypoints, Color color) + public TargetLineRenderable(IEnumerable waypoints, Color color, int width = 1, int markerSize = 1) { this.waypoints = waypoints; this.color = color; + this.width = width; + this.markerSize = markerSize; } public WPos Pos { get { return waypoints.First(); } } @@ -42,23 +46,23 @@ namespace OpenRA.Graphics if (!waypoints.Any()) return; - var iz = 1 / wr.Viewport.Zoom; + var sw = width / wr.Viewport.Zoom; var first = wr.Screen3DPosition(waypoints.First()); var a = first; foreach (var b in waypoints.Skip(1).Select(pos => wr.Screen3DPosition(pos))) { - Game.Renderer.WorldRgbaColorRenderer.DrawLine(a, b, iz, color); - DrawTargetMarker(wr, color, b); + Game.Renderer.WorldRgbaColorRenderer.DrawLine(a, b, sw, color); + DrawTargetMarker(wr, color, b, markerSize); a = b; } DrawTargetMarker(wr, color, first); } - public static void DrawTargetMarker(WorldRenderer wr, Color color, float3 location) + public static void DrawTargetMarker(WorldRenderer wr, Color color, float3 location, int size = 1) { - var iz = 1 / wr.Viewport.Zoom; - var offset = new float2(iz, iz); + var sw = size / wr.Viewport.Zoom; + var offset = new float2(sw, sw); var tl = location - offset; var br = location + offset; Game.Renderer.WorldRgbaColorRenderer.FillRect(tl, br, color); diff --git a/OpenRA.Mods.Cnc/Activities/LeapAttack.cs b/OpenRA.Mods.Cnc/Activities/LeapAttack.cs index a0d1de1f92..cbe2c0c3d6 100644 --- a/OpenRA.Mods.Cnc/Activities/LeapAttack.cs +++ b/OpenRA.Mods.Cnc/Activities/LeapAttack.cs @@ -9,6 +9,7 @@ */ #endregion +using System.Collections.Generic; using System.Linq; using OpenRA.Activities; using OpenRA.Mods.Cnc.Traits; @@ -27,6 +28,7 @@ namespace OpenRA.Mods.Cnc.Activities readonly Mobile mobile; readonly bool allowMovement; readonly bool forceAttack; + readonly Color? targetLineColor; Target target; Target lastVisibleTarget; @@ -36,9 +38,10 @@ namespace OpenRA.Mods.Cnc.Activities BitSet lastVisibleTargetTypes; Player lastVisibleOwner; - public LeapAttack(Actor self, Target target, bool allowMovement, bool forceAttack, AttackLeap attack, AttackLeapInfo info) + public LeapAttack(Actor self, Target target, bool allowMovement, bool forceAttack, AttackLeap attack, AttackLeapInfo info, Color? targetLineColor = null) { this.target = target; + this.targetLineColor = targetLineColor; this.info = info; this.attack = attack; this.allowMovement = allowMovement; @@ -88,13 +91,8 @@ namespace OpenRA.Mods.Cnc.Activities lastVisibleTargetTypes = target.Actor.GetEnabledTargetTypes(); } - var oldUseLastVisibleTarget = useLastVisibleTarget; useLastVisibleTarget = targetIsHiddenActor || !target.IsValidFor(self); - // Update target lines if required - if (useLastVisibleTarget != oldUseLastVisibleTarget) - self.SetTargetLine(useLastVisibleTarget ? lastVisibleTarget : target, Color.Red, false); - // Target is hidden or dead, and we don't have a fallback position to move towards if (useLastVisibleTarget && !lastVisibleTarget.IsValidFor(self)) return true; @@ -161,5 +159,11 @@ namespace OpenRA.Mods.Cnc.Activities if (!autoTarget.HasValidTargetPriority(self, lastVisibleOwner, lastVisibleTargetTypes)) target = Target.Invalid; } + + public override IEnumerable TargetLineNodes(Actor self) + { + if (targetLineColor != null) + yield return new TargetLineNode(useLastVisibleTarget ? lastVisibleTarget : target, targetLineColor.Value); + } } } diff --git a/OpenRA.Mods.Cnc/Traits/Attack/AttackLeap.cs b/OpenRA.Mods.Cnc/Traits/Attack/AttackLeap.cs index d253103533..ffa797acae 100644 --- a/OpenRA.Mods.Cnc/Traits/Attack/AttackLeap.cs +++ b/OpenRA.Mods.Cnc/Traits/Attack/AttackLeap.cs @@ -12,6 +12,7 @@ using OpenRA.Activities; using OpenRA.Mods.Cnc.Activities; using OpenRA.Mods.Common.Traits; +using OpenRA.Primitives; using OpenRA.Traits; namespace OpenRA.Mods.Cnc.Traits @@ -71,9 +72,9 @@ namespace OpenRA.Mods.Cnc.Traits leapToken = conditionManager.RevokeCondition(self, leapToken); } - public override Activity GetAttackActivity(Actor self, Target newTarget, bool allowMove, bool forceAttack) + public override Activity GetAttackActivity(Actor self, Target newTarget, bool allowMove, bool forceAttack, Color? targetLineColor) { - return new LeapAttack(self, newTarget, allowMove, forceAttack, this, info); + return new LeapAttack(self, newTarget, allowMove, forceAttack, this, info, targetLineColor); } } } diff --git a/OpenRA.Mods.Cnc/Traits/Attack/AttackTDGunboatTurreted.cs b/OpenRA.Mods.Cnc/Traits/Attack/AttackTDGunboatTurreted.cs index a18d475303..027a0135fa 100644 --- a/OpenRA.Mods.Cnc/Traits/Attack/AttackTDGunboatTurreted.cs +++ b/OpenRA.Mods.Cnc/Traits/Attack/AttackTDGunboatTurreted.cs @@ -9,9 +9,12 @@ */ #endregion +using System; +using System.Collections.Generic; using System.Linq; using OpenRA.Activities; using OpenRA.Mods.Common.Traits; +using OpenRA.Primitives; using OpenRA.Traits; namespace OpenRA.Mods.Cnc.Traits @@ -27,9 +30,9 @@ namespace OpenRA.Mods.Cnc.Traits public AttackTDGunboatTurreted(Actor self, AttackTDGunboatTurretedInfo info) : base(self, info) { } - public override Activity GetAttackActivity(Actor self, Target newTarget, bool allowMove, bool forceAttack) + public override Activity GetAttackActivity(Actor self, Target newTarget, bool allowMove, bool forceAttack, Color? targetLineColor) { - return new AttackTDGunboatTurretedActivity(self, newTarget, allowMove, forceAttack); + return new AttackTDGunboatTurretedActivity(self, newTarget, allowMove, forceAttack, targetLineColor); } class AttackTDGunboatTurretedActivity : Activity @@ -37,13 +40,15 @@ namespace OpenRA.Mods.Cnc.Traits readonly AttackTDGunboatTurreted attack; readonly Target target; readonly bool forceAttack; + readonly Color? targetLineColor; bool hasTicked; - public AttackTDGunboatTurretedActivity(Actor self, Target target, bool allowMove, bool forceAttack) + public AttackTDGunboatTurretedActivity(Actor self, Target target, bool allowMove, bool forceAttack, Color? targetLineColor = null) { attack = self.Trait(); this.target = target; this.forceAttack = forceAttack; + this.targetLineColor = targetLineColor; } public override bool Tick(Actor self) @@ -68,6 +73,12 @@ namespace OpenRA.Mods.Cnc.Traits return false; } + + public override IEnumerable TargetLineNodes(Actor self) + { + if (targetLineColor != null) + yield return new TargetLineNode(target, targetLineColor.Value); + } } } } diff --git a/OpenRA.Mods.Cnc/Traits/Attack/AttackTesla.cs b/OpenRA.Mods.Cnc/Traits/Attack/AttackTesla.cs index 4d345f2c69..31c2cba287 100644 --- a/OpenRA.Mods.Cnc/Traits/Attack/AttackTesla.cs +++ b/OpenRA.Mods.Cnc/Traits/Attack/AttackTesla.cs @@ -9,9 +9,11 @@ */ #endregion +using System.Collections.Generic; using OpenRA.Activities; using OpenRA.Mods.Common.Activities; using OpenRA.Mods.Common.Traits; +using OpenRA.Primitives; using OpenRA.Traits; namespace OpenRA.Mods.Cnc.Traits @@ -76,9 +78,9 @@ namespace OpenRA.Mods.Cnc.Traits void INotifyAttack.PreparingAttack(Actor self, Target target, Armament a, Barrel barrel) { } - public override Activity GetAttackActivity(Actor self, Target newTarget, bool allowMove, bool forceAttack) + public override Activity GetAttackActivity(Actor self, Target newTarget, bool allowMove, bool forceAttack, Color? targetLineColor = null) { - return new ChargeAttack(this, newTarget, forceAttack); + return new ChargeAttack(this, newTarget, forceAttack, targetLineColor); } class ChargeAttack : Activity, IActivityNotifyStanceChanged @@ -86,12 +88,14 @@ namespace OpenRA.Mods.Cnc.Traits readonly AttackTesla attack; readonly Target target; readonly bool forceAttack; + readonly Color? targetLineColor; - public ChargeAttack(AttackTesla attack, Target target, bool forceAttack) + public ChargeAttack(AttackTesla attack, Target target, bool forceAttack, Color? targetLineColor = null) { this.attack = attack; this.target = target; this.forceAttack = forceAttack; + this.targetLineColor = targetLineColor; } public override bool Tick(Actor self) @@ -132,6 +136,12 @@ namespace OpenRA.Mods.Cnc.Traits Cancel(self, true); } } + + public override IEnumerable TargetLineNodes(Actor self) + { + if (targetLineColor != null) + yield return new TargetLineNode(target, targetLineColor.Value); + } } class ChargeFire : Activity diff --git a/OpenRA.Mods.Cnc/Traits/Infiltration/Infiltrates.cs b/OpenRA.Mods.Cnc/Traits/Infiltration/Infiltrates.cs index 2b35ebb45e..36e43f7acb 100644 --- a/OpenRA.Mods.Cnc/Traits/Infiltration/Infiltrates.cs +++ b/OpenRA.Mods.Cnc/Traits/Infiltration/Infiltrates.cs @@ -117,8 +117,8 @@ namespace OpenRA.Mods.Cnc.Traits if (!order.Queued) self.CancelActivity(); - self.SetTargetLine(order.Target, Color.Red); self.QueueActivity(new Infiltrate(self, order.Target, this)); + self.ShowTargetLines(); } } diff --git a/OpenRA.Mods.Cnc/Traits/MadTank.cs b/OpenRA.Mods.Cnc/Traits/MadTank.cs index 32a3ba8664..643ff7869c 100644 --- a/OpenRA.Mods.Cnc/Traits/MadTank.cs +++ b/OpenRA.Mods.Cnc/Traits/MadTank.cs @@ -141,8 +141,8 @@ namespace OpenRA.Mods.Cnc.Traits { if (order.OrderString == "DetonateAttack") { - self.SetTargetLine(order.Target, Color.Red); self.QueueActivity(order.Queued, new DetonationSequence(self, this, order.Target)); + self.ShowTargetLines(); } else if (order.OrderString == "Detonate") self.QueueActivity(order.Queued, new DetonationSequence(self, this)); @@ -248,6 +248,11 @@ namespace OpenRA.Mods.Cnc.Traits }); } + public override IEnumerable TargetLineNodes(Actor self) + { + yield return new TargetLineNode(target, Color.Crimson); + } + void EjectDriver() { var driver = self.World.CreateActor(mad.info.DriverActor.ToLowerInvariant(), new TypeDictionary diff --git a/OpenRA.Mods.Cnc/Traits/Minelayer.cs b/OpenRA.Mods.Cnc/Traits/Minelayer.cs index 755fa99c03..4cba1fdc46 100644 --- a/OpenRA.Mods.Cnc/Traits/Minelayer.cs +++ b/OpenRA.Mods.Cnc/Traits/Minelayer.cs @@ -112,10 +112,9 @@ namespace OpenRA.Mods.Cnc.Traits Minefield = GetMinefieldCells(minefieldStart, cell, info.MinefieldDepth) .Where(p => movement.CanEnterCell(p, null, false)).ToArray(); - if (Minefield.Length == 1 && Minefield[0] != self.Location) - self.SetTargetLine(Target.FromCell(self.World, Minefield[0]), Color.Red); - self.QueueActivity(order.Queued, new LayMines(self, Minefield)); + if (Minefield.Length == 1 && Minefield[0] != self.Location) + self.ShowTargetLines(); } } diff --git a/OpenRA.Mods.Cnc/Traits/PortableChrono.cs b/OpenRA.Mods.Cnc/Traits/PortableChrono.cs index d3a58700c5..d80abae905 100644 --- a/OpenRA.Mods.Cnc/Traits/PortableChrono.cs +++ b/OpenRA.Mods.Cnc/Traits/PortableChrono.cs @@ -114,12 +114,12 @@ namespace OpenRA.Mods.Cnc.Traits self.CancelActivity(); var cell = self.World.Map.CellContaining(order.Target.CenterPosition); - self.SetTargetLine(order.Target, Color.LawnGreen); if (maxDistance != null) - self.QueueActivity(move.MoveWithinRange(order.Target, WDist.FromCells(maxDistance.Value))); + self.QueueActivity(move.MoveWithinRange(order.Target, WDist.FromCells(maxDistance.Value), targetLineColor: Color.LawnGreen)); self.QueueActivity(new Teleport(self, cell, maxDistance, Info.KillCargo, Info.FlashScreen, Info.ChronoshiftSound)); - self.QueueActivity(move.MoveTo(cell, 5)); + self.QueueActivity(move.MoveTo(cell, 5, Color.LawnGreen)); + self.ShowTargetLines(); } } diff --git a/OpenRA.Mods.Cnc/Traits/TDGunboat.cs b/OpenRA.Mods.Cnc/Traits/TDGunboat.cs index cd8677995a..c966b166ba 100644 --- a/OpenRA.Mods.Cnc/Traits/TDGunboat.cs +++ b/OpenRA.Mods.Cnc/Traits/TDGunboat.cs @@ -183,8 +183,8 @@ namespace OpenRA.Mods.Cnc.Traits self.World.UpdateMaps(self, this); } - public Activity MoveTo(CPos cell, int nearEnough) { return null; } - public Activity MoveTo(CPos cell, Actor ignoreActor) { return null; } + public Activity MoveTo(CPos cell, int nearEnough, Color? targetLineColor = null) { return null; } + public Activity MoveTo(CPos cell, Actor ignoreActor, Color? targetLineColor = null) { return null; } public Activity MoveWithinRange(Target target, WDist range, WPos? initialTargetPosition = null, Color? targetLineColor = null) { return null; } public Activity MoveWithinRange(Target target, WDist minRange, WDist maxRange, diff --git a/OpenRA.Mods.Common/Activities/Air/Fly.cs b/OpenRA.Mods.Common/Activities/Air/Fly.cs index acde3bace1..72dbf861fc 100644 --- a/OpenRA.Mods.Common/Activities/Air/Fly.cs +++ b/OpenRA.Mods.Common/Activities/Air/Fly.cs @@ -139,13 +139,8 @@ namespace OpenRA.Mods.Common.Activities if (!targetIsHiddenActor && target.Type == TargetType.Actor) lastVisibleTarget = Target.FromTargetPositions(target); - var oldUseLastVisibleTarget = useLastVisibleTarget; useLastVisibleTarget = targetIsHiddenActor || !target.IsValidFor(self); - // Update target lines if required - if (useLastVisibleTarget != oldUseLastVisibleTarget && targetLineColor.HasValue) - self.SetTargetLine(useLastVisibleTarget ? lastVisibleTarget : target, targetLineColor.Value, false); - // Target is hidden or dead, and we don't have a fallback position to move towards if (useLastVisibleTarget && !lastVisibleTarget.IsValidFor(self)) return true; @@ -228,6 +223,12 @@ namespace OpenRA.Mods.Common.Activities yield return target; } + public override IEnumerable TargetLineNodes(Actor self) + { + if (targetLineColor.HasValue) + yield return new TargetLineNode(useLastVisibleTarget ? lastVisibleTarget : target, targetLineColor.Value); + } + public static int CalculateTurnRadius(int speed, int turnSpeed) { // turnSpeed -> divide into 256 to get the number of ticks per complete rotation diff --git a/OpenRA.Mods.Common/Activities/Air/FlyAttack.cs b/OpenRA.Mods.Common/Activities/Air/FlyAttack.cs index a552d68a9d..ab5767b190 100644 --- a/OpenRA.Mods.Common/Activities/Air/FlyAttack.cs +++ b/OpenRA.Mods.Common/Activities/Air/FlyAttack.cs @@ -9,6 +9,7 @@ */ #endregion +using System.Collections.Generic; using System.Linq; using OpenRA.Activities; using OpenRA.Mods.Common.Traits; @@ -24,6 +25,7 @@ namespace OpenRA.Mods.Common.Activities readonly Rearmable rearmable; readonly bool forceAttack; readonly int ticksUntilTurn; + readonly Color? targetLineColor; Target target; Target lastVisibleTarget; @@ -32,11 +34,14 @@ namespace OpenRA.Mods.Common.Activities Player lastVisibleOwner; bool useLastVisibleTarget; bool hasTicked; + bool returnToBase; - public FlyAttack(Actor self, Target target, bool forceAttack) + public FlyAttack(Actor self, Target target, bool forceAttack, Color? targetLineColor) { this.target = target; this.forceAttack = forceAttack; + this.targetLineColor = targetLineColor; + aircraft = self.Trait(); attackAircraft = self.Trait(); rearmable = self.TraitOrDefault(); @@ -45,7 +50,7 @@ namespace OpenRA.Mods.Common.Activities // The target may become hidden between the initial order request and the first tick (e.g. if queued) // Moving to any position (even if quite stale) is still better than immediately giving up if ((target.Type == TargetType.Actor && target.Actor.CanBeViewedByPlayer(self.Owner)) - || target.Type == TargetType.FrozenActor || target.Type == TargetType.Terrain) + || target.Type == TargetType.FrozenActor || target.Type == TargetType.Terrain) { lastVisibleTarget = Target.FromPos(target.CenterPosition); lastVisibleMaximumRange = attackAircraft.GetMaximumRangeVersusTarget(target); @@ -65,6 +70,8 @@ namespace OpenRA.Mods.Common.Activities public override bool Tick(Actor self) { + returnToBase = false; + // Refuse to take off if it would land immediately again. if (aircraft.ForceLanding) Cancel(self); @@ -93,13 +100,8 @@ namespace OpenRA.Mods.Common.Activities lastVisibleTargetTypes = target.Actor.GetEnabledTargetTypes(); } - var oldUseLastVisibleTarget = useLastVisibleTarget; useLastVisibleTarget = targetIsHiddenActor || !target.IsValidFor(self); - // Update target lines if required - if (useLastVisibleTarget != oldUseLastVisibleTarget) - self.SetTargetLine(useLastVisibleTarget ? lastVisibleTarget : target, Color.Red, false); - // Target is hidden or dead, and we don't have a fallback position to move towards if (useLastVisibleTarget && !lastVisibleTarget.IsValidFor(self)) return true; @@ -109,6 +111,7 @@ namespace OpenRA.Mods.Common.Activities if (rearmable != null && !useLastVisibleTarget && attackAircraft.Armaments.All(x => x.IsTraitPaused || !x.Weapon.IsValidAgainst(target, self.World, self))) { QueueChild(new ReturnToBase(self)); + returnToBase = true; return attackAircraft.Info.AbortOnResupply; } @@ -169,5 +172,17 @@ namespace OpenRA.Mods.Common.Activities if (!autoTarget.HasValidTargetPriority(self, lastVisibleOwner, lastVisibleTargetTypes)) attackAircraft.ClearRequestedTarget(); } + + public override IEnumerable TargetLineNodes(Actor self) + { + if (targetLineColor != null) + { + if (returnToBase) + foreach (var n in ChildActivity.TargetLineNodes(self)) + yield return n; + if (!returnToBase || !attackAircraft.Info.AbortOnResupply) + yield return new TargetLineNode(useLastVisibleTarget ? lastVisibleTarget : target, targetLineColor.Value); + } + } } } diff --git a/OpenRA.Mods.Common/Activities/Air/FlyFollow.cs b/OpenRA.Mods.Common/Activities/Air/FlyFollow.cs index 2f6deb692b..7e0cbf4e4b 100644 --- a/OpenRA.Mods.Common/Activities/Air/FlyFollow.cs +++ b/OpenRA.Mods.Common/Activities/Air/FlyFollow.cs @@ -9,6 +9,7 @@ */ #endregion +using System.Collections.Generic; using OpenRA.Activities; using OpenRA.Mods.Common.Traits; using OpenRA.Primitives; @@ -59,7 +60,6 @@ namespace OpenRA.Mods.Common.Activities if (!targetIsHiddenActor && target.Type == TargetType.Actor) lastVisibleTarget = Target.FromTargetPositions(target); - var oldUseLastVisibleTarget = useLastVisibleTarget; useLastVisibleTarget = targetIsHiddenActor || !target.IsValidFor(self); // If we are ticking again after previously sequencing a MoveWithRange then that move must have completed @@ -69,10 +69,6 @@ namespace OpenRA.Mods.Common.Activities wasMovingWithinRange = false; - // Update target lines if required - if (useLastVisibleTarget != oldUseLastVisibleTarget && targetLineColor.HasValue) - self.SetTargetLine(useLastVisibleTarget ? lastVisibleTarget : target, targetLineColor.Value, false); - // Target is hidden or dead, and we don't have a fallback position to move towards if (useLastVisibleTarget && !lastVisibleTarget.IsValidFor(self)) return true; @@ -94,5 +90,11 @@ namespace OpenRA.Mods.Common.Activities QueueChild(aircraft.MoveWithinRange(target, minRange, maxRange, checkTarget.CenterPosition, targetLineColor)); return false; } + + public override IEnumerable TargetLineNodes(Actor self) + { + if (targetLineColor != null) + yield return new TargetLineNode(useLastVisibleTarget ? lastVisibleTarget : target, targetLineColor.Value); + } } } diff --git a/OpenRA.Mods.Common/Activities/Air/Land.cs b/OpenRA.Mods.Common/Activities/Air/Land.cs index 7c544f9224..ec382b5956 100644 --- a/OpenRA.Mods.Common/Activities/Air/Land.cs +++ b/OpenRA.Mods.Common/Activities/Air/Land.cs @@ -13,6 +13,7 @@ using System; using System.Collections.Generic; using OpenRA.Activities; using OpenRA.Mods.Common.Traits; +using OpenRA.Primitives; using OpenRA.Traits; namespace OpenRA.Mods.Common.Activities @@ -25,6 +26,7 @@ namespace OpenRA.Mods.Common.Activities readonly bool assignTargetOnFirstRun; readonly CPos[] clearCells; readonly WDist landRange; + readonly Color? targetLineColor; Target target; WPos targetPosition; @@ -32,28 +34,29 @@ namespace OpenRA.Mods.Common.Activities bool landingInitiated; bool finishedApproach; - public Land(Actor self, int facing = -1) + public Land(Actor self, int facing = -1, Color? targetLineColor = null) : this(self, Target.Invalid, new WDist(-1), WVec.Zero, facing, null) { assignTargetOnFirstRun = true; } - public Land(Actor self, Target target, int facing = -1) - : this(self, target, new WDist(-1), WVec.Zero, facing) { } + public Land(Actor self, Target target, int facing = -1, Color? targetLineColor = null) + : this(self, target, new WDist(-1), WVec.Zero, facing, targetLineColor: targetLineColor) { } - public Land(Actor self, Target target, WDist landRange, int facing = -1) - : this(self, target, landRange, WVec.Zero, facing) { } + public Land(Actor self, Target target, WDist landRange, int facing = -1, Color? targetLineColor = null) + : this(self, target, landRange, WVec.Zero, facing, targetLineColor: targetLineColor) { } - public Land(Actor self, Target target, WVec offset, int facing = -1) - : this(self, target, WDist.Zero, offset, facing) { } + public Land(Actor self, Target target, WVec offset, int facing = -1, Color? targetLineColor = null) + : this(self, target, WDist.Zero, offset, facing, targetLineColor: targetLineColor) { } - public Land(Actor self, Target target, WDist landRange, WVec offset, int facing = -1, CPos[] clearCells = null) + public Land(Actor self, Target target, WDist landRange, WVec offset, int facing = -1, CPos[] clearCells = null, Color? targetLineColor = null) { aircraft = self.Trait(); this.target = target; this.offset = offset; this.clearCells = clearCells ?? new CPos[0]; this.landRange = landRange.Length >= 0 ? landRange : aircraft.Info.LandRange; + this.targetLineColor = targetLineColor; // NOTE: desiredFacing = -1 means we should not prefer any particular facing and instead just // use whatever facing gives us the most direct path to the landing site. @@ -256,5 +259,11 @@ namespace OpenRA.Mods.Common.Activities return false; } + + public override IEnumerable TargetLineNodes(Actor self) + { + if (targetLineColor != null) + yield return new TargetLineNode(target, targetLineColor.Value); + } } } diff --git a/OpenRA.Mods.Common/Activities/Air/ReturnToBase.cs b/OpenRA.Mods.Common/Activities/Air/ReturnToBase.cs index 3388bfe07e..6fd21abdb5 100644 --- a/OpenRA.Mods.Common/Activities/Air/ReturnToBase.cs +++ b/OpenRA.Mods.Common/Activities/Air/ReturnToBase.cs @@ -119,14 +119,22 @@ namespace OpenRA.Mods.Common.Activities facing = 192; aircraft.MakeReservation(dest); - QueueChild(new Land(self, Target.FromActor(dest), offset, facing)); + QueueChild(new Land(self, Target.FromActor(dest), offset, facing, Color.Green)); QueueChild(new Resupply(self, dest, WDist.Zero, alwaysLand)); - return true; } QueueChild(new Fly(self, Target.FromActor(dest))); return true; } + + public override IEnumerable TargetLineNodes(Actor self) + { + if (ChildActivity == null) + yield return new TargetLineNode(Target.FromActor(dest), Color.Green); + else + foreach (var n in ChildActivity.TargetLineNodes(self)) + yield return n; + } } } diff --git a/OpenRA.Mods.Common/Activities/Attack.cs b/OpenRA.Mods.Common/Activities/Attack.cs index 12e37e45b1..1a187cc29b 100644 --- a/OpenRA.Mods.Common/Activities/Attack.cs +++ b/OpenRA.Mods.Common/Activities/Attack.cs @@ -31,6 +31,7 @@ namespace OpenRA.Mods.Common.Activities readonly IFacing facing; readonly IPositionable positionable; readonly bool forceAttack; + readonly Color? targetLineColor; protected Target target; Target lastVisibleTarget; @@ -44,9 +45,10 @@ namespace OpenRA.Mods.Common.Activities WDist maxRange; AttackStatus attackStatus = AttackStatus.UnableToAttack; - public Attack(Actor self, Target target, bool allowMovement, bool forceAttack) + public Attack(Actor self, Target target, bool allowMovement, bool forceAttack, Color? targetLineColor = null) { this.target = target; + this.targetLineColor = targetLineColor; this.forceAttack = forceAttack; attackTraits = self.TraitsImplementing().ToArray(); @@ -100,7 +102,6 @@ namespace OpenRA.Mods.Common.Activities lastVisibleTargetTypes = target.Actor.GetEnabledTargetTypes(); } - var oldUseLastVisibleTarget = useLastVisibleTarget; useLastVisibleTarget = targetIsHiddenActor || !target.IsValidFor(self); // If we are ticking again after previously sequencing a MoveWithRange then that move must have completed @@ -108,10 +109,6 @@ namespace OpenRA.Mods.Common.Activities if (wasMovingWithinRange && targetIsHiddenActor) return true; - // Update target lines if required - if (useLastVisibleTarget != oldUseLastVisibleTarget) - self.SetTargetLine(useLastVisibleTarget ? lastVisibleTarget : target, Color.Red, false); - // Target is hidden or dead, and we don't have a fallback position to move towards if (useLastVisibleTarget && !lastVisibleTarget.IsValidFor(self)) return true; @@ -231,5 +228,11 @@ namespace OpenRA.Mods.Common.Activities if (!autoTarget.HasValidTargetPriority(self, lastVisibleOwner, lastVisibleTargetTypes)) target = Target.Invalid; } + + public override IEnumerable TargetLineNodes(Actor self) + { + if (targetLineColor != null) + yield return new TargetLineNode(useLastVisibleTarget ? lastVisibleTarget : target, targetLineColor.Value); + } } } diff --git a/OpenRA.Mods.Common/Activities/DeliverResources.cs b/OpenRA.Mods.Common/Activities/DeliverResources.cs index c333e29915..ab804d3ab1 100644 --- a/OpenRA.Mods.Common/Activities/DeliverResources.cs +++ b/OpenRA.Mods.Common/Activities/DeliverResources.cs @@ -9,6 +9,7 @@ */ #endregion +using System.Collections.Generic; using System.Linq; using OpenRA.Activities; using OpenRA.Mods.Common.Traits; @@ -24,6 +25,8 @@ namespace OpenRA.Mods.Common.Activities readonly Actor targetActor; readonly INotifyHarvesterAction[] notifyHarvesterActions; + Actor proc; + public DeliverResources(Actor self, Actor targetActor = null) { movement = self.Trait(); @@ -54,10 +57,9 @@ namespace OpenRA.Mods.Common.Activities return false; } - var proc = harv.LinkedProc; + proc = harv.LinkedProc; var iao = proc.Trait(); - self.SetTargetLine(Target.FromActor(proc), Color.Green, false); if (self.Location != proc.Location + iao.DeliveryOffset) { foreach (var n in notifyHarvesterActions) @@ -79,5 +81,13 @@ namespace OpenRA.Mods.Common.Activities base.Cancel(self, keepQueue); } + + public override IEnumerable TargetLineNodes(Actor self) + { + if (proc != null) + yield return new TargetLineNode(Target.FromActor(proc), Color.Green); + else + yield return new TargetLineNode(Target.FromActor(harv.LinkedProc), Color.Green); + } } } diff --git a/OpenRA.Mods.Common/Activities/DeliverUnit.cs b/OpenRA.Mods.Common/Activities/DeliverUnit.cs index cd7678ddd6..dca10beb59 100644 --- a/OpenRA.Mods.Common/Activities/DeliverUnit.cs +++ b/OpenRA.Mods.Common/Activities/DeliverUnit.cs @@ -9,8 +9,10 @@ */ #endregion +using System.Collections.Generic; using OpenRA.Activities; using OpenRA.Mods.Common.Traits; +using OpenRA.Primitives; using OpenRA.Traits; namespace OpenRA.Mods.Common.Activities @@ -56,6 +58,11 @@ namespace OpenRA.Mods.Common.Activities QueueChild(new TakeOff(self)); } + public override IEnumerable TargetLineNodes(Actor self) + { + yield return new TargetLineNode(destination, Color.Yellow); + } + class ReleaseUnit : Activity { readonly Carryall carryall; diff --git a/OpenRA.Mods.Common/Activities/Enter.cs b/OpenRA.Mods.Common/Activities/Enter.cs index 840d1f5aa5..513fb2aed6 100644 --- a/OpenRA.Mods.Common/Activities/Enter.cs +++ b/OpenRA.Mods.Common/Activities/Enter.cs @@ -9,6 +9,7 @@ */ #endregion +using System.Collections.Generic; using OpenRA.Activities; using OpenRA.Mods.Common.Traits; using OpenRA.Primitives; @@ -75,10 +76,6 @@ namespace OpenRA.Mods.Common.Activities TickInner(self, target, useLastVisibleTarget); - // Update target lines if required - if (useLastVisibleTarget != oldUseLastVisibleTarget && targetLineColor.HasValue) - self.SetTargetLine(useLastVisibleTarget ? lastVisibleTarget : target, targetLineColor.Value, false); - // We need to wait for movement to finish before transitioning to // the next state or next activity if (!TickChild(self)) @@ -146,5 +143,11 @@ namespace OpenRA.Mods.Common.Activities return false; } + + public override IEnumerable TargetLineNodes(Actor self) + { + if (targetLineColor != null) + yield return new TargetLineNode(useLastVisibleTarget ? lastVisibleTarget : target, targetLineColor.Value); + } } } diff --git a/OpenRA.Mods.Common/Activities/EnterTransport.cs b/OpenRA.Mods.Common/Activities/EnterTransport.cs index c8a65e42ac..f1036b89f3 100644 --- a/OpenRA.Mods.Common/Activities/EnterTransport.cs +++ b/OpenRA.Mods.Common/Activities/EnterTransport.cs @@ -9,9 +9,6 @@ */ #endregion -using System; -using System.Linq; -using OpenRA.Activities; using OpenRA.Mods.Common.Traits; using OpenRA.Primitives; using OpenRA.Traits; diff --git a/OpenRA.Mods.Common/Activities/FindAndDeliverResources.cs b/OpenRA.Mods.Common/Activities/FindAndDeliverResources.cs index 4c398ad4c8..f2df49160e 100644 --- a/OpenRA.Mods.Common/Activities/FindAndDeliverResources.cs +++ b/OpenRA.Mods.Common/Activities/FindAndDeliverResources.cs @@ -27,8 +27,8 @@ namespace OpenRA.Mods.Common.Activities readonly ResourceClaimLayer claimLayer; readonly IPathFinder pathFinder; readonly DomainIndex domainIndex; - readonly Actor deliverActor; + Actor deliverActor; CPos? orderLocation; CPos? lastHarvestedCell; bool hasDeliveredLoad; @@ -73,6 +73,7 @@ namespace OpenRA.Mods.Common.Activities { QueueChild(new DeliverResources(self, deliverActor)); hasDeliveredLoad = true; + deliverActor = null; } } @@ -139,7 +140,6 @@ namespace OpenRA.Mods.Common.Activities { var unblockCell = deliveryLoc + harv.Info.UnblockCell; var moveTo = mobile.NearestMoveableCell(unblockCell, 1, 5); - self.SetTargetLine(Target.FromCell(self.World, moveTo), Color.Green, false); QueueChild(mobile.MoveTo(moveTo, 1)); } } @@ -205,6 +205,18 @@ namespace OpenRA.Mods.Common.Activities yield return Target.FromCell(self.World, self.Location); } + public override IEnumerable TargetLineNodes(Actor self) + { + if (ChildActivity != null) + foreach (var n in ChildActivity.TargetLineNodes(self)) + yield return n; + + if (orderLocation != null) + yield return new TargetLineNode(Target.FromCell(self.World, orderLocation.Value), Color.Green); + else if (deliverActor != null) + yield return new TargetLineNode(Target.FromActor(deliverActor), Color.Green); + } + CPos GetSearchFromLocation(Actor self) { if (harv.LastLinkedProc != null && !harv.LastLinkedProc.IsDead && harv.LastLinkedProc.IsInWorld) diff --git a/OpenRA.Mods.Common/Activities/HarvestResource.cs b/OpenRA.Mods.Common/Activities/HarvestResource.cs index c0e16f4da4..b7a9fb0eb9 100644 --- a/OpenRA.Mods.Common/Activities/HarvestResource.cs +++ b/OpenRA.Mods.Common/Activities/HarvestResource.cs @@ -9,6 +9,7 @@ */ #endregion +using System.Collections.Generic; using System.Linq; using OpenRA.Activities; using OpenRA.Mods.Common.Traits; @@ -61,7 +62,6 @@ namespace OpenRA.Mods.Common.Activities foreach (var n in notifyHarvesterActions) n.MovingToResources(self, targetCell); - self.SetTargetLine(Target.FromCell(self.World, targetCell), Color.Red, false); QueueChild(move.MoveTo(targetCell, 2)); return false; } @@ -106,5 +106,10 @@ namespace OpenRA.Mods.Common.Activities base.Cancel(self, keepQueue); } + + public override IEnumerable TargetLineNodes(Actor self) + { + yield return new TargetLineNode(Target.FromCell(self.World, targetCell), Color.Green); + } } } diff --git a/OpenRA.Mods.Common/Activities/HarvesterDockSequence.cs b/OpenRA.Mods.Common/Activities/HarvesterDockSequence.cs index 2186c71ff9..3ed3c0859a 100644 --- a/OpenRA.Mods.Common/Activities/HarvesterDockSequence.cs +++ b/OpenRA.Mods.Common/Activities/HarvesterDockSequence.cs @@ -13,6 +13,7 @@ using System; using System.Collections.Generic; using OpenRA.Activities; using OpenRA.Mods.Common.Traits; +using OpenRA.Primitives; using OpenRA.Traits; namespace OpenRA.Mods.Common.Activities @@ -104,6 +105,11 @@ namespace OpenRA.Mods.Common.Activities yield return Target.FromActor(Refinery); } + public override IEnumerable TargetLineNodes(Actor self) + { + yield return new TargetLineNode(Target.FromActor(Refinery), Color.Green); + } + public abstract void OnStateDock(Actor self); public abstract void OnStateUndock(Actor self); diff --git a/OpenRA.Mods.Common/Activities/Move/AttackMoveActivity.cs b/OpenRA.Mods.Common/Activities/Move/AttackMoveActivity.cs index b490e6eef8..c1b28f061a 100644 --- a/OpenRA.Mods.Common/Activities/Move/AttackMoveActivity.cs +++ b/OpenRA.Mods.Common/Activities/Move/AttackMoveActivity.cs @@ -92,5 +92,13 @@ namespace OpenRA.Mods.Common.Activities return Target.None; } + + public override IEnumerable TargetLineNodes(Actor self) + { + foreach (var n in getInner().TargetLineNodes(self)) + yield return n; + + yield break; + } } } diff --git a/OpenRA.Mods.Common/Activities/Move/Drag.cs b/OpenRA.Mods.Common/Activities/Move/Drag.cs index 0db2348cfa..ad3a5cfefe 100644 --- a/OpenRA.Mods.Common/Activities/Move/Drag.cs +++ b/OpenRA.Mods.Common/Activities/Move/Drag.cs @@ -12,6 +12,7 @@ using System.Collections.Generic; using OpenRA.Activities; using OpenRA.Mods.Common.Traits; +using OpenRA.Primitives; using OpenRA.Traits; namespace OpenRA.Mods.Common.Activities @@ -62,5 +63,10 @@ namespace OpenRA.Mods.Common.Activities { yield return Target.FromPos(end); } + + public override IEnumerable TargetLineNodes(Actor self) + { + yield return new TargetLineNode(Target.FromPos(end), Color.Green); + } } } diff --git a/OpenRA.Mods.Common/Activities/Move/Follow.cs b/OpenRA.Mods.Common/Activities/Move/Follow.cs index 53b0e0f328..5c92d0071e 100644 --- a/OpenRA.Mods.Common/Activities/Move/Follow.cs +++ b/OpenRA.Mods.Common/Activities/Move/Follow.cs @@ -9,6 +9,7 @@ */ #endregion +using System.Collections.Generic; using OpenRA.Activities; using OpenRA.Mods.Common.Traits; using OpenRA.Primitives; @@ -55,7 +56,6 @@ namespace OpenRA.Mods.Common.Activities if (!targetIsHiddenActor && target.Type == TargetType.Actor) lastVisibleTarget = Target.FromTargetPositions(target); - var oldUseLastVisibleTarget = useLastVisibleTarget; useLastVisibleTarget = targetIsHiddenActor || !target.IsValidFor(self); // If we are ticking again after previously sequencing a MoveWithRange then that move must have completed @@ -65,10 +65,6 @@ namespace OpenRA.Mods.Common.Activities wasMovingWithinRange = false; - // Update target lines if required - if (useLastVisibleTarget != oldUseLastVisibleTarget && targetLineColor.HasValue) - self.SetTargetLine(useLastVisibleTarget ? lastVisibleTarget : target, targetLineColor.Value, false); - // Target is hidden or dead, and we don't have a fallback position to move towards if (useLastVisibleTarget && !lastVisibleTarget.IsValidFor(self)) return true; @@ -86,5 +82,11 @@ namespace OpenRA.Mods.Common.Activities QueueChild(move.MoveWithinRange(target, minRange, maxRange, checkTarget.CenterPosition, targetLineColor)); return false; } + + public override IEnumerable TargetLineNodes(Actor self) + { + if (targetLineColor != null) + yield return new TargetLineNode(useLastVisibleTarget ? lastVisibleTarget : target, targetLineColor.Value); + } } } diff --git a/OpenRA.Mods.Common/Activities/Move/Move.cs b/OpenRA.Mods.Common/Activities/Move/Move.cs index aa42431cec..89c181b77a 100644 --- a/OpenRA.Mods.Common/Activities/Move/Move.cs +++ b/OpenRA.Mods.Common/Activities/Move/Move.cs @@ -29,6 +29,7 @@ namespace OpenRA.Mods.Common.Activities readonly WDist nearEnough; readonly Func> getPath; readonly Actor ignoreActor; + readonly Color? targetLineColor; List path; CPos? destination; @@ -43,7 +44,7 @@ namespace OpenRA.Mods.Common.Activities // Scriptable move order // Ignores lane bias and nearby units - public Move(Actor self, CPos destination) + public Move(Actor self, CPos destination, Color? targetLineColor = null) { mobile = self.Trait(); @@ -57,10 +58,12 @@ namespace OpenRA.Mods.Common.Activities return path; }; this.destination = destination; + this.targetLineColor = targetLineColor; nearEnough = WDist.Zero; } - public Move(Actor self, CPos destination, WDist nearEnough, Actor ignoreActor = null, bool evaluateNearestMovableCell = false) + public Move(Actor self, CPos destination, WDist nearEnough, Actor ignoreActor = null, bool evaluateNearestMovableCell = false, + Color? targetLineColor = null) { mobile = self.Trait(); @@ -79,9 +82,10 @@ namespace OpenRA.Mods.Common.Activities this.nearEnough = nearEnough; this.ignoreActor = ignoreActor; this.evaluateNearestMovableCell = evaluateNearestMovableCell; + this.targetLineColor = targetLineColor; } - public Move(Actor self, CPos destination, SubCell subCell, WDist nearEnough) + public Move(Actor self, CPos destination, SubCell subCell, WDist nearEnough, Color? targetLineColor = null) { mobile = self.Trait(); @@ -89,9 +93,10 @@ namespace OpenRA.Mods.Common.Activities .FindUnitPathToRange(mobile.FromCell, subCell, self.World.Map.CenterOfSubCell(destination, subCell), nearEnough, self); this.destination = destination; this.nearEnough = nearEnough; + this.targetLineColor = targetLineColor; } - public Move(Actor self, Target target, WDist range) + public Move(Actor self, Target target, WDist range, Color? targetLineColor = null) { mobile = self.Trait(); @@ -106,9 +111,10 @@ namespace OpenRA.Mods.Common.Activities destination = null; nearEnough = range; + this.targetLineColor = targetLineColor; } - public Move(Actor self, Func> getPath) + public Move(Actor self, Func> getPath, Color? targetLineColor = null) { mobile = self.Trait(); @@ -116,6 +122,7 @@ namespace OpenRA.Mods.Common.Activities destination = null; nearEnough = WDist.Zero; + this.targetLineColor = targetLineColor; } static int HashList(List xs) @@ -261,6 +268,12 @@ namespace OpenRA.Mods.Common.Activities return Target.None; } + public override IEnumerable TargetLineNodes(Actor self) + { + if (targetLineColor != null) + yield return new TargetLineNode(Target.FromCell(self.World, destination.Value), targetLineColor.Value); + } + abstract class MovePart : Activity { protected readonly Move Move; diff --git a/OpenRA.Mods.Common/Activities/Move/MoveAdjacentTo.cs b/OpenRA.Mods.Common/Activities/Move/MoveAdjacentTo.cs index 0dbfbaa8c0..4ca12068da 100644 --- a/OpenRA.Mods.Common/Activities/Move/MoveAdjacentTo.cs +++ b/OpenRA.Mods.Common/Activities/Move/MoveAdjacentTo.cs @@ -99,13 +99,8 @@ namespace OpenRA.Mods.Common.Activities // Target is equivalent to checkTarget variable in other activities // value is either lastVisibleTarget or target based on visibility and validity var targetIsValid = Target.IsValidFor(self); - var oldUseLastVisibleTarget = useLastVisibleTarget; useLastVisibleTarget = targetIsHiddenActor || !targetIsValid; - // Update target lines if required - if (useLastVisibleTarget != oldUseLastVisibleTarget && targetLineColor.HasValue) - self.SetTargetLine(useLastVisibleTarget ? lastVisibleTarget : target, targetLineColor.Value, false); - // Target is hidden or dead, and we don't have a fallback position to move towards var noTarget = useLastVisibleTarget && !lastVisibleTarget.IsValidFor(self); @@ -149,5 +144,11 @@ namespace OpenRA.Mods.Common.Activities return Target.None; } + + public override IEnumerable TargetLineNodes(Actor self) + { + if (targetLineColor.HasValue) + yield return new TargetLineNode(useLastVisibleTarget ? lastVisibleTarget : target, targetLineColor.Value); + } } } diff --git a/OpenRA.Mods.Common/Activities/Move/VisualMoveIntoTarget.cs b/OpenRA.Mods.Common/Activities/Move/VisualMoveIntoTarget.cs index d551889f43..c9f994068f 100644 --- a/OpenRA.Mods.Common/Activities/Move/VisualMoveIntoTarget.cs +++ b/OpenRA.Mods.Common/Activities/Move/VisualMoveIntoTarget.cs @@ -12,6 +12,7 @@ using System.Collections.Generic; using OpenRA.Activities; using OpenRA.Mods.Common.Traits; +using OpenRA.Primitives; using OpenRA.Traits; namespace OpenRA.Mods.Common.Activities @@ -20,14 +21,16 @@ namespace OpenRA.Mods.Common.Activities { readonly Mobile mobile; readonly Target target; + readonly Color? targetLineColor; readonly WDist targetMovementThreshold; WPos targetStartPos; - public VisualMoveIntoTarget(Actor self, Target target, WDist targetMovementThreshold) + public VisualMoveIntoTarget(Actor self, Target target, WDist targetMovementThreshold, Color? targetLineColor = null) { mobile = self.Trait(); this.target = target; this.targetMovementThreshold = targetMovementThreshold; + this.targetLineColor = targetLineColor; } protected override void OnFirstRun(Actor self) @@ -76,5 +79,11 @@ namespace OpenRA.Mods.Common.Activities { yield return target; } + + public override IEnumerable TargetLineNodes(Actor self) + { + if (targetLineColor != null) + yield return new TargetLineNode(target, targetLineColor.Value); + } } } diff --git a/OpenRA.Mods.Common/Activities/PickupUnit.cs b/OpenRA.Mods.Common/Activities/PickupUnit.cs index b4873b1d4d..4575efdbe5 100644 --- a/OpenRA.Mods.Common/Activities/PickupUnit.cs +++ b/OpenRA.Mods.Common/Activities/PickupUnit.cs @@ -9,6 +9,7 @@ */ #endregion +using System.Collections.Generic; using OpenRA.Activities; using OpenRA.Mods.Common.Traits; using OpenRA.Primitives; @@ -79,7 +80,7 @@ namespace OpenRA.Mods.Common.Activities switch (state) { case PickupState.Intercept: - QueueChild(movement.MoveWithinRange(Target.FromActor(cargo), WDist.FromCells(4), targetLineColor: Color.Yellow)); + QueueChild(movement.MoveWithinRange(Target.FromActor(cargo), WDist.FromCells(4))); state = PickupState.LockCarryable; return false; @@ -110,6 +111,11 @@ namespace OpenRA.Mods.Common.Activities return true; } + public override IEnumerable TargetLineNodes(Actor self) + { + yield return new TargetLineNode(Target.FromActor(cargo), Color.Yellow); + } + class AttachUnit : Activity { readonly Actor cargo; diff --git a/OpenRA.Mods.Common/Activities/Resupply.cs b/OpenRA.Mods.Common/Activities/Resupply.cs index 7e96e0b8d8..a7aeb7213f 100644 --- a/OpenRA.Mods.Common/Activities/Resupply.cs +++ b/OpenRA.Mods.Common/Activities/Resupply.cs @@ -149,6 +149,15 @@ namespace OpenRA.Mods.Common.Activities base.Cancel(self, keepQueue); } + public override IEnumerable TargetLineNodes(Actor self) + { + if (ChildActivity == null) + yield return new TargetLineNode(host, Color.Green); + else + foreach (var n in ChildActivity.TargetLineNodes(self)) + yield return n; + } + void OnResupplyEnding(Actor self) { if (aircraft != null) diff --git a/OpenRA.Mods.Common/Activities/Transform.cs b/OpenRA.Mods.Common/Activities/Transform.cs index 9fab16684a..2a1a6c42b0 100644 --- a/OpenRA.Mods.Common/Activities/Transform.cs +++ b/OpenRA.Mods.Common/Activities/Transform.cs @@ -9,7 +9,7 @@ */ #endregion -using System; +using System.Collections.Generic; using OpenRA.Activities; using OpenRA.Mods.Common.Traits; using OpenRA.Mods.Common.Traits.Render; @@ -149,16 +149,24 @@ namespace OpenRA.Mods.Common.Activities { readonly string orderString; readonly Target target; + readonly Color? targetLineColor; - public IssueOrderAfterTransform(string orderString, Target target) + public IssueOrderAfterTransform(string orderString, Target target, Color? targetLineColor = null) { this.orderString = orderString; this.target = target; + this.targetLineColor = targetLineColor; } public Order IssueOrderForTransformedActor(Actor newActor) { return new Order(orderString, newActor, target, true); } + + public override IEnumerable TargetLineNodes(Actor self) + { + if (targetLineColor != null) + yield return new TargetLineNode(target, targetLineColor.Value); + } } } diff --git a/OpenRA.Mods.Common/Activities/UnloadCargo.cs b/OpenRA.Mods.Common/Activities/UnloadCargo.cs index dccdbca23d..cce65675ad 100644 --- a/OpenRA.Mods.Common/Activities/UnloadCargo.cs +++ b/OpenRA.Mods.Common/Activities/UnloadCargo.cs @@ -122,7 +122,6 @@ namespace OpenRA.Mods.Common.Activities actor.CancelActivity(); pos.SetVisualPosition(actor, spawn); actor.QueueActivity(move.MoveIntoWorld(actor, exitSubCell.Value.First, exitSubCell.Value.Second)); - actor.SetTargetLine(Target.FromCell(w, exitSubCell.Value.First, exitSubCell.Value.Second), Color.Green, false); w.Add(actor); }); } diff --git a/OpenRA.Mods.Common/Effects/RallyPointIndicator.cs b/OpenRA.Mods.Common/Effects/RallyPointIndicator.cs index b4c5e7400f..9556f92419 100644 --- a/OpenRA.Mods.Common/Effects/RallyPointIndicator.cs +++ b/OpenRA.Mods.Common/Effects/RallyPointIndicator.cs @@ -98,7 +98,7 @@ namespace OpenRA.Mods.Common.Effects IEnumerable RenderInner(WorldRenderer wr) { if (Game.Settings.Game.DrawTargetLine) - yield return new TargetLineRenderable(targetLine, building.Owner.Color); + yield return new TargetLineRenderable(targetLine, building.Owner.Color, rp.Info.LineWidth); if (circles != null || flag != null) { diff --git a/OpenRA.Mods.Common/Scripting/Properties/DeliveryProperties.cs b/OpenRA.Mods.Common/Scripting/Properties/DeliveryProperties.cs index 827c2e2b4b..bc4579054e 100644 --- a/OpenRA.Mods.Common/Scripting/Properties/DeliveryProperties.cs +++ b/OpenRA.Mods.Common/Scripting/Properties/DeliveryProperties.cs @@ -34,8 +34,8 @@ namespace OpenRA.Mods.Common.Scripting public void DeliverCash(Actor target) { var t = Target.FromActor(target); - Self.SetTargetLine(t, Color.Yellow); Self.QueueActivity(new DonateCash(Self, t, info.Payload, info.PlayerExperience)); + Self.ShowTargetLines(); } } @@ -66,8 +66,8 @@ namespace OpenRA.Mods.Common.Scripting var level = gainsExperience.Level; var t = Target.FromActor(target); - Self.SetTargetLine(t, Color.Yellow); Self.QueueActivity(new DonateExperience(Self, t, level, deliversExperience.PlayerExperience)); + Self.ShowTargetLines(); } } } diff --git a/OpenRA.Mods.Common/Traits/Air/Aircraft.cs b/OpenRA.Mods.Common/Traits/Air/Aircraft.cs index e42ddc547b..7be7f966e2 100644 --- a/OpenRA.Mods.Common/Traits/Air/Aircraft.cs +++ b/OpenRA.Mods.Common/Traits/Air/Aircraft.cs @@ -830,14 +830,14 @@ namespace OpenRA.Mods.Common.Traits #region Implement IMove - public Activity MoveTo(CPos cell, int nearEnough) + public Activity MoveTo(CPos cell, int nearEnough, Color? targetLineColor = null) { - return new Fly(self, Target.FromCell(self.World, cell)); + return new Fly(self, Target.FromCell(self.World, cell), targetLineColor: targetLineColor); } - public Activity MoveTo(CPos cell, Actor ignoreActor) + public Activity MoveTo(CPos cell, Actor ignoreActor, Color? targetLineColor = null) { - return new Fly(self, Target.FromCell(self.World, cell)); + return new Fly(self, Target.FromCell(self.World, cell), targetLineColor: targetLineColor); } public Activity MoveWithinRange(Target target, WDist range, @@ -993,8 +993,8 @@ namespace OpenRA.Mods.Common.Traits UnReserve(); var target = Target.FromCell(self.World, cell); - self.SetTargetLine(target, Color.Green); - self.QueueActivity(order.Queued, new Fly(self, target)); + self.QueueActivity(order.Queued, new Fly(self, target, targetLineColor: Color.Green)); + self.ShowTargetLines(); } else if (orderString == "Land") { @@ -1007,8 +1007,8 @@ namespace OpenRA.Mods.Common.Traits var target = Target.FromCell(self.World, cell); - self.SetTargetLine(target, Color.Green); - self.QueueActivity(order.Queued, new Land(self, target)); + self.QueueActivity(order.Queued, new Land(self, target, targetLineColor: Color.Green)); + self.ShowTargetLines(); } else if (orderString == "Enter" || orderString == "ForceEnter" || orderString == "Repair") { @@ -1029,13 +1029,12 @@ namespace OpenRA.Mods.Common.Traits if (!order.Queued) UnReserve(); - self.SetTargetLine(Target.FromActor(targetActor), Color.Green); - // Aircraft with TakeOffOnResupply would immediately take off again, so there's no point in automatically forcing // them to land on a resupplier. For aircraft without it, it makes more sense to land than to idle above a // free resupplier. var forceLand = isForceEnter || !Info.TakeOffOnResupply; self.QueueActivity(order.Queued, new ReturnToBase(self, targetActor, forceLand)); + self.ShowTargetLines(); } else if (orderString == "Stop") { @@ -1077,9 +1076,8 @@ namespace OpenRA.Mods.Common.Traits .Rotate(WRot.FromFacing(self.World.SharedRandom.Next(256))); var target = Target.FromPos(self.CenterPosition + offset); - self.CancelActivity(); - self.SetTargetLine(target, Color.Green, false); - self.QueueActivity(new Fly(self, target)); + self.QueueActivity(false, new Fly(self, target)); + self.ShowTargetLines(); UnReserve(); } diff --git a/OpenRA.Mods.Common/Traits/Air/AttackAircraft.cs b/OpenRA.Mods.Common/Traits/Air/AttackAircraft.cs index 1150393014..b67f496bd1 100644 --- a/OpenRA.Mods.Common/Traits/Air/AttackAircraft.cs +++ b/OpenRA.Mods.Common/Traits/Air/AttackAircraft.cs @@ -11,6 +11,7 @@ using OpenRA.Activities; using OpenRA.Mods.Common.Activities; +using OpenRA.Primitives; using OpenRA.Traits; namespace OpenRA.Mods.Common.Traits @@ -44,9 +45,9 @@ namespace OpenRA.Mods.Common.Traits aircraftInfo = self.Info.TraitInfo(); } - public override Activity GetAttackActivity(Actor self, Target newTarget, bool allowMove, bool forceAttack) + public override Activity GetAttackActivity(Actor self, Target newTarget, bool allowMove, bool forceAttack, Color? targetLineColor = null) { - return new FlyAttack(self, newTarget, forceAttack); + return new FlyAttack(self, newTarget, forceAttack, targetLineColor); } protected override bool CanAttack(Actor self, Target target) diff --git a/OpenRA.Mods.Common/Traits/Air/AttackBomber.cs b/OpenRA.Mods.Common/Traits/Air/AttackBomber.cs index 47968ccaba..e03bd3353b 100644 --- a/OpenRA.Mods.Common/Traits/Air/AttackBomber.cs +++ b/OpenRA.Mods.Common/Traits/Air/AttackBomber.cs @@ -12,6 +12,7 @@ using System; using System.Linq; using OpenRA.Activities; +using OpenRA.Primitives; using OpenRA.Traits; namespace OpenRA.Mods.Common.Traits @@ -85,7 +86,7 @@ namespace OpenRA.Mods.Common.Traits OnRemovedFromWorld(self); } - public override Activity GetAttackActivity(Actor self, Target newTarget, bool allowMove, bool forceAttack) + public override Activity GetAttackActivity(Actor self, Target newTarget, bool allowMove, bool forceAttack, Color? targetLineColor) { throw new NotImplementedException("AttackBomber requires a scripted target"); } diff --git a/OpenRA.Mods.Common/Traits/Attack/AttackBase.cs b/OpenRA.Mods.Common/Traits/Attack/AttackBase.cs index 336161404a..ac8744613a 100644 --- a/OpenRA.Mods.Common/Traits/Attack/AttackBase.cs +++ b/OpenRA.Mods.Common/Traits/Attack/AttackBase.cs @@ -30,6 +30,9 @@ namespace OpenRA.Mods.Common.Traits public readonly string OutsideRangeCursor = null; + [Desc("Color to use for the target line.")] + public readonly Color TargetLineColor = Color.Red; + [Desc("Does the attack type require the attacker to enter the target's cell?")] public readonly bool AttackRequiresEnteringCell = false; @@ -196,8 +199,8 @@ namespace OpenRA.Mods.Common.Traits if (!order.Target.IsValidFor(self)) return; - self.SetTargetLine(order.Target, Color.Red); - AttackTarget(order.Target, order.Queued, true, forceAttack); + AttackTarget(order.Target, order.Queued, true, forceAttack, Info.TargetLineColor); + self.ShowTargetLines(); } if (order.OrderString == "Stop") @@ -221,7 +224,7 @@ namespace OpenRA.Mods.Common.Traits return order.OrderString == attackOrderName || order.OrderString == forceAttackOrderName ? Info.Voice : null; } - public abstract Activity GetAttackActivity(Actor self, Target newTarget, bool allowMove, bool forceAttack); + public abstract Activity GetAttackActivity(Actor self, Target newTarget, bool allowMove, bool forceAttack, Color? targetLineColor = null); public bool HasAnyValidWeapons(Target t, bool checkForCenterTargetingWeapons = false) { @@ -388,7 +391,7 @@ namespace OpenRA.Mods.Common.Traits && a.Weapon.IsValidAgainst(t, self.World, self)); } - public void AttackTarget(Target target, bool queued, bool allowMove, bool forceAttack = false) + public void AttackTarget(Target target, bool queued, bool allowMove, bool forceAttack = false, Color? targetLineColor = null) { if (IsTraitDisabled) return; @@ -399,7 +402,7 @@ namespace OpenRA.Mods.Common.Traits if (!queued) self.CancelActivity(); - var activity = GetAttackActivity(self, target, allowMove, forceAttack); + var activity = GetAttackActivity(self, target, allowMove, forceAttack, targetLineColor); self.QueueActivity(activity); OnQueueAttackActivity(self, activity, target, allowMove, forceAttack); } diff --git a/OpenRA.Mods.Common/Traits/Attack/AttackFollow.cs b/OpenRA.Mods.Common/Traits/Attack/AttackFollow.cs index efb4b4203b..8c63b97497 100644 --- a/OpenRA.Mods.Common/Traits/Attack/AttackFollow.cs +++ b/OpenRA.Mods.Common/Traits/Attack/AttackFollow.cs @@ -10,6 +10,7 @@ #endregion using System; +using System.Collections.Generic; using System.Linq; using OpenRA.Activities; using OpenRA.Primitives; @@ -151,9 +152,9 @@ namespace OpenRA.Mods.Common.Traits base.Tick(self); } - public override Activity GetAttackActivity(Actor self, Target newTarget, bool allowMove, bool forceAttack) + public override Activity GetAttackActivity(Actor self, Target newTarget, bool allowMove, bool forceAttack, Color? targetLineColor = null) { - return new AttackActivity(self, newTarget, allowMove, forceAttack); + return new AttackActivity(self, newTarget, allowMove, forceAttack, targetLineColor); } public override void OnQueueAttackActivity(Actor self, Activity activity, Target target, bool allowMove, bool forceAttack) @@ -213,6 +214,7 @@ namespace OpenRA.Mods.Common.Traits readonly RevealsShroud[] revealsShroud; readonly IMove move; readonly bool forceAttack; + readonly Color? targetLineColor; Target target; Target lastVisibleTarget; @@ -224,7 +226,7 @@ namespace OpenRA.Mods.Common.Traits bool wasMovingWithinRange; bool hasTicked; - public AttackActivity(Actor self, Target target, bool allowMove, bool forceAttack) + public AttackActivity(Actor self, Target target, bool allowMove, bool forceAttack, Color? targetLineColor = null) { attack = self.Trait(); move = allowMove ? self.TraitOrDefault() : null; @@ -232,6 +234,7 @@ namespace OpenRA.Mods.Common.Traits this.target = target; this.forceAttack = forceAttack; + this.targetLineColor = targetLineColor; // The target may become hidden between the initial order request and the first tick (e.g. if queued) // Moving to any position (even if quite stale) is still better than immediately giving up @@ -290,7 +293,6 @@ namespace OpenRA.Mods.Common.Traits } } - var oldUseLastVisibleTarget = useLastVisibleTarget; var maxRange = lastVisibleMaximumRange; var minRange = lastVisibleMinimumRange; useLastVisibleTarget = targetIsHiddenActor || !target.IsValidFor(self); @@ -313,10 +315,6 @@ namespace OpenRA.Mods.Common.Traits if (wasMovingWithinRange && targetIsHiddenActor) return true; - // Update target lines if required - if (useLastVisibleTarget != oldUseLastVisibleTarget) - self.SetTargetLine(useLastVisibleTarget ? lastVisibleTarget : target, Color.Red, false); - // Target is hidden or dead, and we don't have a fallback position to move towards if (useLastVisibleTarget && !lastVisibleTarget.IsValidFor(self)) return true; @@ -339,7 +337,7 @@ namespace OpenRA.Mods.Common.Traits return true; wasMovingWithinRange = true; - QueueChild(move.MoveWithinRange(target, minRange, maxRange, checkTarget.CenterPosition, Color.Red)); + QueueChild(move.MoveWithinRange(target, minRange, maxRange, checkTarget.CenterPosition)); return false; } @@ -358,6 +356,12 @@ namespace OpenRA.Mods.Common.Traits if (!autoTarget.HasValidTargetPriority(self, lastVisibleOwner, lastVisibleTargetTypes)) attack.ClearRequestedTarget(); } + + public override IEnumerable TargetLineNodes(Actor self) + { + if (targetLineColor != null) + yield return new TargetLineNode(useLastVisibleTarget ? lastVisibleTarget : target, targetLineColor.Value); + } } } } diff --git a/OpenRA.Mods.Common/Traits/Attack/AttackFrontal.cs b/OpenRA.Mods.Common/Traits/Attack/AttackFrontal.cs index 166f8e8d7d..7ee8849a96 100644 --- a/OpenRA.Mods.Common/Traits/Attack/AttackFrontal.cs +++ b/OpenRA.Mods.Common/Traits/Attack/AttackFrontal.cs @@ -10,6 +10,7 @@ #endregion using OpenRA.Activities; +using OpenRA.Primitives; using OpenRA.Traits; namespace OpenRA.Mods.Common.Traits @@ -41,9 +42,9 @@ namespace OpenRA.Mods.Common.Traits return TargetInFiringArc(self, target, Info.FacingTolerance); } - public override Activity GetAttackActivity(Actor self, Target newTarget, bool allowMove, bool forceAttack) + public override Activity GetAttackActivity(Actor self, Target newTarget, bool allowMove, bool forceAttack, Color? targetLineColor = null) { - return new Activities.Attack(self, newTarget, allowMove, forceAttack); + return new Activities.Attack(self, newTarget, allowMove, forceAttack, targetLineColor); } } } diff --git a/OpenRA.Mods.Common/Traits/Attack/AttackOmni.cs b/OpenRA.Mods.Common/Traits/Attack/AttackOmni.cs index a38efe76f0..dad3682155 100644 --- a/OpenRA.Mods.Common/Traits/Attack/AttackOmni.cs +++ b/OpenRA.Mods.Common/Traits/Attack/AttackOmni.cs @@ -9,8 +9,10 @@ */ #endregion +using System.Collections.Generic; using OpenRA.Activities; using OpenRA.Mods.Common.Activities; +using OpenRA.Primitives; using OpenRA.Traits; namespace OpenRA.Mods.Common.Traits @@ -25,9 +27,9 @@ namespace OpenRA.Mods.Common.Traits public AttackOmni(Actor self, AttackOmniInfo info) : base(self, info) { } - public override Activity GetAttackActivity(Actor self, Target newTarget, bool allowMove, bool forceAttack) + public override Activity GetAttackActivity(Actor self, Target newTarget, bool allowMove, bool forceAttack, Color? targetLineColor = null) { - return new SetTarget(this, newTarget, allowMove, forceAttack); + return new SetTarget(this, newTarget, allowMove, forceAttack, targetLineColor); } // Some 3rd-party mods rely on this being public @@ -36,11 +38,13 @@ namespace OpenRA.Mods.Common.Traits readonly AttackOmni attack; readonly bool allowMove; readonly bool forceAttack; + readonly Color? targetLineColor; Target target; - public SetTarget(AttackOmni attack, Target target, bool allowMove, bool forceAttack) + public SetTarget(AttackOmni attack, Target target, bool allowMove, bool forceAttack, Color? targetLineColor = null) { this.target = target; + this.targetLineColor = targetLineColor; this.attack = attack; this.allowMove = allowMove; this.forceAttack = forceAttack; @@ -77,6 +81,12 @@ namespace OpenRA.Mods.Common.Traits target = Target.Invalid; } } + + public override IEnumerable TargetLineNodes(Actor self) + { + if (targetLineColor != null) + yield return new TargetLineNode(target, targetLineColor.Value); + } } } } diff --git a/OpenRA.Mods.Common/Traits/AttackMove.cs b/OpenRA.Mods.Common/Traits/AttackMove.cs index fcdf16839f..d040ee6a84 100644 --- a/OpenRA.Mods.Common/Traits/AttackMove.cs +++ b/OpenRA.Mods.Common/Traits/AttackMove.cs @@ -77,9 +77,9 @@ namespace OpenRA.Mods.Common.Traits return; var targetLocation = move.NearestMoveableCell(cell); - self.SetTargetLine(Target.FromCell(self.World, targetLocation), Color.Red); var assaultMoving = order.OrderString == "AssaultMove"; - self.QueueActivity(new AttackMoveActivity(self, () => move.MoveTo(targetLocation, 1), assaultMoving)); + self.QueueActivity(new AttackMoveActivity(self, () => move.MoveTo(targetLocation, 1, targetLineColor: Color.Red), assaultMoving)); + self.ShowTargetLines(); } } } diff --git a/OpenRA.Mods.Common/Traits/AutoTarget.cs b/OpenRA.Mods.Common/Traits/AutoTarget.cs index 2412ca6692..4d5bc3879b 100644 --- a/OpenRA.Mods.Common/Traits/AutoTarget.cs +++ b/OpenRA.Mods.Common/Traits/AutoTarget.cs @@ -311,8 +311,6 @@ namespace OpenRA.Mods.Common.Traits void Attack(Actor self, Target target, bool allowMove) { - self.SetTargetLine(target, Color.Red, false); - foreach (var ab in ActiveAttackBases) ab.AttackTarget(target, false, allowMove); } diff --git a/OpenRA.Mods.Common/Traits/Buildings/RallyPoint.cs b/OpenRA.Mods.Common/Traits/Buildings/RallyPoint.cs index 17742460cd..89956897ed 100644 --- a/OpenRA.Mods.Common/Traits/Buildings/RallyPoint.cs +++ b/OpenRA.Mods.Common/Traits/Buildings/RallyPoint.cs @@ -21,6 +21,9 @@ namespace OpenRA.Mods.Common.Traits { public readonly string Image = "rallypoint"; + [Desc("Width (in pixels) of the rallypoint line.")] + public readonly int LineWidth = 2; + [SequenceReference("Image")] public readonly string FlagSequence = "flag"; diff --git a/OpenRA.Mods.Common/Traits/Buildings/TransformsIntoAircraft.cs b/OpenRA.Mods.Common/Traits/Buildings/TransformsIntoAircraft.cs index e46f971bd5..9087315241 100644 --- a/OpenRA.Mods.Common/Traits/Buildings/TransformsIntoAircraft.cs +++ b/OpenRA.Mods.Common/Traits/Buildings/TransformsIntoAircraft.cs @@ -103,8 +103,6 @@ namespace OpenRA.Mods.Common.Traits return; var target = Target.FromCell(self.World, cell); - - self.SetTargetLine(target, Color.Green); } else if (order.OrderString == "Enter") { @@ -114,10 +112,6 @@ namespace OpenRA.Mods.Common.Traits return; var targetActor = order.Target.Actor; - - // We only want to set a target line if the order will (most likely) succeed - if (Reservable.IsAvailableFor(targetActor, self)) - self.SetTargetLine(Target.FromActor(targetActor), Color.Green); } var currentTransform = self.CurrentActivity as Transform; @@ -130,10 +124,12 @@ namespace OpenRA.Mods.Common.Traits if (!order.Queued && activity.NextActivity != null) activity.NextActivity.Cancel(self); - activity.Queue(new IssueOrderAfterTransform(order.OrderString, order.Target)); + activity.Queue(new IssueOrderAfterTransform(order.OrderString, order.Target, Color.Green)); if (currentTransform == null) self.QueueActivity(order.Queued, activity); + + self.ShowTargetLines(); } string IOrderVoice.VoicePhraseForOrder(Actor self, Order order) diff --git a/OpenRA.Mods.Common/Traits/Buildings/TransformsIntoEntersTunnels.cs b/OpenRA.Mods.Common/Traits/Buildings/TransformsIntoEntersTunnels.cs index 5d951d653d..0c90e20fd5 100644 --- a/OpenRA.Mods.Common/Traits/Buildings/TransformsIntoEntersTunnels.cs +++ b/OpenRA.Mods.Common/Traits/Buildings/TransformsIntoEntersTunnels.cs @@ -93,17 +93,17 @@ namespace OpenRA.Mods.Common.Traits if (transform == null && currentTransform == null) return; - self.SetTargetLine(order.Target, Color.Green); - // Manually manage the inner activity queue var activity = currentTransform ?? transform.GetTransformActivity(self); if (!order.Queued && activity.NextActivity != null) activity.NextActivity.Cancel(self); - activity.Queue(new IssueOrderAfterTransform(order.OrderString, order.Target)); + activity.Queue(new IssueOrderAfterTransform(order.OrderString, order.Target, Color.Green)); if (currentTransform == null) self.QueueActivity(order.Queued, activity); + + self.ShowTargetLines(); } string IOrderVoice.VoicePhraseForOrder(Actor self, Order order) diff --git a/OpenRA.Mods.Common/Traits/Buildings/TransformsIntoMobile.cs b/OpenRA.Mods.Common/Traits/Buildings/TransformsIntoMobile.cs index d3217bec27..3f938a868f 100644 --- a/OpenRA.Mods.Common/Traits/Buildings/TransformsIntoMobile.cs +++ b/OpenRA.Mods.Common/Traits/Buildings/TransformsIntoMobile.cs @@ -107,17 +107,17 @@ namespace OpenRA.Mods.Common.Traits if (transform == null && currentTransform == null) return; - self.SetTargetLine(Target.FromCell(self.World, cell), Color.Green); - // Manually manage the inner activity queue var activity = currentTransform ?? transform.GetTransformActivity(self); if (!order.Queued && activity.NextActivity != null) activity.NextActivity.Cancel(self); - activity.Queue(new IssueOrderAfterTransform("Move", order.Target)); + activity.Queue(new IssueOrderAfterTransform("Move", order.Target, Color.Green)); if (currentTransform == null) self.QueueActivity(order.Queued, activity); + + self.ShowTargetLines(); } else if (order.OrderString == "Stop") { diff --git a/OpenRA.Mods.Common/Traits/Buildings/TransformsIntoPassenger.cs b/OpenRA.Mods.Common/Traits/Buildings/TransformsIntoPassenger.cs index 7913aa6a72..ddf519fc3d 100644 --- a/OpenRA.Mods.Common/Traits/Buildings/TransformsIntoPassenger.cs +++ b/OpenRA.Mods.Common/Traits/Buildings/TransformsIntoPassenger.cs @@ -117,17 +117,17 @@ namespace OpenRA.Mods.Common.Traits if (transform == null && currentTransform == null) return; - self.SetTargetLine(order.Target, Color.Green); - // Manually manage the inner activity queue var activity = currentTransform ?? transform.GetTransformActivity(self); if (!order.Queued && activity.NextActivity != null) activity.NextActivity.Cancel(self); - activity.Queue(new IssueOrderAfterTransform(order.OrderString, order.Target)); + activity.Queue(new IssueOrderAfterTransform(order.OrderString, order.Target, Color.Green)); if (currentTransform == null) self.QueueActivity(order.Queued, activity); + + self.ShowTargetLines(); } string IOrderVoice.VoicePhraseForOrder(Actor self, Order order) diff --git a/OpenRA.Mods.Common/Traits/Buildings/TransformsIntoRepairable.cs b/OpenRA.Mods.Common/Traits/Buildings/TransformsIntoRepairable.cs index cb0a64b19e..0b2a28000e 100644 --- a/OpenRA.Mods.Common/Traits/Buildings/TransformsIntoRepairable.cs +++ b/OpenRA.Mods.Common/Traits/Buildings/TransformsIntoRepairable.cs @@ -111,17 +111,17 @@ namespace OpenRA.Mods.Common.Traits if (transform == null && currentTransform == null) return; - self.SetTargetLine(order.Target, Color.Green); - // Manually manage the inner activity queue var activity = currentTransform ?? transform.GetTransformActivity(self); if (!order.Queued && activity.NextActivity != null) activity.NextActivity.Cancel(self); - activity.Queue(new IssueOrderAfterTransform(order.OrderString, order.Target)); + activity.Queue(new IssueOrderAfterTransform(order.OrderString, order.Target, Color.Green)); if (currentTransform == null) self.QueueActivity(order.Queued, activity); + + self.ShowTargetLines(); } string IOrderVoice.VoicePhraseForOrder(Actor self, Order order) diff --git a/OpenRA.Mods.Common/Traits/Captures.cs b/OpenRA.Mods.Common/Traits/Captures.cs index 1dc2fdea53..6a74e4eeeb 100644 --- a/OpenRA.Mods.Common/Traits/Captures.cs +++ b/OpenRA.Mods.Common/Traits/Captures.cs @@ -98,8 +98,8 @@ namespace OpenRA.Mods.Common.Traits if (!order.Queued) self.CancelActivity(); - self.SetTargetLine(order.Target, Color.Red); self.QueueActivity(new CaptureActor(self, order.Target)); + self.ShowTargetLines(); } protected override void TraitEnabled(Actor self) { captureManager.RefreshCaptures(self); } diff --git a/OpenRA.Mods.Common/Traits/Carryall.cs b/OpenRA.Mods.Common/Traits/Carryall.cs index 3c2727b592..df3217a832 100644 --- a/OpenRA.Mods.Common/Traits/Carryall.cs +++ b/OpenRA.Mods.Common/Traits/Carryall.cs @@ -297,8 +297,8 @@ namespace OpenRA.Mods.Common.Traits return; var targetLocation = move.NearestMoveableCell(cell); - self.SetTargetLine(Target.FromCell(self.World, targetLocation), Color.Yellow); self.QueueActivity(order.Queued, new DeliverUnit(self, order.Target, Info.DropRange)); + self.ShowTargetLines(); } else if (order.OrderString == "Unload") { @@ -316,8 +316,8 @@ namespace OpenRA.Mods.Common.Traits if (!order.Queued) self.CancelActivity(); - self.SetTargetLine(order.Target, Color.Yellow); self.QueueActivity(order.Queued, new PickupUnit(self, order.Target.Actor, Info.BeforeLoadDelay)); + self.ShowTargetLines(); } } diff --git a/OpenRA.Mods.Common/Traits/DeliversCash.cs b/OpenRA.Mods.Common/Traits/DeliversCash.cs index ea2c05b34e..f2326ab7ea 100644 --- a/OpenRA.Mods.Common/Traits/DeliversCash.cs +++ b/OpenRA.Mods.Common/Traits/DeliversCash.cs @@ -76,8 +76,8 @@ namespace OpenRA.Mods.Common.Traits if (!order.Queued) self.CancelActivity(); - self.SetTargetLine(order.Target, Color.Yellow); self.QueueActivity(new DonateCash(self, order.Target, info.Payload, info.PlayerExperience)); + self.ShowTargetLines(); } void INotifyCashTransfer.OnAcceptingCash(Actor self, Actor donor) { } diff --git a/OpenRA.Mods.Common/Traits/DeliversExperience.cs b/OpenRA.Mods.Common/Traits/DeliversExperience.cs index 60be9364fb..8a3c3bffd9 100644 --- a/OpenRA.Mods.Common/Traits/DeliversExperience.cs +++ b/OpenRA.Mods.Common/Traits/DeliversExperience.cs @@ -87,8 +87,8 @@ namespace OpenRA.Mods.Common.Traits if (!order.Queued) self.CancelActivity(); - self.SetTargetLine(order.Target, Color.Yellow); self.QueueActivity(new DonateExperience(self, order.Target, gainsExperience.Level, info.PlayerExperience)); + self.ShowTargetLines(); } public class DeliversExperienceOrderTargeter : UnitOrderTargeter diff --git a/OpenRA.Mods.Common/Traits/Demolition.cs b/OpenRA.Mods.Common/Traits/Demolition.cs index af6ba71c68..686db69f02 100644 --- a/OpenRA.Mods.Common/Traits/Demolition.cs +++ b/OpenRA.Mods.Common/Traits/Demolition.cs @@ -86,9 +86,10 @@ namespace OpenRA.Mods.Common.Traits if (!order.Queued) self.CancelActivity(); - self.SetTargetLine(order.Target, Color.Red); self.QueueActivity(new Demolish(self, order.Target, info.EnterBehaviour, info.DetonationDelay, info.Flashes, info.FlashesDelay, info.FlashInterval)); + + self.ShowTargetLines(); } public string VoicePhraseForOrder(Actor self, Order order) diff --git a/OpenRA.Mods.Common/Traits/EngineerRepair.cs b/OpenRA.Mods.Common/Traits/EngineerRepair.cs index ab2e4ff41c..2feff2e71f 100644 --- a/OpenRA.Mods.Common/Traits/EngineerRepair.cs +++ b/OpenRA.Mods.Common/Traits/EngineerRepair.cs @@ -95,8 +95,8 @@ namespace OpenRA.Mods.Common.Traits if (!order.Queued) self.CancelActivity(); - self.SetTargetLine(order.Target, Color.Yellow); self.QueueActivity(new RepairBuilding(self, order.Target, Info)); + self.ShowTargetLines(); } class EngineerRepairOrderTargeter : UnitOrderTargeter diff --git a/OpenRA.Mods.Common/Traits/EntersTunnels.cs b/OpenRA.Mods.Common/Traits/EntersTunnels.cs index 1cd37d0480..2feea6dd59 100644 --- a/OpenRA.Mods.Common/Traits/EntersTunnels.cs +++ b/OpenRA.Mods.Common/Traits/EntersTunnels.cs @@ -85,9 +85,9 @@ namespace OpenRA.Mods.Common.Traits if (!order.Queued) self.CancelActivity(); - self.SetTargetLine(Target.FromCell(self.World, tunnel.Exit.Value), Color.Green); - self.QueueActivity(move.MoveTo(tunnel.Entrance, tunnel.NearEnough)); - self.QueueActivity(move.MoveTo(tunnel.Exit.Value, tunnel.NearEnough)); + self.QueueActivity(move.MoveTo(tunnel.Entrance, tunnel.NearEnough, targetLineColor: Color.Green)); + self.QueueActivity(move.MoveTo(tunnel.Exit.Value, tunnel.NearEnough, targetLineColor: Color.Green)); + self.ShowTargetLines(); } IEnumerable IObservesVariables.GetVariableObservers() diff --git a/OpenRA.Mods.Common/Traits/Guard.cs b/OpenRA.Mods.Common/Traits/Guard.cs index ceb3d0588e..d69aabba67 100644 --- a/OpenRA.Mods.Common/Traits/Guard.cs +++ b/OpenRA.Mods.Common/Traits/Guard.cs @@ -53,10 +53,9 @@ namespace OpenRA.Mods.Common.Traits if (target.Type != TargetType.Actor) return; - self.SetTargetLine(target, Color.Yellow); - var range = target.Actor.Info.TraitInfo().Range; self.QueueActivity(new AttackMoveActivity(self, () => move.MoveFollow(self, target, WDist.Zero, range, targetLineColor: Color.Yellow))); + self.ShowTargetLines(); } public string VoicePhraseForOrder(Actor self, Order order) diff --git a/OpenRA.Mods.Common/Traits/Harvester.cs b/OpenRA.Mods.Common/Traits/Harvester.cs index fe096fc470..36731fc9fb 100644 --- a/OpenRA.Mods.Common/Traits/Harvester.cs +++ b/OpenRA.Mods.Common/Traits/Harvester.cs @@ -149,24 +149,9 @@ namespace OpenRA.Mods.Common.Traits self.World.AddFrameEndTask(w => self.QueueActivity(new FindAndDeliverResources(self))); } - public void SetProcLines(Actor proc) - { - if (proc == null || proc.IsDead) - return; - - var linkedHarvs = proc.World.ActorsHavingTrait(h => h.LinkedProc == proc) - .Select(a => Target.FromActor(a)) - .ToList(); - - proc.SetTargetLines(linkedHarvs, Color.Gold); - } - public void LinkProc(Actor self, Actor proc) { - var oldProc = LinkedProc; LinkedProc = proc; - SetProcLines(oldProc); - SetProcLines(proc); } public void UnlinkProc(Actor self, Actor proc) @@ -345,10 +330,9 @@ namespace OpenRA.Mods.Common.Traits loc = self.Location; } - self.SetTargetLine(Target.FromCell(self.World, loc), Color.Red); - // FindResources takes care of calling INotifyHarvesterAction self.QueueActivity(order.Queued, new FindAndDeliverResources(self, loc)); + self.ShowTargetLines(); } else if (order.OrderString == "Deliver") { @@ -362,8 +346,8 @@ namespace OpenRA.Mods.Common.Traits if (iao == null || !iao.AllowDocking || !IsAcceptableProcType(targetActor)) return; - self.SetTargetLine(order.Target, Color.Green); self.QueueActivity(order.Queued, new FindAndDeliverResources(self, targetActor)); + self.ShowTargetLines(); } } diff --git a/OpenRA.Mods.Common/Traits/Mobile.cs b/OpenRA.Mods.Common/Traits/Mobile.cs index 2c4f565185..c96901351d 100644 --- a/OpenRA.Mods.Common/Traits/Mobile.cs +++ b/OpenRA.Mods.Common/Traits/Mobile.cs @@ -314,8 +314,8 @@ namespace OpenRA.Mods.Common.Traits if (moveTo.HasValue) { self.CancelActivity(); - self.SetTargetLine(Target.FromCell(self.World, moveTo.Value), Color.Green, false); self.QueueActivity(new Move(self, moveTo.Value, WDist.Zero)); + self.ShowTargetLines(); Log.Write("debug", "OnNudge #{0} from {1} to {2}", self.ActorID, self.Location, moveTo.Value); @@ -527,14 +527,14 @@ namespace OpenRA.Mods.Common.Traits return inner; } - public Activity MoveTo(CPos cell, int nearEnough) + public Activity MoveTo(CPos cell, int nearEnough, Color? targetLineColor = null) { - return WrapMove(new Move(self, cell, WDist.FromCells(nearEnough), null)); + return WrapMove(new Move(self, cell, WDist.FromCells(nearEnough), targetLineColor: targetLineColor)); } - public Activity MoveTo(CPos cell, Actor ignoreActor) + public Activity MoveTo(CPos cell, Actor ignoreActor, Color? targetLineColor = null) { - return WrapMove(new Move(self, cell, WDist.Zero, ignoreActor)); + return WrapMove(new Move(self, cell, WDist.Zero, ignoreActor, targetLineColor: targetLineColor)); } public Activity MoveWithinRange(Target target, WDist range, @@ -805,8 +805,8 @@ namespace OpenRA.Mods.Common.Traits if (!order.Queued) self.CancelActivity(); - self.SetTargetLine(Target.FromCell(self.World, cell), Color.Green); - self.QueueActivity(order.Queued, WrapMove(new Move(self, cell, WDist.FromCells(8), null, true))); + self.QueueActivity(order.Queued, WrapMove(new Move(self, cell, WDist.FromCells(8), null, true, Color.Green))); + self.ShowTargetLines(); } // TODO: This should only cancel activities queued by this trait diff --git a/OpenRA.Mods.Common/Traits/Passenger.cs b/OpenRA.Mods.Common/Traits/Passenger.cs index 9b52696ba2..126f8b7b78 100644 --- a/OpenRA.Mods.Common/Traits/Passenger.cs +++ b/OpenRA.Mods.Common/Traits/Passenger.cs @@ -162,8 +162,8 @@ namespace OpenRA.Mods.Common.Traits if (!order.Queued) self.CancelActivity(); - self.SetTargetLine(order.Target, Color.Green); self.QueueActivity(new EnterTransport(self, order.Target)); + self.ShowTargetLines(); } public bool Reserve(Actor self, Cargo cargo) diff --git a/OpenRA.Mods.Common/Traits/Production.cs b/OpenRA.Mods.Common/Traits/Production.cs index 3d0d9f7415..23795c2e5b 100644 --- a/OpenRA.Mods.Common/Traits/Production.cs +++ b/OpenRA.Mods.Common/Traits/Production.cs @@ -43,7 +43,6 @@ namespace OpenRA.Mods.Common.Traits { var exit = CPos.Zero; var exitLocation = CPos.Zero; - var target = Target.Invalid; // Clone the initializer dictionary for the new actor var td = new TypeDictionary(); @@ -70,7 +69,6 @@ namespace OpenRA.Mods.Common.Traits } exitLocation = rp.Value != null ? rp.Value.Location : exit; - target = Target.FromCell(self.World, exitLocation); td.Add(new LocationInit(exit)); td.Add(new CenterPositionInit(spawn)); @@ -94,8 +92,6 @@ namespace OpenRA.Mods.Common.Traits } } - newUnit.SetTargetLine(target, rp.Value != null ? Color.Red : Color.Green, false); - if (!self.IsDead) foreach (var t in self.TraitsImplementing()) t.UnitProduced(self, newUnit, exit); diff --git a/OpenRA.Mods.Common/Traits/ProductionFromMapEdge.cs b/OpenRA.Mods.Common/Traits/ProductionFromMapEdge.cs index c985ec369b..4cd5b379e6 100644 --- a/OpenRA.Mods.Common/Traits/ProductionFromMapEdge.cs +++ b/OpenRA.Mods.Common/Traits/ProductionFromMapEdge.cs @@ -93,8 +93,6 @@ namespace OpenRA.Mods.Common.Traits if (move != null) newUnit.QueueActivity(move.MoveTo(destination, 2)); - newUnit.SetTargetLine(Target.FromCell(self.World, destination), Color.Green, false); - if (!self.IsDead) foreach (var t in self.TraitsImplementing()) t.UnitProduced(self, newUnit, destination); diff --git a/OpenRA.Mods.Common/Traits/ProductionParadrop.cs b/OpenRA.Mods.Common/Traits/ProductionParadrop.cs index c8af2713bd..fddaa9d6e7 100644 --- a/OpenRA.Mods.Common/Traits/ProductionParadrop.cs +++ b/OpenRA.Mods.Common/Traits/ProductionParadrop.cs @@ -103,7 +103,6 @@ namespace OpenRA.Mods.Common.Traits { var exit = CPos.Zero; var exitLocation = CPos.Zero; - var target = Target.Invalid; var info = (ProductionParadropInfo)Info; var actorType = info.ActorType; @@ -124,7 +123,6 @@ namespace OpenRA.Mods.Common.Traits var initialFacing = exitinfo.Facing < 0 ? (to - spawn).Yaw.Facing : exitinfo.Facing; exitLocation = rp.Value != null ? rp.Value.Location : exit; - target = Target.FromCell(self.World, exitLocation); td.Add(new LocationInit(exit)); td.Add(new CenterPositionInit(spawn)); @@ -149,8 +147,6 @@ namespace OpenRA.Mods.Common.Traits } } - newUnit.SetTargetLine(target, rp.Value != null ? Color.Red : Color.Green, false); - if (!self.IsDead) foreach (var t in self.TraitsImplementing()) t.UnitProduced(self, newUnit, exit); diff --git a/OpenRA.Mods.Common/Traits/Render/DrawLineToTarget.cs b/OpenRA.Mods.Common/Traits/Render/DrawLineToTarget.cs index f5e6a1868d..ffbf93bb90 100644 --- a/OpenRA.Mods.Common/Traits/Render/DrawLineToTarget.cs +++ b/OpenRA.Mods.Common/Traits/Render/DrawLineToTarget.cs @@ -10,24 +10,31 @@ #endregion using System.Collections.Generic; +using OpenRA.Activities; using OpenRA.Graphics; using OpenRA.Primitives; using OpenRA.Traits; namespace OpenRA.Mods.Common.Traits { + [Desc("Renders target lines between order waypoints.")] public class DrawLineToTargetInfo : ITraitInfo { + [Desc("Delay (in ticks) before the target lines disappear.")] public readonly int Delay = 60; + [Desc("Width (in pixels) of the target lines.")] + public readonly int LineWidth = 2; + + [Desc("Width (in pixels) of the end node markers.")] + public readonly int MarkerWidth = 3; + public virtual object Create(ActorInitializer init) { return new DrawLineToTarget(init.Self, this); } } - public class DrawLineToTarget : IRenderAboveShroudWhenSelected, INotifySelected, INotifyBecomingIdle, INotifyOwnerChanged + public class DrawLineToTarget : IRenderAboveShroudWhenSelected, INotifySelected { readonly DrawLineToTargetInfo info; - List targets; - Color c; int lifetime; public DrawLineToTarget(Actor self, DrawLineToTargetInfo info) @@ -35,25 +42,7 @@ namespace OpenRA.Mods.Common.Traits this.info = info; } - public void SetTarget(Actor self, Target target, Color c, bool display) - { - targets = new List { target }; - this.c = c; - - if (display) - lifetime = info.Delay; - } - - public void SetTargets(Actor self, List targets, Color c, bool display) - { - this.targets = targets; - this.c = c; - - if (display) - lifetime = info.Delay; - } - - void INotifySelected.Selected(Actor a) + public void ShowTargetLines(Actor a) { if (a.IsIdle) return; @@ -62,65 +51,57 @@ namespace OpenRA.Mods.Common.Traits lifetime = info.Delay; } + void INotifySelected.Selected(Actor a) + { + ShowTargetLines(a); + } + IEnumerable IRenderAboveShroudWhenSelected.RenderAboveShroud(Actor self, WorldRenderer wr) { - var force = Game.GetModifierKeys().HasModifier(Modifiers.Alt); - if ((lifetime <= 0 || --lifetime <= 0) && !force) + if (self.Owner != self.World.LocalPlayer) + yield break; + + // Players want to see the lines when in waypoint mode. + var force = Game.GetModifierKeys().HasModifier(Modifiers.Shift); + + if (--lifetime <= 0 && !force) yield break; if (!(force || Game.Settings.Game.DrawTargetLine)) yield break; - if (targets == null || targets.Count == 0) - yield break; - - foreach (var target in targets) + var prev = self.CenterPosition; + var a = self.CurrentActivity; + for (; a != null; a = a.NextActivity) { - if (target.Type == TargetType.Invalid) + if (a.IsCanceling) continue; - yield return new TargetLineRenderable(new[] { self.CenterPosition, target.CenterPosition }, c); + foreach (var n in a.TargetLineNodes(self)) + { + if (n.Target.Type != TargetType.Invalid) + { + yield return new TargetLineRenderable(new[] { prev, n.Target.CenterPosition }, n.Color, info.LineWidth, info.MarkerWidth); + prev = n.Target.CenterPosition; + } + } } } bool IRenderAboveShroudWhenSelected.SpatiallyPartitionable { get { return false; } } - - void INotifyBecomingIdle.OnBecomingIdle(Actor self) - { - targets = null; - } - - void INotifyOwnerChanged.OnOwnerChanged(Actor self, Player oldOwner, Player newOwner) - { - targets = null; - } } public static class LineTargetExts { - public static void SetTargetLines(this Actor self, List targets, Color color) + public static void ShowTargetLines(this Actor self) { - var line = self.TraitOrDefault(); - if (line != null) - self.World.AddFrameEndTask(w => line.SetTargets(self, targets, color, false)); - } - - public static void SetTargetLine(this Actor self, Target target, Color color) - { - self.SetTargetLine(target, color, true); - } - - public static void SetTargetLine(this Actor self, Target target, Color color, bool display) - { - if (!self.Owner.IsAlliedWith(self.World.LocalPlayer)) - return; - - if (self.Disposed) + if (self.Owner != self.World.LocalPlayer) return; + // Draw after frame end so that all the queueing of activities are done before drawing. var line = self.TraitOrDefault(); if (line != null) - line.SetTarget(self, target, color, display); + self.World.AddFrameEndTask(w => line.ShowTargetLines(self)); } } } diff --git a/OpenRA.Mods.Common/Traits/Repairable.cs b/OpenRA.Mods.Common/Traits/Repairable.cs index 116c0f0beb..f99824abcf 100644 --- a/OpenRA.Mods.Common/Traits/Repairable.cs +++ b/OpenRA.Mods.Common/Traits/Repairable.cs @@ -123,8 +123,8 @@ namespace OpenRA.Mods.Common.Traits if (!CanRepairAt(order.Target.Actor) || (!CanRepair() && !CanRearm())) return; - self.SetTargetLine(order.Target, Color.Green); self.QueueActivity(order.Queued, new Resupply(self, order.Target.Actor, new WDist(512))); + self.ShowTargetLines(); } IEnumerable IObservesVariables.GetVariableObservers() diff --git a/OpenRA.Mods.Common/Traits/RepairableNear.cs b/OpenRA.Mods.Common/Traits/RepairableNear.cs index 8b94480a16..d377c2575c 100644 --- a/OpenRA.Mods.Common/Traits/RepairableNear.cs +++ b/OpenRA.Mods.Common/Traits/RepairableNear.cs @@ -102,8 +102,8 @@ namespace OpenRA.Mods.Common.Traits if (!order.Queued) self.CancelActivity(); - self.SetTargetLine(order.Target, Color.Green); self.QueueActivity(new Resupply(self, order.Target.Actor, Info.CloseEnough)); + self.ShowTargetLines(); } public Actor FindRepairBuilding(Actor self) diff --git a/OpenRA.Mods.Common/Traits/RepairsBridges.cs b/OpenRA.Mods.Common/Traits/RepairsBridges.cs index bcb60c6d8a..9e97039314 100644 --- a/OpenRA.Mods.Common/Traits/RepairsBridges.cs +++ b/OpenRA.Mods.Common/Traits/RepairsBridges.cs @@ -105,8 +105,8 @@ namespace OpenRA.Mods.Common.Traits if (!order.Queued) self.CancelActivity(); - self.SetTargetLine(order.Target, Color.Yellow); self.QueueActivity(new RepairBridge(self, order.Target, info.EnterBehaviour, info.RepairNotification)); + self.ShowTargetLines(); } } diff --git a/OpenRA.Mods.Common/TraitsInterfaces.cs b/OpenRA.Mods.Common/TraitsInterfaces.cs index e5884dc10a..78a99c65fa 100644 --- a/OpenRA.Mods.Common/TraitsInterfaces.cs +++ b/OpenRA.Mods.Common/TraitsInterfaces.cs @@ -425,8 +425,8 @@ namespace OpenRA.Mods.Common.Traits public interface IMove { - Activity MoveTo(CPos cell, int nearEnough); - Activity MoveTo(CPos cell, Actor ignoreActor); + Activity MoveTo(CPos cell, int nearEnough, Color? targetLineColor = null); + Activity MoveTo(CPos cell, Actor ignoreActor, Color? targetLineColor = null); Activity MoveWithinRange(Target target, WDist range, WPos? initialTargetPosition = null, Color? targetLineColor = null); Activity MoveWithinRange(Target target, WDist minRange, WDist maxRange, diff --git a/OpenRA.Mods.D2k/Traits/AttackSwallow.cs b/OpenRA.Mods.D2k/Traits/AttackSwallow.cs index fe18d5b5f5..54e7575e3d 100644 --- a/OpenRA.Mods.D2k/Traits/AttackSwallow.cs +++ b/OpenRA.Mods.D2k/Traits/AttackSwallow.cs @@ -15,6 +15,7 @@ using OpenRA.Activities; using OpenRA.Mods.Common.Activities; using OpenRA.Mods.Common.Traits; using OpenRA.Mods.D2k.Activities; +using OpenRA.Primitives; using OpenRA.Traits; namespace OpenRA.Mods.D2k.Traits @@ -70,7 +71,7 @@ namespace OpenRA.Mods.D2k.Traits self.QueueActivity(new SwallowActor(self, target, a, facing)); } - public override Activity GetAttackActivity(Actor self, Target newTarget, bool allowMove, bool forceAttack) + public override Activity GetAttackActivity(Actor self, Target newTarget, bool allowMove, bool forceAttack, Color? targetLineColor) { return new SwallowTarget(self, newTarget, allowMove, forceAttack); }