using Kryz.CharacterStats; using Kryz.CharacterStats.Examples; using UnityEngine; public class BasicStatModifierCalculator : BrokerInterceptor { float percentStatMitigation; float reducedDamage; protected override void Awake() { base.Awake(); broker.OnOutgoingDamage.Subscribe(CalculateDamageModsBasedOnStats, GameConstants.BrokerEventPriority.BasicStatAmplification); broker.OnIncomingDamage.Subscribe(HandleStatMitigation, GameConstants.BrokerEventPriority.BasicStatMitigation); } private void CalculateDamageModsBasedOnStats(DamageArgs args) { float finalValue = args.currentValue; if (stats == null) { Debug.LogError("character stat influence calculator: stats null"); return; } for (int i = 0; i < args.sourceEffect.influencingStats.Count; i++) { if (stats.primaryStatsDictionary.TryGetValue(args.sourceEffect.influencingStats[i].statTag.name.ToLower(), out CharacterStat stat)) { finalValue += stat.Value * args.sourceEffect.influencingStats[i].percentInfluence; } else if (stats.secondaryStatsDictionary.TryGetValue(args.sourceEffect.influencingStats[i].statTag.name.ToLower(), out CharacterStat secondaryStat)) { finalValue += secondaryStat.Value * args.sourceEffect.influencingStats[i].percentInfluence; } } if (IsCrit(stats)) { finalValue *= (1 + stats.GetStat("critdamage").Value / 100f); args.isCrit = true; } else args.isCrit = false; args.currentValue = finalValue; } private void HandleStatMitigation(DamageArgs args) { if (args.currentValue >= 0) return; float finalValue = args.currentValue; switch (GetCorrectMitigationType(args)) { case DamageType.Attack: default: { percentStatMitigation = Mathf.Clamp((stats.GetStat("armor").Value * GameConstants.CharacterStatsBalancing.PercentArmorIntoDamageReduction), 0, GameConstants.CharacterStatsBalancing.MaximumPercentDamageReductionFromArmor); } break; case DamageType.Spell: { percentStatMitigation = Mathf.Clamp((stats.GetStat("magicresistance").Value * GameConstants.CharacterStatsBalancing.PercentMagicResistanceIntoDamageReduction), 0, GameConstants.CharacterStatsBalancing.MaximumPercentDamageReductionFromMagicResistance); } break; } reducedDamage = args.currentValue * percentStatMitigation; finalValue += Mathf.Abs(reducedDamage); //Debug.Log(gameObject.name + " receiving dmg = " + incomingValue + $" after mitigations from {(dmgType == DamageType.Attack ? nameof(character.Armor) : nameof(character.MagicResistance))}"); if (finalValue > 0) //avoid damage ultra mitigated turning into healing finalValue = 0; args.currentValue = finalValue; } private DamageType GetCorrectMitigationType(DamageArgs args) { switch (args.damageType) { default: case DamageType.Physical: case DamageType.Attack: return DamageType.Attack; case DamageType.Spell: case DamageType.Fire: case DamageType.Cold: case DamageType.Lightning: case DamageType.Mystic: case DamageType.Poison: case DamageType.Shadow: return DamageType.Spell; } } private bool IsCrit(CharacterStats stats) { return MathHelpers.RollChancePercent(stats.GetStat("critchance").Value); //return Random.Range(0, 100) < stats.CritChance.Value; } }