diff --git a/Barotrauma/BarotraumaClient/Source/Characters/CharacterHealth.cs b/Barotrauma/BarotraumaClient/Source/Characters/CharacterHealth.cs index 4a7da5645..ef0f43c1d 100644 --- a/Barotrauma/BarotraumaClient/Source/Characters/CharacterHealth.cs +++ b/Barotrauma/BarotraumaClient/Source/Characters/CharacterHealth.cs @@ -95,15 +95,18 @@ namespace Barotrauma if (openHealthWindow == value) return; if (value != null && !value.UseHealthWindow) return; + openHealthWindow = value; + toggledThisFrame = true; + if (Character.Controlled == null) { return; } + if (value == null && - Character.Controlled?.SelectedCharacter?.CharacterHealth == openHealthWindow && + Character.Controlled?.SelectedCharacter?.CharacterHealth != null && + Character.Controlled.SelectedCharacter.CharacterHealth == openHealthWindow && !Character.Controlled.SelectedCharacter.CanInventoryBeAccessed) { Character.Controlled.DeselectCharacter(); } - openHealthWindow = value; - toggledThisFrame = true; Character.Controlled.ResetInteract = true; if (openHealthWindow != null) { diff --git a/Barotrauma/BarotraumaClient/Source/Characters/CharacterInfo.cs b/Barotrauma/BarotraumaClient/Source/Characters/CharacterInfo.cs index fa3d44c74..832c86fe6 100644 --- a/Barotrauma/BarotraumaClient/Source/Characters/CharacterInfo.cs +++ b/Barotrauma/BarotraumaClient/Source/Characters/CharacterInfo.cs @@ -157,10 +157,10 @@ namespace Barotrauma float scale = targetWidth * 0.9f / Portrait.size.X; Vector2 offset = Portrait.size * backgroundScale / 4; Portrait.Draw(spriteBatch, screenPos + offset, scale: scale, spriteEffect: SpriteEffects.FlipHorizontally); - if (AttachmentsSprites != null) + if (AttachmentSprites != null) { float depthStep = 0.000001f; - foreach (var attachment in AttachmentsSprites) + foreach (var attachment in AttachmentSprites) { DrawAttachmentSprite(spriteBatch, attachment, Portrait, screenPos + offset, scale, depthStep, SpriteEffects.FlipHorizontally); depthStep += depthStep; @@ -175,10 +175,10 @@ namespace Barotrauma { float scale = Math.Min(targetAreaSize.X / HeadSprite.size.X, targetAreaSize.Y / HeadSprite.size.Y); HeadSprite.Draw(spriteBatch, screenPos, scale: scale); - if (AttachmentsSprites != null) + if (AttachmentSprites != null) { float depthStep = 0.000001f; - foreach (var attachment in AttachmentsSprites) + foreach (var attachment in AttachmentSprites) { DrawAttachmentSprite(spriteBatch, attachment, HeadSprite, screenPos, scale, depthStep); depthStep += depthStep; @@ -189,7 +189,7 @@ namespace Barotrauma private void DrawAttachmentSprite(SpriteBatch spriteBatch, WearableSprite attachment, Sprite head, Vector2 drawPos, float scale, float depthStep, SpriteEffects spriteEffects = SpriteEffects.None) { - var list = AttachmentsSprites.ToList(); + var list = AttachmentSprites.ToList(); if (attachment.InheritSourceRect) { if (attachment.SheetIndex.HasValue) diff --git a/Barotrauma/BarotraumaClient/Source/GameMain.cs b/Barotrauma/BarotraumaClient/Source/GameMain.cs index 162a60801..ab0880a0e 100644 --- a/Barotrauma/BarotraumaClient/Source/GameMain.cs +++ b/Barotrauma/BarotraumaClient/Source/GameMain.cs @@ -177,9 +177,7 @@ namespace Barotrauma Config.WasGameUpdated = false; Config.Save(); } - - TextManager.LoadTextPacks(); - + ApplyGraphicsSettings(); Content.RootDirectory = "Content"; diff --git a/Barotrauma/BarotraumaClient/Source/GameSession/CrewManager.cs b/Barotrauma/BarotraumaClient/Source/GameSession/CrewManager.cs index 870f6f909..77cd7e14b 100644 --- a/Barotrauma/BarotraumaClient/Source/GameSession/CrewManager.cs +++ b/Barotrauma/BarotraumaClient/Source/GameSession/CrewManager.cs @@ -800,6 +800,12 @@ namespace Barotrauma style: "InnerFrame"); optionFrames.Add(optionFrame); + new GUIFrame(new RectTransform(Vector2.One, optionFrame.RectTransform, Anchor.Center), + style: "OuterGlow") + { + Color = Color.Black * 0.7f + }; + var optionContainer = new GUILayoutGroup(new RectTransform(new Vector2(0.9f), optionFrame.RectTransform, Anchor.Center)) { Stretch = true, @@ -868,7 +874,9 @@ namespace Barotrauma } int shadowSize = (int)(200 * GUI.Scale); orderTargetFrameShadow = new GUIFrame(new RectTransform(orderTargetFrame.Rect.Size + new Point(shadowSize * 2), GUI.Canvas) - { AbsoluteOffset = orderTargetFrame.Rect.Location - new Point(shadowSize) }, style: "OuterGlow", color: Color.Black * 0.65f); + { AbsoluteOffset = orderTargetFrame.Rect.Location - new Point(shadowSize) }, + style: "OuterGlow", + color: matchingItems.Count > 1 ? Color.Black * 0.9f : Color.Black * 0.7f); } private void DrawMiniMapOverlay(SpriteBatch spriteBatch, GUICustomComponent container) diff --git a/Barotrauma/BarotraumaClient/Source/Items/Components/Machines/Fabricator.cs b/Barotrauma/BarotraumaClient/Source/Items/Components/Machines/Fabricator.cs index 68982c692..dceb00e25 100644 --- a/Barotrauma/BarotraumaClient/Source/Items/Components/Machines/Fabricator.cs +++ b/Barotrauma/BarotraumaClient/Source/Items/Components/Machines/Fabricator.cs @@ -306,13 +306,13 @@ namespace Barotrauma.Items.Components new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), paddedFrame.RectTransform), text, textColor: inadequateSkills.Any() ? Color.Red : Color.LightGreen, font: GUI.SmallFont); } - } - - private bool SelectItem(Character user, FabricableItem selectedItem) - { - selectedItemFrame.ClearChildren(); - var paddedFrame = new GUILayoutGroup(new RectTransform(new Vector2(0.95f, 0.9f), selectedItemFrame.RectTransform, Anchor.Center)) { RelativeSpacing = 0.03f, Stretch = true }; + if (tooltip != null) + { + GUIComponent.DrawToolTip(spriteBatch, tooltip.Second, tooltip.First); + tooltip = null; + } + } float degreeOfSuccess = user == null ? 0.0f : DegreeOfSuccess(user, selectedItem.RequiredSkills); if (degreeOfSuccess > 0.5f) { degreeOfSuccess = 1.0f; } diff --git a/Barotrauma/BarotraumaClient/Source/Items/Components/Machines/MiniMap.cs b/Barotrauma/BarotraumaClient/Source/Items/Components/Machines/MiniMap.cs index 881a80755..e437af8fc 100644 --- a/Barotrauma/BarotraumaClient/Source/Items/Components/Machines/MiniMap.cs +++ b/Barotrauma/BarotraumaClient/Source/Items/Components/Machines/MiniMap.cs @@ -98,14 +98,20 @@ namespace Barotrauma.Items.Components private void DrawHUDBack(SpriteBatch spriteBatch, GUICustomComponent container) { + Hull mouseOnHull = null; hullInfoFrame.Visible = false; - if (item.Submarine == null || !hasPower) - { - foreach (Hull hull in Hull.hullList) - { - var hullFrame = submarineContainer.Children.First().FindChild(hull); - if (hullFrame == null) continue; + foreach (Hull hull in Hull.hullList) + { + var hullFrame = submarineContainer.Children.First().FindChild(hull); + if (hullFrame == null) { continue; } + + if (GUI.MouseOn == hullFrame || hullFrame.IsParentOf(GUI.MouseOn)) + { + mouseOnHull = hull; + } + if (item.Submarine == null || !hasPower) + { hullFrame.Color = Color.DarkCyan * 0.3f; hullFrame.Children.First().Color = Color.DarkCyan * 0.3f; } @@ -123,6 +129,7 @@ namespace Barotrauma.Items.Components if (hullData == null) { hullData = new HullData(); + GetLinkedHulls(hull, hullData.LinkedHulls); hullDatas.Add(hull, hullData); } @@ -171,13 +178,33 @@ namespace Barotrauma.Items.Components } } - if (GUI.MouseOn == hullFrame || hullFrame.IsParentOf(GUI.MouseOn)) + if (mouseOnHull == hull || + hullData.LinkedHulls.Contains(mouseOnHull)) { - hullInfoFrame.RectTransform.ScreenSpaceOffset = hullFrame.Rect.Center; + borderColor = Color.Lerp(borderColor, Color.White, 0.5f); + hullFrame.Children.First().Color = Color.White; + hullFrame.Color = borderColor; + } + else + { + hullFrame.Children.First().Color = Color.DarkCyan * 0.8f; + } + if (mouseOnHull == hull) + { + hullInfoFrame.RectTransform.ScreenSpaceOffset = hullFrame.Rect.Center; hullInfoFrame.Visible = true; hullNameText.Text = hull.RoomName; + foreach (Hull linkedHull in hullData.LinkedHulls) + { + gapOpenSum += linkedHull.ConnectedGaps.Where(g => !g.IsRoomToRoom).Sum(g => g.Open); + oxygenAmount += linkedHull.OxygenPercentage; + waterAmount += Math.Min(linkedHull.WaterVolume / linkedHull.Volume, 1.0f); + } + oxygenAmount /= (hullData.LinkedHulls.Count + 1); + waterAmount /= (hullData.LinkedHulls.Count + 1); + hullBreachText.Text = gapOpenSum > 0.1f ? TextManager.Get("MiniMapHullBreach") : ""; hullBreachText.TextColor = Color.Red; @@ -186,17 +213,11 @@ namespace Barotrauma.Items.Components hullWaterText.Text = waterAmount == null ? TextManager.Get("MiniMapWaterLevelUnavailable") : TextManager.Get("MiniMapWaterLevel") + ": " + (int)(waterAmount * 100.0f) + " %"; hullWaterText.TextColor = waterAmount == null ? Color.Red : Color.Lerp(Color.LightGreen, Color.Red, (float)waterAmount); - - borderColor = Color.Lerp(borderColor, Color.White, 0.5f); - hullFrame.Children.First().Color = Color.White; - } - else - { - hullFrame.Children.First().Color = Color.DarkCyan * 0.8f; } + hullFrame.Color = borderColor; } - + foreach (Submarine sub in subs) { if (sub.HullVertices == null) { continue; } @@ -222,5 +243,18 @@ namespace Barotrauma.Items.Components } } } + + private void GetLinkedHulls(Hull hull, List linkedHulls) + { + foreach (var linkedEntity in hull.linkedTo) + { + if (linkedEntity is Hull linkedHull) + { + if (linkedHulls.Contains(linkedHull)) { continue; } + linkedHulls.Add(linkedHull); + GetLinkedHulls(linkedHull, linkedHulls); + } + } + } } } diff --git a/Barotrauma/BarotraumaClient/Source/Map/Hull.cs b/Barotrauma/BarotraumaClient/Source/Map/Hull.cs index c623731a8..b8704f851 100644 --- a/Barotrauma/BarotraumaClient/Source/Map/Hull.cs +++ b/Barotrauma/BarotraumaClient/Source/Map/Hull.cs @@ -93,8 +93,11 @@ namespace Barotrauma { if (entity == this || !entity.IsHighlighted) continue; if (!entity.IsMouseOn(position)) continue; - - if (entity.Linkable && entity.linkedTo != null) entity.linkedTo.Add(this); + if (entity.Linkable && entity.linkedTo != null) + { + entity.linkedTo.Add(this); + linkedTo.Add(entity); + } } } else @@ -103,8 +106,12 @@ namespace Barotrauma { if (entity == this || !entity.IsHighlighted) continue; if (!entity.IsMouseOn(position)) continue; - - if (entity.linkedTo != null && entity.linkedTo.Contains(this)) entity.linkedTo.Remove(this); + if (entity.linkedTo != null && entity.linkedTo.Contains(this)) + { + entity.linkedTo.Remove(this); + linkedTo.Remove(entity); + + } } } } @@ -249,6 +256,33 @@ namespace Barotrauma new Vector2(rect.Width - 10, rect.Height - 10), isHighlighted ? Color.LightBlue * 0.5f : Color.Red * 0.5f, true, 0, (int)Math.Max((1.5f / GameScreen.Selected.Cam.Zoom), 1.0f)); } + + foreach (MapEntity e in linkedTo) + { + if (e is Hull) + { + Hull linkedHull = (Hull)e; + Rectangle connectedHullRect = e.Submarine == null ? + linkedHull.rect : + new Rectangle( + (int)(Submarine.DrawPosition.X + linkedHull.WorldPosition.X), + (int)(Submarine.DrawPosition.Y + linkedHull.WorldPosition.Y), + linkedHull.WorldRect.Width, linkedHull.WorldRect.Height); + + //center of the hull + Rectangle currentHullRect = Submarine == null ? + WorldRect : + new Rectangle( + (int)(Submarine.DrawPosition.X + WorldPosition.X), + (int)(Submarine.DrawPosition.Y + WorldPosition.Y), + WorldRect.Width, WorldRect.Height); + + GUI.DrawLine(spriteBatch, + new Vector2(currentHullRect.X, -currentHullRect.Y), + new Vector2(connectedHullRect.X, -connectedHullRect.Y), + Color.Green, width: 2); + } + } } public static void UpdateVertices(GraphicsDevice graphicsDevice, Camera cam, WaterRenderer renderer) diff --git a/Barotrauma/BarotraumaClient/Source/Map/Submarine.cs b/Barotrauma/BarotraumaClient/Source/Map/Submarine.cs index 7cdeae5fb..084a6b94b 100644 --- a/Barotrauma/BarotraumaClient/Source/Map/Submarine.cs +++ b/Barotrauma/BarotraumaClient/Source/Map/Submarine.cs @@ -284,8 +284,8 @@ namespace Barotrauma foreach (Entity entity in pointsOfInterest) { Vector2 relativePos = new Vector2( - (entity.WorldPosition.X - worldBorders.X) / Borders.Width, - (worldBorders.Y - entity.WorldPosition.Y) / Borders.Height); + (entity.WorldPosition.X - worldBorders.X) / worldBorders.Width, + (worldBorders.Y - entity.WorldPosition.Y) / worldBorders.Height); new GUIFrame(new RectTransform(new Point(1, 1), hullContainer.RectTransform) { RelativeOffset = relativePos }, style: null) { CanBeFocused = false, diff --git a/Barotrauma/BarotraumaClient/Source/Networking/GameClient.cs b/Barotrauma/BarotraumaClient/Source/Networking/GameClient.cs index 250d31cd6..898e1124f 100644 --- a/Barotrauma/BarotraumaClient/Source/Networking/GameClient.cs +++ b/Barotrauma/BarotraumaClient/Source/Networking/GameClient.cs @@ -1191,6 +1191,15 @@ namespace Barotrauma.Networking ConnectedClients.RemoveAt(i); } } + //remove clients that aren't present anymore + for (int i = ConnectedClients.Count - 1; i >= 0; i--) + { + if (!currentClients.Contains(ConnectedClients[i])) + { + GameMain.NetLobbyScreen.RemovePlayer(ConnectedClients[i].Name); + ConnectedClients.RemoveAt(i); + } + } Voting.AllowSubVoting = allowSubVoting; Voting.AllowModeVoting = allowModeVoting; diff --git a/Barotrauma/BarotraumaClient/Source/Screens/MainMenuScreen.cs b/Barotrauma/BarotraumaClient/Source/Screens/MainMenuScreen.cs index 0525f8ee8..5c7588f2a 100644 --- a/Barotrauma/BarotraumaClient/Source/Screens/MainMenuScreen.cs +++ b/Barotrauma/BarotraumaClient/Source/Screens/MainMenuScreen.cs @@ -163,6 +163,7 @@ namespace Barotrauma { steamWorkshopButton = new GUIButton(new RectTransform(new Vector2(1.0f, 0.1f), buttonsParent.RectTransform), TextManager.Get("SteamWorkshopButton"), style: "GUIButtonLarge") { + Enabled = false, OnClicked = SteamWorkshopClicked }; } @@ -363,6 +364,7 @@ namespace Barotrauma private bool SteamWorkshopClicked(GUIButton button, object obj) { + if (!Steam.SteamManager.IsInitialized) { return false; } GameMain.SteamWorkshopScreen.Select(); return true; } @@ -453,6 +455,10 @@ namespace Barotrauma } steamWorkshopButton.Enabled = Steam.SteamManager.IsInitialized; } +#else + joinServerButton.Enabled = true; + hostServerButton.Enabled = true; + steamWorkshopButton.Enabled = true; #endif } diff --git a/Barotrauma/BarotraumaClient/Source/Screens/NetLobbyScreen.cs b/Barotrauma/BarotraumaClient/Source/Screens/NetLobbyScreen.cs index f251a588c..e187f55f7 100644 --- a/Barotrauma/BarotraumaClient/Source/Screens/NetLobbyScreen.cs +++ b/Barotrauma/BarotraumaClient/Source/Screens/NetLobbyScreen.cs @@ -69,6 +69,9 @@ namespace Barotrauma private GUITextBox serverMessage; + private GUIButton faceSelectionLeft; + private GUIButton faceSelectionRight; + private float autoRestartTimer; //persistent characterinfo provided by the server @@ -715,17 +718,15 @@ namespace Barotrauma if (!playYourself.Selected) return; if (characterInfo == null) { - characterInfo = - new CharacterInfo(Character.HumanConfigFile, GameMain.NetworkMember.Name, GameMain.Config.CharacterGender, null) - { - Race = GameMain.Config.CharacterRace, - HeadSpriteId = GameMain.Config.CharacterHeadIndex, - HairIndex = GameMain.Config.CharacterHairIndex, - BeardIndex = GameMain.Config.CharacterBeardIndex, - MoustacheIndex = GameMain.Config.CharacterMoustacheIndex, - FaceAttachmentIndex = GameMain.Config.CharacterFaceAttachmentIndex, - }; - // Need to reload the attachments because the indices may have changed + characterInfo = new CharacterInfo(Character.HumanConfigFile, GameMain.NetworkMember.Name, GameMain.Config.CharacterGender, null) + { + Race = GameMain.Config.CharacterRace, + HairIndex = GameMain.Config.CharacterHairIndex, + BeardIndex = GameMain.Config.CharacterBeardIndex, + MoustacheIndex = GameMain.Config.CharacterMoustacheIndex, + FaceAttachmentIndex = GameMain.Config.CharacterFaceAttachmentIndex, + }; + characterInfo.Head.HeadSpriteId = GameMain.Config.CharacterHeadIndex; characterInfo.LoadHeadAttachments(); GameMain.NetworkMember.CharacterInfo = characterInfo; } @@ -744,11 +745,13 @@ namespace Barotrauma if (allowEditing) { - new GUIButton(new RectTransform(new Vector2(0.1f, 1.0f), headContainer.RectTransform), "", style: "GUIButtonHorizontalArrow") + faceSelectionLeft = new GUIButton(new RectTransform(new Vector2(0.1f, 1.0f), headContainer.RectTransform), "", style: "GUIButtonHorizontalArrow") { + Enabled = generatedHeads.UndoCount > 1, UserData = -1, - OnClicked = ToggleHead - }.Children.ForEach(c => c.SpriteEffects = SpriteEffects.FlipHorizontally); + OnClicked = SwitchHead + }; + faceSelectionLeft.Children.ForEach(c => c.SpriteEffects = SpriteEffects.FlipHorizontally); } new GUICustomComponent(new RectTransform(new Vector2(0.3f, 1.0f), headContainer.RectTransform), @@ -756,10 +759,10 @@ namespace Barotrauma if (allowEditing) { - new GUIButton(new RectTransform(new Vector2(0.1f, 1.0f), headContainer.RectTransform), style: "GUIButtonHorizontalArrow") + faceSelectionRight = new GUIButton(new RectTransform(new Vector2(0.1f, 1.0f), headContainer.RectTransform), style: "GUIButtonHorizontalArrow") { UserData = 1, - OnClicked = ToggleHead + OnClicked = SwitchHead }; new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.05f), infoContainer.RectTransform), @@ -1511,29 +1514,66 @@ namespace Barotrauma if ((prevSize == 1.0f && chatBox.BarScroll == 0.0f) || (prevSize < 1.0f && chatBox.BarScroll == 1.0f)) chatBox.BarScroll = 1.0f; } - // TODO: remember the previous head(s), check that the next is unique - private bool ToggleHead(GUIButton button, object userData) + private Memento generatedHeads = new Memento(); + + private bool SwitchHead(GUIButton button, object userData) { if (GameMain.NetworkMember.CharacterInfo == null) return true; int dir = (int)userData; var info = GameMain.NetworkMember.CharacterInfo; - info.SetRandomRace(); - info.SetRandomHead(); - info.LoadHeadAttachments(); - info.LoadHeadSprite(); + if (generatedHeads.Current == null) + { + // Add the current head in the memory + generatedHeads.Store(info.Head); + } + if (dir == 1) + { + // Try redo, if not possible, generate new + var previousHead = generatedHeads.Redo(); + if (previousHead == info.Head || previousHead == null) + { + // Generate new and add to the list + // If the head id is the same, regenerate until it's not + // The counter is there to prevent stack overflow if we for some reason cannot get unique ids (e.g. an issue with the head id range or simply if there is no heads defined). + int newHeadId = previousHead.HeadSpriteId; + int counter = 0; + while (newHeadId == previousHead.HeadSpriteId && counter < 10) + { + newHeadId = info.GetRandomHeadID(); + counter++; + } + info.Head = new CharacterInfo.HeadInfo(newHeadId) { gender = GameMain.Config.CharacterGender }; + generatedHeads.Store(info.Head); + } + else + { + info.Head = previousHead; + } + } + else + { + // Undo, if not possible, the button should be disabled + var previousHead = generatedHeads.Undo(); + if (previousHead != info.Head && previousHead != null) + { + info.Head = previousHead; + } + } + info.ReloadHeadAttachments(); StoreHead(); GameMain.Config.Save(); + faceSelectionLeft.Enabled = generatedHeads.UndoCount > 0; return true; } private bool SwitchGender(GUIButton button, object obj) { + generatedHeads.Clear(); Gender gender = (Gender)obj; var info = GameMain.NetworkMember.CharacterInfo; info.Gender = gender; info.SetRandomHead(); info.LoadHeadAttachments(); - info.LoadHeadSprite(); StoreHead(); GameMain.Config.Save(); return true; diff --git a/Barotrauma/BarotraumaClient/Source/Screens/ServerListScreen.cs b/Barotrauma/BarotraumaClient/Source/Screens/ServerListScreen.cs index 5a90448c0..6e971d407 100644 --- a/Barotrauma/BarotraumaClient/Source/Screens/ServerListScreen.cs +++ b/Barotrauma/BarotraumaClient/Source/Screens/ServerListScreen.cs @@ -714,9 +714,11 @@ namespace Barotrauma } catch (PingException ex) { - string errorMsg = "Failed to ping a server (" + serverInfo.ServerName + ", " + serverInfo.IP + ") - " + ex.Message; + string errorMsg = "Failed to ping a server (" + serverInfo.ServerName + ", " + serverInfo.IP + ") - " + (ex?.InnerException?.Message ?? ex.Message); GameAnalyticsManager.AddErrorEventOnce("ServerListScreen.PingServer:PingException" + serverInfo.IP, GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg); +#if DEBUG DebugConsole.NewMessage(errorMsg, Color.Red); +#endif } } } diff --git a/Barotrauma/BarotraumaServer/Source/GameMain.cs b/Barotrauma/BarotraumaServer/Source/GameMain.cs index d600976c2..a165d5325 100644 --- a/Barotrauma/BarotraumaServer/Source/GameMain.cs +++ b/Barotrauma/BarotraumaServer/Source/GameMain.cs @@ -69,9 +69,7 @@ namespace Barotrauma Config.WasGameUpdated = false; Config.Save(); } - - TextManager.LoadTextPacks(); - + SteamManager.Initialize(); if (GameSettings.SendUserStatistics) GameAnalyticsManager.Init(); diff --git a/Barotrauma/BarotraumaShared/BarotraumaShared.projitems b/Barotrauma/BarotraumaShared/BarotraumaShared.projitems index df8e3c7ea..47ff281c2 100644 --- a/Barotrauma/BarotraumaShared/BarotraumaShared.projitems +++ b/Barotrauma/BarotraumaShared/BarotraumaShared.projitems @@ -2734,6 +2734,7 @@ + diff --git a/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveContainItem.cs b/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveContainItem.cs index ed59a6184..7ed31326a 100644 --- a/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveContainItem.cs +++ b/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveContainItem.cs @@ -85,7 +85,7 @@ namespace Barotrauma foreach (string identifier in itemIdentifiers) { itemToContain = character.Inventory.FindItemByIdentifier(identifier) ?? character.Inventory.FindItemByTag(identifier); - if (itemToContain != null) break; + if (itemToContain != null && itemToContain.Condition > 0.0f) break; } if (itemToContain == null) @@ -138,8 +138,6 @@ namespace Barotrauma } return true; - } - - + } } } diff --git a/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveDecontainItem.cs b/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveDecontainItem.cs new file mode 100644 index 000000000..34adea1bb --- /dev/null +++ b/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveDecontainItem.cs @@ -0,0 +1,141 @@ +using Barotrauma.Items.Components; +using Microsoft.Xna.Framework; +using System; +using System.Linq; + +namespace Barotrauma +{ + class AIObjectiveDecontainItem : AIObjective + { + //can either be a tag or an identifier + private string[] itemIdentifiers; + + private ItemContainer container; + + private bool isCompleted; + + public Func GetItemPriority; + + private AIObjectiveGetItem getItemObjective; + private AIObjectiveGoTo goToObjective; + private Item targetItem; + + public AIObjectiveDecontainItem(Character character, Item targetItem, ItemContainer container) + : base(character, "") + { + this.targetItem = targetItem; + this.container = container; + } + + + public AIObjectiveDecontainItem(Character character, string itemIdentifier, ItemContainer container) + : this(character, new string[] { itemIdentifier }, container) + { + } + + public AIObjectiveDecontainItem(Character character, string[] itemIdentifiers, ItemContainer container) + : base(character, "") + { + this.itemIdentifiers = itemIdentifiers; + for (int i = 0; i < itemIdentifiers.Length; i++) + { + itemIdentifiers[i] = itemIdentifiers[i].ToLowerInvariant(); + } + + this.container = container; + } + + public override bool IsCompleted() + { + return isCompleted; + } + + public override bool CanBeCompleted + { + get + { + if (goToObjective != null) + { + return goToObjective.CanBeCompleted; + } + + return getItemObjective == null || getItemObjective.CanBeCompleted; + } + } + + public override float GetPriority(AIObjectiveManager objectiveManager) + { + if (objectiveManager.CurrentOrder == this) + { + return AIObjectiveManager.OrderPriority; + } + + return 1.0f; + } + + protected override void Act(float deltaTime) + { + if (isCompleted) return; + + Item itemToDecontain = null; + + //get the item that should be de-contained + if (targetItem == null) + { + if (itemIdentifiers != null) + { + foreach (string identifier in itemIdentifiers) + { + itemToDecontain = container.Inventory.FindItemByIdentifier(identifier) ?? container.Inventory.FindItemByTag(identifier); + if (itemToDecontain != null) break; + } + } + } + else + { + itemToDecontain = targetItem; + } + + if (itemToDecontain == null || itemToDecontain.Container != container.Item) // Item not found or already de-contained, consider complete + { + isCompleted = true; + return; + } + + if (itemToDecontain.OwnInventory != character.Inventory && itemToDecontain.ParentInventory != character.Inventory) + { + if (Vector2.Distance(character.Position, container.Item.Position) > container.Item.InteractDistance + && !container.Item.IsInsideTrigger(character.WorldPosition)) + { + goToObjective = new AIObjectiveGoTo(container.Item, character); + AddSubObjective(goToObjective); + return; + } + } + + itemToDecontain.Drop(character); + isCompleted = true; + } + + public override bool IsDuplicate(AIObjective otherObjective) + { + AIObjectiveDecontainItem decontainItem = otherObjective as AIObjectiveDecontainItem; + if (decontainItem == null) return false; + if (decontainItem.itemIdentifiers != null && itemIdentifiers != null) + { + if (decontainItem.itemIdentifiers.Length != itemIdentifiers.Length) return false; + for (int i = 0; i < decontainItem.itemIdentifiers.Length; i++) + { + if (decontainItem.itemIdentifiers[i] != itemIdentifiers[i]) return false; + } + return true; + } + else if (decontainItem.itemIdentifiers == null && itemIdentifiers == null) + { + return decontainItem.targetItem == targetItem; + } + + return false; + } + } +} diff --git a/Barotrauma/BarotraumaShared/Source/Characters/Character.cs b/Barotrauma/BarotraumaShared/Source/Characters/Character.cs index 518a16277..f25db6662 100644 --- a/Barotrauma/BarotraumaShared/Source/Characters/Character.cs +++ b/Barotrauma/BarotraumaShared/Source/Characters/Character.cs @@ -754,7 +754,7 @@ namespace Barotrauma if (head == null) { return; } if (headId.HasValue) { - Info.HeadSpriteId = headId.Value; + Info.Head.HeadSpriteId = headId.Value; Info.LoadHeadSprite(); Info.HairIndex = hairIndex ?? -1; Info.BeardIndex = beardIndex ?? -1; diff --git a/Barotrauma/BarotraumaShared/Source/Characters/CharacterInfo.cs b/Barotrauma/BarotraumaShared/Source/Characters/CharacterInfo.cs index 6d0959718..0a96185d7 100644 --- a/Barotrauma/BarotraumaShared/Source/Characters/CharacterInfo.cs +++ b/Barotrauma/BarotraumaShared/Source/Characters/CharacterInfo.cs @@ -14,8 +14,83 @@ namespace Barotrauma public enum Gender { None, Male, Female }; public enum Race { None, White, Black, Asian }; + // TODO: Generating the HeadInfo could be simplified. partial class CharacterInfo { + public class HeadInfo + { + private int _headSpriteId; + public int HeadSpriteId + { + get { return _headSpriteId; } + set + { + _headSpriteId = value; + if (_headSpriteId < (int)headSpriteRange.X) + { + _headSpriteId = (int)headSpriteRange.Y; + } + if (_headSpriteId > (int)headSpriteRange.Y) + { + _headSpriteId = (int)headSpriteRange.X; + } + } + } + public Vector2 headSpriteRange; + public Gender gender; + public Race race; + + public int HairIndex { get; set; } = -1; + public int BeardIndex { get; set; } = -1; + public int MoustacheIndex { get; set; } = -1; + public int FaceAttachmentIndex { get; set; } = -1; + + public XElement HairElement { get; set; } + public XElement BeardElement { get; set; } + public XElement MoustacheElement { get; set; } + public XElement FaceAttachment { get; set; } + + public HeadInfo() { } + + public HeadInfo(int headId) + { + _headSpriteId = headId; + } + + public void ResetAttachmentIndices() + { + HairIndex = -1; + BeardIndex = -1; + MoustacheIndex = -1; + FaceAttachmentIndex = -1; + } + } + + private HeadInfo head = new HeadInfo(); + public HeadInfo Head + { + get { return head; } + set + { + if (head != value && value != null) + { + head = value; + if (head.race == Race.None) + { + head.race = GetRandomRace(); + } + if (head.gender == Gender.None) + { + head.gender = GetRandomGender(); + } + CalculateHeadSpriteRange(); + Head.HeadSpriteId = value.HeadSpriteId; + HeadSprite = null; + AttachmentSprites = null; + } + } + } + private static Dictionary cachedConfigs = new Dictionary(); private static ushort idCounter; @@ -70,7 +145,97 @@ namespace Barotrauma public int Salary; - private Vector2 headSpriteRange; + private Sprite headSprite; + public Sprite HeadSprite + { + get + { + if (headSprite == null) + { + LoadHeadSprite(); + } + return headSprite; + } + private set + { + if (headSprite != null) + { + headSprite.Remove(); + } + headSprite = value; + } + } + + private Sprite portrait; + public Sprite Portrait + { + get + { + if (portrait == null) + { + LoadHeadSprite(); + } + return portrait; + } + private set + { + if (portrait != null) + { + portrait.Remove(); + } + portrait = value; + } + } + + private Sprite portraitBackground; + public Sprite PortraitBackground + { + get + { + if (portraitBackground == null) + { + var portraitBackgroundElement = SourceElement.Element("portraitbackground"); + if (portraitBackgroundElement != null) + { + portraitBackground = new Sprite(portraitBackgroundElement.Element("sprite")); + } + } + return portraitBackground; + } + private set + { + if (portraitBackground != null) + { + portraitBackground.Remove(); + } + portraitBackground = value; + } + } + + private List attachmentSprites; + public List AttachmentSprites + { + get + { + if (attachmentSprites == null) + { + LoadAttachmentSprites(); + } + return attachmentSprites; + } + private set + { + if (attachmentSprites != null) + { + attachmentSprites.ForEach(s => s.Sprite?.Remove()); + } + attachmentSprites = value; + } + } + + public XElement SourceElement { get; set; } + + public readonly string ragdollFileName = string.Empty; private Sprite headSprite; public Sprite HeadSprite @@ -114,35 +279,14 @@ namespace Barotrauma } } - private Sprite portraitBackground; - public Sprite PortraitBackground - { - get - { - if (portraitBackground == null) - { - var portraitBackgroundElement = SourceElement.Element("portraitbackground"); - if (portraitBackgroundElement != null) - { - portraitBackground = new Sprite(portraitBackgroundElement.Element("sprite")); - } - } - return portraitBackground; - } - } + private NPCPersonalityTrait personalityTrait; - private List attachmentSprites; - public List AttachmentsSprites - { - get - { - if (attachmentSprites == null) - { - LoadAttachmentSprites(); - } - return attachmentSprites; - } - } + //unique ID given to character infos in MP + //used by clients to identify which infos are the same to prevent duplicate characters in round summary + public ushort ID; + + public XElement InventoryData; + public XElement SourceElement { get; set; } @@ -186,22 +330,17 @@ namespace Barotrauma get { return personalityTrait; } } - private int headSpriteId; + /// + /// Setting the value with this property also resets the head attachments. Use Head.headSpriteId if you don't want that. + /// public int HeadSpriteId { - get { return headSpriteId; } + get { return Head.HeadSpriteId; } set { - int oldId = headSpriteId; - - headSpriteId = value; - Vector2 spriteRange = headSpriteRange; - - if (headSpriteId < (int)spriteRange.X) headSpriteId = (int)(spriteRange.Y); - if (headSpriteId > (int)spriteRange.Y) headSpriteId = (int)(spriteRange.X); - - headSprite = null; - attachmentSprites = null; + Head.HeadSpriteId = value; + HeadSprite = null; + AttachmentSprites = null; ResetHeadAttachments(); } } @@ -209,47 +348,50 @@ namespace Barotrauma private Gender gender; public Gender Gender { - get { return gender; } + get { return Head.gender; } set { - if (gender == value) return; - gender = value; - if (gender == Gender.None) + if (Head.gender == value) return; + Head.gender = value; + if (Head.gender == Gender.None) { - Gender = Gender.Male; - //SetRandomGender(); + Head.gender = Gender.Male; } CalculateHeadSpriteRange(); ResetHeadAttachments(); - headSprite = null; - attachmentSprites = null; - //SetRandomHead(); - //LoadHeadSprite(); + HeadSprite = null; + AttachmentSprites = null; } } - private Race race; public Race Race { - get { return race; } + get { return Head.race; } set { - if (race == value) { return; } - race = value; - if (race == Race.None) + if (Head.race == value) { return; } + Head.race = value; + if (Head.race == Race.None) { - race = Race.White; - //SetRandomRace(); + Head.race = Race.White; } CalculateHeadSpriteRange(); ResetHeadAttachments(); - headSprite = null; - attachmentSprites = null; - //SetRandomHead(); - //LoadHeadSprite(); + HeadSprite = null; + AttachmentSprites = null; } } + public int HairIndex { get => Head.HairIndex; set => Head.HairIndex = value; } + public int BeardIndex { get => Head.BeardIndex; set => Head.BeardIndex = value; } + public int MoustacheIndex { get => Head.MoustacheIndex; set => Head.MoustacheIndex = value; } + public int FaceAttachmentIndex { get => Head.FaceAttachmentIndex; set => Head.FaceAttachmentIndex = value; } + + public XElement HairElement { get => Head.HairElement; set => Head.HairElement = value; } + public XElement BeardElement { get => Head.BeardElement; set => Head.BeardElement = value; } + public XElement MoustacheElement { get => Head.MoustacheElement; set => Head.MoustacheElement = value; } + public XElement FaceAttachment { get => Head.FaceAttachment; set => Head.FaceAttachment = value; } + private RagdollParams ragdoll; public RagdollParams Ragdoll { @@ -268,6 +410,8 @@ namespace Barotrauma set { ragdoll = value; } } + public bool IsAttachmentsLoaded => HairIndex > -1 && BeardIndex > -1 && MoustacheIndex > -1 && FaceAttachmentIndex > -1; + // Used for creating the data public CharacterInfo(string file, string name = "", Gender gender = Gender.None, JobPrefab jobPrefab = null, string ragdollFileName = null) { @@ -279,18 +423,18 @@ namespace Barotrauma SourceElement = doc.Root; if (doc.Root.GetAttributeBool("genders", false)) { - this.gender = gender == Gender.None ? GetRandomGender() : gender; + Head.gender = gender == Gender.None ? GetRandomGender() : gender; } - if (!Enum.TryParse(doc.Root.GetAttributeString("race", "None"), true, out race)) + if (!Enum.TryParse(doc.Root.GetAttributeString("race", "None"), true, out Head.race)) { - race = GetRandomRace(); + Head.race = GetRandomRace(); } - if (race == Race.None) + if (Head.race == Race.None) { - race = GetRandomRace(); + Head.race = GetRandomRace(); } CalculateHeadSpriteRange(); - SetRandomHeadID(); + Head.HeadSpriteId = GetRandomHeadID(); Job = (jobPrefab == null) ? Job.Random(Rand.RandSync.Server) : new Job(jobPrefab); if (!string.IsNullOrEmpty(name)) { @@ -304,14 +448,14 @@ namespace Barotrauma string firstNamePath = doc.Root.Element("name").GetAttributeString("firstname", ""); if (firstNamePath != "") { - firstNamePath = firstNamePath.Replace("[GENDER]", (this.gender == Gender.Female) ? "female" : "male"); + firstNamePath = firstNamePath.Replace("[GENDER]", (Head.gender == Gender.Female) ? "female" : "male"); Name = ToolBox.GetRandomLine(firstNamePath); } string lastNamePath = doc.Root.Element("name").GetAttributeString("lastname", ""); if (lastNamePath != "") { - lastNamePath = lastNamePath.Replace("[GENDER]", (this.gender == Gender.Female) ? "female" : "male"); + lastNamePath = lastNamePath.Replace("[GENDER]", (Head.gender == Gender.Female) ? "female" : "male"); if (Name != "") Name += " "; Name += ToolBox.GetRandomLine(lastNamePath); } @@ -333,16 +477,16 @@ namespace Barotrauma idCounter++; Name = element.GetAttributeString("name", "unnamed"); string genderStr = element.GetAttributeString("gender", "male").ToLowerInvariant(); - gender = (genderStr == "male") ? Gender.Male : Gender.Female; - Enum.TryParse(element.GetAttributeString("race", "white"), true, out race); + Head.gender = (genderStr == "male") ? Gender.Male : Gender.Female; + Enum.TryParse(element.GetAttributeString("race", "white"), true, out Head.race); File = element.GetAttributeString("file", ""); SourceElement = GetConfig(File).Root; Salary = element.GetAttributeInt("salary", 1000); - headSpriteId = element.GetAttributeInt("headspriteid", 1); - HairIndex = element.GetAttributeInt("hairindex", -1); - BeardIndex = element.GetAttributeInt("beardindex", -1); - MoustacheIndex = element.GetAttributeInt("moustacheindex", -1); - FaceAttachmentIndex = element.GetAttributeInt("faceattachmentindex", -1); + Head.HeadSpriteId = element.GetAttributeInt("headspriteid", 1); + Head.HairIndex = element.GetAttributeInt("hairindex", -1); + Head.BeardIndex = element.GetAttributeInt("beardindex", -1); + Head.MoustacheIndex = element.GetAttributeInt("moustacheindex", -1); + Head.FaceAttachmentIndex = element.GetAttributeInt("faceattachmentindex", -1); StartItemsGiven = element.GetAttributeBool("startitemsgiven", false); string personalityName = element.GetAttributeString("personality", ""); ragdollFileName = element.GetAttributeString("ragdoll", string.Empty); @@ -369,8 +513,8 @@ namespace Barotrauma string spritePath = spriteElement.Attribute("texture").Value; - spritePath = spritePath.Replace("[GENDER]", (gender == Gender.Female) ? "female" : "male"); - spritePath = spritePath.Replace("[RACE]", race.ToString().ToLowerInvariant()); + spritePath = spritePath.Replace("[GENDER]", (Head.gender == Gender.Female) ? "female" : "male"); + spritePath = spritePath.Replace("[RACE]", Head.race.ToString().ToLowerInvariant()); spritePath = spritePath.Replace("[HEADID]", HeadSpriteId.ToString()); string fileName = Path.GetFileNameWithoutExtension(spritePath); @@ -386,8 +530,8 @@ namespace Barotrauma fileWithoutTags = fileWithoutTags.Split('[', ']').First(); if (fileWithoutTags != fileName) continue; - headSprite = new Sprite(spriteElement, "", file); - portrait = new Sprite(spriteElement, "", file) { RelativeOrigin = Vector2.Zero }; + HeadSprite = new Sprite(spriteElement, "", file); + Portrait = new Sprite(spriteElement, "", file) { RelativeOrigin = Vector2.Zero }; //extract the tags out of the filename SpriteTags = file.Split('[', ']').Skip(1).ToList(); @@ -416,22 +560,11 @@ namespace Barotrauma public Gender SetRandomGender() => Gender = GetRandomGender(); public Race SetRandomRace() => Race = GetRandomRace(); - public int SetRandomHead() => HeadSpriteId = SetRandomHeadID(); + public int SetRandomHead() => HeadSpriteId = GetRandomHeadID(); + public Gender GetRandomGender() => (Rand.Range(0.0f, 1.0f, Rand.RandSync.Server) < SourceElement.GetAttributeFloat("femaleratio", 0.5f)) ? Gender.Female : Gender.Male; public Race GetRandomRace() => new Race[] { Race.White, Race.Black, Race.Asian }.GetRandom(Rand.RandSync.Server); - - private int SetRandomHeadID() - { - if (headSpriteRange != Vector2.Zero) - { - headSpriteId = Rand.Range((int)headSpriteRange.X, (int)headSpriteRange.Y + 1, Rand.RandSync.Server); - } - else - { - headSpriteId = 0; - } - return headSpriteId; - } + public int GetRandomHeadID() => Head.headSpriteRange != Vector2.Zero ? Rand.Range((int)Head.headSpriteRange.X, (int)Head.headSpriteRange.Y + 1, Rand.RandSync.Server) : 0; private List hairs; private List beards; @@ -459,27 +592,27 @@ namespace Barotrauma { if (elements == null) { return elements; } return elements.Where(w => - Enum.TryParse(w.GetAttributeString("gender", "male"), true, out Gender g) && g == gender && - Enum.TryParse(w.GetAttributeString("race", "None"), true, out Race r) && r == race); + Enum.TryParse(w.GetAttributeString("gender", "male"), true, out Gender g) && g == Head.gender && + Enum.TryParse(w.GetAttributeString("race", "None"), true, out Race r) && r == Head.race); } private void CalculateHeadSpriteRange() { if (SourceElement == null) { return; } - headSpriteRange = SourceElement.GetAttributeVector2("headidrange", Vector2.Zero); - if (headSpriteRange == Vector2.Zero) + Head.headSpriteRange = SourceElement.GetAttributeVector2("headidrange", Vector2.Zero); + if (Head.headSpriteRange == Vector2.Zero) { // If range is defined, we use it as it is // Else we calculate the range from the wearables. var wearables = FilterElementsByGenderAndRace(Wearables); if (wearables == null) { - headSpriteRange = Vector2.Zero; + Head.headSpriteRange = Vector2.Zero; return; } if (wearables.None()) { - DebugConsole.ThrowError($"[CharacterInfo] No headidrange defined and no wearables matching the gender {gender} and the race {race} could be found. Total wearables found: {Wearables.Count()}."); + DebugConsole.ThrowError($"[CharacterInfo] No headidrange defined and no wearables matching the gender {Head.gender} and the race {Head.race} could be found. Total wearables found: {Wearables.Count()}."); return; } else @@ -492,7 +625,7 @@ namespace Barotrauma return; } ids = ids.OrderBy(id => id); - headSpriteRange = new Vector2(ids.First(), ids.Last()); + Head.headSpriteRange = new Vector2(ids.First(), ids.Last()); } } } @@ -521,41 +654,41 @@ namespace Barotrauma faceAttachments = AddEmpty(FilterByTypeAndHeadID(FilterElementsByGenderAndRace(wearables), WearableType.FaceAttachment), WearableType.FaceAttachment); } - if (IsValidIndex(HairIndex, hairs)) + if (IsValidIndex(Head.HairIndex, hairs)) { - HairElement = hairs[HairIndex]; + Head.HairElement = hairs[Head.HairIndex]; } else { - HairElement = GetRandomElement(hairs); - HairIndex = hairs.IndexOf(HairElement); + Head.HairElement = GetRandomElement(hairs); + Head.HairIndex = hairs.IndexOf(Head.HairElement); } - if (IsValidIndex(BeardIndex, beards)) + if (IsValidIndex(Head.BeardIndex, beards)) { - BeardElement = beards[BeardIndex]; + Head.BeardElement = beards[Head.BeardIndex]; } else { - BeardElement = GetRandomElement(beards); - BeardIndex = beards.IndexOf(BeardElement); + Head.BeardElement = GetRandomElement(beards); + Head.BeardIndex = beards.IndexOf(Head.BeardElement); } - if (IsValidIndex(MoustacheIndex, moustaches)) + if (IsValidIndex(Head.MoustacheIndex, moustaches)) { - MoustacheElement = moustaches[MoustacheIndex]; + Head.MoustacheElement = moustaches[Head.MoustacheIndex]; } else { - MoustacheElement = GetRandomElement(moustaches); - MoustacheIndex = moustaches.IndexOf(MoustacheElement); + Head.MoustacheElement = GetRandomElement(moustaches); + Head.MoustacheIndex = moustaches.IndexOf(Head.MoustacheElement); } - if (IsValidIndex(FaceAttachmentIndex, faceAttachments)) + if (IsValidIndex(Head.FaceAttachmentIndex, faceAttachments)) { - FaceAttachment = faceAttachments[FaceAttachmentIndex]; + Head.FaceAttachment = faceAttachments[Head.FaceAttachmentIndex]; } else { - FaceAttachment = GetRandomElement(faceAttachments); - FaceAttachmentIndex = faceAttachments.IndexOf(FaceAttachment); + Head.FaceAttachment = GetRandomElement(faceAttachments); + Head.FaceAttachmentIndex = faceAttachments.IndexOf(Head.FaceAttachment); } List AddEmpty(IEnumerable elements, WearableType type) @@ -583,14 +716,14 @@ namespace Barotrauma if (Enum.TryParse(e.GetAttributeString("type", ""), true, out WearableType type) && type != targetType) { return false; } int headId = e.GetAttributeInt("headid", -1); // if the head id is less than 1, the id is not valid and the condition is ignored. - return headId < 1 || headId == headSpriteId; + return headId < 1 || headId == Head.HeadSpriteId; }); } bool IsWearableAllowed(XElement element) { string spriteName = element.Element("sprite").GetAttributeString("name", string.Empty); - return IsAllowed(HairElement, spriteName) && IsAllowed(BeardElement, spriteName) && IsAllowed(MoustacheElement, spriteName) && IsAllowed(FaceAttachment, spriteName); + return IsAllowed(Head.HairElement, spriteName) && IsAllowed(Head.BeardElement, spriteName) && IsAllowed(Head.MoustacheElement, spriteName) && IsAllowed(Head.FaceAttachment, spriteName); } bool IsAllowed(XElement element, string spriteName) @@ -671,8 +804,8 @@ namespace Barotrauma charElement.Add( new XAttribute("name", Name), new XAttribute("file", File), - new XAttribute("gender", gender == Gender.Male ? "male" : "female"), - new XAttribute("race", race.ToString()), + new XAttribute("gender", Head.gender == Gender.Male ? "male" : "female"), + new XAttribute("race", Head.race.ToString()), new XAttribute("salary", Salary), new XAttribute("headspriteid", HeadSpriteId), new XAttribute("hairindex", HairIndex), @@ -735,10 +868,10 @@ namespace Barotrauma msg.Write(Gender == Gender.Female); msg.Write((byte)Race); msg.Write((byte)HeadSpriteId); - msg.Write((byte)HairIndex); - msg.Write((byte)BeardIndex); - msg.Write((byte)MoustacheIndex); - msg.Write((byte)FaceAttachmentIndex); + msg.Write((byte)Head.HairIndex); + msg.Write((byte)Head.BeardIndex); + msg.Write((byte)Head.MoustacheIndex); + msg.Write((byte)Head.FaceAttachmentIndex); msg.Write(ragdollFileName); if (Job != null) @@ -791,13 +924,13 @@ namespace Barotrauma CharacterInfo ch = new CharacterInfo(configPath, newName, isFemale ? Gender.Female : Gender.Male, jobPrefab, ragdollFile) { ID = infoID, - race = (Race)race, - headSpriteId = headSpriteID, - HairIndex = hairIndex, - BeardIndex = beardIndex, - MoustacheIndex = moustacheIndex, - FaceAttachmentIndex = faceAttachmentIndex }; + ch.Head.race = (Race)race; + ch.Head.HeadSpriteId = headSpriteID; + ch.HairIndex = hairIndex; + ch.BeardIndex = beardIndex; + ch.MoustacheIndex = moustacheIndex; + ch.FaceAttachmentIndex = faceAttachmentIndex; ch.CalculateHeadSpriteRange(); ch.ReloadHeadAttachments(); @@ -832,10 +965,7 @@ namespace Barotrauma private void ResetAttachmentIndices() { - HairIndex = -1; - BeardIndex = -1; - MoustacheIndex = -1; - FaceAttachmentIndex = -1; + Head.ResetAttachmentIndices(); } private void ResetLoadedAttachments() @@ -849,26 +979,10 @@ namespace Barotrauma public void Remove() { Character = null; - if (headSprite != null) - { - headSprite.Remove(); - headSprite = null; - } - if (portrait != null) - { - portrait.Remove(); - portrait = null; - } - if (portraitBackground != null) - { - portraitBackground.Remove(); - portraitBackground = null; - } - if (attachmentSprites != null) - { - attachmentSprites.ForEach(a => a.Sprite.Remove()); - attachmentSprites = null; - } + HeadSprite = null; + Portrait = null; + PortraitBackground = null; + AttachmentSprites = null; } } } diff --git a/Barotrauma/BarotraumaShared/Source/Characters/Health/DamageModifier.cs b/Barotrauma/BarotraumaShared/Source/Characters/Health/DamageModifier.cs index c1e7ddd80..67ed71327 100644 --- a/Barotrauma/BarotraumaShared/Source/Characters/Health/DamageModifier.cs +++ b/Barotrauma/BarotraumaShared/Source/Characters/Health/DamageModifier.cs @@ -80,6 +80,8 @@ namespace Barotrauma public bool MatchesAffliction(Affliction affliction) { + if (AfflictionIdentifiers.Length == 0) { return true; } + foreach (string afflictionName in AfflictionIdentifiers) { if (affliction.Prefab.Identifier.ToLowerInvariant() == afflictionName) return true; diff --git a/Barotrauma/BarotraumaShared/Source/GameSettings.cs b/Barotrauma/BarotraumaShared/Source/GameSettings.cs index fc431c53a..2606d6408 100644 --- a/Barotrauma/BarotraumaShared/Source/GameSettings.cs +++ b/Barotrauma/BarotraumaShared/Source/GameSettings.cs @@ -411,8 +411,9 @@ namespace Barotrauma } UnsavedSettings = false; - - bool invalidPackagesFound = false; + + List missingPackagePaths = new List(); + List incompatiblePackages = new List(); foreach (XElement subElement in doc.Root.Elements()) { switch (subElement.Name.ToString().ToLowerInvariant()) @@ -422,27 +423,35 @@ namespace Barotrauma var matchingContentPackage = ContentPackage.List.Find(cp => System.IO.Path.GetFullPath(cp.Path) == path); if (matchingContentPackage == null) { - DebugConsole.ThrowError(TextManager.Get("ContentPackageNotFound").Replace("[packagepath]", path), createMessageBox: true); + missingPackagePaths.Add(path); } else if (!matchingContentPackage.IsCompatible()) { - invalidPackagesFound = true; - DebugConsole.ThrowError( - TextManager.Get(matchingContentPackage.GameVersion <= new Version(0, 0, 0, 0) ? "IncompatibleContentPackageUnknownVersion" : "IncompatibleContentPackage") - .Replace("[packagename]", matchingContentPackage.Name) - .Replace("[packageversion]", matchingContentPackage.GameVersion.ToString()) - .Replace("[gameversion]", GameMain.Version.ToString()), - createMessageBox: true); + incompatiblePackages.Add(matchingContentPackage); } else { - invalidPackagesFound = true; SelectedContentPackages.Add(matchingContentPackage); } break; - } + } } + + TextManager.LoadTextPacks(SelectedContentPackages); + //display error messages after all content packages have been loaded + //to make sure the package that contains text files has been loaded before we attempt to use TextManager + foreach (string missingPackagePath in missingPackagePaths) + { + DebugConsole.ThrowError(TextManager.Get("ContentPackageNotFound").Replace("[packagepath]", missingPackagePath)); + } + foreach (ContentPackage incompatiblePackage in incompatiblePackages) + { + DebugConsole.ThrowError(TextManager.Get(incompatiblePackage.GameVersion <= new Version(0, 0, 0, 0) ? "IncompatibleContentPackageUnknownVersion" : "IncompatibleContentPackage") + .Replace("[packagename]", incompatiblePackage.Name) + .Replace("[packageversion]", incompatiblePackage.GameVersion.ToString()) + .Replace("[gameversion]", GameMain.Version.ToString())); + } foreach (ContentPackage contentPackage in SelectedContentPackages) { foreach (ContentFile file in contentPackage.Files) @@ -465,9 +474,9 @@ namespace Barotrauma } //save to get rid of the invalid selected packages in the config file - if (invalidPackagesFound) { Save(); } + if (missingPackagePaths.Count > 0 || incompatiblePackages.Count > 0) { Save(); } } - + public KeyOrMouse KeyBind(InputType inputType) { return keyMapping[(int)inputType]; diff --git a/Barotrauma/BarotraumaShared/Source/Items/Components/Machines/MiniMap.cs b/Barotrauma/BarotraumaShared/Source/Items/Components/Machines/MiniMap.cs index 4ab7dec7f..3f3698112 100644 --- a/Barotrauma/BarotraumaShared/Source/Items/Components/Machines/MiniMap.cs +++ b/Barotrauma/BarotraumaShared/Source/Items/Components/Machines/MiniMap.cs @@ -14,8 +14,10 @@ namespace Barotrauma.Items.Components public bool Distort; public float DistortionTimer; + + public List LinkedHulls = new List(); } - + private DateTime resetDataTime; private bool hasPower; diff --git a/Barotrauma/BarotraumaShared/Source/Items/Components/Turret.cs b/Barotrauma/BarotraumaShared/Source/Items/Components/Turret.cs index 73564e42e..b24d730ac 100644 --- a/Barotrauma/BarotraumaShared/Source/Items/Components/Turret.cs +++ b/Barotrauma/BarotraumaShared/Source/Items/Components/Turret.cs @@ -404,7 +404,7 @@ namespace Barotrauma.Items.Components } } - int projectileCount = 0; + int usableProjectileCount = 0; int maxProjectileCount = 0; foreach (MapEntity e in item.linkedTo) { @@ -416,11 +416,22 @@ namespace Barotrauma.Items.Components { var container = projectileContainer.GetComponent(); if (containedItems != null) maxProjectileCount += container.Capacity; - projectileCount += containedItems.Length; + + int projectiles = 0; + + for (int i = 0; i < containedItems.Length; i++) + { + if (containedItems[i].Condition > 0.0f) + { + projectiles++; + } + } + + usableProjectileCount += projectiles; } } - if (projectileCount == 0 || (projectileCount < maxProjectileCount && objective.Option.ToLowerInvariant() != "fireatwill")) + if (usableProjectileCount == 0 || (usableProjectileCount < maxProjectileCount && objective.Option.ToLowerInvariant() != "fireatwill")) { ItemContainer container = null; foreach (MapEntity e in item.linkedTo) @@ -434,11 +445,17 @@ namespace Barotrauma.Items.Components if (container == null || container.ContainableItems.Count == 0) return true; + if (container.Inventory.Items[0] != null && container.Inventory.Items[0].Condition <= 0.0f) + { + var removeShellObjective = new AIObjectiveDecontainItem(character, container.Inventory.Items[0], container); + objective.AddSubObjective(removeShellObjective); + } + var containShellObjective = new AIObjectiveContainItem(character, container.ContainableItems[0].Identifiers[0], container); character?.Speak(TextManager.Get("DialogLoadTurret").Replace("[itemname]", item.Name), null, 0.0f, "loadturret", 30.0f); - containShellObjective.MinContainedAmount = projectileCount + 1; + containShellObjective.MinContainedAmount = usableProjectileCount + 1; containShellObjective.IgnoreAlreadyContainedItems = true; - objective.AddSubObjective(containShellObjective); + objective.AddSubObjective(containShellObjective); return false; } diff --git a/Barotrauma/BarotraumaShared/Source/Items/Item.cs b/Barotrauma/BarotraumaShared/Source/Items/Item.cs index dde5d29d1..bb23aeca0 100644 --- a/Barotrauma/BarotraumaShared/Source/Items/Item.cs +++ b/Barotrauma/BarotraumaShared/Source/Items/Item.cs @@ -2265,12 +2265,7 @@ namespace Barotrauma if (linkedTo != null && linkedTo.Count > 0) { var saveableLinked = linkedTo.Where(l => l.ShouldBeSaved).ToList(); - string[] linkedToIDs = new string[saveableLinked.Count]; - for (int i = 0; i < saveableLinked.Count; i++) - { - linkedToIDs[i] = saveableLinked[i].ID.ToString(); - } - element.Add(new XAttribute("linked", string.Join(",", linkedToIDs))); + element.Add(new XAttribute("linked", string.Join(",", saveableLinked.Select(l => l.ID.ToString())))); } SerializableProperty.SerializeProperties(this, element); diff --git a/Barotrauma/BarotraumaShared/Source/Map/Hull.cs b/Barotrauma/BarotraumaShared/Source/Map/Hull.cs index 5c8f95d58..e59a51e32 100644 --- a/Barotrauma/BarotraumaShared/Source/Map/Hull.cs +++ b/Barotrauma/BarotraumaShared/Source/Map/Hull.cs @@ -206,6 +206,9 @@ namespace Barotrauma OxygenPercentage = 100.0f; FireSources = new List(); + linkedTo = new System.Collections.ObjectModel.ObservableCollection(); + + properties = SerializableProperty.GetProperties(this); @@ -938,7 +941,18 @@ namespace Barotrauma waterVolume = element.GetAttributeFloat("pressure", 0.0f), ID = (ushort)int.Parse(element.Attribute("ID").Value) }; - + + hull.linkedToID = new List(); + string linkedToString = element.GetAttributeString("linked", ""); + if (linkedToString != "") + { + string[] linkedToIds = linkedToString.Split(','); + for (int i = 0; i < linkedToIds.Length; i++) + { + hull.linkedToID.Add((ushort)int.Parse(linkedToIds[i])); + } + } + SerializableProperty.DeserializeProperties(hull, element); if (element.Attribute("oxygen") == null) { hull.Oxygen = hull.Volume; } @@ -965,6 +979,12 @@ namespace Barotrauma rect.Width + "," + rect.Height), new XAttribute("water", waterVolume) ); + + if (linkedTo != null && linkedTo.Count > 0) + { + var saveableLinked = linkedTo.Where(l => l.ShouldBeSaved).ToList(); + element.Add(new XAttribute("linked", string.Join(",", saveableLinked.Select(l => l.ID.ToString())))); + } SerializableProperty.SerializeProperties(this, element); parentElement.Add(element); return element; diff --git a/Barotrauma/BarotraumaShared/Source/Map/Map/Map.cs b/Barotrauma/BarotraumaShared/Source/Map/Map/Map.cs index 4e39f612e..c644d63d9 100644 --- a/Barotrauma/BarotraumaShared/Source/Map/Map/Map.cs +++ b/Barotrauma/BarotraumaShared/Source/Map/Map/Map.cs @@ -430,6 +430,13 @@ namespace Barotrauma } CurrentLocation.SelectedMissionIndex = missionIndex; + //the destination must be the same as the destination of the mission + if (CurrentLocation.SelectedMission != null && + CurrentLocation.SelectedMission.Locations[1] != SelectedLocation) + { + SelectLocation(CurrentLocation.SelectedMission.Locations[1]); + } + SelectedLocation = location; SelectedConnection = connections.Find(c => c.Locations.Contains(CurrentLocation) && c.Locations.Contains(SelectedLocation)); OnLocationSelected?.Invoke(SelectedLocation, SelectedConnection); diff --git a/Barotrauma/BarotraumaShared/Source/Map/MapEntityPrefab.cs b/Barotrauma/BarotraumaShared/Source/Map/MapEntityPrefab.cs index bd05e39f7..9ce5d63bd 100644 --- a/Barotrauma/BarotraumaShared/Source/Map/MapEntityPrefab.cs +++ b/Barotrauma/BarotraumaShared/Source/Map/MapEntityPrefab.cs @@ -111,8 +111,10 @@ namespace Barotrauma Description = TextManager.Get("EntityDescription.hull"), constructor = typeof(Hull).GetConstructor(new Type[] { typeof(MapEntityPrefab), typeof(Rectangle) }), ResizeHorizontal = true, - ResizeVertical = true + ResizeVertical = true, + Linkable = true }; + ep.AllowedLinks.Add("hull"); List.Add(ep); ep = new MapEntityPrefab diff --git a/Barotrauma/BarotraumaShared/Source/Memento.cs b/Barotrauma/BarotraumaShared/Source/Memento.cs index dbac8172e..17c106a4d 100644 --- a/Barotrauma/BarotraumaShared/Source/Memento.cs +++ b/Barotrauma/BarotraumaShared/Source/Memento.cs @@ -7,6 +7,9 @@ namespace Barotrauma { public T Current { get; private set; } + public int UndoCount => undoStack.Count; + public int RedoCount => redoStack.Count; + private Stack undoStack = new Stack(); private Stack redoStack = new Stack(); diff --git a/Barotrauma/BarotraumaShared/Source/Networking/GameServer.cs b/Barotrauma/BarotraumaShared/Source/Networking/GameServer.cs index 594927260..59a144fcb 100644 --- a/Barotrauma/BarotraumaShared/Source/Networking/GameServer.cs +++ b/Barotrauma/BarotraumaShared/Source/Networking/GameServer.cs @@ -2423,13 +2423,12 @@ namespace Barotrauma.Networking sender.CharacterInfo = new CharacterInfo(Character.HumanConfigFile, sender.Name, gender) { Race = race, - HeadSpriteId = headSpriteId, HairIndex = hairIndex, BeardIndex = beardIndex, MoustacheIndex = moustacheIndex, FaceAttachmentIndex = faceAttachmentIndex }; - // Need to reload the attachments because the indices may have changed + sender.CharacterInfo.Head.HeadSpriteId = headSpriteId; sender.CharacterInfo.LoadHeadAttachments(); //if the client didn't provide job preferences, we'll use the preferences that are randomly assigned in the Client constructor diff --git a/Barotrauma/BarotraumaShared/Source/Networking/SteamManager.cs b/Barotrauma/BarotraumaShared/Source/Networking/SteamManager.cs index f08a1a5e9..0d327e34f 100644 --- a/Barotrauma/BarotraumaShared/Source/Networking/SteamManager.cs +++ b/Barotrauma/BarotraumaShared/Source/Networking/SteamManager.cs @@ -75,6 +75,10 @@ namespace Barotrauma.Steam private SteamManager() { +#if SERVER + return; +#endif + try { client = new Facepunch.Steamworks.Client(AppID); @@ -118,34 +122,112 @@ namespace Barotrauma.Steam } } - public static ulong GetSteamID() + + #region Server + + public static bool CreateServer(Networking.GameServer server, bool isPublic) + { + +#if !SERVER + if (instance == null || !instance.isInitialized) + { + return false; + } +#endif + + ServerInit options = new ServerInit("Barotrauma", "Barotrauma") + { + GamePort = (ushort)server.Port, + QueryPort = (ushort)server.QueryPort + }; + + instance.server = new Server(AppID, options, isPublic); + if (!instance.server.IsValid) + { + instance.server.Dispose(); + instance.server = null; + DebugConsole.ThrowError("Initializing Steam server failed."); + return false; + } +#if SERVER + instance.isInitialized = true; +#endif + RefreshServerDetails(server); + + instance.server.Auth.OnAuthChange = server.OnAuthChange; + Instance.server.LogOnAnonymous(); + + return true; + } + + public static bool RefreshServerDetails(Networking.GameServer server) { if (instance == null || !instance.isInitialized) { - return 0; + return false; } - return instance.client.SteamId; + + // These server state variables may be changed at any time. Note that there is no lnoger a mechanism + // to send the player count. The player count is maintained by steam and you should use the player + // creation/authentication functions to maintain your player count. + instance.server.ServerName = server.Name; + instance.server.MaxPlayers = server.MaxPlayers; + instance.server.Passworded = server.HasPassword; + Instance.server.SetKey("message", GameMain.NetLobbyScreen.ServerMessageText); + Instance.server.SetKey("version", GameMain.Version.ToString()); + Instance.server.SetKey("contentpackage", string.Join(",", GameMain.Config.SelectedContentPackages.Select(cp => cp.Name))); + Instance.server.SetKey("contentpackagehash", string.Join(",", GameMain.Config.SelectedContentPackages.Select(cp => cp.MD5hash.Hash))); + Instance.server.SetKey("contentpackageurl", string.Join(",", GameMain.Config.SelectedContentPackages.Select(cp => cp.SteamWorkshopUrl ?? ""))); + Instance.server.SetKey("usingwhitelist", (server.WhiteList != null && server.WhiteList.Enabled).ToString()); + Instance.server.SetKey("modeselectionmode", server.ModeSelectionMode.ToString()); + Instance.server.SetKey("subselectionmode", server.SubSelectionMode.ToString()); + Instance.server.SetKey("allowspectating", server.AllowSpectating.ToString()); + Instance.server.SetKey("allowrespawn", server.AllowRespawn.ToString()); + Instance.server.SetKey("traitors", server.TraitorsEnabled.ToString()); + Instance.server.SetKey("gamestarted", server.GameStarted.ToString()); + Instance.server.SetKey("gamemode", server.GameModeIdentifier); + +#if SERVER + instance.server.DedicatedServer = true; +#endif + + return true; } - public static ulong GetWorkshopItemIDFromUrl(string url) + public static bool StartAuthSession(byte[] authTicketData, ulong clientSteamID) { - try - { - Uri uri = new Uri(url); - string idStr = HttpUtility.ParseQueryString(uri.Query).Get("id"); - if (ulong.TryParse(idStr, out ulong id)) - { - return id; - } - } - catch (Exception e) - { - DebugConsole.ThrowError("Failed to get Workshop item ID from the url \""+url+"\"!", e); - } + if (instance == null || !instance.isInitialized || instance.server == null) return false; - return 0; + DebugConsole.Log("SteamManager authenticating Steam client " + clientSteamID); + if (!instance.server.Auth.StartSession(authTicketData, clientSteamID)) + { + DebugConsole.Log("Authentication failed"); + return false; + } + return true; } - + + public static void StopAuthSession(ulong clientSteamID) + { + if (instance == null || !instance.isInitialized || instance.server == null) return; + + DebugConsole.Log("SteamManager ending auth session with Steam client " + clientSteamID); + instance.server.Auth.EndSession(clientSteamID); + } + + public static bool CloseServer() + { + if (instance == null || !instance.isInitialized || instance.server == null) return false; + + instance.server.Dispose(); + instance.server = null; + + return true; + } + + #endregion + + public static bool UnlockAchievement(string achievementName) { if (instance == null || !instance.isInitialized) @@ -173,7 +255,7 @@ namespace Barotrauma.Steam public static bool IncrementStat(string statName, int increment) { - if (instance == null || !instance.isInitialized) { return false; } + if (instance == null || !instance.isInitialized || instance.client == null) { return false; } DebugConsole.Log("Incremented stat \"" + statName + "\" by " + increment); bool success = instance.client.Stats.Add(statName, increment); if (!success) @@ -187,7 +269,7 @@ namespace Barotrauma.Steam public static bool IncrementStat(string statName, float increment) { - if (instance == null || !instance.isInitialized) { return false; } + if (instance == null || !instance.isInitialized || instance.client == null) { return false; } DebugConsole.Log("Incremented stat \"" + statName + "\" by " + increment); bool success = instance.client.Stats.Add(statName, increment); if (!success) @@ -199,7 +281,35 @@ namespace Barotrauma.Steam return success; } +#if CLIENT + public static ulong GetSteamID() + { + if (instance == null || !instance.isInitialized) + { + return 0; + } + return instance.client.SteamId; + } + public static ulong GetWorkshopItemIDFromUrl(string url) + { + try + { + Uri uri = new Uri(url); + string idStr = HttpUtility.ParseQueryString(uri.Query).Get("id"); + if (ulong.TryParse(idStr, out ulong id)) + { + return id; + } + } + catch (Exception e) + { + DebugConsole.ThrowError("Failed to get Workshop item ID from the url \""+url+"\"!", e); + } + + return 0; + } + #region Connecting to servers public static bool GetServers(Action onServerFound, Action onServerRulesReceived, Action onFinished) @@ -326,106 +436,6 @@ namespace Barotrauma.Steam return instance.client.Auth.GetAuthSessionTicket(); } -#endregion - -#region Server - - public static bool CreateServer(Networking.GameServer server, bool isPublic) - { - if (instance == null || !instance.isInitialized) - { - return false; - } - - ServerInit options = new ServerInit("Barotrauma", "Barotrauma") - { - GamePort = (ushort)server.Port, - QueryPort = (ushort)server.QueryPort - }; - //options.QueryShareGamePort(); - - instance.server = new Server(AppID, options, isPublic); - if (!instance.server.IsValid) - { - instance.server.Dispose(); - instance.server = null; - DebugConsole.ThrowError("Initializing Steam server failed."); - return false; - } - - RefreshServerDetails(server); - - instance.server.Auth.OnAuthChange = server.OnAuthChange; - Instance.server.LogOnAnonymous(); - - return true; - } - - public static bool RefreshServerDetails(Networking.GameServer server) - { - if (instance == null || !instance.isInitialized) - { - return false; - } - - // These server state variables may be changed at any time. Note that there is no lnoger a mechanism - // to send the player count. The player count is maintained by steam and you should use the player - // creation/authentication functions to maintain your player count. - instance.server.ServerName = server.Name; - instance.server.MaxPlayers = server.MaxPlayers; - instance.server.Passworded = server.HasPassword; - Instance.server.SetKey("message", GameMain.NetLobbyScreen.ServerMessageText); - Instance.server.SetKey("version", GameMain.Version.ToString()); - Instance.server.SetKey("contentpackage", string.Join(",", GameMain.Config.SelectedContentPackages.Select(cp => cp.Name))); - Instance.server.SetKey("contentpackagehash", string.Join(",", GameMain.Config.SelectedContentPackages.Select(cp => cp.MD5hash.Hash))); - Instance.server.SetKey("contentpackageurl", string.Join(",", GameMain.Config.SelectedContentPackages.Select(cp => cp.SteamWorkshopUrl ?? ""))); - Instance.server.SetKey("usingwhitelist", (server.WhiteList != null && server.WhiteList.Enabled).ToString()); - Instance.server.SetKey("modeselectionmode", server.ModeSelectionMode.ToString()); - Instance.server.SetKey("subselectionmode", server.SubSelectionMode.ToString()); - Instance.server.SetKey("allowspectating", server.AllowSpectating.ToString()); - Instance.server.SetKey("allowrespawn", server.AllowRespawn.ToString()); - Instance.server.SetKey("traitors", server.TraitorsEnabled.ToString()); - Instance.server.SetKey("gamestarted", server.GameStarted.ToString()); - Instance.server.SetKey("gamemode", server.GameModeIdentifier); - -#if SERVER - instance.server.DedicatedServer = true; -#endif - - return true; - } - - public static bool StartAuthSession(byte[] authTicketData, ulong clientSteamID) - { - if (instance == null || !instance.isInitialized || instance.server == null) return false; - - DebugConsole.Log("SteamManager authenticating Steam client " + clientSteamID); - if (!instance.server.Auth.StartSession(authTicketData, clientSteamID)) - { - DebugConsole.Log("Authentication failed"); - return false; - } - return true; - } - - public static void StopAuthSession(ulong clientSteamID) - { - if (instance == null || !instance.isInitialized || instance.server == null) return; - - DebugConsole.Log("SteamManager ending auth session with Steam client " + clientSteamID); - instance.server.Auth.EndSession(clientSteamID); - } - - public static bool CloseServer() - { - if (instance == null || !instance.isInitialized || instance.server == null) return false; - - instance.server.Dispose(); - instance.server = null; - - return true; - } - #endregion #region Workshop @@ -1028,6 +1038,8 @@ namespace Barotrauma.Steam #endregion +#endif + public static void Update(float deltaTime) { if (instance == null || !instance.isInitialized) return; @@ -1040,15 +1052,11 @@ namespace Barotrauma.Steam public static void ShutDown() { - if (instance == null || !instance.isInitialized) - { - return; - } - instance.client?.Dispose(); instance.client = null; instance.server?.Dispose(); instance.server = null; + instance = null; } } } diff --git a/Barotrauma/BarotraumaShared/Source/TextManager.cs b/Barotrauma/BarotraumaShared/Source/TextManager.cs index b88edac5c..fe210d1cf 100644 --- a/Barotrauma/BarotraumaShared/Source/TextManager.cs +++ b/Barotrauma/BarotraumaShared/Source/TextManager.cs @@ -39,9 +39,9 @@ namespace Barotrauma } } - public static void LoadTextPacks() + public static void LoadTextPacks(IEnumerable selectedContentPackages) { - var textFiles = ContentPackage.GetFilesOfType(GameMain.Config.SelectedContentPackages, ContentType.Text); + var textFiles = ContentPackage.GetFilesOfType(selectedContentPackages, ContentType.Text); foreach (string file in textFiles) { diff --git a/Barotrauma/BarotraumaShared/Submarines/Orca.sub b/Barotrauma/BarotraumaShared/Submarines/Orca.sub index 9205d10de..37c5a53e7 100644 Binary files a/Barotrauma/BarotraumaShared/Submarines/Orca.sub and b/Barotrauma/BarotraumaShared/Submarines/Orca.sub differ diff --git a/Barotrauma/BarotraumaShared/Submarines/Typhon.sub b/Barotrauma/BarotraumaShared/Submarines/Typhon.sub index b8a5f90fb..26df97f6a 100644 Binary files a/Barotrauma/BarotraumaShared/Submarines/Typhon.sub and b/Barotrauma/BarotraumaShared/Submarines/Typhon.sub differ