Index: source/simulation2/components/CCmpUnitMotion.h =================================================================== --- source/simulation2/components/CCmpUnitMotion.h +++ source/simulation2/components/CCmpUnitMotion.h @@ -28,6 +28,7 @@ #include "simulation2/components/ICmpPosition.h" #include "simulation2/components/ICmpPathfinder.h" #include "simulation2/components/ICmpRangeManager.h" +#include "simulation2/system/TurnManager.h" #include "simulation2/components/ICmpValueModificationManager.h" #include "simulation2/components/ICmpVisual.h" #include "simulation2/helpers/Geometry.h" @@ -39,6 +40,7 @@ #include "graphics/Overlay.h" #include "maths/FixedVector2D.h" #include "ps/CLogger.h" +#include "ps/Game.h" #include "ps/Profile.h" #include "renderer/Scene.h" @@ -1349,7 +1351,6 @@ } else { - out = cmpTargetPosition->GetPosition2D(); // Position is only updated after all units have moved & pushed. // Therefore, we may need to interpolate the target position, depending on when this call takes place during the turn: // - On "Turn Start", we'll check positions directly without interpolation. @@ -1357,16 +1358,13 @@ // (this way, we move where the unit will end up at the end of _this_ turn, making it match on next turn start). // - After movement, we'll call this to request paths & we need to interpolate // (this way, we'll move where the unit ends up in the end of _next_ turn, making it a match in 2 turns). - // TODO: This does not really aim many turns in advance, with orthogonal trajectories it probably should. + // TODO: This does not really aim many turns in advance. If we wish to compute the intersection point we should. CmpPtr cmpUnitMotion(GetSimContext(), moveRequest.m_Entity); CmpPtr cmpUnitMotionManager(GetSystemEntity()); - bool needInterpolation = cmpUnitMotion && cmpUnitMotion->IsMoveRequested() && cmpUnitMotionManager->ComputingMotion(); - if (needInterpolation) - { - // Add predicted movement. - CFixedVector2D tempPos = out + (out - cmpTargetPosition->GetPreviousPosition2D()); - out = tempPos; - } + + out = cmpUnitMotion && cmpUnitMotion->IsMoveRequested() && cmpUnitMotionManager->ComputingMotion() && g_Game && g_Game->GetTurnManager() ? + cmpUnitMotion->EstimateFuturePosition(fixed::FromInt(g_Game->GetTurnManager()->GetLatestTurnLength()) / 1000) : + cmpTargetPosition->GetPosition2D(); } return true; } Index: source/simulation2/system/TurnManager.h =================================================================== --- source/simulation2/system/TurnManager.h +++ source/simulation2/system/TurnManager.h @@ -112,6 +112,11 @@ bool UpdateFastForward(); /** + * Returns the current turn length. + */ + u32 GetLatestTurnLength() const; + + /** * Advance the graphics by a certain time. * @param simFrameLength Length of the previous frame, in simulation seconds * @param realFrameLength Length of the previous frame, in real time seconds Index: source/simulation2/system/TurnManager.cpp =================================================================== --- source/simulation2/system/TurnManager.cpp +++ source/simulation2/system/TurnManager.cpp @@ -192,6 +192,11 @@ return true; } +u32 CTurnManager::GetLatestTurnLength() const +{ + return m_TurnLength; +} + void CTurnManager::Interpolate(float simFrameLength, float realFrameLength) { // TODO: using m_TurnLength might be a bit dodgy when length changes - maybe