Files
LuaCsForBarotraumaEP/Barotrauma/BarotraumaShared/SharedSource/GameSettings.cs
T
2020-05-13 12:55:42 -03:00

1507 lines
61 KiB
C#

using System.Linq;
using System.Xml.Linq;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Barotrauma.IO;
using Barotrauma.Extensions;
#if CLIENT
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Graphics;
using Barotrauma.Tutorials;
#endif
using System;
namespace Barotrauma
{
public enum WindowMode
{
Windowed, Fullscreen, BorderlessWindowed
}
public enum LosMode
{
None,
Transparent,
Opaque
}
public partial class GameSettings
{
public const string SavePath = "config.xml";
public const string PlayerSavePath = "config_player.xml";
public const string VanillaContentPackagePath = "Data/ContentPackages/Vanilla";
public int GraphicsWidth { get; set; }
public int GraphicsHeight { get; set; }
public bool VSyncEnabled { get; set; }
public bool TextureCompressionEnabled { get; set; }
public bool EnableSplashScreen { get; set; }
public int ParticleLimit { get; set; }
public float LightMapScale { get; set; }
public bool ChromaticAberrationEnabled { get; set; }
public bool PauseOnFocusLost { get; set; }
public bool MuteOnFocusLost { get; set; }
public bool DynamicRangeCompressionEnabled { get; set; }
public bool VoipAttenuationEnabled { get; set; }
public bool UseDirectionalVoiceChat { get; set; }
public IList<string> CaptureDeviceNames;
public enum VoiceMode
{
Disabled,
PushToTalk,
Activity
};
public VoiceMode VoiceSetting { get; set; }
public string VoiceCaptureDevice { get; set; }
public float NoiseGateThreshold { get; set; }
#if CLIENT
private KeyOrMouse[] keyMapping;
private KeyOrMouse[] inventoryKeyMapping;
#endif
private WindowMode windowMode;
private LosMode losMode;
public List<Pair<string, int>> jobPreferences;
public string QuickStartSubmarineName;
#if USE_STEAM
public bool RequireSteamAuthentication { get; set; }
public bool UseSteamMatchmaking { get; set; }
#else
public bool RequireSteamAuthentication
{
get { return false; }
set { /*do nothing*/ }
}
public bool UseSteamMatchmaking
{
get { return false; }
set { /*do nothing*/ }
}
#endif
public bool UseDualModeSockets { get; set; } = true;
public bool AutoUpdateWorkshopItems;
public WindowMode WindowMode
{
get { return windowMode; }
set
{
#if (OSX)
// Fullscreen doesn't work on macOS, so just force any usage of it to borderless windowed.
if (value == WindowMode.Fullscreen)
{
windowMode = WindowMode.BorderlessWindowed;
return;
}
#endif
windowMode = value;
}
}
public List<Pair<string, int>> JobPreferences
{
get { return jobPreferences; }
set { jobPreferences = value; }
}
public bool AreJobPreferencesEqual(List<Pair<string, int>> compareTo)
{
if (jobPreferences == null || compareTo == null) return false;
if (jobPreferences.Count != compareTo.Count) return false;
for (int i = 0; i < jobPreferences.Count; i++)
{
if (jobPreferences[i].First != compareTo[i].First || jobPreferences[i].Second != compareTo[i].Second) return false;
}
return true;
}
public int CharacterHeadIndex { get; set; }
public int CharacterHairIndex { get; set; }
public int CharacterBeardIndex { get; set; }
public int CharacterMoustacheIndex { get; set; }
public int CharacterFaceAttachmentIndex { get; set; }
public Gender CharacterGender { get; set; }
public Race CharacterRace { get; set; }
private float aimAssistAmount;
public float AimAssistAmount
{
get { return aimAssistAmount; }
set { aimAssistAmount = MathHelper.Clamp(value, 0.0f, 5.0f); }
}
public bool EnableMouseLook { get; set; } = true;
public bool CrewMenuOpen { get; set; } = true;
public bool ChatOpen { get; set; } = true;
public float CorpseDespawnDelay { get; set; } = 10.0f * 60.0f;
/// <summary>
/// How many corpses there can be in a sub before they start to get despawned
/// </summary>
public int CorpsesPerSubDespawnThreshold { get; set; } = 5;
private string overrideSaveFolder, overrideMultiplayerSaveFolder;
private bool unsavedSettings;
public bool UnsavedSettings
{
get
{
return unsavedSettings;
}
private set
{
unsavedSettings = value;
#if CLIENT
if (applyButton != null)
{
applyButton.Enabled = unsavedSettings;
applyButton.Text = TextManager.Get(unsavedSettings ? "ApplySettingsButtonUnsavedChanges" : "ApplySettingsButton");
}
#endif
}
}
private float soundVolume, musicVolume, voiceChatVolume, microphoneVolume;
public float SoundVolume
{
get { return soundVolume; }
set
{
soundVolume = MathHelper.Clamp(value, 0.0f, 1.0f);
#if CLIENT
if (GameMain.SoundManager != null)
{
GameMain.SoundManager.SetCategoryGainMultiplier("default", soundVolume, 0);
GameMain.SoundManager.SetCategoryGainMultiplier("ui", soundVolume, 0);
GameMain.SoundManager.SetCategoryGainMultiplier("waterambience", soundVolume, 0);
}
#endif
}
}
public float MusicVolume
{
get { return musicVolume; }
set
{
musicVolume = MathHelper.Clamp(value, 0.0f, 1.0f);
#if CLIENT
GameMain.SoundManager?.SetCategoryGainMultiplier("music", musicVolume * 0.7f, 0);
#endif
}
}
public float VoiceChatVolume
{
get { return voiceChatVolume; }
set
{
voiceChatVolume = MathHelper.Clamp(value, 0.0f, 2.0f);
#if CLIENT
GameMain.SoundManager?.SetCategoryGainMultiplier("voip", Math.Min(voiceChatVolume, 1.0f), 0);
#endif
}
}
public int VoiceChatCutoffPrevention
{
get;
set;
}
public const float MaxMicrophoneVolume = 10.0f;
public float MicrophoneVolume
{
get { return microphoneVolume; }
set
{
microphoneVolume = MathHelper.Clamp(value, 0.2f, MaxMicrophoneVolume);
}
}
public string Language
{
get { return TextManager.Language; }
set { TextManager.Language = value; }
}
public readonly List<ContentPackage> SelectedContentPackages = new List<ContentPackage>();
public bool ContentPackageSelectionDirtyNotification
{
get;
set;
}
public bool ContentPackageSelectionDirty
{
get;
private set;
}
public volatile bool SuppressModFolderWatcher;
#if DEBUG
public bool AutomaticQuickStartEnabled { get; set; }
public bool TextManagerDebugModeEnabled { get; set; }
#endif
private System.IO.FileSystemWatcher modsFolderWatcher;
private int ContentFileLoadOrder(ContentFile a)
{
switch (a.Type)
{
case ContentType.Text:
return -2;
case ContentType.Afflictions:
return -1;
case ContentType.ItemAssembly:
return 1;
default:
return 0;
}
}
public void SelectCorePackage(ContentPackage contentPackage, bool forceReloadAll = false)
{
ContentPackage otherCorePackage = SelectedContentPackages.Where(cp => cp.CorePackage).First();
SelectedContentPackages.Remove(otherCorePackage);
SelectedContentPackages.Add(contentPackage);
ContentPackage.SortContentPackages();
List<ContentFile> filesToRemove = otherCorePackage.Files.Where(f1 => forceReloadAll ||
!contentPackage.Files.Any(f2 =>
Path.GetFullPath(f1.Path).CleanUpPath() == Path.GetFullPath(f2.Path).CleanUpPath())).ToList();
List<ContentFile> filesToAdd = contentPackage.Files.Where(f1 => forceReloadAll ||
!otherCorePackage.Files.Any(f2 =>
Path.GetFullPath(f1.Path).CleanUpPath() == Path.GetFullPath(f2.Path).CleanUpPath())).ToList();
DisableContentPackageItems(filesToRemove.OrderBy(ContentFileLoadOrder));
EnableContentPackageItems(filesToAdd.OrderBy(ContentFileLoadOrder));
RefreshContentPackageItems(filesToAdd.Concat(filesToRemove));
}
public void SelectContentPackage(ContentPackage contentPackage)
{
if (!SelectedContentPackages.Contains(contentPackage))
{
SelectedContentPackages.Add(contentPackage);
ContentPackage.SortContentPackages();
EnableContentPackageItems(contentPackage.Files.OrderBy(ContentFileLoadOrder));
RefreshContentPackageItems(contentPackage.Files);
}
}
public void DeselectContentPackage(ContentPackage contentPackage)
{
if (SelectedContentPackages.Contains(contentPackage))
{
SelectedContentPackages.Remove(contentPackage);
ContentPackage.SortContentPackages();
DisableContentPackageItems(contentPackage.Files.OrderBy(ContentFileLoadOrder));
RefreshContentPackageItems(contentPackage.Files);
}
}
private void EnableContentPackageItems(IOrderedEnumerable<ContentFile> files)
{
foreach (ContentFile file in files)
{
switch (file.Type)
{
case ContentType.Character:
CharacterPrefab.LoadFromFile(file);
break;
case ContentType.Corpses:
CorpsePrefab.LoadFromFile(file);
break;
case ContentType.NPCConversations:
NPCConversation.LoadFromFile(file);
break;
case ContentType.Jobs:
JobPrefab.LoadFromFile(file);
break;
case ContentType.Item:
ItemPrefab.LoadFromFile(file);
break;
case ContentType.ItemAssembly:
new ItemAssemblyPrefab(file.Path);
break;
case ContentType.Structure:
StructurePrefab.LoadFromFile(file);
break;
case ContentType.Text:
TextManager.LoadTextPack(file.Path);
break;
#if CLIENT
case ContentType.Particles:
GameMain.ParticleManager?.LoadPrefabsFromFile(file);
break;
case ContentType.Decals:
GameMain.DecalManager?.LoadFromFile(file);
break;
#endif
}
UpdateContentPackageDirtyFlag(file);
}
}
private void DisableContentPackageItems(IOrderedEnumerable<ContentFile> files)
{
foreach (ContentFile file in files)
{
switch (file.Type)
{
case ContentType.Character:
CharacterPrefab.RemoveByFile(file.Path);
break;
case ContentType.Corpses:
CorpsePrefab.RemoveByFile(file.Path);
break;
case ContentType.NPCConversations:
NPCConversation.RemoveByFile(file.Path);
break;
case ContentType.Jobs:
JobPrefab.RemoveByFile(file.Path);
break;
case ContentType.Item:
ItemPrefab.RemoveByFile(file.Path);
break;
case ContentType.ItemAssembly:
ItemAssemblyPrefab.Remove(file.Path);
break;
case ContentType.Structure:
StructurePrefab.RemoveByFile(file.Path);
break;
case ContentType.Text:
TextManager.RemoveTextPack(file.Path);
break;
#if CLIENT
case ContentType.Particles:
GameMain.ParticleManager?.RemovePrefabsByFile(file.Path);
break;
case ContentType.Decals:
GameMain.DecalManager?.RemoveByFile(file.Path);
break;
#endif
}
UpdateContentPackageDirtyFlag(file);
}
}
private void RefreshContentPackageItems(IEnumerable<ContentFile> files)
{
if (files.Any(f => f.Type == ContentType.Afflictions)) { AfflictionPrefab.LoadAll(GameMain.Instance.GetFilesOfType(ContentType.Afflictions)); }
if (files.Any(f => f.Type == ContentType.Submarine)) { SubmarineInfo.RefreshSavedSubs(); }
if (files.Any(f => f.Type == ContentType.Item)) { ItemPrefab.InitFabricationRecipes(); }
if (files.Any(f => f.Type == ContentType.RuinConfig)) { RuinGeneration.RuinGenerationParams.ClearAll(); }
if (files.Any(f => f.Type == ContentType.RandomEvents)) { ScriptedEventSet.LoadPrefabs(); }
if (files.Any(f => f.Type == ContentType.Missions)) { MissionPrefab.Init(); }
if (files.Any(f => f.Type == ContentType.LevelObjectPrefabs)) { LevelObjectPrefab.LoadAll(); }
if (files.Any(f => f.Type == ContentType.LocationTypes)) { LocationType.Init(); }
if (files.Any(f => f.Type == ContentType.MapGenerationParameters)) { MapGenerationParams.Init(); }
if (files.Any(f => f.Type == ContentType.LevelGenerationParameters)) { LevelGenerationParams.LoadPresets(); }
if (files.Any(f => f.Type == ContentType.TraitorMissions)) { TraitorMissionPrefab.Init(); }
if (files.Any(f => f.Type == ContentType.Orders)) { Order.Init(); }
if (files.Any(f => f.Type == ContentType.EventManagerSettings)) { EventManagerSettings.Init(); }
if (files.Any(f => f.Type == ContentType.WreckAIConfig)) { WreckAIConfig.LoadAll(); }
if (files.Any(f => f.Type == ContentType.SkillSettings)) { SkillSettings.Load(GameMain.Instance.GetFilesOfType(ContentType.SkillSettings)); }
#if CLIENT
if (files.Any(f => f.Type == ContentType.Tutorials)) { Tutorial.Init(); }
if (files.Any(f => f.Type == ContentType.Sounds)) { SoundPlayer.Init().ForEach(_ => { return; }); }
#endif
}
private readonly static ContentType[] hotswappableContentTypes = new ContentType[]
{
ContentType.Character,
ContentType.Corpses,
ContentType.NPCConversations,
ContentType.Jobs,
ContentType.Orders,
ContentType.EventManagerSettings,
ContentType.Item,
ContentType.ItemAssembly,
ContentType.Structure,
ContentType.Submarine,
ContentType.Text,
ContentType.Afflictions,
ContentType.RuinConfig,
ContentType.RandomEvents,
ContentType.Missions,
ContentType.LevelObjectPrefabs,
ContentType.LocationTypes,
ContentType.MapGenerationParameters,
ContentType.LevelGenerationParameters,
ContentType.Sounds,
ContentType.Particles,
ContentType.Decals,
ContentType.Outpost,
ContentType.Wreck,
ContentType.WreckAIConfig,
ContentType.BackgroundCreaturePrefabs,
ContentType.ServerExecutable,
ContentType.TraitorMissions,
ContentType.Tutorials,
ContentType.SkillSettings,
ContentType.None
};
private void UpdateContentPackageDirtyFlag(ContentFile file)
{
if (!hotswappableContentTypes.Contains(file.Type))
{
if (ContentPackage.MultiplayerIncompatibleContent.Contains(file.Type))
{
ContentPackageSelectionDirty = true;
}
ContentPackageSelectionDirtyNotification = true;
}
}
public void ReorderSelectedContentPackages<T>(Func<ContentPackage, T> orderFunction)
{
ContentPackage.List = ContentPackage.List
.OrderByDescending(p => p.CorePackage)
.ThenBy(orderFunction)
.ToList();
ContentPackage.SortContentPackages();
CharacterPrefab.Prefabs.SortAll();
AfflictionPrefab.Prefabs.SortAll();
JobPrefab.Prefabs.SortAll();
ItemPrefab.Prefabs.SortAll();
CoreEntityPrefab.Prefabs.SortAll();
ItemAssemblyPrefab.Prefabs.SortAll();
StructurePrefab.Prefabs.SortAll();
SubmarineInfo.RefreshSavedSubs();
ItemPrefab.InitFabricationRecipes();
RuinGeneration.RuinGenerationParams.ClearAll();
ScriptedEventSet.LoadPrefabs();
MissionPrefab.Init();
LevelObjectPrefab.LoadAll();
LocationType.Init();
MapGenerationParams.Init();
LevelGenerationParams.LoadPresets();
TraitorMissionPrefab.Init();
Order.Init();
EventManagerSettings.Init();
WreckAIConfig.LoadAll();
SkillSettings.Load(GameMain.Instance.GetFilesOfType(ContentType.SkillSettings));
#if CLIENT
GameMain.DecalManager.Prefabs.SortAll();
GameMain.ParticleManager.Prefabs.SortAll();
SoundPlayer.Init().ForEach(_ => { return; });
#endif
}
private HashSet<string> selectedContentPackagePaths = new HashSet<string>();
public string MasterServerUrl { get; set; }
public string RemoteContentUrl { get; set; }
public bool AutoCheckUpdates { get; set; }
public bool WasGameUpdated { get; set; }
private string playerName;
public string PlayerName
{
get
{
return string.IsNullOrWhiteSpace(playerName) ? Steam.SteamManager.GetUsername() : playerName;
}
set
{
if (playerName != value)
{
playerName = value;
}
}
}
public LosMode LosMode
{
get { return losMode; }
set { losMode = value; }
}
private const float MinHUDScale = 0.75f, MaxHUDScale = 1.25f;
public static float HUDScale { get; set; }
private const float MinInventoryScale = 0.75f, MaxInventoryScale = 1.25f;
public static float InventoryScale { get; set; }
public List<string> CompletedTutorialNames { get; private set; }
public static bool VerboseLogging { get; set; }
public static bool SaveDebugConsoleLogs { get; set; }
public bool CampaignDisclaimerShown, EditorDisclaimerShown;
private static bool sendUserStatistics = true;
public static bool SendUserStatistics
{
get
{
return false;
/*#if DEBUG
return false;
#endif
return sendUserStatistics;*/
}
set
{
sendUserStatistics = value;
GameMain.Config.SaveNewPlayerConfig();
}
}
public static bool ShowUserStatisticsPrompt { get; set; }
public bool ShowLanguageSelectionPrompt { get; set; }
private bool showTutorialSkipWarning = true;
public static bool EnableSubmarineAutoSave { get; set; }
public static Color SubEditorBackgroundColor { get; set; }
public bool ShowTutorialSkipWarning
{
get { return showTutorialSkipWarning && CompletedTutorialNames.Count == 0; }
set { showTutorialSkipWarning = value; }
}
public GameSettings()
{
ContentPackage.LoadAll();
CompletedTutorialNames = new List<string>();
LoadDefaultConfig();
if (WasGameUpdated)
{
UpdaterUtil.CleanOldFiles();
WasGameUpdated = false;
SaveNewDefaultConfig();
}
LoadPlayerConfig();
modsFolderWatcher = new System.IO.FileSystemWatcher("Mods");
modsFolderWatcher.Filter = "*";
modsFolderWatcher.NotifyFilter = System.IO.NotifyFilters.LastWrite | System.IO.NotifyFilters.FileName | System.IO.NotifyFilters.DirectoryName;
modsFolderWatcher.Created += OnModFolderUpdate;
modsFolderWatcher.Deleted += OnModFolderUpdate;
modsFolderWatcher.Renamed += OnModFolderUpdate;
modsFolderWatcher.EnableRaisingEvents = true;
}
private void OnModFolderUpdate(object sender, System.IO.FileSystemEventArgs e)
{
if (SuppressModFolderWatcher || (GameMain.NetworkMember?.IsClient ?? false)) { return; }
switch (e.ChangeType)
{
case System.IO.WatcherChangeTypes.Created:
{
string cpPath = Path.GetFullPath(Path.Combine(e.FullPath, Steam.SteamManager.MetadataFileName)).CleanUpPath();
if (File.Exists(cpPath) && !ContentPackage.List.Any(cp => Path.GetFullPath(cp.Path).CleanUpPath() == cpPath))
{
var cp = new ContentPackage(cpPath);
ContentPackage.List.Add(cp);
}
}
break;
case System.IO.WatcherChangeTypes.Deleted:
{
string cpPath = Path.GetFullPath(Path.Combine(e.FullPath, Steam.SteamManager.MetadataFileName)).CleanUpPath();
var toRemove = ContentPackage.List.Where(cp => Path.GetFullPath(cp.Path).CleanUpPath() == cpPath).ToList();
var packagesToDeselect = GameMain.Config.SelectedContentPackages.Where(p => toRemove.Contains(p)).ToList();
foreach (var cp in packagesToDeselect)
{
if (cp.CorePackage)
{
GameMain.Config.SelectCorePackage(ContentPackage.List.Find(cpp => cpp.CorePackage && !toRemove.Contains(cpp)));
}
else
{
GameMain.Config.DeselectContentPackage(cp);
}
}
foreach (var cp in toRemove)
{
ContentPackage.List.Remove(cp);
}
}
break;
case System.IO.WatcherChangeTypes.Renamed:
{
System.IO.RenamedEventArgs renameArgs = e as System.IO.RenamedEventArgs;
string cpPath = Path.GetFullPath(Path.Combine(renameArgs.OldFullPath, Steam.SteamManager.MetadataFileName)).CleanUpPath();
var toRemove = ContentPackage.List.Where(cp => Path.GetFullPath(cp.Path).CleanUpPath() == cpPath).ToList();
foreach (var cp in toRemove)
{
GameMain.Config.DeselectContentPackage(cp);
ContentPackage.List.Remove(cp);
}
cpPath = Path.GetFullPath(Path.Combine(renameArgs.FullPath, Steam.SteamManager.MetadataFileName)).CleanUpPath();
if (File.Exists(cpPath) && !ContentPackage.List.Any(cp => Path.GetFullPath(cp.Path).CleanUpPath() == cpPath))
{
var cp = new ContentPackage(cpPath);
ContentPackage.List.Add(cp);
}
}
break;
}
}
private void LoadDefaultConfig(bool setLanguage = true)
{
XDocument doc = XMLExtensions.TryLoadXml(SavePath);
if (doc == null)
{
GraphicsWidth = 1024;
GraphicsHeight = 768;
MasterServerUrl = "";
SelectContentPackage(ContentPackage.List.Any() ? ContentPackage.List[0] : new ContentPackage(""));
jobPreferences = new List<Pair<string, int>>();
return;
}
bool resetLanguage = setLanguage || string.IsNullOrEmpty(Language);
SetDefaultValues(resetLanguage);
#if CLIENT
SetDefaultBindings(doc, legacy: false);
#endif
MasterServerUrl = doc.Root.GetAttributeString("masterserverurl", MasterServerUrl);
RemoteContentUrl = doc.Root.GetAttributeString("remotecontenturl", RemoteContentUrl);
WasGameUpdated = doc.Root.GetAttributeBool("wasgameupdated", WasGameUpdated);
VerboseLogging = doc.Root.GetAttributeBool("verboselogging", VerboseLogging);
SaveDebugConsoleLogs = doc.Root.GetAttributeBool("savedebugconsolelogs", SaveDebugConsoleLogs);
AutoUpdateWorkshopItems = doc.Root.GetAttributeBool("autoupdateworkshopitems", AutoUpdateWorkshopItems);
LoadGeneralSettings(doc, resetLanguage);
LoadGraphicSettings(doc);
LoadAudioSettings(doc);
#if CLIENT
LoadControls(doc);
#endif
LoadContentPackages(doc);
#if DEBUG
WindowMode = WindowMode.Windowed;
#endif
UnsavedSettings = false;
}
private void SaveNewDefaultConfig()
{
XDocument doc = new XDocument();
if (doc.Root == null)
{
doc.Add(new XElement("config"));
}
doc.Root.Add(
new XAttribute("language", TextManager.Language),
new XAttribute("masterserverurl", MasterServerUrl),
new XAttribute("remotecontenturl", RemoteContentUrl),
new XAttribute("autocheckupdates", AutoCheckUpdates),
new XAttribute("musicvolume", musicVolume),
new XAttribute("soundvolume", soundVolume),
new XAttribute("microphonevolume", microphoneVolume),
new XAttribute("voicechatvolume", voiceChatVolume),
new XAttribute("voicechatcutoffprevention", VoiceChatCutoffPrevention),
new XAttribute("verboselogging", VerboseLogging),
new XAttribute("savedebugconsolelogs", SaveDebugConsoleLogs),
new XAttribute("submarineautosave", EnableSubmarineAutoSave),
new XAttribute("subeditorbackground", XMLExtensions.ColorToString(SubEditorBackgroundColor)),
new XAttribute("enablesplashscreen", EnableSplashScreen),
new XAttribute("usesteammatchmaking", UseSteamMatchmaking),
new XAttribute("quickstartsub", QuickStartSubmarineName),
new XAttribute("requiresteamauthentication", RequireSteamAuthentication),
new XAttribute("aimassistamount", aimAssistAmount),
new XAttribute("tutorialskipwarning", ShowTutorialSkipWarning));
if (!ShowUserStatisticsPrompt)
{
doc.Root.Add(new XAttribute("senduserstatistics", sendUserStatistics));
}
if (WasGameUpdated)
{
doc.Root.Add(new XAttribute("wasgameupdated", true));
}
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("framelimit", Timing.FrameLimit),
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("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;
}
}
#if CLIENT
var keyMappingElement = new XElement("keymapping");
doc.Root.Add(keyMappingElement);
for (int i = 0; i < keyMapping.Length; i++)
{
KeyOrMouse bind = keyMapping[i];
if (bind.MouseButton == MouseButton.None)
{
keyMappingElement.Add(new XAttribute(((InputType)i).ToString(), bind.Key));
}
else
{
keyMappingElement.Add(new XAttribute(((InputType)i).ToString(), bind.MouseButton));
}
}
var inventoryKeyMappingElement = new XElement("inventorykeymapping");
doc.Root.Add(inventoryKeyMappingElement);
for (int i = 0; i < inventoryKeyMapping.Length; i++)
{
KeyOrMouse bind = inventoryKeyMapping[i];
if (bind.MouseButton == MouseButton.None)
{
inventoryKeyMappingElement.Add(new XAttribute($"slot{i}", bind.Key));
}
else
{
inventoryKeyMappingElement.Add(new XAttribute($"slot{i}", bind.MouseButton));
}
}
#endif
var gameplay = new XElement("gameplay");
var jobPreferences = new XElement("jobpreferences");
foreach (Pair<string, int> job in JobPreferences)
{
XElement jobElement = new XElement("job");
jobElement.Add(new XAttribute("identifier", job.First));
jobElement.Add(new XAttribute("variant", job.Second));
jobPreferences.Add(jobElement);
}
gameplay.Add(jobPreferences);
doc.Root.Add(gameplay);
var playerElement = new XElement("player",
new XAttribute("name", playerName ?? ""),
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);
System.Xml.XmlWriterSettings settings = new System.Xml.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);
}
}
#region Load PlayerConfig
public void LoadPlayerConfig()
{
bool fileFound = LoadPlayerConfigInternal();
#if CLIENT
CheckBindings(!fileFound);
#endif
if (!fileFound)
{
ShowLanguageSelectionPrompt = true;
ShowUserStatisticsPrompt = true;
SaveNewPlayerConfig();
}
}
// TODO: DRY
/// <summary>
/// Returns false if no player config file was found, in which case a new file is created.
/// </summary>
private bool LoadPlayerConfigInternal()
{
XDocument doc = XMLExtensions.LoadXml(PlayerSavePath);
if (doc == null || doc.Root == null)
{
ShowUserStatisticsPrompt = true;
ShowTutorialSkipWarning = true;
return false;
}
LoadGeneralSettings(doc);
LoadGraphicSettings(doc);
LoadAudioSettings(doc);
#if CLIENT
LoadControls(doc);
#endif
LoadContentPackages(doc);
//allow overriding the save paths in the config file
if (doc.Root.Attribute("overridesavefolder") != null)
{
overrideSaveFolder = SaveUtil.SaveFolder = doc.Root.GetAttributeString("overridesavefolder", "");
overrideMultiplayerSaveFolder = SaveUtil.MultiplayerSaveFolder = Path.Combine(overrideSaveFolder, "Multiplayer");
}
if (doc.Root.Attribute("overridemultiplayersavefolder") != null)
{
overrideMultiplayerSaveFolder = SaveUtil.MultiplayerSaveFolder = doc.Root.GetAttributeString("overridemultiplayersavefolder", "");
}
XElement tutorialsElement = doc.Root.Element("tutorials");
if (tutorialsElement != null)
{
foreach (XElement element in tutorialsElement.Elements())
{
CompletedTutorialNames.Add(element.GetAttributeString("name", ""));
}
}
UnsavedSettings = false;
return true;
}
public void ReloadContentPackages()
{
LoadContentPackages(selectedContentPackagePaths);
}
private void LoadContentPackages(IEnumerable<string> contentPackagePaths)
{
var missingPackagePaths = new List<string>();
var incompatiblePackages = new List<ContentPackage>();
var packagesWithErrors = new List<ContentPackage>();
SelectedContentPackages.Clear();
foreach (string path in contentPackagePaths)
{
var matchingContentPackage = ContentPackage.List.Find(cp => Barotrauma.IO.Path.GetFullPath(cp.Path).CleanUpPath() == path.CleanUpPath());
if (matchingContentPackage == null)
{
missingPackagePaths.Add(path);
}
else if (!matchingContentPackage.IsCompatible())
{
DebugConsole.NewMessage(
$"Content package \"{matchingContentPackage.Name}\" is not compatible with this version of Barotrauma (game version: {GameMain.Version}, content package version: {matchingContentPackage.GameVersion})",
Color.Red);
incompatiblePackages.Add(matchingContentPackage);
}
else
{
if (!matchingContentPackage.CheckErrors(out List<string> errorMessages))
{
DebugConsole.NewMessage(
$"Errors found in content package \"{matchingContentPackage.Name}\": " + string.Join(", ", errorMessages),
Color.Red);
packagesWithErrors.Add(matchingContentPackage);
}
//add content packages with errors as they are generally able to load most of their assets
SelectedContentPackages.Add(matchingContentPackage);
}
}
EnsureCoreContentPackageSelected(gameLoaded: false);
ContentPackage.SortContentPackages();
TextManager.LoadTextPacks(SelectedContentPackages);
foreach (ContentPackage contentPackage in SelectedContentPackages)
{
foreach (ContentFile file in contentPackage.Files)
{
ToolBox.IsProperFilenameCase(file.Path);
}
}
//save to get rid of the invalid selected packages in the config file
if (missingPackagePaths.Count > 0 || incompatiblePackages.Count > 0 || packagesWithErrors.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.GetWithVariable("ContentPackageNotFound", "[packagepath]", missingPackagePath));
}
foreach (ContentPackage invalidPackage in packagesWithErrors)
{
DebugConsole.ThrowError(TextManager.GetWithVariable("ContentPackageHasErrors", "[packagename]", invalidPackage.Name), createMessageBox: true);
}
foreach (ContentPackage incompatiblePackage in incompatiblePackages)
{
DebugConsole.ThrowError(TextManager.GetWithVariables(incompatiblePackage.GameVersion <= new Version(0, 0, 0, 0) ? "IncompatibleContentPackageUnknownVersion" : "IncompatibleContentPackage",
new string[3] { "[packagename]", "[packageversion]", "[gameversion]" }, new string[3] { incompatiblePackage.Name, incompatiblePackage.GameVersion.ToString(), GameMain.Version.ToString() }),
createMessageBox: true);
}
}
public void EnsureCoreContentPackageSelected(bool gameLoaded=true)
{
if (SelectedContentPackages.Any(cp => cp.CorePackage)) { return; }
if (GameMain.VanillaContent != null)
{
if (gameLoaded)
{
SelectContentPackage(GameMain.VanillaContent);
}
else
{
SelectedContentPackages.Add(GameMain.VanillaContent);
}
}
else
{
var availablePackage = ContentPackage.List.FirstOrDefault(cp => cp.IsCompatible() && cp.CorePackage);
if (availablePackage != null)
{
if (gameLoaded)
{
SelectContentPackage(availablePackage);
}
else
{
SelectedContentPackages.Add(availablePackage);
}
}
}
}
#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("submarineautosave", EnableSubmarineAutoSave),
new XAttribute("subeditorbackground", XMLExtensions.ColorToString(SubEditorBackgroundColor)),
new XAttribute("enablesplashscreen", EnableSplashScreen),
new XAttribute("usesteammatchmaking", UseSteamMatchmaking),
new XAttribute("quickstartsub", QuickStartSubmarineName),
new XAttribute("requiresteamauthentication", RequireSteamAuthentication),
new XAttribute("autoupdateworkshopitems", AutoUpdateWorkshopItems),
new XAttribute("pauseonfocuslost", PauseOnFocusLost),
new XAttribute("aimassistamount", aimAssistAmount),
new XAttribute("enablemouselook", EnableMouseLook),
new XAttribute("chatopen", ChatOpen),
new XAttribute("crewmenuopen", CrewMenuOpen),
new XAttribute("campaigndisclaimershown", CampaignDisclaimerShown),
new XAttribute("editordisclaimershown", EditorDisclaimerShown),
new XAttribute("tutorialskipwarning", ShowTutorialSkipWarning),
new XAttribute("corpsedespawndelay", CorpseDespawnDelay),
new XAttribute("corpsespersubdespawnthreshold", CorpsesPerSubDespawnThreshold),
new XAttribute("usedualmodesockets", UseDualModeSockets)
#if DEBUG
, new XAttribute("automaticquickstartenabled", AutomaticQuickStartEnabled)
, new XAttribute("textmanagerdebugmodeenabled", TextManagerDebugModeEnabled)
#endif
);
if (!string.IsNullOrEmpty(overrideSaveFolder))
{
doc.Root.Add(new XAttribute("overridesavefolder", overrideSaveFolder));
}
if (!string.IsNullOrEmpty(overrideMultiplayerSaveFolder))
{
doc.Root.Add(new XAttribute("overridemultiplayersavefolder", overrideMultiplayerSaveFolder));
}
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("compresstextures", TextureCompressionEnabled),
new XAttribute("framelimit", Timing.FrameLimit),
new XAttribute("displaymode", windowMode));
}
XElement audio = doc.Root.Element("audio");
if (audio == null)
{
audio = new XElement("audio");
doc.Root.Add(audio);
}
audio.ReplaceAttributes(
new XAttribute("musicvolume", musicVolume),
new XAttribute("soundvolume", soundVolume),
new XAttribute("voicechatvolume", voiceChatVolume),
new XAttribute("voicechatcutoffprevention", VoiceChatCutoffPrevention),
new XAttribute("microphonevolume", microphoneVolume),
new XAttribute("muteonfocuslost", MuteOnFocusLost),
new XAttribute("dynamicrangecompressionenabled", DynamicRangeCompressionEnabled),
new XAttribute("voipattenuationenabled", VoipAttenuationEnabled),
new XAttribute("usedirectionalvoicechat", UseDirectionalVoiceChat),
new XAttribute("voicesetting", VoiceSetting),
new XAttribute("voicecapturedevice", System.Xml.XmlConvert.EncodeName(VoiceCaptureDevice ?? "")),
new XAttribute("noisegatethreshold", NoiseGateThreshold));
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("chromaticaberration", ChromaticAberrationEnabled),
new XAttribute("losmode", LosMode),
new XAttribute("hudscale", HUDScale),
new XAttribute("inventoryscale", InventoryScale));
foreach (ContentPackage contentPackage in SelectedContentPackages)
{
doc.Root.Add(new XElement("contentpackage",
new XAttribute("path", contentPackage.Path)));
}
#if CLIENT
var keyMappingElement = new XElement("keymapping");
doc.Root.Add(keyMappingElement);
for (int i = 0; i < keyMapping.Length; i++)
{
var key = keyMapping[i];
if (key == null) { continue; }
if (key.MouseButton == MouseButton.None)
{
keyMappingElement.Add(new XAttribute(((InputType)i).ToString(), keyMapping[i].Key));
}
else
{
keyMappingElement.Add(new XAttribute(((InputType)i).ToString(), keyMapping[i].MouseButton));
}
}
var inventoryKeyMappingElement = new XElement("inventorykeymapping");
doc.Root.Add(inventoryKeyMappingElement);
for (int i = 0; i < inventoryKeyMapping.Length; i++)
{
KeyOrMouse bind = inventoryKeyMapping[i];
if (bind.MouseButton == MouseButton.None)
{
inventoryKeyMappingElement.Add(new XAttribute($"slot{i}", bind.Key));
}
else
{
inventoryKeyMappingElement.Add(new XAttribute($"slot{i}", bind.MouseButton));
}
}
#endif
var gameplay = new XElement("gameplay");
var jobPreferences = new XElement("jobpreferences");
foreach (Pair<string, int> job in JobPreferences)
{
XElement jobElement = new XElement("job");
jobElement.Add(new XAttribute("identifier", job.First));
jobElement.Add(new XAttribute("variant", job.Second));
jobPreferences.Add(jobElement);
}
gameplay.Add(jobPreferences);
doc.Root.Add(gameplay);
var playerElement = new XElement("player",
new XAttribute("name", playerName ?? ""),
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);
#if CLIENT
if (Tutorial.Tutorials != null)
{
foreach (Tutorial tutorial in Tutorial.Tutorials)
{
if (tutorial.Completed && !CompletedTutorialNames.Contains(tutorial.Identifier))
{
CompletedTutorialNames.Add(tutorial.Identifier);
}
}
}
#endif
var tutorialElement = new XElement("tutorials");
foreach (string tutorialName in CompletedTutorialNames)
{
tutorialElement.Add(new XElement("Tutorial", new XAttribute("name", tutorialName)));
}
doc.Root.Add(tutorialElement);
System.Xml.XmlWriterSettings settings = new System.Xml.XmlWriterSettings
{
Indent = true,
OmitXmlDeclaration = true,
NewLineOnAttributes = true
};
try
{
using (var writer = XmlWriter.Create(PlayerSavePath, 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 Loading Configs
private void LoadGeneralSettings(XDocument doc, bool setLanguage = true)
{
if (setLanguage)
{
Language = doc.Root.GetAttributeString("language", Language);
}
AutoCheckUpdates = doc.Root.GetAttributeBool("autocheckupdates", AutoCheckUpdates);
sendUserStatistics = doc.Root.GetAttributeBool("senduserstatistics", sendUserStatistics);
QuickStartSubmarineName = doc.Root.GetAttributeString("quickstartsub", QuickStartSubmarineName);
EnableSubmarineAutoSave = doc.Root.GetAttributeBool("submarineautosave", true);
SubEditorBackgroundColor = doc.Root.GetAttributeColor("subeditorbackground", new Color(0.051f, 0.149f, 0.271f, 1.0f));
UseSteamMatchmaking = doc.Root.GetAttributeBool("usesteammatchmaking", UseSteamMatchmaking);
RequireSteamAuthentication = doc.Root.GetAttributeBool("requiresteamauthentication", RequireSteamAuthentication);
EnableSplashScreen = doc.Root.GetAttributeBool("enablesplashscreen", EnableSplashScreen);
PauseOnFocusLost = doc.Root.GetAttributeBool("pauseonfocuslost", PauseOnFocusLost);
AimAssistAmount = doc.Root.GetAttributeFloat("aimassistamount", AimAssistAmount);
EnableMouseLook = doc.Root.GetAttributeBool("enablemouselook", EnableMouseLook);
CrewMenuOpen = doc.Root.GetAttributeBool("crewmenuopen", CrewMenuOpen);
ChatOpen = doc.Root.GetAttributeBool("chatopen", ChatOpen);
CorpseDespawnDelay = doc.Root.GetAttributeInt("corpsedespawndelay", 10 * 60);
CorpsesPerSubDespawnThreshold = doc.Root.GetAttributeInt("corpsespersubdespawnthreshold", 5);
CampaignDisclaimerShown = doc.Root.GetAttributeBool("campaigndisclaimershown", CampaignDisclaimerShown);
EditorDisclaimerShown = doc.Root.GetAttributeBool("editordisclaimershown", EditorDisclaimerShown);
ShowTutorialSkipWarning = doc.Root.GetAttributeBool("tutorialskipwarning", true);
UseDualModeSockets = doc.Root.GetAttributeBool("usedualmodesockets", true);
#if DEBUG
AutomaticQuickStartEnabled = doc.Root.GetAttributeBool("automaticquickstartenabled", AutomaticQuickStartEnabled);
TextManagerDebugModeEnabled = doc.Root.GetAttributeBool("textmanagerdebugmodeenabled", TextManagerDebugModeEnabled);
#endif
XElement gameplayElement = doc.Root.Element("gameplay");
jobPreferences = new List<Pair<string, int>>();
if (gameplayElement != null)
{
var preferencesElement = gameplayElement.Element("jobpreferences");
if (preferencesElement != null)
{
foreach (XElement ele in preferencesElement.Elements("job"))
{
string jobIdentifier = ele.GetAttributeString("identifier", "");
int outfitVariant = ele.GetAttributeInt("variant", 1);
if (string.IsNullOrEmpty(jobIdentifier)) continue;
jobPreferences.Add(new Pair<string, int>(jobIdentifier, outfitVariant));
}
}
}
XElement playerElement = doc.Root.Element("player");
if (playerElement != null)
{
playerName = playerElement.GetAttributeString("name", playerName);
CharacterHeadIndex = playerElement.GetAttributeInt("headindex", CharacterHeadIndex);
if (Enum.TryParse(playerElement.GetAttributeString("gender", "none"), true, out Gender g))
{
CharacterGender = g;
}
if (Enum.TryParse(playerElement.GetAttributeString("race", "white"), true, out Race r))
{
CharacterRace = r;
}
else
{
CharacterRace = Race.White;
}
CharacterHairIndex = playerElement.GetAttributeInt("hairindex", CharacterHairIndex);
CharacterBeardIndex = playerElement.GetAttributeInt("beardindex", CharacterBeardIndex);
CharacterMoustacheIndex = playerElement.GetAttributeInt("moustacheindex", CharacterMoustacheIndex);
CharacterFaceAttachmentIndex = playerElement.GetAttributeInt("faceattachmentindex", CharacterFaceAttachmentIndex);
}
}
private void LoadGraphicSettings(XDocument doc)
{
XElement graphicsMode = doc.Root.Element("graphicsmode");
GraphicsWidth = graphicsMode.GetAttributeInt("width", GraphicsWidth);
GraphicsHeight = graphicsMode.GetAttributeInt("height", GraphicsHeight);
VSyncEnabled = graphicsMode.GetAttributeBool("vsync", VSyncEnabled);
TextureCompressionEnabled = graphicsMode.GetAttributeBool("compresstextures", TextureCompressionEnabled);
Timing.FrameLimit = graphicsMode.GetAttributeInt("framelimit", 200);
XElement graphicsSettings = doc.Root.Element("graphicssettings");
ParticleLimit = graphicsSettings.GetAttributeInt("particlelimit", ParticleLimit);
LightMapScale = MathHelper.Clamp(graphicsSettings.GetAttributeFloat("lightmapscale", LightMapScale), 0.1f, 1.0f);
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;
}
}
private void LoadAudioSettings(XDocument doc)
{
XElement audioSettings = doc.Root.Element("audio");
if (audioSettings != null)
{
SoundVolume = audioSettings.GetAttributeFloat("soundvolume", SoundVolume);
MusicVolume = audioSettings.GetAttributeFloat("musicvolume", MusicVolume);
DynamicRangeCompressionEnabled = audioSettings.GetAttributeBool("dynamicrangecompressionenabled", DynamicRangeCompressionEnabled);
VoipAttenuationEnabled = audioSettings.GetAttributeBool("voipattenuationenabled", VoipAttenuationEnabled);
VoiceChatVolume = audioSettings.GetAttributeFloat("voicechatvolume", VoiceChatVolume);
VoiceChatCutoffPrevention = audioSettings.GetAttributeInt("voicechatcutoffprevention", VoiceChatCutoffPrevention);
MuteOnFocusLost = audioSettings.GetAttributeBool("muteonfocuslost", MuteOnFocusLost);
UseDirectionalVoiceChat = audioSettings.GetAttributeBool("usedirectionalvoicechat", UseDirectionalVoiceChat);
VoiceCaptureDevice = System.Xml.XmlConvert.DecodeName(audioSettings.GetAttributeString("voicecapturedevice", VoiceCaptureDevice));
NoiseGateThreshold = audioSettings.GetAttributeFloat("noisegatethreshold", NoiseGateThreshold);
MicrophoneVolume = audioSettings.GetAttributeFloat("microphonevolume", MicrophoneVolume);
string voiceSettingStr = audioSettings.GetAttributeString("voicesetting", "");
if (Enum.TryParse(voiceSettingStr, out VoiceMode voiceSetting))
{
VoiceSetting = voiceSetting;
}
}
}
private void LoadContentPackages(XDocument doc)
{
selectedContentPackagePaths = new HashSet<string>();
foreach (XElement subElement in doc.Root.Elements())
{
switch (subElement.Name.ToString().ToLowerInvariant())
{
case "contentpackage":
string path = Path.GetFullPath(subElement.GetAttributeString("path", ""));
selectedContentPackagePaths.Add(path);
break;
}
}
LoadContentPackages(selectedContentPackagePaths);
}
#endregion
public void ResetToDefault()
{
LoadDefaultConfig();
#if CLIENT
CheckBindings(true);
#endif
SaveNewPlayerConfig();
}
private void SetDefaultValues(bool resetLanguage = true)
{
GraphicsWidth = 0;
GraphicsHeight = 0;
VSyncEnabled = true;
TextureCompressionEnabled = true;
Timing.FrameLimit = 200;
#if DEBUG
EnableSplashScreen = false;
#else
EnableSplashScreen = true;
#endif
ParticleLimit = 1500;
LightMapScale = 0.5f;
ChromaticAberrationEnabled = true;
PauseOnFocusLost = true;
MuteOnFocusLost = false;
UseDirectionalVoiceChat = true;
VoiceSetting = VoiceMode.Disabled;
VoiceCaptureDevice = null;
NoiseGateThreshold = -45;
windowMode = WindowMode.BorderlessWindowed;
losMode = LosMode.Transparent;
UseSteamMatchmaking = true;
RequireSteamAuthentication = true;
QuickStartSubmarineName = string.Empty;
CharacterHeadIndex = 1;
CharacterHairIndex = -1;
CharacterBeardIndex = -1;
CharacterMoustacheIndex = -1;
CharacterFaceAttachmentIndex = -1;
CharacterGender = Gender.None;
CharacterRace = Race.White;
aimAssistAmount = 0.5f;
EnableMouseLook = true;
CrewMenuOpen = true;
ChatOpen = true;
soundVolume = 0.5f;
musicVolume = 0.3f;
DynamicRangeCompressionEnabled = true;
VoipAttenuationEnabled = true;
voiceChatVolume = 0.5f;
microphoneVolume = 5.0f;
AutoCheckUpdates = true;
playerName = string.Empty;
HUDScale = 1;
InventoryScale = 1;
AutoUpdateWorkshopItems = true;
CampaignDisclaimerShown = false;
CorpseDespawnDelay = 10 * 60;
CorpsesPerSubDespawnThreshold = 5;
if (resetLanguage)
{
Language = "English";
}
MasterServerUrl = "http://www.undertowgames.com/baromaster";
WasGameUpdated = false;
VerboseLogging = false;
SaveDebugConsoleLogs = false;
AutoUpdateWorkshopItems = true;
}
}
}