Build 1.1.4.0

This commit is contained in:
Markus Isberg
2023-03-31 18:40:44 +03:00
parent efba17e0ff
commit 9470edead3
483 changed files with 17487 additions and 8548 deletions
@@ -1,13 +1,134 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Xml.Linq;
using System.Linq;
using Barotrauma.IO;
using XmlWriterSettings = System.Xml.XmlWriterSettings;
#nullable enable
namespace Barotrauma
{
public class CreatureMetrics
public static class CreatureMetrics
{
public readonly HashSet<Identifier> RecentlyEncountered = new HashSet<Identifier>();
public readonly HashSet<Identifier> Encountered = new HashSet<Identifier>();
public readonly HashSet<Identifier> Killed = new HashSet<Identifier>();
private const string path = "creature_metrics.xml";
public readonly static CreatureMetrics Instance = new CreatureMetrics();
/// <summary>
/// Resets every round.
/// </summary>
public static HashSet<Identifier> RecentlyEncountered { get; private set; } = new HashSet<Identifier>();
public static HashSet<Identifier> Encountered { get; private set; } = new HashSet<Identifier>();
public static HashSet<Identifier> Unlocked { get; private set; } = new HashSet<Identifier>();
public static HashSet<Identifier> Killed { get; private set; } = new HashSet<Identifier>();
public static bool IsInitialized { get; private set; }
public static bool UnlockAll { get; set; }
public static void Init()
{
IsInitialized = true;
if (File.Exists(path))
{
Load();
}
Save();
}
private static void Load()
{
XDocument doc = XMLExtensions.TryLoadXml(path);
XElement? root = doc?.Root;
if (root == null)
{
DebugConsole.AddWarning($"Failed to load creature metrics from {path}!");
return;
}
UnlockAll = root.GetAttributeBool(nameof(UnlockAll), UnlockAll);
Unlocked = new HashSet<Identifier>(root.GetAttributeIdentifierArray(nameof(Unlocked), Array.Empty<Identifier>()));
Encountered = new HashSet<Identifier>(root.GetAttributeIdentifierArray(nameof(Encountered), Array.Empty<Identifier>()));
Killed = new HashSet<Identifier>(root.GetAttributeIdentifierArray(nameof(Killed), Array.Empty<Identifier>()));
SyncSets();
}
public static void Save()
{
if (!IsInitialized)
{
throw new Exception("Creature Metrics not yet initialized!");
}
SyncSets();
XDocument configDoc = new XDocument();
XElement root = new XElement("CreatureMetrics");
configDoc.Add(root);
root.SetAttributeValue(nameof(UnlockAll), UnlockAll);
root.SetAttributeValue(nameof(Unlocked), string.Join(",", Unlocked).Trim().ToLowerInvariant());
root.SetAttributeValue(nameof(Encountered), string.Join(",", Encountered).Trim().ToLowerInvariant());
root.SetAttributeValue(nameof(Killed), string.Join(",", Killed).Trim().ToLowerInvariant());
configDoc.SaveSafe(path);
XmlWriterSettings settings = new XmlWriterSettings
{
Indent = true,
OmitXmlDeclaration = true,
NewLineOnAttributes = true
};
try
{
using var writer = XmlWriter.Create(path, settings);
configDoc.WriteTo(writer);
writer.Flush();
}
catch (Exception e)
{
DebugConsole.ThrowError("Saving creature metrics failed.", e);
GameAnalyticsManager.AddErrorEventOnce("CreatureMetrics.Save:SaveFailed", GameAnalyticsManager.ErrorSeverity.Error,
"Saving creature metrics failed.\n" + e.Message + "\n" + e.StackTrace.CleanupStackTrace());
}
}
public static void RecordKill(Identifier species)
{
AddEncounter(species);
if (!Killed.Contains(species))
{
Killed.Add(species);
}
}
public static void AddEncounter(Identifier species)
{
if (species == CharacterPrefab.HumanSpeciesName) { return; }
if (Encountered.Contains(species)) { return; }
Encountered.Add(species);
RecentlyEncountered.Add(species);
UnlockInEditor(species);
}
private static IEnumerable<CharacterFile>? vanillaCharacters;
public static void UnlockInEditor(Identifier species)
{
if (species == CharacterPrefab.HumanSpeciesName) { return; }
if (Unlocked.Contains(species)) { return; }
vanillaCharacters ??= GameMain.VanillaContent.GetFiles<CharacterFile>();
var contentFile = CharacterPrefab.FindBySpeciesName(species);
if (contentFile == null) { return; }
if (!vanillaCharacters.Contains(contentFile.ContentFile))
{
// Don't try to unlock custom characters. They are always unlocked.
return;
}
Unlocked.Add(species);
}
private static void SyncSets()
{
// Ensure that all killed are also encountered and both unlocked.
// Otherwise we could permanently hide some creatures by manually adding them to the encountered or by removing from unlocked in the xml file.
foreach (var species in Killed)
{
Encountered.Add(species);
}
foreach (var species in Encountered)
{
Unlocked.Add(species);
}
}
}
}
@@ -25,7 +25,8 @@ namespace Barotrauma
{
None = 0,
Transparent = 1,
Opaque = 2
Opaque = 2,
BlockOutsideView = 3
}
public enum VoiceMode
@@ -110,6 +111,7 @@ namespace Barotrauma
#if CLIENT
retVal.KeyMap = new KeyMapping(element.GetChildElements("keymapping"), retVal.KeyMap);
retVal.InventoryKeyMap = new InventoryKeyMapping(element.GetChildElements("inventorykeymapping"), retVal.InventoryKeyMap);
retVal.SavedCampaignSettings = element.GetChildElement("campaignsettings");
LoadSubEditorImages(element);
#endif
@@ -139,6 +141,9 @@ namespace Barotrauma
public bool DisableInGameHints;
public bool EnableSubmarineAutoSave;
public Identifier QuickStartSub;
#if CLIENT
public XElement SavedCampaignSettings;
#endif
#if DEBUG
public bool UseSteamMatchmaking;
public bool RequireSteamAuthentication;
@@ -230,7 +235,7 @@ namespace Barotrauma
SoundVolume = 0.5f,
UiVolume = 0.3f,
VoiceChatVolume = 0.5f,
VoiceChatCutoffPrevention = 0,
VoiceChatCutoffPrevention = 200,
MicrophoneVolume = 5,
MuteOnFocusLost = false,
DynamicRangeCompressionEnabled = true,
@@ -618,6 +623,8 @@ namespace Barotrauma
root.Add(inventoryKeyMappingElement);
SubEditorScreen.ImageManager.Save(root);
root.Add(CampaignSettings.CurrentSettings.Save());
#endif
configDoc.SaveSafe(PlayerConfigPath);
@@ -0,0 +1,63 @@
using System;
using System.Collections.Immutable;
using System.Linq;
using System.Xml.Linq;
namespace Barotrauma;
static class ServerLanguageOptions
{
public readonly record struct LanguageOption(
string Label,
LanguageIdentifier Identifier,
ImmutableArray<LanguageIdentifier> MapsFrom)
{
public static LanguageOption FromXElement(XElement element)
=> new LanguageOption(
Label:
element.GetAttributeString("label", ""),
Identifier:
element.GetAttributeIdentifier("identifier", LanguageIdentifier.None.Value)
.ToLanguageIdentifier(),
MapsFrom:
element.GetAttributeIdentifierArray("mapsFrom", Array.Empty<Identifier>())
.Select(id => id.ToLanguageIdentifier()).ToImmutableArray());
}
public static readonly ImmutableArray<LanguageOption> Options;
static ServerLanguageOptions()
{
var languageOptionElements
= XMLExtensions.TryLoadXml("Data/languageoptions.xml")?.Root?.Elements()
?? Enumerable.Empty<XElement>();
Options = languageOptionElements
// Convert the XElements into LanguageOptions immediately since they can be worked with more directly
.Select(LanguageOption.FromXElement)
// Remove options with duplicate identifiers
.DistinctBy(p => p.Identifier)
// Remove options where the label is empty or the identifier is missing
.Where(p => !p.Label.IsNullOrWhiteSpace() && p.Identifier != LanguageIdentifier.None)
// Sort the options based on the lexicographical order of the labels
.OrderBy(p => p.Label)
.ToImmutableArray();
}
public static LanguageIdentifier PickLanguage(LanguageIdentifier id)
{
if (id == LanguageIdentifier.None)
{
id = GameSettings.CurrentConfig.Language;
}
foreach (var (_, identifier, mapsFrom) in Options)
{
if (id == identifier || mapsFrom.Contains(id))
{
return identifier;
}
}
return TextManager.DefaultLanguage;
}
}