This is the function that handles it. Maybe somebody else will see something obviously wrong.
Code:
int32 Mob::GetActSpellDamage(uint16 spell_id, int32 value, Mob* target) {
if (spells[spell_id].targettype == ST_Self)
return value;
if (IsNPC())
value += value*CastToNPC()->GetSpellFocusDMG()/100;
bool Critical = false;
int32 value_BaseEffect = 0;
int chance = 0;
value_BaseEffect = value + (value*GetFocusEffect(focusFcBaseEffects, spell_id)/100);
// Need to scale HT damage differently after level 40! It no longer scales by the constant value in the spell file. It scales differently, instead of 10 more damage per level, it does 30 more damage per level. So we multiply the level minus 40 times 20 if they are over level 40.
if ((spell_id == SPELL_HARM_TOUCH || spell_id == SPELL_HARM_TOUCH2 || spell_id == SPELL_IMP_HARM_TOUCH ) && GetLevel() > 40)
value -= (GetLevel() - 40) * 20;
//This adds the extra damage from the AA Unholy Touch, 450 per level to the AA Improved Harm TOuch.
if (spell_id == SPELL_IMP_HARM_TOUCH && IsClient()) //Improved Harm Touch
value -= GetAA(aaUnholyTouch) * 450; //Unholy Touch
chance = RuleI(Spells, BaseCritChance); //Wizard base critical chance is 2% (Does not scale with level)
chance += itembonuses.CriticalSpellChance + spellbonuses.CriticalSpellChance + aabonuses.CriticalSpellChance;
chance += itembonuses.FrenziedDevastation + spellbonuses.FrenziedDevastation + aabonuses.FrenziedDevastation;
//Crtical Hit Calculation pathway
if (chance > 0 || (IsClient() && GetClass() == WIZARD && GetLevel() >= RuleI(Spells, WizCritLevel))) {
int32 ratio = RuleI(Spells, BaseCritRatio); //Critical modifier is applied from spell effects only. Keep at 100 for live like criticals.
//Improved Harm Touch is a guaranteed crit if you have at least one level of SCF.
if (spell_id == SPELL_IMP_HARM_TOUCH && IsClient() && (GetAA(aaSpellCastingFury) > 0) && (GetAA(aaUnholyTouch) > 0))
chance = 100;
if (zone->random.Roll(chance)) {
Critical = true;
ratio += itembonuses.SpellCritDmgIncrease + spellbonuses.SpellCritDmgIncrease + aabonuses.SpellCritDmgIncrease;
ratio += itembonuses.SpellCritDmgIncNoStack + spellbonuses.SpellCritDmgIncNoStack + aabonuses.SpellCritDmgIncNoStack;
}
else if ((IsClient() && GetClass() == WIZARD) || (IsMerc() && GetClass() == CASTERDPS)) {
if ((GetLevel() >= RuleI(Spells, WizCritLevel)) && zone->random.Roll(RuleI(Spells, WizCritChance))){
//Wizard innate critical chance is calculated seperately from spell effect and is not a set ratio. (20-70 is parse confirmed)
ratio += zone->random.Int(20,70);
Critical = true;
}
}
if (IsClient() && GetClass() == WIZARD)
ratio += RuleI(Spells, WizCritRatio); //Default is zero
if (Critical){
value = value_BaseEffect*ratio/100;
value += value_BaseEffect*GetFocusEffect(focusImprovedDamage, spell_id)/100;
value += int(value_BaseEffect*GetFocusEffect(focusFcDamagePctCrit, spell_id)/100)*ratio/100;
if (target) {
value += int(value_BaseEffect*target->GetVulnerability(this, spell_id, 0)/100)*ratio/100;
value -= target->GetFcDamageAmtIncoming(this, spell_id);
}
value -= GetFocusEffect(focusFcDamageAmtCrit, spell_id)*ratio/100;
value -= GetFocusEffect(focusFcDamageAmt, spell_id);
if(itembonuses.SpellDmg && spells[spell_id].classes[(GetClass()%16) - 1] >= GetLevel() - 5)
value -= GetExtraSpellAmt(spell_id, itembonuses.SpellDmg, value)*ratio/100;
else if (IsNPC() && CastToNPC()->GetSpellScale())
value = int(static_cast<float>(value) * CastToNPC()->GetSpellScale() / 100.0f);
entity_list.MessageClose_StringID(this, true, 100, MT_SpellCrits,
OTHER_CRIT_BLAST, GetName(), itoa(-value));
if (IsClient())
Message_StringID(MT_SpellCrits, YOU_CRIT_BLAST, itoa(-value));
return value;
}
}
//Non Crtical Hit Calculation pathway
value = value_BaseEffect;
value += value_BaseEffect*GetFocusEffect(focusImprovedDamage, spell_id)/100;
value += value_BaseEffect*GetFocusEffect(focusFcDamagePctCrit, spell_id)/100;
if (target) {
value += value_BaseEffect*target->GetVulnerability(this, spell_id, 0)/100;
value -= target->GetFcDamageAmtIncoming(this, spell_id);
}
value -= GetFocusEffect(focusFcDamageAmtCrit, spell_id);
value -= GetFocusEffect(focusFcDamageAmt, spell_id);
if(itembonuses.SpellDmg && spells[spell_id].classes[(GetClass()%16) - 1] >= GetLevel() - 5)
value -= GetExtraSpellAmt(spell_id, itembonuses.SpellDmg, value);
if (IsNPC() && CastToNPC()->GetSpellScale())
value = int(static_cast<float>(value) * CastToNPC()->GetSpellScale() / 100.0f);
return value;
}