From 8d83580b7581520b6d0baa916dd8546838b25b39 Mon Sep 17 00:00:00 2001 From: Joonas Rikkonen Date: Wed, 29 Aug 2018 13:38:56 +0300 Subject: [PATCH] Docking port fixes again. Closes #551 - Non-saveable entities aren't removed from the linkedTo-list during saving, because that causes gaps to become unlinked with the hulls between docking ports when starting a campaign round. - Hull rechecks are disabled on docking port gaps, because moving linked subs into place may cause the gaps to become unlinked if they're positioned in a certain way (for example in some subs the hulls between the docking ports end up inside the gap). - Dockingports only connect the waypoints linked to their gap to each other, instead of every waypoint that happens to be inside the gap. --- .../Source/Items/Components/DockingPort.cs | 56 ++++++++----------- .../BarotraumaShared/Source/Items/Item.cs | 11 ++-- Barotrauma/BarotraumaShared/Source/Map/Gap.cs | 10 +++- .../Source/Map/LinkedSubmarine.cs | 6 -- .../BarotraumaShared/Source/Map/Submarine.cs | 11 +--- .../BarotraumaShared/Source/Map/WayPoint.cs | 1 + 6 files changed, 39 insertions(+), 56 deletions(-) diff --git a/Barotrauma/BarotraumaShared/Source/Items/Components/DockingPort.cs b/Barotrauma/BarotraumaShared/Source/Items/Components/DockingPort.cs index b87de4e83..9b9b4c888 100644 --- a/Barotrauma/BarotraumaShared/Source/Items/Components/DockingPort.cs +++ b/Barotrauma/BarotraumaShared/Source/Items/Components/DockingPort.cs @@ -201,22 +201,16 @@ namespace Barotrauma.Items.Components Math.Sign(dockingTarget.item.WorldPosition.X - item.WorldPosition.X) : Math.Sign(dockingTarget.item.WorldPosition.Y - item.WorldPosition.Y); dockingTarget.dockingDir = -dockingDir; - - foreach (WayPoint wp in WayPoint.WayPointList) + if (door != null && dockingTarget.door != null) { - if (wp.Submarine != item.Submarine || wp.SpawnType != SpawnType.Path) continue; + WayPoint myWayPoint = WayPoint.WayPointList.Find(wp => door.LinkedGap == wp.ConnectedGap); + WayPoint targetWayPoint = WayPoint.WayPointList.Find(wp => dockingTarget.door.LinkedGap == wp.ConnectedGap); - if (!Submarine.RectContains(item.Rect, wp.Position)) continue; - - foreach (WayPoint wp2 in WayPoint.WayPointList) + if (myWayPoint != null && targetWayPoint != null) { - if (wp2.Submarine != dockingTarget.item.Submarine || wp2.SpawnType != SpawnType.Path) continue; - - if (!Submarine.RectContains(dockingTarget.item.Rect, wp2.Position)) continue; - - wp.linkedTo.Add(wp2); - wp2.linkedTo.Add(wp); + myWayPoint.linkedTo.Add(targetWayPoint); + targetWayPoint.linkedTo.Add(myWayPoint); } } @@ -498,29 +492,31 @@ namespace Barotrauma.Items.Components for (int i = 0; i < 2; i++) { - Gap gap = i == 0 ? door?.LinkedGap : dockingTarget?.door?.LinkedGap; - if (gap == null || gap.linkedTo.Count == 2) continue; - + Gap doorGap = i == 0 ? door?.LinkedGap : dockingTarget?.door?.LinkedGap; + if (doorGap == null) continue; + doorGap.DisableHullRechecks = true; + if (doorGap.linkedTo.Count >= 2) continue; + if (IsHorizontal) { if (item.WorldPosition.X < dockingTarget.item.WorldPosition.X) { - if (!gap.linkedTo.Contains(hulls[0])) gap.linkedTo.Add(hulls[0]); + if (!doorGap.linkedTo.Contains(hulls[0])) doorGap.linkedTo.Add(hulls[0]); } else { - if (!gap.linkedTo.Contains(hulls[1])) gap.linkedTo.Add(hulls[1]); + if (!doorGap.linkedTo.Contains(hulls[1])) doorGap.linkedTo.Add(hulls[1]); } } else { if (item.WorldPosition.Y < dockingTarget.item.WorldPosition.Y) { - if (!gap.linkedTo.Contains(hulls[0])) gap.linkedTo.Add(hulls[0]); + if (!doorGap.linkedTo.Contains(hulls[0])) doorGap.linkedTo.Add(hulls[0]); } else { - if (!gap.linkedTo.Contains(hulls[1])) gap.linkedTo.Add(hulls[1]); + if (!doorGap.linkedTo.Contains(hulls[1])) doorGap.linkedTo.Add(hulls[1]); } } } @@ -536,25 +532,19 @@ namespace Barotrauma.Items.Components dockingTarget.item.Submarine.DockedTo.Remove(item.Submarine); item.Submarine.DockedTo.Remove(dockingTarget.item.Submarine); - - //remove all waypoint links between this sub and the dockingtarget - foreach (WayPoint wp in WayPoint.WayPointList) + + if (door != null && dockingTarget.door != null) { - if (wp.Submarine != item.Submarine || wp.SpawnType != SpawnType.Path) continue; + WayPoint myWayPoint = WayPoint.WayPointList.Find(wp => door.LinkedGap == wp.ConnectedGap); + WayPoint targetWayPoint = WayPoint.WayPointList.Find(wp => dockingTarget.door.LinkedGap == wp.ConnectedGap); - for (int i = wp.linkedTo.Count - 1; i >= 0; i--) + if (myWayPoint != null && targetWayPoint != null) { - var wp2 = wp.linkedTo[i] as WayPoint; - if (wp2 == null) continue; - - if (wp.Submarine == dockingTarget.item.Submarine) - { - wp.linkedTo.RemoveAt(i); - wp2.linkedTo.Remove(wp); - } + myWayPoint.linkedTo.Remove(targetWayPoint); + targetWayPoint.linkedTo.Remove(myWayPoint); } } - + item.linkedTo.Clear(); docked = false; diff --git a/Barotrauma/BarotraumaShared/Source/Items/Item.cs b/Barotrauma/BarotraumaShared/Source/Items/Item.cs index c46104937..17dd9133d 100644 --- a/Barotrauma/BarotraumaShared/Source/Items/Item.cs +++ b/Barotrauma/BarotraumaShared/Source/Items/Item.cs @@ -1939,16 +1939,15 @@ namespace Barotrauma (int)(rect.X - Submarine.HiddenSubPosition.X) + "," + (int)(rect.Y - Submarine.HiddenSubPosition.Y))); } - + if (linkedTo != null && linkedTo.Count > 0) { - string[] linkedToIDs = new string[linkedTo.Count]; - - for (int i = 0; i < linkedTo.Count; i++) + var saveableLinked = linkedTo.Where(l => l.ShouldBeSaved).ToList(); + string[] linkedToIDs = new string[saveableLinked.Count]; + for (int i = 0; i < saveableLinked.Count; i++) { - linkedToIDs[i] = linkedTo[i].ID.ToString(); + linkedToIDs[i] = saveableLinked[i].ID.ToString(); } - element.Add(new XAttribute("linked", string.Join(",", linkedToIDs))); } diff --git a/Barotrauma/BarotraumaShared/Source/Map/Gap.cs b/Barotrauma/BarotraumaShared/Source/Map/Gap.cs index 5f67267c8..140d57fae 100644 --- a/Barotrauma/BarotraumaShared/Source/Map/Gap.cs +++ b/Barotrauma/BarotraumaShared/Source/Map/Gap.cs @@ -135,13 +135,21 @@ namespace Barotrauma { base.Move(amount); - FindHulls(); + if (!DisableHullRechecks) FindHulls(); } public static void UpdateHulls() { foreach (Gap g in GapList) { + for (int i = g.linkedTo.Count - 1; i >= 0; i--) + { + if (g.linkedTo[i].Removed) + { + g.linkedTo.RemoveAt(i); + } + } + if (g.DisableHullRechecks) continue; g.FindHulls(); } diff --git a/Barotrauma/BarotraumaShared/Source/Map/LinkedSubmarine.cs b/Barotrauma/BarotraumaShared/Source/Map/LinkedSubmarine.cs index 75a9b39f9..79f4c679d 100644 --- a/Barotrauma/BarotraumaShared/Source/Map/LinkedSubmarine.cs +++ b/Barotrauma/BarotraumaShared/Source/Map/LinkedSubmarine.cs @@ -261,22 +261,16 @@ namespace Barotrauma if (saveElement.Attribute("pos") != null) saveElement.Attribute("pos").Remove(); saveElement.Add(new XAttribute("pos", XMLExtensions.Vector2ToString(Position - Submarine.HiddenSubPosition))); - - var linkedPort = linkedTo.FirstOrDefault(lt => (lt is Item) && ((Item)lt).GetComponent() != null); if (linkedPort != null) { if (saveElement.Attribute("linkedto") != null) saveElement.Attribute("linkedto").Remove(); - saveElement.Add(new XAttribute("linkedto", linkedPort.ID)); } } else { - saveElement = new XElement("LinkedSubmarine"); - - sub.SaveToXElement(saveElement); } diff --git a/Barotrauma/BarotraumaShared/Source/Map/Submarine.cs b/Barotrauma/BarotraumaShared/Source/Map/Submarine.cs index 49612ca16..9aa51ee67 100644 --- a/Barotrauma/BarotraumaShared/Source/Map/Submarine.cs +++ b/Barotrauma/BarotraumaShared/Source/Map/Submarine.cs @@ -1250,16 +1250,7 @@ namespace Barotrauma element.Add(new XAttribute("recommendedcrewsizemax", RecommendedCrewSizeMax)); element.Add(new XAttribute("recommendedcrewexperience", RecommendedCrewExperience ?? "")); element.Add(new XAttribute("compatiblecontentpackages", string.Join(", ", CompatibleContentPackages))); - - foreach (MapEntity e in MapEntity.mapEntityList) - { - if (e.linkedTo == null) continue; - for (int i = e.linkedTo.Count - 1; i >= 0; i--) - { - if (!e.linkedTo[i].ShouldBeSaved) e.linkedTo.RemoveAt(i); - } - } - + foreach (MapEntity e in MapEntity.mapEntityList) { if (e.Submarine != this || !e.ShouldBeSaved) continue; diff --git a/Barotrauma/BarotraumaShared/Source/Map/WayPoint.cs b/Barotrauma/BarotraumaShared/Source/Map/WayPoint.cs index 533219f87..46d9a7d05 100644 --- a/Barotrauma/BarotraumaShared/Source/Map/WayPoint.cs +++ b/Barotrauma/BarotraumaShared/Source/Map/WayPoint.cs @@ -636,6 +636,7 @@ namespace Barotrauma int i = 0; foreach (MapEntity e in linkedTo) { + if (!e.ShouldBeSaved) continue; element.Add(new XAttribute("linkedto" + i, e.ID)); i += 1; }