ability modifier + runtime ability instance with source control

This commit is contained in:
Pedro Gomes 2025-06-15 21:34:34 +01:00
parent 00b86fa97c
commit d7eb479da7
2 changed files with 191 additions and 9 deletions

View File

@ -1,5 +1,5 @@
// ============================================================================
// 2. ABILITY MODIFIER SYSTEM
// 2. ABILITY MODIFIER SYSTEM - Enhanced with Source Tracking
// ============================================================================
using UnityEngine;
@ -30,31 +30,118 @@ public class AbilityModifier
public string description = "";
public float duration = -1f; // -1 = permanent
// Factory methods for common modifiers
public static AbilityModifier CreateDamageBoost(float multiplier, string name = "Damage Boost")
// Source tracking - matches StatModifier pattern
public readonly object Source;
// ========================================================================
// CONSTRUCTORS - Multiple overloads like StatModifier
// ========================================================================
// Default constructor (for serialization)
public AbilityModifier()
{
return new AbilityModifier
Source = null;
}
// Constructor with source
public AbilityModifier(object source)
{
Source = source;
}
// Copy constructor with new source
public AbilityModifier(AbilityModifier original, object newSource)
{
// Copy all values
manaCostMultiplier = original.manaCostMultiplier;
manaCostFlat = original.manaCostFlat;
healthCostMultiplier = original.healthCostMultiplier;
healthCostFlat = original.healthCostFlat;
classResourceCostMultiplier = original.classResourceCostMultiplier;
classResourceCostFlat = original.classResourceCostFlat;
castTimeMultiplier = original.castTimeMultiplier;
cooldownMultiplier = original.cooldownMultiplier;
damageMultiplier = original.damageMultiplier;
healingMultiplier = original.healingMultiplier;
durationMultiplier = original.durationMultiplier;
rangeMultiplier = original.rangeMultiplier;
modifierName = original.modifierName;
description = original.description;
duration = original.duration;
// Set new source
Source = newSource;
}
// ========================================================================
// FACTORY METHODS - Enhanced with source support
// ========================================================================
public static AbilityModifier CreateDamageBoost(float multiplier, string name = "Damage Boost", object source = null)
{
var modifier = new AbilityModifier(source)
{
damageMultiplier = multiplier,
modifierName = name
};
return modifier;
}
public static AbilityModifier CreateCooldownReduction(float reductionPercent, string name = "Cooldown Reduction")
public static AbilityModifier CreateCooldownReduction(float reductionPercent, string name = "Cooldown Reduction", object source = null)
{
return new AbilityModifier
var modifier = new AbilityModifier(source)
{
cooldownMultiplier = 1f - (reductionPercent / 100f),
modifierName = name
};
return modifier;
}
public static AbilityModifier CreateManaCostReduction(float reductionPercent, string name = "Mana Cost Reduction")
public static AbilityModifier CreateManaCostReduction(float reductionPercent, string name = "Mana Cost Reduction", object source = null)
{
return new AbilityModifier
var modifier = new AbilityModifier(source)
{
manaCostMultiplier = 1f - (reductionPercent / 100f),
modifierName = name
};
return modifier;
}
public static AbilityModifier CreateCastTimeReduction(float reductionPercent, string name = "Cast Time Reduction", object source = null)
{
var modifier = new AbilityModifier(source)
{
castTimeMultiplier = 1f - (reductionPercent / 100f),
modifierName = name
};
return modifier;
}
public static AbilityModifier CreateHealingBoost(float multiplier, string name = "Healing Boost", object source = null)
{
var modifier = new AbilityModifier(source)
{
healingMultiplier = multiplier,
modifierName = name
};
return modifier;
}
// ========================================================================
// UTILITY METHODS
// ========================================================================
public bool HasSource(object source)
{
return Source != null && Source.Equals(source);
}
public override string ToString()
{
string sourceStr = Source?.ToString() ?? "No Source";
return $"{modifierName} (Source: {sourceStr})";
}
}

View File

@ -2,8 +2,10 @@
// RUNTIME ABILITY WRAPPER - DROP-IN REPLACEMENT FOR BaseAbility
// ============================================================================
using Kryz.CharacterStats.Examples;
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
// ============================================================================
@ -163,7 +165,7 @@ public class RuntimeAbilityInstance
}
// ========================================================================
// MODIFIER SYSTEM
// ENHANCED MODIFIER SYSTEM - Source-Aware Management
// ========================================================================
public void AddModifier(AbilityModifier modifier)
@ -172,18 +174,86 @@ public class RuntimeAbilityInstance
RecalculateModifiedValues();
}
public void AddModifier(AbilityModifier modifier, object source)
{
// Create a copy with the specified source
var modifierWithSource = new AbilityModifier(modifier, source);
activeModifiers.Add(modifierWithSource);
RecalculateModifiedValues();
}
public void RemoveModifier(AbilityModifier modifier)
{
activeModifiers.Remove(modifier);
RecalculateModifiedValues();
}
public bool RemoveAllModifiersFromSource(object source)
{
int numRemovals = activeModifiers.RemoveAll(mod => mod.Source != null && mod.Source.Equals(source));
if (numRemovals > 0)
{
RecalculateModifiedValues();
return true;
}
return false;
}
public bool HasModifiersFromSource(object source)
{
return activeModifiers.Any(mod => mod.Source != null && mod.Source.Equals(source));
}
public List<AbilityModifier> GetModifiersFromSource(object source)
{
return activeModifiers.Where(mod => mod.Source != null && mod.Source.Equals(source)).ToList();
}
public void RemoveAllModifiers()
{
activeModifiers.Clear();
RecalculateModifiedValues();
}
// ========================================================================
// CONVENIENCE METHODS - Common source-based operations
// ========================================================================
// Add modifier from equipment
public void AddEquipmentModifier(AbilityModifier modifier, EquippableItem equipment)
{
AddModifier(modifier, equipment);
}
// Add modifier from buff/effect
public void AddEffectModifier(AbilityModifier modifier, BaseEffect effect)
{
AddModifier(modifier, effect);
}
// Add modifier from skill/talent
public void AddSkillModifier(AbilityModifier modifier, string skillSource)
{
AddModifier(modifier, skillSource);
}
// Remove equipment modifiers when unequipping
public void RemoveEquipmentModifiers(EquippableItem equipment)
{
RemoveAllModifiersFromSource(equipment);
}
// Remove effect modifiers when effect expires
public void RemoveEffectModifiers(BaseEffect effect)
{
RemoveAllModifiersFromSource(effect);
}
// ========================================================================
// MODIFIER CALCULATION
// ========================================================================
private void RecalculateModifiedValues()
{
// Start with original values
@ -263,6 +333,31 @@ public class RuntimeAbilityInstance
}
}
// ========================================================================
// DEBUG/UTILITY METHODS
// ========================================================================
public void PrintActiveModifiers()
{
Debug.Log($"=== Active Modifiers for {displayName} ===");
foreach (var modifier in activeModifiers)
{
string sourceStr = modifier.Source?.ToString() ?? "No Source";
Debug.Log($"- {modifier.modifierName} (Source: {sourceStr})");
}
}
public Dictionary<object, int> GetModifierCountBySource()
{
var counts = new Dictionary<object, int>();
foreach (var modifier in activeModifiers)
{
var source = modifier.Source ?? "No Source";
counts[source] = counts.ContainsKey(source) ? counts[source] + 1 : 1;
}
return counts;
}
// ========================================================================
// UTILITY METHODS
// ========================================================================