using Kryz.CharacterStats; using Kryz.CharacterStats.Examples; using System.Collections; using System.Collections.Generic; using UnityEngine; [CreateAssetMenu(fileName = "InstantEffect", menuName = "RiftMayhem/AbilitySystem/Effects/Instant Effect", order = 1)] public class InstantValueEffect : BaseEffect { public float baseValue; public DamageType damageType = DamageType.Attack; [Header("Optional Modifiers for damage / healing based on target")] public float AlliedTargetMultiplier = 1f; public float EnemyTargetMultiplier = 1f; public float FriendlyNPCTargetMultiplier = 1f; [Header("Optional apply this to class resource instead:")] public bool applyToClassResourceInstead = false; public bool applyToSelfResourceInsteadOfHit = false; Health targetHealth; ClassResource classResource; private float finalValue; private EntityEventBroker userBroker; private CharacterStats stats; private DamageOutputModifierEffectInstance damageOutputModifier; private bool isCrit; public override void ApplyEffect(Taggable user, List targets, BaseAbility source) { if (user == null) return; userBroker = user.GetComponent(); foreach (Taggable target in targets) { if (target == null) continue; //Debug.Log($"Applied instant effect of {GetCorrectValueSign(user, target)} to target {target.name}"); if (applyToClassResourceInstead) { /*if (user.IsMinion()) return; if (applyToSelfResourceInsteadOfHit) { classResource = user.GetComponent(); if (classResource != null) classResource.ChangeValue(GetCorrectValueSign(user, user)); } else { classResource = target.GetComponent(); if (classResource != null) classResource.ChangeValue(GetCorrectValueSign(user, target)); }*/ } else { targetHealth = target.GetComponent(); if (targetHealth != null) { ApplyEffect(user, target, source, targets.Count); //targetHealth.ChangeValue(GetCorrectValueSign(user, target), (int)damageType, isCrit); } //targetHealth.ChangeValue(target.targetTag == TargettingTag.Enemy ? -value : value); } } } private void ApplyEffect(Taggable user, Taggable target, BaseAbility source, int totalTargetsHit) { if (user == null) { Debug.LogError("ApplyEffect user is null"); return; } if (target == null) { Debug.LogError("ApplyEffect target is null"); return; } if (user.AlliedTagsContains(target.targetTag)) { HealArgs args = CObjectPool.Get(); args.source = source; args.effect = this; args.user = user; args.target = target; args.currentValue = baseValue; args.outgoingAccumulator = 0f; args.incomingAccumulator= 0f; args.applicationMethod = EffectApplicationMethod.Hit; args.isCrit = false; args.totalTargetsHit = totalTargetsHit; userBroker.OnOutgoingHeal.Invoke(args); userBroker.OnOutgoingHealProcessed.Invoke(args); targetHealth.ApplyHeal(args); CObjectPool.Release(args); } else { DamageArgs args = CObjectPool.Get(); args.sourceAbility = source; args.sourceEffect = this; args.user = user; args.target = target; args.currentValue = -baseValue; args.outgoingAccumulator = 0f; args.incomingAccumulator = 0f; args.damageType = damageType; args.applicationMethod = EffectApplicationMethod.Hit; args.isCrit = false; args.totalTargetsHit = totalTargetsHit; args.targetDead = false; userBroker.OnOutgoingDamage.Invoke(args); userBroker.OnOutgoingDamageProcessed.Invoke(args); targetHealth.ApplyDamage(args); CObjectPool.Release(args); } } private float GetCorrectValueSign(Taggable user, Taggable target) { if (user == null) return 0; if (target == null) return 0; stats = user.GetComponent(); damageOutputModifier = user.GetComponent(); GetFinalValue(stats, damageOutputModifier); //return user.targetTag.AlliedTags.Contains(target.targetTag) ? (finalValue * AlliedTargetMultiplier) : (-finalValue * EnemyTargetMultiplier); if (user.AlliedTagsContains(target.targetTag)) { if (target.IsFriendlyNPC()) return (finalValue * FriendlyNPCTargetMultiplier); else return (finalValue * AlliedTargetMultiplier); } else return (-finalValue * EnemyTargetMultiplier); } private void GetFinalValue(CharacterStats stats, DamageOutputModifierEffectInstance damageOutputModifier) { finalValue = baseValue; if (stats != null) { foreach (var statInfluence in influencingStats) { if (stats.primaryStatsDictionary.TryGetValue(statInfluence.statTag.name.ToLower(), out CharacterStat stat)) { finalValue += stat.Value * statInfluence.percentInfluence; } else if (stats.secondaryStatsDictionary.TryGetValue(statInfluence.statTag.name.ToLower(), out CharacterStat secondaryStat)) { finalValue += secondaryStat.Value * statInfluence.percentInfluence; } if (statInfluence.statTag.name.ToLower().Contains("Attack")) damageType = DamageType.Attack; else if (statInfluence.statTag.name.ToLower().Contains("Spell")) damageType = DamageType.Spell; } } //Debug.Log("FinalValue = " + finalValue + " dmgType = " + damageType); if (IsCrit(stats) && !applyToClassResourceInstead) { finalValue *= (1 + stats.GetStat("critdamage").Value / 100f); isCrit = true; //Debug.Log("FinalValue IsCrit = " + finalValue + " dmgType = " + damageType); } else isCrit = false; finalValue = damageOutputModifier.ModifyDamageOutput(finalValue); } private bool IsCrit(CharacterStats stats) { return MathHelpers.RollChancePercent(stats.GetStat("critchance").Value); //return Random.Range(0, 100) < stats.CritChance.Value; } }