I figured out what the problem was. There is just too much stuff being done with chancetohit at the point that the defense bonuses are calculated to actually set it with a percentage. I set the spell bonus check to do a percentage on the final value of chancetohit.
In attack.cpp remove this line:
Code:
bonus = defender->spellbonuses.AvoidMeleeChance + defender->itembonuses.AvoidMeleeChance;
And replace it with the line in
RED here:
Code:
//subtract off avoidance by the defender
bonus = defender->itembonuses.AvoidMeleeChance;
if(bonus > 0) {
chancetohit -= (bonus) / 10; //
mlog(COMBAT__TOHIT, "Applied avoidance chance %.2f/10, yeilding %.2f", bonus, chancetohit);
}
And then, right above this section at the end of Mob::CheckHitChance:
Code:
mlog(COMBAT__TOHIT, "Final hit chance: %.2f%%. Hit roll %.2f", chancetohit, tohit_roll);
return(tohit_roll <= chancetohit);
Add the Lines in red:
Code:
//Reduce final chancetohit by % based on spell bonuses
bonus = (100 - (defender->spellbonuses.AvoidMeleeChance / 10)) / 100;
if(bonus > 0) {
chancetohit *= (bonus);
}
mlog(COMBAT__TOHIT, "Final hit chance: %.2f%%. Hit roll %.2f", chancetohit, tohit_roll);
return(tohit_roll <= chancetohit);
I tested this and it looks to work great. Everything works the same as before, accept now spell bonuses that are supposed to reduce hit chance are now factored into the final hit chance as a percentage.
Really, the code that AndMetal posted would probably work great as well if it was just moved to the end of Mob::CheckHitChance instead of being done in the middle of it. Doing it in the middle as a percentage really throws off the rest of the calculations.
I have no idea why "case SE_AvoidMeleeChance:" and "case SE_ProcChance:" are multiplying the spell values by 10, but if there is no other use for them, I think we could remove that multiplier and then remove the "/ 10" from the related code in Mob::CheckHitChance. No reason to do unneeded math 2 times!