diff options
| author | ariel- <ariel-@users.noreply.github.com> | 2018-02-10 16:43:01 -0300 |
|---|---|---|
| committer | Ariel Silva <ariel-@users.noreply.github.com> | 2018-03-09 14:41:28 -0300 |
| commit | 45c5e1b9d63796d168339a44f63418f220cf2403 (patch) | |
| tree | c5c2ef9917147e38779d1f94e6ffc38386b9b251 /src/server/game/Spells/SpellEffects.cpp | |
| parent | 080d2c6cd439acb2059adc4e24a279de98aa0db6 (diff) | |
Core/Spells: rework part 5: GameObject casting
Closes #21330
Closes #18885
Ref #18752
Diffstat (limited to 'src/server/game/Spells/SpellEffects.cpp')
| -rw-r--r-- | src/server/game/Spells/SpellEffects.cpp | 975 |
1 files changed, 541 insertions, 434 deletions
diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index 7c64440eea9..bdc262ef0bd 100644 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -60,7 +60,7 @@ #include "WorldPacket.h" #include "WorldSession.h" -pEffect SpellEffects[TOTAL_SPELL_EFFECTS]= +SpellEffectHandlerFn SpellEffectHandlers[TOTAL_SPELL_EFFECTS] = { &Spell::EffectNULL, // 0 &Spell::EffectInstaKill, // 1 SPELL_EFFECT_INSTAKILL @@ -286,7 +286,7 @@ void Spell::EffectInstaKill(SpellEffIndex /*effIndex*/) data << uint32(m_spellInfo->Id); m_caster->SendMessageToSet(&data, true); - Unit::DealDamage(m_caster, unitTarget, unitTarget->GetHealth(), nullptr, NODAMAGE, SPELL_SCHOOL_MASK_NORMAL, nullptr, false); + Unit::DealDamage(unitCaster, unitTarget, unitTarget->GetHealth(), nullptr, NODAMAGE, SPELL_SCHOOL_MASK_NORMAL, nullptr, false); } void Spell::EffectEnvironmentalDMG(SpellEffIndex /*effIndex*/) @@ -302,12 +302,13 @@ void Spell::EffectEnvironmentalDMG(SpellEffIndex /*effIndex*/) unitTarget->ToPlayer()->EnvironmentalDamage(DAMAGE_FIRE, damage); else { - DamageInfo damageInfo(m_caster, unitTarget, damage, m_spellInfo, m_spellInfo->GetSchoolMask(), SPELL_DIRECT_DAMAGE, BASE_ATTACK); + DamageInfo damageInfo(unitCaster, unitTarget, damage, m_spellInfo, m_spellInfo->GetSchoolMask(), SPELL_DIRECT_DAMAGE, BASE_ATTACK); Unit::CalcAbsorbResist(damageInfo); - uint32 absorb = damageInfo.GetAbsorb(); - uint32 resist = damageInfo.GetResist(); - m_caster->SendSpellNonMeleeDamageLog(unitTarget, m_spellInfo->Id, damage, m_spellInfo->GetSchoolMask(), absorb, resist, false, 0, false); + uint32 const absorb = damageInfo.GetAbsorb(); + uint32 const resist = damageInfo.GetResist(); + if (unitCaster) + unitCaster->SendSpellNonMeleeDamageLog(unitTarget, m_spellInfo->Id, damage, m_spellInfo->GetSchoolMask(), absorb, resist, false, 0, false); } } @@ -328,17 +329,27 @@ void Spell::EffectSchoolDMG(SpellEffIndex effIndex) { uint32 count = 0; for (auto ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit) + { + if (ihit->MissCondition != SPELL_MISS_NONE) + continue; + if (ihit->EffectMask & (1 << effIndex)) ++count; + } - damage /= count; // divide to all targets + // divide to all targets + if (count) + damage /= count; } + ///@todo: move those to scripts switch (m_spellInfo->Id) // better way to check unknown { // Consumption case 28865: - damage = (((InstanceMap*)m_caster->GetMap())->GetDifficulty() == REGULAR_DIFFICULTY ? 2750 : 4250); + damage = 2750; + if (m_caster->GetMap()->IsHeroic()) + damage = 4250; break; // percent from health with min case 25599: // Thundercrash @@ -351,16 +362,17 @@ void Spell::EffectSchoolDMG(SpellEffIndex effIndex) // arcane charge. must only affect demons (also undead?) case 45072: { - if (unitTarget->GetCreatureType() != CREATURE_TYPE_DEMON - && unitTarget->GetCreatureType() != CREATURE_TYPE_UNDEAD) + if (!(unitTarget->GetCreatureTypeMask() & CREATURE_TYPEMASK_DEMON_OR_UNDEAD)) return; break; } // Gargoyle Strike case 51963: { + damage = 60; // about +4 base spell dmg per level - damage = (m_caster->getLevel() - 60) * 4 + 60; + if (unitCaster && unitCaster->getLevel() >= 60) + damage += (unitCaster->getLevel() - 60) * 4; break; } } @@ -368,28 +380,34 @@ void Spell::EffectSchoolDMG(SpellEffIndex effIndex) } case SPELLFAMILY_WARRIOR: { + if (!unitCaster) + break; + // Shield Slam - if (m_spellInfo->SpellFamilyFlags[1] & 0x200 && m_spellInfo->GetCategory() == 1209) + if ((m_spellInfo->SpellFamilyFlags[1] & 0x200) && m_spellInfo->GetCategory() == 1209) { - uint8 level = m_caster->getLevel(); - uint32 block_value = m_caster->GetShieldBlockValue(uint32(float(level) * 24.5f), uint32(float(level) * 34.5f)); - damage += int32(m_caster->ApplyEffectModifiers(m_spellInfo, effIndex, float(block_value))); + uint8 level = unitCaster->getLevel(); + uint32 block_value = unitCaster->GetShieldBlockValue(uint32(float(level) * 24.5f), uint32(float(level) * 34.5f)); + damage += int32(unitCaster->ApplyEffectModifiers(m_spellInfo, effIndex, float(block_value))); } // Victory Rush else if (m_spellInfo->SpellFamilyFlags[1] & 0x100) - ApplyPct(damage, m_caster->GetTotalAttackPowerValue(BASE_ATTACK)); + ApplyPct(damage, unitCaster->GetTotalAttackPowerValue(BASE_ATTACK)); // Shockwave else if (m_spellInfo->Id == 46968) { - int32 pct = m_caster->CalculateSpellDamage(unitTarget, m_spellInfo, 2); + int32 pct = unitCaster->CalculateSpellDamage(m_spellInfo, EFFECT_2); if (pct > 0) - damage += int32(CalculatePct(m_caster->GetTotalAttackPowerValue(BASE_ATTACK), pct)); + damage += int32(CalculatePct(unitCaster->GetTotalAttackPowerValue(BASE_ATTACK), pct)); break; } break; } case SPELLFAMILY_WARLOCK: { + if (!unitCaster) + break; + // Incinerate Rank 1 & 2 if ((m_spellInfo->SpellFamilyFlags[1] & 0x000040) && m_spellInfo->SpellIconID == 2128) { @@ -411,7 +429,7 @@ void Spell::EffectSchoolDMG(SpellEffIndex effIndex) { // for caster applied auras only if ((*i)->GetSpellInfo()->SpellFamilyName != SPELLFAMILY_WARLOCK || - (*i)->GetCasterGUID() != m_caster->GetGUID()) + (*i)->GetCasterGUID() != unitCaster->GetGUID()) continue; // Immolate @@ -431,15 +449,15 @@ void Spell::EffectSchoolDMG(SpellEffIndex effIndex) { // Calculate damage of Immolate/Shadowflame tick int32 pdamage = aura->GetAmount(); - pdamage = unitTarget->SpellDamageBonusTaken(m_caster, aura->GetSpellInfo(), pdamage, DOT); + pdamage = unitTarget->SpellDamageBonusTaken(unitCaster, aura->GetSpellInfo(), pdamage, DOT); // And multiply by amount of ticks to get damage potential pdamage *= aura->GetSpellInfo()->GetMaxTicks(); - int32 pct_dir = m_caster->CalculateSpellDamage(unitTarget, m_spellInfo, EFFECT_1); + int32 pct_dir = unitCaster->CalculateSpellDamage(m_spellInfo, EFFECT_1); damage += CalculatePct(pdamage, pct_dir); - int32 pct_dot = m_caster->CalculateSpellDamage(unitTarget, m_spellInfo, EFFECT_2); + int32 pct_dot = unitCaster->CalculateSpellDamage(m_spellInfo, EFFECT_2); int32 const dotBasePoints = CalculatePct(pdamage, pct_dot); ASSERT(m_spellInfo->GetMaxTicks() > 0); @@ -447,8 +465,8 @@ void Spell::EffectSchoolDMG(SpellEffIndex effIndex) apply_direct_bonus = false; // Glyph of Conflagrate - if (!m_caster->HasAura(56235)) - unitTarget->RemoveAurasDueToSpell(aura->GetId(), m_caster->GetGUID()); + if (!unitCaster->HasAura(56235)) + unitTarget->RemoveAurasDueToSpell(aura->GetId(), unitCaster->GetGUID()); break; } @@ -456,16 +474,16 @@ void Spell::EffectSchoolDMG(SpellEffIndex effIndex) // Shadow Bite else if (m_spellInfo->SpellFamilyFlags[1] & 0x400000) { - if (m_caster->GetTypeId() == TYPEID_UNIT && m_caster->IsPet()) + if (unitCaster->GetTypeId() == TYPEID_UNIT && unitCaster->IsPet()) { - if (Player* owner = m_caster->GetOwner()->ToPlayer()) + if (Player* owner = unitCaster->GetOwner()->ToPlayer()) { if (AuraEffect* aurEff = owner->GetAuraEffect(SPELL_AURA_ADD_FLAT_MODIFIER, SPELLFAMILY_WARLOCK, 214, 0)) { int32 bp0 = aurEff->GetId() == 54037 ? 4 : 8; CastSpellExtraArgs args(TRIGGERED_FULL_MASK); args.AddSpellMod(SPELLVALUE_BASE_POINT0, bp0); - m_caster->CastSpell(m_caster, 54425, args); + unitCaster->CastSpell(nullptr, 54425, args); } } } @@ -474,19 +492,22 @@ void Spell::EffectSchoolDMG(SpellEffIndex effIndex) } case SPELLFAMILY_PRIEST: { + if (!unitCaster) + break; + // Improved Mind Blast (Mind Blast in shadow form bonus) - if (m_caster->GetShapeshiftForm() == FORM_SHADOW && (m_spellInfo->SpellFamilyFlags[0] & 0x00002000)) + if (unitCaster->GetShapeshiftForm() == FORM_SHADOW && (m_spellInfo->SpellFamilyFlags[0] & 0x00002000)) { - Unit::AuraEffectList const& ImprMindBlast = m_caster->GetAuraEffectsByType(SPELL_AURA_ADD_FLAT_MODIFIER); + Unit::AuraEffectList const& ImprMindBlast = unitCaster->GetAuraEffectsByType(SPELL_AURA_ADD_FLAT_MODIFIER); for (Unit::AuraEffectList::const_iterator i = ImprMindBlast.begin(); i != ImprMindBlast.end(); ++i) { if ((*i)->GetSpellInfo()->SpellFamilyName == SPELLFAMILY_PRIEST && ((*i)->GetSpellInfo()->SpellIconID == 95)) { - int chance = (*i)->GetSpellInfo()->Effects[EFFECT_1].CalcValue(m_caster); + // Mind Trauma + int32 const chance = (*i)->GetSpellInfo()->Effects[EFFECT_1].CalcValue(unitCaster); if (roll_chance_i(chance)) - // Mind Trauma - m_caster->CastSpell(unitTarget, 48301, true); + unitCaster->CastSpell(unitTarget, 48301, true); break; } } @@ -495,21 +516,24 @@ void Spell::EffectSchoolDMG(SpellEffIndex effIndex) } case SPELLFAMILY_DRUID: { + if (!unitCaster) + break; + // Ferocious Bite - if (m_caster->GetTypeId() == TYPEID_PLAYER && (m_spellInfo->SpellFamilyFlags[0] & 0x000800000) && m_spellInfo->SpellVisual[0] == 6587) + if (unitCaster->GetTypeId() == TYPEID_PLAYER && (m_spellInfo->SpellFamilyFlags[0] & 0x000800000) && m_spellInfo->SpellVisual[0] == 6587) { // converts each extra point of energy into ($f1+$AP/410) additional damage - float ap = m_caster->GetTotalAttackPowerValue(BASE_ATTACK); + float ap = unitCaster->GetTotalAttackPowerValue(BASE_ATTACK); float multiple = ap / 410 + m_spellInfo->Effects[effIndex].DamageMultiplier; - int32 energy = -(m_caster->ModifyPower(POWER_ENERGY, -30)); + int32 energy = -(unitCaster->ModifyPower(POWER_ENERGY, -30)); damage += int32(energy * multiple); - damage += int32(CalculatePct(m_caster->ToPlayer()->GetComboPoints() * ap, 7)); + damage += int32(CalculatePct(unitCaster->ToPlayer()->GetComboPoints() * ap, 7)); } // Wrath else if (m_spellInfo->SpellFamilyFlags[0] & 0x00000001) { // Improved Insect Swarm - if (AuraEffect const* aurEff = m_caster->GetDummyAuraEffect(SPELLFAMILY_DRUID, 1771, 0)) + if (AuraEffect const* aurEff = unitCaster->GetDummyAuraEffect(SPELLFAMILY_DRUID, 1771, 0)) if (unitTarget->GetAuraEffect(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_DRUID, 0x00200000, 0, 0)) AddPct(damage, aurEff->GetAmount()); } @@ -517,16 +541,19 @@ void Spell::EffectSchoolDMG(SpellEffIndex effIndex) } case SPELLFAMILY_ROGUE: { + if (!unitCaster) + break; + // Envenom if (m_spellInfo->SpellFamilyFlags[1] & 0x00000008) { - if (Player* player = m_caster->ToPlayer()) + if (Player* player = unitCaster->ToPlayer()) { // consume from stack dozes not more that have combo-points if (uint32 combo = player->GetComboPoints()) { // Lookup for Deadly poison (only attacker applied) - if (AuraEffect const* aurEff = unitTarget->GetAuraEffect(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_ROGUE, 0x00010000, 0, 0, m_caster->GetGUID())) + if (AuraEffect const* aurEff = unitTarget->GetAuraEffect(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_ROGUE, 0x00010000, 0, 0, unitCaster->GetGUID())) { // count consumed deadly poison doses at target bool needConsume = true; @@ -542,7 +569,7 @@ void Spell::EffectSchoolDMG(SpellEffIndex effIndex) { if ((*iter)->GetSpellInfo()->SpellFamilyName == SPELLFAMILY_ROGUE && (*iter)->GetSpellInfo()->SpellIconID == 1960) { - uint32 chance = (*iter)->GetSpellInfo()->Effects[EFFECT_2].CalcValue(m_caster); + uint32 chance = (*iter)->GetSpellInfo()->Effects[EFFECT_2].CalcValue(unitCaster); if (chance && roll_chance_i(chance)) needConsume = false; @@ -553,14 +580,14 @@ void Spell::EffectSchoolDMG(SpellEffIndex effIndex) if (needConsume) for (uint32 i = 0; i < doses; ++i) - unitTarget->RemoveAuraFromStack(spellId, m_caster->GetGUID()); + unitTarget->RemoveAuraFromStack(spellId, unitCaster->GetGUID()); damage *= doses; damage += int32(player->GetTotalAttackPowerValue(BASE_ATTACK) * 0.09f * combo); } // Eviscerate and Envenom Bonus Damage (item set effect) - if (m_caster->HasAura(37169)) + if (unitCaster->HasAura(37169)) damage += combo * 40; } } @@ -568,15 +595,15 @@ void Spell::EffectSchoolDMG(SpellEffIndex effIndex) // Eviscerate else if (m_spellInfo->SpellFamilyFlags[0] & 0x00020000) { - if (Player* player = m_caster->ToPlayer()) + if (Player* player = unitCaster->ToPlayer()) { if (uint32 combo = player->GetComboPoints()) { - float ap = m_caster->GetTotalAttackPowerValue(BASE_ATTACK); + float ap = unitCaster->GetTotalAttackPowerValue(BASE_ATTACK); damage += std::lroundf(ap * combo * 0.07f); // Eviscerate and Envenom Bonus Damage (item set effect) - if (m_caster->HasAura(37169)) + if (unitCaster->HasAura(37169)) damage += combo*40; } } @@ -585,10 +612,13 @@ void Spell::EffectSchoolDMG(SpellEffIndex effIndex) } case SPELLFAMILY_HUNTER: { + if (!unitCaster) + break; + //Gore if (m_spellInfo->SpellIconID == 1578) { - if (m_caster->HasAura(57627)) // Charge 6 sec post-affect + if (unitCaster->HasAura(57627)) // Charge 6 sec post-affect damage *= 2; } // Steady Shot @@ -610,7 +640,7 @@ void Spell::EffectSchoolDMG(SpellEffIndex effIndex) if (found) damage += m_spellInfo->Effects[EFFECT_1].CalcValue(); - if (Player* caster = m_caster->ToPlayer()) + if (Player* caster = unitCaster->ToPlayer()) { // Add Ammo and Weapon damage plus RAP * 0.1 float dmg_min = 0.f; @@ -632,8 +662,11 @@ void Spell::EffectSchoolDMG(SpellEffIndex effIndex) } case SPELLFAMILY_PALADIN: { + if (!unitCaster) + break; + // Hammer of the Righteous - if (m_spellInfo->SpellFamilyFlags[1]&0x00040000) + if (m_spellInfo->SpellFamilyFlags[1] & 0x00040000) { float minTotal = 0.f; float maxTotal = 0.f; @@ -641,22 +674,22 @@ void Spell::EffectSchoolDMG(SpellEffIndex effIndex) float tmpMin, tmpMax; for (uint8 i = 0; i < MAX_ITEM_PROTO_DAMAGES; ++i) { - m_caster->CalculateMinMaxDamage(BASE_ATTACK, false, false, tmpMin, tmpMax, i); + unitCaster->CalculateMinMaxDamage(BASE_ATTACK, false, false, tmpMin, tmpMax, i); minTotal += tmpMin; maxTotal += tmpMax; } float average = (minTotal + maxTotal) / 2; // Add main hand dps * effect[2] amount - int32 count = m_caster->CalculateSpellDamage(unitTarget, m_spellInfo, EFFECT_2); - damage += count * int32(average * IN_MILLISECONDS) / m_caster->GetAttackTime(BASE_ATTACK); + int32 count = unitCaster->CalculateSpellDamage(m_spellInfo, EFFECT_2); + damage += count * int32(average * IN_MILLISECONDS) / unitCaster->GetAttackTime(BASE_ATTACK); break; } // Shield of Righteousness if (m_spellInfo->SpellFamilyFlags[EFFECT_1] & 0x100000) { - uint8 level = m_caster->getLevel(); - uint32 block_value = m_caster->GetShieldBlockValue(uint32(float(level) * 29.5f), uint32(float(level) * 39.5f)); + uint8 level = unitCaster->getLevel(); + uint32 block_value = unitCaster->GetShieldBlockValue(uint32(float(level) * 29.5f), uint32(float(level) * 39.5f)); damage += CalculatePct(block_value, m_spellInfo->Effects[EFFECT_1].CalcValue()); break; } @@ -664,23 +697,26 @@ void Spell::EffectSchoolDMG(SpellEffIndex effIndex) } case SPELLFAMILY_DEATHKNIGHT: { + if (!unitCaster) + break; + // Blood Boil - bonus for diseased targets if (m_spellInfo->SpellFamilyFlags[0] & 0x00040000) { - if (unitTarget->GetAuraEffect(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_DEATHKNIGHT, 0, 0, 0x00000002, m_caster->GetGUID())) + if (unitTarget->GetAuraEffect(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_DEATHKNIGHT, 0, 0, 0x00000002, unitCaster->GetGUID())) { damage += m_damage / 2; - damage += int32(m_caster->GetTotalAttackPowerValue(BASE_ATTACK) * 0.035f); + damage += int32(unitCaster->GetTotalAttackPowerValue(BASE_ATTACK) * 0.035f); } } break; } } - if (m_originalCaster && damage > 0 && apply_direct_bonus) + if (unitCaster && damage > 0 && apply_direct_bonus) { - damage = m_originalCaster->SpellDamageBonusDone(unitTarget, m_spellInfo, (uint32)damage, SPELL_DIRECT_DAMAGE, effIndex, { }); - damage = unitTarget->SpellDamageBonusTaken(m_originalCaster, m_spellInfo, (uint32)damage, SPELL_DIRECT_DAMAGE); + damage = unitCaster->SpellDamageBonusDone(unitTarget, m_spellInfo, (uint32)damage, SPELL_DIRECT_DAMAGE, effIndex, { }); + damage = unitTarget->SpellDamageBonusTaken(unitCaster, m_spellInfo, (uint32)damage, SPELL_DIRECT_DAMAGE); } m_damage += damage; @@ -768,10 +804,12 @@ void Spell::EffectTriggerSpell(SpellEffIndex effIndex) // Mirror Image case 58832: { - // Glyph of Mirror Image - if (m_caster->HasAura(63093)) - m_caster->CastSpell(m_caster, 65047, true); // Mirror Image + if (!unitCaster) + break; + // Glyph of Mirror Image + if (unitCaster->HasAura(63093)) + unitCaster->CastSpell(nullptr, 65047, true); // Mirror Image break; } // Demonic Empowerment -- succubus @@ -842,7 +880,12 @@ void Spell::EffectTriggerSpell(SpellEffIndex effIndex) if (Unit* target = m_targets.GetUnitTarget()) targets.SetUnitTarget(target); else - targets.SetUnitTarget(m_caster); + { + if (Unit* unit = m_caster->ToUnit()) + targets.SetUnitTarget(unit); + else if (GameObject* go = m_caster->ToGameObject()) + targets.SetGOTarget(go); + } } CastSpellExtraArgs args(m_originalCasterGUID); @@ -886,7 +929,10 @@ void Spell::EffectTriggerMissileSpell(SpellEffIndex effIndex) if (spellInfo->GetExplicitTargetMask() & TARGET_FLAG_DEST_LOCATION) targets.SetDst(m_targets); - targets.SetUnitTarget(m_caster); + if (Unit* unit = m_caster->ToUnit()) + targets.SetUnitTarget(unit); + else if (GameObject* go = m_caster->ToGameObject()) + targets.SetGOTarget(go); } CastSpellExtraArgs args(m_originalCasterGUID); @@ -971,20 +1017,35 @@ void Spell::EffectTriggerRitualOfSummoning(SpellEffIndex effIndex) m_caster->CastSpell(nullptr, spellInfo->Id, false); } +inline void CalculateJumpSpeeds(SpellInfo const* spellInfo, uint8 i, float dist, float& speedXY, float& speedZ) +{ + if (spellInfo->Effects[i].MiscValue) + speedZ = spellInfo->Effects[i].MiscValue / 10.f; + else if (spellInfo->Effects[i].MiscValueB) + speedZ = spellInfo->Effects[i].MiscValueB / 10.f; + else + speedZ = 10.0f; + + speedXY = dist * 10.0f / speedZ; +} + void Spell::EffectJump(SpellEffIndex effIndex) { if (effectHandleMode != SPELL_EFFECT_HANDLE_LAUNCH_TARGET) return; - if (m_caster->IsInFlight()) + if (!unitCaster) + return; + + if (unitCaster->IsInFlight()) return; if (!unitTarget) return; float speedXY, speedZ; - CalculateJumpSpeeds(effIndex, m_caster->GetExactDist2d(unitTarget), speedXY, speedZ); - m_caster->GetMotionMaster()->MoveJump(*unitTarget, speedXY, speedZ, EVENT_JUMP, false); + CalculateJumpSpeeds(m_spellInfo, effIndex, unitCaster->GetExactDist2d(unitTarget), speedXY, speedZ); + unitCaster->GetMotionMaster()->MoveJump(*unitTarget, speedXY, speedZ, EVENT_JUMP, false); } void Spell::EffectJumpDest(SpellEffIndex effIndex) @@ -992,26 +1053,18 @@ void Spell::EffectJumpDest(SpellEffIndex effIndex) if (effectHandleMode != SPELL_EFFECT_HANDLE_LAUNCH) return; - if (m_caster->IsInFlight()) + if (!unitCaster) + return; + + if (unitCaster->IsInFlight()) return; if (!m_targets.HasDst()) return; float speedXY, speedZ; - CalculateJumpSpeeds(effIndex, m_caster->GetExactDist2d(destTarget), speedXY, speedZ); - m_caster->GetMotionMaster()->MoveJump(*destTarget, speedXY, speedZ, EVENT_JUMP, !m_targets.GetObjectTargetGUID().IsEmpty()); -} - -void Spell::CalculateJumpSpeeds(uint8 i, float dist, float & speedXY, float & speedZ) -{ - if (m_spellInfo->Effects[i].MiscValue) - speedZ = float(m_spellInfo->Effects[i].MiscValue)/10; - else if (m_spellInfo->Effects[i].MiscValueB) - speedZ = float(m_spellInfo->Effects[i].MiscValueB)/10; - else - speedZ = 10.0f; - speedXY = dist * 10.0f / speedZ; + CalculateJumpSpeeds(m_spellInfo, effIndex, unitCaster->GetExactDist2d(destTarget), speedXY, speedZ); + unitCaster->GetMotionMaster()->MoveJump(*destTarget, speedXY, speedZ, EVENT_JUMP, !m_targets.GetObjectTargetGUID().IsEmpty()); } void Spell::EffectTeleportUnits(SpellEffIndex /*effIndex*/) @@ -1192,13 +1245,15 @@ void Spell::EffectPowerDrain(SpellEffIndex effIndex) return; Powers powerType = Powers(m_spellInfo->Effects[effIndex].MiscValue); - if (!unitTarget || !unitTarget->IsAlive() || unitTarget->GetPowerType() != powerType || damage < 0) return; // add spell damage bonus - damage = m_caster->SpellDamageBonusDone(unitTarget, m_spellInfo, uint32(damage), SPELL_DIRECT_DAMAGE, effIndex, { }); - damage = unitTarget->SpellDamageBonusTaken(m_caster, m_spellInfo, uint32(damage), SPELL_DIRECT_DAMAGE); + if (unitCaster) + { + damage = unitCaster->SpellDamageBonusDone(unitTarget, m_spellInfo, uint32(damage), SPELL_DIRECT_DAMAGE, effIndex, { }); + damage = unitTarget->SpellDamageBonusTaken(unitCaster, m_spellInfo, uint32(damage), SPELL_DIRECT_DAMAGE); + } // resilience reduce mana draining effect at spell crit damage reduction (added in 2.4) int32 power = damage; @@ -1207,16 +1262,14 @@ void Spell::EffectPowerDrain(SpellEffIndex effIndex) int32 newDamage = -(unitTarget->ModifyPower(powerType, -int32(power))); - float gainMultiplier = 0.0f; - // Don't restore from self drain - if (m_caster != unitTarget) + float gainMultiplier = 0.f; + if (unitCaster && unitCaster != unitTarget) { - gainMultiplier = m_spellInfo->Effects[effIndex].CalcValueMultiplier(m_originalCaster, this); - - int32 gain = int32(newDamage* gainMultiplier); + gainMultiplier = m_spellInfo->Effects[effIndex].CalcValueMultiplier(unitCaster, this); + int32 const gain = int32(newDamage * gainMultiplier); - m_caster->EnergizeBySpell(m_caster, m_spellInfo, gain, powerType); + unitCaster->EnergizeBySpell(unitCaster, m_spellInfo, gain, powerType); } ExecuteLogEffectTakeTargetPower(effIndex, unitTarget, powerType, newDamage, gainMultiplier); } @@ -1271,14 +1324,14 @@ void Spell::EffectPowerBurn(SpellEffIndex effIndex) return; Powers powerType = Powers(m_spellInfo->Effects[effIndex].MiscValue); - if (!unitTarget || !unitTarget->IsAlive() || unitTarget->GetPowerType() != powerType || damage < 0) return; // burn x% of target's mana, up to maximum of 2x% of caster's mana (Mana Burn) - if (m_spellInfo->Id == 8129) + ///@todo: move this to scripts + if (unitCaster && m_spellInfo->Id == 8129) { - int32 maxDamage = int32(CalculatePct(m_caster->GetMaxPower(powerType), damage * 2)); + int32 maxDamage = int32(CalculatePct(unitCaster->GetMaxPower(powerType), damage * 2)); damage = int32(CalculatePct(unitTarget->GetMaxPower(powerType), damage)); damage = std::min(damage, maxDamage); } @@ -1291,7 +1344,7 @@ void Spell::EffectPowerBurn(SpellEffIndex effIndex) int32 newDamage = -(unitTarget->ModifyPower(powerType, -power)); // NO - Not a typo - EffectPowerBurn uses effect value multiplier - not effect damage multiplier - float dmgMultiplier = m_spellInfo->Effects[effIndex].CalcValueMultiplier(m_originalCaster, this); + float dmgMultiplier = m_spellInfo->Effects[effIndex].CalcValueMultiplier(unitCaster, this); // add log data before multiplication (need power amount, not damage) ExecuteLogEffectTakeTargetPower(effIndex, unitTarget, powerType, newDamage, 0.0f); @@ -1306,115 +1359,107 @@ void Spell::EffectHeal(SpellEffIndex effIndex) if (effectHandleMode != SPELL_EFFECT_HANDLE_LAUNCH_TARGET) return; - if (unitTarget && unitTarget->IsAlive() && damage >= 0) - { - // Try to get original caster - Unit* caster = m_originalCasterGUID ? m_originalCaster : m_caster; - - // Skip if m_originalCaster not available - if (!caster) - return; + if (!unitTarget || !unitTarget->IsAlive() || damage < 0) + return; - int32 addhealth = damage; + // Skip if m_originalCaster not available + if (!unitCaster) + return; - // Vessel of the Naaru (Vial of the Sunwell trinket) - if (m_spellInfo->Id == 45064) - { - // Amount of heal - depends from stacked Holy Energy - int32 damageAmount = 0; - if (AuraEffect const* aurEff = m_caster->GetAuraEffect(45062, 0)) - { - damageAmount += aurEff->GetAmount(); - m_caster->RemoveAurasDueToSpell(45062); - } + int32 addhealth = damage; - addhealth += damageAmount; - } - // Runic Healing Injector (heal increased by 25% for engineers - 3.2.0 patch change) - else if (m_spellInfo->Id == 67489) + // Vessel of the Naaru (Vial of the Sunwell trinket) + ///@todo: move this to scripts + if (m_spellInfo->Id == 45064) + { + // Amount of heal - depends from stacked Holy Energy + int32 damageAmount = 0; + if (AuraEffect const* aurEff = unitCaster->GetAuraEffect(45062, 0)) { - if (Player* player = m_caster->ToPlayer()) - if (player->HasSkill(SKILL_ENGINEERING)) - AddPct(addhealth, 25); + damageAmount += aurEff->GetAmount(); + unitCaster->RemoveAurasDueToSpell(45062); } - // Swiftmend - consumes Regrowth or Rejuvenation - else if (m_spellInfo->TargetAuraState == AURA_STATE_SWIFTMEND && unitTarget->HasAuraState(AURA_STATE_SWIFTMEND, m_spellInfo, m_caster)) - { - Unit::AuraEffectList const& RejorRegr = unitTarget->GetAuraEffectsByType(SPELL_AURA_PERIODIC_HEAL); - // find most short by duration - AuraEffect* targetAura = nullptr; - for (Unit::AuraEffectList::const_iterator i = RejorRegr.begin(); i != RejorRegr.end(); ++i) - { - if ((*i)->GetSpellInfo()->SpellFamilyName == SPELLFAMILY_DRUID - && (*i)->GetSpellInfo()->SpellFamilyFlags[0] & 0x50) - { - if (!targetAura || (*i)->GetBase()->GetDuration() < targetAura->GetBase()->GetDuration()) - targetAura = *i; - } - } - if (!targetAura) + addhealth += damageAmount; + } + // Runic Healing Injector (heal increased by 25% for engineers - 3.2.0 patch change) + else if (m_spellInfo->Id == 67489) + { + if (Player* player = unitCaster->ToPlayer()) + if (player->HasSkill(SKILL_ENGINEERING)) + AddPct(addhealth, 25); + } + // Swiftmend - consumes Regrowth or Rejuvenation + else if (m_spellInfo->TargetAuraState == AURA_STATE_SWIFTMEND && unitTarget->HasAuraState(AURA_STATE_SWIFTMEND, m_spellInfo, unitCaster)) + { + Unit::AuraEffectList const& RejorRegr = unitTarget->GetAuraEffectsByType(SPELL_AURA_PERIODIC_HEAL); + // find most short by duration + AuraEffect* targetAura = nullptr; + for (Unit::AuraEffectList::const_iterator i = RejorRegr.begin(); i != RejorRegr.end(); ++i) + { + if ((*i)->GetSpellInfo()->SpellFamilyName == SPELLFAMILY_DRUID + && (*i)->GetSpellInfo()->SpellFamilyFlags[0] & 0x50) { - TC_LOG_ERROR("spells", "Target (%s) has the aurastate AURA_STATE_SWIFTMEND, but no matching aura.", unitTarget->GetGUID().ToString().c_str()); - return; + if (!targetAura || (*i)->GetBase()->GetDuration() < targetAura->GetBase()->GetDuration()) + targetAura = *i; } + } - int32 tickheal = targetAura->GetAmount(); - unitTarget->SpellHealingBonusTaken(m_caster, targetAura->GetSpellInfo(), tickheal, DOT); + if (!targetAura) + { + TC_LOG_ERROR("spells", "Target (%s) has the aurastate AURA_STATE_SWIFTMEND, but no matching aura.", unitTarget->GetGUID().ToString().c_str()); + return; + } - //int32 tickheal = targetAura->GetSpellInfo()->EffectBasePoints[idx] + 1; - //It is said that talent bonus should not be included + int32 tickheal = targetAura->GetAmount(); + unitTarget->SpellHealingBonusTaken(unitCaster, targetAura->GetSpellInfo(), tickheal, DOT); - int32 tickcount = 0; - // Rejuvenation - if (targetAura->GetSpellInfo()->SpellFamilyFlags[0] & 0x10) - tickcount = 4; - // Regrowth - else // if (targetAura->GetSpellInfo()->SpellFamilyFlags[0] & 0x40) - tickcount = 6; + int32 tickcount = 0; + // Rejuvenation + if (targetAura->GetSpellInfo()->SpellFamilyFlags[0] & 0x10) + tickcount = 4; + // Regrowth + else // if (targetAura->GetSpellInfo()->SpellFamilyFlags[0] & 0x40) + tickcount = 6; - addhealth += tickheal * tickcount; + addhealth += tickheal * tickcount; - // Glyph of Swiftmend - if (!caster->HasAura(54824)) - unitTarget->RemoveAura(targetAura->GetId(), targetAura->GetCasterGUID()); + // Glyph of Swiftmend + if (!unitCaster->HasAura(54824)) + unitTarget->RemoveAura(targetAura->GetId(), targetAura->GetCasterGUID()); + } + // Nourish + else if (m_spellInfo->SpellFamilyName == SPELLFAMILY_DRUID && m_spellInfo->SpellFamilyFlags[1] & 0x2000000) + { + addhealth = unitCaster->SpellHealingBonusDone(unitTarget, m_spellInfo, addhealth, HEAL, effIndex, { }); - //addhealth += tickheal * tickcount; - //addhealth = caster->SpellHealingBonus(m_spellInfo, addhealth, HEAL, unitTarget); - } - // Nourish - else if (m_spellInfo->SpellFamilyName == SPELLFAMILY_DRUID && m_spellInfo->SpellFamilyFlags[1] & 0x2000000) + // Glyph of Nourish + if (AuraEffect const* aurEff = unitCaster->GetAuraEffect(62971, 0)) { - addhealth = caster->SpellHealingBonusDone(unitTarget, m_spellInfo, addhealth, HEAL, effIndex, { }); - - // Glyph of Nourish - if (AuraEffect const* aurEff = m_caster->GetAuraEffect(62971, 0)) + uint32 auraCount = 0; + Unit::AuraEffectList const& periodicHeals = unitTarget->GetAuraEffectsByType(SPELL_AURA_PERIODIC_HEAL); + for (AuraEffect const* hot : periodicHeals) { - uint32 auraCount = 0; - Unit::AuraEffectList const& periodicHeals = unitTarget->GetAuraEffectsByType(SPELL_AURA_PERIODIC_HEAL); - for (AuraEffect const* hot : periodicHeals) - { - if (m_caster->GetGUID() == hot->GetCasterGUID()) - ++auraCount; - } - - AddPct(addhealth, aurEff->GetAmount() * auraCount); + if (unitCaster->GetGUID() == hot->GetCasterGUID()) + ++auraCount; } + + AddPct(addhealth, aurEff->GetAmount() * auraCount); } - // Death Pact - return pct of max health to caster - else if (m_spellInfo->SpellFamilyName == SPELLFAMILY_DEATHKNIGHT && m_spellInfo->SpellFamilyFlags[0] & 0x00080000) - addhealth = caster->SpellHealingBonusDone(unitTarget, m_spellInfo, int32(caster->CountPctFromMaxHealth(damage)), HEAL, effIndex, { }); - else - addhealth = caster->SpellHealingBonusDone(unitTarget, m_spellInfo, addhealth, HEAL, effIndex, { }); + } + // Death Pact - return pct of max health to caster + else if (m_spellInfo->SpellFamilyName == SPELLFAMILY_DEATHKNIGHT && m_spellInfo->SpellFamilyFlags[0] & 0x00080000) + addhealth = unitCaster->SpellHealingBonusDone(unitTarget, m_spellInfo, int32(unitCaster->CountPctFromMaxHealth(damage)), HEAL, effIndex, { }); + else + addhealth = unitCaster->SpellHealingBonusDone(unitTarget, m_spellInfo, addhealth, HEAL, effIndex, { }); - addhealth = unitTarget->SpellHealingBonusTaken(caster, m_spellInfo, addhealth, HEAL); + addhealth = unitTarget->SpellHealingBonusTaken(unitCaster, m_spellInfo, addhealth, HEAL); - // Remove Grievious bite if fully healed - if (unitTarget->HasAura(48920) && (unitTarget->GetHealth() + addhealth >= unitTarget->GetMaxHealth())) - unitTarget->RemoveAura(48920); + // Remove Grievious bite if fully healed + if (unitTarget->HasAura(48920) && (unitTarget->GetHealth() + addhealth >= unitTarget->GetMaxHealth())) + unitTarget->RemoveAura(48920); - m_healing += addhealth; - } + m_healing += addhealth; } void Spell::EffectHealPct(SpellEffIndex effIndex) @@ -1425,12 +1470,14 @@ void Spell::EffectHealPct(SpellEffIndex effIndex) if (!unitTarget || !unitTarget->IsAlive() || damage < 0) return; - // Skip if m_originalCaster not available - if (!m_originalCaster) - return; + uint32 heal = unitTarget->CountPctFromMaxHealth(damage); + if (unitCaster) + { + heal = unitCaster->SpellHealingBonusDone(unitTarget, m_spellInfo, heal, HEAL, effIndex, { }); + heal = unitTarget->SpellHealingBonusTaken(unitCaster, m_spellInfo, heal, HEAL); + } - uint32 heal = m_originalCaster->SpellHealingBonusDone(unitTarget, m_spellInfo, unitTarget->CountPctFromMaxHealth(damage), HEAL, effIndex, { }); - m_healing += unitTarget->SpellHealingBonusTaken(m_originalCaster, m_spellInfo, heal, HEAL); + m_healing += heal; } void Spell::EffectHealMechanical(SpellEffIndex effIndex) @@ -1441,12 +1488,14 @@ void Spell::EffectHealMechanical(SpellEffIndex effIndex) if (!unitTarget || !unitTarget->IsAlive() || damage < 0) return; - // Skip if m_originalCaster not available - if (!m_originalCaster) - return; + uint32 heal = damage; + if (unitCaster) + { + heal = unitCaster->SpellHealingBonusDone(unitTarget, m_spellInfo, heal, HEAL, effIndex, { }); + heal = unitTarget->SpellHealingBonusTaken(unitCaster, m_spellInfo, heal, HEAL); + } - uint32 heal = m_originalCaster->SpellHealingBonusDone(unitTarget, m_spellInfo, uint32(damage), HEAL, effIndex, { }); - m_healing += unitTarget->SpellHealingBonusTaken(m_originalCaster, m_spellInfo, heal, HEAL); + m_healing += heal; } void Spell::EffectHealthLeech(SpellEffIndex effIndex) @@ -1457,24 +1506,27 @@ void Spell::EffectHealthLeech(SpellEffIndex effIndex) if (!unitTarget || !unitTarget->IsAlive() || damage < 0) return; - damage = m_caster->SpellDamageBonusDone(unitTarget, m_spellInfo, uint32(damage), SPELL_DIRECT_DAMAGE, effIndex, { }); - damage = unitTarget->SpellDamageBonusTaken(m_caster, m_spellInfo, uint32(damage), SPELL_DIRECT_DAMAGE); + if (unitCaster) + { + damage = unitCaster->SpellDamageBonusDone(unitTarget, m_spellInfo, uint32(damage), SPELL_DIRECT_DAMAGE, effIndex, { }); + damage = unitTarget->SpellDamageBonusTaken(unitCaster, m_spellInfo, uint32(damage), SPELL_DIRECT_DAMAGE); + } TC_LOG_DEBUG("spells", "HealthLeech :%i", damage); - float healMultiplier = m_spellInfo->Effects[effIndex].CalcValueMultiplier(m_originalCaster, this); + float healMultiplier = m_spellInfo->Effects[effIndex].CalcValueMultiplier(unitCaster, this); m_damage += damage; // get max possible damage, don't count overkill for heal uint32 healthGain = uint32(-unitTarget->GetHealthGain(-damage) * healMultiplier); - if (m_caster->IsAlive()) + if (unitCaster && unitCaster->IsAlive()) { - healthGain = m_caster->SpellHealingBonusDone(m_caster, m_spellInfo, healthGain, HEAL, effIndex, { }); - healthGain = m_caster->SpellHealingBonusTaken(m_caster, m_spellInfo, healthGain, HEAL); + healthGain = unitCaster->SpellHealingBonusDone(unitCaster, m_spellInfo, healthGain, HEAL, effIndex, { }); + healthGain = unitCaster->SpellHealingBonusTaken(unitCaster, m_spellInfo, healthGain, HEAL); - HealInfo healInfo(m_caster, m_caster, healthGain, m_spellInfo, m_spellSchoolMask); - m_caster->HealBySpell(healInfo); + HealInfo healInfo(unitCaster, unitCaster, healthGain, m_spellInfo, m_spellSchoolMask); + unitCaster->HealBySpell(healInfo); } } @@ -1671,6 +1723,9 @@ void Spell::EffectPersistentAA(SpellEffIndex effIndex) if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT) return; + if (!unitCaster) + return; + // only handle at last effect for (uint8 i = effIndex + 1; i < MAX_SPELL_EFFECTS; ++i) if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_PERSISTENT_AREA_AURA) @@ -1678,15 +1733,14 @@ void Spell::EffectPersistentAA(SpellEffIndex effIndex) ASSERT(!_dynObjAura); - Unit* caster = m_caster->GetEntry() == WORLD_TRIGGER ? m_originalCaster : m_caster; - float radius = m_spellInfo->Effects[effIndex].CalcRadius(caster); + float radius = m_spellInfo->Effects[effIndex].CalcRadius(unitCaster); // Caster not in world, might be spell triggered from aura removal - if (!caster->IsInWorld()) + if (!unitCaster->IsInWorld()) return; DynamicObject* dynObj = new DynamicObject(false); - if (!dynObj->CreateDynamicObject(caster->GetMap()->GenerateLowGuid<HighGuid::DynamicObject>(), caster, m_spellInfo->Id, *destTarget, radius, DYNAMIC_OBJECT_AREA_SPELL)) + if (!dynObj->CreateDynamicObject(unitCaster->GetMap()->GenerateLowGuid<HighGuid::DynamicObject>(), unitCaster, m_spellInfo->Id, *destTarget, radius, DYNAMIC_OBJECT_AREA_SPELL)) { delete dynObj; return; @@ -1694,7 +1748,7 @@ void Spell::EffectPersistentAA(SpellEffIndex effIndex) AuraCreateInfo createInfo(m_spellInfo, MAX_EFFECT_MASK, dynObj); createInfo - .SetCaster(caster) + .SetCaster(unitCaster) .SetBaseAmount(m_spellValue->EffectBasePoints); if (Aura* aura = Aura::TryCreate(createInfo)) @@ -1714,8 +1768,9 @@ void Spell::EffectEnergize(SpellEffIndex effIndex) if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) return; - if (!unitTarget) + if (!unitCaster || !unitTarget) return; + if (!unitTarget->IsAlive()) return; @@ -1723,7 +1778,6 @@ void Spell::EffectEnergize(SpellEffIndex effIndex) return; Powers power = Powers(m_spellInfo->Effects[effIndex].MiscValue); - if (unitTarget->GetTypeId() == TYPEID_PLAYER && unitTarget->GetPowerType() != power && m_spellInfo->SpellFamilyName != SPELLFAMILY_POTION && !m_spellInfo->HasAttribute(SPELL_ATTR7_CAN_RESTORE_SECONDARY_POWER)) return; @@ -1732,20 +1786,21 @@ void Spell::EffectEnergize(SpellEffIndex effIndex) return; // Some level depends spells - int level_multiplier = 0; - int level_diff = 0; + ///@todo: move this to scripts + int32 level_multiplier = 0; + int32 level_diff = 0; switch (m_spellInfo->Id) { case 9512: // Restore Energy - level_diff = m_caster->getLevel() - 40; + level_diff = unitCaster->getLevel() - 40; level_multiplier = 2; break; case 24571: // Blood Fury - level_diff = m_caster->getLevel() - 60; + level_diff = unitCaster->getLevel() - 60; level_multiplier = 10; break; case 24532: // Burst of Energy - level_diff = m_caster->getLevel() - 60; + level_diff = unitCaster->getLevel() - 60; level_multiplier = 4; break; case 31930: // Judgements of the Wise @@ -1758,7 +1813,7 @@ void Spell::EffectEnergize(SpellEffIndex effIndex) break; case 67490: // Runic Mana Injector (mana gain increased by 25% for engineers - 3.2.0 patch change) { - if (Player* player = m_caster->ToPlayer()) + if (Player* player = unitCaster->ToPlayer()) if (player->HasSkill(SKILL_ENGINEERING)) AddPct(damage, 25); break; @@ -1776,7 +1831,7 @@ void Spell::EffectEnergize(SpellEffIndex effIndex) if (damage < 0) return; - m_caster->EnergizeBySpell(unitTarget, m_spellInfo, damage, power); + unitCaster->EnergizeBySpell(unitTarget, m_spellInfo, damage, power); } void Spell::EffectEnergizePct(SpellEffIndex effIndex) @@ -1784,8 +1839,9 @@ void Spell::EffectEnergizePct(SpellEffIndex effIndex) if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) return; - if (!unitTarget) + if (!unitCaster || !unitTarget) return; + if (!unitTarget->IsAlive()) return; @@ -1798,11 +1854,11 @@ void Spell::EffectEnergizePct(SpellEffIndex effIndex) return; uint32 maxPower = unitTarget->GetMaxPower(power); - if (maxPower == 0) + if (!maxPower) return; - uint32 gain = CalculatePct(maxPower, damage); - m_caster->EnergizeBySpell(unitTarget, m_spellInfo, gain, power); + uint32 const gain = CalculatePct(maxPower, damage); + unitCaster->EnergizeBySpell(unitTarget, m_spellInfo, gain, power); } void Spell::SendLoot(ObjectGuid guid, LootType loottype) @@ -1823,7 +1879,7 @@ void Spell::SendLoot(ObjectGuid guid, LootType loottype) // special case, already has GossipHello inside so return and avoid calling twice if (gameObjTarget->GetGoType() == GAMEOBJECT_TYPE_GOOBER) { - gameObjTarget->Use(m_caster); + gameObjTarget->Use(player); return; } @@ -1846,7 +1902,7 @@ void Spell::SendLoot(ObjectGuid guid, LootType loottype) case GAMEOBJECT_TYPE_SPELL_FOCUS: // triggering linked GO if (uint32 trapEntry = gameObjTarget->GetGOInfo()->spellFocus.linkedTrapId) - gameObjTarget->TriggeringLinkedGameObject(trapEntry, m_caster); + gameObjTarget->TriggeringLinkedGameObject(trapEntry, player); return; case GAMEOBJECT_TYPE_CHEST: @@ -1859,7 +1915,7 @@ void Spell::SendLoot(ObjectGuid guid, LootType loottype) // triggering linked GO if (uint32 trapEntry = gameObjTarget->GetGOInfo()->chest.linkedTrapId) - gameObjTarget->TriggeringLinkedGameObject(trapEntry, m_caster); + gameObjTarget->TriggeringLinkedGameObject(trapEntry, player); // Don't return, let loots been taken default: @@ -2129,11 +2185,12 @@ void Spell::EffectSummonType(SpellEffIndex effIndex) return; } - if (!m_originalCaster) - return; + WorldObject* caster = m_caster; + if (m_originalCaster) + caster = m_originalCaster; int32 duration = m_spellInfo->GetDuration(); - if (Player* modOwner = m_originalCaster->GetSpellModOwner()) + if (Player* modOwner = caster->GetSpellModOwner()) modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DURATION, duration); TempSummon* summon = nullptr; @@ -2174,11 +2231,13 @@ void Spell::EffectSummonType(SpellEffIndex effIndex) case SUMMON_CATEGORY_WILD: case SUMMON_CATEGORY_ALLY: case SUMMON_CATEGORY_UNK: + { if (properties->Flags & 512) { SummonGuardian(effIndex, entry, properties, numSummons); break; } + switch (properties->Type) { case SUMMON_TYPE_PET: @@ -2187,21 +2246,29 @@ void Spell::EffectSummonType(SpellEffIndex effIndex) case SUMMON_TYPE_MINION: SummonGuardian(effIndex, entry, properties, numSummons); break; - // Summons a vehicle, but doesn't force anyone to enter it (see SUMMON_CATEGORY_VEHICLE) + // Summons a vehicle, but doesn't force anyone to enter it (see SUMMON_CATEGORY_VEHICLE) case SUMMON_TYPE_VEHICLE: case SUMMON_TYPE_VEHICLE2: - summon = m_caster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, m_originalCaster, m_spellInfo->Id); + { + if (!unitCaster) + return; + + summon = unitCaster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, unitCaster, m_spellInfo->Id); break; + } case SUMMON_TYPE_LIGHTWELL: case SUMMON_TYPE_TOTEM: { - summon = m_caster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, m_originalCaster, m_spellInfo->Id); + if (!unitCaster) + return; + + summon = unitCaster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, unitCaster, m_spellInfo->Id); if (!summon || !summon->IsTotem()) return; // Mana Tide Totem if (m_spellInfo->Id == 16190) - damage = m_caster->CountPctFromMaxHealth(10); + damage = unitCaster->CountPctFromMaxHealth(10); if (damage) // if not spell info, DB values used { @@ -2212,7 +2279,10 @@ void Spell::EffectSummonType(SpellEffIndex effIndex) } case SUMMON_TYPE_MINIPET: { - summon = m_caster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, m_originalCaster, m_spellInfo->Id); + if (!unitCaster) + return; + + summon = unitCaster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, unitCaster, m_spellInfo->Id); if (!summon || !summon->HasUnitTypeMask(UNIT_MASK_MINION)) return; @@ -2236,16 +2306,16 @@ void Spell::EffectSummonType(SpellEffIndex effIndex) pos = *destTarget; else // randomize position for multiple summons - pos = m_caster->GetRandomPoint(*destTarget, radius); + pos = caster->GetRandomPoint(*destTarget, radius); - summon = m_originalCaster->SummonCreature(entry, pos, summonType, duration); + summon = caster->SummonCreature(entry, pos, summonType, duration); if (!summon) continue; if (properties->Category == SUMMON_CATEGORY_ALLY) { - summon->SetOwnerGUID(m_originalCaster->GetGUID()); - summon->SetFaction(m_originalCaster->GetFaction()); + summon->SetOwnerGUID(caster->GetGUID()); + summon->SetFaction(caster->GetFaction()); summon->SetUInt32Value(UNIT_CREATED_BY_SPELL, m_spellInfo->Id); } @@ -2253,18 +2323,28 @@ void Spell::EffectSummonType(SpellEffIndex effIndex) } return; } - }//switch + } break; + } case SUMMON_CATEGORY_PET: SummonGuardian(effIndex, entry, properties, numSummons); break; case SUMMON_CATEGORY_PUPPET: - summon = m_caster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, m_originalCaster, m_spellInfo->Id); + { + if (!unitCaster) + return; + + summon = unitCaster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, unitCaster, m_spellInfo->Id); break; + } case SUMMON_CATEGORY_VEHICLE: + { + if (!unitCaster) + return; + // Summoning spells (usually triggered by npc_spellclick) that spawn a vehicle and that cause the clicker // to cast a ride vehicle spell on the summoned unit. - summon = m_originalCaster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, m_caster, m_spellInfo->Id); + summon = unitCaster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, unitCaster, m_spellInfo->Id); if (!summon || !summon->IsVehicle()) return; @@ -2284,19 +2364,20 @@ void Spell::EffectSummonType(SpellEffIndex effIndex) if (basePoints > 0 && basePoints < MAX_VEHICLE_SEATS) args.AddSpellMod(SPELLVALUE_BASE_POINT0, basePoints); - m_originalCaster->CastSpell(summon, spellId, args); + unitCaster->CastSpell(summon, spellId, args); uint32 faction = properties->Faction; if (!faction) - faction = m_originalCaster->GetFaction(); + faction = unitCaster->GetFaction(); summon->SetFaction(faction); break; + } } if (summon) { - summon->SetCreatorGUID(m_originalCaster->GetGUID()); + summon->SetCreatorGUID(caster->GetGUID()); ExecuteLogEffectSummonObject(effIndex, summon); } } @@ -2484,17 +2565,18 @@ void Spell::EffectAddFarsight(SpellEffIndex effIndex) if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT) return; - if (m_caster->GetTypeId() != TYPEID_PLAYER) + Player* player = m_caster->ToPlayer(); + if (!player) return; float radius = m_spellInfo->Effects[effIndex].CalcRadius(); int32 duration = m_spellInfo->GetDuration(); // Caster not in world, might be spell triggered from aura removal - if (!m_caster->IsInWorld()) + if (!player->IsInWorld()) return; DynamicObject* dynObj = new DynamicObject(true); - if (!dynObj->CreateDynamicObject(m_caster->GetMap()->GenerateLowGuid<HighGuid::DynamicObject>(), m_caster, m_spellInfo->Id, *destTarget, radius, DYNAMIC_OBJECT_FARSIGHT_FOCUS)) + if (!dynObj->CreateDynamicObject(player->GetMap()->GenerateLowGuid<HighGuid::DynamicObject>(), player, m_spellInfo->Id, *destTarget, radius, DYNAMIC_OBJECT_FARSIGHT_FOCUS)) { delete dynObj; return; @@ -2863,7 +2945,7 @@ void Spell::EffectTameCreature(SpellEffIndex /*effIndex*/) if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) return; - if (m_caster->GetPetGUID()) + if (!unitCaster || unitCaster->GetPetGUID()) return; if (!unitTarget) @@ -2877,21 +2959,21 @@ void Spell::EffectTameCreature(SpellEffIndex /*effIndex*/) if (creatureTarget->IsPet()) return; - if (m_caster->getClass() != CLASS_HUNTER) + if (unitCaster->getClass() != CLASS_HUNTER) return; // cast finish successfully //SendChannelUpdate(0); finish(); - Pet* pet = m_caster->CreateTamedPetFrom(creatureTarget, m_spellInfo->Id); + Pet* pet = unitCaster->CreateTamedPetFrom(creatureTarget, m_spellInfo->Id); if (!pet) // in very specific state like near world end/etc. return; // "kill" original creature creatureTarget->DespawnOrUnsummon(); - uint8 level = (creatureTarget->getLevel() < (m_caster->getLevel() - 5)) ? (m_caster->getLevel() - 5) : creatureTarget->getLevel(); + uint8 level = (creatureTarget->getLevel() < (unitCaster->getLevel() - 5)) ? (unitCaster->getLevel() - 5) : creatureTarget->getLevel(); // prepare visual effect for levelup pet->SetUInt32Value(UNIT_FIELD_LEVEL, level - 1); @@ -2903,14 +2985,14 @@ void Spell::EffectTameCreature(SpellEffIndex /*effIndex*/) pet->SetUInt32Value(UNIT_FIELD_LEVEL, level); // caster have pet now - m_caster->SetMinion(pet, true); + unitCaster->SetMinion(pet, true); pet->InitTalentForLevel(); - if (m_caster->GetTypeId() == TYPEID_PLAYER) + if (unitCaster->GetTypeId() == TYPEID_PLAYER) { pet->SavePetToDB(PET_SAVE_AS_CURRENT); - m_caster->ToPlayer()->PetSpellInitialize(); + unitCaster->ToPlayer()->PetSpellInitialize(); } } @@ -2920,11 +3002,11 @@ void Spell::EffectSummonPet(SpellEffIndex effIndex) return; Player* owner = nullptr; - if (m_originalCaster) + if (unitCaster) { - owner = m_originalCaster->ToPlayer(); - if (!owner && m_originalCaster->IsTotem()) - owner = m_originalCaster->GetCharmerOrOwnerPlayerOrPlayerItself(); + owner = unitCaster->ToPlayer(); + if (!owner && unitCaster->IsTotem()) + owner = unitCaster->GetCharmerOrOwnerPlayerOrPlayerItself(); } uint32 petentry = m_spellInfo->Effects[effIndex].MiscValue; @@ -2986,7 +3068,7 @@ void Spell::EffectSummonPet(SpellEffIndex effIndex) if (m_caster->GetTypeId() == TYPEID_UNIT) { - if (m_caster->IsTotem()) + if (m_caster->ToCreature()->IsTotem()) pet->SetReactState(REACT_AGGRESSIVE); else pet->SetReactState(REACT_DEFENSIVE); @@ -3033,6 +3115,9 @@ void Spell::EffectTaunt(SpellEffIndex /*effIndex*/) if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) return; + if (!unitCaster) + return; + // this effect use before aura Taunt apply for prevent taunt already attacking target // for spell as marked "non effective at already attacking target" if (!unitTarget || !unitTarget->CanHaveThreatList()) @@ -3042,7 +3127,7 @@ void Spell::EffectTaunt(SpellEffIndex /*effIndex*/) } ThreatManager& mgr = unitTarget->GetThreatManager(); - if (mgr.GetCurrentVictim() == m_caster) + if (mgr.GetCurrentVictim() == unitCaster) { SendCastResult(SPELL_FAILED_DONT_REPORT); return; @@ -3050,11 +3135,11 @@ void Spell::EffectTaunt(SpellEffIndex /*effIndex*/) // Hand of Reckoning if (m_spellInfo->Id == 62124) - m_caster->CastSpell(unitTarget, 67485, true); + unitCaster->CastSpell(unitTarget, 67485, true); if (!mgr.IsThreatListEmpty()) // Set threat equal to highest threat currently on target - mgr.MatchUnitThreatToHighestThreat(m_caster); + mgr.MatchUnitThreatToHighestThreat(unitCaster); } void Spell::EffectWeaponDmg(SpellEffIndex effIndex) @@ -3062,6 +3147,9 @@ void Spell::EffectWeaponDmg(SpellEffIndex effIndex) if (effectHandleMode != SPELL_EFFECT_HANDLE_LAUNCH_TARGET) return; + if (!unitCaster) + return; + if (!unitTarget || !unitTarget->IsAlive()) return; @@ -3093,17 +3181,17 @@ void Spell::EffectWeaponDmg(SpellEffIndex effIndex) // Devastate (player ones) if (m_spellInfo->SpellFamilyFlags[1] & 0x40) { - m_caster->CastSpell(unitTarget, 58567, true); + unitCaster->CastSpell(unitTarget, 58567, true); // 58388 - Glyph of Devastate dummy aura. - if (m_caster->HasAura(58388)) - m_caster->CastSpell(unitTarget, 58567, true); + if (unitCaster->HasAura(58388)) + unitCaster->CastSpell(unitTarget, 58567, true); - if (Aura* aur = unitTarget->GetAura(58567, m_caster->GetGUID())) - fixed_bonus += (aur->GetStackAmount() - 1) * CalculateDamage(EFFECT_2, unitTarget); // subtract 1 so fixed bonus is not applied twice + if (Aura* aur = unitTarget->GetAura(58567, unitCaster->GetGUID())) + fixed_bonus += (aur->GetStackAmount() - 1) * CalculateDamage(EFFECT_2); // subtract 1 so fixed bonus is not applied twice } else if (m_spellInfo->SpellFamilyFlags[0] & 0x8000000) // Mocking Blow { - if (unitTarget->IsImmunedToSpellEffect(m_spellInfo, EFFECT_1, m_caster) || unitTarget->GetTypeId() == TYPEID_PLAYER) + if (unitTarget->IsImmunedToSpellEffect(m_spellInfo, EFFECT_1, unitCaster) || unitTarget->GetTypeId() == TYPEID_PLAYER) { m_damage = 0; return; @@ -3122,8 +3210,8 @@ void Spell::EffectWeaponDmg(SpellEffIndex effIndex) AddComboPointGain(unitTarget, 1); // 50% more damage with daggers - if (m_caster->GetTypeId() == TYPEID_PLAYER) - if (Item* item = m_caster->ToPlayer()->GetWeaponForAttack(m_attackType, true)) + if (unitCaster->GetTypeId() == TYPEID_PLAYER) + if (Item* item = unitCaster->ToPlayer()->GetWeaponForAttack(m_attackType, true)) if (item->GetTemplate()->SubClass == ITEM_SUBCLASS_WEAPON_DAGGER) totalDamagePercentMod *= 1.5f; } @@ -3132,7 +3220,7 @@ void Spell::EffectWeaponDmg(SpellEffIndex effIndex) { bool found = false; // fast check - if (unitTarget->HasAuraState(AURA_STATE_DEADLY_POISON, m_spellInfo, m_caster)) + if (unitTarget->HasAuraState(AURA_STATE_DEADLY_POISON, m_spellInfo, unitCaster)) found = true; // full aura scan else @@ -3158,8 +3246,8 @@ void Spell::EffectWeaponDmg(SpellEffIndex effIndex) // Seal of Command Unleashed if (m_spellInfo->Id == 20467) { - spell_bonus += int32(0.08f * m_caster->GetTotalAttackPowerValue(BASE_ATTACK)); - spell_bonus += int32(0.13f * m_caster->SpellBaseDamageBonusDone(m_spellInfo->GetSchoolMask())); + spell_bonus += int32(0.08f * unitCaster->GetTotalAttackPowerValue(BASE_ATTACK)); + spell_bonus += int32(0.13f * unitCaster->SpellBaseDamageBonusDone(m_spellInfo->GetSchoolMask())); } break; } @@ -3167,8 +3255,8 @@ void Spell::EffectWeaponDmg(SpellEffIndex effIndex) { // Skyshatter Harness item set bonus // Stormstrike - if (AuraEffect* aurEff = m_caster->IsScriptOverriden(m_spellInfo, 5634)) - m_caster->CastSpell(m_caster, 38430, aurEff); + if (AuraEffect* aurEff = unitCaster->IsScriptOverriden(m_spellInfo, 5634)) + unitCaster->CastSpell(nullptr, 38430, aurEff); break; } case SPELLFAMILY_DRUID: @@ -3180,7 +3268,7 @@ void Spell::EffectWeaponDmg(SpellEffIndex effIndex) // Shred, Maul - Rend and Tear else if (m_spellInfo->SpellFamilyFlags[0] & 0x00008800 && unitTarget->HasAuraState(AURA_STATE_BLEEDING)) { - if (AuraEffect const* rendAndTear = m_caster->GetDummyAuraEffect(SPELLFAMILY_DRUID, 2859, 0)) + if (AuraEffect const* rendAndTear = unitCaster->GetDummyAuraEffect(SPELLFAMILY_DRUID, 2859, 0)) AddPct(totalDamagePercentMod, rendAndTear->GetAmount()); } break; @@ -3189,7 +3277,7 @@ void Spell::EffectWeaponDmg(SpellEffIndex effIndex) { // Kill Shot - bonus damage from Ranged Attack Power if (m_spellInfo->SpellFamilyFlags[1] & 0x800000) - spell_bonus += int32(0.4f * m_caster->GetTotalAttackPowerValue(RANGED_ATTACK)); + spell_bonus += int32(0.4f * unitCaster->GetTotalAttackPowerValue(RANGED_ATTACK)); break; } case SPELLFAMILY_DEATHKNIGHT: @@ -3198,21 +3286,21 @@ void Spell::EffectWeaponDmg(SpellEffIndex effIndex) if (m_spellInfo->SpellFamilyFlags[0] & 0x1) { // Glyph of Plague Strike - if (AuraEffect const* aurEff = m_caster->GetAuraEffect(58657, EFFECT_0)) + if (AuraEffect const* aurEff = unitCaster->GetAuraEffect(58657, EFFECT_0)) AddPct(totalDamagePercentMod, aurEff->GetAmount()); break; } // Blood Strike if (m_spellInfo->SpellFamilyFlags[0] & 0x400000) { - float bonusPct = m_spellInfo->Effects[EFFECT_2].CalcValue() * unitTarget->GetDiseasesByCaster(m_caster->GetGUID()) / 2.0f; + float bonusPct = m_spellInfo->Effects[EFFECT_2].CalcValue() * unitTarget->GetDiseasesByCaster(unitCaster->GetGUID()) / 2.0f; // Death Knight T8 Melee 4P Bonus - if (AuraEffect const* aurEff = m_caster->GetAuraEffect(64736, EFFECT_0)) + if (AuraEffect const* aurEff = unitCaster->GetAuraEffect(64736, EFFECT_0)) AddPct(bonusPct, aurEff->GetAmount()); AddPct(totalDamagePercentMod, bonusPct); // Glyph of Blood Strike - if (m_caster->GetAuraEffect(59332, EFFECT_0)) + if (unitCaster->GetAuraEffect(59332, EFFECT_0)) if (unitTarget->HasAuraType(SPELL_AURA_MOD_DECREASE_SPEED)) AddPct(totalDamagePercentMod, 20); break; @@ -3221,8 +3309,8 @@ void Spell::EffectWeaponDmg(SpellEffIndex effIndex) if (m_spellInfo->SpellFamilyFlags[0] & 0x10) { // Glyph of Death Strike - if (AuraEffect const* aurEff = m_caster->GetAuraEffect(59336, EFFECT_0)) - if (uint32 runic = std::min<uint32>(m_caster->GetPower(POWER_RUNIC_POWER), aurEff->GetSpellInfo()->Effects[EFFECT_1].CalcValue())) + if (AuraEffect const* aurEff = unitCaster->GetAuraEffect(59336, EFFECT_0)) + if (uint32 runic = std::min<uint32>(unitCaster->GetPower(POWER_RUNIC_POWER), aurEff->GetSpellInfo()->Effects[EFFECT_1].CalcValue())) AddPct(totalDamagePercentMod, runic); break; } @@ -3231,14 +3319,14 @@ void Spell::EffectWeaponDmg(SpellEffIndex effIndex) { bool consumeDiseases = true; // Annihilation - if (AuraEffect const* aurEff = m_caster->GetDummyAuraEffect(SPELLFAMILY_DEATHKNIGHT, 2710, EFFECT_0)) + if (AuraEffect const* aurEff = unitCaster->GetDummyAuraEffect(SPELLFAMILY_DEATHKNIGHT, 2710, EFFECT_0)) // Do not consume diseases if roll sucesses if (roll_chance_i(aurEff->GetAmount())) consumeDiseases = false; - float bonusPct = m_spellInfo->Effects[EFFECT_2].CalcValue() * unitTarget->GetDiseasesByCaster(m_caster->GetGUID(), consumeDiseases) / 2.0f; + float bonusPct = m_spellInfo->Effects[EFFECT_2].CalcValue() * unitTarget->GetDiseasesByCaster(unitCaster->GetGUID(), consumeDiseases) / 2.0f; // Death Knight T8 Melee 4P Bonus - if (AuraEffect const* aurEff = m_caster->GetAuraEffect(64736, EFFECT_0)) + if (AuraEffect const* aurEff = unitCaster->GetAuraEffect(64736, EFFECT_0)) AddPct(bonusPct, aurEff->GetAmount()); AddPct(totalDamagePercentMod, bonusPct); break; @@ -3246,15 +3334,15 @@ void Spell::EffectWeaponDmg(SpellEffIndex effIndex) // Blood-Caked Strike - Blood-Caked Blade if (m_spellInfo->SpellIconID == 1736) { - AddPct(totalDamagePercentMod, unitTarget->GetDiseasesByCaster(m_caster->GetGUID()) * 50.0f); + AddPct(totalDamagePercentMod, unitTarget->GetDiseasesByCaster(unitCaster->GetGUID()) * 50.0f); break; } // Heart Strike if (m_spellInfo->SpellFamilyFlags[0] & 0x1000000) { - float bonusPct = m_spellInfo->Effects[EFFECT_2].CalcValue() * unitTarget->GetDiseasesByCaster(m_caster->GetGUID()); + float bonusPct = m_spellInfo->Effects[EFFECT_2].CalcValue() * unitTarget->GetDiseasesByCaster(unitCaster->GetGUID()); // Death Knight T8 Melee 4P Bonus - if (AuraEffect const* aurEff = m_caster->GetAuraEffect(64736, EFFECT_0)) + if (AuraEffect const* aurEff = unitCaster->GetAuraEffect(64736, EFFECT_0)) AddPct(bonusPct, aurEff->GetAmount()); AddPct(totalDamagePercentMod, bonusPct); @@ -3272,14 +3360,14 @@ void Spell::EffectWeaponDmg(SpellEffIndex effIndex) { case SPELL_EFFECT_WEAPON_DAMAGE: case SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL: - fixed_bonus += CalculateDamage(j, unitTarget); + fixed_bonus += CalculateDamage(j); break; case SPELL_EFFECT_NORMALIZED_WEAPON_DMG: - fixed_bonus += CalculateDamage(j, unitTarget); + fixed_bonus += CalculateDamage(j); normalized = true; break; case SPELL_EFFECT_WEAPON_PERCENT_DAMAGE: - ApplyPct(weaponDamagePercentMod, CalculateDamage(j, unitTarget)); + ApplyPct(weaponDamagePercentMod, CalculateDamage(j)); break; default: break; // not weapon damage effect, just skip @@ -3300,14 +3388,14 @@ void Spell::EffectWeaponDmg(SpellEffIndex effIndex) case RANGED_ATTACK: unitMod = UNIT_MOD_DAMAGE_RANGED; break; } - float weapon_total_pct = m_caster->GetPctModifierValue(unitMod, TOTAL_PCT); + float weapon_total_pct = unitCaster->GetPctModifierValue(unitMod, TOTAL_PCT); if (fixed_bonus) fixed_bonus = int32(fixed_bonus * weapon_total_pct); if (spell_bonus) spell_bonus = int32(spell_bonus * weapon_total_pct); } - int32 weaponDamage = m_caster->CalculateDamage(m_attackType, normalized, addPctMods); + int32 weaponDamage = unitCaster->CalculateDamage(m_attackType, normalized, addPctMods); // Sequence is important for (uint8 j = 0; j < MAX_SPELL_EFFECTS; ++j) @@ -3333,15 +3421,15 @@ void Spell::EffectWeaponDmg(SpellEffIndex effIndex) weaponDamage = int32(weaponDamage * totalDamagePercentMod); // apply spellmod to Done damage - if (Player* modOwner = m_caster->GetSpellModOwner()) + if (Player* modOwner = unitCaster->GetSpellModOwner()) modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DAMAGE, weaponDamage); // prevent negative damage weaponDamage = std::max(weaponDamage, 0); // Add melee damage bonuses (also check for negative) - weaponDamage = m_caster->MeleeDamageBonusDone(unitTarget, weaponDamage, m_attackType, m_spellInfo); - m_damage += unitTarget->MeleeDamageBonusTaken(m_caster, weaponDamage, m_attackType, m_spellInfo); + weaponDamage = unitCaster->MeleeDamageBonusDone(unitTarget, weaponDamage, m_attackType, m_spellInfo); + m_damage += unitTarget->MeleeDamageBonusTaken(unitCaster, weaponDamage, m_attackType, m_spellInfo); } void Spell::EffectThreat(SpellEffIndex /*effIndex*/) @@ -3349,13 +3437,16 @@ void Spell::EffectThreat(SpellEffIndex /*effIndex*/) if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) return; - if (!unitTarget || !m_caster->IsAlive()) + if (!unitCaster || !unitCaster->IsAlive()) + return; + + if (!unitTarget) return; if (!unitTarget->CanHaveThreatList()) return; - unitTarget->GetThreatManager().AddThreat(m_caster, float(damage), m_spellInfo, true); + unitTarget->GetThreatManager().AddThreat(unitCaster, float(damage), m_spellInfo, true); } void Spell::EffectHealMaxHealth(SpellEffIndex /*effIndex*/) @@ -3363,6 +3454,9 @@ void Spell::EffectHealMaxHealth(SpellEffIndex /*effIndex*/) if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) return; + if (!unitCaster) + return; + if (!unitTarget || !unitTarget->IsAlive()) return; @@ -3370,7 +3464,7 @@ void Spell::EffectHealMaxHealth(SpellEffIndex /*effIndex*/) // damage == 0 - heal for caster max health if (damage == 0) - addhealth = m_caster->GetMaxHealth(); + addhealth = unitCaster->GetMaxHealth(); else addhealth = unitTarget->GetMaxHealth() - unitTarget->GetHealth(); @@ -3400,11 +3494,11 @@ void Spell::EffectInterruptCast(SpellEffIndex effIndex) && ((i == CURRENT_GENERIC_SPELL && curSpellInfo->InterruptFlags & SPELL_INTERRUPT_FLAG_INTERRUPT) || (i == CURRENT_CHANNELED_SPELL && curSpellInfo->ChannelInterruptFlags & CHANNEL_INTERRUPT_FLAG_INTERRUPT))) { - if (m_originalCaster) + if (unitCaster) { int32 duration = m_spellInfo->GetDuration(); unitTarget->GetSpellHistory()->LockSpellSchool(curSpellInfo->GetSchoolMask(), unitTarget->ModSpellDuration(m_spellInfo, unitTarget, duration, false, 1 << effIndex)); - Unit::ProcSkillsAndAuras(m_originalCaster, unitTarget, PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG, PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_NEG, PROC_SPELL_TYPE_MASK_ALL, PROC_SPELL_PHASE_HIT, PROC_HIT_INTERRUPT, nullptr, nullptr, nullptr); + Unit::ProcSkillsAndAuras(unitCaster, unitTarget, PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG, PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_NEG, PROC_SPELL_TYPE_MASK_ALL, PROC_SPELL_PHASE_HIT, PROC_HIT_INTERRUPT, nullptr, nullptr, nullptr); } ExecuteLogEffectInterruptCast(effIndex, unitTarget, curSpellInfo->Id); unitTarget->InterruptSpell(CurrentSpellTypes(i), false); @@ -3471,7 +3565,7 @@ void Spell::EffectScriptEffect(SpellEffIndex effIndex) return; /// @todo we must implement hunter pet summon at login there (spell 6962) - + /// @todo: move this to scripts switch (m_spellInfo->SpellFamilyName) { case SPELLFAMILY_GENERIC: @@ -3481,6 +3575,9 @@ void Spell::EffectScriptEffect(SpellEffIndex effIndex) // Glyph of Scourge Strike case 69961: { + if (!unitCaster) + return; + Unit::AuraEffectList const& mPeriodic = unitTarget->GetAuraEffectsByType(SPELL_AURA_PERIODIC_DAMAGE); for (Unit::AuraEffectList::const_iterator i = mPeriodic.begin(); i != mPeriodic.end(); ++i) { @@ -3488,7 +3585,7 @@ void Spell::EffectScriptEffect(SpellEffIndex effIndex) SpellInfo const* spellInfo = aurEff->GetSpellInfo(); // search our Blood Plague and Frost Fever on target if (spellInfo->SpellFamilyName == SPELLFAMILY_DEATHKNIGHT && spellInfo->SpellFamilyFlags[2] & 0x2 && - aurEff->GetCasterGUID() == m_caster->GetGUID()) + aurEff->GetCasterGUID() == unitCaster->GetGUID()) { uint32 countMin = aurEff->GetBase()->GetMaxDuration(); uint32 countMax = spellInfo->GetMaxDuration(); @@ -3496,7 +3593,7 @@ void Spell::EffectScriptEffect(SpellEffIndex effIndex) // this Glyph countMax += 9000; // talent Epidemic - if (AuraEffect const* epidemic = m_caster->GetAuraEffect(SPELL_AURA_ADD_FLAT_MODIFIER, SPELLFAMILY_DEATHKNIGHT, 234, EFFECT_0)) + if (AuraEffect const* epidemic = unitCaster->GetAuraEffect(SPELL_AURA_ADD_FLAT_MODIFIER, SPELLFAMILY_DEATHKNIGHT, 234, EFFECT_0)) countMax += epidemic->GetAmount(); if (countMin < countMax) @@ -3519,8 +3616,7 @@ void Spell::EffectScriptEffect(SpellEffIndex effIndex) if (!itemTarget && m_caster->GetTypeId() != TYPEID_PLAYER) return; - uint32 spell_id = roll_chance_i(20) ? 8854 : 8855; - + uint32 const spell_id = roll_chance_i(20) ? 8854 : 8855; m_caster->CastSpell(m_caster, spell_id, true); return; } @@ -3655,14 +3751,13 @@ void Spell::EffectScriptEffect(SpellEffIndex effIndex) unitTarget->CastSpell(unitTarget, spellId, true); break; } - // 5, 000 Gold + // 5,000 Gold case 46642: { if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) return; unitTarget->ToPlayer()->ModifyMoney(5000 * GOLD); - break; } // Death Knight Initiate Visual @@ -3736,8 +3831,8 @@ void Spell::EffectScriptEffect(SpellEffIndex effIndex) unitTarget->ToTempSummon()->UnSummon(); return; case 52479: // Gift of the Harvester - if (unitTarget && m_originalCaster) - m_originalCaster->CastSpell(unitTarget, urand(0, 1) ? damage : 52505, true); + if (unitTarget && unitCaster) + unitCaster->CastSpell(unitTarget, urand(0, 1) ? damage : 52505, true); return; case 53110: // Devour Humanoid if (unitTarget) @@ -3793,14 +3888,17 @@ void Spell::EffectScriptEffect(SpellEffIndex effIndex) } case 62482: // Grab Crate { + if (!unitCaster) + return; + if (unitTarget) { - if (Unit* seat = m_caster->GetVehicleBase()) + if (Unit* seat = unitCaster->GetVehicleBase()) { if (Unit* parent = seat->GetVehicleBase()) { /// @todo a hack, range = 11, should after some time cast, otherwise too far - m_caster->CastSpell(parent, 62496, true); + unitCaster->CastSpell(parent, 62496, true); unitTarget->CastSpell(parent, m_spellInfo->Effects[EFFECT_0].CalcValue()); } } @@ -3809,7 +3907,7 @@ void Spell::EffectScriptEffect(SpellEffIndex effIndex) } case 60123: // Lightwell { - if (m_caster->GetTypeId() != TYPEID_UNIT || !m_caster->IsSummon()) + if (m_caster->GetTypeId() != TYPEID_UNIT || !m_caster->ToCreature()->IsSummon()) return; uint32 spell_heal; @@ -3828,11 +3926,11 @@ void Spell::EffectScriptEffect(SpellEffIndex effIndex) } // proc a spellcast - if (Aura* chargesAura = m_caster->GetAura(59907)) + if (Aura* chargesAura = m_caster->ToCreature()->GetAura(59907)) { - m_caster->CastSpell(unitTarget, spell_heal, m_caster->ToTempSummon()->GetSummonerGUID()); + m_caster->CastSpell(unitTarget, spell_heal, m_caster->ToCreature()->ToTempSummon()->GetSummonerGUID()); if (chargesAura->ModCharges(-1)) - m_caster->ToTempSummon()->UnSummon(); + m_caster->ToCreature()->ToTempSummon()->UnSummon(); } return; @@ -3987,29 +4085,29 @@ void Spell::EffectDuel(SpellEffIndex effIndex) Position const pos = { - m_caster->GetPositionX() + (unitTarget->GetPositionX() - m_caster->GetPositionX()) / 2, - m_caster->GetPositionY() + (unitTarget->GetPositionY() - m_caster->GetPositionY()) / 2, - m_caster->GetPositionZ(), - m_caster->GetOrientation() + caster->GetPositionX() + (unitTarget->GetPositionX() - caster->GetPositionX()) / 2, + caster->GetPositionY() + (unitTarget->GetPositionY() - caster->GetPositionY()) / 2, + caster->GetPositionZ(), + caster->GetOrientation() }; - Map* map = m_caster->GetMap(); + Map* map = caster->GetMap(); QuaternionData rot = QuaternionData::fromEulerAnglesZYX(pos.GetOrientation(), 0.f, 0.f); - if (!pGameObj->Create(map->GenerateLowGuid<HighGuid::GameObject>(), gameobject_id, map, m_caster->GetPhaseMask(), pos, rot, 0, GO_STATE_READY)) + if (!pGameObj->Create(map->GenerateLowGuid<HighGuid::GameObject>(), gameobject_id, map, caster->GetPhaseMask(), pos, rot, 0, GO_STATE_READY)) { delete pGameObj; return; } - pGameObj->SetFaction(m_caster->GetFaction()); - pGameObj->SetUInt32Value(GAMEOBJECT_LEVEL, m_caster->getLevel()+1); + pGameObj->SetFaction(caster->GetFaction()); + pGameObj->SetUInt32Value(GAMEOBJECT_LEVEL, caster->getLevel() + 1); int32 duration = m_spellInfo->GetDuration(); pGameObj->SetRespawnTime(duration > 0 ? duration/IN_MILLISECONDS : 0); pGameObj->SetSpellId(m_spellInfo->Id); ExecuteLogEffectSummonObject(effIndex, pGameObj); - m_caster->AddGameObject(pGameObj); + caster->AddGameObject(pGameObj); map->AddToMap(pGameObj); //END @@ -4095,10 +4193,13 @@ void Spell::EffectSummonPlayer(SpellEffIndex /*effIndex*/) if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) return; + if (!unitCaster) + return; + if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) return; - unitTarget->ToPlayer()->SendSummonRequestFrom(m_caster); + unitTarget->ToPlayer()->SendSummonRequestFrom(unitCaster); } void Spell::EffectActivateObject(SpellEffIndex /*effIndex*/) @@ -4140,7 +4241,7 @@ void Spell::EffectApplyGlyph(SpellEffIndex effIndex) case 4: minLevel = 70; break; case 5: minLevel = 80; break; } - if (minLevel && m_caster->getLevel() < minLevel) + if (minLevel && player->getLevel() < minLevel) { SendCastResult(SPELL_FAILED_GLYPH_SOCKET_LOCKED); return; @@ -4170,7 +4271,7 @@ void Spell::EffectApplyGlyph(SpellEffIndex effIndex) } } - player->CastSpell(m_caster, gp->SpellId, true); + player->CastSpell(player, gp->SpellId, true); player->SetGlyph(m_glyphIndex, glyph); player->SendTalentsInfoData(false); } @@ -4319,50 +4420,53 @@ void Spell::EffectSummonObject(SpellEffIndex effIndex) if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT) return; + if (!unitCaster) + return; + uint32 go_id = m_spellInfo->Effects[effIndex].MiscValue; uint8 slot = m_spellInfo->Effects[effIndex].Effect - SPELL_EFFECT_SUMMON_OBJECT_SLOT1; - if (ObjectGuid guid = m_caster->m_ObjectSlot[slot]) + if (ObjectGuid guid = unitCaster->m_ObjectSlot[slot]) { - if (GameObject* obj = m_caster->GetMap()->GetGameObject(guid)) + if (GameObject* obj = unitCaster->GetMap()->GetGameObject(guid)) { // Recast case - null spell id to make auras not be removed on object remove from world if (m_spellInfo->Id == obj->GetSpellId()) obj->SetSpellId(0); - m_caster->RemoveGameObject(obj, true); + unitCaster->RemoveGameObject(obj, true); } - m_caster->m_ObjectSlot[slot].Clear(); + unitCaster->m_ObjectSlot[slot].Clear(); } GameObject* go = new GameObject(); - float x, y, z; // If dest location if present if (m_targets.HasDst()) destTarget->GetPosition(x, y, z); // Summon in random point all other units if location present else - m_caster->GetClosePoint(x, y, z, DEFAULT_PLAYER_BOUNDING_RADIUS); + unitCaster->GetClosePoint(x, y, z, DEFAULT_PLAYER_BOUNDING_RADIUS); - Map* map = m_caster->GetMap(); - QuaternionData rot = QuaternionData::fromEulerAnglesZYX(m_caster->GetOrientation(), 0.f, 0.f); - if (!go->Create(map->GenerateLowGuid<HighGuid::GameObject>(), go_id, map, m_caster->GetPhaseMask(), Position(x, y, z, m_caster->GetOrientation()), rot, 255, GO_STATE_READY)) + Map* map = unitCaster->GetMap(); + QuaternionData rot = QuaternionData::fromEulerAnglesZYX(unitCaster->GetOrientation(), 0.f, 0.f); + if (!go->Create(map->GenerateLowGuid<HighGuid::GameObject>(), go_id, map, unitCaster->GetPhaseMask(), Position(x, y, z, unitCaster->GetOrientation()), rot, 255, GO_STATE_READY)) { delete go; return; } - //pGameObj->SetUInt32Value(GAMEOBJECT_LEVEL, m_caster->getLevel()); + go->SetFaction(unitCaster->GetFaction()); + go->SetUInt32Value(GAMEOBJECT_LEVEL, unitCaster->getLevel()); int32 duration = m_spellInfo->GetDuration(); - go->SetRespawnTime(duration > 0 ? duration/IN_MILLISECONDS : 0); + go->SetRespawnTime(duration > 0 ? duration / IN_MILLISECONDS : 0); go->SetSpellId(m_spellInfo->Id); - m_caster->AddGameObject(go); + unitCaster->AddGameObject(go); ExecuteLogEffectSummonObject(effIndex, go); map->AddToMap(go); - m_caster->m_ObjectSlot[slot] = go->GetGUID(); + unitCaster->m_ObjectSlot[slot] = go->GetGUID(); } void Spell::EffectResurrect(SpellEffIndex effIndex) @@ -4491,23 +4595,26 @@ void Spell::EffectForceDeselect(SpellEffIndex /*effIndex*/) if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT) return; - float dist = m_caster->GetVisibilityRange(); + if (!unitCaster) + return; + + float dist = unitCaster->GetVisibilityRange(); // clear focus - WorldPacket data(SMSG_BREAK_TARGET, m_caster->GetPackGUID().size()); - data << m_caster->GetPackGUID(); - Trinity::MessageDistDelivererToHostile notifierBreak(m_caster, &data, dist); - Cell::VisitWorldObjects(m_caster, notifierBreak, dist); + WorldPacket data(SMSG_BREAK_TARGET, unitCaster->GetPackGUID().size()); + data << unitCaster->GetPackGUID(); + Trinity::MessageDistDelivererToHostile notifierBreak(unitCaster, &data, dist); + Cell::VisitWorldObjects(unitCaster, notifierBreak, dist); // and selection data.Initialize(SMSG_CLEAR_TARGET, 8); - data << uint64(m_caster->GetGUID()); - Trinity::MessageDistDelivererToHostile notifierClear(m_caster, &data, dist); - Cell::VisitWorldObjects(m_caster, notifierClear, dist); + data << uint64(unitCaster->GetGUID()); + Trinity::MessageDistDelivererToHostile notifierClear(unitCaster, &data, dist); + Cell::VisitWorldObjects(unitCaster, notifierClear, dist); // we should also force pets to remove us from current target Unit::AttackerSet attackerSet; - for (Unit::AttackerSet::const_iterator itr = m_caster->getAttackers().begin(); itr != m_caster->getAttackers().end(); ++itr) + for (Unit::AttackerSet::const_iterator itr = unitCaster->getAttackers().begin(); itr != unitCaster->getAttackers().end(); ++itr) if ((*itr)->GetTypeId() == TYPEID_UNIT && !(*itr)->CanHaveThreatList()) attackerSet.insert(*itr); @@ -4520,11 +4627,8 @@ void Spell::EffectSelfResurrect(SpellEffIndex effIndex) if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT) return; - if (!m_caster || m_caster->IsAlive()) - return; - if (m_caster->GetTypeId() != TYPEID_PLAYER) - return; - if (!m_caster->IsInWorld()) + Player* player = m_caster->ToPlayer(); + if (!player || !player->IsInWorld() || player->IsAlive()) return; uint32 health = 0; @@ -4539,12 +4643,11 @@ void Spell::EffectSelfResurrect(SpellEffIndex effIndex) // percent case else { - health = m_caster->CountPctFromMaxHealth(damage); - if (m_caster->GetMaxPower(POWER_MANA) > 0) - mana = CalculatePct(m_caster->GetMaxPower(POWER_MANA), damage); + health = player->CountPctFromMaxHealth(damage); + if (player->GetMaxPower(POWER_MANA) > 0) + mana = CalculatePct(player->GetMaxPower(POWER_MANA), damage); } - Player* player = m_caster->ToPlayer(); player->ResurrectPlayer(0.0f); player->SetHealth(health); @@ -4562,7 +4665,9 @@ void Spell::EffectSkinning(SpellEffIndex /*effIndex*/) if (unitTarget->GetTypeId() != TYPEID_UNIT) return; - if (m_caster->GetTypeId() != TYPEID_PLAYER) + + Player* player = m_caster->ToPlayer(); + if (!player) return; Creature* creature = unitTarget->ToCreature(); @@ -4572,14 +4677,13 @@ void Spell::EffectSkinning(SpellEffIndex /*effIndex*/) creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SKINNABLE); creature->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE); - m_caster->ToPlayer()->SendLoot(creature->GetGUID(), LOOT_SKINNING); - - int32 reqValue = targetLevel < 10 ? 0 : targetLevel < 20 ? (targetLevel-10)*10 : targetLevel*5; + player->SendLoot(creature->GetGUID(), LOOT_SKINNING); - int32 skillValue = m_caster->ToPlayer()->GetPureSkillValue(skill); + int32 const reqValue = targetLevel < 10 ? 0 : (targetLevel < 20 ? (targetLevel - 10) * 10 : targetLevel * 5); + int32 const skillValue = player->GetPureSkillValue(skill); // Double chances for elites - m_caster->ToPlayer()->UpdateGatherSkill(skill, skillValue, reqValue, creature->isElite() ? 2 : 1); + player->UpdateGatherSkill(skill, skillValue, reqValue, creature->isElite() ? 2 : 1); } void Spell::EffectCharge(SpellEffIndex /*effIndex*/) @@ -4587,11 +4691,14 @@ void Spell::EffectCharge(SpellEffIndex /*effIndex*/) if (!unitTarget) return; + if (!unitCaster) + return; + if (effectHandleMode == SPELL_EFFECT_HANDLE_LAUNCH_TARGET) { // charge changes fall time - if (m_caster->GetTypeId() == TYPEID_PLAYER) - m_caster->ToPlayer()->SetFallInformation(0, m_caster->GetPositionZ()); + if (unitCaster->GetTypeId() == TYPEID_PLAYER) + unitCaster->ToPlayer()->SetFallInformation(0, unitCaster->GetPositionZ()); float speed = G3D::fuzzyGt(m_spellInfo->Speed, 0.0f) ? m_spellInfo->Speed : SPEED_CHARGE; // Spell is not using explicit target - no generated path @@ -4599,17 +4706,17 @@ void Spell::EffectCharge(SpellEffIndex /*effIndex*/) { //unitTarget->GetContactPoint(m_caster, pos.m_positionX, pos.m_positionY, pos.m_positionZ); Position pos = unitTarget->GetFirstCollisionPosition(unitTarget->GetCombatReach(), unitTarget->GetRelativeAngle(m_caster)); - m_caster->GetMotionMaster()->MoveCharge(pos.m_positionX, pos.m_positionY, pos.m_positionZ, speed); + unitCaster->GetMotionMaster()->MoveCharge(pos.m_positionX, pos.m_positionY, pos.m_positionZ, speed); } else - m_caster->GetMotionMaster()->MoveCharge(*m_preGeneratedPath, speed); + unitCaster->GetMotionMaster()->MoveCharge(*m_preGeneratedPath, speed); } if (effectHandleMode == SPELL_EFFECT_HANDLE_HIT_TARGET) { // not all charge effects used in negative spells if (!m_spellInfo->IsPositive() && m_caster->GetTypeId() == TYPEID_PLAYER) - m_caster->Attack(unitTarget, true); + unitCaster->Attack(unitTarget, true); } } @@ -4618,18 +4725,21 @@ void Spell::EffectChargeDest(SpellEffIndex /*effIndex*/) if (effectHandleMode != SPELL_EFFECT_HANDLE_LAUNCH) return; + if (!unitCaster) + return; + if (m_targets.HasDst()) { Position pos = destTarget->GetPosition(); - if (!m_caster->IsWithinLOS(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ())) + if (!unitCaster->IsWithinLOS(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ())) { - float angle = m_caster->GetRelativeAngle(pos.GetPositionX(), pos.GetPositionY()); - float dist = m_caster->GetDistance(pos); - pos = m_caster->GetFirstCollisionPosition(dist, angle); + float angle = unitCaster->GetRelativeAngle(pos.GetPositionX(), pos.GetPositionY()); + float dist = unitCaster->GetDistance(pos); + pos = unitCaster->GetFirstCollisionPosition(dist, angle); } - m_caster->GetMotionMaster()->MoveCharge(pos.m_positionX, pos.m_positionY, pos.m_positionZ); + unitCaster->GetMotionMaster()->MoveCharge(pos.m_positionX, pos.m_positionY, pos.m_positionZ); } } @@ -4641,7 +4751,7 @@ void Spell::EffectKnockBack(SpellEffIndex effIndex) if (!unitTarget) return; - if (m_caster->GetTypeId() == TYPEID_PLAYER || m_caster->GetOwnerGUID().IsPlayer() || m_caster->IsHunterPet()) + if (m_caster->GetAffectingPlayer()) if (Creature* creatureTarget = unitTarget->ToCreature()) if (creatureTarget->isWorldBoss() || creatureTarget->IsDungeonBoss()) return; @@ -4669,9 +4779,7 @@ void Spell::EffectKnockBack(SpellEffIndex effIndex) return; } else //if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_KNOCK_BACK) - { m_caster->GetPosition(x, y); - } unitTarget->KnockbackFrom(x, y, speedxy, speedz); } @@ -4869,13 +4977,16 @@ void Spell::EffectDestroyAllTotems(SpellEffIndex /*effIndex*/) if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT) return; + if (!unitCaster) + return; + int32 mana = 0; for (uint8 slot = SUMMON_SLOT_TOTEM; slot < MAX_TOTEM_SLOT; ++slot) { - if (!m_caster->m_SummonSlot[slot]) + if (!unitCaster->m_SummonSlot[slot]) continue; - Creature* totem = m_caster->GetMap()->GetCreature(m_caster->m_SummonSlot[slot]); + Creature* totem = unitCaster->GetMap()->GetCreature(unitCaster->m_SummonSlot[slot]); if (totem && totem->IsTotem()) { uint32 spell_id = totem->GetUInt32Value(UNIT_CREATED_BY_SPELL); @@ -4883,7 +4994,7 @@ void Spell::EffectDestroyAllTotems(SpellEffIndex /*effIndex*/) if (spellInfo) { mana += spellInfo->ManaCost; - mana += int32(CalculatePct(m_caster->GetCreateMana(), spellInfo->ManaCostPercentage)); + mana += int32(CalculatePct(unitCaster->GetCreateMana(), spellInfo->ManaCostPercentage)); } totem->ToTotem()->UnSummon(); } @@ -4893,7 +5004,7 @@ void Spell::EffectDestroyAllTotems(SpellEffIndex /*effIndex*/) { CastSpellExtraArgs args(TRIGGERED_FULL_MASK); args.AddSpellMod(SPELLVALUE_BASE_POINT0, mana); - m_caster->CastSpell(m_caster, 39104, args); + unitCaster->CastSpell(unitCaster, 39104, args); } } @@ -4960,10 +5071,10 @@ void Spell::EffectModifyThreatPercent(SpellEffIndex /*effIndex*/) if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) return; - if (!unitTarget) + if (!unitCaster || !unitTarget) return; - unitTarget->GetThreatManager().ModifyThreatByPercent(m_caster, damage); + unitTarget->GetThreatManager().ModifyThreatByPercent(unitCaster, damage); } void Spell::EffectTransmitted(SpellEffIndex effIndex) @@ -4971,10 +5082,11 @@ void Spell::EffectTransmitted(SpellEffIndex effIndex) if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT) return; - uint32 name_id = m_spellInfo->Effects[effIndex].MiscValue; + if (!unitCaster) + return; + uint32 name_id = m_spellInfo->Effects[effIndex].MiscValue; GameObjectTemplate const* goinfo = sObjectMgr->GetGameObjectTemplate(name_id); - if (!goinfo) { TC_LOG_ERROR("sql.sql", "Gameobject (Entry: %u) does not exist and is not created by spell (ID: %u) cast.", name_id, m_spellInfo->Id); @@ -4988,8 +5100,8 @@ void Spell::EffectTransmitted(SpellEffIndex effIndex) //FIXME: this can be better check for most objects but still hack else if (m_spellInfo->Effects[effIndex].HasRadius() && m_spellInfo->Speed == 0) { - float dis = m_spellInfo->Effects[effIndex].CalcRadius(m_originalCaster); - m_caster->GetClosePoint(fx, fy, fz, DEFAULT_PLAYER_BOUNDING_RADIUS, dis); + float dis = m_spellInfo->Effects[effIndex].CalcRadius(unitCaster); + unitCaster->GetClosePoint(fx, fy, fz, DEFAULT_PLAYER_BOUNDING_RADIUS, dis); } else { @@ -4998,32 +5110,31 @@ void Spell::EffectTransmitted(SpellEffIndex effIndex) float max_dis = m_spellInfo->GetMaxRange(true); float dis = (float)rand_norm() * (max_dis - min_dis) + min_dis; - m_caster->GetClosePoint(fx, fy, fz, DEFAULT_PLAYER_BOUNDING_RADIUS, dis); + unitCaster->GetClosePoint(fx, fy, fz, DEFAULT_PLAYER_BOUNDING_RADIUS, dis); } - Map* cMap = m_caster->GetMap(); + Map* cMap = unitCaster->GetMap(); // if gameobject is summoning object, it should be spawned right on caster's position if (goinfo->type == GAMEOBJECT_TYPE_SUMMONING_RITUAL) - m_caster->GetPosition(fx, fy, fz); + unitCaster->GetPosition(fx, fy, fz); GameObject* pGameObj = new GameObject; - Position pos = { fx, fy, fz, m_caster->GetOrientation() }; - QuaternionData rot = QuaternionData::fromEulerAnglesZYX(m_caster->GetOrientation(), 0.f, 0.f); - if (!pGameObj->Create(cMap->GenerateLowGuid<HighGuid::GameObject>(), name_id, cMap, m_caster->GetPhaseMask(), pos, rot, 255, GO_STATE_READY)) + Position pos = { fx, fy, fz, unitCaster->GetOrientation() }; + QuaternionData rot = QuaternionData::fromEulerAnglesZYX(unitCaster->GetOrientation(), 0.f, 0.f); + if (!pGameObj->Create(cMap->GenerateLowGuid<HighGuid::GameObject>(), name_id, cMap, unitCaster->GetPhaseMask(), pos, rot, 255, GO_STATE_READY)) { delete pGameObj; return; } int32 duration = m_spellInfo->GetDuration(); - switch (goinfo->type) { case GAMEOBJECT_TYPE_FISHINGNODE: { - m_caster->SetChannelObjectGuid(pGameObj->GetGUID()); - m_caster->AddGameObject(pGameObj); // will removed at spell cancel + unitCaster->SetChannelObjectGuid(pGameObj->GetGUID()); + unitCaster->AddGameObject(pGameObj); // will removed at spell cancel // end time of range when possible catch fish (FISHING_BOBBER_READY_TIME..GetDuration(m_spellInfo)) // start time == fish-FISHING_BOBBER_READY_TIME (0..GetDuration(m_spellInfo)-FISHING_BOBBER_READY_TIME) @@ -5041,15 +5152,15 @@ void Spell::EffectTransmitted(SpellEffIndex effIndex) } case GAMEOBJECT_TYPE_SUMMONING_RITUAL: { - if (m_caster->GetTypeId() == TYPEID_PLAYER) + if (unitCaster->GetTypeId() == TYPEID_PLAYER) { - pGameObj->AddUniqueUse(m_caster->ToPlayer()); - m_caster->AddGameObject(pGameObj); // will be removed at spell cancel + pGameObj->AddUniqueUse(unitCaster->ToPlayer()); + unitCaster->AddGameObject(pGameObj); // will be removed at spell cancel } break; } case GAMEOBJECT_TYPE_DUEL_ARBITER: // 52991 - m_caster->AddGameObject(pGameObj); + unitCaster->AddGameObject(pGameObj); break; case GAMEOBJECT_TYPE_FISHINGHOLE: case GAMEOBJECT_TYPE_CHEST: @@ -5059,15 +5170,15 @@ void Spell::EffectTransmitted(SpellEffIndex effIndex) pGameObj->SetRespawnTime(duration > 0 ? duration/IN_MILLISECONDS : 0); - pGameObj->SetOwnerGUID(m_caster->GetGUID()); + pGameObj->SetOwnerGUID(unitCaster->GetGUID()); - //pGameObj->SetUInt32Value(GAMEOBJECT_LEVEL, m_caster->getLevel()); + //pGameObj->SetUInt32Value(GAMEOBJECT_LEVEL, unitCaster->getLevel()); pGameObj->SetSpellId(m_spellInfo->Id); ExecuteLogEffectSummonObject(effIndex, pGameObj); TC_LOG_DEBUG("spells", "AddObject at SpellEfects.cpp EffectTransmitted"); - //m_caster->AddGameObject(pGameObj); + //unitCaster->AddGameObject(pGameObj); //m_ObjToDel.push_back(pGameObj); cMap->AddToMap(pGameObj); @@ -5075,9 +5186,9 @@ void Spell::EffectTransmitted(SpellEffIndex effIndex) if (GameObject* linkedTrap = pGameObj->GetLinkedTrap()) { linkedTrap->SetRespawnTime(duration > 0 ? duration/IN_MILLISECONDS : 0); - //linkedTrap->SetUInt32Value(GAMEOBJECT_LEVEL, m_caster->getLevel()); + //linkedTrap->SetUInt32Value(GAMEOBJECT_LEVEL, unitCaster->getLevel()); linkedTrap->SetSpellId(m_spellInfo->Id); - linkedTrap->SetOwnerGUID(m_caster->GetGUID()); + linkedTrap->SetOwnerGUID(unitCaster->GetGUID()); ExecuteLogEffectSummonObject(effIndex, linkedTrap); } @@ -5470,8 +5581,11 @@ void Spell::EffectRedirectThreat(SpellEffIndex /*effIndex*/) if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) return; + if (!unitCaster) + return; + if (unitTarget) - m_caster->GetThreatManager().RegisterRedirectThreat(m_spellInfo->Id, unitTarget->GetGUID(), uint32(damage)); + unitCaster->GetThreatManager().RegisterRedirectThreat(m_spellInfo->Id, unitTarget->GetGUID(), uint32(damage)); } void Spell::EffectGameObjectDamage(SpellEffIndex /*effIndex*/) @@ -5482,15 +5596,11 @@ void Spell::EffectGameObjectDamage(SpellEffIndex /*effIndex*/) if (!gameObjTarget) return; - Unit* caster = m_originalCaster; - if (!caster) - return; - - FactionTemplateEntry const* casterFaction = caster->GetFactionTemplateEntry(); + FactionTemplateEntry const* casterFaction = m_caster->GetFactionTemplateEntry(); FactionTemplateEntry const* targetFaction = sFactionTemplateStore.LookupEntry(gameObjTarget->GetFaction()); // Do not allow to damage GO's of friendly factions (ie: Wintergrasp Walls/Ulduar Storm Beacons) if (!targetFaction || (casterFaction && !casterFaction->IsFriendlyTo(*targetFaction))) - gameObjTarget->ModifyHealth(-damage, caster, GetSpellInfo()->Id); + gameObjTarget->ModifyHealth(-damage, m_caster, GetSpellInfo()->Id); } void Spell::EffectGameObjectRepair(SpellEffIndex /*effIndex*/) @@ -5509,41 +5619,38 @@ void Spell::EffectGameObjectSetDestructionState(SpellEffIndex effIndex) if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) return; - if (!gameObjTarget || !m_originalCaster) + if (!gameObjTarget) return; - Player* player = m_originalCaster->GetCharmerOrOwnerPlayerOrPlayerItself(); - gameObjTarget->SetDestructibleState(GameObjectDestructibleState(m_spellInfo->Effects[effIndex].MiscValue), player, true); + gameObjTarget->SetDestructibleState(GameObjectDestructibleState(m_spellInfo->Effects[effIndex].MiscValue), m_caster, true); } void Spell::SummonGuardian(uint32 i, uint32 entry, SummonPropertiesEntry const* properties, uint32 numGuardians) { - Unit* caster = m_originalCaster; - if (!caster) + if (!unitCaster) return; - if (caster->IsTotem()) - caster = caster->ToTotem()->GetOwner(); + if (unitCaster->IsTotem()) + unitCaster = unitCaster->ToTotem()->GetOwner(); // in another case summon new - uint8 level = caster->getLevel(); + uint8 level = unitCaster->getLevel(); // level of pet summoned using engineering item based at engineering skill level - if (m_CastItem && caster->GetTypeId() == TYPEID_PLAYER) + if (m_CastItem && unitCaster->GetTypeId() == TYPEID_PLAYER) if (ItemTemplate const* proto = m_CastItem->GetTemplate()) if (proto->RequiredSkill == SKILL_ENGINEERING) - if (uint16 skill202 = caster->ToPlayer()->GetSkillValue(SKILL_ENGINEERING)) + if (uint16 skill202 = unitCaster->ToPlayer()->GetSkillValue(SKILL_ENGINEERING)) level = skill202 / 5; float radius = 5.0f; int32 duration = m_spellInfo->GetDuration(); - if (Player* modOwner = m_originalCaster->GetSpellModOwner()) + if (Player* modOwner = unitCaster->GetSpellModOwner()) modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DURATION, duration); //TempSummonType summonType = (duration == 0) ? TEMPSUMMON_DEAD_DESPAWN : TEMPSUMMON_TIMED_DESPAWN; - Map* map = caster->GetMap(); - + Map* map = unitCaster->GetMap(); for (uint32 count = 0; count < numGuardians; ++count) { Position pos; @@ -5551,9 +5658,9 @@ void Spell::SummonGuardian(uint32 i, uint32 entry, SummonPropertiesEntry const* pos = *destTarget; else // randomize position for multiple summons - pos = m_caster->GetRandomPoint(*destTarget, radius); + pos = unitCaster->GetRandomPoint(*destTarget, radius); - TempSummon* summon = map->SummonCreature(entry, pos, properties, duration, caster, m_spellInfo->Id); + TempSummon* summon = map->SummonCreature(entry, pos, properties, duration, unitCaster, m_spellInfo->Id); if (!summon) return; @@ -5561,14 +5668,14 @@ void Spell::SummonGuardian(uint32 i, uint32 entry, SummonPropertiesEntry const* ((Guardian*)summon)->InitStatsForLevel(level); if (properties && properties->Category == SUMMON_CATEGORY_ALLY) - summon->SetFaction(caster->GetFaction()); + summon->SetFaction(unitCaster->GetFaction()); if (summon->HasUnitTypeMask(UNIT_MASK_MINION) && m_targets.HasDst()) - ((Minion*)summon)->SetFollowAngle(m_caster->GetAngle(summon)); + ((Minion*)summon)->SetFollowAngle(unitCaster->GetAngle(summon)); if (summon->GetEntry() == 27893) { - if (uint32 weapon = m_caster->GetUInt32Value(PLAYER_VISIBLE_ITEM_16_ENTRYID)) + if (uint32 weapon = unitCaster->GetUInt32Value(PLAYER_VISIBLE_ITEM_16_ENTRYID)) { summon->SetDisplayId(11686); // modelid2 summon->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, weapon); @@ -5687,16 +5794,16 @@ void Spell::EffectCastButtons(SpellEffIndex effIndex) if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT) return; - if (m_caster->GetTypeId() != TYPEID_PLAYER) + Player* player = m_caster->ToPlayer(); + if (!player) return; - Player* p_caster = m_caster->ToPlayer(); uint32 button_id = m_spellInfo->Effects[effIndex].MiscValue + 132; uint32 n_buttons = m_spellInfo->Effects[effIndex].MiscValueB; for (; n_buttons; --n_buttons, ++button_id) { - ActionButton const* ab = p_caster->GetActionButton(button_id); + ActionButton const* ab = player->GetActionButton(button_id); if (!ab || ab->GetType() != ACTION_BUTTON_SPELL) continue; @@ -5710,18 +5817,18 @@ void Spell::EffectCastButtons(SpellEffIndex effIndex) if (!spellInfo) continue; - if (!p_caster->HasSpell(spell_id) || p_caster->GetSpellHistory()->HasCooldown(spell_id)) + if (!player->HasSpell(spell_id) || player->GetSpellHistory()->HasCooldown(spell_id)) continue; if (!spellInfo->HasAttribute(SPELL_ATTR7_SUMMON_PLAYER_TOTEM)) continue; - uint32 cost = spellInfo->CalcPowerCost(m_caster, spellInfo->GetSchoolMask()); - if (m_caster->GetPower(POWER_MANA) < cost) + uint32 cost = spellInfo->CalcPowerCost(player, spellInfo->GetSchoolMask()); + if (player->GetPower(POWER_MANA) < cost) continue; TriggerCastFlags triggerFlags = TriggerCastFlags(TRIGGERED_IGNORE_GCD | TRIGGERED_IGNORE_CAST_IN_PROGRESS | TRIGGERED_CAST_DIRECTLY); - m_caster->CastSpell(m_caster, spell_id, triggerFlags); + player->CastSpell(player, spell_id, triggerFlags); } } |
