From dbeb55e2aa78cb3a8b4bc36689782f9223d07c87 Mon Sep 17 00:00:00 2001 From: PhatPhuckDave Date: Mon, 24 Feb 2025 10:10:21 +0100 Subject: [PATCH] Add BooleanField for configurable boolean field settings --- .../TerraTech/ModuleWeaponGunManager.cs | 4 +- .../TerraTech/ObjectFieldMultiplier.cs | 121 +++++++++++++++++- 2 files changed, 119 insertions(+), 6 deletions(-) diff --git a/Projects/TerraTech/TerraTech/ModuleWeaponGunManager.cs b/Projects/TerraTech/TerraTech/ModuleWeaponGunManager.cs index f7dc403..0a3433a 100644 --- a/Projects/TerraTech/TerraTech/ModuleWeaponGunManager.cs +++ b/Projects/TerraTech/TerraTech/ModuleWeaponGunManager.cs @@ -59,8 +59,8 @@ namespace TerraTech { } private static void ConfigureManager(MultipliedObject obj) { - // obj.AddField(new FieldConfiguration("m_SeekingRounds", seekingRoundsAll)); - // obj.AddField(new FieldConfiguration("m_ResetBurstOnInterrupt", resetBurstOnInterruptAll)); + obj.AddBooleanField(new BooleanFieldConfiguration("m_SeekingRounds", seekingRoundsAll)); + obj.AddBooleanField(new BooleanFieldConfiguration("m_ResetBurstOnInterrupt", resetBurstOnInterruptAll)); obj.AddField(new FieldConfiguration("m_BurstCooldown", burstCooldownMultiplier)); obj.AddField(new FieldConfiguration("m_BurstShotCount", burstShotCountMultiplier)); obj.AddField(new FieldConfiguration("m_ShotCooldown", shotCooldownMultiplier)); diff --git a/Projects/TerraTech/TerraTech/ObjectFieldMultiplier.cs b/Projects/TerraTech/TerraTech/ObjectFieldMultiplier.cs index 3a62de2..f142bf2 100644 --- a/Projects/TerraTech/TerraTech/ObjectFieldMultiplier.cs +++ b/Projects/TerraTech/TerraTech/ObjectFieldMultiplier.cs @@ -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 : IMultipliedField { + public class MultipliedField : IFieldModifier { private readonly string _fieldName; private readonly ConfigEntry _multiplier; private readonly Traverse _parentTraverse; @@ -156,6 +156,114 @@ namespace TerraTech { } } + public class BooleanFieldConfiguration { + private string _fieldName; + private ConfigEntry _value; + private Func> _conditionalValue; + + public string FieldName { + get { return _fieldName; } + set { _fieldName = value; } + } + + public ConfigEntry Value { + get { return _value; } + set { _value = value; } + } + + public Func> ConditionalValue { + get { return _conditionalValue; } + set { _conditionalValue = value; } + } + + public BooleanFieldConfiguration(string fieldName, ConfigEntry value) { + _fieldName = fieldName; + _value = value; + } + + public BooleanFieldConfiguration(string fieldName, ConfigEntry value, + Func> conditionalValue) { + _fieldName = fieldName; + _value = value; + _conditionalValue = conditionalValue; + } + + public ConfigEntry GetValue(object instance) { + if (_conditionalValue == null) { + return _value; + } + return _conditionalValue(instance); + } + } + + public class BooleanField : IFieldModifier { + private readonly string _fieldName; + private readonly ConfigEntry _value; + private readonly Traverse _parentTraverse; + private bool _originalValue; + + public string FieldName { + get { return _fieldName; } + } + + public BooleanField(string fieldName, ConfigEntry 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); + } + } + /// /// Represents an object with multiple fields that can be multiplied /// @@ -163,12 +271,12 @@ namespace TerraTech { public class MultipliedObject { private readonly T _instance; private readonly Traverse _objectTraverse; - private readonly Dictionary _fields; + private readonly Dictionary _fields; public MultipliedObject(T instance) { _instance = instance; _objectTraverse = Traverse.Create(instance); - _fields = new Dictionary(); + _fields = new Dictionary(); } public void AddField(FieldConfiguration config) { @@ -177,6 +285,11 @@ namespace TerraTech { new MultipliedField(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();