Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # HG changeset patch
- # User Riname <riname@laposte.net>
- # Date 1308076198 -7200
- # Branch Enhanced Edition // Feriale
- # Node ID f38058f568e468d6247de26b96db47dbba619d8b
- # Parent f0ba6a0deaa4e455736bff9d141107a83f85e4b6
- Enhanced Edition // Feriale: Try to fix Spell penetration and Binary resistance
- diff -r f0ba6a0deaa4 -r f38058f568e4 src/server/game/Entities/GameObject/GameObject.cpp
- --- a/src/server/game/Entities/GameObject/GameObject.cpp Mon Jun 13 20:21:50 2011 +0200
- +++ b/src/server/game/Entities/GameObject/GameObject.cpp Tue Jun 14 20:29:58 2011 +0200
- @@ -1668,11 +1668,13 @@
- if (Unit* owner = GetOwner())
- {
- trigger->setFaction(owner->getFaction());
- + trigger->SetLevel(owner->getLevel());
- trigger->CastSpell(target ? target : trigger, spellInfo, true, 0, 0, owner->GetGUID());
- }
- else
- {
- trigger->setFaction(14);
- + trigger->SetLevel(target ? target->getLevel() : 255);
- // Set owner guid for target if no owner avalible - needed by trigger auras
- // - trigger gets despawned and there's no caster avalible (see AuraEffect::TriggerSpell())
- trigger->CastSpell(target ? target : trigger, spellInfo, true, 0, 0, target ? target->GetGUID() : 0);
- diff -r f0ba6a0deaa4 -r f38058f568e4 src/server/game/Entities/Player/Player.cpp
- --- a/src/server/game/Entities/Player/Player.cpp Mon Jun 13 20:21:50 2011 +0200
- +++ b/src/server/game/Entities/Player/Player.cpp Tue Jun 14 20:29:58 2011 +0200
- @@ -8088,9 +8088,8 @@
- case ITEM_MOD_HEALTH_REGEN:
- ApplyHealthRegenBonus(int32(val), apply);
- break;
- - case ITEM_MOD_SPELL_PENETRATION:
- - ApplyModInt32Value(PLAYER_FIELD_MOD_TARGET_RESISTANCE, -val, apply);
- - m_spellPenetrationItemMod += apply ? val : -val;
- + case ITEM_MOD_SPELL_PENETRATION:
- + ApplySpellPenetrationBonus(int32(val), apply);
- break;
- // deprecated item mods
- case ITEM_MOD_SPELL_HEALING_DONE:
- @@ -14069,8 +14068,7 @@
- sLog->outDebug(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);
- sLog->outDebug(LOG_FILTER_PLAYER_ITEMS, "+ %u SPELL_PENETRATION", enchant_amount);
- break;
- case ITEM_MOD_BLOCK_VALUE:
- diff -r f0ba6a0deaa4 -r f38058f568e4 src/server/game/Entities/Player/Player.h
- --- a/src/server/game/Entities/Player/Player.h Mon Jun 13 20:21:50 2011 +0200
- +++ b/src/server/game/Entities/Player/Player.h Tue Jun 14 20:29:58 2011 +0200
- @@ -1877,6 +1877,7 @@
- bool UpdateStats(Stats stat);
- bool UpdateAllStats();
- + void ApplySpellPenetrationBonus(int32 amount, bool apply);
- void UpdateResistances(uint32 school);
- void UpdateArmor();
- void UpdateMaxHealth();
- @@ -1902,7 +1903,7 @@
- float OCTRegenMPPerSpirit();
- float GetRatingMultiplier(CombatRating cr) const;
- float GetRatingBonusValue(CombatRating cr) const;
- - uint32 GetBaseSpellPowerBonus() { return m_baseSpellPower; }
- + uint32 GetBaseSpellPowerBonus() const { return m_baseSpellPower; }
- int32 GetSpellPenetrationItemMod() const { return m_spellPenetrationItemMod; }
- float GetExpertiseDodgeOrParryReduction(WeaponAttackType attType) const;
- diff -r f0ba6a0deaa4 -r f38058f568e4 src/server/game/Entities/Unit/StatSystem.cpp
- --- a/src/server/game/Entities/Unit/StatSystem.cpp Mon Jun 13 20:21:50 2011 +0200
- +++ b/src/server/game/Entities/Unit/StatSystem.cpp Tue Jun 14 20:29:58 2011 +0200
- @@ -176,6 +176,12 @@
- 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 -r f0ba6a0deaa4 -r f38058f568e4 src/server/game/Entities/Unit/Unit.cpp
- --- a/src/server/game/Entities/Unit/Unit.cpp Mon Jun 13 20:21:50 2011 +0200
- +++ b/src/server/game/Entities/Unit/Unit.cpp Tue Jun 14 20:29:58 2011 +0200
- @@ -974,7 +974,7 @@
- return damageInfo.damage;
- }
- -void Unit::CalculateSpellDamageTaken(SpellNonMeleeDamage *damageInfo, int32 damage, SpellEntry const *spellInfo, WeaponAttackType attackType, bool crit)
- +void Unit::CalculateSpellDamageTaken(SpellNonMeleeDamage *damageInfo, int32 damage, SpellEntry const *spellInfo, WeaponAttackType attackType, bool crit, int32 calc_resist)
- {
- if (damage < 0)
- return;
- @@ -1082,7 +1082,7 @@
- // Calculate absorb resist
- if (damage > 0)
- {
- - CalcAbsorbResist(pVictim, damageSchoolMask, SPELL_DIRECT_DAMAGE, damage, &damageInfo->absorb, &damageInfo->resist, spellInfo);
- + CalcAbsorbResist(pVictim, damageSchoolMask, SPELL_DIRECT_DAMAGE, damage, &damageInfo->absorb, &damageInfo->resist, spellInfo, calc_resist);
- damage -= damageInfo->absorb + damageInfo->resist;
- }
- else
- @@ -1572,73 +1572,134 @@
- return (newdamage > 1) ? newdamage : 1;
- }
- -void Unit::CalcAbsorbResist(Unit *pVictim, SpellSchoolMask schoolMask, DamageEffectType damagetype, const uint32 damage, uint32 *absorb, uint32 *resist, SpellEntry const *spellInfo)
- +uint32 Unit::GetSpellPenetration(SpellSchoolMask schoolMask) const
- +{
- + int32 spellPenetration = 0;
- +
- + const Unit * source = ToPlayer();
- +
- + if (!source)
- + {
- + source = ToCreature();
- +
- + if (source)
- + {
- + source = source->ToCreature()->GetOwner();
- +
- + if (source)
- + source = source->ToPlayer();
- + }
- + }
- +
- + if (source && !isTotem())
- + spellPenetration += source->ToPlayer()->GetSpellPenetrationItemMod();
- + else
- + source = this;
- +
- + spellPenetration += -source->GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_TARGET_RESISTANCE, schoolMask);
- +
- + return uint32(std::max<int32>(spellPenetration, 0));
- +}
- +
- +uint32 Unit::CalcSpellResistance(Unit * pVictim, SpellSchoolMask schoolMask, bool binary, SpellEntry const * spellProto) const
- +{
- + // Magic damage, check for resists
- + if (uint32(schoolMask & (SPELL_SCHOOL_MASK_NORMAL | SPELL_SCHOOL_HOLY)) > 0)
- + return 0;
- +
- + // These spells should ignore any resistances
- + if (spellProto && spellProto->AttributesEx3 & SPELL_ATTR3_IGNORE_HIT_RESULT)
- + return 0;
- +
- + uint8 BOSS_LEVEL = 83;
- + int32 BOSS_RESISTANCE_CONSTANT = 510;
- +
- + int32 resistanceConstant = 0;
- + if (getLevel() >= BOSS_LEVEL)
- + resistanceConstant = BOSS_RESISTANCE_CONSTANT;
- + else
- + resistanceConstant = getLevel() * 5;
- +
- + int32 levelDiff = std::max<int32>(pVictim->getLevel() - getLevel(), 0);
- +
- + int32 baseVictimResistance = pVictim->GetResistance(GetFirstSchoolInMask(schoolMask));
- + uint32 spellPenetration = GetSpellPenetration(schoolMask);
- + int32 victimResistance = std::max<int32>(baseVictimResistance - spellPenetration, 0);
- +
- + int32 ignoredResistance = 0;
- +
- + if (victimResistance > 0)
- + {
- + AuraEffectList const & aurasA = GetAuraEffectsByType(SPELL_AURA_MOD_ABILITY_IGNORE_TARGET_RESIST);
- + for (AuraEffectList::const_iterator itr = aurasA.begin(); itr != aurasA.end(); ++itr)
- + if (((*itr)->GetMiscValue() & schoolMask) && (*itr)->IsAffectedOnSpell(spellProto))
- + ignoredResistance += (*itr)->GetAmount();
- +
- + AuraEffectList const & aurasB = GetAuraEffectsByType(SPELL_AURA_MOD_IGNORE_TARGET_RESIST);
- + for (AuraEffectList::const_iterator itr = aurasB.begin(); itr != aurasB.end(); ++itr)
- + if ((*itr)->GetMiscValue() & schoolMask)
- + ignoredResistance += (*itr)->GetAmount();
- +
- + ignoredResistance = std::min<int32>(ignoredResistance, 100);
- + }
- +
- + victimResistance = victimResistance * (100 - ignoredResistance) / 100;
- + victimResistance += (levelDiff * 5); // Level diff resistance cannot be pierced
- +
- + if (victimResistance <= 0)
- + return 0;
- +
- + float averageResist = float(victimResistance) / float(victimResistance + resistanceConstant);
- +
- + if (binary) // No partial resists for binary spells
- + {
- + int32 tmp = int32(averageResist * 10000);
- + int32 rand = irand(0, 10000);
- + return rand < tmp ? 100 : 0;
- + }
- +
- + 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 (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))
- + {
- + ++resistance;
- + probabilitySum += discreteResistProbability[resistance];
- + }
- +
- + return (resistance * 10);
- +}
- +
- +void Unit::CalcAbsorbResist(Unit * pVictim, SpellSchoolMask schoolMask, DamageEffectType damagetype, const uint32 damage, uint32 * absorb, uint32 * resist, SpellEntry const * spellInfo, int32 calc_resist)
- {
- if (!pVictim || !pVictim->isAlive() || !damage)
- return;
- DamageInfo dmgInfo = DamageInfo(this, pVictim, damage, spellInfo, schoolMask, damagetype);
- - // Magic damage, check for resists
- - if ((schoolMask & SPELL_SCHOOL_MASK_NORMAL) == 0)
- - {
- - float baseVictimResistance = float(pVictim->GetResistance(GetFirstSchoolInMask(schoolMask)));
- - float ignoredResistance = float(GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_TARGET_RESISTANCE, schoolMask));
- - if (Player* player = ToPlayer())
- - ignoredResistance += float(player->GetSpellPenetrationItemMod());
- - float victimResistance = baseVictimResistance + ignoredResistance;
- -
- - static const uint32 BOSS_LEVEL = 83;
- - static const float BOSS_RESISTANCE_CONSTANT = 510.0;
- - uint32 level = getLevel();
- - float resistanceConstant = 0.0f;
- -
- - if (level == BOSS_LEVEL)
- - resistanceConstant = BOSS_RESISTANCE_CONSTANT;
- - else
- - resistanceConstant = level * 5.0f;
- -
- - 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 (averageResist <= 0.1f)
- - {
- - discreteResistProbability[0] = 1.0f - 7.5f * averageResist;
- - discreteResistProbability[1] = 5.0f * averageResist;
- - discreteResistProbability[2] = 2.5f * averageResist;
- - }
- -
- - float r = float(rand_norm());
- - uint32 i = 0;
- - float probabilitySum = discreteResistProbability[0];
- -
- - while (r >= probabilitySum && i < 10)
- - probabilitySum += discreteResistProbability[++i];
- -
- - float damageResisted = float(damage * i / 10);
- -
- - 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))
- - AddPctN(damageResisted, -(*j)->GetAmount());
- -
- - 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)
- - AddPctN(damageResisted, -(*j)->GetAmount());
- -
- - // These spells should ignore any resistances
- - if (spellInfo && spellInfo->AttributesEx3 & SPELL_ATTR3_IGNORE_HIT_RESULT)
- - damageResisted = 0;
- -
- - dmgInfo.ResistDamage(uint32(damageResisted));
- - }
- + bool binary = (spellInfo && (uint32(sSpellMgr->GetSpellCustomAttr(spellInfo->Id) & SPELL_ATTR0_CU_BINARY) > 0));
- + if (!binary)
- + if (calc_resist >= 0)
- + dmgInfo.ResistDamage(damage * calc_resist / 100);
- + else
- + dmgInfo.ResistDamage(damage * CalcSpellResistance(pVictim, schoolMask, binary, spellInfo) / 100);
- // Ignore Absorption Auras
- float auraAbsorbMod = 0;
- @@ -2264,7 +2325,7 @@
- return false;
- }
- -int32 Unit::GetMechanicResistChance(const SpellEntry *spell)
- +int32 Unit::GetMechanicResistChance(const SpellEntry *spell) const
- {
- if (!spell)
- return 0;
- @@ -2455,19 +2516,13 @@
- return SPELL_MISS_NONE;
- }
- -// TODO need use unit spell resistances in calculations
- -SpellMissInfo Unit::MagicSpellHitResult(Unit *pVictim, SpellEntry const *spell)
- -{
- - // Can`t miss on dead target (on skinning for example)
- - if (!pVictim->isAlive() && pVictim->GetTypeId() != TYPEID_PLAYER)
- - return SPELL_MISS_NONE;
- -
- - SpellSchoolMask schoolMask = GetSpellSchoolMask(spell);
- +uint32 Unit::CalcMagicSpellHitChance(Unit * pVictim, SpellSchoolMask schoolMask, SpellEntry const * spellProto)
- +{
- // PvP - PvE spell misschances per leveldif > 2
- int32 lchance = pVictim->GetTypeId() == TYPEID_PLAYER ? 7 : 11;
- int32 thisLevel = getLevelForTarget(pVictim);
- if (GetTypeId() == TYPEID_UNIT && ToCreature()->isTrigger())
- - thisLevel = std::max<int32>(thisLevel, spell->spellLevel);
- + thisLevel = std::max<int32>(thisLevel, spellProto->spellLevel);
- int32 leveldif = int32(pVictim->getLevelForTarget(this)) - thisLevel;
- // Base hit chance from attacker and victim levels
- @@ -2475,44 +2530,131 @@
- if (leveldif < 3)
- modHitChance = 96 - leveldif;
- else
- - modHitChance = 94 - (leveldif - 2) * lchance;
- -
- + modHitChance = 94 - (leveldif - 2) * lchance;
- +
- + Unit * source = ToPlayer();
- + if (!source)
- + {
- + source = ToCreature();
- + if (source)
- + {
- + source = source->ToCreature()->GetOwner();
- + if (source)
- + source = source->ToPlayer();
- + }
- + }
- + if (source && !isTotem())
- + source->ToPlayer()->ApplySpellMod(spellProto->Id, SPELLMOD_RESIST_MISS_CHANCE, modHitChance);
- + else
- + source = this;
- +
- // Spellmod from SPELLMOD_RESIST_MISS_CHANCE
- if (Player *modOwner = GetSpellModOwner())
- - modOwner->ApplySpellMod(spell->Id, SPELLMOD_RESIST_MISS_CHANCE, modHitChance);
- + modOwner->ApplySpellMod(spellProto->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 (!(spellProto->AttributesEx3 & SPELL_ATTR3_IGNORE_HIT_RESULT))
- {
- // Chance hit from victim SPELL_AURA_MOD_ATTACKER_SPELL_HIT_CHANCE auras
- - if (!(spell->SpellFamilyName == SPELLFAMILY_WARLOCK && spell->SpellIconID == 3178)) // Chaos Bolt should ignore it
- - modHitChance += pVictim->GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_ATTACKER_SPELL_HIT_CHANCE, schoolMask);
- + if (!(spellProto->SpellFamilyName == SPELLFAMILY_WARLOCK && spellProto->SpellIconID == 3178)) // Chaos Bolt should ignore it
- + modHitChance += pVictim->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 (IsAreaOfEffectSpell(spell))
- + if (IsAreaOfEffectSpell(spellProto))
- modHitChance -= pVictim->GetTotalAuraModifier(SPELL_AURA_MOD_AOE_AVOIDANCE);
- // Decrease hit chance from victim rating bonus
- if (pVictim->GetTypeId() == TYPEID_PLAYER)
- modHitChance -= int32(pVictim->ToPlayer()->GetRatingBonusValue(CR_HIT_TAKEN_SPELL));
- - }
- -
- - int32 HitChance = modHitChance * 100;
- - // Increase hit chance from attacker SPELL_AURA_MOD_SPELL_HIT_CHANCE and attacker ratings
- - HitChance += int32(m_modSpellHitChance * 100.0f);
- -
- - if (HitChance < 100)
- - HitChance = 100;
- - else if (HitChance > 10000)
- - HitChance = 10000;
- -
- - int32 tmp = 10000 - HitChance;
- + }
- + // Chance resist mechanic (select max value from every mechanic spell effect)
- + modHitChance -= pVictim->GetMechanicResistChance(spellProto);
- +
- + // Chance resist debuff
- + if (!IsPositiveSpell(spellProto->Id))
- + {
- + bool bNegativeAura = false;
- + for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
- + {
- + if (spellProto->EffectApplyAuraName[i] != 0)
- + {
- + bNegativeAura = true;
- + break;
- + }
- + }
- +
- + // Direct Damage spells should not be fully resisted
- + bool bDirectDamage = false;
- + for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
- + {
- + if (spellProto->Effect[i] == SPELL_EFFECT_SCHOOL_DAMAGE || spellProto->Effect[i] == SPELL_EFFECT_HEALTH_LEECH)
- + {
- + bDirectDamage = true;
- + break;
- + }
- + }
- +
- + if (bNegativeAura && !bDirectDamage)
- + {
- + modHitChance -= pVictim->GetMaxPositiveAuraModifierByMiscValue(SPELL_AURA_MOD_DEBUFF_RESISTANCE, int32(spellProto->Dispel));
- + modHitChance -= pVictim->GetMaxNegativeAuraModifierByMiscValue(SPELL_AURA_MOD_DEBUFF_RESISTANCE, int32(spellProto->Dispel));
- + }
- + }
- +
- + int32 hit = modHitChance * 100;
- + // Increase hit chance from attacker SPELL_AURA_MOD_SPELL_HIT_CHANCE and attacker ratings
- + hit += int32(source->m_modSpellHitChance * 100.0f);
- +
- + // Decrease hit chance from victim rating bonus
- + if (pVictim->ToPlayer())
- + hit -= int32(pVictim->ToPlayer()->GetRatingBonusValue(CR_HIT_TAKEN_SPELL) * 100.0f);
- +
- + hit = std::min<int32>(std::max<int32>(hit, 100), 10000);
- +
- + return uint32(hit);
- +}
- +
- +SpellMissInfo Unit::MagicSpellHitResult(Unit * pVictim, SpellEntry const * spell)
- +{
- + // Can`t miss on dead target (on skinning for example)
- + if (!pVictim->isAlive() && pVictim->GetTypeId() != TYPEID_PLAYER)
- + return SPELL_MISS_NONE;
- +
- + SpellSchoolMask schoolMask = GetSpellSchoolMask(spell);
- +
- + int32 ignoredResistance = 0;
- +
- + AuraEffectList const & aurasA = GetAuraEffectsByType(SPELL_AURA_MOD_ABILITY_IGNORE_TARGET_RESIST);
- + for (AuraEffectList::const_iterator itr = aurasA.begin(); itr != aurasA.end(); ++itr)
- + if (((*itr)->GetMiscValue() & schoolMask) && (*itr)->IsAffectedOnSpell(spell))
- + ignoredResistance += (*itr)->GetAmount();
- +
- + AuraEffectList const & aurasB = GetAuraEffectsByType(SPELL_AURA_MOD_IGNORE_TARGET_RESIST);
- + for (AuraEffectList::const_iterator itr = aurasB.begin(); itr != aurasB.end(); ++itr)
- + if ((*itr)->GetMiscValue() & schoolMask)
- + ignoredResistance += (*itr)->GetAmount();
- +
- + ignoredResistance = std::min(ignoredResistance, int32(100));
- +
- + // cast by caster in front of victim
- + int32 deflect_chance = (pVictim->GetTotalAuraModifier(SPELL_AURA_DEFLECT_SPELLS) * (100 - ignoredResistance) / 100) * 100;
- +
- + if (deflect_chance > 0)
- + if (pVictim->HasInArc(M_PI, this) || pVictim->HasAuraType(SPELL_AURA_IGNORE_HIT_DIRECTION))
- + {
- + int32 rand = irand(0, 10000);
- +
- + if (rand < deflect_chance)
- + return SPELL_MISS_DEFLECT;
- + }
- +
- + int32 miss = (10000 - CalcMagicSpellHitChance(pVictim, schoolMask, spell)) * (100 - ignoredResistance) / 100;
- int32 rand = irand(0, 10000);
- - if (rand < tmp)
- + if (rand < miss)
- return SPELL_MISS_MISS;
- // Spells with SPELL_ATTR3_IGNORE_HIT_RESULT will additionally fully ignore
- @@ -2520,58 +2662,10 @@
- if (spell->AttributesEx3 & SPELL_ATTR3_IGNORE_HIT_RESULT)
- return SPELL_MISS_NONE;
- - // Chance resist mechanic (select max value from every mechanic spell effect)
- - int32 resist_chance = pVictim->GetMechanicResistChance(spell) * 100;
- - tmp += resist_chance;
- -
- - // Chance resist debuff
- - if (!IsPositiveSpell(spell->Id))
- - {
- - bool bNegativeAura = false;
- - for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
- - {
- - if (spell->EffectApplyAuraName[i] != 0)
- - {
- - bNegativeAura = true;
- - break;
- - }
- - }
- -
- - // Direct Damage spells should not be fully resisted
- - bool bDirectDamage = false;
- - for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
- - {
- - if (spell->Effect[i] == SPELL_EFFECT_SCHOOL_DAMAGE || spell->Effect[i] == SPELL_EFFECT_HEALTH_LEECH)
- - {
- - bDirectDamage = true;
- - break;
- - }
- - }
- -
- - if (bNegativeAura && !bDirectDamage)
- - {
- - tmp += pVictim->GetMaxPositiveAuraModifierByMiscValue(SPELL_AURA_MOD_DEBUFF_RESISTANCE, int32(spell->Dispel)) * 100;
- - tmp += pVictim->GetMaxNegativeAuraModifierByMiscValue(SPELL_AURA_MOD_DEBUFF_RESISTANCE, int32(spell->Dispel)) * 100;
- - }
- - }
- -
- - // Roll chance
- - if (rand < tmp)
- - return SPELL_MISS_RESIST;
- -
- // Chaos Bolt cannot be deflected
- if (spell->SpellFamilyName == SPELLFAMILY_WARLOCK && spell->SpellIconID == 3178)
- return SPELL_MISS_NONE;
- - // cast by caster in front of victim
- - if (pVictim->HasInArc(M_PI, this) || pVictim->HasAuraType(SPELL_AURA_IGNORE_HIT_DIRECTION))
- - {
- - int32 deflect_chance = pVictim->GetTotalAuraModifier(SPELL_AURA_DEFLECT_SPELLS) * 100;
- - tmp += deflect_chance;
- - if (rand < tmp)
- - return SPELL_MISS_DEFLECT;
- - }
- -
- return SPELL_MISS_NONE;
- }
- diff -r f0ba6a0deaa4 -r f38058f568e4 src/server/game/Entities/Unit/Unit.h
- --- a/src/server/game/Entities/Unit/Unit.h Mon Jun 13 20:21:50 2011 +0200
- +++ b/src/server/game/Entities/Unit/Unit.h Tue Jun 14 20:29:58 2011 +0200
- @@ -1254,6 +1254,7 @@
- uint32 GetResistance(SpellSchools school) const { return GetUInt32Value(UNIT_FIELD_RESISTANCES+school); }
- void SetResistance(SpellSchools school, int32 val) { SetStatInt32Value(UNIT_FIELD_RESISTANCES+school, val); }
- + uint32 GetSpellPenetration(SpellSchoolMask schoolMask) const;
- uint32 GetHealth() const { return GetUInt32Value(UNIT_FIELD_HEALTH); }
- uint32 GetMaxHealth() const { return GetUInt32Value(UNIT_FIELD_MAXHEALTH); }
- @@ -1358,7 +1359,7 @@
- void CalculateMeleeDamage(Unit *pVictim, uint32 damage, CalcDamageInfo *damageInfo, WeaponAttackType attackType = BASE_ATTACK);
- void DealMeleeDamage(CalcDamageInfo *damageInfo, bool durabilityLoss);
- - void CalculateSpellDamageTaken(SpellNonMeleeDamage *damageInfo, int32 damage, SpellEntry const *spellInfo, WeaponAttackType attackType = BASE_ATTACK, bool crit = false);
- + void CalculateSpellDamageTaken(SpellNonMeleeDamage *damageInfo, int32 damage, SpellEntry const *spellInfo, WeaponAttackType attackType = BASE_ATTACK, bool crit = false, int32 calc_resist = -1);
- void DealSpellDamage(SpellNonMeleeDamage *damageInfo, bool durabilityLoss);
- // player or player's pet resilience (-1%)
- @@ -1384,13 +1385,14 @@
- float MeleeSpellMissChance(const Unit *pVictim, WeaponAttackType attType, int32 skillDiff, uint32 spellId) const;
- SpellMissInfo MeleeSpellHitResult(Unit *pVictim, SpellEntry const *spell);
- SpellMissInfo MagicSpellHitResult(Unit *pVictim, SpellEntry const *spell);
- + uint32 CalcMagicSpellHitChance(Unit * pVictim, SpellSchoolMask schoolMask, SpellEntry const * spellProto);
- SpellMissInfo SpellHitResult(Unit *pVictim, SpellEntry const *spell, bool canReflect = false);
- float GetUnitDodgeChance() const;
- float GetUnitParryChance() const;
- float GetUnitBlockChance() const;
- float GetUnitCriticalChance(WeaponAttackType attackType, const Unit *pVictim) const;
- - int32 GetMechanicResistChance(const SpellEntry *spell);
- + int32 GetMechanicResistChance(const SpellEntry *spell) const;
- bool CanUseAttackType(uint8 attacktype) const
- {
- switch(attacktype)
- @@ -1937,7 +1939,8 @@
- // redefined in Creature
- static bool IsDamageReducedByArmor(SpellSchoolMask damageSchoolMask, SpellEntry const *spellInfo = NULL, uint8 effIndex = MAX_SPELL_EFFECTS);
- uint32 CalcArmorReducedDamage(Unit* pVictim, const uint32 damage, SpellEntry const *spellInfo, WeaponAttackType attackType=MAX_ATTACK);
- - void CalcAbsorbResist(Unit *pVictim, SpellSchoolMask schoolMask, DamageEffectType damagetype, const uint32 damage, uint32 *absorb, uint32 *resist, SpellEntry const *spellInfo = NULL);
- + void CalcAbsorbResist(Unit *pVictim, SpellSchoolMask schoolMask, DamageEffectType damagetype, const uint32 damage, uint32 *absorb, uint32 *resist, SpellEntry const *spellInfo = NULL, int32 calc_resist = -1);
- + uint32 CalcSpellResistance(Unit * pVictim, SpellSchoolMask schoolMask, bool binary, SpellEntry const * spellProto) const;
- void CalcHealAbsorb(Unit *pVictim, const SpellEntry *spellProto, uint32 &healAmount, uint32 &absorb);
- void UpdateSpeed(UnitMoveType mtype, bool forced);
- diff -r f0ba6a0deaa4 -r f38058f568e4 src/server/game/Spells/Spell.cpp
- --- a/src/server/game/Spells/Spell.cpp Mon Jun 13 20:21:50 2011 +0200
- +++ b/src/server/game/Spells/Spell.cpp Tue Jun 14 20:29:58 2011 +0200
- @@ -932,15 +932,9 @@
- target.scaleAura = true;
- }
- - // Calculate hit result
- - if (m_originalCaster)
- - {
- - target.missCondition = m_originalCaster->SpellHitResult(pVictim, m_spellInfo, m_canReflect);
- - if (m_skipCheck && target.missCondition != SPELL_MISS_IMMUNE)
- - target.missCondition = SPELL_MISS_NONE;
- - }
- - else
- - target.missCondition = SPELL_MISS_EVADE; //SPELL_MISS_NONE;
- + target.missCondition = m_originalCaster->SpellHitResult(pVictim, m_spellInfo, m_canReflect);
- + if (m_skipCheck && target.missCondition != SPELL_MISS_IMMUNE)
- + target.missCondition = SPELL_MISS_NONE;
- // Spell have speed - need calculate incoming time
- // Incoming time is zero for self casts. At least I think so.
- @@ -1109,6 +1103,7 @@
- // Reset damage/healing counter
- m_damage = target->damage;
- m_healing = -target->damage;
- + m_resist = 0;
- // Fill base trigger info
- uint32 procAttacker = m_procAttacker;
- @@ -1138,11 +1133,11 @@
- if (spellHitTarget)
- {
- - SpellMissInfo missInfo = DoSpellHitOnUnit(spellHitTarget, mask, target->scaleAura);
- - if (missInfo != SPELL_MISS_NONE)
- - {
- - if (missInfo != SPELL_MISS_MISS)
- - m_caster->SendSpellMiss(unit, m_spellInfo->Id, missInfo);
- + SpellMissInfo tmp = DoSpellHitOnUnit(spellHitTarget, mask, target->scaleAura);
- + if (tmp != SPELL_MISS_NONE)
- + {
- + if (tmp != SPELL_MISS_MISS)
- + m_caster->SendSpellMiss(unit, m_spellInfo->Id, tmp);
- m_damage = 0;
- spellHitTarget = NULL;
- }
- @@ -1238,7 +1233,7 @@
- SpellNonMeleeDamage damageInfo(caster, unitTarget, m_spellInfo->Id, m_spellSchoolMask);
- // Add bonuses and fill damageInfo struct
- - caster->CalculateSpellDamageTaken(&damageInfo, m_damage, m_spellInfo, m_attackType, target->crit);
- + caster->CalculateSpellDamageTaken(&damageInfo, m_damage, m_spellInfo, m_attackType, target->crit, m_resist);
- caster->DealDamageMods(damageInfo.target, damageInfo.damage, &damageInfo.absorb);
- // Send log damage message to client
- @@ -1371,6 +1366,11 @@
- //TODO: This is a hack. But we do not know what types of stealth should be interrupted by CC
- if ((m_customAttr & SPELL_ATTR0_CU_AURA_CC) && unit->IsControlledByPlayer())
- unit->RemoveAurasByType(SPELL_AURA_MOD_STEALTH);
- +
- + bool binary = (uint32(sSpellMgr->GetSpellCustomAttr(m_spellInfo->Id) & SPELL_ATTR0_CU_BINARY) > 0);
- + m_resist = m_caster->CalcSpellResistance(unit, GetSpellSchoolMask(m_spellInfo), binary, m_spellInfo);
- + if (m_resist >= 100)
- + return SPELL_MISS_RESIST;
- }
- else
- {
- @@ -1393,6 +1393,13 @@
- }
- }
- }
- + else if (!IsPositiveSpell(m_spellInfo->Id))
- + {
- + bool binary = (uint32(sSpellMgr->GetSpellCustomAttr(m_spellInfo->Id) & SPELL_ATTR0_CU_BINARY) > 0);
- + m_resist = m_caster->CalcSpellResistance(unit, GetSpellSchoolMask(m_spellInfo), binary, m_spellInfo);
- + if (m_resist >= 100)
- + return SPELL_MISS_RESIST;
- + }
- // Get Data Needed for Diminishing Returns, some effects may have multiple auras, so this must be done on spell hit, not aura add
- m_diminishGroup = GetDiminishingReturnsGroupForSpell(m_spellInfo, m_triggeredByAuraSpell);
- diff -r f0ba6a0deaa4 -r f38058f568e4 src/server/game/Spells/Spell.h
- --- a/src/server/game/Spells/Spell.h Mon Jun 13 20:21:50 2011 +0200
- +++ b/src/server/game/Spells/Spell.h Tue Jun 14 20:29:58 2011 +0200
- @@ -605,6 +605,7 @@
- // Damage and healing in effects need just calculate
- int32 m_damage; // Damge in effects count here
- int32 m_healing; // Healing in effects count here
- + int32 m_resist; // Resist in effects count here
- // ******************************************
- // Spell trigger system
- diff -r f0ba6a0deaa4 -r f38058f568e4 src/server/game/Spells/SpellMgr.cpp
- --- a/src/server/game/Spells/SpellMgr.cpp Mon Jun 13 20:21:50 2011 +0200
- +++ b/src/server/game/Spells/SpellMgr.cpp Tue Jun 14 20:29:58 2011 +0200
- @@ -3613,6 +3613,79 @@
- }
- }
- + if (spellInfo->DmgClass == SPELL_DAMAGE_CLASS_MAGIC)
- + {
- + if (spellInfo->Mechanic != 0 &&
- + spellInfo->Mechanic != MECHANIC_INFECTED)
- + {
- + mSpellCustomAttr[i] |= SPELL_ATTR0_CU_BINARY;
- + count++;
- + }
- + else if (spellInfo->EffectMechanic[0] != 0 &&
- + spellInfo->EffectMechanic[0] != MECHANIC_INFECTED &&
- + spellInfo->Effect[1] != SPELL_EFFECT_SCHOOL_DAMAGE)
- + {
- + mSpellCustomAttr[i] |= SPELL_ATTR0_CU_BINARY;
- + count++;
- + }
- + else if (spellInfo->EffectMechanic[1] != 0 &&
- + spellInfo->EffectMechanic[1] != MECHANIC_INFECTED)
- + {
- + mSpellCustomAttr[i] |= SPELL_ATTR0_CU_BINARY;
- + count++;
- + }
- + else if (spellInfo->Effect[0] == SPELL_EFFECT_DISPEL ||
- + spellInfo->Effect[1] == SPELL_EFFECT_DISPEL ||
- + spellInfo->Effect[2] == SPELL_EFFECT_DISPEL)
- + {
- + mSpellCustomAttr[i] |= SPELL_ATTR0_CU_BINARY;
- + count++;
- + }
- + else if (spellInfo->Effect[0] == SPELL_EFFECT_STEAL_BENEFICIAL_BUFF ||
- + spellInfo->Effect[1] == SPELL_EFFECT_STEAL_BENEFICIAL_BUFF ||
- + spellInfo->Effect[2] == SPELL_EFFECT_STEAL_BENEFICIAL_BUFF)
- + {
- + mSpellCustomAttr[i] |= SPELL_ATTR0_CU_BINARY;
- + count++;
- + }
- + else if (spellInfo->Effect[0] == SPELL_EFFECT_POWER_BURN ||
- + spellInfo->Effect[1] == SPELL_EFFECT_POWER_BURN ||
- + spellInfo->Effect[2] == SPELL_EFFECT_POWER_BURN)
- + {
- + mSpellCustomAttr[i] |= SPELL_ATTR0_CU_BINARY;
- + count++;
- + }
- + else if (spellInfo->Effect[0] == SPELL_EFFECT_POWER_DRAIN ||
- + spellInfo->Effect[1] == SPELL_EFFECT_POWER_DRAIN ||
- + spellInfo->Effect[2] == SPELL_EFFECT_POWER_DRAIN)
- + {
- + mSpellCustomAttr[i] |= SPELL_ATTR0_CU_BINARY;
- + count++;
- + }
- + else if (spellInfo->EffectApplyAuraName[0] == SPELL_AURA_PERIODIC_MANA_LEECH ||
- + spellInfo->EffectApplyAuraName[1] == SPELL_AURA_PERIODIC_MANA_LEECH ||
- + spellInfo->EffectApplyAuraName[2] == SPELL_AURA_PERIODIC_MANA_LEECH)
- + {
- + mSpellCustomAttr[i] |= SPELL_ATTR0_CU_BINARY;
- + count++;
- + }
- + else if ((spellInfo->Dispel == DISPEL_POISON) ||
- + (spellInfo->Dispel == DISPEL_CURSE) ||
- + (spellInfo->Dispel == DISPEL_DISEASE))
- + {
- + if (spellInfo->Effect[0] != SPELL_EFFECT_SCHOOL_DAMAGE &&
- + spellInfo->Effect[1] != SPELL_EFFECT_SCHOOL_DAMAGE &&
- + spellInfo->Effect[2] != SPELL_EFFECT_SCHOOL_DAMAGE &&
- + spellInfo->EffectApplyAuraName[0] != SPELL_AURA_PERIODIC_DAMAGE &&
- + spellInfo->EffectApplyAuraName[1] != SPELL_AURA_PERIODIC_DAMAGE &&
- + spellInfo->EffectApplyAuraName[2] != SPELL_AURA_PERIODIC_DAMAGE)
- + {
- + mSpellCustomAttr[i] |= SPELL_ATTR0_CU_BINARY;
- + count++;
- + }
- + }
- + }
- +
- if (!_isPositiveEffect(i, 0, false))
- {
- mSpellCustomAttr[i] |= SPELL_ATTR0_CU_NEGATIVE_EFF0;
- diff -r f0ba6a0deaa4 -r f38058f568e4 src/server/game/Spells/SpellMgr.h
- --- a/src/server/game/Spells/SpellMgr.h Mon Jun 13 20:21:50 2011 +0200
- +++ b/src/server/game/Spells/SpellMgr.h Tue Jun 14 20:29:58 2011 +0200
- @@ -890,6 +890,7 @@
- SPELL_ATTR0_CU_NEGATIVE_EFF1 = 0x00020000,
- SPELL_ATTR0_CU_NEGATIVE_EFF2 = 0x00040000,
- SPELL_ATTR0_CU_IGNORE_ARMOR = 0x00080000,
- + SPELL_ATTR0_CU_BINARY = 0x00100000,
- SPELL_ATTR0_CU_NEGATIVE = SPELL_ATTR0_CU_NEGATIVE_EFF0 | SPELL_ATTR0_CU_NEGATIVE_EFF1 | SPELL_ATTR0_CU_NEGATIVE_EFF2,
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement