diff --git a/OpenRA.Mods.Cnc/Traits/TDGunboat.cs b/OpenRA.Mods.Cnc/Traits/TDGunboat.cs index 71447e470c..fb3057a39d 100644 --- a/OpenRA.Mods.Cnc/Traits/TDGunboat.cs +++ b/OpenRA.Mods.Cnc/Traits/TDGunboat.cs @@ -206,6 +206,8 @@ namespace OpenRA.Mods.Cnc.Traits public Activity ReturnToCell(Actor self) { return null; } public Activity MoveToTarget(Actor self, in Target target, WPos? initialTargetPosition = null, Color? targetLineColor = null) { return null; } + public Activity MoveOntoTarget(Actor self, in Target target, in WVec offset, + WAngle? facing, Color? targetLineColor = null) { return null; } public Activity MoveIntoTarget(Actor self, in Target target) { return null; } public Activity LocalMove(Actor self, WPos fromPos, WPos toPos) { return null; } diff --git a/OpenRA.Mods.Common/Activities/Air/ReturnToBase.cs b/OpenRA.Mods.Common/Activities/Air/ReturnToBase.cs index f79283cbdc..cd0443b39e 100644 --- a/OpenRA.Mods.Common/Activities/Air/ReturnToBase.cs +++ b/OpenRA.Mods.Common/Activities/Air/ReturnToBase.cs @@ -119,7 +119,7 @@ namespace OpenRA.Mods.Common.Activities } aircraft.MakeReservation(dest); - QueueChild(new Land(self, Target.FromActor(dest), offset, facing, Color.Green)); + QueueChild(aircraft.MoveOntoTarget(self, Target.FromActor(dest), offset, facing, Color.Green)); QueueChild(new Resupply(self, dest, WDist.Zero, alwaysLand)); return true; } diff --git a/OpenRA.Mods.Common/Activities/DeliverResources.cs b/OpenRA.Mods.Common/Activities/DeliverResources.cs index db44eb9640..911871cebc 100644 --- a/OpenRA.Mods.Common/Activities/DeliverResources.cs +++ b/OpenRA.Mods.Common/Activities/DeliverResources.cs @@ -62,12 +62,13 @@ namespace OpenRA.Mods.Common.Activities proc = harv.LinkedProc; var iao = proc.Trait(); - if (self.Location != proc.Location + iao.DeliveryOffset) + if (self.CenterPosition != iao.DeliveryPosition) { foreach (var n in notifyHarvesterActions) n.MovingToRefinery(self, proc); - QueueChild(movement.MoveTo(proc.Location + iao.DeliveryOffset, 0)); + var target = Target.FromActor(proc); + QueueChild(movement.MoveOntoTarget(self, target, iao.DeliveryPosition - proc.CenterPosition, iao.DeliveryAngle)); return false; } diff --git a/OpenRA.Mods.Common/Activities/FindAndDeliverResources.cs b/OpenRA.Mods.Common/Activities/FindAndDeliverResources.cs index 1a9b612500..8d3f0cf8f4 100644 --- a/OpenRA.Mods.Common/Activities/FindAndDeliverResources.cs +++ b/OpenRA.Mods.Common/Activities/FindAndDeliverResources.cs @@ -131,10 +131,10 @@ namespace OpenRA.Mods.Common.Activities var lastproc = harv.LastLinkedProc ?? harv.LinkedProc; if (lastproc != null && !lastproc.Disposed) { - var deliveryLoc = lastproc.Location + lastproc.Trait().DeliveryOffset; - if (self.Location == deliveryLoc && harv.IsEmpty) + var deliveryLoc = lastproc.Trait().DeliveryPosition; + if (self.CenterPosition == deliveryLoc && harv.IsEmpty) { - var unblockCell = deliveryLoc + harv.Info.UnblockCell; + var unblockCell = self.World.Map.CellContaining(deliveryLoc) + harv.Info.UnblockCell; var moveTo = mobile.NearestMoveableCell(unblockCell, 1, 5); QueueChild(mobile.MoveTo(moveTo, 1)); } @@ -246,10 +246,10 @@ namespace OpenRA.Mods.Common.Activities CPos? GetSearchFromProcLocation() { if (harv.LastLinkedProc != null && !harv.LastLinkedProc.IsDead && harv.LastLinkedProc.IsInWorld) - return harv.LastLinkedProc.Location + harv.LastLinkedProc.Trait().DeliveryOffset; + return harv.LastLinkedProc.World.Map.CellContaining(harv.LastLinkedProc.Trait().DeliveryPosition); if (harv.LinkedProc != null && !harv.LinkedProc.IsDead && harv.LinkedProc.IsInWorld) - return harv.LinkedProc.Location + harv.LinkedProc.Trait().DeliveryOffset; + return harv.LinkedProc.World.Map.CellContaining(harv.LinkedProc.Trait().DeliveryPosition); return null; } diff --git a/OpenRA.Mods.Common/Activities/HarvesterDockSequence.cs b/OpenRA.Mods.Common/Activities/HarvesterDockSequence.cs index 0d585951a2..430600166e 100644 --- a/OpenRA.Mods.Common/Activities/HarvesterDockSequence.cs +++ b/OpenRA.Mods.Common/Activities/HarvesterDockSequence.cs @@ -22,14 +22,12 @@ namespace OpenRA.Mods.Common.Activities { public class HarvesterDockSequence : Activity { - protected enum DockingState { Wait, Turn, Drag, Dock, Loop, Undock, Complete } + protected enum DockingState { Wait, Drag, Dock, Loop, Undock, Complete } protected readonly Actor RefineryActor; - protected readonly Refinery Refinery; protected readonly WithDockingOverlay DockHostSpriteOverlay; protected readonly Harvester Harv; protected readonly IDockClientBody DockClientBody; - protected readonly WAngle DockAngle; protected readonly bool IsDragRequired; protected readonly WVec DragOffset; protected readonly int DragLength; @@ -45,11 +43,9 @@ namespace OpenRA.Mods.Common.Activities public HarvesterDockSequence(Actor self, Actor refineryActor, Refinery refinery) { - dockingState = DockingState.Turn; - Refinery = refinery; + dockingState = DockingState.Drag; RefineryActor = refineryActor; DockHostSpriteOverlay = refineryActor.TraitOrDefault(); - DockAngle = refinery.DeliveryAngle; IsDragRequired = refinery.IsDragRequired; DragOffset = refinery.DragOffset; DragLength = refinery.DragLength; @@ -68,11 +64,6 @@ namespace OpenRA.Mods.Common.Activities case DockingState.Wait: return false; - case DockingState.Turn: - dockingState = DockingState.Drag; - QueueChild(new Turn(self, DockAngle)); - return false; - case DockingState.Drag: if (IsCanceling || !RefineryActor.IsInWorld || RefineryActor.IsDead || Harv.IsTraitDisabled) return true; diff --git a/OpenRA.Mods.Common/Activities/Move/MoveOntoAndTurn.cs b/OpenRA.Mods.Common/Activities/Move/MoveOntoAndTurn.cs new file mode 100644 index 0000000000..eaeb3adba6 --- /dev/null +++ b/OpenRA.Mods.Common/Activities/Move/MoveOntoAndTurn.cs @@ -0,0 +1,43 @@ +#region Copyright & License Information +/* + * Copyright (c) The OpenRA Developers and Contributors + * This file is part of OpenRA, which is free software. It is made + * available to you under the terms of the GNU General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. For more + * information, see COPYING. + */ +#endregion + +using OpenRA.Primitives; +using OpenRA.Traits; + +namespace OpenRA.Mods.Common.Activities +{ + public class MoveOntoAndTurn : MoveOnto + { + readonly WAngle? desiredFacing; + + public MoveOntoAndTurn(Actor self, in Target target, in WVec offset, WAngle? desiredFacing, Color? targetLineColor = null) + : base(self, target, offset, null, targetLineColor) + { + this.desiredFacing = desiredFacing; + } + + public override bool Tick(Actor self) + { + if (base.Tick(self)) + { + if (!IsCanceling && desiredFacing.HasValue && desiredFacing.Value != Mobile.Facing) + { + QueueChild(new Turn(self, desiredFacing.Value)); + return false; + } + + return true; + } + + return false; + } + } +} diff --git a/OpenRA.Mods.Common/Activities/Resupply.cs b/OpenRA.Mods.Common/Activities/Resupply.cs index 40eb05c7bf..18f223d966 100644 --- a/OpenRA.Mods.Common/Activities/Resupply.cs +++ b/OpenRA.Mods.Common/Activities/Resupply.cs @@ -132,12 +132,13 @@ namespace OpenRA.Mods.Common.Activities else if (activeResupplyTypes != 0 && aircraft == null && !isCloseEnough) { var targetCell = self.World.Map.CellContaining(host.Actor.CenterPosition); - QueueChild(move.MoveWithinRange(host, closeEnough, targetLineColor: moveInfo.GetTargetLineColor())); // HACK: Repairable needs the actor to move to host center. // TODO: Get rid of this or at least replace it with something less hacky. if (repairableNear == null) - QueueChild(move.MoveTo(targetCell, targetLineColor: moveInfo.GetTargetLineColor())); + QueueChild(move.MoveOntoTarget(self, host, WVec.Zero, null, moveInfo.GetTargetLineColor())); + else + QueueChild(move.MoveWithinRange(host, closeEnough, targetLineColor: moveInfo.GetTargetLineColor())); var delta = (self.CenterPosition - host.CenterPosition).LengthSquared; transportCallers.FirstOrDefault(t => t.MinimumDistance.LengthSquared < delta)?.RequestTransport(self, targetCell); diff --git a/OpenRA.Mods.Common/Traits/Air/Aircraft.cs b/OpenRA.Mods.Common/Traits/Air/Aircraft.cs index 3665f435f4..ddcaa0d949 100644 --- a/OpenRA.Mods.Common/Traits/Air/Aircraft.cs +++ b/OpenRA.Mods.Common/Traits/Air/Aircraft.cs @@ -935,6 +935,11 @@ namespace OpenRA.Mods.Common.Traits return new Land(self, target); } + public Activity MoveOntoTarget(Actor self, in Target target, in WVec offset, WAngle? facing, Color? targetLineColor = null) + { + return new Land(self, target, offset, facing, targetLineColor); + } + public Activity LocalMove(Actor self, WPos fromPos, WPos toPos) { // TODO: Ignore repulsion when moving diff --git a/OpenRA.Mods.Common/Traits/Buildings/Refinery.cs b/OpenRA.Mods.Common/Traits/Buildings/Refinery.cs index f886716196..22c3372f44 100644 --- a/OpenRA.Mods.Common/Traits/Buildings/Refinery.cs +++ b/OpenRA.Mods.Common/Traits/Buildings/Refinery.cs @@ -70,7 +70,7 @@ namespace OpenRA.Mods.Common.Traits bool preventDock = false; public bool AllowDocking => !preventDock; - public CVec DeliveryOffset => info.DockOffset; + public WPos DeliveryPosition => self.World.Map.CenterOfCell(self.Location + info.DockOffset); public WAngle DeliveryAngle => info.DockAngle; public bool IsDragRequired => info.IsDragRequired; public WVec DragOffset => info.DragOffset; diff --git a/OpenRA.Mods.Common/Traits/CarryableHarvester.cs b/OpenRA.Mods.Common/Traits/CarryableHarvester.cs index 3c51f7c166..2485c96d5e 100644 --- a/OpenRA.Mods.Common/Traits/CarryableHarvester.cs +++ b/OpenRA.Mods.Common/Traits/CarryableHarvester.cs @@ -37,7 +37,7 @@ namespace OpenRA.Mods.Common.Traits void INotifyHarvesterAction.MovingToRefinery(Actor self, Actor refineryActor) { var iao = refineryActor.Trait(); - var location = refineryActor.Location + iao.DeliveryOffset; + var location = self.World.Map.CellContaining(iao.DeliveryPosition); foreach (var t in transports) t.RequestTransport(self, location); } diff --git a/OpenRA.Mods.Common/Traits/Harvester.cs b/OpenRA.Mods.Common/Traits/Harvester.cs index 8914f7f997..10ed1c1c81 100644 --- a/OpenRA.Mods.Common/Traits/Harvester.cs +++ b/OpenRA.Mods.Common/Traits/Harvester.cs @@ -187,7 +187,7 @@ namespace OpenRA.Mods.Common.Traits .Where(r => r.Actor != ignore && r.Actor.Owner == self.Owner && IsAcceptableProcType(r.Actor)) .Select(r => new { - Location = r.Actor.Location + r.Trait.DeliveryOffset, + Location = r.Actor.World.Map.CellContaining(r.Trait.DeliveryPosition), Actor = r.Actor, Occupancy = self.World.ActorsHavingTrait(h => h.LinkedProc == r.Actor).Count() }) diff --git a/OpenRA.Mods.Common/Traits/Mobile.cs b/OpenRA.Mods.Common/Traits/Mobile.cs index b91a89ae11..49cd4e0177 100644 --- a/OpenRA.Mods.Common/Traits/Mobile.cs +++ b/OpenRA.Mods.Common/Traits/Mobile.cs @@ -704,6 +704,11 @@ namespace OpenRA.Mods.Common.Traits return WrapMove(new LocalMoveIntoTarget(self, target, new WDist(512))); } + public Activity MoveOntoTarget(Actor self, in Target target, in WVec offset, WAngle? facing, Color? targetLineColor = null) + { + return WrapMove(new MoveOntoAndTurn(self, target, offset, facing, targetLineColor)); + } + public Activity LocalMove(Actor self, WPos fromPos, WPos toPos) { return WrapMove(LocalMove(self, fromPos, toPos, self.Location)); diff --git a/OpenRA.Mods.Common/TraitsInterfaces.cs b/OpenRA.Mods.Common/TraitsInterfaces.cs index 8181ed1ecb..3d18bbd579 100644 --- a/OpenRA.Mods.Common/TraitsInterfaces.cs +++ b/OpenRA.Mods.Common/TraitsInterfaces.cs @@ -271,7 +271,8 @@ namespace OpenRA.Mods.Common.Traits { void OnDock(Actor harv, DeliverResources dockOrder); int AcceptResources(string resourceType, int count = 1); - CVec DeliveryOffset { get; } + WPos DeliveryPosition { get; } + WAngle DeliveryAngle { get; } bool AllowDocking { get; } } @@ -455,6 +456,8 @@ namespace OpenRA.Mods.Common.Traits WPos? initialTargetPosition = null, Color? targetLineColor = null); Activity ReturnToCell(Actor self); Activity MoveIntoTarget(Actor self, in Target target); + Activity MoveOntoTarget(Actor self, in Target target, in WVec offset, + WAngle? facing, Color? targetLineColor = null); Activity LocalMove(Actor self, WPos fromPos, WPos toPos); int EstimatedMoveDuration(Actor self, WPos fromPos, WPos toPos); CPos NearestMoveableCell(CPos target);