diff --git a/Barotrauma/BarotraumaClient/Source/Characters/Character.cs b/Barotrauma/BarotraumaClient/Source/Characters/Character.cs index 633916804..b281ff3bb 100644 --- a/Barotrauma/BarotraumaClient/Source/Characters/Character.cs +++ b/Barotrauma/BarotraumaClient/Source/Characters/Character.cs @@ -442,7 +442,8 @@ namespace Barotrauma if (draggingItemToWorld) { if (item.OwnInventory == null || - !item.OwnInventory.CanBePut(CharacterInventory.draggingItem)) + !item.OwnInventory.CanBePut(CharacterInventory.draggingItem) || + !CanAccessInventory(item.OwnInventory)) { continue; } diff --git a/Barotrauma/BarotraumaClient/Source/Characters/CharacterHUD.cs b/Barotrauma/BarotraumaClient/Source/Characters/CharacterHUD.cs index aaf8d1e3b..75b6872dd 100644 --- a/Barotrauma/BarotraumaClient/Source/Characters/CharacterHUD.cs +++ b/Barotrauma/BarotraumaClient/Source/Characters/CharacterHUD.cs @@ -139,7 +139,7 @@ namespace Barotrauma foreach (Item item in Item.ItemList) { if (!item.Repairables.Any(r => item.Condition < r.ShowRepairUIThreshold)) { continue; } - if (!Submarine.VisibleEntities.Contains(item)) { continue; } + if (Submarine.VisibleEntities != null && !Submarine.VisibleEntities.Contains(item)) { continue; } Vector2 diff = item.WorldPosition - character.WorldPosition; if (Submarine.CheckVisibility(character.SimPosition, character.SimPosition + ConvertUnits.ToSimUnits(diff)) == null) diff --git a/Barotrauma/BarotraumaClient/Source/Characters/Limb.cs b/Barotrauma/BarotraumaClient/Source/Characters/Limb.cs index a3d57f795..846e82d39 100644 --- a/Barotrauma/BarotraumaClient/Source/Characters/Limb.cs +++ b/Barotrauma/BarotraumaClient/Source/Characters/Limb.cs @@ -449,12 +449,11 @@ namespace Barotrauma { float depth = ActiveSprite.Depth - 0.0000015f; - // TODO: enable when the damage overlay textures have been remade. - //DamagedSprite.Draw(spriteBatch, - // new Vector2(body.DrawPosition.X, -body.DrawPosition.Y), - // color * Math.Min(damageOverlayStrength, 1.0f), ActiveSprite.Origin, - // -body.DrawRotation, - // 1.0f, spriteEffect, depth); + DamagedSprite.Draw(spriteBatch, + new Vector2(body.DrawPosition.X, -body.DrawPosition.Y), + color * Math.Min(damageOverlayStrength, 1.0f), ActiveSprite.Origin, + -body.DrawRotation, + 1.0f, spriteEffect, depth); } if (GameMain.DebugDraw) diff --git a/Barotrauma/BarotraumaClient/Source/GUI/GUIDropDown.cs b/Barotrauma/BarotraumaClient/Source/GUI/GUIDropDown.cs index 6cdba8652..c2f8351bc 100644 --- a/Barotrauma/BarotraumaClient/Source/GUI/GUIDropDown.cs +++ b/Barotrauma/BarotraumaClient/Source/GUI/GUIDropDown.cs @@ -148,7 +148,14 @@ namespace Barotrauma //find the parent GUIListBox highest in the hierarchy for (int i = parentHierarchy.Count - 1; i >= 0; i--) { - if (parentHierarchy[i].GUIComponent is GUIListBox) return parentHierarchy[i]; + if (parentHierarchy[i].GUIComponent is GUIListBox) + { + if (parentHierarchy[i].Parent != null && parentHierarchy[i].Parent.GUIComponent != null) + { + return parentHierarchy[i].Parent; + } + return parentHierarchy[i]; + } } //or just go with the direct parent if there are no listboxes in the hierarchy parentHierarchy.Clear(); diff --git a/Barotrauma/BarotraumaClient/Source/GUI/GUIStyle.cs b/Barotrauma/BarotraumaClient/Source/GUI/GUIStyle.cs index 780264181..26fe1031b 100644 --- a/Barotrauma/BarotraumaClient/Source/GUI/GUIStyle.cs +++ b/Barotrauma/BarotraumaClient/Source/GUI/GUIStyle.cs @@ -40,6 +40,9 @@ namespace Barotrauma { ToolBox.IsProperFilenameCase(file); doc = XDocument.Load(file, LoadOptions.SetBaseUri); + if (doc == null) { throw new Exception("doc is null"); } + if (doc.Root == null) { throw new Exception("doc.Root is null"); } + if (doc.Root.Elements() == null) { throw new Exception("doc.Root.Elements() is null"); } } catch (Exception e) { @@ -113,26 +116,34 @@ namespace Barotrauma private void RescaleFonts() { + if (configElement == null) { return; } + if (configElement.Elements() == null) { return; } foreach (XElement subElement in configElement.Elements()) { switch (subElement.Name.ToString().ToLowerInvariant()) { case "font": + if (Font == null) { continue; } Font.Size = GetFontSize(subElement); break; case "smallfont": + if (SmallFont == null) { continue; } SmallFont.Size = GetFontSize(subElement); break; case "largefont": + if (LargeFont == null) { continue; } LargeFont.Size = GetFontSize(subElement); break; case "objectivetitle": + if (ObjectiveTitleFont == null) { continue; } ObjectiveTitleFont.Size = GetFontSize(subElement); break; case "objectivename": + if (ObjectiveNameFont == null) { continue; } ObjectiveNameFont.Size = GetFontSize(subElement); break; case "videotitle": + if (VideoTitleFont == null) { continue; } VideoTitleFont.Size = GetFontSize(subElement); break; } diff --git a/Barotrauma/BarotraumaClient/Source/GameSession/CrewManager.cs b/Barotrauma/BarotraumaClient/Source/GameSession/CrewManager.cs index 69b2aa985..a95140454 100644 --- a/Barotrauma/BarotraumaClient/Source/GameSession/CrewManager.cs +++ b/Barotrauma/BarotraumaClient/Source/GameSession/CrewManager.cs @@ -20,8 +20,8 @@ namespace Barotrauma /// const float CharacterWaitOnSwitch = 10.0f; - private List characterInfos = new List(); - private List characters = new List(); + private readonly List characterInfos = new List(); + private readonly List characters = new List(); private Point screenResolution; diff --git a/Barotrauma/BarotraumaClient/Source/GameSession/GameModes/SinglePlayerCampaign.cs b/Barotrauma/BarotraumaClient/Source/GameSession/GameModes/SinglePlayerCampaign.cs index 0bb370465..ad998bd39 100644 --- a/Barotrauma/BarotraumaClient/Source/GameSession/GameModes/SinglePlayerCampaign.cs +++ b/Barotrauma/BarotraumaClient/Source/GameSession/GameModes/SinglePlayerCampaign.cs @@ -256,6 +256,18 @@ namespace Barotrauma { if (c.Info == null || c.Inventory == null) { continue; } var inventoryElement = new XElement("inventory"); + + // Recharge headset batteries + var headset = c.Inventory.FindItemByIdentifier("headset"); + if (headset != null) + { + var battery = headset.OwnInventory.FindItemByTag("loadable"); + if (battery != null) + { + battery.Condition = battery.MaxCondition; + } + } + c.SaveInventory(c.Inventory, inventoryElement); c.Info.InventoryData = inventoryElement; c.Inventory?.DeleteAllItems(); diff --git a/Barotrauma/BarotraumaClient/Source/Items/Inventory.cs b/Barotrauma/BarotraumaClient/Source/Items/Inventory.cs index 8c3597b8d..2ebb44dc4 100644 --- a/Barotrauma/BarotraumaClient/Source/Items/Inventory.cs +++ b/Barotrauma/BarotraumaClient/Source/Items/Inventory.cs @@ -620,6 +620,7 @@ namespace Barotrauma { if (DraggingItemToWorld && Character.Controlled.FocusedItem?.OwnInventory != null && + Character.Controlled.FocusedItem.OwnInventory.CanBePut(draggingItem) && Character.Controlled.FocusedItem.OwnInventory.TryPutItem(draggingItem, Character.Controlled)) { GUI.PlayUISound(GUISoundType.PickItem); diff --git a/Barotrauma/BarotraumaClient/Source/Map/ItemAssemblyPrefab.cs b/Barotrauma/BarotraumaClient/Source/Map/ItemAssemblyPrefab.cs index 00eb633c9..0fcff3a6d 100644 --- a/Barotrauma/BarotraumaClient/Source/Map/ItemAssemblyPrefab.cs +++ b/Barotrauma/BarotraumaClient/Source/Map/ItemAssemblyPrefab.cs @@ -82,7 +82,7 @@ namespace Barotrauma center.Y -= center.Y % Submarine.GridSize.Y; MapEntity.SelectedList.Clear(); - MapEntity.SelectedList.AddRange(assemblyEntities); + assemblyEntities.ForEach(e => MapEntity.AddSelection(e)); foreach (MapEntity mapEntity in assemblyEntities) { diff --git a/Barotrauma/BarotraumaClient/Source/Map/Levels/LevelRenderer.cs b/Barotrauma/BarotraumaClient/Source/Map/Levels/LevelRenderer.cs index 28a1f7b89..fe1140184 100644 --- a/Barotrauma/BarotraumaClient/Source/Map/Levels/LevelRenderer.cs +++ b/Barotrauma/BarotraumaClient/Source/Map/Levels/LevelRenderer.cs @@ -142,24 +142,27 @@ namespace Barotrauma backgroundPos.Y = -backgroundPos.Y; backgroundPos *= 0.05f; - - if (backgroundPos.Y < 1024) + if (level.GenerationParams.BackgroundTopSprite != null) { - if (backgroundPos.Y < 0 && level.GenerationParams.BackgroundTopSprite != null) + int backgroundSize = (int)level.GenerationParams.BackgroundTopSprite.size.Y; + if (backgroundPos.Y < backgroundSize) { - var backgroundTop = level.GenerationParams.BackgroundTopSprite; - backgroundTop.SourceRect = new Rectangle((int)backgroundPos.X, (int)backgroundPos.Y, 1024, (int)Math.Min(-backgroundPos.Y, 1024)); - backgroundTop.DrawTiled(spriteBatch, Vector2.Zero, new Vector2(GameMain.GraphicsWidth, Math.Min(-backgroundPos.Y, GameMain.GraphicsHeight)), - color: level.BackgroundTextureColor); - } - if (backgroundPos.Y > -1024 && level.GenerationParams.BackgroundSprite != null) - { - var background = level.GenerationParams.BackgroundSprite; - background.SourceRect = new Rectangle((int)backgroundPos.X, (int)Math.Max(backgroundPos.Y, 0), 1024, 1024); - background.DrawTiled(spriteBatch, - (backgroundPos.Y < 0) ? new Vector2(0.0f, (int)-backgroundPos.Y) : Vector2.Zero, - new Vector2(GameMain.GraphicsWidth, (int)Math.Ceiling(1024 - backgroundPos.Y)), - color: level.BackgroundTextureColor); + if (backgroundPos.Y < 0) + { + var backgroundTop = level.GenerationParams.BackgroundTopSprite; + backgroundTop.SourceRect = new Rectangle((int)backgroundPos.X, (int)backgroundPos.Y, backgroundSize, (int)Math.Min(-backgroundPos.Y, backgroundSize)); + backgroundTop.DrawTiled(spriteBatch, Vector2.Zero, new Vector2(GameMain.GraphicsWidth, Math.Min(-backgroundPos.Y, GameMain.GraphicsHeight)), + color: level.BackgroundTextureColor); + } + if (-backgroundPos.Y < GameMain.GraphicsHeight && level.GenerationParams.BackgroundSprite != null) + { + var background = level.GenerationParams.BackgroundSprite; + background.SourceRect = new Rectangle((int)backgroundPos.X, (int)Math.Max(backgroundPos.Y, 0), backgroundSize, backgroundSize); + background.DrawTiled(spriteBatch, + (backgroundPos.Y < 0) ? new Vector2(0.0f, (int)-backgroundPos.Y) : Vector2.Zero, + new Vector2(GameMain.GraphicsWidth, (int)Math.Min(Math.Ceiling(backgroundSize - backgroundPos.Y), backgroundSize)), + color: level.BackgroundTextureColor); + } } } diff --git a/Barotrauma/BarotraumaClient/Source/Map/MapEntity.cs b/Barotrauma/BarotraumaClient/Source/Map/MapEntity.cs index b30101b37..a739629e9 100644 --- a/Barotrauma/BarotraumaClient/Source/Map/MapEntity.cs +++ b/Barotrauma/BarotraumaClient/Source/Map/MapEntity.cs @@ -478,6 +478,60 @@ namespace Barotrauma return true; }; } + + public static void AddSelection(MapEntity entity) + { + if (selectedList.Contains(entity)) { return; } + selectedList.Add(entity); + HandleDoorGapLinks(entity, + onGapFound: (door, gap) => + { + door.RefreshLinkedGap(); + if (!selectedList.Contains(gap)) + { + selectedList.Add(gap); + } + }, + onDoorFound: (door, gap) => + { + if (!selectedList.Contains(door.Item)) + { + selectedList.Add(door.Item); + } + }); + } + + private static void HandleDoorGapLinks(MapEntity entity, Action onGapFound, Action onDoorFound) + { + if (entity is Item i) + { + var door = i.GetComponent(); + if (door != null) + { + var gap = door.LinkedGap; + if (gap != null) + { + onGapFound(door, gap); + } + } + } + else if (entity is Gap gap) + { + var door = gap.ConnectedDoor; + if (door != null) + { + onDoorFound(door, gap); + } + } + } + + public static void RemoveSelection(MapEntity entity) + { + selectedList.Remove(entity); + HandleDoorGapLinks(entity, + onGapFound: (door, gap) => selectedList.Remove(gap), + onDoorFound: (door, gap) => selectedList.Remove(door.Item)); + } static partial void UpdateAllProjSpecific(float deltaTime) { @@ -550,7 +604,7 @@ namespace Barotrauma if (editingHUD != null) { - if (selectedList.Count == 0 || editingHUD.UserData != selectedList[0]) + if (FilteredSelectedList.Count == 0 || editingHUD.UserData != FilteredSelectedList[0]) { foreach (GUIComponent component in editingHUD.Children) { @@ -561,21 +615,56 @@ namespace Barotrauma editingHUD = null; } } - + FilteredSelectedList.Clear(); if (selectedList.Count == 0) return; - - if (editingHUD != null) + foreach (var e in selectedList) { - selectedList[0].UpdateEditing(cam); - if (selectedList[0].ResizeHorizontal || selectedList[0].ResizeVertical) + if (e is Gap) { continue; } + FilteredSelectedList.Add(e); + } + var first = FilteredSelectedList.FirstOrDefault(); + if (first != null) + { + first.UpdateEditing(cam); + if (first.ResizeHorizontal || first.ResizeVertical) { - foreach (GUIComponent component in editingHUD.Children) + first.UpdateResizing(cam); + } + } + + if ((PlayerInput.KeyDown(Keys.LeftControl) || PlayerInput.KeyDown(Keys.RightControl))) + { + if (PlayerInput.KeyHit(Keys.N)) + { + float minX = selectedList[0].WorldRect.X, maxX = selectedList[0].WorldRect.Right; + for (int i = 0; i < selectedList.Count; i++) { - var textBox = component as GUITextBox; - if (textBox == null) continue; - textBox.Deselect(); + minX = Math.Min(minX, selectedList[i].WorldRect.X); + maxX = Math.Max(maxX, selectedList[i].WorldRect.Right); + } + + float centerX = (minX + maxX) / 2.0f; + foreach (MapEntity me in selectedList) + { + me.FlipX(false); + me.Move(new Vector2((centerX - me.WorldPosition.X) * 2.0f, 0.0f)); + } + } + else if (PlayerInput.KeyHit(Keys.M)) + { + float minY = selectedList[0].WorldRect.Y - selectedList[0].WorldRect.Height, maxY = selectedList[0].WorldRect.Y; + for (int i = 0; i < selectedList.Count; i++) + { + minY = Math.Min(minY, selectedList[i].WorldRect.Y - selectedList[i].WorldRect.Height); + maxY = Math.Max(maxY, selectedList[i].WorldRect.Y); + } + + float centerY = (minY + maxY) / 2.0f; + foreach (MapEntity me in selectedList) + { + me.FlipY(false); + me.Move(new Vector2(0.0f, (centerY - me.WorldPosition.Y) * 2.0f)); } - editingHUD = null; } } FilteredSelectedList.Clear(); diff --git a/Barotrauma/BarotraumaClient/Source/Map/WayPoint.cs b/Barotrauma/BarotraumaClient/Source/Map/WayPoint.cs index d1f937d7f..27c059ccf 100644 --- a/Barotrauma/BarotraumaClient/Source/Map/WayPoint.cs +++ b/Barotrauma/BarotraumaClient/Source/Map/WayPoint.cs @@ -51,6 +51,10 @@ namespace Barotrauma { iconSize = (int)(iconSize * 1.5f); } + if (Stairs != null) + { + iconSize = (int)(iconSize * 1.5f); + } spriteBatch.Draw(iconTexture, new Rectangle((int)(drawPos.X - iconSize / 2), (int)(drawPos.Y - iconSize / 2), iconSize, iconSize), @@ -93,7 +97,7 @@ namespace Barotrauma editingHUD = CreateEditingHUD(); } - if (PlayerInput.LeftButtonClicked()) + if (IsSelected && PlayerInput.LeftButtonClicked()) { Vector2 position = cam.ScreenToWorld(PlayerInput.MousePosition); @@ -149,6 +153,23 @@ namespace Barotrauma } } + private void UpdateLinkedEntity(Vector2 worldPos, IEnumerable list, Action match, Action noMatch, int inflate = 0) where T : MapEntity + { + foreach (var entity in list) + { + var rect = entity.WorldRect; + rect.Inflate(inflate, inflate); + if (Submarine.RectContains(rect, worldPos)) + { + match(entity); + } + else + { + noMatch(entity); + } + } + } + private bool ChangeSpawnType(GUIButton button, object obj) { GUITextBlock spawnTypeText = button.Parent.GetChildByUserData("spawntypetext") as GUITextBlock; diff --git a/Barotrauma/BarotraumaClient/Source/Networking/SteamManager.cs b/Barotrauma/BarotraumaClient/Source/Networking/SteamManager.cs index 4b27e024c..a7e1a484b 100644 --- a/Barotrauma/BarotraumaClient/Source/Networking/SteamManager.cs +++ b/Barotrauma/BarotraumaClient/Source/Networking/SteamManager.cs @@ -594,8 +594,15 @@ namespace Barotrauma.Steam } SaveUtil.ClearFolder(WorkshopItemStagingFolder); - Directory.Delete(WorkshopItemStagingFolder); File.Delete(PreviewImageName); + try + { + Directory.Delete(WorkshopItemStagingFolder); + } + catch (Exception e) + { + DebugConsole.ThrowError("Failed to delete Workshop item staging folder.", e); + } yield return CoroutineStatus.Success; } @@ -927,28 +934,50 @@ namespace Barotrauma.Steam { if (instance == null || !instance.isInitialized) { return false; } - bool itemsUpdated = false; - foreach (ulong subscribedItemId in instance.client.Workshop.GetSubscribedItemIds()) + bool? itemsUpdated = null; + bool timedOut = false; + var query = instance.client.Workshop.CreateQuery(); + query.FileId = new List(instance.client.Workshop.GetSubscribedItemIds()); + query.UploaderAppId = AppID; + query.Run(); + query.OnResult = (Workshop.Query q) => { - //TODO: fix this, GetItem doesn't query item.Modified - var item = instance.client.Workshop.GetItem(subscribedItemId); - if (item.Installed && CheckWorkshopItemEnabled(item) && !CheckWorkshopItemUpToDate(item)) + if (timedOut) { return; } + itemsUpdated = false; + foreach (var item in q.Items) { - if (!UpdateWorkshopItem(item, out string errorMsg)) + if (item.Installed && CheckWorkshopItemEnabled(item) && !CheckWorkshopItemUpToDate(item)) { - DebugConsole.ThrowError(errorMsg); - new GUIMessageBox( - TextManager.Get("Error"), - TextManager.GetWithVariables("WorkshopItemUpdateFailed", new string[2] { "[itemname]", "[errormessage]" }, new string[2] { item.Title, errorMsg })); - } - else - { - new GUIMessageBox("", TextManager.GetWithVariable("WorkshopItemUpdated", "[itemname]", item.Title)); - itemsUpdated = true; + if (!UpdateWorkshopItem(item, out string errorMsg)) + { + DebugConsole.ThrowError(errorMsg); + new GUIMessageBox( + TextManager.Get("Error"), + TextManager.GetWithVariables("WorkshopItemUpdateFailed", new string[2] { "[itemname]", "[errormessage]" }, new string[2] { item.Title, errorMsg })); + } + else + { + new GUIMessageBox("", TextManager.GetWithVariable("WorkshopItemUpdated", "[itemname]", item.Title)); + itemsUpdated = true; + } } } + }; + + DateTime timeOut = DateTime.Now + new TimeSpan(0, 0, 10); + while (!itemsUpdated.HasValue) + { + if (DateTime.Now > timeOut) + { + itemsUpdated = false; + timedOut = true; + break; + } + instance.client.Update(); + System.Threading.Thread.Sleep(10); } - return itemsUpdated; + + return itemsUpdated.Value; } public static bool UpdateWorkshopItem(Workshop.Item item, out string errorMsg) diff --git a/Barotrauma/BarotraumaClient/Source/Screens/CampaignUI.cs b/Barotrauma/BarotraumaClient/Source/Screens/CampaignUI.cs index 4f96e0cdc..ee84ed139 100644 --- a/Barotrauma/BarotraumaClient/Source/Screens/CampaignUI.cs +++ b/Barotrauma/BarotraumaClient/Source/Screens/CampaignUI.cs @@ -441,36 +441,43 @@ namespace Barotrauma characterPreviewFrame = null; } - if (Campaign is SinglePlayerCampaign) + if (characterList != null) { - var hireableCharacters = location.GetHireableCharacters(); - foreach (GUIComponent child in characterList.Content.Children.ToList()) + if (Campaign is SinglePlayerCampaign) { - if (child.UserData is CharacterInfo character) + var hireableCharacters = location.GetHireableCharacters(); + foreach (GUIComponent child in characterList.Content.Children.ToList()) { - if (GameMain.GameSession.CrewManager.GetCharacterInfos().Contains(character)) { continue; } + if (child.UserData is CharacterInfo character) + { + if (GameMain.GameSession.CrewManager != null) + { + if (GameMain.GameSession.CrewManager.GetCharacterInfos().Contains(character)) { continue; } + } + } + else if (child.UserData as string == "mycrew" || child.UserData as string == "hire") + { + continue; + } + characterList.RemoveChild(child); } - else if (child.UserData as string == "mycrew" || child.UserData as string == "hire") + if (!hireableCharacters.Any()) { - continue; + new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.2f), characterList.Content.RectTransform), TextManager.Get("HireUnavailable"), textAlignment: Alignment.Center) + { + CanBeFocused = false + }; } - characterList.RemoveChild(child); - } - if (!hireableCharacters.Any()) - { - new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.2f), characterList.Content.RectTransform), TextManager.Get("HireUnavailable"), textAlignment: Alignment.Center) + else { - CanBeFocused = false - }; - } - else - { - foreach (CharacterInfo c in hireableCharacters) - { - var frame = c.CreateCharacterFrame(characterList.Content, c.Name + " (" + c.Job.Name + ")", c); - new GUITextBlock(new RectTransform(Vector2.One, frame.RectTransform, Anchor.TopRight), c.Salary.ToString(), textAlignment: Alignment.CenterRight); + foreach (CharacterInfo c in hireableCharacters) + { + var frame = c.CreateCharacterFrame(characterList.Content, c.Name + " (" + c.Job.Name + ")", c); + new GUITextBlock(new RectTransform(Vector2.One, frame.RectTransform, Anchor.TopRight), c.Salary.ToString(), textAlignment: Alignment.CenterRight); + } } } + characterList.UpdateScrollBarSize(); } characterList.UpdateScrollBarSize(); diff --git a/Barotrauma/BarotraumaClient/Source/Screens/MainMenuScreen.cs b/Barotrauma/BarotraumaClient/Source/Screens/MainMenuScreen.cs index d8ab767b4..a55342ca6 100644 --- a/Barotrauma/BarotraumaClient/Source/Screens/MainMenuScreen.cs +++ b/Barotrauma/BarotraumaClient/Source/Screens/MainMenuScreen.cs @@ -14,7 +14,7 @@ namespace Barotrauma { class MainMenuScreen : Screen { - public enum Tab { NewGame = 1, LoadGame = 2, HostServer = 3, Settings = 4, Tutorials = 5, JoinServer = 6, CharacterEditor = 7, SubmarineEditor = 8, QuickStartDev = 9, SteamWorkshop = 10, Credits = 11 } + public enum Tab { NewGame = 1, LoadGame = 2, HostServer = 3, Settings = 4, Tutorials = 5, JoinServer = 6, CharacterEditor = 7, SubmarineEditor = 8, QuickStartDev = 9, SteamWorkshop = 10, Credits = 11, Empty = 12 } private GUIComponent buttonsParent; @@ -37,7 +37,11 @@ namespace Barotrauma private GUIComponent titleText; private CreditsPlayer creditsPlayer; - + + #if OSX + private bool firstLoadOnMac = true; + #endif + #region Creation public MainMenuScreen(GameMain game) { @@ -360,9 +364,9 @@ namespace Barotrauma OnClicked = SelectTab }; } -#endregion + #endregion -#region Selection + #region Selection public override void Select() { base.Select(); @@ -378,6 +382,25 @@ namespace Barotrauma ResetButtonStates(null); GameAnalyticsManager.SetCustomDimension01(""); + + #if OSX + // Hack for adjusting the viewport properly after splash screens on older Macs + if (firstLoadOnMac) + { + firstLoadOnMac = false; + + menuTabs[(int)Tab.Empty] = new GUIFrame(new RectTransform(new Vector2(1f, 1f), GUI.Canvas), "", Color.Transparent) + { + CanBeFocused = false + }; + var emptyList = new GUIListBox(new RectTransform(new Vector2(0.0f, 0.0f), menuTabs[(int)Tab.Empty].RectTransform)) + { + CanBeFocused = false + }; + + SelectTab(null, Tab.Empty); + } + #endif } public override void Deselect() @@ -925,7 +948,11 @@ namespace Barotrauma new GUITextBlock(new RectTransform(textLabelSize, parent.RectTransform), TextManager.Get("HostServerButton"), textAlignment: Alignment.Center, font: GUI.LargeFont) { ForceUpperCase = true }; var label = new GUITextBlock(new RectTransform(textLabelSize, parent.RectTransform), TextManager.Get("ServerName"), textAlignment: textAlignment); - serverNameBox = new GUITextBox(new RectTransform(textFieldSize, label.RectTransform, Anchor.CenterRight), textAlignment: textAlignment); + serverNameBox = new GUITextBox(new RectTransform(textFieldSize, label.RectTransform, Anchor.CenterRight), textAlignment: textAlignment) + { + MaxTextLength = NetConfig.ServerNameMaxLength, + OverflowClip = true + }; label = new GUITextBlock(new RectTransform(textLabelSize, parent.RectTransform), TextManager.Get("ServerPort"), textAlignment: textAlignment); portBox = new GUITextBox(new RectTransform(textFieldSize, label.RectTransform, Anchor.CenterRight), textAlignment: textAlignment) diff --git a/Barotrauma/BarotraumaClient/Source/Screens/NetLobbyScreen.cs b/Barotrauma/BarotraumaClient/Source/Screens/NetLobbyScreen.cs index d050187db..d392f2bfa 100644 --- a/Barotrauma/BarotraumaClient/Source/Screens/NetLobbyScreen.cs +++ b/Barotrauma/BarotraumaClient/Source/Screens/NetLobbyScreen.cs @@ -335,8 +335,12 @@ namespace Barotrauma new GUIFrame(new RectTransform(new Vector2(1.0f, 0.03f), rightInfoColumn.RectTransform), style: null); //server info ------------------------------------------------------------------ - - ServerName = new GUITextBox(new RectTransform(new Vector2(0.3f, 0.05f), infoFrameContent.RectTransform)); + + ServerName = new GUITextBox(new RectTransform(new Vector2(infoColumnContainer.RectTransform.RelativeSize.X, 0.05f), infoFrameContent.RectTransform)) + { + MaxTextLength = NetConfig.ServerNameMaxLength, + OverflowClip = true + }; ServerName.OnDeselected += (textBox, key) => { GameMain.Client.ServerSettings.ClientAdminWrite(ServerSettings.NetFlags.Name); diff --git a/Barotrauma/BarotraumaClient/Source/Screens/SteamWorkshopScreen.cs b/Barotrauma/BarotraumaClient/Source/Screens/SteamWorkshopScreen.cs index ce5b54c2d..af3414813 100644 --- a/Barotrauma/BarotraumaClient/Source/Screens/SteamWorkshopScreen.cs +++ b/Barotrauma/BarotraumaClient/Source/Screens/SteamWorkshopScreen.cs @@ -49,7 +49,7 @@ namespace Barotrauma { tabs = new GUIFrame[Enum.GetValues(typeof(Tab)).Length]; - menu = new GUIFrame(new RectTransform(new Vector2(0.6f, 0.8f), GUI.Canvas, Anchor.Center) { MinSize = new Point(GameMain.GraphicsHeight, 0) }); + menu = new GUIFrame(new RectTransform(new Vector2(0.85f, 0.8f), GUI.Canvas, Anchor.Center) { MinSize = new Point(GameMain.GraphicsHeight, 0) }); var container = new GUILayoutGroup(new RectTransform(new Vector2(0.95f, 0.85f), menu.RectTransform, Anchor.Center) { RelativeOffset = new Vector2(0.0f, 0.05f) }) { Stretch = true }; @@ -394,6 +394,7 @@ namespace Barotrauma { IsHorizontal = true, Stretch = true, + RelativeSpacing = 0.05f, CanBeFocused = false }; @@ -405,32 +406,6 @@ namespace Barotrauma if (item.Installed) { - if (listBox != publishedItemList && SteamManager.CheckWorkshopItemEnabled(item) && !SteamManager.CheckWorkshopItemUpToDate(item)) - { - new GUIButton(new RectTransform(new Vector2(0.4f, 0.5f), rightColumn.RectTransform, Anchor.BottomLeft), text: "Update") - { - UserData = "updatebutton", - IgnoreLayoutGroups = true, - OnClicked = (btn, userdata) => - { - if (SteamManager.UpdateWorkshopItem(item, out string errorMsg)) - { - new GUIMessageBox("", TextManager.GetWithVariable("WorkshopItemUpdated", "[itemname]", TextManager.EnsureUTF8(item.Title))); - } - else - { - DebugConsole.ThrowError(errorMsg); - new GUIMessageBox( - TextManager.Get("Error"), - TextManager.GetWithVariables("WorkshopItemUpdateFailed", new string[2] { "[itemname]", "[errormessage]" }, new string[2] { TextManager.EnsureUTF8(item.Title), errorMsg })); - } - btn.Enabled = false; - btn.Visible = false; - return true; - } - }; - } - GUITickBox enabledTickBox = null; try { @@ -476,6 +451,33 @@ namespace Barotrauma }; } } + + if (listBox != publishedItemList && SteamManager.CheckWorkshopItemEnabled(item) && !SteamManager.CheckWorkshopItemUpToDate(item)) + { + new GUIButton(new RectTransform(new Vector2(0.4f, 0.5f), rightColumn.RectTransform, Anchor.BottomLeft), text: TextManager.Get("WorkshopItemUpdate")) + { + UserData = "updatebutton", + Font = GUI.SmallFont, + OnClicked = (btn, userdata) => + { + if (SteamManager.UpdateWorkshopItem(item, out string errorMsg)) + { + new GUIMessageBox("", TextManager.GetWithVariable("WorkshopItemUpdated", "[itemname]", TextManager.EnsureUTF8(item.Title))); + } + else + { + DebugConsole.ThrowError(errorMsg); + new GUIMessageBox( + TextManager.Get("Error"), + TextManager.GetWithVariables("WorkshopItemUpdateFailed", new string[2] { "[itemname]", "[errormessage]" }, new string[2] { TextManager.EnsureUTF8(item.Title), errorMsg })); + } + btn.Enabled = false; + btn.Visible = false; + return true; + } + }; + } + } else if (item.Downloading) { @@ -900,7 +902,7 @@ namespace Barotrauma new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), topRightColumn.RectTransform), TextManager.Get("WorkshopItemDescription")); var descriptionContainer = new GUIListBox(new RectTransform(new Vector2(1.0f, 0.4f), topRightColumn.RectTransform)); - var descriptionBox = new GUITextBox(new RectTransform(Vector2.One, descriptionContainer.Content.RectTransform), itemEditor.Description, textAlignment: Alignment.TopLeft, wrap: true); + var descriptionBox = new GUITextBox(new RectTransform(Vector2.One, descriptionContainer.Content.RectTransform), itemEditor.Description, textAlignment: Alignment.TopLeft, font: GUI.SmallFont, wrap: true); descriptionBox.OnTextChanged += (textBox, text) => { Vector2 textSize = textBox.Font.MeasureString(descriptionBox.WrappedText); @@ -1081,6 +1083,7 @@ namespace Barotrauma { InitialDirectory = Path.GetFullPath(SteamManager.WorkshopItemStagingFolder), Title = TextManager.Get("workshopitemaddfiles"), + Multiselect = true }; if (ofd.ShowDialog() == DialogResult.OK) { @@ -1228,7 +1231,7 @@ namespace Barotrauma private void OnAddFilesSelected(string[] fileNames) { if (fileNames == null) { return; } - for(int i = 0; i < fileNames.Length; i++) + for (int i = 0; i < fileNames.Length; i++) { string file = fileNames[i]; if (string.IsNullOrEmpty(file)) { continue; } @@ -1258,6 +1261,7 @@ namespace Barotrauma itemContentPackage.AddFile(filePathRelativeToStagingFolder, ContentType.None); } } + itemContentPackage.Save(itemContentPackage.Path); RefreshCreateItemFileList(); } @@ -1331,6 +1335,7 @@ namespace Barotrauma OnClicked = (btn, userdata) => { itemContentPackage.RemoveFile(contentFile); + itemContentPackage.Save(itemContentPackage.Path); RefreshCreateItemFileList(); return true; } @@ -1346,7 +1351,7 @@ namespace Barotrauma { if (itemContentPackage == null || itemEditor == null) return; - SteamManager.StartPublishItem(itemContentPackage, itemEditor); + SteamManager.StartPublishItem(itemContentPackage, itemEditor); CoroutineManager.StartCoroutine(WaitForPublish(itemEditor), "WaitForPublish"); } diff --git a/Barotrauma/BarotraumaClient/Source/Screens/SubEditorScreen.cs b/Barotrauma/BarotraumaClient/Source/Screens/SubEditorScreen.cs index a45f872e6..e69d4a663 100644 --- a/Barotrauma/BarotraumaClient/Source/Screens/SubEditorScreen.cs +++ b/Barotrauma/BarotraumaClient/Source/Screens/SubEditorScreen.cs @@ -2109,10 +2109,7 @@ namespace Barotrauma public override void AddToGUIUpdateList() { - if (MapEntity.SelectedList.Count == 1) - { - MapEntity.SelectedList[0].AddToGUIUpdateList(); - } + MapEntity.FilteredSelectedList.FirstOrDefault()?.AddToGUIUpdateList(); if (MapEntity.HighlightedListBox != null) { MapEntity.HighlightedListBox.AddToGUIUpdateList(); @@ -2293,9 +2290,9 @@ namespace Barotrauma dummyCharacter.SelectedConstruction = null; }*/ } - else if (MapEntity.SelectedList.Count == 1) + else if (MapEntity.FilteredSelectedList.Count == 1) { - (MapEntity.SelectedList[0] as Item)?.UpdateHUD(cam, dummyCharacter, (float)deltaTime); + (MapEntity.FilteredSelectedList[0] as Item)?.UpdateHUD(cam, dummyCharacter, (float)deltaTime); } CharacterHUD.Update((float)deltaTime, dummyCharacter, cam); diff --git a/Barotrauma/BarotraumaClient/Source/Utils/OpenFileDialog.cs b/Barotrauma/BarotraumaClient/Source/Utils/OpenFileDialog.cs index b7e5dba5c..54257c19a 100644 --- a/Barotrauma/BarotraumaClient/Source/Utils/OpenFileDialog.cs +++ b/Barotrauma/BarotraumaClient/Source/Utils/OpenFileDialog.cs @@ -18,34 +18,33 @@ namespace Barotrauma public string FileName { get; private set; } public string[] FileNames { get; private set; } - public OpenFileDialog() - { - ofd = new System.Windows.Forms.OpenFileDialog(); - } + public OpenFileDialog() { } public System.Windows.Forms.DialogResult ShowDialog() { + ofd = new System.Windows.Forms.OpenFileDialog(); ofd.Multiselect = Multiselect; ofd.InitialDirectory = InitialDirectory; ofd.Filter = Filter; ofd.Title = Title; -#if LINUX + System.Windows.Forms.DialogResult result; +#if LINUX || OSX var wrapperForm = new WrapperForm(ofd); System.Windows.Forms.Application.Run(wrapperForm); - System.Windows.Forms.Application.Exit(); FileName = wrapperForm.FileName; FileNames = wrapperForm.FileNames; - return wrapperForm.Result; + result = wrapperForm.Result; #else - var result = ofd.ShowDialog(); + result = ofd.ShowDialog(); FileName = ofd.FileName; FileNames = ofd.FileNames; - return result; #endif + ofd = null; + return result; } -#if LINUX +#if LINUX || OSX private class WrapperForm : System.Windows.Forms.Form { private System.Windows.Forms.OpenFileDialog ofd; @@ -66,7 +65,7 @@ namespace Barotrauma FileName = ofd.FileName; FileNames = ofd.FileNames; System.Threading.Thread.Sleep(100); - this.Close(); + System.Windows.Forms.Application.Exit(); } } #endif diff --git a/Barotrauma/BarotraumaServer/Source/DebugConsole.cs b/Barotrauma/BarotraumaServer/Source/DebugConsole.cs index c06a6807b..a3d73eb15 100644 --- a/Barotrauma/BarotraumaServer/Source/DebugConsole.cs +++ b/Barotrauma/BarotraumaServer/Source/DebugConsole.cs @@ -167,7 +167,8 @@ namespace Barotrauma RewriteInputToCommandLine(input); } - Thread.Yield(); + //TODO: be more clever about it + Thread.Sleep(10); //sleep for 10ms to not pin the CPU super hard } } catch (ThreadAbortException) diff --git a/Barotrauma/BarotraumaServer/Source/Networking/GameServer.cs b/Barotrauma/BarotraumaServer/Source/Networking/GameServer.cs index 291ca50dc..586e28a2e 100644 --- a/Barotrauma/BarotraumaServer/Source/Networking/GameServer.cs +++ b/Barotrauma/BarotraumaServer/Source/Networking/GameServer.cs @@ -93,6 +93,10 @@ namespace Barotrauma.Networking { name = name.Replace(":", ""); name = name.Replace(";", ""); + if (name.Length > NetConfig.ServerNameMaxLength) + { + name = name.Substring(0, NetConfig.ServerNameMaxLength); + } this.name = name; diff --git a/Barotrauma/BarotraumaShared/SharedContent.projitems b/Barotrauma/BarotraumaShared/SharedContent.projitems index cc7685501..4780726aa 100644 --- a/Barotrauma/BarotraumaShared/SharedContent.projitems +++ b/Barotrauma/BarotraumaShared/SharedContent.projitems @@ -1295,15 +1295,6 @@ PreserveNewest - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - PreserveNewest diff --git a/Barotrauma/BarotraumaShared/Source/DebugConsole.cs b/Barotrauma/BarotraumaShared/Source/DebugConsole.cs index 572c7ae1d..bc79f5f24 100644 --- a/Barotrauma/BarotraumaShared/Source/DebugConsole.cs +++ b/Barotrauma/BarotraumaShared/Source/DebugConsole.cs @@ -380,7 +380,7 @@ namespace Barotrauma }; })); - commands.Add(new Command("banid", "banid [id]: Kick and ban the player with the specified client ID from the server.", (string[] args) => + commands.Add(new Command("banid", "banid [id]: Kick and ban the player with the specified client ID from the server. You can see the IDs of the clients using the command \"clientlist\".", (string[] args) => { if (GameMain.NetworkMember == null || args.Length == 0) return; diff --git a/Barotrauma/BarotraumaShared/Source/Items/Components/Door.cs b/Barotrauma/BarotraumaShared/Source/Items/Components/Door.cs index 50de362ac..7ac15962c 100644 --- a/Barotrauma/BarotraumaShared/Source/Items/Components/Door.cs +++ b/Barotrauma/BarotraumaShared/Source/Items/Components/Door.cs @@ -22,7 +22,6 @@ namespace Barotrauma.Items.Components private float openState; private Sprite doorSprite, weldedSprite, brokenSprite; private bool scaleBrokenSprite, fadeBrokenSprite; - private bool createdNewGap; private bool autoOrientGap; private bool isStuck; @@ -89,12 +88,7 @@ namespace Barotrauma.Items.Components { if (linkedGap == null) { - linkedGap = e as Gap; - if (linkedGap != null) - { - linkedGap.PassAmbientLight = Window != Rectangle.Empty; - return linkedGap; - } + GetLinkedGap(); } return linkedGap; } @@ -116,16 +110,11 @@ namespace Barotrauma.Items.Components rect.X -= 5; rect.Width += 10; } - linkedGap = new Gap(rect, !IsHorizontal, Item.Submarine) { - Submarine = item.Submarine, - PassAmbientLight = Window != Rectangle.Empty, - Open = openState + Submarine = item.Submarine }; item.linkedTo.Add(linkedGap); - createdNewGap = true; - return linkedGap; } RefreshLinkedGap(); } @@ -386,7 +375,8 @@ namespace Barotrauma.Items.Components LinkedGap.AutoOrient(); } LinkedGap.Open = openState; - if (createdNewGap && autoOrientGap) linkedGap.AutoOrient(); + LinkedGap.PassAmbientLight = Window != Rectangle.Empty; + } public override void OnMapLoaded() { diff --git a/Barotrauma/BarotraumaShared/Source/Items/Item.cs b/Barotrauma/BarotraumaShared/Source/Items/Item.cs index 964e2651c..d62ab48bb 100644 --- a/Barotrauma/BarotraumaShared/Source/Items/Item.cs +++ b/Barotrauma/BarotraumaShared/Source/Items/Item.cs @@ -285,7 +285,7 @@ namespace Barotrauma get { return spriteColor; } } - public bool IsFullCondition => Condition >= MaxCondition; + public bool IsFullCondition => MathUtils.NearlyEqual(Condition, MaxCondition); public float MaxCondition => Prefab.Health; public float ConditionPercentage => MathUtils.Percentage(Condition, MaxCondition); @@ -304,6 +304,7 @@ namespace Barotrauma if (Indestructible) return; float prev = condition; + condition = MathHelper.Clamp(value, 0.0f, Prefab.Health); if (condition == 0.0f && prev > 0.0f) { diff --git a/Barotrauma/BarotraumaShared/Source/Map/ItemAssemblyPrefab.cs b/Barotrauma/BarotraumaShared/Source/Map/ItemAssemblyPrefab.cs index 736acb775..3e1024dfa 100644 --- a/Barotrauma/BarotraumaShared/Source/Map/ItemAssemblyPrefab.cs +++ b/Barotrauma/BarotraumaShared/Source/Map/ItemAssemblyPrefab.cs @@ -107,7 +107,7 @@ namespace Barotrauma if (Screen.Selected == GameMain.SubEditorScreen) { MapEntity.SelectedList.Clear(); - MapEntity.SelectedList.AddRange(entities); + entities.ForEach(e => MapEntity.AddSelection(e)); } #endif return entities; diff --git a/Barotrauma/BarotraumaShared/Source/Utils/SaveUtil.cs b/Barotrauma/BarotraumaShared/Source/Utils/SaveUtil.cs index acbe640cb..23c9465fa 100644 --- a/Barotrauma/BarotraumaShared/Source/Utils/SaveUtil.cs +++ b/Barotrauma/BarotraumaShared/Source/Utils/SaveUtil.cs @@ -378,8 +378,6 @@ namespace Barotrauma Thread.Sleep(250); } } - - return true; } @@ -470,7 +468,20 @@ namespace Barotrauma foreach (DirectoryInfo di in dir.GetDirectories()) { ClearFolder(di.FullName, ignoredFileNames); - di.Delete(); + int maxRetries = 4; + for (int i = 0; i <= maxRetries; i++) + { + try + { + di.Delete(); + break; + } + catch (IOException) + { + if (i >= maxRetries) { throw; } + Thread.Sleep(250); + } + } } } } diff --git a/Barotrauma/BarotraumaShared/Submarines/Berilia.sub b/Barotrauma/BarotraumaShared/Submarines/Berilia.sub index b8903bf84..7d10e0914 100644 Binary files a/Barotrauma/BarotraumaShared/Submarines/Berilia.sub and b/Barotrauma/BarotraumaShared/Submarines/Berilia.sub differ