diff --git a/Barotrauma/BarotraumaClient/Properties/AssemblyInfo.cs b/Barotrauma/BarotraumaClient/Properties/AssemblyInfo.cs index 8e6e3a82f..fd04d73aa 100644 --- a/Barotrauma/BarotraumaClient/Properties/AssemblyInfo.cs +++ b/Barotrauma/BarotraumaClient/Properties/AssemblyInfo.cs @@ -31,5 +31,5 @@ using System.Runtime.InteropServices; // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("0.9.0.6")] -[assembly: AssemblyFileVersion("0.9.0.6")] +[assembly: AssemblyVersion("0.9.0.5")] +[assembly: AssemblyFileVersion("0.9.0.5")] 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 ddbdb63cc..38d0135f5 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; } } 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/GameClient.cs b/Barotrauma/BarotraumaClient/Source/Networking/GameClient.cs index 4b910e119..bcf031886 100644 --- a/Barotrauma/BarotraumaClient/Source/Networking/GameClient.cs +++ b/Barotrauma/BarotraumaClient/Source/Networking/GameClient.cs @@ -2047,13 +2047,15 @@ namespace Barotrauma.Networking client.SendMessage(msg, NetDeliveryMethod.ReliableUnordered); } - public void SetupNewCampaign(Submarine sub, string savePath, string mapSeed) + public void SetupNewCampaign(Submarine sub, string saveName, string mapSeed) { + saveName = Path.GetFileNameWithoutExtension(saveName); + NetOutgoingMessage msg = client.CreateMessage(); msg.Write((byte)ClientPacketHeader.CAMPAIGN_SETUP_INFO); msg.Write(true); msg.WritePadBits(); - msg.Write(savePath); + msg.Write(saveName); msg.Write(mapSeed); msg.Write(sub.Name); msg.Write(sub.MD5Hash.Hash); diff --git a/Barotrauma/BarotraumaClient/Source/Networking/SteamManager.cs b/Barotrauma/BarotraumaClient/Source/Networking/SteamManager.cs index 4b27e024c..224623330 100644 --- a/Barotrauma/BarotraumaClient/Source/Networking/SteamManager.cs +++ b/Barotrauma/BarotraumaClient/Source/Networking/SteamManager.cs @@ -590,12 +590,19 @@ namespace Barotrauma.Steam } else { - DebugConsole.ThrowError("Publishing workshop item " + item.Title + " failed. " + item.Error); + DebugConsole.NewMessage("Publishing workshop item " + item.Title + " failed. " + item.Error, Microsoft.Xna.Framework.Color.Red); } 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/Networking/WhiteList.cs b/Barotrauma/BarotraumaClient/Source/Networking/WhiteList.cs index 120fdf0bd..ff30c85a9 100644 --- a/Barotrauma/BarotraumaClient/Source/Networking/WhiteList.cs +++ b/Barotrauma/BarotraumaClient/Source/Networking/WhiteList.cs @@ -210,7 +210,6 @@ namespace Barotrauma.Networking { ip = "IP concealed by host"; } - DebugConsole.NewMessage("nerd: " + name, Color.Lime); whitelistedPlayers.Add(new WhiteListedPlayer(name, uniqueIdentifier, ip)); } 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..e6f273ba7 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"); } @@ -1381,9 +1386,20 @@ namespace Barotrauma } else { - new GUIMessageBox( - TextManager.Get("Error"), - TextManager.GetWithVariable("WorkshopItemPublishFailed", "[itemname]", TextManager.EnsureUTF8(item.Title)) + item.Error); + string errorMsg = item.ErrorCode.HasValue ? + TextManager.Get("WorkshopPublishError." + item.ErrorCode.Value.ToString(), returnNull: true) : + null; + + if (errorMsg == null) + { + new GUIMessageBox( + TextManager.Get("Error"), + TextManager.GetWithVariable("WorkshopItemPublishFailed", "[itemname]", TextManager.EnsureUTF8(item.Title)) + item.Error); + } + else + { + new GUIMessageBox(TextManager.Get("Error"), errorMsg); + } } createItemFrame.ClearChildren(); 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/Properties/AssemblyInfo.cs b/Barotrauma/BarotraumaServer/Properties/AssemblyInfo.cs index 2ccbcdb86..da654b402 100644 --- a/Barotrauma/BarotraumaServer/Properties/AssemblyInfo.cs +++ b/Barotrauma/BarotraumaServer/Properties/AssemblyInfo.cs @@ -31,5 +31,5 @@ using System.Runtime.InteropServices; // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("0.9.0.6")] -[assembly: AssemblyFileVersion("0.9.0.6")] +[assembly: AssemblyVersion("0.9.0.5")] +[assembly: AssemblyFileVersion("0.9.0.5")] diff --git a/Barotrauma/BarotraumaServer/Source/DebugConsole.cs b/Barotrauma/BarotraumaServer/Source/DebugConsole.cs index c06a6807b..f097ff73b 100644 --- a/Barotrauma/BarotraumaServer/Source/DebugConsole.cs +++ b/Barotrauma/BarotraumaServer/Source/DebugConsole.cs @@ -90,7 +90,16 @@ namespace Barotrauma while (queuedMessages.Count > 0) { ColoredText msg = queuedMessages.Dequeue(); - + if (GameSettings.SaveDebugConsoleLogs) + { + unsavedMessages.Add(msg); + if (unsavedMessages.Count >= messagesPerFile) + { + SaveLogs(); + unsavedMessages.Clear(); + } + } + string msgTxt = msg.Text; if (msg.IsCommand) commandMemory.Add(msgTxt); @@ -167,7 +176,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..6dbaf7cb0 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; @@ -724,7 +728,7 @@ namespace Barotrauma.Networking bool isNew = inc.ReadBoolean(); inc.ReadPadBits(); if (isNew) { - string savePath = inc.ReadString(); + string saveName = inc.ReadString(); string seed = inc.ReadString(); string subName = inc.ReadString(); string subHash = inc.ReadString(); @@ -739,7 +743,11 @@ namespace Barotrauma.Networking } else { - if (connectedClient.HasPermission(ClientPermissions.SelectMode)) MultiPlayerCampaign.StartNewCampaign(savePath, matchingSub.FilePath, seed); + string localSavePath = SaveUtil.CreateSavePath(SaveUtil.SaveType.Multiplayer, saveName); + if (connectedClient.HasPermission(ClientPermissions.SelectMode)) + { + MultiPlayerCampaign.StartNewCampaign(localSavePath, matchingSub.FilePath, seed); + } } } else diff --git a/Barotrauma/BarotraumaShared/SharedContent.projitems b/Barotrauma/BarotraumaShared/SharedContent.projitems index 8987fe9ea..4780726aa 100644 --- a/Barotrauma/BarotraumaShared/SharedContent.projitems +++ b/Barotrauma/BarotraumaShared/SharedContent.projitems @@ -1295,15 +1295,6 @@ PreserveNewest - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - PreserveNewest @@ -2313,7 +2304,7 @@ PreserveNewest - Never + PreserveNewest diff --git a/Barotrauma/BarotraumaShared/Source/Characters/Character.cs b/Barotrauma/BarotraumaShared/Source/Characters/Character.cs index 2b6f9f194..2d122b966 100644 --- a/Barotrauma/BarotraumaShared/Source/Characters/Character.cs +++ b/Barotrauma/BarotraumaShared/Source/Characters/Character.cs @@ -840,35 +840,20 @@ namespace Barotrauma { if (string.IsNullOrEmpty(humanConfigFile)) { - humanConfigFile = GetConfigFile("Human"); + humanConfigFile = GameMain.Instance.GetFilesOfType(ContentType.Character)? + .FirstOrDefault(c => Path.GetFileName(c).ToLowerInvariant() == "human.xml"); + + if (humanConfigFile == null) + { + DebugConsole.ThrowError($"Couldn't find a human config file from the selected content packages!"); + DebugConsole.ThrowError($"(The config file must end with \"human.xml\")"); + return string.Empty; + } } - return characterConfigFiles; + return humanConfigFile; } } - public static string GetConfigFile(string speciesName, ContentPackage contentPackage = null) - { - string configFile = null; - if (contentPackage == null) - { - configFile = GameMain.Instance.GetFilesOfType(ContentType.Character, searchAllContentPackages: true) - .FirstOrDefault(c => Path.GetFileName(c).ToLowerInvariant() == $"{speciesName.ToLowerInvariant()}.xml"); - } - else - { - configFile = contentPackage.GetFilesOfType(ContentType.Character)? - .FirstOrDefault(c => Path.GetFileName(c).ToLowerInvariant() == $"{speciesName.ToLowerInvariant()}.xml"); - } - - if (configFile == null) - { - DebugConsole.ThrowError($"Couldn't find a config file for {speciesName} from the selected content packages!"); - DebugConsole.ThrowError($"(The config file must end with \"{speciesName}.xml\")"); - return string.Empty; - } - return configFile; - } - private static IEnumerable characterConfigFiles; private static IEnumerable CharacterConfigFiles { @@ -882,12 +867,16 @@ namespace Barotrauma } } + /// + /// Searches for a character config file from all currently selected content packages, + /// or from a specific package if the contentPackage parameter is given. + /// public static string GetConfigFile(string speciesName, ContentPackage contentPackage = null) { string configFile = null; if (contentPackage == null) { - configFile = GameMain.Instance.GetFilesOfType(ContentType.Character, searchAllContentPackages: true) + configFile = GameMain.Instance.GetFilesOfType(ContentType.Character) .FirstOrDefault(c => Path.GetFileName(c).ToLowerInvariant() == $"{speciesName.ToLowerInvariant()}.xml"); } else 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 8a8725e0b..49fa9b7dd 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) { @@ -1554,7 +1555,7 @@ namespace Barotrauma public void Use(float deltaTime, Character character = null, Limb targetLimb = null) { - if (RequireAimToUse && !character.IsKeyDown(InputType.Aim)) + if (RequireAimToUse && (character == null || !character.IsKeyDown(InputType.Aim))) { return; } diff --git a/Barotrauma/BarotraumaShared/Source/Items/RelatedItem.cs b/Barotrauma/BarotraumaShared/Source/Items/RelatedItem.cs index 5317f2df1..7c907cd87 100644 --- a/Barotrauma/BarotraumaShared/Source/Items/RelatedItem.cs +++ b/Barotrauma/BarotraumaShared/Source/Items/RelatedItem.cs @@ -17,7 +17,8 @@ namespace Barotrauma } public bool IsOptional { get; set; } - + public bool MatchOnEmpty { get; set; } + public bool IgnoreInEditor { get; set; } private string[] excludedIdentifiers; @@ -227,6 +228,7 @@ namespace Barotrauma ri.IsOptional = element.GetAttributeBool("optional", false); ri.IgnoreInEditor = element.GetAttributeBool("ignoreineditor", false); + ri.MatchOnEmpty = element.GetAttributeBool("matchonempty", false); return ri; } } diff --git a/Barotrauma/BarotraumaShared/Source/Map/Entity.cs b/Barotrauma/BarotraumaShared/Source/Map/Entity.cs index 54d21b2ee..60ff02152 100644 --- a/Barotrauma/BarotraumaShared/Source/Map/Entity.cs +++ b/Barotrauma/BarotraumaShared/Source/Map/Entity.cs @@ -9,6 +9,7 @@ namespace Barotrauma class Entity : ISpatialEntity { public const ushort NullEntityID = 0; + public const ushort EntitySpawnerID = ushort.MaxValue; private static Dictionary dictionary = new Dictionary(); public static List GetEntityList() @@ -43,12 +44,19 @@ namespace Barotrauma } set { + if (this is EntitySpawner) { return; } if (value == NullEntityID) { DebugConsole.ThrowError("Cannot set the ID of an entity to " + NullEntityID + "! The value is reserved for entity events referring to a non-existent (e.g. removed) entity.\n" + Environment.StackTrace); return; } + if (value == EntitySpawnerID) + { + DebugConsole.ThrowError("Cannot set the ID of an entity to " + EntitySpawnerID + + "! The value is reserved for EntitySpawner.\n" + Environment.StackTrace); + return; + } if (dictionary.TryGetValue(id, out Entity thisEntity) && thisEntity == this) { @@ -107,15 +115,17 @@ namespace Barotrauma this.Submarine = submarine; //give a unique ID - id = FindFreeID(submarine == null ? (ushort)1 : submarine.IdOffset); - + id = this is EntitySpawner ? + EntitySpawnerID : + FindFreeID(submarine == null ? (ushort)1 : submarine.IdOffset); + dictionary.Add(id, this); } public static ushort FindFreeID(ushort idOffset = 0) { - //ushort.MaxValue - 1 because 0 is a reserved value - if (dictionary.Count >= ushort.MaxValue - 1) + //ushort.MaxValue - 2 because 0 and ushort.MaxValue are reserved values + if (dictionary.Count >= ushort.MaxValue - 2) { throw new Exception("Maximum amount of entities (" + (ushort.MaxValue - 1) + ") reached!"); } 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/Map/Levels/Level.cs b/Barotrauma/BarotraumaShared/Source/Map/Levels/Level.cs index 41b29c95a..6b469c300 100644 --- a/Barotrauma/BarotraumaShared/Source/Map/Levels/Level.cs +++ b/Barotrauma/BarotraumaShared/Source/Map/Levels/Level.cs @@ -1274,6 +1274,8 @@ namespace Barotrauma } } + DebugConsole.Log("Generating level resources..."); + for (int i = 0; i < generationParams.ItemCount; i++) { var selectedPrefab = ToolBox.SelectWeightedRandom( @@ -1286,6 +1288,7 @@ namespace Barotrauma var selectedEdge = selectedCell.Edges.GetRandom(e => e.IsSolid && !e.OutsideLevel, Rand.RandSync.Server); if (selectedEdge == null) continue; + float edgePos = Rand.Range(0.0f, 1.0f, Rand.RandSync.Server); Vector2 selectedPos = Vector2.Lerp(selectedEdge.Point1, selectedEdge.Point2, edgePos); Vector2 edgeNormal = selectedEdge.GetNormal(selectedCell); @@ -1306,6 +1309,8 @@ namespace Barotrauma #endif } } + + DebugConsole.Log("Level resources generated"); } public Vector2 GetRandomItemPos(PositionType spawnPosType, float randomSpread, float minDistFromSubs, float offsetFromWall = 10.0f) diff --git a/Barotrauma/BarotraumaShared/Source/Map/Levels/Ruins/RuinGenerator.cs b/Barotrauma/BarotraumaShared/Source/Map/Levels/Ruins/RuinGenerator.cs index 86a73d3c2..70813cd69 100644 --- a/Barotrauma/BarotraumaShared/Source/Map/Levels/Ruins/RuinGenerator.cs +++ b/Barotrauma/BarotraumaShared/Source/Map/Levels/Ruins/RuinGenerator.cs @@ -1022,12 +1022,12 @@ namespace Barotrauma.RuinGeneration { targetEntity = ruinEntities.GetRandom(e => e.Room == targetRoom && - e.Entity.prefab?.Identifier == connection.TargetEntityIdentifier)?.Entity; + e.Entity.prefab?.Identifier == connection.TargetEntityIdentifier, Rand.RandSync.Server)?.Entity; } } else { - targetEntity = ruinEntities.GetRandom(e => e.Entity.prefab?.Identifier == connection.TargetEntityIdentifier)?.Entity; + targetEntity = ruinEntities.GetRandom(e => e.Entity.prefab?.Identifier == connection.TargetEntityIdentifier, Rand.RandSync.Server)?.Entity; } if (targetEntity == null) continue; diff --git a/Barotrauma/BarotraumaShared/Source/Map/Structure.cs b/Barotrauma/BarotraumaShared/Source/Map/Structure.cs index f8f14717d..7cf65a8bf 100644 --- a/Barotrauma/BarotraumaShared/Source/Map/Structure.cs +++ b/Barotrauma/BarotraumaShared/Source/Map/Structure.cs @@ -366,20 +366,6 @@ namespace Barotrauma return Name; } - partial void InitProjSpecific(); - - public override string ToString() - { - return Name; - } - - partial void InitProjSpecific(); - - public override string ToString() - { - return Name; - } - public override MapEntity Clone() { var clone = new Structure(rect, Prefab, Submarine) diff --git a/Barotrauma/BarotraumaShared/Source/Map/Submarine.cs b/Barotrauma/BarotraumaShared/Source/Map/Submarine.cs index 1a31b77c7..eb3714650 100644 --- a/Barotrauma/BarotraumaShared/Source/Map/Submarine.cs +++ b/Barotrauma/BarotraumaShared/Source/Map/Submarine.cs @@ -1404,7 +1404,6 @@ namespace Barotrauma } - ID = (ushort)(ushort.MaxValue - 1 - Submarine.loaded.IndexOf(this)); } diff --git a/Barotrauma/BarotraumaShared/Source/Physics/PhysicsBody.cs b/Barotrauma/BarotraumaShared/Source/Physics/PhysicsBody.cs index 17d762f18..5484e3ffe 100644 --- a/Barotrauma/BarotraumaShared/Source/Physics/PhysicsBody.cs +++ b/Barotrauma/BarotraumaShared/Source/Physics/PhysicsBody.cs @@ -375,7 +375,7 @@ namespace Barotrauma //Enum.TryParse(element.GetAttributeString("bodytype", "Dynamic"), out BodyType bodyType); body.BodyType = BodyType.Dynamic; body.CollisionCategories = Physics.CollisionItem; - body.CollidesWith = Physics.CollisionWall | Physics.CollisionLevel; + body.CollidesWith = Physics.CollisionWall | Physics.CollisionLevel | Physics.CollisionPlatform; body.Friction = element.GetAttributeFloat("friction", 0.3f); body.Restitution = element.GetAttributeFloat("restitution", 0.05f); body.UserData = this; diff --git a/Barotrauma/BarotraumaShared/Source/StatusEffects/StatusEffect.cs b/Barotrauma/BarotraumaShared/Source/StatusEffects/StatusEffect.cs index dfe562c88..6c3210466 100644 --- a/Barotrauma/BarotraumaShared/Source/StatusEffects/StatusEffect.cs +++ b/Barotrauma/BarotraumaShared/Source/StatusEffects/StatusEffect.cs @@ -424,6 +424,7 @@ namespace Barotrauma public virtual bool HasRequiredConditions(List targets) { if (!propertyConditionals.Any()) return true; + if (requiredItems.All(ri => ri.MatchOnEmpty) && targets.Count == 0) return true; switch (conditionalComparison) { case PropertyConditional.Comparison.Or: 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 diff --git a/Barotrauma/BarotraumaShared/changelog.txt b/Barotrauma/BarotraumaShared/changelog.txt index 0b04fa32e..7092e37b0 100644 --- a/Barotrauma/BarotraumaShared/changelog.txt +++ b/Barotrauma/BarotraumaShared/changelog.txt @@ -1,10 +1,3 @@ ---------------------------------------------------------------------------------------------------------- -v0.9.0.6 ---------------------------------------------------------------------------------------------------------- - -- Fixed clients failing to connect to servers that have banned clients based on their Steam ID. -- Removed Berilia (vanilla sub that's not ready for release). - --------------------------------------------------------------------------------------------------------- v0.9.0.5 --------------------------------------------------------------------------------------------------------- diff --git a/Barotrauma_Solution.sln b/Barotrauma_Solution.sln index 88ed780fe..bea6b8805 100644 --- a/Barotrauma_Solution.sln +++ b/Barotrauma_Solution.sln @@ -338,6 +338,7 @@ Global {85232B20-074D-4723-B0C6-91495391E448}.ReleaseWindows|x86.ActiveCfg = ReleaseWindows|x86 {85232B20-074D-4723-B0C6-91495391E448}.ReleaseWindows|x86.Build.0 = ReleaseWindows|x86 {85232B20-074D-4723-B0C6-91495391E448}.ReleaseMac|Any CPU.Build.0 = ReleaseMac|x64 + {85232B20-074D-4723-B0C6-91495391E448}.DebugMac|Any CPU.Build.0 = DebugMac|x64 {A4610E4C-DD34-428B-BABB-779CA0B5993A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {A4610E4C-DD34-428B-BABB-779CA0B5993A}.Debug|Any CPU.Build.0 = Debug|Any CPU {A4610E4C-DD34-428B-BABB-779CA0B5993A}.Debug|x64.ActiveCfg = Debug|Any CPU diff --git a/Libraries/Facepunch.Steamworks/Interfaces/Workshop.Editor.cs b/Libraries/Facepunch.Steamworks/Interfaces/Workshop.Editor.cs index 36bcb330d..771768dbd 100644 --- a/Libraries/Facepunch.Steamworks/Interfaces/Workshop.Editor.cs +++ b/Libraries/Facepunch.Steamworks/Interfaces/Workshop.Editor.cs @@ -24,6 +24,7 @@ namespace Facepunch.Steamworks public bool Publishing { get; internal set; } public ItemType? Type { get; set; } public string Error { get; internal set; } = null; + public SteamNative.Result? ErrorCode { get; internal set; } = null; public string ChangeNote { get; set; } = ""; public uint WorkshopUploadAppId { get; set; } public string MetaData { get; set; } = null; @@ -99,6 +100,7 @@ namespace Facepunch.Steamworks Publishing = true; Error = null; + ErrorCode = null; if ( Id == 0 ) { @@ -129,12 +131,14 @@ namespace Facepunch.Steamworks if ( obj.Result == SteamNative.Result.OK && !Failed ) { Error = null; + ErrorCode = null; Id = obj.PublishedFileId; PublishChanges(); return; } Error = $"Error creating new file: {obj.Result} ({obj.PublishedFileId})"; + ErrorCode = obj.Result; Publishing = false; OnChangesSubmitted?.Invoke( (Result) obj.Result ); @@ -221,6 +225,7 @@ namespace Facepunch.Steamworks NeedToAgreeToWorkshopLegal = obj.UserNeedsToAcceptWorkshopLegalAgreement; Publishing = false; + ErrorCode = obj.Result; Error = obj.Result != SteamNative.Result.OK ? $"Error publishing changes: {obj.Result} ({NeedToAgreeToWorkshopLegal})" : null; diff --git a/Libraries/Facepunch.Steamworks/SteamNative/SteamNative.Enums.cs b/Libraries/Facepunch.Steamworks/SteamNative/SteamNative.Enums.cs index f57eb4066..5729eca44 100644 --- a/Libraries/Facepunch.Steamworks/SteamNative/SteamNative.Enums.cs +++ b/Libraries/Facepunch.Steamworks/SteamNative/SteamNative.Enums.cs @@ -20,7 +20,7 @@ namespace SteamNative // // EResult // - internal enum Result : int + public enum Result : int { OK = 1, Fail = 2,