Add BooleanField for configurable boolean field settings

This commit is contained in:
2025-02-24 10:10:21 +01:00
parent 212c82b448
commit dbeb55e2aa
2 changed files with 119 additions and 6 deletions

View File

@@ -59,8 +59,8 @@ namespace TerraTech {
}
private static void ConfigureManager(MultipliedObject<ModuleWeaponGun> obj) {
// obj.AddField(new FieldConfiguration<bool, bool>("m_SeekingRounds", seekingRoundsAll));
// obj.AddField(new FieldConfiguration<bool, bool>("m_ResetBurstOnInterrupt", resetBurstOnInterruptAll));
obj.AddBooleanField(new BooleanFieldConfiguration("m_SeekingRounds", seekingRoundsAll));
obj.AddBooleanField(new BooleanFieldConfiguration("m_ResetBurstOnInterrupt", resetBurstOnInterruptAll));
obj.AddField(new FieldConfiguration<float, float>("m_BurstCooldown", burstCooldownMultiplier));
obj.AddField(new FieldConfiguration<int, float>("m_BurstShotCount", burstShotCountMultiplier));
obj.AddField(new FieldConfiguration<float, float>("m_ShotCooldown", shotCooldownMultiplier));

View File

@@ -5,7 +5,7 @@ using BepInEx.Configuration;
using HarmonyLib;
namespace TerraTech {
public interface IMultipliedField {
public interface IFieldModifier {
void CaptureOriginal();
void Apply();
void Restore();
@@ -57,7 +57,7 @@ namespace TerraTech {
}
}
public class MultipliedField<TField, TMul> : IMultipliedField {
public class MultipliedField<TField, TMul> : IFieldModifier {
private readonly string _fieldName;
private readonly ConfigEntry<TMul> _multiplier;
private readonly Traverse _parentTraverse;
@@ -156,6 +156,114 @@ namespace TerraTech {
}
}
public class BooleanFieldConfiguration {
private string _fieldName;
private ConfigEntry<bool> _value;
private Func<object, ConfigEntry<bool>> _conditionalValue;
public string FieldName {
get { return _fieldName; }
set { _fieldName = value; }
}
public ConfigEntry<bool> Value {
get { return _value; }
set { _value = value; }
}
public Func<object, ConfigEntry<bool>> ConditionalValue {
get { return _conditionalValue; }
set { _conditionalValue = value; }
}
public BooleanFieldConfiguration(string fieldName, ConfigEntry<bool> value) {
_fieldName = fieldName;
_value = value;
}
public BooleanFieldConfiguration(string fieldName, ConfigEntry<bool> value,
Func<object, ConfigEntry<bool>> conditionalValue) {
_fieldName = fieldName;
_value = value;
_conditionalValue = conditionalValue;
}
public ConfigEntry<bool> GetValue(object instance) {
if (_conditionalValue == null) {
return _value;
}
return _conditionalValue(instance);
}
}
public class BooleanField : IFieldModifier {
private readonly string _fieldName;
private readonly ConfigEntry<bool> _value;
private readonly Traverse _parentTraverse;
private bool _originalValue;
public string FieldName {
get { return _fieldName; }
}
public BooleanField(string fieldName, ConfigEntry<bool> value, Traverse parentTraverse) {
_fieldName = fieldName;
_value = value;
_parentTraverse = parentTraverse;
if (!parentTraverse.Field(fieldName).FieldExists()) {
throw new ArgumentException(
string.Format("Field {0} does not exist on {1}", fieldName, parentTraverse));
}
}
public bool GetValue() {
var value = _parentTraverse.Field(_fieldName).GetValue();
if (value == null)
throw new InvalidOperationException(string.Format("Field {0} returned null", _fieldName));
return (bool)value;
}
public void SetValue(bool value) {
_parentTraverse.Field(_fieldName).SetValue(value);
var verifyValue = GetValue();
if (verifyValue != value)
throw new InvalidOperationException(
string.Format("Field {0} set to {1} but read back as {2}", _fieldName, value, verifyValue));
}
public void CaptureOriginal() {
_originalValue = GetValue();
if (Main.debug.Value)
Console.WriteLine("Captured original value for {0}: {1}", _fieldName, _originalValue);
}
public void Apply() {
try {
if (Main.debug.Value)
Console.WriteLine("Applying to {0}: setting to {1}", _fieldName, _value.Value);
SetValue(_value.Value);
} catch (Exception e) {
throw new InvalidOperationException(string.Format("Failed to apply value to {0}", _fieldName), e);
}
}
public void Restore() {
if (Main.debug.Value)
Console.WriteLine("Restoring {0} to original value: {1}", _fieldName, _originalValue);
SetValue(_originalValue);
}
public void LogValue(string prefix) {
if (!Main.debug.Value)
return;
var currentValue = GetValue();
Console.WriteLine("{0} {1}; {2}: {3} (original: {4}, value: {5})", prefix, _parentTraverse, _fieldName,
currentValue, _originalValue, _value.Value);
}
}
/// <summary>
/// Represents an object with multiple fields that can be multiplied
/// </summary>
@@ -163,12 +271,12 @@ namespace TerraTech {
public class MultipliedObject<T> {
private readonly T _instance;
private readonly Traverse _objectTraverse;
private readonly Dictionary<string, IMultipliedField> _fields;
private readonly Dictionary<string, IFieldModifier> _fields;
public MultipliedObject(T instance) {
_instance = instance;
_objectTraverse = Traverse.Create(instance);
_fields = new Dictionary<string, IMultipliedField>();
_fields = new Dictionary<string, IFieldModifier>();
}
public void AddField<TField, TMul>(FieldConfiguration<TField, TMul> config) {
@@ -177,6 +285,11 @@ namespace TerraTech {
new MultipliedField<TField, TMul>(config.FieldName, multiplier, _objectTraverse);
}
public void AddBooleanField(BooleanFieldConfiguration config) {
var value = config.GetValue(_instance);
_fields[config.FieldName] = new BooleanField(config.FieldName, value, _objectTraverse);
}
public void CaptureFrom() {
foreach (var field in _fields.Values) {
field.CaptureOriginal();