diff --git a/source/simulation2/components/CCmpPosition.cpp b/source/simulation2/components/CCmpPosition.cpp index 83379ff1a2..9a44635976 100644 --- a/source/simulation2/components/CCmpPosition.cpp +++ b/source/simulation2/components/CCmpPosition.cpp @@ -485,22 +485,24 @@ public: float x, z, rotY; GetInterpolatedPosition2D(frameOffset, x, z, rotY); - float y = GetHeightFixed().ToFloat() + Interpolate(0.f, m_LastYDifference.ToFloat(), frameOffset); - - if (forceFloating) + + float baseY = 0; + if (m_RelativeToGround) { - // if the actor has a flag, it shouldn't be serialized, - // so it's handled here separately CmpPtr cmpTerrain(GetSystemEntity()); - CmpPtr cmpWaterManager(GetSystemEntity()); - if (cmpTerrain && cmpWaterManager) + if (cmpTerrain) + baseY = cmpTerrain->GetExactGroundLevel(x, z); + + if (m_Floating || forceFloating) { - float diff = (cmpWaterManager->GetWaterLevel(m_X, m_Z) - cmpTerrain->GetGroundLevel(m_X, m_Z)).ToFloat(); - if (diff > 0.f) - y += diff; + CmpPtr cmpWaterManager(GetSystemEntity()); + if (cmpWaterManager) + baseY = std::max(baseY, cmpWaterManager->GetExactWaterLevel(x, z)); } } + float y = baseY + m_Y.ToFloat() + Interpolate(m_LastYDifference.ToFloat(), 0.f, frameOffset); + CMatrix3D m; // linear interpolation is good enough (for RotX/Z).