diff --git a/Barotrauma/BarotraumaClient/Source/GameSettings.cs b/Barotrauma/BarotraumaClient/Source/GameSettings.cs index b3d977283..0d6bf5671 100644 --- a/Barotrauma/BarotraumaClient/Source/GameSettings.cs +++ b/Barotrauma/BarotraumaClient/Source/GameSettings.cs @@ -683,6 +683,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 0a0491d5c..addf8c522 100644 --- a/Barotrauma/BarotraumaClient/Source/Items/Components/Machines/Fabricator.cs +++ b/Barotrauma/BarotraumaClient/Source/Items/Components/Machines/Fabricator.cs @@ -391,6 +391,9 @@ namespace Barotrauma.Items.Components return true; } + return true; + } + public override void UpdateHUD(Character character, float deltaTime, Camera cam) { activateButton.Enabled = false; diff --git a/Barotrauma/BarotraumaShared/Source/GameSettings.cs b/Barotrauma/BarotraumaShared/Source/GameSettings.cs index ae821f72d..4cba09ae3 100644 --- a/Barotrauma/BarotraumaShared/Source/GameSettings.cs +++ b/Barotrauma/BarotraumaShared/Source/GameSettings.cs @@ -406,6 +406,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); @@ -908,6 +913,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)]