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; } } }