From 0159cc3f254fa712de3f7340980285b4ea04cb5e Mon Sep 17 00:00:00 2001 From: Joonas Rikkonen Date: Mon, 7 Aug 2017 23:14:25 +0300 Subject: [PATCH] Submarine position syncing fix: The position correction logic only moved the submarine that's being synced and the subs docked directly to it, but not the subs docked to the docked subs. This caused severe physics issues with some specific subs, for example mirrored HSE Kullervo Carriers tended to get launched downwards at a game-breaking speed. --- .../BarotraumaShared/Source/Map/Submarine.cs | 32 +++++++++++++++++-- .../Source/Map/SubmarineBody.cs | 10 +++--- 2 files changed, 33 insertions(+), 9 deletions(-) diff --git a/Barotrauma/BarotraumaShared/Source/Map/Submarine.cs b/Barotrauma/BarotraumaShared/Source/Map/Submarine.cs index 2f2496998..cc859c440 100644 --- a/Barotrauma/BarotraumaShared/Source/Map/Submarine.cs +++ b/Barotrauma/BarotraumaShared/Source/Map/Submarine.cs @@ -306,10 +306,13 @@ namespace Barotrauma Rectangle dockedBorders = Borders; dockedBorders.Y -= dockedBorders.Height; - foreach (Submarine dockedSub in DockedTo) + var connectedSubs = GetConnectedSubs(); + + foreach (Submarine dockedSub in connectedSubs) { - Vector2 diff = dockedSub.Submarine == this ? dockedSub.WorldPosition : dockedSub.WorldPosition - WorldPosition; - + if (dockedSub == this) continue; + + Vector2 diff = dockedSub.Submarine == this ? dockedSub.WorldPosition : dockedSub.WorldPosition - WorldPosition; Rectangle dockedSubBorders = dockedSub.Borders; dockedSubBorders.Y -= dockedSubBorders.Height; @@ -322,6 +325,29 @@ namespace Barotrauma return dockedBorders; } + /// + /// Returns a list of all submarines that are connected to this one via docking ports. + /// + public List GetConnectedSubs() + { + List connectedSubs = new List(); + connectedSubs.Add(this); + GetConnectedSubsRecursive(connectedSubs); + + return connectedSubs; + } + + private void GetConnectedSubsRecursive(List subs) + { + foreach (Submarine dockedSub in DockedTo) + { + if (subs.Contains(dockedSub)) continue; + + subs.Add(dockedSub); + dockedSub.GetConnectedSubsRecursive(subs); + } + } + public Vector2 FindSpawnPos(Vector2 spawnPos) { Rectangle dockedBorders = GetDockedBorders(); diff --git a/Barotrauma/BarotraumaShared/Source/Map/SubmarineBody.cs b/Barotrauma/BarotraumaShared/Source/Map/SubmarineBody.cs index 824345fa1..75b91f7dd 100644 --- a/Barotrauma/BarotraumaShared/Source/Map/SubmarineBody.cs +++ b/Barotrauma/BarotraumaShared/Source/Map/SubmarineBody.cs @@ -193,12 +193,11 @@ namespace Barotrauma Body.CorrectPosition(memPos, deltaTime, out newVelocity, out newPosition); Vector2 moveAmount = ConvertUnits.ToDisplayUnits(newPosition - Body.SimPosition); - List subsToMove = new List() { this.submarine }; - subsToMove.AddRange(submarine.DockedTo); - - foreach (Submarine dockedSub in submarine.DockedTo) + List subsToMove = submarine.GetConnectedSubs(); + foreach (Submarine dockedSub in subsToMove) { - //clear the position buffer of the docked sub to prevent unnecessary position corrections + if (dockedSub == submarine) continue; + //clear the position buffer of the docked subs to prevent unnecessary position corrections dockedSub.SubBody.memPos.Clear(); } @@ -213,7 +212,6 @@ namespace Barotrauma } bool displace = moveAmount.Length() > 100.0f; - foreach (Submarine sub in subsToMove) { sub.PhysicsBody.SetTransform(sub.PhysicsBody.SimPosition + ConvertUnits.ToSimUnits(moveAmount), 0.0f);