Enhance ObjectFieldMultiplier with flexible field configuration and selective application

This commit is contained in:
2025-02-24 08:44:18 +01:00
parent 13610a301a
commit edc8fd5a5b

View File

@@ -8,12 +8,36 @@ namespace TerraTech {
/// Represents a field that can be multiplied by a configurable value /// Represents a field that can be multiplied by a configurable value
/// </summary> /// </summary>
/// <typeparam name="TValue">The type of the field value</typeparam> /// <typeparam name="TValue">The type of the field value</typeparam>
public class FieldConfiguration<TValue> {
public string FieldName { get; }
public ConfigEntry<TValue> DefaultMultiplier { get; }
public Func<object, ConfigEntry<TValue>> ConditionalMultiplier { get; }
public FieldConfiguration(string fieldName, ConfigEntry<TValue> defaultMultiplier) {
FieldName = fieldName;
DefaultMultiplier = defaultMultiplier;
}
public FieldConfiguration(string fieldName, ConfigEntry<TValue> defaultMultiplier,
Func<object, ConfigEntry<TValue>> conditionalMultiplier) {
FieldName = fieldName;
DefaultMultiplier = defaultMultiplier;
ConditionalMultiplier = conditionalMultiplier;
}
public ConfigEntry<TValue> GetMultiplier(object instance) {
return ConditionalMultiplier?.Invoke(instance) ?? DefaultMultiplier;
}
}
public class MultipliedField<TValue> { public class MultipliedField<TValue> {
private readonly string _fieldName; private readonly string _fieldName;
private readonly ConfigEntry<TValue> _multiplier; private readonly ConfigEntry<TValue> _multiplier;
private readonly Traverse _parentTraverse; private readonly Traverse _parentTraverse;
private TValue _originalValue; private TValue _originalValue;
public string FieldName => _fieldName;
public MultipliedField(string fieldName, ConfigEntry<TValue> multiplier, Traverse parentTraverse) { public MultipliedField(string fieldName, ConfigEntry<TValue> multiplier, Traverse parentTraverse) {
_fieldName = fieldName; _fieldName = fieldName;
_multiplier = multiplier; _multiplier = multiplier;
@@ -99,32 +123,43 @@ namespace TerraTech {
/// </summary> /// </summary>
/// <typeparam name="T">The type of the object being managed</typeparam> /// <typeparam name="T">The type of the object being managed</typeparam>
public class MultipliedObject<T> { public class MultipliedObject<T> {
private readonly T _instance;
private readonly Traverse _objectTraverse; private readonly Traverse _objectTraverse;
private readonly List<MultipliedField<float>> _fields; private readonly Dictionary<string, MultipliedField<float>> _fields;
public MultipliedObject(T instance) { public MultipliedObject(T instance) {
_instance = instance;
_objectTraverse = Traverse.Create(instance); _objectTraverse = Traverse.Create(instance);
_fields = new List<MultipliedField<float>>(); _fields = new Dictionary<string, MultipliedField<float>>();
} }
public void AddField(string fieldName, ConfigEntry<float> multiplier) { public void AddField(FieldConfiguration<float> config) {
_fields.Add(new MultipliedField<float>(fieldName, multiplier, _objectTraverse)); var multiplier = config.GetMultiplier(_instance);
_fields[config.FieldName] = new MultipliedField<float>(config.FieldName, multiplier, _objectTraverse);
} }
public void CaptureFrom() { public void CaptureFrom() {
foreach (var field in _fields) { foreach (var field in _fields.Values) {
field.CaptureOriginal(); field.CaptureOriginal();
} }
} }
public void ApplyTo() { public void ApplyTo(IEnumerable<string> fieldNames = null) {
foreach (var field in _fields) { var fieldsToApply = fieldNames != null
? fieldNames.Where(name => _fields.ContainsKey(name)).Select(name => _fields[name])
: _fields.Values;
foreach (var field in fieldsToApply) {
field.Apply(); field.Apply();
} }
} }
public void RestoreTo() { public void RestoreTo(IEnumerable<string> fieldNames = null) {
foreach (var field in _fields) { var fieldsToRestore =
fieldNames != null ? fieldNames.Where(name => _fields.ContainsKey(name)).Select(name => _fields[name])
: _fields.Values;
foreach (var field in fieldsToRestore) {
field.Restore(); field.Restore();
} }
} }
@@ -132,7 +167,7 @@ namespace TerraTech {
public void LogValues(string prefix) { public void LogValues(string prefix) {
if (!Main.debug.Value) if (!Main.debug.Value)
return; return;
foreach (var field in _fields) { foreach (var field in _fields.Values) {
field.LogValue(prefix); field.LogValue(prefix);
} }
} }
@@ -182,25 +217,25 @@ namespace TerraTech {
} }
} }
public void ApplyAll() { public void ApplyAll(IEnumerable<string> fieldNames = null) {
if (Main.debug.Value) if (Main.debug.Value)
Console.WriteLine("Modifying {0} {1}", _managedObjects.Count, typeof(T).Name); Console.WriteLine("Modifying {0} {1}", _managedObjects.Count, typeof(T).Name);
foreach (var instance in _managedObjects.Keys) { foreach (var instance in _managedObjects.Keys) {
RestoreTo(instance); RestoreTo(instance, fieldNames);
ApplyTo(instance); ApplyTo(instance, fieldNames);
} }
} }
private void ApplyTo(T instance) { public void ApplyTo(T instance, IEnumerable<string> fieldNames = null) {
MultipliedObject<T> obj; MultipliedObject<T> obj;
if (_managedObjects.TryGetValue(instance, out obj)) if (_managedObjects.TryGetValue(instance, out obj))
obj.ApplyTo(); obj.ApplyTo(fieldNames);
} }
private void RestoreTo(T instance) { public void RestoreTo(T instance, IEnumerable<string> fieldNames = null) {
MultipliedObject<T> obj; MultipliedObject<T> obj;
if (_managedObjects.TryGetValue(instance, out obj)) if (_managedObjects.TryGetValue(instance, out obj))
obj.RestoreTo(); obj.RestoreTo(fieldNames);
} }
} }
} }