diff --git a/Projects/TerraTech/TerraTech/ObjectFieldMultiplier.cs b/Projects/TerraTech/TerraTech/ObjectFieldMultiplier.cs index a67c5d0..3a62de2 100644 --- a/Projects/TerraTech/TerraTech/ObjectFieldMultiplier.cs +++ b/Projects/TerraTech/TerraTech/ObjectFieldMultiplier.cs @@ -5,43 +5,51 @@ using BepInEx.Configuration; using HarmonyLib; namespace TerraTech { + public interface IMultipliedField { + void CaptureOriginal(); + void Apply(); + void Restore(); + void LogValue(string prefix); + } + /// /// Represents a field that can be multiplied by a configurable value /// - /// The type of the field value - public class FieldConfiguration { + /// The type of the field value + /// The type of the multiplier + public class FieldConfiguration { private string _fieldName; - private ConfigEntry _defaultMultiplier; - private Func> _conditionalMultiplier; + private ConfigEntry _defaultMultiplier; + private Func> _conditionalMultiplier; public string FieldName { get { return _fieldName; } set { _fieldName = value; } } - public ConfigEntry DefaultMultiplier { + public ConfigEntry DefaultMultiplier { get { return _defaultMultiplier; } set { _defaultMultiplier = value; } } - public Func> ConditionalMultiplier { + public Func> ConditionalMultiplier { get { return _conditionalMultiplier; } set { _conditionalMultiplier = value; } } - public FieldConfiguration(string fieldName, ConfigEntry defaultMultiplier) { + public FieldConfiguration(string fieldName, ConfigEntry defaultMultiplier) { _fieldName = fieldName; _defaultMultiplier = defaultMultiplier; } - public FieldConfiguration(string fieldName, ConfigEntry defaultMultiplier, - Func> conditionalMultiplier) { + public FieldConfiguration(string fieldName, ConfigEntry defaultMultiplier, + Func> conditionalMultiplier) { _fieldName = fieldName; _defaultMultiplier = defaultMultiplier; _conditionalMultiplier = conditionalMultiplier; } - public ConfigEntry GetMultiplier(object instance) { + public ConfigEntry GetMultiplier(object instance) { if (_conditionalMultiplier == null) { return _defaultMultiplier; } @@ -49,17 +57,17 @@ namespace TerraTech { } } - public class MultipliedField { + public class MultipliedField : IMultipliedField { private readonly string _fieldName; - private readonly ConfigEntry _multiplier; + private readonly ConfigEntry _multiplier; private readonly Traverse _parentTraverse; - private TValue _originalValue; + private TField _originalValue; public string FieldName { get { return _fieldName; } } - public MultipliedField(string fieldName, ConfigEntry multiplier, Traverse parentTraverse) { + public MultipliedField(string fieldName, ConfigEntry multiplier, Traverse parentTraverse) { _fieldName = fieldName; _multiplier = multiplier; _parentTraverse = parentTraverse; @@ -69,9 +77,16 @@ namespace TerraTech { string.Format("Field {0} does not exist on {1}", fieldName, parentTraverse)); } - // Verify TValue is a numeric type - if (!IsNumericType(typeof(TValue))) { - throw new ArgumentException(string.Format("Type {0} must be a numeric type", typeof(TValue).Name)); + // Verify TField is a numeric type + if (!IsNumericType(typeof(TField))) { + throw new ArgumentException( + string.Format("Field type {0} must be a numeric type", typeof(TField).Name)); + } + + // Verify TMul is a numeric type + if (!IsNumericType(typeof(TMul))) { + throw new ArgumentException( + string.Format("Multiplier type {0} must be a numeric type", typeof(TMul).Name)); } } @@ -81,21 +96,23 @@ namespace TerraTech { type == typeof(float) || type == typeof(double) || type == typeof(decimal); } - private static TValue MultiplyValues(TValue a, TValue b) { - // Convert to double for the multiplication - double result = Convert.ToDouble(a) * Convert.ToDouble(b); - // Convert back to TValue - return (TValue)Convert.ChangeType(result, typeof(TValue)); + private TField MultiplyValues(TField fieldValue, TMul multiplierValue) { + // Convert both to double for the multiplication + double fieldDouble = Convert.ToDouble(fieldValue); + double multiplierDouble = Convert.ToDouble(multiplierValue); + double result = fieldDouble * multiplierDouble; + // Convert back to TField + return (TField)Convert.ChangeType(result, typeof(TField)); } - public TValue GetValue() { + public TField GetValue() { var value = _parentTraverse.Field(_fieldName).GetValue(); if (value == null) throw new InvalidOperationException(string.Format("Field {0} returned null", _fieldName)); - return (TValue)value; + return (TField)value; } - public void SetValue(TValue value) { + public void SetValue(TField value) { _parentTraverse.Field(_fieldName).SetValue(value); var verifyValue = GetValue(); if (!verifyValue.Equals(value)) @@ -146,17 +163,18 @@ 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) { + public void AddField(FieldConfiguration config) { var multiplier = config.GetMultiplier(_instance); - _fields[config.FieldName] = new MultipliedField(config.FieldName, multiplier, _objectTraverse); + _fields[config.FieldName] = + new MultipliedField(config.FieldName, multiplier, _objectTraverse); } public void CaptureFrom() { @@ -166,28 +184,16 @@ namespace TerraTech { } public void ApplyTo(IEnumerable fieldNames = null) { - IEnumerable> fieldsToApply; - if (fieldNames != null) { - fieldsToApply = fieldNames.Where(name => _fields.ContainsKey(name)).Select(name => _fields[name]); - } else { - fieldsToApply = _fields.Values; - } - - foreach (var field in fieldsToApply) { - field.Apply(); + IEnumerable fieldsToApply = fieldNames ?? _fields.Keys; + foreach (var fieldName in fieldsToApply.Where(name => _fields.ContainsKey(name))) { + _fields[fieldName].Apply(); } } public void RestoreTo(IEnumerable fieldNames = null) { - IEnumerable> fieldsToRestore; - if (fieldNames != null) { - fieldsToRestore = fieldNames.Where(name => _fields.ContainsKey(name)).Select(name => _fields[name]); - } else { - fieldsToRestore = _fields.Values; - } - - foreach (var field in fieldsToRestore) { - field.Restore(); + IEnumerable fieldsToRestore = fieldNames ?? _fields.Keys; + foreach (var fieldName in fieldsToRestore.Where(name => _fields.ContainsKey(name))) { + _fields[fieldName].Restore(); } } @@ -247,7 +253,8 @@ namespace TerraTech { public void ApplyAll(IEnumerable fieldNames = null) { if (Main.debug.Value) Console.WriteLine("Modifying {0} {1}", _managedObjects.Count, typeof(T).Name); - foreach (var instance in _managedObjects.Keys) { + foreach (var instance in _managedObjects.Keys + .ToList()) { // ToList to avoid modification during enumeration RestoreTo(instance, fieldNames); ApplyTo(instance, fieldNames); }