diff --git a/OpenRA.FileFormats/WPos.cs b/OpenRA.FileFormats/WPos.cs index 7800ef8508..25f76bef65 100644 --- a/OpenRA.FileFormats/WPos.cs +++ b/OpenRA.FileFormats/WPos.cs @@ -34,6 +34,8 @@ namespace OpenRA public static bool operator ==(WPos me, WPos other) { return (me.X == other.X && me.Y == other.Y && me.Z == other.Z); } public static bool operator !=(WPos me, WPos other) { return !(me == other); } + public static WPos Lerp(WPos a, WPos b, int mul, int div) { return a + (b - a) * mul / div; } + public static WPos Average(params WPos[] list) { if (list == null || list.Length == 0) diff --git a/OpenRA.Game/Traits/Util.cs b/OpenRA.Game/Traits/Util.cs index d40af1fa6c..c68b0d932e 100755 --- a/OpenRA.Game/Traits/Util.cs +++ b/OpenRA.Game/Traits/Util.cs @@ -30,6 +30,11 @@ namespace OpenRA.Traits return ( facing - rot ) & 0xFF; } + public static int GetFacing(WVec d, int currentFacing) + { + return GetFacing(new int2(d.X, d.Y), currentFacing); + } + public static int GetFacing(PVecInt d, int currentFacing) { return GetFacing(d.ToInt2(), currentFacing); diff --git a/OpenRA.Mods.Cnc/Activities/HarvesterDockSequence.cs b/OpenRA.Mods.Cnc/Activities/HarvesterDockSequence.cs index 59999add0e..337438a7fc 100644 --- a/OpenRA.Mods.Cnc/Activities/HarvesterDockSequence.cs +++ b/OpenRA.Mods.Cnc/Activities/HarvesterDockSequence.cs @@ -27,16 +27,15 @@ namespace OpenRA.Mods.Cnc readonly RenderUnit ru; State state; - PPos startDock; - PPos endDock; + WPos startDock, endDock; public HarvesterDockSequence(Actor self, Actor proc) { this.proc = proc; state = State.Turn; harv = self.Trait(); ru = self.Trait(); - startDock = self.Trait().PxPosition; - endDock = proc.Trait().PxPosition + new PVecInt(-15,8); + startDock = self.Trait().PxPosition.ToWPos(0); + endDock = (proc.Trait().PxPosition + new PVecInt(-15,8)).ToWPos(0); } public override Activity Tick(Actor self) diff --git a/OpenRA.Mods.RA/Activities/Enter.cs b/OpenRA.Mods.RA/Activities/Enter.cs index 652e970c63..fbf2243139 100755 --- a/OpenRA.Mods.RA/Activities/Enter.cs +++ b/OpenRA.Mods.RA/Activities/Enter.cs @@ -35,9 +35,9 @@ namespace OpenRA.Mods.RA.Activities // Move to the middle of the target, ignoring impassable tiles var mobile = self.Trait(); - var to = target.CenterLocation; - var from = self.CenterLocation; - var speed = mobile.MovementSpeedForCell(self, self.Location); + var to = target.CenterPosition; + var from = self.CenterPosition; + var speed = mobile.WorldMovementSpeedForCell(self, self.Location); var length = speed > 0 ? (int)((to - from).Length * 3 / speed) : 0; return Util.SequenceActivities( diff --git a/OpenRA.Mods.RA/Activities/UnloadCargo.cs b/OpenRA.Mods.RA/Activities/UnloadCargo.cs index 56968ad59e..e4cba01ee2 100644 --- a/OpenRA.Mods.RA/Activities/UnloadCargo.cs +++ b/OpenRA.Mods.RA/Activities/UnloadCargo.cs @@ -79,23 +79,24 @@ namespace OpenRA.Mods.RA.Activities return this; var actor = cargo.Unload(self); - var exitPx = Util.CenterOfCell(exitTile.Value); - var currentPx = Util.CenterOfCell(self.Location); + var exit = exitTile.Value.CenterPosition; + var current = self.Location.CenterPosition; self.World.AddFrameEndTask(w => { - if (actor.Destroyed) return; + if (actor.Destroyed) + return; var mobile = actor.Trait(); - mobile.Facing = Util.GetFacing( (exitPx - currentPx).ToInt2(), mobile.Facing ); + mobile.Facing = Util.GetFacing(exit - current, mobile.Facing ); mobile.SetPosition(actor, exitTile.Value); - mobile.AdjustPxPosition(actor, currentPx); - var speed = mobile.MovementSpeedForCell(actor, exitTile.Value); - var length = speed > 0 ? ((int)(exitPx - currentPx).Length * 3 / speed) : 0; + mobile.AdjustPxPosition(actor, PPos.FromWPos(current)); + var speed = mobile.WorldMovementSpeedForCell(actor, exitTile.Value); + var length = speed > 0 ? ((int)(exit - current).Length * 3 / speed) : 0; w.Add(actor); actor.CancelActivity(); - actor.QueueActivity(new Drag(currentPx, exitPx, length)); + actor.QueueActivity(new Drag(current, exit, length)); actor.QueueActivity(mobile.MoveTo(exitTile.Value, 0)); var rallyPoint = ChooseRallyPoint(actor).Value; diff --git a/OpenRA.Mods.RA/Move/Drag.cs b/OpenRA.Mods.RA/Move/Drag.cs index 9379d8c936..abfaf89392 100755 --- a/OpenRA.Mods.RA/Move/Drag.cs +++ b/OpenRA.Mods.RA/Move/Drag.cs @@ -15,25 +15,25 @@ namespace OpenRA.Mods.RA.Move { public class Drag : Activity { - PPos endLocation; - PPos startLocation; + WPos start, end; int length; int ticks = 0; - public Drag(PPos start, PPos end, int length) + public Drag(WPos start, WPos end, int length) { - startLocation = start; - endLocation = end; + this.start = start; + this.end = end; this.length = length; } public override Activity Tick( Actor self ) { var mobile = self.Trait(); - mobile.PxPosition = length > 1 - ? PPos.Lerp(startLocation, endLocation, ticks, length - 1) - : endLocation; + var pos = length > 1 + ? WPos.Lerp(start, end, ticks, length - 1) + : end; + mobile.PxPosition = PPos.FromWPos(pos); if (++ticks >= length) { mobile.IsMoving = false; @@ -46,7 +46,7 @@ namespace OpenRA.Mods.RA.Move public override IEnumerable GetTargets( Actor self ) { - yield return Target.FromPos(endLocation); + yield return Target.FromPos(PPos.FromWPos(end)); } // Cannot be cancelled diff --git a/OpenRA.Mods.RA/Move/Mobile.cs b/OpenRA.Mods.RA/Move/Mobile.cs index b1c44e96a1..f109367585 100755 --- a/OpenRA.Mods.RA/Move/Mobile.cs +++ b/OpenRA.Mods.RA/Move/Mobile.cs @@ -420,6 +420,11 @@ namespace OpenRA.Mods.RA.Move return (int)(speed / 100); } + public int WorldMovementSpeedForCell(Actor self, CPos cell) + { + return MovementSpeedForCell(self, cell) * 1024 / Game.CellSize; + } + public void AddInfluence() { if (self.IsInWorld) diff --git a/OpenRA.Mods.RA/Production.cs b/OpenRA.Mods.RA/Production.cs index ffdbcf8fdb..d8718b08f9 100755 --- a/OpenRA.Mods.RA/Production.cs +++ b/OpenRA.Mods.RA/Production.cs @@ -50,8 +50,8 @@ namespace OpenRA.Mods.RA public void DoProduction(Actor self, ActorInfo producee, ExitInfo exitinfo) { var exit = self.Location + exitinfo.ExitCellVector; - var spawn = self.Trait().PxPosition + exitinfo.SpawnOffsetVector; - var to = Util.CenterOfCell(exit); + var spawn = (self.Trait().PxPosition + exitinfo.SpawnOffsetVector).ToWPos(0); + var to = exit.CenterPosition; var fi = producee.Traits.Get(); var initialFacing = exitinfo.Facing < 0 ? Util.GetFacing(to - spawn, fi.GetInitialFacing()) : exitinfo.Facing; @@ -66,7 +66,7 @@ namespace OpenRA.Mods.RA // TODO: Move this into an *Init // TODO: We should be adjusting the actual position for aircraft, not just visuals. var teleportable = newUnit.Trait(); - teleportable.AdjustPxPosition(newUnit, spawn); + teleportable.AdjustPxPosition(newUnit, PPos.FromWPos(spawn)); // TODO: Generalize this for non-mobile (e.g. aircraft) too // Remember to update the Enter activity too @@ -74,7 +74,7 @@ namespace OpenRA.Mods.RA if (mobile != null) { // Animate the spawn -> exit transition - var speed = mobile.MovementSpeedForCell(newUnit, exit); + var speed = mobile.WorldMovementSpeedForCell(newUnit, exit); var length = speed > 0 ? (int)((to - spawn).Length * 3 / speed) : 0; newUnit.QueueActivity(new Drag(spawn, to, length)); }