RiftMayhem/Assets/Scripts/EntityBroker/BasicStatModifierCalculator.cs

109 lines
3.8 KiB
C#

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;
}
}