/// <summary> /// Heals this unit and sends the corresponding animation (healer might be null) /// </summary> /// <param name="effect">The effect of the spell that triggered the healing (or null)</param> /// <param name="healer">The object that heals this Unit (or null)</param> /// <param name="value">The amount to be healed</param> public void Heal(Unit healer, int value, SpellEffect effect) { var critChance = 0f; var crit = false; int overheal = 0; if (effect != null) { var oldVal = value; if (healer != null) { if (effect.IsPeriodic) { // add periodic boni if (healer is Character) { value = ((Character)healer).PlayerSpells.GetModifiedInt(SpellModifierType.PeriodicEffectValue, effect.Spell, value); } } else { // add healing mods (spell power for healing) value = healer.AddHealingModsToAction(value, effect, effect.Spell.Schools[0]); } } if (this is Character) { value += (int) ((oldVal*((Character) this).HealingTakenModPct)/100); } critChance = GetSpellCritChance((DamageSchool) effect.Spell.SchoolMask)*100; // do a critcheck if (!effect.Spell.AttributesExB.HasFlag(SpellAttributesExB.CannotCrit) && critChance != 0) { var roll = Utility.Random(1f, 10001); if (roll <= critChance) { value = (int) (value*(SpellHandler.SpellCritBaseFactor + GetIntMod(StatModifierInt.CriticalHealValuePct))); crit = true; } } } if (value > 0) { value = (int)(value * Utility.Random(0.95f, 1.05f)); if (Health + value > MaxHealth) { overheal = (Health + value) - MaxHealth; value = (MaxHealth - Health); } Health += value; value += overheal; CombatLogHandler.SendHealLog(healer, this, effect != null ? effect.Spell.Id : 0, value, crit, overheal); } if (healer != null) { var action = new HealAction { Attacker = (Unit)healer, Victim = this, Spell = effect != null ? effect.Spell : null, IsCritical = crit, Value = value }; healer.Proc(ProcTriggerFlags.HealOther, this, action, true); Proc(ProcTriggerFlags.Heal, healer, action, false); OnHeal(healer, effect, value); } }