mirror of
https://github.com/All-Of-Us-Mods/MiraAPI.git
synced 2026-10-19 15:51:48 +00:00
Created subclass with generic values
This commit is contained in:
1 parent
612597566b
commit
71a3461432
1 file changed
+146
-1
@@ -34,8 +34,10 @@ public abstract class ModdedOptionList : IModdedOptionList
|
||||
/// <inheritdoc />
|
||||
public IReadOnlyList<StringNames> StringNames { get; }
|
||||
|
||||
protected readonly BaseGameSetting[] _data;
|
||||
|
||||
/// <inheritdoc />
|
||||
public IReadOnlyList<BaseGameSetting> Data { get; protected set; } = [];
|
||||
public IReadOnlyList<BaseGameSetting> Data => _data;
|
||||
|
||||
/// <inheritdoc />
|
||||
public IMiraPlugin? ParentMod
|
||||
@@ -118,3 +120,146 @@ public abstract class ModdedOptionList : IModdedOptionList
|
||||
PlayerOption playerOpt,
|
||||
Transform container);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a modded option list.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The value type.</typeparam>
|
||||
public abstract class ModdedOptionList<T> : ModdedOptionList
|
||||
{
|
||||
protected override void OnParentModChange()
|
||||
{
|
||||
var configFile = _parentMod!.GetConfigFile();
|
||||
for (int i = 0; i < Count; i++)
|
||||
{
|
||||
var entry = configFile.Bind(ConfigDefinitions[i], DefaultValue(i));
|
||||
Values[i] = entry.Value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the list of values of the options.
|
||||
/// </summary>
|
||||
public T[] Values { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the list of default value of the options.
|
||||
/// </summary>
|
||||
public Func<int, T> DefaultValue { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the event that is invoked when the value of an option changes.
|
||||
/// </summary>
|
||||
public Action<int, T>? ChangedEvent { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ModdedOptionList{T}"/> class.
|
||||
/// </summary>
|
||||
/// <param name="title">The options' title.</param>
|
||||
/// <param name="count">The option list's length.</param>
|
||||
/// <param name="defaultValues">The default values.</param>
|
||||
/// <param name="includeInPreset">Whether to include the options in the preset.</param>
|
||||
/// <param name="zeroIndexTitle">Whether the first option's title index is 0, else 1.</param>
|
||||
protected ModdedOptionList(string title, int count, Func<int, T> defaultValues, bool includeInPreset = true, bool zeroIndexTitle = false)
|
||||
: base(title, count, includeInPreset, zeroIndexTitle)
|
||||
{
|
||||
DefaultValue = defaultValues;
|
||||
Values = Enumerable.Range(0, Count).Select(defaultValues).ToArray();
|
||||
}
|
||||
|
||||
internal void ValueChanged(int idx, OptionBehaviour optionBehaviour)
|
||||
{
|
||||
SetValue(idx, GetValueFromOptionBehaviour(idx, optionBehaviour));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the value of the option.
|
||||
/// </summary>
|
||||
/// <param name="idx">The option's index.</param>
|
||||
/// <param name="newValue">The new value.</param>
|
||||
/// <param name="sendRpc">Whether to send the value to other players.</param>
|
||||
public void SetValue(int idx, T newValue, bool sendRpc = true)
|
||||
{
|
||||
var oldVal = Values[idx];
|
||||
Values[idx] = newValue;
|
||||
|
||||
if (Values[idx]?.Equals(oldVal) == false)
|
||||
{
|
||||
ChangedEvent?.Invoke(idx, Values[idx]);
|
||||
}
|
||||
|
||||
if (sendRpc && AmongUsClient.Instance.AmHost)
|
||||
{
|
||||
if (ParentMod?.GetConfigFile().TryGetEntry<T>(ConfigDefinitions[idx], out var entry) == true)
|
||||
{
|
||||
entry.Value = Values[idx];
|
||||
}
|
||||
|
||||
Rpc<SyncOptionsRpc>.Instance.Send(PlayerControl.LocalPlayer, [GetNetData(idx)], true); // This might not work
|
||||
}
|
||||
|
||||
OnValueChanged(idx, newValue);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void SaveToPreset(ConfigFile presetConfig, bool saveDefault = false)
|
||||
{
|
||||
if (ConfigDefinitions.Any(d => d is null))
|
||||
{
|
||||
Error($"Attempted to save {Title} to preset, but some ConfigDefinitions are null.");
|
||||
return;
|
||||
}
|
||||
Bind(presetConfig);
|
||||
for (int i = 0; i < Count; i++)
|
||||
{
|
||||
presetConfig[ConfigDefinitions[i]].BoxedValue = saveDefault ? DefaultValue(i) : Values[i];
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void Bind(ConfigFile config)
|
||||
{
|
||||
for (int i = 0; i < Count; i++)
|
||||
{
|
||||
config.Bind(ConfigDefinitions[i], DefaultValue(i));
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void LoadFromPreset(ConfigFile presetConfig)
|
||||
{
|
||||
for (int i = 0; i < Count; i++)
|
||||
{
|
||||
if (presetConfig.TryGetEntry(ConfigDefinitions[i], out ConfigEntry<T> entry))
|
||||
{
|
||||
SetValue(i, entry.Value, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
Error($"Attempted to load {Title} from preset, but ConfigDefinition {i} is not found in preset.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles the value changed event.
|
||||
/// </summary>
|
||||
/// <param name="idx">The option's index.</param>
|
||||
/// <param name="newValue">The new value.</param>
|
||||
protected abstract void OnValueChanged(int idx, T newValue);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the value from the option behaviour.
|
||||
/// </summary>
|
||||
/// <param name="idx">The option's index.</param>
|
||||
/// <param name="optionBehaviour">The OptionBehaviour.</param>
|
||||
/// <returns>The value.</returns>
|
||||
public abstract T GetValueFromOptionBehaviour(int idx, OptionBehaviour optionBehaviour);
|
||||
|
||||
/// <summary>
|
||||
/// Indexes the option for its value of type <typeparamref name="T"/>.
|
||||
/// </summary>
|
||||
/// <param name="idx">The option's index.</param>
|
||||
/// <returns>value of type <typeparamref name="T"/>.</returns>
|
||||
public T this[int idx] => Values[idx];
|
||||
}
|
||||
Reference in new issue
Block a user