From 40c28a11dee7f6934c2b8c5d02a4aa5d31a91094 Mon Sep 17 00:00:00 2001 From: Regalis Date: Tue, 13 Dec 2016 23:11:13 +0200 Subject: [PATCH] Docked subs are forced to correct positions during loading and the docking is "locked" (subs won't get stuck inside each other even if the linked sub is placed incorrectly in the editor) --- .../Source/Items/Components/DockingPort.cs | 76 +++++++++++++------ Subsurface/Source/Map/LinkedSubmarine.cs | 45 ++++++++--- 2 files changed, 89 insertions(+), 32 deletions(-) diff --git a/Subsurface/Source/Items/Components/DockingPort.cs b/Subsurface/Source/Items/Components/DockingPort.cs index 4ebbda948..25564ca60 100644 --- a/Subsurface/Source/Items/Components/DockingPort.cs +++ b/Subsurface/Source/Items/Components/DockingPort.cs @@ -44,6 +44,12 @@ namespace Barotrauma.Items.Components private bool docked; + public int DockingDir + { + get { return dockingDir; } + set { dockingDir = value; } + } + [HasDefaultValue("32.0,32.0", false)] public string DistanceTolerance { @@ -177,8 +183,9 @@ namespace Barotrauma.Items.Components dockingDir = IsHorizontal ? Math.Sign(dockingTarget.item.WorldPosition.X - item.WorldPosition.X) : - Math.Sign(item.WorldPosition.Y - dockingTarget.item.WorldPosition.Y); + Math.Sign(dockingTarget.item.WorldPosition.Y - item.WorldPosition.Y); dockingTarget.dockingDir = -dockingDir; + foreach (WayPoint wp in WayPoint.WayPointList) { @@ -200,12 +207,46 @@ namespace Barotrauma.Items.Components CreateJoint(false); } + public void Lock() + { + if (dockingTarget==null) + { + DebugConsole.ThrowError("Error - attempted to lock a docking port that's not connected to anything"); + return; + } + else if (joint is WeldJoint) + { + DebugConsole.ThrowError("Error - attempted to lock a docking port that's already locked"); + return; + } + + dockingDir = IsHorizontal ? + Math.Sign(dockingTarget.item.WorldPosition.X - item.WorldPosition.X) : + Math.Sign(dockingTarget.item.WorldPosition.Y - item.WorldPosition.Y); + dockingTarget.dockingDir = -dockingDir; + + GameMain.World.RemoveJoint(joint); + + PlaySound(ActionType.OnSecondaryUse, item.WorldPosition); + + ConnectWireBetweenPorts(); + + CreateJoint(true); + + if (!item.linkedTo.Any(e => e is Hull) && !dockingTarget.item.linkedTo.Any(e => e is Hull)) + { + CreateHull(); + + item.NewComponentEvent(this, false, true); + } + } + private void CreateJoint(bool useWeldJoint) { Vector2 offset = (IsHorizontal ? - Vector2.UnitX * Math.Sign(dockingTarget.item.WorldPosition.X - item.WorldPosition.X) : - Vector2.UnitY * Math.Sign(dockingTarget.item.WorldPosition.Y - item.WorldPosition.Y)); + Vector2.UnitX * dockingDir : + Vector2.UnitY * dockingDir); offset *= DockedDistance * 0.5f; Vector2 pos1 = item.WorldPosition + offset; @@ -500,25 +541,12 @@ namespace Barotrauma.Items.Components if (joint is DistanceJoint) { item.SendSignal(0, "0", "state_out"); + dockingState = MathHelper.Lerp(dockingState, 0.5f, deltaTime * 10.0f); if (Vector2.Distance(joint.WorldAnchorA, joint.WorldAnchorB) < 0.05f) { - GameMain.World.RemoveJoint(joint); - - PlaySound(ActionType.OnSecondaryUse, item.WorldPosition); - - ConnectWireBetweenPorts(); - - CreateJoint(true); - - if (!item.linkedTo.Any(e => e is Hull) && !dockingTarget.item.linkedTo.Any(e => e is Hull)) - { - CreateHull(); - - item.NewComponentEvent(this, false, true); - } + Lock(); } - dockingState = MathHelper.Lerp(dockingState, 0.5f, deltaTime * 10.0f); } else { @@ -612,12 +640,14 @@ namespace Barotrauma.Items.Components if (!item.linkedTo.Any()) return; - foreach (MapEntity entity in item.linkedTo) + List linked = new List(item.linkedTo); + foreach (MapEntity entity in linked) { var hull = entity as Hull; if (hull != null) { hull.Remove(); + item.linkedTo.Remove(hull); continue; } @@ -625,6 +655,7 @@ namespace Barotrauma.Items.Components if (gap != null) { gap.Remove(); + gap.linkedTo.Remove(hull); continue; } @@ -632,10 +663,11 @@ namespace Barotrauma.Items.Components if (linkedItem == null) continue; var dockingPort = linkedItem.GetComponent(); - if (dockingPort != null) dockingTarget = dockingPort; + if (dockingPort != null) + { + Dock(dockingPort); + } } - - item.linkedTo.Clear(); } public override void ReceiveSignal(int stepsTaken, string signal, Connection connection, Item sender, float power = 0.0f) diff --git a/Subsurface/Source/Map/LinkedSubmarine.cs b/Subsurface/Source/Map/LinkedSubmarine.cs index 856a65f65..631f76248 100644 --- a/Subsurface/Source/Map/LinkedSubmarine.cs +++ b/Subsurface/Source/Map/LinkedSubmarine.cs @@ -405,19 +405,29 @@ namespace Barotrauma } else { - sub.SetPosition(WorldPosition - Submarine.WorldPosition); - sub.Submarine = Submarine; + sub.SetPosition(WorldPosition); } - - var linkedItem = linkedTo.FirstOrDefault(lt => (lt is Item) && ((Item)lt).GetComponent() != null); - if (linkedItem == null) return; - - var linkedPort = ((Item)linkedItem).GetComponent(); + DockingPort linkedPort = null; DockingPort myPort = null; - float closestDistance = 0.0f; + + MapEntity linkedItem = linkedTo.FirstOrDefault(lt => (lt is Item) && ((Item)lt).GetComponent() != null); + if (linkedItem == null) + { + linkedPort = DockingPort.list.Find(dp => dp.DockingTarget != null && dp.DockingTarget.Item.Submarine == sub); + } + else + { + linkedPort = ((Item)linkedItem).GetComponent(); + } + if (linkedPort == null) + { + return; + } + + float closestDistance = 0.0f; foreach (DockingPort port in DockingPort.list) { if (port.Item.Submarine != sub || port.IsHorizontal != linkedPort.IsHorizontal) continue; @@ -432,8 +442,23 @@ namespace Barotrauma if (myPort != null) { - myPort.DockingTarget = linkedPort; - } + Vector2 portDiff = myPort.Item.WorldPosition - sub.WorldPosition; + Vector2 offset = (myPort.IsHorizontal ? + Vector2.UnitX * Math.Sign(linkedPort.Item.WorldPosition.X - myPort.Item.WorldPosition.X) : + Vector2.UnitY * Math.Sign(linkedPort.Item.WorldPosition.Y - myPort.Item.WorldPosition.Y)); + offset *= myPort.DockedDistance; + + sub.SetPosition( + (linkedPort.Item.WorldPosition - portDiff) + - offset); + + + myPort.Dock(linkedPort); + myPort.Lock(); + } + + sub.SetPosition(sub.WorldPosition - Submarine.WorldPosition); + sub.Submarine = Submarine; } } }