diff --git a/Subsurface/Source/Items/Components/DockingPort.cs b/Subsurface/Source/Items/Components/DockingPort.cs index 83cd58e32..5215b232b 100644 --- a/Subsurface/Source/Items/Components/DockingPort.cs +++ b/Subsurface/Source/Items/Components/DockingPort.cs @@ -345,8 +345,6 @@ namespace Barotrauma.Items.Components public override void Update(float deltaTime, Camera cam) { - - if (dockingTarget == null) { dockingState = MathHelper.Lerp(dockingState, 0.0f, deltaTime * 10.0f); @@ -411,7 +409,7 @@ namespace Barotrauma.Items.Components drawPos - Vector2.UnitX * (rect.Width / 2 * dockingState), new Rectangle( rect.X, rect.Y, - (int)(rect.Width / 2 * dockingState), rect.Height), Color.Red); + (int)(rect.Width / 2 * dockingState), rect.Height), Color.White); } } else @@ -433,7 +431,7 @@ namespace Barotrauma.Items.Components drawPos - Vector2.UnitY * (rect.Height / 2 * dockingState), new Rectangle( rect.X, rect.Y, - rect.Width, (int)(rect.Height / 2 * dockingState)), Color.Red); + rect.Width, (int)(rect.Height / 2 * dockingState)), Color.White); } } } @@ -456,6 +454,8 @@ namespace Barotrauma.Items.Components public override void ReceiveSignal(int stepsTaken, string signal, Connection connection, Item sender, float power = 0.0f) { + if (GameMain.Client != null) return; + switch (connection.Name) { case "toggle": @@ -466,6 +466,50 @@ namespace Barotrauma.Items.Components Docked = signal != "0"; break; } + + item.NewComponentEvent(this, false, true); + } + + public override bool FillNetworkData(Networking.NetworkEventType type, Lidgren.Network.NetBuffer message) + { + message.Write(docked); + + if (docked) + { + message.Write(dockingTarget.item.ID); + } + + return true; + } + + public override void ReadNetworkData(Networking.NetworkEventType type, Lidgren.Network.NetIncomingMessage message, float sendingTime) + { + bool isDocked = message.ReadBoolean(); + + if (isDocked) + { + ushort dockingTargetID = message.ReadUInt16(); + Entity targetEntity = Entity.FindEntityByID(dockingTargetID); + if (targetEntity == null || !(targetEntity is Item)) + { + DebugConsole.ThrowError("Invalid docking port network event (can't dock to "+targetEntity.ToString()+")"); + return; + } + + dockingTarget = (targetEntity as Item).GetComponent(); + + if (dockingTarget == null) + { + DebugConsole.ThrowError("Invalid docking port network event ("+targetEntity+" doesn't have a docking port component)"); + return; + } + + Dock(dockingTarget); + } + else + { + Undock(); + } } } } diff --git a/Subsurface/Source/Items/Components/Signal/Wire.cs b/Subsurface/Source/Items/Components/Signal/Wire.cs index a1bbe5540..c3372dee5 100644 --- a/Subsurface/Source/Items/Components/Signal/Wire.cs +++ b/Subsurface/Source/Items/Components/Signal/Wire.cs @@ -204,10 +204,17 @@ namespace Barotrauma.Items.Components // position.Y += item.CurrentHull.Rect.Y - item.CurrentHull.Rect.Height; //} + Submarine sub = null; if (connections[0] != null && connections[0].Item.Submarine != null) sub = connections[0].Item.Submarine; if (connections[1] != null && connections[1].Item.Submarine != null) sub = connections[1].Item.Submarine; + if (item.Submarine != sub) + { + ClearConnections(); + Nodes.Clear(); + } + newNodePos = RoundNode(item.Position, item.CurrentHull) - sub.HiddenSubPosition; //if (Vector2.Distance(position, nodes[nodes.Count - 1]) > nodeDistance*10) diff --git a/Subsurface/Source/Map/Lights/LightSource.cs b/Subsurface/Source/Map/Lights/LightSource.cs index 0542cd359..5412b025e 100644 --- a/Subsurface/Source/Map/Lights/LightSource.cs +++ b/Subsurface/Source/Map/Lights/LightSource.cs @@ -223,6 +223,8 @@ namespace Barotrauma.Lights //light and convexhull are inside different subs else { + if (sub.DockedTo.Contains(ParentSub) && !NeedsHullUpdate) return list; + lightPos -= (sub.Position - ParentSub.Position); Rectangle subBorders = sub.Borders; @@ -233,6 +235,7 @@ namespace Barotrauma.Lights var fullChList = ConvexHull.HullLists.Find(x => x.Submarine == sub); list = fullChList.List.FindAll(ch => MathUtils.CircleIntersectsRectangle(lightPos, range, ch.BoundingBox)); + chList.List = list; } } diff --git a/Subsurface/Source/Map/LinkedSubmarine.cs b/Subsurface/Source/Map/LinkedSubmarine.cs index 90286dfb0..768ffec13 100644 --- a/Subsurface/Source/Map/LinkedSubmarine.cs +++ b/Subsurface/Source/Map/LinkedSubmarine.cs @@ -4,6 +4,7 @@ using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Input; using System; using System.Collections.Generic; +using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; @@ -25,7 +26,7 @@ namespace Barotrauma { System.Diagnostics.Debug.Assert(Submarine.MainSub != null); - LinkedSubmarine.Create(Submarine.MainSub, mainSub.FilePath, rect.Location.ToVector2()); + LinkedSubmarine.CreateDummy(Submarine.MainSub, mainSub.FilePath, rect.Location.ToVector2()); } } @@ -56,20 +57,21 @@ namespace Barotrauma InsertToList(); } - public static LinkedSubmarine Create(Submarine mainSub, string filePath, Vector2 position) + public static LinkedSubmarine CreateDummy(Submarine mainSub, string filePath, Vector2 position) { - LinkedSubmarine sl = new LinkedSubmarine(mainSub); - sl.filePath = filePath; - XDocument doc = Submarine.OpenFile(filePath); if (doc == null || doc.Root == null) return null; - sl.GenerateWallVertices(doc.Root); + LinkedSubmarine sl = CreateDummy(mainSub, doc.Root, position); + sl.filePath = filePath; - //for (int i = 0; i < sl.wallVertices.Count; i++) - //{ - // sl.wallVertices[i] = sl.wallVertices[i] += position; - //} + return sl; + } + + public static LinkedSubmarine CreateDummy(Submarine mainSub, XElement element, Vector2 position) + { + LinkedSubmarine sl = new LinkedSubmarine(mainSub); + sl.GenerateWallVertices(element); sl.Rect = new Rectangle( (int)sl.wallVertices.Min(v => v.X + position.X), @@ -166,12 +168,22 @@ namespace Barotrauma new GUITextBlock(new Rectangle(0, 0, 100, 20), "Linked submarine", GUI.Style, Alignment.TopLeft, Alignment.TopLeft, editingHUD, false, GUI.LargeFont); + var pathBox = new GUITextBox(new Rectangle(10,30,300,20), GUI.Style, editingHUD); + pathBox.Font = GUI.SmallFont; + pathBox.Text = filePath; + + var reloadButton = new GUIButton(new Rectangle(320,30,80,20), "Refresh", GUI.Style, editingHUD); + reloadButton.OnClicked = Reload; + reloadButton.UserData = pathBox; + + reloadButton.ToolTip = "Reload the linked submarine from the specified file"; + y += 20; if (!inGame) { new GUITextBlock(new Rectangle(0, 0, 0, 20), "Hold space to link to a docking port", - GUI.Style, Alignment.TopRight, Alignment.TopRight, editingHUD).Font = GUI.SmallFont; + GUI.Style, Alignment.TopRight, Alignment.TopRight, editingHUD, false, GUI.SmallFont); y += 25; } @@ -179,6 +191,31 @@ namespace Barotrauma } + private bool Reload(GUIButton button, object obj) + { + var pathBox = obj as GUITextBox; + + if (!File.Exists(pathBox.Text)) + { + new GUIMessageBox("Error", "Submarine file ''" + pathBox.Text + "'' not found!"); + pathBox.Flash(Color.Red); + pathBox.Text = filePath; + return false; + } + + XDocument doc = Submarine.OpenFile(pathBox.Text); + if (doc == null || doc.Root == null) return false; + + pathBox.Flash(Color.Green); + + GenerateWallVertices(doc.Root); + saveElement = doc.Root; + + filePath = pathBox.Text; + + return true; + } + private void GenerateWallVertices(XElement rootElement) { List points = new List(); @@ -210,16 +247,27 @@ namespace Barotrauma if (sub == null) { - var doc = Submarine.OpenFile(filePath); - saveElement = doc.Root; + if (this.saveElement == null) + { + var doc = Submarine.OpenFile(filePath); + saveElement = doc.Root; - saveElement.Name = "LinkedSubmarine"; + saveElement.Name = "LinkedSubmarine"; - saveElement.Add(new XAttribute("filepath", filePath)); + saveElement.Add(new XAttribute("filepath", filePath)); + } + else + { + saveElement = this.saveElement; + } + + 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)); } } @@ -231,7 +279,8 @@ namespace Barotrauma sub.SaveToXElement(saveElement); } - + + if (saveElement.Attribute("pos") != null) saveElement.Attribute("pos").Remove(); saveElement.Add(new XAttribute("pos", ToolBox.Vector2ToString(Position - Submarine.HiddenSubPosition))); parentElement.Add(saveElement); @@ -247,9 +296,10 @@ namespace Barotrauma if (Screen.Selected == GameMain.EditMapScreen) { - string filePath = ToolBox.GetAttributeString(element, "filepath", ""); + //string filePath = ToolBox.GetAttributeString(element, "filepath", ""); - linkedSub = Create(submarine, filePath, pos); + linkedSub = CreateDummy(submarine, element, pos); + linkedSub.saveElement = element; } else { @@ -259,6 +309,8 @@ namespace Barotrauma linkedSub.rect.Location = pos.ToPoint(); } + linkedSub.filePath = ToolBox.GetAttributeString(element, "filepath", ""); + string linkedToString = ToolBox.GetAttributeString(element, "linkedto", ""); if (linkedToString != "") { @@ -273,7 +325,7 @@ namespace Barotrauma public override void OnMapLoaded() { - if (saveElement == null) return; + if (Screen.Selected == GameMain.EditMapScreen) return; sub = Submarine.Load(saveElement, false); sub.SetPosition(WorldPosition - Submarine.WorldPosition); @@ -281,30 +333,29 @@ namespace Barotrauma var linkedItem = linkedTo.FirstOrDefault(lt => (lt is Item) && ((Item)lt).GetComponent() != null); - if (linkedItem != null) + if (linkedItem == null) return; + + var linkedPort = ((Item)linkedItem).GetComponent(); + + DockingPort myPort = null; + float closestDistance = 0.0f; + + foreach (DockingPort port in DockingPort.list) { - var linkedPort = ((Item)linkedItem).GetComponent(); + if (port.Item.Submarine != sub || port.IsHorizontal != linkedPort.IsHorizontal) continue; - DockingPort myPort = null; - float closestDistance = 0.0f; - - foreach (DockingPort port in DockingPort.list) + float dist = Vector2.Distance(port.Item.WorldPosition, linkedPort.Item.WorldPosition); + if (myPort == null || dist < closestDistance) { - if (port.Item.Submarine != sub || port.IsHorizontal != linkedPort.IsHorizontal) continue; - - float dist = Vector2.Distance(port.Item.WorldPosition, linkedPort.Item.WorldPosition); - if (myPort == null || dist < closestDistance) - { - myPort = port; - closestDistance = dist; - } - } - - if (myPort != null) - { - myPort.Dock(linkedPort); + myPort = port; + closestDistance = dist; } } + + if (myPort != null) + { + myPort.Dock(linkedPort); + } } } } diff --git a/Subsurface/Source/Networking/GameServer.cs b/Subsurface/Source/Networking/GameServer.cs index 2be79e8bb..190e8ed04 100644 --- a/Subsurface/Source/Networking/GameServer.cs +++ b/Subsurface/Source/Networking/GameServer.cs @@ -395,6 +395,9 @@ namespace Barotrauma.Networking { foreach (Submarine sub in Submarine.Loaded) { + //no need to send position updates for submarines that are docked to mainsub + if (sub != Submarine.MainSub && sub.DockedTo.Contains(Submarine.MainSub)) continue; + new NetworkEvent(sub.ID, false); } }