diff options
-rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 6 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.h | 1 | ||||
-rw-r--r-- | src/server/game/Entities/Unit/StatSystem.cpp | 6 | ||||
-rw-r--r-- | src/server/game/Entities/Unit/Unit.cpp | 238 | ||||
-rw-r--r-- | src/server/game/Entities/Unit/Unit.h | 23 |
5 files changed, 153 insertions, 121 deletions
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index d1b42151e0a..c57c5c9a076 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -7961,8 +7961,7 @@ void Player::_ApplyItemBonuses(ItemTemplate const* proto, uint8 slot, bool apply ApplyHealthRegenBonus(int32(val), apply); break; case ITEM_MOD_SPELL_PENETRATION: - ApplyModInt32Value(PLAYER_FIELD_MOD_TARGET_RESISTANCE, -val, apply); - m_spellPenetrationItemMod += apply ? val : -val; + ApplySpellPenetrationBonus(val, apply); break; case ITEM_MOD_BLOCK_VALUE: HandleBaseModValue(SHIELD_BLOCK_VALUE, FLAT_MOD, float(val), apply); @@ -14146,8 +14145,7 @@ void Player::ApplyEnchantment(Item* item, EnchantmentSlot slot, bool apply, bool TC_LOG_DEBUG(LOG_FILTER_PLAYER_ITEMS, "+ %u HEALTH_REGENERATION", enchant_amount); break; case ITEM_MOD_SPELL_PENETRATION: - ApplyModInt32Value(PLAYER_FIELD_MOD_TARGET_RESISTANCE, enchant_amount, apply); - m_spellPenetrationItemMod += apply ? int32(enchant_amount) : -int32(enchant_amount); + ApplySpellPenetrationBonus(enchant_amount, apply); TC_LOG_DEBUG(LOG_FILTER_PLAYER_ITEMS, "+ %u SPELL_PENETRATION", enchant_amount); break; case ITEM_MOD_BLOCK_VALUE: diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 2cdf89dce75..6cc8c0c3929 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -1738,6 +1738,7 @@ class Player : public Unit, public GridObject<Player> bool UpdateStats(Stats stat); bool UpdateAllStats(); + void ApplySpellPenetrationBonus(int32 amount, bool apply); void UpdateResistances(uint32 school); void UpdateArmor(); void UpdateMaxHealth(); diff --git a/src/server/game/Entities/Unit/StatSystem.cpp b/src/server/game/Entities/Unit/StatSystem.cpp index 7651297a078..e6cc30c867a 100644 --- a/src/server/game/Entities/Unit/StatSystem.cpp +++ b/src/server/game/Entities/Unit/StatSystem.cpp @@ -184,6 +184,12 @@ bool Player::UpdateAllStats() return true; } +void Player::ApplySpellPenetrationBonus(int32 amount, bool apply) +{ + ApplyModInt32Value(PLAYER_FIELD_MOD_TARGET_RESISTANCE, -amount, apply); + m_spellPenetrationItemMod += apply ? amount : -amount; +} + void Player::UpdateResistances(uint32 school) { if (school > SPELL_SCHOOL_NORMAL) diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 629b202470d..1db86f24e64 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -1548,75 +1548,93 @@ uint32 Unit::CalcArmorReducedDamage(Unit* victim, const uint32 damage, SpellInfo return std::max<uint32>(damage * (1.0f - tmpvalue), 1); } -void Unit::CalcAbsorbResist(Unit* victim, SpellSchoolMask schoolMask, DamageEffectType damagetype, uint32 const damage, uint32 *absorb, uint32 *resist, SpellInfo const* spellInfo) +uint32 Unit::CalcSpellResistance(Unit* victim, SpellSchoolMask schoolMask, SpellInfo const* spellInfo) const { - if (!victim || !victim->IsAlive() || !damage) - return; + // Magic damage, check for resists + if (!(schoolMask & SPELL_SCHOOL_MASK_SPELL)) + return 0; - DamageInfo dmgInfo = DamageInfo(this, victim, damage, spellInfo, schoolMask, damagetype); + // Ignore spells that can't be resisted + if (spellInfo && spellInfo->AttributesEx4 & SPELL_ATTR4_IGNORE_RESISTANCES) + return 0; - // Magic damage, check for resists - // Ignore spells that cant be resisted - if ((schoolMask & SPELL_SCHOOL_MASK_NORMAL) == 0 && (!spellInfo || (spellInfo->AttributesEx4 & SPELL_ATTR4_IGNORE_RESISTANCES) == 0)) - { - float victimResistance = float(victim->GetResistance(schoolMask)); - victimResistance += float(GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_TARGET_RESISTANCE, schoolMask)); + uint32 const BOSS_LEVEL = 83; + uint32 const BOSS_RESISTANCE_CONSTANT = 510; + uint32 resistanceConstant = 0; + uint8 level = victim->getLevel(); - if (Player* player = ToPlayer()) - victimResistance -= float(player->GetSpellPenetrationItemMod()); + if (level == BOSS_LEVEL) + resistanceConstant = BOSS_RESISTANCE_CONSTANT; + else + resistanceConstant = level * 5; - // Resistance can't be lower then 0. - if (victimResistance < 0.0f) - victimResistance = 0.0f; + int32 baseVictimResistance = victim->GetResistance(schoolMask); + baseVictimResistance += GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_TARGET_RESISTANCE, schoolMask); - static uint32 const BOSS_LEVEL = 83; - static float const BOSS_RESISTANCE_CONSTANT = 510.0f; - uint32 level = victim->getLevel(); - float resistanceConstant = 0.0f; + if (Player const* player = ToPlayer()) + baseVictimResistance -= player->GetSpellPenetrationItemMod(); - if (level == BOSS_LEVEL) - resistanceConstant = BOSS_RESISTANCE_CONSTANT; - else - resistanceConstant = level * 5.0f; + // Resistance can't be lower then 0 + int32 victimResistance = std::max<int32>(baseVictimResistance, 0); - float averageResist = victimResistance / (victimResistance + resistanceConstant); - float discreteResistProbability[11]; - for (uint32 i = 0; i < 11; ++i) - { - discreteResistProbability[i] = 0.5f - 2.5f * fabs(0.1f * i - averageResist); - if (discreteResistProbability[i] < 0.0f) - discreteResistProbability[i] = 0.0f; - } + if (victimResistance > 0) + { + int32 ignoredResistance = 0; - if (averageResist <= 0.1f) - { - discreteResistProbability[0] = 1.0f - 7.5f * averageResist; - discreteResistProbability[1] = 5.0f * averageResist; - discreteResistProbability[2] = 2.5f * averageResist; - } + AuraEffectList const& ResIgnoreAurasAb = GetAuraEffectsByType(SPELL_AURA_MOD_ABILITY_IGNORE_TARGET_RESIST); + for (AuraEffectList::const_iterator itr = ResIgnoreAurasAb.begin(); itr != ResIgnoreAurasAb.end(); ++itr) + if (((*itr)->GetMiscValue() & schoolMask) && (*itr)->IsAffectedOnSpell(spellInfo)) + ignoredResistance += (*itr)->GetAmount(); - float r = float(rand_norm()); - uint32 i = 0; - float probabilitySum = discreteResistProbability[0]; + AuraEffectList const& ResIgnoreAuras = GetAuraEffectsByType(SPELL_AURA_MOD_IGNORE_TARGET_RESIST); + for (AuraEffectList::const_iterator itr = ResIgnoreAuras.begin(); itr != ResIgnoreAuras.end(); ++itr) + if ((*itr)->GetMiscValue() & schoolMask) + ignoredResistance += (*itr)->GetAmount(); - while (r >= probabilitySum && i < 10) - probabilitySum += discreteResistProbability[++i]; + ignoredResistance = std::min<int32>(ignoredResistance, 100); + ApplyPct(victimResistance, 100 - ignoredResistance); + } - float damageResisted = float(damage * i / 10); + if (victimResistance <= 0) + return 0; - AuraEffectList const& ResIgnoreAurasAb = GetAuraEffectsByType(SPELL_AURA_MOD_ABILITY_IGNORE_TARGET_RESIST); - for (AuraEffectList::const_iterator j = ResIgnoreAurasAb.begin(); j != ResIgnoreAurasAb.end(); ++j) - if (((*j)->GetMiscValue() & schoolMask) && (*j)->IsAffectedOnSpell(spellInfo)) - AddPct(damageResisted, -(*j)->GetAmount()); + float averageResist = float(victimResistance) / float(victimResistance + resistanceConstant); - AuraEffectList const& ResIgnoreAuras = GetAuraEffectsByType(SPELL_AURA_MOD_IGNORE_TARGET_RESIST); - for (AuraEffectList::const_iterator j = ResIgnoreAuras.begin(); j != ResIgnoreAuras.end(); ++j) - if ((*j)->GetMiscValue() & schoolMask) - AddPct(damageResisted, -(*j)->GetAmount()); + float discreteResistProbability[11]; + for (uint32 i = 0; i < 11; ++i) + { + discreteResistProbability[i] = 0.5f - 2.5f * fabs(0.1f * i - averageResist); + if (discreteResistProbability[i] < 0.0f) + discreteResistProbability[i] = 0.0f; + } - dmgInfo.ResistDamage(uint32(damageResisted)); + if (averageResist <= 0.1f) + { + discreteResistProbability[0] = 1.0f - 7.5f * averageResist; + discreteResistProbability[1] = 5.0f * averageResist; + discreteResistProbability[2] = 2.5f * averageResist; } + uint32 resistance = 0; + float r = float(rand_norm()); + float probabilitySum = discreteResistProbability[0]; + + while (r >= probabilitySum && resistance < 10) + probabilitySum += discreteResistProbability[++resistance]; + + return resistance * 10; +} + +void Unit::CalcAbsorbResist(Unit* victim, SpellSchoolMask schoolMask, DamageEffectType damagetype, uint32 const damage, uint32* absorb, uint32* resist, SpellInfo const* spellInfo /*= NULL*/) +{ + if (!victim || !victim->IsAlive() || !damage) + return; + + DamageInfo dmgInfo = DamageInfo(this, victim, damage, spellInfo, schoolMask, damagetype); + + uint32 spellResistance = CalcSpellResistance(victim, schoolMask, spellInfo); + dmgInfo.ResistDamage(CalculatePct(damage, spellResistance)); + // Ignore Absorption Auras float auraAbsorbMod = 0; AuraEffectList const& AbsIgnoreAurasA = GetAuraEffectsByType(SPELL_AURA_MOD_TARGET_ABSORB_SCHOOL); @@ -1833,7 +1851,7 @@ void Unit::CalcAbsorbResist(Unit* victim, SpellSchoolMask schoolMask, DamageEffe *absorb = dmgInfo.GetAbsorb(); } -void Unit::CalcHealAbsorb(Unit* victim, const SpellInfo* healSpell, uint32 &healAmount, uint32 &absorb) +void Unit::CalcHealAbsorb(Unit* victim, SpellInfo const* healSpell, uint32 &healAmount, uint32 &absorb) { if (!healAmount) return; @@ -2241,24 +2259,26 @@ bool Unit::isBlockCritical() return false; } -int32 Unit::GetMechanicResistChance(const SpellInfo* spell) const +int32 Unit::GetMechanicResistChance(SpellInfo const* spellInfo) const { - if (!spell) + if (!spellInfo) return 0; - int32 resist_mech = 0; + + int32 resistMech = 0; for (uint8 eff = 0; eff < MAX_SPELL_EFFECTS; ++eff) { - if (!spell->Effects[eff].IsEffect()) - break; - int32 effect_mech = spell->GetEffectMechanic(eff); - if (effect_mech) + if (!spellInfo->Effects[eff].IsEffect()) + break; + + int32 effectMech = spellInfo->GetEffectMechanic(eff); + if (effectMech) { - int32 temp = GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_MECHANIC_RESISTANCE, effect_mech); - if (resist_mech < temp) - resist_mech = temp; + int32 temp = GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_MECHANIC_RESISTANCE, effectMech); + if (resistMech < temp) + resistMech = temp; } } - return resist_mech; + return resistMech; } bool Unit::CanUseAttackType(uint8 attacktype) const @@ -2277,23 +2297,23 @@ bool Unit::CanUseAttackType(uint8 attacktype) const } // Melee based spells hit result calculations -SpellMissInfo Unit::MeleeSpellHitResult(Unit* victim, SpellInfo const* spell) +SpellMissInfo Unit::MeleeSpellHitResult(Unit* victim, SpellInfo const* spellInfo) { // Spells with SPELL_ATTR3_IGNORE_HIT_RESULT will additionally fully ignore // resist and deflect chances - if (spell->AttributesEx3 & SPELL_ATTR3_IGNORE_HIT_RESULT) + if (spellInfo->AttributesEx3 & SPELL_ATTR3_IGNORE_HIT_RESULT) return SPELL_MISS_NONE; WeaponAttackType attType = BASE_ATTACK; // Check damage class instead of attack type to correctly handle judgements // - they are meele, but can't be dodged/parried/deflected because of ranged dmg class - if (spell->DmgClass == SPELL_DAMAGE_CLASS_RANGED) + if (spellInfo->DmgClass == SPELL_DAMAGE_CLASS_RANGED) attType = RANGED_ATTACK; int32 attackerWeaponSkill; // skill value for these spells (for example judgements) is 5* level - if (spell->DmgClass == SPELL_DAMAGE_CLASS_RANGED && !spell->IsRangedWeaponSpell()) + if (spellInfo->DmgClass == SPELL_DAMAGE_CLASS_RANGED && !spellInfo->IsRangedWeaponSpell()) attackerWeaponSkill = getLevel() * 5; // bonus from skills is 0.04% per skill Diff else @@ -2303,7 +2323,7 @@ SpellMissInfo Unit::MeleeSpellHitResult(Unit* victim, SpellInfo const* spell) uint32 roll = urand (0, 10000); - uint32 missChance = uint32(MeleeSpellMissChance(victim, attType, skillDiff, spell->Id) * 100.0f); + uint32 missChance = uint32(MeleeSpellMissChance(victim, attType, skillDiff, spellInfo->Id) * 100.0f); // Roll miss uint32 tmp = missChance; if (roll < tmp) @@ -2314,12 +2334,12 @@ SpellMissInfo Unit::MeleeSpellHitResult(Unit* victim, SpellInfo const* spell) // Get effects mechanic and chance for (uint8 eff = 0; eff < MAX_SPELL_EFFECTS; ++eff) { - int32 effect_mech = spell->GetEffectMechanic(eff); + int32 effect_mech = spellInfo->GetEffectMechanic(eff); if (effect_mech) { int32 temp = victim->GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_MECHANIC_RESISTANCE, effect_mech); - if (resist_mech < temp*100) - resist_mech = temp*100; + if (resist_mech < temp * 100) + resist_mech = temp * 100; } } // Roll chance @@ -2329,14 +2349,14 @@ SpellMissInfo Unit::MeleeSpellHitResult(Unit* victim, SpellInfo const* spell) bool canDodge = true; bool canParry = true; - bool canBlock = spell->AttributesEx3 & SPELL_ATTR3_BLOCKABLE_SPELL; + bool canBlock = spellInfo->AttributesEx3 & SPELL_ATTR3_BLOCKABLE_SPELL; // Same spells cannot be parry/dodge - if (spell->Attributes & SPELL_ATTR0_IMPOSSIBLE_DODGE_PARRY_BLOCK) + if (spellInfo->Attributes & SPELL_ATTR0_IMPOSSIBLE_DODGE_PARRY_BLOCK) return SPELL_MISS_NONE; // Chance resist mechanic - int32 resist_chance = victim->GetMechanicResistChance(spell) * 100; + int32 resist_chance = victim->GetMechanicResistChance(spellInfo) * 100; tmp += resist_chance; if (roll < tmp) return SPELL_MISS_RESIST; @@ -2351,7 +2371,7 @@ SpellMissInfo Unit::MeleeSpellHitResult(Unit* victim, SpellInfo const* spell) if (victim->HasInArc(M_PI, this) || victim->HasAuraType(SPELL_AURA_IGNORE_HIT_DIRECTION)) { int32 deflect_chance = victim->GetTotalAuraModifier(SPELL_AURA_DEFLECT_SPELLS) * 100; - tmp+=deflect_chance; + tmp += deflect_chance; if (roll < tmp) return SPELL_MISS_DEFLECT; } @@ -2372,7 +2392,7 @@ SpellMissInfo Unit::MeleeSpellHitResult(Unit* victim, SpellInfo const* spell) } else // Only deterrence as of 3.3.5 { - if (spell->AttributesCu & SPELL_ATTR0_CU_REQ_CASTER_BEHIND_TARGET) + if (spellInfo->AttributesCu & SPELL_ATTR0_CU_REQ_CASTER_BEHIND_TARGET) canParry = false; } } @@ -2390,13 +2410,19 @@ SpellMissInfo Unit::MeleeSpellHitResult(Unit* victim, SpellInfo const* spell) AuraEffectList const& ignore = GetAuraEffectsByType(SPELL_AURA_IGNORE_COMBAT_RESULT); for (AuraEffectList::const_iterator i = ignore.begin(); i != ignore.end(); ++i) { - if (!(*i)->IsAffectedOnSpell(spell)) + if (!(*i)->IsAffectedOnSpell(spellInfo)) continue; switch ((*i)->GetMiscValue()) { - case MELEE_HIT_DODGE: canDodge = false; break; - case MELEE_HIT_BLOCK: canBlock = false; break; - case MELEE_HIT_PARRY: canParry = false; break; + case MELEE_HIT_DODGE: + canDodge = false; + break; + case MELEE_HIT_BLOCK: + canBlock = false; + break; + case MELEE_HIT_PARRY: + canParry = false; + break; default: TC_LOG_DEBUG(LOG_FILTER_UNITS, "Spell %u SPELL_AURA_IGNORE_COMBAT_RESULT has unhandled state %d", (*i)->GetId(), (*i)->GetMiscValue()); break; @@ -2454,18 +2480,18 @@ SpellMissInfo Unit::MeleeSpellHitResult(Unit* victim, SpellInfo const* spell) } /// @todo need use unit spell resistances in calculations -SpellMissInfo Unit::MagicSpellHitResult(Unit* victim, SpellInfo const* spell) +SpellMissInfo Unit::MagicSpellHitResult(Unit* victim, SpellInfo const* spellInfo) { // Can`t miss on dead target (on skinning for example) if (!victim->IsAlive() && victim->GetTypeId() != TYPEID_PLAYER) return SPELL_MISS_NONE; - SpellSchoolMask schoolMask = spell->GetSchoolMask(); + SpellSchoolMask schoolMask = spellInfo->GetSchoolMask(); // PvP - PvE spell misschances per leveldif > 2 int32 lchance = victim->GetTypeId() == TYPEID_PLAYER ? 7 : 11; int32 thisLevel = getLevelForTarget(victim); if (GetTypeId() == TYPEID_UNIT && ToCreature()->IsTrigger()) - thisLevel = std::max<int32>(thisLevel, spell->SpellLevel); + thisLevel = std::max<int32>(thisLevel, spellInfo->SpellLevel); int32 leveldif = int32(victim->getLevelForTarget(this)) - thisLevel; // Base hit chance from attacker and victim levels @@ -2477,18 +2503,18 @@ SpellMissInfo Unit::MagicSpellHitResult(Unit* victim, SpellInfo const* spell) // Spellmod from SPELLMOD_RESIST_MISS_CHANCE if (Player* modOwner = GetSpellModOwner()) - modOwner->ApplySpellMod(spell->Id, SPELLMOD_RESIST_MISS_CHANCE, modHitChance); + modOwner->ApplySpellMod(spellInfo->Id, SPELLMOD_RESIST_MISS_CHANCE, modHitChance); // Increase from attacker SPELL_AURA_MOD_INCREASES_SPELL_PCT_TO_HIT auras modHitChance += GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_INCREASES_SPELL_PCT_TO_HIT, schoolMask); // Spells with SPELL_ATTR3_IGNORE_HIT_RESULT will ignore target's avoidance effects - if (!(spell->AttributesEx3 & SPELL_ATTR3_IGNORE_HIT_RESULT)) + if (!(spellInfo->AttributesEx3 & SPELL_ATTR3_IGNORE_HIT_RESULT)) { // Chance hit from victim SPELL_AURA_MOD_ATTACKER_SPELL_HIT_CHANCE auras modHitChance += victim->GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_ATTACKER_SPELL_HIT_CHANCE, schoolMask); // Reduce spell hit chance for Area of effect spells from victim SPELL_AURA_MOD_AOE_AVOIDANCE aura - if (spell->IsTargetingArea()) + if (spellInfo->IsTargetingArea()) modHitChance -= victim->GetTotalAuraModifier(SPELL_AURA_MOD_AOE_AVOIDANCE); // Decrease hit chance from victim rating bonus @@ -2514,30 +2540,30 @@ SpellMissInfo Unit::MagicSpellHitResult(Unit* victim, SpellInfo const* spell) // Spells with SPELL_ATTR3_IGNORE_HIT_RESULT will additionally fully ignore // resist and deflect chances - if (spell->AttributesEx3 & SPELL_ATTR3_IGNORE_HIT_RESULT) + if (spellInfo->AttributesEx3 & SPELL_ATTR3_IGNORE_HIT_RESULT) return SPELL_MISS_NONE; // Chance resist mechanic (select max value from every mechanic spell effect) - int32 resist_chance = victim->GetMechanicResistChance(spell) * 100; + int32 resist_chance = victim->GetMechanicResistChance(spellInfo) * 100; tmp += resist_chance; // Chance resist debuff - if (!spell->IsPositive()) + if (!spellInfo->IsPositive()) { - bool bNegativeAura = true; + bool hasAura = false; for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) { - if (spell->Effects[i].ApplyAuraName == 0) + if (spellInfo->Effects[i].IsAura()) { - bNegativeAura = false; + hasAura = true; break; } } - if (bNegativeAura) + if (hasAura) { - tmp += victim->GetMaxPositiveAuraModifierByMiscValue(SPELL_AURA_MOD_DEBUFF_RESISTANCE, int32(spell->Dispel)) * 100; - tmp += victim->GetMaxNegativeAuraModifierByMiscValue(SPELL_AURA_MOD_DEBUFF_RESISTANCE, int32(spell->Dispel)) * 100; + tmp += victim->GetMaxPositiveAuraModifierByMiscValue(SPELL_AURA_MOD_DEBUFF_RESISTANCE, int32(spellInfo->Dispel)) * 100; + tmp += victim->GetMaxNegativeAuraModifierByMiscValue(SPELL_AURA_MOD_DEBUFF_RESISTANCE, int32(spellInfo->Dispel)) * 100; } } @@ -2565,19 +2591,19 @@ SpellMissInfo Unit::MagicSpellHitResult(Unit* victim, SpellInfo const* spell) // Parry // For spells // Resist -SpellMissInfo Unit::SpellHitResult(Unit* victim, SpellInfo const* spell, bool CanReflect) +SpellMissInfo Unit::SpellHitResult(Unit* victim, SpellInfo const* spellInfo, bool CanReflect) { // Check for immune - if (victim->IsImmunedToSpell(spell)) + if (victim->IsImmunedToSpell(spellInfo)) return SPELL_MISS_IMMUNE; // All positive spells can`t miss /// @todo client not show miss log for this spells - so need find info for this in dbc and use it! - if (spell->IsPositive() - &&(!IsHostileTo(victim))) // prevent from affecting enemy by "positive" spell + if (spellInfo->IsPositive() && !IsHostileTo(victim)) // prevent from affecting enemy by "positive" spell return SPELL_MISS_NONE; + // Check for immune - if (victim->IsImmunedToDamage(spell)) + if (victim->IsImmunedToDamage(spellInfo)) return SPELL_MISS_IMMUNE; if (this == victim) @@ -2593,25 +2619,25 @@ SpellMissInfo Unit::SpellHitResult(Unit* victim, SpellInfo const* spell, bool Ca int32 reflectchance = victim->GetTotalAuraModifier(SPELL_AURA_REFLECT_SPELLS); Unit::AuraEffectList const& mReflectSpellsSchool = victim->GetAuraEffectsByType(SPELL_AURA_REFLECT_SPELLS_SCHOOL); for (Unit::AuraEffectList::const_iterator i = mReflectSpellsSchool.begin(); i != mReflectSpellsSchool.end(); ++i) - if ((*i)->GetMiscValue() & spell->GetSchoolMask()) + if ((*i)->GetMiscValue() & spellInfo->GetSchoolMask()) reflectchance += (*i)->GetAmount(); if (reflectchance > 0 && roll_chance_i(reflectchance)) { // Start triggers for remove charges if need (trigger only for victim, and mark as active spell) - ProcDamageAndSpell(victim, PROC_FLAG_NONE, PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_NEG, PROC_EX_REFLECT, 1, BASE_ATTACK, spell); + ProcDamageAndSpell(victim, PROC_FLAG_NONE, PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_NEG, PROC_EX_REFLECT, 1, BASE_ATTACK, spellInfo); return SPELL_MISS_REFLECT; } } - switch (spell->DmgClass) + switch (spellInfo->DmgClass) { case SPELL_DAMAGE_CLASS_RANGED: case SPELL_DAMAGE_CLASS_MELEE: - return MeleeSpellHitResult(victim, spell); + return MeleeSpellHitResult(victim, spellInfo); case SPELL_DAMAGE_CLASS_NONE: return SPELL_MISS_NONE; case SPELL_DAMAGE_CLASS_MAGIC: - return MagicSpellHitResult(victim, spell); + return MagicSpellHitResult(victim, spellInfo); } return SPELL_MISS_NONE; } diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index 14a4decb390..8f3fc6bd873 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -1471,16 +1471,16 @@ class Unit : public WorldObject void ApplyResilience(Unit const* victim, float* crit, int32* damage, bool isCrit, CombatRating type) const; float MeleeSpellMissChance(Unit const* victim, WeaponAttackType attType, int32 skillDiff, uint32 spellId) const; - SpellMissInfo MeleeSpellHitResult(Unit* victim, SpellInfo const* spell); - SpellMissInfo MagicSpellHitResult(Unit* victim, SpellInfo const* spell); - SpellMissInfo SpellHitResult(Unit* victim, SpellInfo const* spell, bool canReflect = false); + SpellMissInfo MeleeSpellHitResult(Unit* victim, SpellInfo const* spellInfo); + SpellMissInfo MagicSpellHitResult(Unit* victim, SpellInfo const* spellInfo); + SpellMissInfo SpellHitResult(Unit* victim, SpellInfo const* spellInfo, bool canReflect = false); float GetUnitDodgeChance() const; float GetUnitParryChance() const; float GetUnitBlockChance() const; float GetUnitMissChance(WeaponAttackType attType) const; float GetUnitCriticalChance(WeaponAttackType attackType, const Unit* victim) const; - int32 GetMechanicResistChance(const SpellInfo* spell) const; + int32 GetMechanicResistChance(SpellInfo const* spellInfo) const; bool CanUseAttackType(uint8 attacktype) const; virtual uint32 GetShieldBlockValue() const =0; @@ -1980,16 +1980,17 @@ class Unit : public WorldObject void ApplySpellImmune(uint32 spellId, uint32 op, uint32 type, bool apply); void ApplySpellDispelImmunity(const SpellInfo* spellProto, DispelType type, bool apply); - virtual bool IsImmunedToSpell(SpellInfo const* spellInfo) const; - // redefined in Creature + virtual bool IsImmunedToSpell(SpellInfo const* spellInfo) const; // redefined in Creature + bool IsImmunedToDamage(SpellSchoolMask meleeSchoolMask) const; bool IsImmunedToDamage(SpellInfo const* spellInfo) const; - virtual bool IsImmunedToSpellEffect(SpellInfo const* spellInfo, uint32 index) const; - // redefined in Creature + virtual bool IsImmunedToSpellEffect(SpellInfo const* spellInfo, uint32 index) const; // redefined in Creature + static bool IsDamageReducedByArmor(SpellSchoolMask damageSchoolMask, SpellInfo const* spellInfo = NULL, uint8 effIndex = MAX_SPELL_EFFECTS); - uint32 CalcArmorReducedDamage(Unit* victim, const uint32 damage, SpellInfo const* spellInfo, WeaponAttackType attackType=MAX_ATTACK); - void CalcAbsorbResist(Unit* victim, SpellSchoolMask schoolMask, DamageEffectType damagetype, const uint32 damage, uint32 *absorb, uint32 *resist, SpellInfo const* spellInfo = NULL); - void CalcHealAbsorb(Unit* victim, const SpellInfo* spellProto, uint32 &healAmount, uint32 &absorb); + uint32 CalcArmorReducedDamage(Unit* victim, const uint32 damage, SpellInfo const* spellInfo, WeaponAttackType attackType = MAX_ATTACK); + uint32 CalcSpellResistance(Unit* victim, SpellSchoolMask schoolMask, SpellInfo const* spellInfo) const; + void CalcAbsorbResist(Unit* victim, SpellSchoolMask schoolMask, DamageEffectType damagetype, uint32 const damage, uint32* absorb, uint32* resist, SpellInfo const* spellInfo = NULL); + void CalcHealAbsorb(Unit* victim, SpellInfo const* spellInfo, uint32& healAmount, uint32& absorb); void UpdateSpeed(UnitMoveType mtype, bool forced); float GetSpeed(UnitMoveType mtype) const; |