The gameplay settings menu kinda works (only for luacsforbarotrauma).

This commit is contained in:
MapleWheels
2026-03-04 20:39:13 -05:00
parent ce8b984542
commit f38a7bd574
16 changed files with 182 additions and 16 deletions

View File

@@ -0,0 +1,9 @@
using System;
using Microsoft.Xna.Framework;
namespace Barotrauma.LuaCs.Data;
public interface IDisplayable
{
public void AddDisplayComponent(GUILayoutGroup layoutGroup, Vector2 relativeSize, Action<string> onSerializedValue);
}

View File

@@ -0,0 +1,6 @@
namespace Barotrauma.LuaCs.Data;
public partial interface ISettingBase : IDisplayable
{
}

View File

@@ -6,7 +6,7 @@ using Barotrauma.LuaCs.Data;
using Microsoft.Xna.Framework.Input;
using OneOf;
namespace Barotrauma.LuaCs.Configuration;
namespace Barotrauma.LuaCs.Data;
public class SettingControl : SettingBase, ISettingControl
{

View File

@@ -1,10 +1,7 @@
using System;
using System.Collections.Immutable;
using System.Linq;
using Barotrauma.LuaCs.Configuration;
using Barotrauma.LuaCs.Data;
using Barotrauma.Networking;
using FluentResults;
namespace Barotrauma.LuaCs;

View File

@@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using Barotrauma.LuaCs.Configuration;
using Barotrauma.LuaCs.Data;
using Barotrauma.LuaCs;
using Barotrauma.Networking;

View File

@@ -14,4 +14,9 @@ internal sealed class ModsControlsSettingsMenu : ModsSettingsMenuBase
{
// TODO: Finish this later.
}
public override void ApplyInstalledModChanges()
{
// TODO: Finish this later.
}
}

View File

@@ -1,8 +1,12 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Immutable;
using Microsoft.Xna.Framework;
using System.Linq;
using System.Numerics;
using Barotrauma.LuaCs.Data;
using Vector2 = Microsoft.Xna.Framework.Vector2;
// ReSharper disable ObjectCreationAsStatement
namespace Barotrauma.LuaCs;
@@ -57,6 +61,9 @@ internal sealed class ModsGameplaySettingsMenu : ModsSettingsMenuBase
(_modCategoryDisplayGroup, _settingsDisplayGroup) = GUIUtil.CreateSidebars(settingsContentAreaGroup, true);
_modCategoryDisplayGroup.RectTransform.RelativeSize = new Vector2(0.3f, 1f);
_settingsDisplayGroup.RectTransform.RelativeSize = new Vector2(0.7f, 1f);
// default category
_selectedCategory = "All";
GenerateCategoryListDisplay(_modCategoryDisplayGroup, GetTargetPackagesList(), GetDisplayCategoriesList());
GenerateSettingsListDisplay(_settingsDisplayGroup, GetDisplaySettingsList());
@@ -68,18 +75,20 @@ internal sealed class ModsGameplaySettingsMenu : ModsSettingsMenuBase
GenerateSettingsListDisplay(_settingsDisplayGroup, GetDisplaySettingsList());
}
string GetLocalizedString(string identifier)
string GetLocalizedString(string identifier, string defaultValue)
{
var lstr = TextManager.Get(identifier);
return lstr.IsNullOrWhiteSpace() ? "General" : lstr.Value;
return lstr.IsNullOrWhiteSpace() ? defaultValue : lstr.Value;
}
// Filters by selected package and query text
ImmutableArray<string> GetDisplayCategoriesList()
{
return GetFilteredSettingsList()
.Select(s => GetLocalizedString(s.GetDisplayInfo().DisplayCategory))
.Select(s => GetLocalizedString(s.GetDisplayInfo().DisplayCategory, "General"))
.Concat(new []{ "All" })
.Distinct()
.OrderBy(s => s)
.ToImmutableArray();
}
@@ -89,7 +98,10 @@ internal sealed class ModsGameplaySettingsMenu : ModsSettingsMenuBase
return _settingsInstancesGameplay
.Where(s => SettingMatchesQuery(s, _selectedSearchQuery))
.Select(s => s.OwnerPackage)
.Concat(new[] { ContentPackageManager.VanillaCorePackage })
.Distinct()
.OrderBy(p => p == ContentPackageManager.VanillaCorePackage ? 1 : 0)
.ThenBy(p => p.Name)
.ToImmutableArray();
}
@@ -98,7 +110,8 @@ internal sealed class ModsGameplaySettingsMenu : ModsSettingsMenuBase
{
return GetFilteredSettingsList()
.Where(s => _selectedCategory.IsNullOrWhiteSpace()
|| GetLocalizedString(s.GetDisplayInfo().DisplayCategory) == _selectedCategory)
|| _selectedCategory == "All"
|| GetLocalizedString(s.GetDisplayInfo().DisplayCategory, "General") == _selectedCategory)
.ToImmutableArray();
}
@@ -147,12 +160,12 @@ internal sealed class ModsGameplaySettingsMenu : ModsSettingsMenuBase
var packageSelectionList = GUIUtil.Dropdown<ContentPackage>(layoutGroup, cp => GetPackageName(cp), null,
packagesList, packagesList.Length > 0 ? packagesList[0] : null, cp =>
{
_selectedContentPackage = cp == ContentPackageManager.VanillaCorePackage ? null : cp;
_selectedContentPackage = cp;
_selectedCategory = string.Empty;
GenerateCategoryListDisplay(_modCategoryDisplayGroup, GetTargetPackagesList(), GetDisplayCategoriesList());
GenerateSettingsListDisplay(_settingsDisplayGroup, GetDisplaySettingsList());
}, new Vector2(1f, 0.07f));
var containerBox = new GUIListBox(new RectTransform(new Vector2(1f, 0.93f), layoutGroup.RectTransform));
var containerBox = new GUIListBox(new RectTransform(new Vector2(1f, 0.945f), layoutGroup.RectTransform));
float size_y = MathF.Max(categories.Length * 0.122f, 1f);
var displayedCategoriesFrame = new GUIFrame(new RectTransform(new Vector2(1f, size_y), containerBox.Content.RectTransform), style: null, color: Color.Black)
{
@@ -185,13 +198,67 @@ internal sealed class ModsGameplaySettingsMenu : ModsSettingsMenuBase
void GenerateSettingsListDisplay(GUILayoutGroup layoutGroup, ImmutableArray<ISettingBase> settings)
{
layoutGroup.ClearChildren();
float settingHeight = 0.06f;
var containerBox = new GUIListBox(new RectTransform(new Vector2(1f, 1f), layoutGroup.RectTransform));
foreach (var setting in settings)
{
var entry = AddSettingToDisplay(
setting,
containerBox.Content.RectTransform,
settingHeight: settingHeight,
labelSize: new Vector2(0.6f, 1f),
controlSize: new Vector2(0.4f, 1f));
}
}
(GUIFrame entryFrame, GUILayoutGroup entryLayoutGroup) AddSettingToDisplay(ISettingBase setting,
RectTransform parent, float settingHeight, Vector2 labelSize, Vector2 controlSize)
{
GUIFrame entryFrame = new GUIFrame(new RectTransform(new Vector2(1f, settingHeight), parent));
GUILayoutGroup entryLayoutGroup = new GUILayoutGroup(new RectTransform(Vector2.One, entryFrame.RectTransform), isHorizontal: true);
new GUITextBlock(new RectTransform(labelSize, entryLayoutGroup.RectTransform),
GetLocalizedString(setting.GetDisplayInfo().DisplayName, setting.GetDisplayInfo().DisplayName),
textColor: Color.PeachPuff,
font: GUIStyle.SmallFont,
textAlignment: Alignment.Left)
{
CanBeFocused = false
};
setting.AddDisplayComponent(entryLayoutGroup, controlSize, newValue =>
{
NewValuesCache[setting] = newValue;
});
return (entryFrame, entryLayoutGroup);
}
}
protected override void DisposeInternal()
{
// TODO: Finish this later.
NewValuesCache.Clear();
_modCategoryDisplayGroup?.Parent.RemoveChild(_modCategoryDisplayGroup);
_settingsDisplayGroup?.Parent.RemoveChild(_settingsDisplayGroup);
_modCategoryDisplayGroup = null;
_settingsDisplayGroup = null;
}
public override void ApplyInstalledModChanges()
{
foreach (var kvp in NewValuesCache)
{
if (kvp.Key.IsDisposed)
{
continue;
}
kvp.Key.TrySetValue(kvp.Value);
}
NewValuesCache.Clear();
}
}

View File

@@ -1,5 +1,7 @@
using System;
using System.Collections.Concurrent;
using Barotrauma.Extensions;
using Barotrauma.LuaCs.Data;
using Microsoft.Xna.Framework;
namespace Barotrauma.LuaCs;
@@ -10,6 +12,7 @@ internal abstract class ModsSettingsMenuBase : IDisposable
protected IPackageManagementService PackageManagementService { get; private set; }
protected IConfigService ConfigService { get; private set; }
protected SettingsMenu SettingsMenuInstance { get; private set; }
protected readonly ConcurrentDictionary<ISettingBase, string> NewValuesCache = new();
protected ModsSettingsMenuBase(GUIFrame contentFrame,
IPackageManagementService packageManagementService,
@@ -22,6 +25,7 @@ internal abstract class ModsSettingsMenuBase : IDisposable
}
protected abstract void DisposeInternal();
public abstract void ApplyInstalledModChanges();
public void Dispose()
{
@@ -31,5 +35,6 @@ internal abstract class ModsSettingsMenuBase : IDisposable
ContentFrame = null;
PackageManagementService = null;
ConfigService = null;
NewValuesCache.Clear();
}
}

View File

@@ -75,6 +75,14 @@ public class SettingsMenuSystem : ISettingsMenuSystem
return contentFr;
}
[HarmonyPatch(typeof(SettingsMenu), nameof(SettingsMenu.ApplyInstalledModChanges)), HarmonyPostfix]
private static void SettingsMenu_ApplyInstalledModChanges_Post()
{
SystemInstance._gameplayMenuInstance?.ApplyInstalledModChanges();
SystemInstance._controlsMenuInstance?.ApplyInstalledModChanges();
}
private void DisposeMenuFrames()
{
_controlsMenuInstance?.Dispose();

View File

@@ -4,7 +4,7 @@
<Setting Name="DisableErrorGUIOverlay" Type="bool" Value="true"/>
<Setting Name="HideUserNamesInLogs" Type="bool" Value="true"/>
<Setting Name="LocalDataSavePath" Type="string" Value="/Data/Mods" AllowChangesWhileExecuting="false"/>
<Setting Name="LuaForBarotraumaSteamId" Type="ulong" Value="2559634234"/>
<Setting Name="LuaForBarotraumaSteamId" Type="ulong" Value="2559634234" ReadOnly="true"/>
<Setting Name="IsCsEnabled" Type="bool" Value="false" AllowChangesWhileExecuting="false"/>
<Setting Name="RestrictMessageSize" Type="bool" Value="true"/>
</Settings>

View File

@@ -11,4 +11,6 @@
<LuaCsForBarotrauma.HideUserNamesInLogs.DisplayCategory>General</LuaCsForBarotrauma.HideUserNamesInLogs.DisplayCategory>
<LuaCsForBarotrauma.LocalDataSavePath.DisplayName>Where to Save Local Data</LuaCsForBarotrauma.LocalDataSavePath.DisplayName>
<LuaCsForBarotrauma.LocalDataSavePath.DisplayCategory>General</LuaCsForBarotrauma.LocalDataSavePath.DisplayCategory>
<LuaCsForBarotrauma.RestrictMessageSize.DisplayName>Limit Network Message Size</LuaCsForBarotrauma.RestrictMessageSize.DisplayName>
<LuaCsForBarotrauma.RestrictMessageSize.DisplayCategory>Networking</LuaCsForBarotrauma.RestrictMessageSize.DisplayCategory>
</infotexts>

View File

@@ -8,7 +8,7 @@ using Barotrauma.Networking;
namespace Barotrauma.LuaCs.Data;
public interface ISettingBase : IDataInfo, IEquatable<ISettingBase>, IDisposable
public partial interface ISettingBase : IDataInfo, IEquatable<ISettingBase>, IDisposable
{
/// <summary>
/// Settings production factory. Should be implemented by all types and registered with the Dependency Injector.

View File

@@ -1,6 +1,7 @@
using System;
using System.Xml.Linq;
using Barotrauma.LuaCs.Data;
using Microsoft.Xna.Framework;
using OneOf;
namespace Barotrauma.LuaCs.Data;
@@ -60,4 +61,17 @@ public abstract class SettingBase : ISettingBase
public abstract bool TrySetValue(OneOf<string, XElement> value);
public abstract event Action<ISettingBase> OnValueChanged;
public abstract OneOf<string, XElement> GetSerializableValue();
#if CLIENT
public virtual void AddDisplayComponent(GUILayoutGroup layoutGroup, Vector2 relativeSize, Action<string> onSerializedValue)
{
new GUITextBox(new RectTransform(relativeSize, layoutGroup.RectTransform), font: GUIStyle.SmallFont)
{
OnEnterPressed = (box, txt) =>
{
onSerializedValue?.Invoke(txt);
return true;
}
};
}
#endif
}

View File

@@ -5,11 +5,12 @@ using Barotrauma.LuaCs.Data;
using Barotrauma.LuaCs;
using Barotrauma.Networking;
using Microsoft.Toolkit.Diagnostics;
using Microsoft.Xna.Framework;
using OneOf;
namespace Barotrauma.LuaCs.Data;
public class SettingEntry<T> : SettingBase, ISettingBase<T>, INetworkSyncVar where T : IEquatable<T>, IConvertible
public partial class SettingEntry<T> : SettingBase, ISettingBase<T>, INetworkSyncVar where T : IEquatable<T>, IConvertible
{
public class Factory : ISettingBase.IFactory<ISettingBase<T>>
{
@@ -302,4 +303,57 @@ public class SettingEntry<T> : SettingBase, ISettingBase<T>, INetworkSyncVar whe
#endif
}
}
#if CLIENT
public override void AddDisplayComponent(GUILayoutGroup layoutGroup, Vector2 relativeSize, Action<string> onSerializedValue)
{
switch (Type.GetTypeCode(typeof(T)))
{
case TypeCode.Boolean:
new GUITickBox(new RectTransform(relativeSize, layoutGroup.RectTransform), "")
{
Selected = (bool)Convert.ChangeType(this.Value, TypeCode.Boolean),
OnSelected = (box) =>
{
onSerializedValue?.Invoke(box.Selected.ToString());
return true;
}
};
break;
case TypeCode.Byte:
case TypeCode.SByte:
case TypeCode.Int16:
case TypeCode.Char:
case TypeCode.UInt16:
case TypeCode.Int32:
case TypeCode.UInt32:
case TypeCode.Int64:
case TypeCode.UInt64:
new GUINumberInput(new RectTransform(relativeSize, layoutGroup.RectTransform), NumberType.Int)
{
IntValue = (int)Convert.ChangeType(this.Value, TypeCode.Int32)!,
OnValueChanged = (num) =>
{
onSerializedValue?.Invoke(num.IntValue.ToString());
}
};
break;
case TypeCode.Single:
case TypeCode.Double:
new GUINumberInput(new RectTransform(relativeSize, layoutGroup.RectTransform), NumberType.Float)
{
FloatValue = (float)Convert.ChangeType(this.Value, TypeCode.Single)!,
OnValueChanged = (num) =>
{
onSerializedValue?.Invoke(num.FloatValue.ToString());
}
};
break;
case TypeCode.String:
default:
base.AddDisplayComponent(layoutGroup, relativeSize, onSerializedValue);
break;
}
}
#endif
}

View File

@@ -75,7 +75,7 @@ public sealed class SettingsFileParserService :
continue;
}
var packageIdent = res.path.ContentPackage.ToIdentifier().ToString();
var packageIdent = res.path.ContentPackage!.Name;
foreach (var element in settingElements)
{