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.
This commit is contained in:
Joonas Rikkonen
2017-08-07 23:14:25 +03:00
parent d0a1a8413b
commit 0159cc3f25
2 changed files with 33 additions and 9 deletions
@@ -306,10 +306,13 @@ namespace Barotrauma
Rectangle dockedBorders = Borders; Rectangle dockedBorders = Borders;
dockedBorders.Y -= dockedBorders.Height; 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; Rectangle dockedSubBorders = dockedSub.Borders;
dockedSubBorders.Y -= dockedSubBorders.Height; dockedSubBorders.Y -= dockedSubBorders.Height;
@@ -322,6 +325,29 @@ namespace Barotrauma
return dockedBorders; return dockedBorders;
} }
/// <summary>
/// Returns a list of all submarines that are connected to this one via docking ports.
/// </summary>
public List<Submarine> GetConnectedSubs()
{
List<Submarine> connectedSubs = new List<Submarine>();
connectedSubs.Add(this);
GetConnectedSubsRecursive(connectedSubs);
return connectedSubs;
}
private void GetConnectedSubsRecursive(List<Submarine> subs)
{
foreach (Submarine dockedSub in DockedTo)
{
if (subs.Contains(dockedSub)) continue;
subs.Add(dockedSub);
dockedSub.GetConnectedSubsRecursive(subs);
}
}
public Vector2 FindSpawnPos(Vector2 spawnPos) public Vector2 FindSpawnPos(Vector2 spawnPos)
{ {
Rectangle dockedBorders = GetDockedBorders(); Rectangle dockedBorders = GetDockedBorders();
@@ -193,12 +193,11 @@ namespace Barotrauma
Body.CorrectPosition(memPos, deltaTime, out newVelocity, out newPosition); Body.CorrectPosition(memPos, deltaTime, out newVelocity, out newPosition);
Vector2 moveAmount = ConvertUnits.ToDisplayUnits(newPosition - Body.SimPosition); Vector2 moveAmount = ConvertUnits.ToDisplayUnits(newPosition - Body.SimPosition);
List<Submarine> subsToMove = new List<Submarine>() { this.submarine }; List<Submarine> subsToMove = submarine.GetConnectedSubs();
subsToMove.AddRange(submarine.DockedTo); foreach (Submarine dockedSub in subsToMove)
foreach (Submarine dockedSub in submarine.DockedTo)
{ {
//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(); dockedSub.SubBody.memPos.Clear();
} }
@@ -213,7 +212,6 @@ namespace Barotrauma
} }
bool displace = moveAmount.Length() > 100.0f; bool displace = moveAmount.Length() > 100.0f;
foreach (Submarine sub in subsToMove) foreach (Submarine sub in subsToMove)
{ {
sub.PhysicsBody.SetTransform(sub.PhysicsBody.SimPosition + ConvertUnits.ToSimUnits(moveAmount), 0.0f); sub.PhysicsBody.SetTransform(sub.PhysicsBody.SimPosition + ConvertUnits.ToSimUnits(moveAmount), 0.0f);