IT BUILDS!!!

- Removed LocalizationServices and other sus things.
- Rewrote AssemblyLoader
[In Progress] SafeStorageService
[In Progress] LuaScriptLoader
This commit is contained in:
MapleWheels
2025-03-30 06:20:45 -04:00
committed by Maplewheels
parent 52d920d969
commit c6713f37bb
67 changed files with 3336 additions and 1283 deletions
@@ -0,0 +1,142 @@
using System;
using System.Collections.Generic;
using Barotrauma.LuaCs.Data;
namespace Barotrauma.LuaCs.Configuration;
/// <summary>
/// Base type of all menu displayable types.
/// </summary>
public interface IDisplayableConfigBase : IDataInfo, IConfigDisplayInfo
{
/// <summary>
/// Whether the current config is editable.
/// </summary>
bool IsEditable { get; }
/// <summary>
/// Used to indicate the implemented interface and targeted display logic.
/// </summary>
static virtual DisplayType DisplayOption => DisplayType.Undefined;
}
public interface IDisplayableConfigBase<out TDisplay, in TValue> : IDisplayableConfigBase
{
void SetValue(TValue value);
TDisplay GetDisplayValue();
}
public interface IDisplayableConfigBool : IDisplayableConfigBase<bool, bool>
{
static DisplayType IDisplayableConfigBase.DisplayOption => DisplayType.Boolean;
}
public interface IDisplayableConfigText : IDisplayableConfigBase<string, string>
{
static DisplayType IDisplayableConfigBase.DisplayOption => DisplayType.Text;
}
public interface IDisplayableConfigInt : IDisplayableConfigBase<int, int>
{
static DisplayType IDisplayableConfigBase.DisplayOption => DisplayType.Integer;
}
public interface IDisplayableConfigFloat : IDisplayableConfigBase<float, float>
{
static DisplayType IDisplayableConfigBase.DisplayOption => DisplayType.Float;
}
public interface IDisplayableConfigSliderInt : IDisplayableConfigBase<(int Min, int Max, int Value, int Steps), int>
{
static DisplayType IDisplayableConfigBase.DisplayOption => DisplayType.SliderInt;
}
public interface IDisplayableConfigSliderFloat : IDisplayableConfigBase<(float Min, float Max, float Value, int Steps), float>
{
static DisplayType IDisplayableConfigBase.DisplayOption => DisplayType.SliderFloat;
}
public interface IDisplayableConfigDropdown : IDisplayableConfigBase<List<string>, string>
{
static DisplayType IDisplayableConfigBase.DisplayOption => DisplayType.Dropdown;
}
/// <summary>
/// Allows completely custom-designed UI for this configuration component.
/// </summary>
public interface IDisplayableConfigCustom : IDisplayableConfigBase
{
static DisplayType IDisplayableConfigBase.DisplayOption => DisplayType.Custom;
/// <summary>
/// Draw your menu settings option.
/// </summary>
/// <param name="layoutGroup">Parent layout component.</param>
void DrawComponent(GUILayoutGroup layoutGroup);
/// <summary>
/// Called when the config element is set to be disposed to allow for cleanup.
/// </summary>
void DisposeGUI();
/// <summary>
/// Called when the UI indicates to save the current value as permanent.
/// </summary>
void OnValueSaved();
/// <summary>
/// Called when the UI indicates to discard the currently displayed value and revert to the last saved value.
/// </summary>
void OnValueDiscarded();
}
/// <summary>
/// Indicates the intended display and feedback logic to be used by the <see cref="SettingsMenu"/>.
/// <br/><b>[Important]</b>
/// <br/>The type must implement the indicated interface for the selected option, or it will not be displayed.
/// </summary>
public enum DisplayType
{
/// <summary>
/// Will not be displayed in menus.
/// </summary>
Undefined,
/// <summary>
/// Will be shown as a checkbox.
/// <br/><b>[Requires(<see cref="IDisplayableConfigBool"/>)]</b>
/// </summary>
Boolean,
/// <summary>
/// Shown as an editable text input.
/// <br/><b>[Requires(<see cref="IDisplayableConfigText"/>)]</b>
/// </summary>
Text,
/// <summary>
/// Shown as number input (no decimal input).
/// <br/><b>[Requires(<see cref="IDisplayableConfigInt"/>)]</b>
/// </summary>
Integer,
/// <summary>
/// Shown as a number input.
/// <br/><b>[Requires(<see cref="IDisplayableConfigFloat"/>)]</b>
/// </summary>
Float,
/// <summary>
/// Shown as a slider, values parsed as integers.
/// <br/><b>[Requires(<see cref="IDisplayableConfigSliderInt"/>)]</b>
/// </summary>
SliderInt,
/// <summary>
/// Shown as a slider, values parsed as single-precision decimal numbers.
/// <br/><b>[Requires(<see cref="IDisplayableConfigSliderFloat"/>)]</b>
/// </summary>
SliderFloat,
/// <summary>
/// Shown as a <see cref="GUIDropDown"/> menu, values parsed as strings.
/// <br/><b>[Requires(<see cref="IDisplayableConfigDropdown"/>)]</b>
/// </summary>
Dropdown,
/// <summary>
/// UI Display is implemented by inheritor and actioned by a call to <see cref="IDisplayableConfigCustom.DrawComponent"/>.
/// <br/><b>[Requires(<see cref="IDisplayableConfigCustom"/>)]</b>
/// </summary>
Custom
}
@@ -1,23 +0,0 @@
using System.Collections.Immutable;
using System.Globalization;
namespace Barotrauma.LuaCs.Data;
public partial record ModConfigInfo : IModConfigInfo
{
public ImmutableArray<IStylesResourceInfo> Styles { get; init; }
}
public record StylesResourceInfo : IStylesResourceInfo
{
public Platform SupportedPlatforms { get; init; }
public Target SupportedTargets { get; init; }
public int LoadPriority { get; init; }
public ImmutableArray<string> FilePaths { get; init; }
public bool Optional { get; init; }
public ImmutableArray<CultureInfo> SupportedCultures { get; init; }
public string InternalName { get; init; }
public ContentPackage OwnerPackage { get; init; }
public string FallbackPackageName { get; init; }
public ImmutableArray<IPackageDependency> Dependencies { get; init; }
}
@@ -2,8 +2,22 @@ using Barotrauma.LuaCs.Configuration;
namespace Barotrauma.LuaCs.Data;
public partial interface IConfigInfo
public partial interface IConfigInfo : IConfigDisplayInfo { }
public interface IConfigDisplayInfo
{
/// <summary>
/// User-friendly name or Localization Token.
/// </summary>
string DisplayName { get; }
/// <summary>
/// User-friendly description or Localization Token.
/// </summary>
string Description { get; }
/// <summary>
/// The menu category to display under. Used for filtering.
/// </summary>
string DisplayCategory { get; }
/// <summary>
/// Should this config be displayed in end-user menus.
/// </summary>
@@ -1,15 +0,0 @@
using System.Collections.Immutable;
namespace Barotrauma.LuaCs.Data;
public partial interface IModConfigInfo : IStylesResourcesInfo { }
public interface IStylesResourceInfo : IResourceInfo, IResourceCultureInfo, IDataInfo, IPackageDependenciesInfo { }
public interface IStylesResourcesInfo
{
/// <summary>
/// Collection of loadable styles data.
/// </summary>
ImmutableArray<IStylesResourceInfo> Styles { get; }
}
@@ -1,6 +0,0 @@
namespace Barotrauma.LuaCs.Data;
public interface IStylesInfo
{
}
@@ -22,9 +22,6 @@ namespace Barotrauma
}
private partial bool ShouldRunCs() => IsCsEnabled.Value;
public IStylesManagementService StylesManagementService => _servicesProvider.TryGetService<IStylesManagementService>(out var svc)
? svc : throw new NullReferenceException("Networking Manager service not found!");
public void CheckCsEnabled()
{
@@ -0,0 +1,26 @@
using System;
using System.Collections.Immutable;
using Barotrauma.LuaCs.Configuration;
using Barotrauma.LuaCs.Data;
using Barotrauma.Networking;
using FluentResults;
namespace Barotrauma.LuaCs.Services;
public partial class ConfigService
{
public ImmutableArray<IDisplayableConfigBase> GetDisplayableConfigs()
{
throw new NotImplementedException();
}
public ImmutableArray<IDisplayableConfigBase> GetDisplayableConfigsForPackage(ContentPackage package)
{
throw new NotImplementedException();
}
public Result<IConfigControl> AddConfigControl(IConfigInfo configInfo)
{
throw new NotImplementedException();
}
}
@@ -1,6 +1,8 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using Barotrauma.LuaCs.Configuration;
using Barotrauma.LuaCs.Data;
using Barotrauma.LuaCs.Services;
using Barotrauma.Networking;
@@ -8,28 +10,8 @@ namespace Barotrauma.LuaCs.Services;
public partial interface IConfigService
{
/*
* Immediate mode
*/
FluentResults.Result<IConfigEntry<T>> AddConfigEntry<T>(IDisplayableData data,
T defaultValue,
NetSync syncMode = NetSync.None,
ClientPermissions permissions = ClientPermissions.None,
Func<T, bool> valueChangePredicate = null,
Action<IConfigEntry<T>> onValueChanged = null) where T : IConvertible, IEquatable<T>;
FluentResults.Result<IConfigList> AddConfigList(IDisplayableData data,
int defaultIndex, IReadOnlyList<string> values,
NetSync syncMode = NetSync.None,
ClientPermissions permissions = ClientPermissions.None,
Func<IConfigList, int, bool> valueChangePredicate = null,
Action<IConfigList, int> onValueChanged = null);
ImmutableArray<IDisplayableConfigBase> GetDisplayableConfigs();
ImmutableArray<IDisplayableConfigBase> GetDisplayableConfigsForPackage(ContentPackage package);
FluentResults.Result<IConfigRangeEntry<T>> AddConfigRangeEntry<T>(IDisplayableData data,
T defaultValue, T minValue, T maxValue,
Func<IConfigRangeEntry<T>, int> getStepCount,
NetSync syncMode = NetSync.None,
ClientPermissions permissions = ClientPermissions.None,
Func<T, bool> valueChangePredicate = null,
Action<IConfigEntry<T>> onValueChanged = null) where T : IConvertible, IEquatable<T>;
FluentResults.Result<IConfigControl> AddConfigControl(IConfigInfo configInfo);
}
@@ -1,13 +0,0 @@
using System.Collections.Immutable;
using System.Threading.Tasks;
using Barotrauma.LuaCs.Data;
namespace Barotrauma.LuaCs.Services;
public interface IStylesManagementService : IReusableService
{
Task<FluentResults.Result> LoadStylesAsync(ImmutableArray<IStylesResourceInfo> styles);
FluentResults.Result<IStylesService> GetStylesService(ContentPackage package);
Task<FluentResults.Result> DisposeAllStyles();
Task<FluentResults.Result> DisposeStylesForPackage(ContentPackage package);
}
@@ -1,58 +0,0 @@
using System.Threading.Tasks;
namespace Barotrauma.LuaCs.Services;
// TODO: Rework interface to support resource infos.
/// <summary>
/// Loads XML Style assets from the given content package.
/// </summary>
public interface IStylesService : IService
{
/// <summary>
/// Tries to load the styles file for the given <see cref="ContentPackage"/> and path into a new <see cref="UIStyleProcessor"/> instance.
/// </summary>
/// <param name="package"></param>
/// <param name="path"></param>
/// <returns></returns>
Task<FluentResults.Result> LoadStylesFileAsync(ContentPackage package, ContentPath path);
/// <summary>
/// Unloads all styles assets and <see cref="UIStyleProcessor"/> instances.
/// </summary>
FluentResults.Result UnloadAllStyles();
/// <summary>
/// Tries to the get the <see cref="GUIFont"/> asset by xml asset name, returns null on failure.
/// </summary>
/// <param name="fontName">XML Name of the asset.</param>
/// <returns>The asset or null if none are found.</returns>
GUIFont GetFont(string fontName);
/// <summary>
/// Tries to the get the <see cref="GUISprite"/> asset by xml asset name, returns null on failure.
/// </summary>
/// <param name="spriteName">XML Name of the asset.</param>
/// <returns>The asset or null if none are found.</returns>
GUISprite GetSprite(string spriteName);
/// <summary>
/// Tries to the get the <see cref="GUISpriteSheet"/> asset by xml asset name, returns null on failure.
/// </summary>
/// <param name="spriteSheetName">XML Name of the asset.</param>
/// <returns>The asset or null if none are found.</returns>
GUISpriteSheet GetSpriteSheet(string spriteSheetName);
/// <summary>
/// Tries to the get the <see cref="GUICursor"/> asset by xml asset name, returns null on failure.
/// </summary>
/// <param name="cursorName">XML Name of the asset.</param>
/// <returns>The asset or null if none are found.</returns>
GUICursor GetCursor(string cursorName);
/// <summary>
/// Tries to the get the <see cref="GUIColor"/> asset by xml asset name, returns null on failure.
/// </summary>
/// <param name="colorName">XML Name of the asset.</param>
/// <returns>The asset or null if none are found.</returns>
GUIColor GetColor(string colorName);
}
@@ -1,13 +1,14 @@
using Barotrauma.LuaCs.Services;
using Barotrauma.Networking;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
namespace Barotrauma.LuaCs.Services;
partial class NetworkingService : INetworkingService
{
private Dictionary<ushort, Queue<IReadMessage>> receiveQueue = new Dictionary<ushort, Queue<IReadMessage>>();
private ConcurrentDictionary<ushort, ConcurrentQueue<IReadMessage>> receiveQueue = new();
public void SendSyncMessage()
{
@@ -99,7 +100,7 @@ partial class NetworkingService : INetworkingService
}
else
{
if (!receiveQueue.ContainsKey(id)) { receiveQueue[id] = new Queue<IReadMessage>(); }
if (!receiveQueue.ContainsKey(id)) { receiveQueue[id] = new ConcurrentQueue<IReadMessage>(); }
receiveQueue[id].Enqueue(netMessage);
if (GameSettings.CurrentConfig.VerboseLogging)
@@ -1,81 +0,0 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Threading.Tasks;
using Barotrauma.LuaCs.Data;
using Barotrauma.LuaCs.Services.Processing;
using FluentResults;
// ReSharper disable UseCollectionExpression
namespace Barotrauma.LuaCs.Services;
public partial class PackageManagementService : IPackageManagementService
{
public PackageManagementService(
IConverterServiceAsync<ContentPackage, IModConfigInfo> modConfigParserService,
IProcessorService<IReadOnlyList<IAssemblyResourceInfo>, IAssembliesResourcesInfo> assemblyInfoConverter,
IProcessorService<IReadOnlyList<IConfigResourceInfo>, IConfigsResourcesInfo> configsInfoConverter,
IProcessorService<IReadOnlyList<IConfigProfileResourceInfo>, IConfigProfilesResourcesInfo> configProfilesConverter,
IProcessorService<IReadOnlyList<ILocalizationResourceInfo>, ILocalizationsResourcesInfo> localizationsConverter,
IProcessorService<IReadOnlyList<ILuaScriptResourceInfo>, ILuaScriptsResourcesInfo> luaScriptsConverter,
IPackageInfoLookupService packageInfoLookupService, Func<IReadOnlyList<IStylesResourceInfo>, IStylesResourcesInfo> stylesInfoConverter)
{
_stylesInfoConverter = stylesInfoConverter;
_modConfigParserService = modConfigParserService;
_assemblyInfoConverter = assemblyInfoConverter;
_configsInfoConverter = configsInfoConverter;
_configProfilesConverter = configProfilesConverter;
_localizationsConverter = localizationsConverter;
_luaScriptsConverter = luaScriptsConverter;
_packageInfoLookupService = packageInfoLookupService;
}
private readonly Func<IReadOnlyList<IStylesResourceInfo>, IStylesResourcesInfo> _stylesInfoConverter;
public ImmutableArray<IStylesResourceInfo> Styles => _modInfos.IsEmpty ? ImmutableArray<IStylesResourceInfo>.Empty
: _modInfos.SelectMany(kvp => kvp.Value.Styles).ToImmutableArray();
public Result<IStylesResourcesInfo> GetStylesInfos(ContentPackage package, bool onlySupportedResources = true)
{
((IService)this).CheckDisposed();
if (package is null)
return FluentResults.Result.Fail($"{nameof(GetStylesInfos)}: ContentPackage is null.");
if (_modInfos.TryGetValue(package, out var result))
return FluentResults.Result.Ok<IStylesResourcesInfo>(_stylesInfoConverter(onlySupportedResources?
result.Styles.Where(r =>
(r.SupportedPlatforms & ModUtils.Environment.CurrentPlatform) > 0
&& (r.SupportedTargets & ModUtils.Environment.CurrentTarget) > 0).ToImmutableArray()
: result.Styles
));
return FluentResults.Result.Fail(
$"{nameof(GetStylesInfos)}: ContentPackage {package.Name} is not registered.");
}
public Result<IStylesResourcesInfo> GetStylesInfos(IReadOnlyList<ContentPackage> packages, bool onlySupportedResources = true)
{
((IService)this).CheckDisposed();
if (packages is null || packages.Count == 0)
return FluentResults.Result.Fail($"{nameof(GetStylesInfos)}: ContentPackage list is null or empty.");
var builder = ImmutableArray.CreateBuilder<IStylesResourceInfo>();
foreach (var package in packages)
{
if (_modInfos.TryGetValue(package, out var result) && result.Styles is { IsEmpty: false })
{
builder.AddRange(onlySupportedResources?
result.Styles.Where(r =>
(r.SupportedPlatforms & ModUtils.Environment.CurrentPlatform) > 0
&& (r.SupportedTargets & ModUtils.Environment.CurrentTarget) > 0).ToImmutableArray()
: result.Styles);
}
}
return FluentResults.Result.Ok(_stylesInfoConverter(builder.MoveToImmutable()));
}
public async Task<Result<IStylesResourcesInfo>> GetStylesInfosAsync(IReadOnlyList<ContentPackage> packages, bool onlySupportedResources = true)
{
return await Task.Run(() => GetStylesInfos(packages, onlySupportedResources));
}
}
@@ -14,26 +14,17 @@ public partial class ModConfigService
private partial async Task<Result<IModConfigInfo>> GetModConfigInfoAsync(ContentPackage package, XElement root)
{
var asm = root.GetChildElements("Assembly").ToImmutableArray();
var loc = root.GetChildElements("Localization").ToImmutableArray();
var cfg = root.GetChildElements("Config").ToImmutableArray();
var lua = root.GetChildElements("Lua").ToImmutableArray();
var stl = root.GetChildElements("Style").ToImmutableArray();
return FluentResults.Result.Ok<IModConfigInfo>(new ModConfigInfo()
{
Package = package,
PackageName = package.Name,
Assemblies = asm.Any() ? GetAssemblies(package, asm) : ImmutableArray<IAssemblyResourceInfo>.Empty,
Localizations = loc.Any() ? GetLocalizations(package, loc) : ImmutableArray<ILocalizationResourceInfo>.Empty,
Configs = cfg.Any() ? GetConfigs(package, cfg) : ImmutableArray<IConfigResourceInfo>.Empty,
ConfigProfiles = cfg.Any() ? GetConfigProfiles(package, cfg) : ImmutableArray<IConfigProfileResourceInfo>.Empty,
LuaScripts = lua.Any() ? GetLuaScripts(package, lua) : ImmutableArray<ILuaScriptResourceInfo>.Empty,
Styles = stl.Any() ? GetStyles(package, stl) : ImmutableArray<IStylesResourceInfo>.Empty
LuaScripts = lua.Any() ? GetLuaScripts(package, lua) : ImmutableArray<ILuaScriptResourceInfo>.Empty
});
}
private ImmutableArray<IStylesResourceInfo> GetStyles(ContentPackage src, IEnumerable<XElement> elements)
{
throw new NotImplementedException();
}
}
@@ -1,6 +0,0 @@
namespace Barotrauma.LuaCs.Services.Processing;
public class StylesManagementService : IStylesManagementService
{
}
@@ -1,120 +0,0 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Xml.Linq;
using FluentResults;
using FluentResults.LuaCs;
namespace Barotrauma.LuaCs.Services;
// TODO: Complete rewrite
public class StylesService : IStylesService
{
private readonly ConcurrentDictionary<string, UIStyleProcessor> _loadedProcessors = new();
private readonly IStorageService _storageService;
private readonly ILoggerService _loggerService;
public StylesService(IStorageService storageService, ILoggerService loggerService)
{
_storageService = storageService;
_loggerService = loggerService;
}
public async Task<FluentResults.Result> LoadStylesFileAsync(ContentPackage package, ContentPath path)
{
throw new NotImplementedException();
}
public FluentResults.Result UnloadAllStyles()
{
if (NoProcessorsLoaded)
return FluentResults.Result.Fail(new Error($"{nameof(StylesService)}.{nameof(UnloadAllStyles)}: No processors have been loaded.")
.WithMetadata(MetadataType.ExceptionObject, this));
foreach (var processor in _loadedProcessors)
{
processor.Value.UnloadFile();
}
_loadedProcessors.Clear();
return FluentResults.Result.Ok();
}
public GUIFont GetFont(string fontName)
{
if (NoProcessorsLoaded)
return null;
foreach (var processor in _loadedProcessors.Values)
{
if (processor.Fonts.TryGetValue(fontName, out var asset))
return asset;
}
return null;
}
public GUISprite GetSprite(string spriteName)
{
if (NoProcessorsLoaded)
return null;
foreach (var processor in _loadedProcessors.Values)
{
if (processor.Sprites.TryGetValue(spriteName, out var asset))
return asset;
}
return null;
}
public GUISpriteSheet GetSpriteSheet(string spriteSheetName)
{
if (NoProcessorsLoaded)
return null;
foreach (var processor in _loadedProcessors.Values)
{
if (processor.SpriteSheets.TryGetValue(spriteSheetName, out var asset))
return asset;
}
return null;
}
public GUICursor GetCursor(string cursorName)
{
if (NoProcessorsLoaded)
return null;
foreach (var processor in _loadedProcessors.Values)
{
if (processor.Cursors.TryGetValue(cursorName, out var asset))
return asset;
}
return null;
}
public GUIColor GetColor(string colorName)
{
if (NoProcessorsLoaded)
return null;
foreach (var processor in _loadedProcessors.Values)
{
if (processor.Colors.TryGetValue(colorName, out var asset))
return asset;
}
return null;
}
private bool NoProcessorsLoaded => _loadedProcessors.IsEmpty;
public void Dispose()
{
UnloadAllStyles();
GC.SuppressFinalize(this);
}
public bool IsDisposed { get; private set; }
}
@@ -1,93 +0,0 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Xml.Linq;
using Barotrauma.Extensions;
namespace Barotrauma.LuaCs.Services;
public class UIStyleProcessor : HashlessFile
{
private readonly UIStyleFile _fake;
public readonly Dictionary<string, GUIFont> Fonts = new();
public readonly Dictionary<string, GUISprite> Sprites = new();
public readonly Dictionary<string, GUISpriteSheet> SpriteSheets = new();
public readonly Dictionary<string, GUICursor> Cursors = new();
public readonly Dictionary<string, GUIColor> Colors = new();
public UIStyleProcessor(ContentPackage contentPackage, ContentPath path) : base(contentPackage, path)
{
_fake = new UIStyleFile(contentPackage, path);
}
public override void LoadFile()
{
var element = XMLExtensions.TryLoadXml(path: Path)?.Root?.FromPackage(ContentPackage);
if (element is null)
throw new InvalidDataException($"UIStyleProcessor: Failed to load UI style file: {Path}");
var styleElement = element.Name.LocalName.ToLowerInvariant() == "style" ? element : element.GetChildElement("style");
if (styleElement is null)
throw new InvalidDataException($"UIStyleProcessor: no 'style' XmlElement found in file: {Path}");
var childElements = styleElement.GetChildElements("Font");
if (childElements is not null)
AddToList<GUIFont, GUIFontPrefab>(Fonts, childElements, _fake);
childElements = styleElement.GetChildElements("Sprite");
if (childElements is not null)
AddToList<GUISprite, GUISpritePrefab>(Sprites, childElements, _fake);
childElements = styleElement.GetChildElements("Spritesheet");
if (childElements is not null)
AddToList<GUISpriteSheet, GUISpriteSheetPrefab>(SpriteSheets, childElements, _fake);
childElements = styleElement.GetChildElements("Cursor");
if (childElements is not null)
AddToList<GUICursor, GUICursorPrefab>(Cursors, childElements, _fake);
childElements = styleElement.GetChildElements("Color");
if (childElements is not null)
AddToList<GUIColor, GUIColorPrefab>(Colors, childElements, _fake);
void AddToList<T1, T2>(Dictionary<string, T1> dict, IEnumerable<ContentXElement> ele, UIStyleFile file) where T1 : GUISelector<T2> where T2 : GUIPrefab
{
foreach (ContentXElement prefabElement in ele)
{
string name = prefabElement.GetAttributeString("name", string.Empty);
if (name != string.Empty)
{
var prefab = (T2)Activator.CreateInstance(typeof(T2), new object[]{ prefabElement, file })!;
if (!dict.ContainsKey(name))
dict[name] = (T1)Activator.CreateInstance(typeof(T1), new object[] { name })!;
dict[name].Prefabs.Add(prefab, false);
}
}
}
}
public override void UnloadFile()
{
Fonts.Values.ForEach(p => p.Prefabs.RemoveByFile(_fake));
Sprites.Values.ForEach(p => p.Prefabs.RemoveByFile(_fake));
SpriteSheets.Values.ForEach(p => p.Prefabs.RemoveByFile(_fake));
Cursors.Values.ForEach(p => p.Prefabs.RemoveByFile(_fake));
Colors.Values.ForEach(p => p.Prefabs.RemoveByFile(_fake));
Fonts.Clear();
Sprites.Clear();
SpriteSheets.Clear();
Cursors.Clear();
Colors.Clear();
}
public override void Sort()
{
Fonts.Values.ForEach(p => p.Prefabs.Sort());
Sprites.Values.ForEach(p => p.Prefabs.Sort());
SpriteSheets.Values.ForEach(p => p.Prefabs.Sort());
Cursors.Values.ForEach(p => p.Prefabs.Sort());
Colors.Values.ForEach(p => p.Prefabs.Sort());
}
}
@@ -12,6 +12,7 @@ using System.Globalization;
using System.Linq;
using System.Threading;
using System.Xml.Linq;
using Barotrauma.LuaCs.Events;
using Barotrauma.Sounds;
namespace Barotrauma
@@ -1532,7 +1533,7 @@ namespace Barotrauma
{
Select(enableAutoSave: true);
GameMain.LuaCs.CheckInitialize();
GameMain.LuaCs.EventService.PublishEvent<IEventScreenSelected>(sub => sub.OnScreenSelected(this));
}
public void Select(bool enableAutoSave = true)