diff --git a/Barotrauma/BarotraumaClient/Source/DebugConsole.cs b/Barotrauma/BarotraumaClient/Source/DebugConsole.cs index 539531cd2..fcaf6de3f 100644 --- a/Barotrauma/BarotraumaClient/Source/DebugConsole.cs +++ b/Barotrauma/BarotraumaClient/Source/DebugConsole.cs @@ -28,7 +28,7 @@ namespace Barotrauma static GUIFrame frame; static GUIListBox listBox; static GUITextBox textBox; - + public static void Init(GameWindow window) { int x = 20, y = 20; @@ -47,7 +47,7 @@ namespace Barotrauma return true; }; - + NewMessage("Press F3 to open/close the debug console", Color.Cyan); NewMessage("Enter \"help\" for a list of available console commands", Color.Cyan); @@ -111,7 +111,7 @@ namespace Barotrauma { textBox.Text = AutoComplete(textBox.Text); } - + if (PlayerInput.KeyHit(Keys.Enter)) { ExecuteCommand(textBox.Text); @@ -164,7 +164,7 @@ namespace Barotrauma { listBox.children.RemoveRange(0, listBox.children.Count - MaxMessages); } - + Messages.Add(msg); if (Messages.Count > MaxMessages) { @@ -190,10 +190,27 @@ namespace Barotrauma private static void InitProjectSpecific() { + commands.Add(new Command("autohull", "", (string[] args) => + { + if (Screen.Selected != GameMain.SubEditorScreen) return; + + if (MapEntity.mapEntityList.Any(e => e is Hull || e is Gap)) + { + ShowQuestionPrompt("This submarine already has hulls and/or gaps. This command will delete them. Do you want to continue? Y/N", + (option) => { + if (option.ToLower() == "y") GameMain.SubEditorScreen.AutoHull(); + }); + } + else + { + GameMain.SubEditorScreen.AutoHull(); + } + })); + commands.Add(new Command("startclient", "", (string[] args) => { if (args.Length == 0) return; - + if (GameMain.Client == null) { GameMain.NetworkMember = new GameClient("Name"); @@ -227,7 +244,7 @@ namespace Barotrauma } GameMain.SubEditorScreen.Select(); })); - + commands.Add(new Command("editcharacter", "", (string[] args) => { GameMain.CharacterEditorScreen.Select(); diff --git a/Barotrauma/BarotraumaClient/Source/Screens/SubEditorScreen.cs b/Barotrauma/BarotraumaClient/Source/Screens/SubEditorScreen.cs index 35c5a36f0..cf5bae8cb 100644 --- a/Barotrauma/BarotraumaClient/Source/Screens/SubEditorScreen.cs +++ b/Barotrauma/BarotraumaClient/Source/Screens/SubEditorScreen.cs @@ -901,7 +901,305 @@ namespace Barotrauma previouslyUsedList.RemoveChild(textBlock); previouslyUsedList.children.Insert(0, textBlock); } + + public void AutoHull() + { + for (int i = 0; i < MapEntity.mapEntityList.Count; i++) + { + MapEntity h = MapEntity.mapEntityList[i]; + if (h is Hull || h is Gap) + { + h.Remove(); + i--; + } + } + List wallPoints = new List(); + Vector2 min = Vector2.Zero; + Vector2 max = Vector2.Zero; + + List mapEntityList = new List(); + + foreach (MapEntity e in MapEntity.mapEntityList) + { + if (e is Item) + { + Item it = e as Item; + Door door = it.GetComponent(); + if (door != null) + { + int halfW = e.WorldRect.Width / 2; + wallPoints.Add(new Vector2(e.WorldRect.X + halfW, -e.WorldRect.Y + e.WorldRect.Height)); + mapEntityList.Add(it); + } + continue; + } + + if (!(e is Structure)) continue; + Structure s = e as Structure; + if (!s.HasBody) continue; + mapEntityList.Add(e); + + if (e.Rect.Width > e.Rect.Height) + { + int halfH = e.WorldRect.Height / 2; + wallPoints.Add(new Vector2(e.WorldRect.X, -e.WorldRect.Y + halfH)); + wallPoints.Add(new Vector2(e.WorldRect.X + e.WorldRect.Width, -e.WorldRect.Y + halfH)); + } + else + { + int halfW = e.WorldRect.Width / 2; + wallPoints.Add(new Vector2(e.WorldRect.X + halfW, -e.WorldRect.Y)); + wallPoints.Add(new Vector2(e.WorldRect.X + halfW, -e.WorldRect.Y + e.WorldRect.Height)); + } + } + + min = wallPoints[0]; + max = wallPoints[0]; + for (int i = 0; i < wallPoints.Count; i++) + { + min.X = Math.Min(min.X, wallPoints[i].X); + min.Y = Math.Min(min.Y, wallPoints[i].Y); + max.X = Math.Max(max.X, wallPoints[i].X); + max.Y = Math.Max(max.Y, wallPoints[i].Y); + } + + List hullRects = new List(); + hullRects.Add(new Rectangle((int)min.X, (int)min.Y, (int)(max.X - min.X), (int)(max.Y - min.Y))); + foreach (Vector2 point in wallPoints) + { + MathUtils.SplitRectanglesHorizontal(hullRects, point); + MathUtils.SplitRectanglesVertical(hullRects, point); + } + + hullRects.Sort((a, b) => + { + if (a.Y < b.Y) return -1; + if (a.Y > b.Y) return 1; + if (a.X < b.X) return -1; + if (a.X > b.X) return 1; + return 0; + }); + + for (int i = 0; i < hullRects.Count - 1; i++) + { + Rectangle rect = hullRects[i]; + if (hullRects[i + 1].Y > rect.Y) continue; + + Vector2 hullRPoint = new Vector2(rect.X + rect.Width - 8, rect.Y + rect.Height / 2); + Vector2 hullLPoint = new Vector2(rect.X, rect.Y + rect.Height / 2); + + MapEntity container = null; + foreach (MapEntity e in mapEntityList) + { + Rectangle entRect = e.WorldRect; + entRect.Y = -entRect.Y; + if (entRect.Contains(hullRPoint)) + { + if (!entRect.Contains(hullLPoint)) container = e; + break; + } + } + if (container == null) + { + rect.Width += hullRects[i + 1].Width; + hullRects[i] = rect; + hullRects.RemoveAt(i + 1); + i--; + } + } + + foreach (MapEntity e in mapEntityList) + { + Rectangle entRect = e.WorldRect; + if (entRect.Width < entRect.Height) continue; + entRect.Y = -entRect.Y - 16; + for (int i = 0; i < hullRects.Count; i++) + { + Rectangle hullRect = hullRects[i]; + if (entRect.Intersects(hullRect)) + { + if (hullRect.Y < entRect.Y) + { + hullRect.Height = Math.Max((entRect.Y + 16 + entRect.Height / 2) - hullRect.Y, hullRect.Height); + hullRects[i] = hullRect; + } + else if (hullRect.Y + hullRect.Height <= entRect.Y + 16 + entRect.Height) + { + hullRects.RemoveAt(i); + i--; + } + } + } + } + + foreach (MapEntity e in mapEntityList) + { + Rectangle entRect = e.WorldRect; + if (entRect.Width < entRect.Height) continue; + entRect.Y = -entRect.Y; + for (int i = 0; i < hullRects.Count; i++) + { + Rectangle hullRect = hullRects[i]; + if (entRect.Intersects(hullRect)) + { + if (hullRect.Y >= entRect.Y - 8 && hullRect.Y + hullRect.Height <= entRect.Y + entRect.Height + 8) + { + hullRects.RemoveAt(i); + i--; + } + } + } + } + + for (int i = 0; i < hullRects.Count;) + { + Rectangle hullRect = hullRects[i]; + Vector2 point = new Vector2(hullRect.X+2, hullRect.Y+hullRect.Height/2); + MapEntity container = null; + foreach (MapEntity e in mapEntityList) + { + Rectangle entRect = e.WorldRect; + entRect.Y = -entRect.Y; + if (entRect.Contains(point)) + { + container = e; + break; + } + } + if (container == null) + { + hullRects.RemoveAt(i); + continue; + } + + while (hullRects[i].Y <= hullRect.Y) + { + i++; + if (i >= hullRects.Count) break; + } + } + + for (int i = hullRects.Count-1; i >= 0;) + { + Rectangle hullRect = hullRects[i]; + Vector2 point = new Vector2(hullRect.X+hullRect.Width-2, hullRect.Y+hullRect.Height/2); + MapEntity container = null; + foreach (MapEntity e in mapEntityList) + { + Rectangle entRect = e.WorldRect; + entRect.Y = -entRect.Y; + if (entRect.Contains(point)) + { + container = e; + break; + } + } + if (container == null) + { + hullRects.RemoveAt(i); i--; + continue; + } + + while (hullRects[i].Y >= hullRect.Y) + { + i--; + if (i < 0) break; + } + } + + hullRects.Sort((a, b) => + { + if (a.X < b.X) return -1; + if (a.X > b.X) return 1; + if (a.Y < b.Y) return -1; + if (a.Y > b.Y) return 1; + return 0; + }); + + for (int i = 0; i < hullRects.Count - 1; i++) + { + Rectangle rect = hullRects[i]; + if (hullRects[i + 1].Width != rect.Width) continue; + if (hullRects[i + 1].X > rect.X) continue; + + Vector2 hullBPoint = new Vector2(rect.X + rect.Width / 2, rect.Y + rect.Height - 8); + Vector2 hullUPoint = new Vector2(rect.X + rect.Width / 2, rect.Y); + + MapEntity container = null; + foreach (MapEntity e in mapEntityList) + { + Rectangle entRect = e.WorldRect; + entRect.Y = -entRect.Y; + if (entRect.Contains(hullBPoint)) + { + if (!entRect.Contains(hullUPoint)) container = e; + break; + } + } + if (container == null) + { + rect.Height += hullRects[i + 1].Height; + hullRects[i] = rect; + hullRects.RemoveAt(i + 1); + i--; + } + } + + for (int i = 0; i < hullRects.Count;i++) + { + Rectangle rect = hullRects[i]; + rect.Y -= 16; + rect.Height += 32; + hullRects[i] = rect; + } + + hullRects.Sort((a, b) => + { + if (a.Y < b.Y) return -1; + if (a.Y > b.Y) return 1; + if (a.X < b.X) return -1; + if (a.X > b.X) return 1; + return 0; + }); + + for (int i = 0; i < hullRects.Count; i++) + { + for (int j = i+1; j < hullRects.Count; j++) + { + if (hullRects[j].Y <= hullRects[i].Y) continue; + if (hullRects[j].Intersects(hullRects[i])) + { + Rectangle rect = hullRects[i]; + rect.Height = hullRects[j].Y - rect.Y; + hullRects[i] = rect; + break; + } + } + } + + foreach (Rectangle rect in hullRects) + { + Rectangle hullRect = rect; + hullRect.Y = -hullRect.Y; + Hull newHull = new Hull(MapEntityPrefab.Find("Hull"), + hullRect, + Submarine.MainSub); + } + + foreach (MapEntity e in mapEntityList) + { + if (!(e is Structure)) continue; + if (!(e as Structure).IsPlatform) continue; + + Rectangle gapRect = e.WorldRect; + gapRect.Y -= 8; + gapRect.Height = 16; + Gap newGap = new Gap(MapEntityPrefab.Find("Gap"), + gapRect); + } + } + public override void AddToGUIUpdateList() { if (tutorial != null) tutorial.AddToGUIUpdateList(); diff --git a/Barotrauma/BarotraumaShared/Source/Networking/GameServerSettings.cs b/Barotrauma/BarotraumaShared/Source/Networking/GameServerSettings.cs index cc07cf19e..d6fe0543f 100644 --- a/Barotrauma/BarotraumaShared/Source/Networking/GameServerSettings.cs +++ b/Barotrauma/BarotraumaShared/Source/Networking/GameServerSettings.cs @@ -349,9 +349,12 @@ namespace Barotrauma.Networking { clientPermissions.Clear(); - if (File.Exists("Data/clientpermissions.txt") && !File.Exists(ClientPermissionsFile)) + if (!File.Exists(ClientPermissionsFile)) { - LoadClientPermissionsOld("Data/clientpermissions.txt"); + if (File.Exists("Data/clientpermissions.txt")) + { + LoadClientPermissionsOld("Data/clientpermissions.txt"); + } return; } diff --git a/Barotrauma/BarotraumaShared/Source/Utils/MathUtils.cs b/Barotrauma/BarotraumaShared/Source/Utils/MathUtils.cs index 637afaeef..92e0a1b16 100644 --- a/Barotrauma/BarotraumaShared/Source/Utils/MathUtils.cs +++ b/Barotrauma/BarotraumaShared/Source/Utils/MathUtils.cs @@ -508,6 +508,52 @@ namespace Barotrauma // Return formatted number with suffix return readable.ToString("0.# ") + suffix; } + + public static void SplitRectanglesHorizontal(List rects, Vector2 point) + { + for (int i = 0; i < rects.Count; i++) + { + if (point.Y > rects[i].Y && point.Y < rects[i].Y + rects[i].Height) + { + Rectangle rect1 = rects[i]; + Rectangle rect2 = rects[i]; + + rect1.Height = (int)(point.Y - rects[i].Y); + + rect2.Height = rects[i].Height - rect1.Height; + rect2.Y = rect1.Y + rect1.Height; + rects[i] = rect1; + rects.Insert(i + 1, rect2); i++; + } + } + } + + public static void SplitRectanglesVertical(List rects, Vector2 point) + { + for (int i = 0; i < rects.Count; i++) + { + if (point.X>rects[i].X && point.X