Build 1.1.4.0
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user