private Change CalcChange(ModificationParameter parameter, float amount, CharacterState sourceCharacter, ISubSpellHandler subSpell) { // Zero-change if (parameter == ModificationParameter.None || Mathf.Abs(amount) < 1e-6) { return new Change { Parameter = ModificationParameter.None, Amount = 0 } } ; if (parameter == ModificationParameter.HpFlat || parameter == ModificationParameter.HpMult) { var targetHp = _hp; if (parameter == ModificationParameter.HpFlat) { targetHp += amount; } if (parameter == ModificationParameter.HpMult) { targetHp *= amount; } targetHp = Mathf.Min(targetHp, MaxHealth); var delta = targetHp - _hp; // If taking damage if (delta < 0) { // If the damage comes from spell, amplify it buy character source damage multiplier if (subSpell != null && sourceCharacter != null) { // Damage amplification delta *= sourceCharacter.SpellDamageMultiplier; #if DEBUG_COMBAT _combatLog.Log( $"Receiving in total <b>{-delta}</b> spell multiplied ({100 * sourceCharacter.SpellDamageMultiplier}%) damage from <b>{sourceCharacter.name}</b> " + $"from spell <b>{subSpell.Spell.name}</b>"); #endif // Lifesteal // TODO: Shouldn't we apply lifesteal afterwards? var lifeStealFactor = subSpell.Spell.LifeSteal.GetValue(subSpell.Stacks); var hpStolen = -delta * lifeStealFactor; if (hpStolen > 0) { #if DEBUG_COMBAT _combatLog.Log( $"Returning <b>{hpStolen}</b> hp back to <b>{sourceCharacter.name}</b> " + $"because spell <b>{subSpell.Spell.name}</b> has <b>{100 * lifeStealFactor}%</b> lifesteal"); #endif sourceCharacter.ApplyModifier(ModificationParameter.HpFlat, hpStolen, this, subSpell); } } } // Notice that we are returning HpFlat even if the original modifier was HpMult. // Because there was some additional modifer applied to damage (if any) return(new Change { Parameter = ModificationParameter.HpFlat, Amount = delta }); } switch (parameter) { case ModificationParameter.CritChanceFlat: case ModificationParameter.EvasionChanceFlat: return(new Change { Parameter = parameter, Amount = 1 - amount }); } // Default change computation for stats like speed and other relatively simple stats return(new Change { Parameter = parameter, Amount = amount }); }