It's all in here:
https://github.com/mangoszero/server/bl ... t/Unit.cpp line 2232 to be exact.
- Code: Select all
// Max 40% chance to score a glancing blow against mobs that are higher level (can do only players and pets and not with ranged weapon)
if (attType != RANGED_ATTACK && !SpellCasted &&
(GetTypeId() == TYPEID_PLAYER || ((Creature*)this)->IsPet()) &&
pVictim->GetTypeId() != TYPEID_PLAYER && !((Creature*)pVictim)->IsPet() &&
getLevel() < pVictim->GetLevelForTarget(this))
{
// cap possible value (with bonuses > max skill)
int32 skill = attackerWeaponSkill;
int32 maxskill = attackerMaxSkillValueForLevel;
skill = (skill > maxskill) ? maxskill : skill;
tmp = (10 + 2 * (victimDefenseSkill - skill)) * 100;
tmp = tmp > 4000 ? 4000 : tmp;
if (roll < (sum += tmp))
{
DEBUG_FILTER_LOG(LOG_FILTER_COMBAT, "RollMeleeOutcomeAgainst: GLANCING <%d, %d)", sum - 4000, sum);
return MELEE_HIT_GLANCING;
}
}
In layman's terms:
The code checks if you are not attacking from range, is not a casted spell, if you are a player, if you are a pet, if victim is not a player and not a pet, and if your level is lower than of our victim.
If this is true, our attack has a chance to glance.
Next it registers our weaponskill, then throws it in a formula.
What this formula does is calculate the chance to glance. So as a human using swords or maces fighting a boss (level 63, 63 * 5 defense), we get this:
- Code: Select all
(10 + 2 * (315 - 305)) * 100 = 3000
3000 is essentially 30%, because the mangos code uses integer in the roll table (line 2175).
After that it checks if our number is higher than 4000. If it is, then we set it to 4000 (can't be higher than 40% chance to glance), if it's lower, then set it as that (3000, or 30% in our case).
Now that we know our hit is going to glance, it needs to calculate the damage reduction.
Starting from line 1552:
- Code: Select all
case MELEE_HIT_GLANCING:
{
damageInfo->HitInfo |= HITINFO_GLANCING;
damageInfo->TargetState = VICTIMSTATE_NORMAL;
damageInfo->procEx |= PROC_EX_NORMAL_HIT;
float reducePercent = 1.0f; // damage factor
// calculate base values and mods
float baseLowEnd = 1.3f;
float baseHighEnd = 1.2f;
switch (getClass()) // lowering base values for casters
{
case CLASS_SHAMAN:
case CLASS_PRIEST:
case CLASS_MAGE:
case CLASS_WARLOCK:
case CLASS_DRUID:
baseLowEnd -= 0.7f;
baseHighEnd -= 0.3f;
break;
}
float maxLowEnd = 0.6f;
switch (getClass()) // upper for melee classes
{
case CLASS_WARRIOR:
case CLASS_ROGUE:
maxLowEnd = 0.91f; // If the attacker is a melee class then instead the lower value of 0.91
}
// calculate values
int32 diff = damageInfo->target->GetDefenseSkillValue() - GetWeaponSkillValue(damageInfo->attackType);
float lowEnd = baseLowEnd - (0.05f * diff);
float highEnd = baseHighEnd - (0.03f * diff);
// apply max/min bounds
if (lowEnd < 0.01f) // the low end must not go bellow 0.01f
{ lowEnd = 0.01f; }
else if (lowEnd > maxLowEnd) // the smaller value of this and 0.6 is kept as the low end
{ lowEnd = maxLowEnd; }
if (highEnd < 0.2f) // high end limits
{ highEnd = 0.2f; }
if (highEnd > 0.99f)
{ highEnd = 0.99f; }
if (lowEnd > highEnd) // prevent negative range size
{ lowEnd = highEnd; }
reducePercent = lowEnd + rand_norm_f() * (highEnd - lowEnd);
damageInfo->cleanDamage += damageInfo->damage - uint32(reducePercent * damageInfo->damage);
damageInfo->damage = uint32(reducePercent * damageInfo->damage);
break;
}
There is a difference in classes. We'll use a Human Warrior again to continue this explanation.
We need to look at these variables:
baseLowEnd = 1.3
baseHighEnd = 1.2
baseLowEnd = biggest reduction, baseHighEnd = smallest reduction.
For Warriors, the cap on our LowEnd is set to 0.91 (line 1578).
Next up is checking skill values, and what's important here.
Skill difference = 315 (boss defense level) - 305 (human weapon skill level) = 10
So, we set our Ends with:
- Code: Select all
lowEnd = baseLowEnd - (0.05 * 10) = 0.8
highEnd = baseHighEnd - (0.03 * 10) = 0.9
our lowEnd is lower than 0.91, so we keep it at 0.8
if our lowEnd is higher than our highEnd, we set highEnd at the same value as lowEnd
- Code: Select all
if (lowEnd > highEnd) lowEnd = highEnd;
which is not the case. Numbers stay the same.
we can then conclude how much damage is reduced with the following formula:
- Code: Select all
lowEnd + randomnumber * (highEnd - lowEnd)
I can't find exactly what randomnumber generates, but I suspect it's a number between 0.1 and 0.9, something like that.
in our example, the formula is:
- Code: Select all
0.8 + random * (0.9 - 0.8)
Our damage will be reduced by between 19 and 11%, depending on the random number generated.
Conclusion: Mangos core weaponskill lowers chance to glance and its dmg. Max % chance to glance is 40%, +5 weaponskill gives rougly 10% in chance decrease versus bosses.
EDIT: Also, +skill gives a massive boost in melee spell hits.
- Code: Select all
skillDif = weaponSkill - targetDefense;
if (skillDiff < -10)
hitChance = 93.0f + (skillDiff + 10) * 0.4f; // 7% base chance to miss for big skill diff (%6 in 3.x)
else
hitChance = 95.0f + skillDiff * 0.1f;
This is taken from mangos code as well. What this means in the end is that +5 weapon skill gives a massive +5% hit for melee spells.