diff --git a/Barotrauma/BarotraumaClient/Source/GUI/GUIImage.cs b/Barotrauma/BarotraumaClient/Source/GUI/GUIImage.cs index 488541683..fcbafb160 100644 --- a/Barotrauma/BarotraumaClient/Source/GUI/GUIImage.cs +++ b/Barotrauma/BarotraumaClient/Source/GUI/GUIImage.cs @@ -70,6 +70,7 @@ namespace Barotrauma private GUIImage(RectTransform rectT, Sprite sprite, Rectangle? sourceRect, bool scaleToFit, string style) : base(style, rectT) { this.scaleToFit = scaleToFit; + sprite?.EnsureLazyLoaded(); Sprite = sprite; if (sourceRect.HasValue) { diff --git a/Barotrauma/BarotraumaClient/Source/GUI/GUIListBox.cs b/Barotrauma/BarotraumaClient/Source/GUI/GUIListBox.cs index ff64bddd2..049ea780e 100644 --- a/Barotrauma/BarotraumaClient/Source/GUI/GUIListBox.cs +++ b/Barotrauma/BarotraumaClient/Source/GUI/GUIListBox.cs @@ -506,7 +506,7 @@ namespace Barotrauma { if (ScrollBar.IsHorizontal) { - if (pos + child.Rect.Height + spacing > Content.Rect.Height || child == children.Last()) + if (pos + child.Rect.Height + spacing > Content.Rect.Height) { pos = 0; totalSize += child.Rect.Width + spacing; @@ -515,10 +515,14 @@ namespace Barotrauma { pos += child.Rect.Height + spacing; } + if (child == children.Last()) + { + totalSize += child.Rect.Width + spacing; + } } else { - if (pos + child.Rect.Width + spacing > Content.Rect.Width || child == children.Last()) + if (pos + child.Rect.Width + spacing > Content.Rect.Width) { pos = 0; totalSize += child.Rect.Height + spacing; @@ -527,6 +531,11 @@ namespace Barotrauma { pos += child.Rect.Width + spacing; } + + if (child == children.Last()) + { + totalSize += child.Rect.Height + spacing; + } } } } diff --git a/Barotrauma/BarotraumaClient/Source/GameSettings.cs b/Barotrauma/BarotraumaClient/Source/GameSettings.cs index 4eb203754..4568583d0 100644 --- a/Barotrauma/BarotraumaClient/Source/GameSettings.cs +++ b/Barotrauma/BarotraumaClient/Source/GameSettings.cs @@ -476,13 +476,13 @@ namespace Barotrauma } }; #endif - var radioButtonFrame = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.12f), audioSliders.RectTransform)); + //var radioButtonFrame = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.12f), audioSliders.RectTransform)); GUIRadioButtonGroup voiceMode = new GUIRadioButtonGroup(); for (int i = 0; i < 3; i++) { string langStr = "VoiceMode." + ((VoiceMode)i).ToString(); - var tick = new GUITickBox(new RectTransform(new Point(32, 32), radioButtonFrame.RectTransform), TextManager.Get(langStr)) + var tick = new GUITickBox(new RectTransform(new Point(32, 32), audioSliders.RectTransform), TextManager.Get(langStr)) { ToolTip = TextManager.Get(langStr + "ToolTip") }; @@ -508,9 +508,12 @@ namespace Barotrauma }; micVolumeSlider.OnMoved(micVolumeSlider, micVolumeSlider.BarScroll); - var voiceInputContainer = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 1.0f), audioSliders.RectTransform, Anchor.BottomCenter)); - new GUITextBlock(new RectTransform(new Vector2(0.6f, 0.05f), voiceInputContainer.RectTransform), TextManager.Get("InputType.Voice") + ": "); - var voiceKeyBox = new GUITextBox(new RectTransform(new Vector2(0.4f, 0.05f), voiceInputContainer.RectTransform, Anchor.TopRight), + + var extraVoiceSettingsContainer = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.2f), audioSliders.RectTransform, Anchor.BottomCenter), style: null); + + var voiceInputContainer = new GUILayoutGroup(new RectTransform(Vector2.One, extraVoiceSettingsContainer.RectTransform, Anchor.BottomCenter)); + new GUITextBlock(new RectTransform(new Vector2(0.6f, 0.25f), voiceInputContainer.RectTransform), TextManager.Get("InputType.Voice") + ": "); + var voiceKeyBox = new GUITextBox(new RectTransform(new Vector2(0.4f, 0.25f), voiceInputContainer.RectTransform, Anchor.TopRight), text: keyMapping[(int)InputType.Voice].ToString()) { UserData = InputType.Voice @@ -518,22 +521,22 @@ namespace Barotrauma voiceKeyBox.OnSelected += KeyBoxSelected; voiceKeyBox.SelectedColor = Color.Gold * 0.3f; - var voiceActivityGroup = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.15f), audioSliders.RectTransform)); - GUITextBlock noiseGateText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.5f), voiceActivityGroup.RectTransform), TextManager.Get("NoiseGateThreshold")) + var voiceActivityGroup = new GUILayoutGroup(new RectTransform(Vector2.One, extraVoiceSettingsContainer.RectTransform)); + GUITextBlock noiseGateText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.25f), voiceActivityGroup.RectTransform), TextManager.Get("NoiseGateThreshold")) { TextGetter = () => { return TextManager.Get("NoiseGateThreshold") + " " + ((int)NoiseGateThreshold).ToString() + " dB"; } }; - var dbMeter = new GUIProgressBar(new RectTransform(new Vector2(1.0f, 0.5f), voiceActivityGroup.RectTransform), 0.0f, Color.Lime); + var dbMeter = new GUIProgressBar(new RectTransform(new Vector2(1.0f, 0.25f), voiceActivityGroup.RectTransform), 0.0f, Color.Lime); dbMeter.ProgressGetter = () => { if (VoipCapture.Instance == null) return 0.0f; dbMeter.Color = VoipCapture.Instance.LastdB > NoiseGateThreshold ? Color.Lime : Color.Orange; //TODO: i'm a filthy hack return ((float)VoipCapture.Instance.LastdB + 100.0f) / 100.0f; }; - var noiseGateSlider = new GUIScrollBar(new RectTransform(new Vector2(1.0f, 1.0f), dbMeter.RectTransform, Anchor.Center), color: Color.White, barSize: 0.03f); + var noiseGateSlider = new GUIScrollBar(new RectTransform(Vector2.One, dbMeter.RectTransform, Anchor.Center), color: Color.White, barSize: 0.03f); noiseGateSlider.Frame.Visible = false; noiseGateSlider.Step = 0.01f; noiseGateSlider.Range = new Vector2(-100.0f, 0.0f); @@ -631,7 +634,7 @@ namespace Barotrauma var inputNames = Enum.GetValues(typeof(InputType)); for (int i = 0; i < inputNames.Length; i++) { - var inputContainer = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.06f), inputFrame.RectTransform)) { Stretch = true, IsHorizontal = true, RelativeSpacing = 0.05f, Color = Color.DarkGray * 0.25f }; + var inputContainer = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.06f), inputFrame.RectTransform)) { Stretch = true, IsHorizontal = true, RelativeSpacing = 0.05f, Color = new Color(12, 14, 15, 215) }; new GUITextBlock(new RectTransform(new Vector2(0.3f, 1.0f), inputContainer.RectTransform, Anchor.TopLeft) { MinSize = new Point(150, 0) }, TextManager.Get("InputType." + ((InputType)i)) + ": ", font: GUI.SmallFont) { ForceUpperCase = true }; var keyBox = new GUITextBox(new RectTransform(new Vector2(0.7f, 1.0f), inputContainer.RectTransform), @@ -643,7 +646,7 @@ namespace Barotrauma keyBox.SelectedColor = Color.Gold * 0.3f; //spacing - new GUIFrame(new RectTransform(new Vector2(1.0f, 0.005f), inputFrame.RectTransform), style: null); + new GUIFrame(new RectTransform(new Vector2(1.0f, 0.02f), inputFrame.RectTransform), style: null); } GUITextBlock aimAssistText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.05f), controlsLayoutGroup.RectTransform), TextManager.Get("AimAssist")); GUIScrollBar aimAssistSlider = new GUIScrollBar(new RectTransform(new Vector2(1.0f, 0.05f), controlsLayoutGroup.RectTransform), @@ -718,6 +721,25 @@ namespace Barotrauma } }; + //spacing + new GUIFrame(new RectTransform(new Vector2(1.0f, 0.02f), generalLayoutGroup.RectTransform), style: null); + + new GUIButton(new RectTransform(new Vector2(0.4f, 1.0f), buttonArea.RectTransform, Anchor.BottomLeft), + TextManager.Get("Cancel"), style: "GUIButtonLarge") + { + IgnoreLayoutGroups = true, + OnClicked = (x, y) => + { + if (UnsavedSettings) + { + LoadPlayerConfig(); + } + if (Screen.Selected == GameMain.MainMenuScreen) GameMain.MainMenuScreen.ReturnToMainMenu(null, null); + GUI.SettingsMenuOpen = false; + return true; + } + }; + applyButton = new GUIButton(new RectTransform(new Vector2(0.4f, 1.0f), buttonArea.RectTransform, Anchor.BottomRight), TextManager.Get("ApplySettingsButton"), style: "GUIButtonLarge") { diff --git a/Barotrauma/BarotraumaClient/Source/Items/Components/Machines/Fabricator.cs b/Barotrauma/BarotraumaClient/Source/Items/Components/Machines/Fabricator.cs index bfb7900fb..4dc0b89a1 100644 --- a/Barotrauma/BarotraumaClient/Source/Items/Components/Machines/Fabricator.cs +++ b/Barotrauma/BarotraumaClient/Source/Items/Components/Machines/Fabricator.cs @@ -17,6 +17,8 @@ namespace Barotrauma.Items.Components private GUIButton activateButton; + private GUITextBox itemFilterBox; + private GUIComponent inputInventoryHolder, outputInventoryHolder; private GUICustomComponent inputInventoryOverlay, outputInventoryOverlay; @@ -28,12 +30,25 @@ namespace Barotrauma.Items.Components partial void InitProjSpecific() { - var paddedFrame = new GUILayoutGroup(new RectTransform(new Vector2(0.95f, 0.9f), GuiFrame.RectTransform, Anchor.Center), childAnchor: Anchor.TopCenter) + var paddedFrame = new GUILayoutGroup(new RectTransform(new Vector2(0.95f, 0.95f), GuiFrame.RectTransform, Anchor.Center), childAnchor: Anchor.TopCenter) { Stretch = true, RelativeSpacing = 0.02f }; + var filterArea = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.06f), paddedFrame.RectTransform), isHorizontal: true) + { + Stretch = true, + UserData = "filterarea" + }; + new GUITextBlock(new RectTransform(new Vector2(0.25f, 1.0f), filterArea.RectTransform), TextManager.Get("FilterMapEntities"), font: GUI.Font); + itemFilterBox = new GUITextBox(new RectTransform(new Vector2(0.8f, 1.0f), filterArea.RectTransform), font: GUI.Font); + itemFilterBox.OnTextChanged += (textBox, text) => { FilterEntities(text); return true; }; + var clearButton = new GUIButton(new RectTransform(new Vector2(0.1f, 1.0f), filterArea.RectTransform), "x") + { + OnClicked = (btn, userdata) => { ClearFilter(); itemFilterBox.Flash(Color.White); return true; } + }; + itemList = new GUIListBox(new RectTransform(new Vector2(1.0f, 0.5f), paddedFrame.RectTransform)) { OnSelected = (GUIComponent component, object userdata) => @@ -50,7 +65,7 @@ namespace Barotrauma.Items.Components CanBeFocused = false }; - var outputArea = new GUILayoutGroup(new RectTransform(new Vector2(0.95f, 0.3f), paddedFrame.RectTransform), isHorizontal: true); + var outputArea = new GUILayoutGroup(new RectTransform(new Vector2(0.95f, 0.25f), paddedFrame.RectTransform), isHorizontal: true); selectedItemFrame = new GUIFrame(new RectTransform(new Vector2(0.75f, 1.0f), outputArea.RectTransform), style: "InnerFrame"); outputInventoryHolder = new GUIFrame(new RectTransform(new Vector2(0.25f, 1.0f), outputArea.RectTransform), style: null); @@ -61,7 +76,7 @@ namespace Barotrauma.Items.Components foreach (FabricationRecipe fi in fabricationRecipes) { - GUIFrame frame = new GUIFrame(new RectTransform(new Point(itemList.Rect.Width, 50), itemList.Content.RectTransform), style: null) + GUIFrame frame = new GUIFrame(new RectTransform(new Point(itemList.Rect.Width, 30), itemList.Content.RectTransform), style: null) { UserData = fi, HoverColor = Color.Gold * 0.2f, @@ -78,7 +93,7 @@ namespace Barotrauma.Items.Components var itemIcon = fi.TargetItem.InventoryIcon ?? fi.TargetItem.sprite; if (itemIcon != null) { - GUIImage img = new GUIImage(new RectTransform(new Point(40, 40), frame.RectTransform, Anchor.CenterLeft) { AbsoluteOffset = new Point(3, 0) }, + GUIImage img = new GUIImage(new RectTransform(new Point(30, 30), frame.RectTransform, Anchor.CenterLeft) { AbsoluteOffset = new Point(3, 0) }, itemIcon, scaleToFit: true) { Color = fi.TargetItem.InventoryIconColor, @@ -88,7 +103,7 @@ namespace Barotrauma.Items.Components } activateButton = new GUIButton(new RectTransform(new Vector2(0.8f, 0.07f), paddedFrame.RectTransform), - TextManager.Get("FabricatorCreate")) + TextManager.Get("FabricatorCreate"), style: "GUIButtonLarge") { OnClicked = StartButtonClicked, UserData = selectedItem, @@ -257,6 +272,36 @@ namespace Barotrauma.Items.Components } } + private bool FilterEntities(string filter) + { + if (string.IsNullOrWhiteSpace(filter)) + { + itemList.Content.Children.ForEach(c => c.Visible = true); + return true; + } + + filter = filter.ToLower(); + foreach (GUIComponent child in itemList.Content.Children) + { + FabricationRecipe recipe = child.UserData as FabricationRecipe; + if (recipe?.DisplayName == null) { continue; } + child.Visible = recipe.DisplayName.ToLower().Contains(filter); + } + itemList.UpdateScrollBarSize(); + itemList.BarScroll = 0.0f; + + return true; + } + + public bool ClearFilter() + { + FilterEntities(""); + itemList.UpdateScrollBarSize(); + itemList.BarScroll = 0.0f; + itemFilterBox.Text = ""; + return true; + } + private bool SelectItem(Character user, FabricationRecipe selectedItem) { selectedItemFrame.ClearChildren(); @@ -340,8 +385,6 @@ namespace Barotrauma.Items.Components { item.CreateClientEvent(this); } - itemList.UpdateScrollBarSize(); - itemList.BarScroll = 0.0f; return true; } diff --git a/Barotrauma/BarotraumaClient/Source/Items/Item.cs b/Barotrauma/BarotraumaClient/Source/Items/Item.cs index 662a31e90..03cfc2bd8 100644 --- a/Barotrauma/BarotraumaClient/Source/Items/Item.cs +++ b/Barotrauma/BarotraumaClient/Source/Items/Item.cs @@ -615,6 +615,9 @@ namespace Barotrauma if (GameMain.GameSession?.CrewManager != null) { disallowedAreas.Add(GameMain.GameSession.CrewManager.GetCharacterListArea()); + disallowedAreas.Add(new Rectangle( + HUDLayoutSettings.ChatBoxArea.X - 50, HUDLayoutSettings.ChatBoxArea.Y, + HUDLayoutSettings.ChatBoxArea.Width + 50, HUDLayoutSettings.ChatBoxArea.Height)); } GUI.PreventElementOverlap(elementsToMove, disallowedAreas, diff --git a/Barotrauma/BarotraumaClient/Source/Screens/MainMenuScreen.cs b/Barotrauma/BarotraumaClient/Source/Screens/MainMenuScreen.cs index 272f9916a..b2657292a 100644 --- a/Barotrauma/BarotraumaClient/Source/Screens/MainMenuScreen.cs +++ b/Barotrauma/BarotraumaClient/Source/Screens/MainMenuScreen.cs @@ -219,9 +219,9 @@ namespace Barotrauma //spacing new GUIFrame(new RectTransform(new Vector2(0.01f, 0.0f), optionHolder.RectTransform), style: null); - var optionButtons = new GUILayoutGroup(new RectTransform(new Vector2(0.8f, 1.0f), parent: optionHolder.RectTransform) { RelativeOffset = new Vector2(0.0f, 0.15f) }); + var optionButtons = new GUILayoutGroup(new RectTransform(new Vector2(0.8f, 1.0f), parent: optionHolder.RectTransform) { RelativeOffset = new Vector2(0.0f, 0.05f) }); - var optionList = new GUILayoutGroup(new RectTransform(new Vector2(0.8f, 0.15f), parent: optionButtons.RectTransform)) + var optionList = new GUILayoutGroup(new RectTransform(new Vector2(0.8f, 0.3f), parent: optionButtons.RectTransform)) { Stretch = false, RelativeSpacing = 0.035f diff --git a/Barotrauma/BarotraumaClient/Source/Screens/SubEditorScreen.cs b/Barotrauma/BarotraumaClient/Source/Screens/SubEditorScreen.cs index 065c518f3..beb723f80 100644 --- a/Barotrauma/BarotraumaClient/Source/Screens/SubEditorScreen.cs +++ b/Barotrauma/BarotraumaClient/Source/Screens/SubEditorScreen.cs @@ -65,6 +65,9 @@ namespace Barotrauma private readonly string containerDeleteTag = "containerdelete"; + private Color primaryColor = new Color(12, 14, 15, 190); + private Color secondaryColor = new Color(12, 14, 15, 215); + public override Camera Cam { get { return cam; } @@ -189,16 +192,17 @@ namespace Barotrauma return true; }; - LeftPanel = new GUIFrame(new RectTransform(new Vector2(0.08f, 1.0f), GUI.Canvas) { MinSize = new Point(170, 0) }, "GUIFrameLeft"); - GUILayoutGroup paddedLeftPanel = new GUILayoutGroup(new RectTransform( - new Point((int)(LeftPanel.Rect.Width * 0.8f), (int)(GameMain.GraphicsHeight - TopPanel.Rect.Height * 0.95f)), - LeftPanel.RectTransform, Anchor.Center) - { AbsoluteOffset = new Point(0, TopPanel.Rect.Height) }) + LeftPanel = new GUIFrame(new RectTransform(new Vector2(0.08f, 1.0f), GUI.Canvas) { MinSize = new Point(170, 0) }, style: null) { Color = primaryColor }; + + GUILayoutGroup paddedLeftPanel = new GUILayoutGroup(new RectTransform(new Point((int)(LeftPanel.Rect.Width), (int)(GameMain.GraphicsHeight - TopPanel.Rect.Height * 0.95f)), + LeftPanel.RectTransform, Anchor.Center)) { - RelativeSpacing = 0.01f, Stretch = true }; + //empty guiframe as a separator + new GUIFrame(new RectTransform(new Vector2(1.0f, 0.02f), paddedLeftPanel.RectTransform) { AbsoluteOffset = new Point(0, TopPanel.Rect.Height) }, style: null); + GUITextBlock itemCount = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), paddedLeftPanel.RectTransform), "ItemCount") { TextGetter = GetItemCount @@ -240,10 +244,9 @@ namespace Barotrauma //Entity menu //------------------------------------------------ - EntityMenu = new GUIFrame(new RectTransform(new Point(GameMain.GraphicsWidth - LeftPanel.Rect.Width + 20, (int)(300 * GUI.Scale)), GUI.Canvas, Anchor.BottomRight), - style: "GUIFrameBottom"); + EntityMenu = new GUIFrame(new RectTransform(new Point(GameMain.GraphicsWidth - LeftPanel.Rect.Width, (int)(359 * GUI.Scale)), GUI.Canvas, Anchor.BottomRight), style: null) { Color = primaryColor }; - toggleEntityMenuButton = new GUIButton(new RectTransform(new Vector2(0.25f, 0.1f), EntityMenu.RectTransform, Anchor.TopCenter, Pivot.BottomCenter) { RelativeOffset = new Vector2(0.0f, -0.12f) }, + toggleEntityMenuButton = new GUIButton(new RectTransform(new Vector2(0.15f, 0.1f), EntityMenu.RectTransform, Anchor.TopCenter, Pivot.BottomCenter) { RelativeOffset = new Vector2(0.0f, -0.05f) }, style: "GUIButtonVerticalArrow") { OnClicked = (btn, userdata) => @@ -259,7 +262,25 @@ namespace Barotrauma } }; - var tabButtonHolder = new GUILayoutGroup(new RectTransform(new Vector2(0.9f, 0.1f), EntityMenu.RectTransform, Anchor.TopRight, Pivot.BottomRight), + var paddedTab = new GUIFrame(new RectTransform(new Vector2(1.0f, 1.0f), EntityMenu.RectTransform, Anchor.Center), style: null); + + var filterArea = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.1f), paddedTab.RectTransform), isHorizontal: true) + { + Color = secondaryColor, + Stretch = true, + UserData = "filterarea" + }; + new GUITextBlock(new RectTransform(new Vector2(0.05f, 1.0f), filterArea.RectTransform), TextManager.Get("FilterMapEntities"), font: GUI.Font); + entityFilterBox = new GUITextBox(new RectTransform(new Vector2(0.8f, 1.0f), filterArea.RectTransform), font: GUI.Font); + entityFilterBox.OnTextChanged += (textBox, text) => { FilterEntities(text); return true; }; + var clearButton = new GUIButton(new RectTransform(new Vector2(0.02f, 1.0f), filterArea.RectTransform), "x") + { + OnClicked = (btn, userdata) => { ClearFilter(); entityFilterBox.Flash(Color.White); return true; } + }; + + var entityListHolder = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.85f), paddedTab.RectTransform, Anchor.Center) { RelativeOffset = new Vector2(0.0f, 0.05f) }); + + var tabButtonHolder = new GUILayoutGroup(new RectTransform(new Vector2(0.9f, 0.1f), entityListHolder.RectTransform, Anchor.TopRight, Pivot.BottomRight), isHorizontal: true) { RelativeSpacing = 0.01f, @@ -280,21 +301,7 @@ namespace Barotrauma }); } - var paddedTab = new GUIFrame(new RectTransform(new Vector2(0.95f, 0.8f), EntityMenu.RectTransform, Anchor.Center), style: null); - var filterArea = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.15f), paddedTab.RectTransform), isHorizontal: true) - { - AbsoluteSpacing = 5, - Stretch = true, - UserData = "filterarea" - }; - new GUITextBlock(new RectTransform(new Vector2(0.15f, 1.0f), filterArea.RectTransform), TextManager.Get("FilterMapEntities"), font: GUI.SmallFont); - entityFilterBox = new GUITextBox(new RectTransform(new Vector2(0.8f, 1.0f), filterArea.RectTransform), font: GUI.SmallFont); - entityFilterBox.OnTextChanged += (textBox, text) => { FilterEntities(text); return true; }; - var clearButton = new GUIButton(new RectTransform(new Vector2(0.05f, 1.0f), filterArea.RectTransform), "x") - { - OnClicked = (btn, userdata) => { ClearFilter(); entityFilterBox.Flash(Color.White); return true; } - }; - entityList = new GUIListBox(new RectTransform(new Vector2(1.0f, 0.85f), paddedTab.RectTransform, Anchor.BottomCenter)) + entityList = new GUIListBox(new RectTransform(new Vector2(1.0f, 0.9f), entityListHolder.RectTransform, Anchor.BottomCenter)) { OnSelected = SelectPrefab, UseGridLayout = true, @@ -305,7 +312,10 @@ namespace Barotrauma //empty guiframe as a separator new GUIFrame(new RectTransform(new Vector2(1.0f, 0.02f), paddedLeftPanel.RectTransform), style: null); - characterModeTickBox = new GUITickBox(new RectTransform(new Vector2(1.0f, 0.025f), paddedLeftPanel.RectTransform), TextManager.Get("CharacterModeButton")) + var characterModeTickBoxHolder = new GUILayoutGroup(new RectTransform(new Vector2(paddedLeftPanel.RectTransform.RelativeSize.X, 0.01f), paddedLeftPanel.RectTransform) { MinSize = new Point(0, 32) }) + { Color = secondaryColor }; + + characterModeTickBox = new GUITickBox(new RectTransform(new Point(32, 32), characterModeTickBoxHolder.RectTransform) { AbsoluteOffset = new Point(10, 0) }, TextManager.Get("CharacterModeButton")) { ToolTip = TextManager.Get("CharacterModeToolTip"), OnSelected = (GUITickBox tBox) => @@ -314,7 +324,11 @@ namespace Barotrauma return true; } }; - wiringModeTickBox = new GUITickBox(new RectTransform(new Vector2(1.0f, 0.025f), paddedLeftPanel.RectTransform), TextManager.Get("WiringModeButton")) + + var wiringModeTickBoxHolder = new GUILayoutGroup(new RectTransform(new Vector2(paddedLeftPanel.RectTransform.RelativeSize.X, 0.01f), paddedLeftPanel.RectTransform) { MinSize = new Point(0, 32) }) + { Color = secondaryColor }; + + wiringModeTickBox = new GUITickBox(new RectTransform(new Point(32, 32), wiringModeTickBoxHolder.RectTransform) { AbsoluteOffset = new Point(10, 0) }, TextManager.Get("WiringModeButton")) { ToolTip = TextManager.Get("WiringModeToolTip"), OnSelected = (GUITickBox tBox) => @@ -333,9 +347,13 @@ namespace Barotrauma OnClicked = GenerateWaypoints }; - new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.03f), paddedLeftPanel.RectTransform), TextManager.Get("ShowEntitiesLabel")); + // empty guiframe as a separator + new GUIFrame(new RectTransform(new Vector2(1.0f, 0.02f), paddedLeftPanel.RectTransform), style: null); - var tickBox = new GUITickBox(new RectTransform(new Vector2(1.0f, 0.03f), paddedLeftPanel.RectTransform), TextManager.Get("ShowLighting")) + var showEntitiesHolder = new GUILayoutGroup(new RectTransform(new Vector2(paddedLeftPanel.RectTransform.RelativeSize.X, 0.3f), paddedLeftPanel.RectTransform)) + { Color = secondaryColor, Stretch = true, RelativeSpacing = 0.05f }; + + var tickBox = new GUITickBox(new RectTransform(new Point(32, 32), showEntitiesHolder.RectTransform) { AbsoluteOffset = new Point(10, 0) }, TextManager.Get("ShowLighting")) { Selected = lightingEnabled, OnSelected = (GUITickBox obj) => @@ -357,52 +375,49 @@ namespace Barotrauma return true; } }; - tickBox = new GUITickBox(new RectTransform(new Vector2(1.0f, 0.03f), paddedLeftPanel.RectTransform), TextManager.Get("ShowWalls")) + tickBox = new GUITickBox(new RectTransform(new Point(32, 32), showEntitiesHolder.RectTransform) { AbsoluteOffset = new Point(10, 0) }, TextManager.Get("ShowWalls")) { Selected = Structure.ShowWalls, OnSelected = (GUITickBox obj) => { Structure.ShowWalls = obj.Selected; return true; } }; - tickBox = new GUITickBox(new RectTransform(new Vector2(1.0f, 0.03f), paddedLeftPanel.RectTransform), TextManager.Get("ShowStructures")) + tickBox = new GUITickBox(new RectTransform(new Point(32, 32), showEntitiesHolder.RectTransform) { AbsoluteOffset = new Point(10, 0) }, TextManager.Get("ShowStructures")) { Selected = Structure.ShowStructures, OnSelected = (GUITickBox obj) => { Structure.ShowStructures = obj.Selected; return true; } }; - tickBox = new GUITickBox(new RectTransform(new Vector2(1.0f, 0.03f), paddedLeftPanel.RectTransform), TextManager.Get("ShowItems")) + tickBox = new GUITickBox(new RectTransform(new Point(32, 32), showEntitiesHolder.RectTransform) { AbsoluteOffset = new Point(10, 0) }, TextManager.Get("ShowItems")) { Selected = Item.ShowItems, OnSelected = (GUITickBox obj) => { Item.ShowItems = obj.Selected; return true; } }; - tickBox = new GUITickBox(new RectTransform(new Vector2(1.0f, 0.03f), paddedLeftPanel.RectTransform), TextManager.Get("ShowWaypoints")) + tickBox = new GUITickBox(new RectTransform(new Point(32, 32), showEntitiesHolder.RectTransform) { AbsoluteOffset = new Point(10, 0) }, TextManager.Get("ShowWaypoints")) { Selected = WayPoint.ShowWayPoints, OnSelected = (GUITickBox obj) => { WayPoint.ShowWayPoints = obj.Selected; return true; } }; - tickBox = new GUITickBox(new RectTransform(new Vector2(1.0f, 0.03f), paddedLeftPanel.RectTransform), TextManager.Get("ShowSpawnpoints")) + tickBox = new GUITickBox(new RectTransform(new Point(32, 32), showEntitiesHolder.RectTransform) { AbsoluteOffset = new Point(10, 0) }, TextManager.Get("ShowSpawnpoints")) { Selected = WayPoint.ShowSpawnPoints, OnSelected = (GUITickBox obj) => { WayPoint.ShowSpawnPoints = obj.Selected; return true; } }; - tickBox = new GUITickBox(new RectTransform(new Vector2(1.0f, 0.03f), paddedLeftPanel.RectTransform), TextManager.Get("ShowLinks")) + tickBox = new GUITickBox(new RectTransform(new Point(32, 32), showEntitiesHolder.RectTransform) { AbsoluteOffset = new Point(10, 0) }, TextManager.Get("ShowLinks")) { Selected = Item.ShowLinks, OnSelected = (GUITickBox obj) => { Item.ShowLinks = obj.Selected; return true; } }; - tickBox = new GUITickBox(new RectTransform(new Vector2(1.0f, 0.03f), paddedLeftPanel.RectTransform), TextManager.Get("ShowHulls")) + tickBox = new GUITickBox(new RectTransform(new Point(32, 32), showEntitiesHolder.RectTransform) { AbsoluteOffset = new Point(10, 0) }, TextManager.Get("ShowHulls")) { Selected = Hull.ShowHulls, OnSelected = (GUITickBox obj) => { Hull.ShowHulls = obj.Selected; return true; } }; - tickBox = new GUITickBox(new RectTransform(new Vector2(1.0f, 0.03f), paddedLeftPanel.RectTransform), TextManager.Get("ShowGaps")) + tickBox = new GUITickBox(new RectTransform(new Point(32, 32), showEntitiesHolder.RectTransform) { AbsoluteOffset = new Point(10, 0) }, TextManager.Get("ShowGaps")) { Selected = Gap.ShowGaps, OnSelected = (GUITickBox obj) => { Gap.ShowGaps = obj.Selected; return true; }, }; - //empty guiframe as a separator - new GUIFrame(new RectTransform(new Vector2(1.0f, 0.025f), paddedLeftPanel.RectTransform), style: null); - - new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.025f), paddedLeftPanel.RectTransform), TextManager.Get("PreviouslyUsedLabel")); - previouslyUsedList = new GUIListBox(new RectTransform(new Vector2(1.0f, 0.25f), paddedLeftPanel.RectTransform)) + new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.025f), paddedLeftPanel.RectTransform, Anchor.BottomCenter) { AbsoluteOffset = new Point(10, 0) }, TextManager.Get("PreviouslyUsedLabel")); + previouslyUsedList = new GUIListBox(new RectTransform(new Vector2(1.0f, 0.2f), paddedLeftPanel.RectTransform, Anchor.BottomCenter) { AbsoluteOffset = new Point(10, 0) }) { OnSelected = SelectPrefab }; diff --git a/Barotrauma/BarotraumaServer/Source/Characters/CharacterNetworking.cs b/Barotrauma/BarotraumaServer/Source/Characters/CharacterNetworking.cs index 9845cb86c..bd80dfedc 100644 --- a/Barotrauma/BarotraumaServer/Source/Characters/CharacterNetworking.cs +++ b/Barotrauma/BarotraumaServer/Source/Characters/CharacterNetworking.cs @@ -356,7 +356,7 @@ namespace Barotrauma } tempBuffer.Write(IsRagdolled); - tempBuffer.Write(AnimController.TargetDir == Direction.Right); + tempBuffer.Write(AnimController.Dir > 0.0f); } if (SelectedCharacter != null || SelectedConstruction != null) diff --git a/Barotrauma/BarotraumaShared/Source/Characters/AI/EnemyAIController.cs b/Barotrauma/BarotraumaShared/Source/Characters/AI/EnemyAIController.cs index bd2b5a4c8..3d5c95995 100644 --- a/Barotrauma/BarotraumaShared/Source/Characters/AI/EnemyAIController.cs +++ b/Barotrauma/BarotraumaShared/Source/Characters/AI/EnemyAIController.cs @@ -530,7 +530,8 @@ namespace Barotrauma } } - if (Math.Abs(Character.AnimController.movement.X) > 0.1f && !Character.AnimController.InWater) + if (Math.Abs(Character.AnimController.movement.X) > 0.1f && !Character.AnimController.InWater && + (GameMain.NetworkMember == null || GameMain.NetworkMember.IsServer || Character.Controlled == Character)) { Character.AnimController.TargetDir = Character.WorldPosition.X < attackWorldPos.X ? Direction.Right : Direction.Left; } diff --git a/Barotrauma/BarotraumaShared/Source/GameSettings.cs b/Barotrauma/BarotraumaShared/Source/GameSettings.cs index bc013075e..faf4efe83 100644 --- a/Barotrauma/BarotraumaShared/Source/GameSettings.cs +++ b/Barotrauma/BarotraumaShared/Source/GameSettings.cs @@ -416,6 +416,11 @@ namespace Barotrauma keyMapping[(int)InputType.Voice] = new KeyOrMouse(Keys.V); + keyMapping[(int)InputType.SelectNextCharacter] = new KeyOrMouse(Keys.Tab); + keyMapping[(int)InputType.SelectPreviousCharacter] = new KeyOrMouse(Keys.Q); + + keyMapping[(int)InputType.Voice] = new KeyOrMouse(Keys.V); + keyMapping[(int)InputType.Use] = new KeyOrMouse(0); keyMapping[(int)InputType.Aim] = new KeyOrMouse(1); @@ -918,6 +923,371 @@ namespace Barotrauma } #endregion + #region Save PlayerConfig + public void SaveNewPlayerConfig() + { + XDocument doc = new XDocument(); + UnsavedSettings = false; + + if (doc.Root == null) + { + doc.Add(new XElement("config")); + } + + doc.Root.Add( + new XAttribute("language", TextManager.Language), + new XAttribute("masterserverurl", MasterServerUrl), + new XAttribute("autocheckupdates", AutoCheckUpdates), + new XAttribute("musicvolume", musicVolume), + new XAttribute("soundvolume", soundVolume), + new XAttribute("verboselogging", VerboseLogging), + new XAttribute("savedebugconsolelogs", SaveDebugConsoleLogs), + new XAttribute("enablesplashscreen", EnableSplashScreen), + new XAttribute("usesteammatchmaking", useSteamMatchmaking), + new XAttribute("quickstartsub", QuickStartSubmarineName), + new XAttribute("requiresteamauthentication", requireSteamAuthentication), + new XAttribute("autoupdateworkshopitems", AutoUpdateWorkshopItems), + new XAttribute("aimassistamount", aimAssistAmount), + new XAttribute("enablemouselook", EnableMouseLook)); + + if (!ShowUserStatisticsPrompt) + { + doc.Root.Add(new XAttribute("senduserstatistics", sendUserStatistics)); + } + + XElement gMode = doc.Root.Element("graphicsmode"); + if (gMode == null) + { + gMode = new XElement("graphicsmode"); + doc.Root.Add(gMode); + } + if (GraphicsWidth == 0 || GraphicsHeight == 0) + { + gMode.ReplaceAttributes(new XAttribute("displaymode", windowMode)); + } + else + { + gMode.ReplaceAttributes( + new XAttribute("width", GraphicsWidth), + new XAttribute("height", GraphicsHeight), + new XAttribute("vsync", VSyncEnabled), + new XAttribute("displaymode", windowMode)); + } + + XElement gSettings = doc.Root.Element("graphicssettings"); + if (gSettings == null) + { + gSettings = new XElement("graphicssettings"); + doc.Root.Add(gSettings); + } + + gSettings.ReplaceAttributes( + new XAttribute("particlelimit", ParticleLimit), + new XAttribute("lightmapscale", LightMapScale), + new XAttribute("specularity", SpecularityEnabled), + new XAttribute("chromaticaberration", ChromaticAberrationEnabled), + new XAttribute("losmode", LosMode), + new XAttribute("hudscale", HUDScale), + new XAttribute("inventoryscale", InventoryScale)); + + foreach (ContentPackage contentPackage in SelectedContentPackages) + { + if (contentPackage.Path.Contains(vanillaContentPackagePath)) + { + doc.Root.Add(new XElement("contentpackage", new XAttribute("path", contentPackage.Path))); + break; + } + } + + var keyMappingElement = new XElement("keymapping"); + doc.Root.Add(keyMappingElement); + for (int i = 0; i < keyMapping.Length; i++) + { + if (keyMapping[i].MouseButton == null) + { + keyMappingElement.Add(new XAttribute(((InputType)i).ToString(), keyMapping[i].Key)); + } + else + { + keyMappingElement.Add(new XAttribute(((InputType)i).ToString(), keyMapping[i].MouseButton)); + } + } + + var gameplay = new XElement("gameplay"); + var jobPreferences = new XElement("jobpreferences"); + foreach (string jobName in JobPreferences) + { + jobPreferences.Add(new XElement("job", new XAttribute("identifier", jobName))); + } + gameplay.Add(jobPreferences); + doc.Root.Add(gameplay); + + var playerElement = new XElement("player", + new XAttribute("name", defaultPlayerName ?? ""), + new XAttribute("headindex", CharacterHeadIndex), + new XAttribute("gender", CharacterGender), + new XAttribute("race", CharacterRace), + new XAttribute("hairindex", CharacterHairIndex), + new XAttribute("beardindex", CharacterBeardIndex), + new XAttribute("moustacheindex", CharacterMoustacheIndex), + new XAttribute("faceattachmentindex", CharacterFaceAttachmentIndex)); + doc.Root.Add(playerElement); + + XmlWriterSettings settings = new XmlWriterSettings + { + Indent = true, + OmitXmlDeclaration = true, + NewLineOnAttributes = true + }; + + try + { + using (var writer = XmlWriter.Create(savePath, settings)) + { + doc.WriteTo(writer); + writer.Flush(); + } + } + catch (Exception e) + { + DebugConsole.ThrowError("Saving game settings failed.", e); + GameAnalyticsManager.AddErrorEventOnce("GameSettings.Save:SaveFailed", GameAnalyticsSDK.Net.EGAErrorSeverity.Error, + "Saving game settings failed.\n" + e.Message + "\n" + e.StackTrace); + } + } + #endregion + + #region Load PlayerConfig + // TODO: DRY + public void LoadPlayerConfig() + { + XDocument doc = XMLExtensions.LoadXml(playerSavePath); + + if (doc == null || doc.Root == null) + { + ShowUserStatisticsPrompt = true; + SaveNewPlayerConfig(); + return; + } + + Language = doc.Root.GetAttributeString("language", Language); + AutoCheckUpdates = doc.Root.GetAttributeBool("autocheckupdates", AutoCheckUpdates); + sendUserStatistics = doc.Root.GetAttributeBool("senduserstatistics", true); + + XElement graphicsMode = doc.Root.Element("graphicsmode"); + GraphicsWidth = graphicsMode.GetAttributeInt("width", GraphicsWidth); + GraphicsHeight = graphicsMode.GetAttributeInt("height", GraphicsHeight); + VSyncEnabled = graphicsMode.GetAttributeBool("vsync", VSyncEnabled); + + XElement graphicsSettings = doc.Root.Element("graphicssettings"); + ParticleLimit = graphicsSettings.GetAttributeInt("particlelimit", ParticleLimit); + LightMapScale = MathHelper.Clamp(graphicsSettings.GetAttributeFloat("lightmapscale", LightMapScale), 0.1f, 1.0f); + SpecularityEnabled = graphicsSettings.GetAttributeBool("specularity", SpecularityEnabled); + ChromaticAberrationEnabled = graphicsSettings.GetAttributeBool("chromaticaberration", ChromaticAberrationEnabled); + HUDScale = graphicsSettings.GetAttributeFloat("hudscale", HUDScale); + InventoryScale = graphicsSettings.GetAttributeFloat("inventoryscale", InventoryScale); + var losModeStr = graphicsSettings.GetAttributeString("losmode", "Transparent"); + if (!Enum.TryParse(losModeStr, out losMode)) + { + losMode = LosMode.Transparent; + } + +#if CLIENT + if (GraphicsWidth == 0 || GraphicsHeight == 0) + { + GraphicsWidth = GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Width; + GraphicsHeight = GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Height; + } +#endif + + var windowModeStr = graphicsMode.GetAttributeString("displaymode", "Fullscreen"); + if (!Enum.TryParse(windowModeStr, out windowMode)) + { + windowMode = WindowMode.Fullscreen; + } + + XElement audioSettings = doc.Root.Element("audio"); + if (audioSettings != null) + { + SoundVolume = audioSettings.GetAttributeFloat("soundvolume", SoundVolume); + MusicVolume = audioSettings.GetAttributeFloat("musicvolume", MusicVolume); + VoiceChatVolume = audioSettings.GetAttributeFloat("voicechatvolume", VoiceChatVolume); + string voiceSettingStr = audioSettings.GetAttributeString("voicesetting", "Disabled"); + VoiceCaptureDevice = audioSettings.GetAttributeString("voicecapturedevice", ""); + NoiseGateThreshold = audioSettings.GetAttributeFloat("noisegatethreshold", -45); + var voiceSetting = VoiceMode.Disabled; + if (Enum.TryParse(voiceSettingStr, out voiceSetting)) + { + VoiceSetting = voiceSetting; + } + } + + useSteamMatchmaking = doc.Root.GetAttributeBool("usesteammatchmaking", useSteamMatchmaking); + requireSteamAuthentication = doc.Root.GetAttributeBool("requiresteamauthentication", requireSteamAuthentication); + + EnableSplashScreen = doc.Root.GetAttributeBool("enablesplashscreen", EnableSplashScreen); + + AimAssistAmount = doc.Root.GetAttributeFloat("aimassistamount", AimAssistAmount); + EnableMouseLook = doc.Root.GetAttributeBool("enablemouselook", EnableMouseLook); + + foreach (XElement subElement in doc.Root.Elements()) + { + switch (subElement.Name.ToString().ToLowerInvariant()) + { + case "keymapping": + foreach (XAttribute attribute in subElement.Attributes()) + { + if (Enum.TryParse(attribute.Name.ToString(), true, out InputType inputType)) + { + if (int.TryParse(attribute.Value.ToString(), out int mouseButton)) + { + keyMapping[(int)inputType] = new KeyOrMouse(mouseButton); + } + else + { + if (Enum.TryParse(attribute.Value.ToString(), true, out Keys key)) + { + keyMapping[(int)inputType] = new KeyOrMouse(key); + } + } + } + } + break; + case "gameplay": + jobPreferences = new List(); + foreach (XElement ele in subElement.Element("jobpreferences").Elements("job")) + { + string jobIdentifier = ele.GetAttributeString("identifier", ""); + if (string.IsNullOrEmpty(jobIdentifier)) continue; + jobPreferences.Add(jobIdentifier); + } + break; + case "player": + defaultPlayerName = subElement.GetAttributeString("name", defaultPlayerName); + CharacterHeadIndex = subElement.GetAttributeInt("headindex", CharacterHeadIndex); + if (Enum.TryParse(subElement.GetAttributeString("gender", "none"), true, out Gender g)) + { + CharacterGender = g; + } + if (Enum.TryParse(subElement.GetAttributeString("race", "white"), true, out Race r)) + { + CharacterRace = r; + } + else + { + CharacterRace = Race.White; + } + CharacterHairIndex = subElement.GetAttributeInt("hairindex", CharacterHairIndex); + CharacterBeardIndex = subElement.GetAttributeInt("beardindex", CharacterBeardIndex); + CharacterMoustacheIndex = subElement.GetAttributeInt("moustacheindex", CharacterMoustacheIndex); + CharacterFaceAttachmentIndex = subElement.GetAttributeInt("faceattachmentindex", CharacterFaceAttachmentIndex); + break; + case "tutorials": + foreach (XElement tutorialElement in subElement.Elements()) + { + CompletedTutorialNames.Add(tutorialElement.GetAttributeString("name", "")); + } + break; + } + } + + foreach (InputType inputType in Enum.GetValues(typeof(InputType))) + { + if (keyMapping[(int)inputType] == null) + { + DebugConsole.ThrowError("Key binding for the input type \"" + inputType + " not set!"); + keyMapping[(int)inputType] = new KeyOrMouse(Keys.D1); + } + } + + UnsavedSettings = false; + + selectedContentPackagePaths = new HashSet(); + + foreach (XElement subElement in doc.Root.Elements()) + { + switch (subElement.Name.ToString().ToLowerInvariant()) + { + case "contentpackage": + string path = System.IO.Path.GetFullPath(subElement.GetAttributeString("path", "")); + selectedContentPackagePaths.Add(path); + break; + } + } + + LoadContentPackages(selectedContentPackagePaths); + } + + public void ReloadContentPackages() + { + LoadContentPackages(selectedContentPackagePaths); + } + + private void LoadContentPackages(IEnumerable contentPackagePaths) + { + var missingPackagePaths = new List(); + var incompatiblePackages = new List(); + SelectedContentPackages.Clear(); + foreach (string path in contentPackagePaths) + { + var matchingContentPackage = ContentPackage.List.Find(cp => System.IO.Path.GetFullPath(cp.Path) == path); + + if (matchingContentPackage == null) + { + missingPackagePaths.Add(path); + } + else if (!matchingContentPackage.IsCompatible()) + { + incompatiblePackages.Add(matchingContentPackage); + } + else + { + SelectedContentPackages.Add(matchingContentPackage); + } + } + + TextManager.LoadTextPacks(SelectedContentPackages); + + foreach (ContentPackage contentPackage in SelectedContentPackages) + { + foreach (ContentFile file in contentPackage.Files) + { + if (!System.IO.File.Exists(file.Path)) + { + DebugConsole.ThrowError("Error in content package \"" + contentPackage.Name + "\" - file \"" + file.Path + "\" not found."); + continue; + } + ToolBox.IsProperFilenameCase(file.Path); + } + } + if (!SelectedContentPackages.Any()) + { + var availablePackage = ContentPackage.List.FirstOrDefault(cp => cp.IsCompatible() && cp.CorePackage); + if (availablePackage != null) + { + SelectedContentPackages.Add(availablePackage); + } + } + + //save to get rid of the invalid selected packages in the config file + if (missingPackagePaths.Count > 0 || incompatiblePackages.Count > 0) { SaveNewPlayerConfig(); } + + //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())); + } + } + #endregion + #region Save PlayerConfig public void SaveNewPlayerConfig() { diff --git a/Barotrauma/BarotraumaShared/Source/Items/Components/Signal/LightComponent.cs b/Barotrauma/BarotraumaShared/Source/Items/Components/Signal/LightComponent.cs index eebf1146a..7845f609c 100644 --- a/Barotrauma/BarotraumaShared/Source/Items/Components/Signal/LightComponent.cs +++ b/Barotrauma/BarotraumaShared/Source/Items/Components/Signal/LightComponent.cs @@ -26,10 +26,6 @@ namespace Barotrauma.Items.Components private float blinkTimer; - private bool itemLoaded; - - private float blinkTimer; - public PhysicsBody ParentBody; [Editable(MinValueFloat = 0.0f, MaxValueFloat = 2048.0f), Serialize(100.0f, true)] diff --git a/Barotrauma/BarotraumaShared/Source/Items/Item.cs b/Barotrauma/BarotraumaShared/Source/Items/Item.cs index bd27ed5fa..04b504efe 100644 --- a/Barotrauma/BarotraumaShared/Source/Items/Item.cs +++ b/Barotrauma/BarotraumaShared/Source/Items/Item.cs @@ -1613,6 +1613,8 @@ namespace Barotrauma GameMain.NetworkMember != null && (GameMain.NetworkMember.IsServer || Character.Controlled == dropper)) { parentInventory.CreateNetworkEvent(); + //send frequent updates after the item has been dropped + PositionUpdateInterval = 0.0f; } } diff --git a/Barotrauma/BarotraumaShared/Source/Map/ItemAssemblyPrefab.cs b/Barotrauma/BarotraumaShared/Source/Map/ItemAssemblyPrefab.cs index 6dda14f5e..736acb775 100644 --- a/Barotrauma/BarotraumaShared/Source/Map/ItemAssemblyPrefab.cs +++ b/Barotrauma/BarotraumaShared/Source/Map/ItemAssemblyPrefab.cs @@ -38,6 +38,9 @@ namespace Barotrauma SerializableProperty.DeserializeProperties(this, configElement); + name = TextManager.Get("EntityName." + identifier, returnNull: true) ?? name; + Description = TextManager.Get("EntityDescription." + identifier, returnNull: true) ?? Description; + int minX = int.MaxValue, minY = int.MaxValue; int maxX = int.MinValue, maxY = int.MinValue; DisplayEntities = new List>(); diff --git a/Barotrauma/BarotraumaShared/Source/SteamAchievementManager.cs b/Barotrauma/BarotraumaShared/Source/SteamAchievementManager.cs index 04e32f2d0..8ab8db1a8 100644 --- a/Barotrauma/BarotraumaShared/Source/SteamAchievementManager.cs +++ b/Barotrauma/BarotraumaShared/Source/SteamAchievementManager.cs @@ -31,6 +31,8 @@ namespace Barotrauma public readonly HashSet ReactorMeltdown = new HashSet(); public readonly HashSet Casualties = new HashSet(); + + public bool SubWasDamaged; } private static RoundData roundData; @@ -110,7 +112,47 @@ namespace Barotrauma UnlockAchievement("subdeep", true, c => c != null && c.Submarine == sub && !c.IsDead && !c.IsUnconscious); } } - } + + if (!roundData.SubWasDamaged) + { + roundData.SubWasDamaged = SubWallsDamaged(Submarine.MainSub); + } + } + + if (GameMain.GameSession != null && Character.Controlled != null) + { + if (Character.Controlled.HasEquippedItem("clownmask") && + Character.Controlled.HasEquippedItem("clowncostume")) + { + UnlockAchievement(Character.Controlled, "clowncostume"); + } + + if (Submarine.MainSub != null && Character.Controlled.Submarine == null) + { + float dist = 500 / Physics.DisplayToRealWorldRatio; + if (Vector2.DistanceSquared(Character.Controlled.WorldPosition, Submarine.MainSub.WorldPosition) > + dist * dist) + { + UnlockAchievement(Character.Controlled, "crewaway"); + } + } + } + } + + private static bool SubWallsDamaged(Submarine sub) + { + foreach (Structure structure in Structure.WallList) + { + if (structure.Submarine != sub || structure.HasBody) { continue; } + for (int i = 0; i < structure.SectionCount; i++) + { + if (structure.SectionIsLeaking(i)) + { + return true; + } + } + } + return false; } public static void OnBiomeDiscovered(Biome biome) @@ -274,14 +316,21 @@ namespace Barotrauma //made it to the destination if (gameSession.Submarine.AtEndPosition) { + bool noDamageRun = !roundData.SubWasDamaged && !roundData.Casualties.Any(c => !(c.AIController is EnemyAIController)); + #if SERVER if (GameMain.Server != null) { //in MP all characters that were inside the sub during reactor meltdown and still alive at the end of the round get an achievement UnlockAchievement("survivereactormeltdown", true, c => c != null && !c.IsDead && roundData.ReactorMeltdown.Contains(c)); + if (noDamageRun) + { + UnlockAchievement("nodamagerun", true, c => c != null && !c.IsDead); + } } #endif #if CLIENT + if (noDamageRun) { UnlockAchievement("nodamagerun"); } if (roundData.ReactorMeltdown.Any()) //in SP getting to the destination after a meltdown is enough { UnlockAchievement("survivereactormeltdown"); @@ -302,6 +351,11 @@ namespace Barotrauma UnlockAchievement(charactersInSub[0], "lonesailor"); } } + foreach (Character character in charactersInSub) + { + if (character.Info.Job == null) { continue; } + UnlockAchievement(character, character.Info.Job.Prefab.Identifier + "round"); + } } } diff --git a/Barotrauma/BarotraumaShared/Submarines/Dugong.sub b/Barotrauma/BarotraumaShared/Submarines/Dugong.sub index 6403c9fd9..4ac57dc62 100644 Binary files a/Barotrauma/BarotraumaShared/Submarines/Dugong.sub and b/Barotrauma/BarotraumaShared/Submarines/Dugong.sub differ diff --git a/Barotrauma/BarotraumaShared/Submarines/Remora.sub b/Barotrauma/BarotraumaShared/Submarines/Remora.sub index ede107e94..54b336683 100644 Binary files a/Barotrauma/BarotraumaShared/Submarines/Remora.sub and b/Barotrauma/BarotraumaShared/Submarines/Remora.sub differ diff --git a/Barotrauma/BarotraumaShared/Submarines/Venture.sub b/Barotrauma/BarotraumaShared/Submarines/Venture.sub index 2ed054c24..188b52454 100644 Binary files a/Barotrauma/BarotraumaShared/Submarines/Venture.sub and b/Barotrauma/BarotraumaShared/Submarines/Venture.sub differ