diff options
| author | Subv <s.v.h21@hotmail.com> | 2012-08-22 17:26:53 -0500 |
|---|---|---|
| committer | Subv <s.v.h21@hotmail.com> | 2012-08-22 17:26:53 -0500 |
| commit | dc95ce61b46ce2d542ee4c4dbdf35a9e854c4316 (patch) | |
| tree | e673101dc6554a76dfacb5cf3497dd1d2bde4f41 /src/server/scripts/Spells | |
| parent | cecaab7948d5289439d1334d7bedcaae90e1fe3a (diff) | |
| parent | 85ed0e32a9b2b029c1db3cf1a914b3940cf72b9b (diff) | |
Merge branch 'master' of github.com:TrinityCore/TrinityCore into mmaps
Conflicts:
dep/PackageList.txt
src/server/game/Movement/MotionMaster.cpp
src/server/game/Movement/MovementGenerators/HomeMovementGenerator.cpp
src/server/game/Movement/MovementGenerators/PointMovementGenerator.h
src/server/game/Movement/Spline/MoveSplineInit.h
src/server/game/World/World.h
Diffstat (limited to 'src/server/scripts/Spells')
| -rw-r--r-- | src/server/scripts/Spells/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | src/server/scripts/Spells/spell_dk.cpp | 93 | ||||
| -rw-r--r-- | src/server/scripts/Spells/spell_druid.cpp | 320 | ||||
| -rw-r--r-- | src/server/scripts/Spells/spell_generic.cpp | 551 | ||||
| -rw-r--r-- | src/server/scripts/Spells/spell_holiday.cpp | 7 | ||||
| -rw-r--r-- | src/server/scripts/Spells/spell_hunter.cpp | 89 | ||||
| -rw-r--r-- | src/server/scripts/Spells/spell_item.cpp | 102 | ||||
| -rw-r--r-- | src/server/scripts/Spells/spell_mage.cpp | 47 | ||||
| -rw-r--r-- | src/server/scripts/Spells/spell_paladin.cpp | 168 | ||||
| -rw-r--r-- | src/server/scripts/Spells/spell_pet.cpp | 1744 | ||||
| -rw-r--r-- | src/server/scripts/Spells/spell_priest.cpp | 182 | ||||
| -rw-r--r-- | src/server/scripts/Spells/spell_quest.cpp | 149 | ||||
| -rw-r--r-- | src/server/scripts/Spells/spell_rogue.cpp | 31 | ||||
| -rw-r--r-- | src/server/scripts/Spells/spell_shaman.cpp | 198 | ||||
| -rw-r--r-- | src/server/scripts/Spells/spell_warlock.cpp | 175 | ||||
| -rw-r--r-- | src/server/scripts/Spells/spell_warrior.cpp | 95 |
16 files changed, 3743 insertions, 209 deletions
diff --git a/src/server/scripts/Spells/CMakeLists.txt b/src/server/scripts/Spells/CMakeLists.txt index 04dcee9287c..2bb695bd8a9 100644 --- a/src/server/scripts/Spells/CMakeLists.txt +++ b/src/server/scripts/Spells/CMakeLists.txt @@ -24,6 +24,7 @@ set(scripts_STAT_SRCS Spells/spell_paladin.cpp Spells/spell_item.cpp Spells/spell_holiday.cpp + Spells/spell_pet.cpp ) message(" -> Prepared: Spells") diff --git a/src/server/scripts/Spells/spell_dk.cpp b/src/server/scripts/Spells/spell_dk.cpp index 5d874faf411..a1c48878507 100644 --- a/src/server/scripts/Spells/spell_dk.cpp +++ b/src/server/scripts/Spells/spell_dk.cpp @@ -40,6 +40,8 @@ enum DeathKnightSpells DK_SPELL_IMPROVED_BLOOD_PRESENCE_TRIGGERED = 63611, DK_SPELL_UNHOLY_PRESENCE = 48265, DK_SPELL_IMPROVED_UNHOLY_PRESENCE_TRIGGERED = 63622, + SPELL_DK_ITEM_T8_MELEE_4P_BONUS = 64736, + DK_SPELL_BLACK_ICE_R1 = 49140, }; // 50462 - Anti-Magic Shell (on raid member) @@ -111,8 +113,7 @@ class spell_dk_anti_magic_shell_self : public SpellScriptLoader void CalculateAmount(AuraEffect const* /*aurEff*/, int32 & amount, bool & /*canBeRecalculated*/) { - // Set absorbtion amount to unlimited - amount = -1; + amount = GetCaster()->CountPctFromMaxHealth(hpPct); } void Absorb(AuraEffect* /*aurEff*/, DamageInfo & dmgInfo, uint32 & absorbAmount) @@ -334,16 +335,30 @@ class spell_dk_death_pact : public SpellScriptLoader { PrepareSpellScript(spell_dk_death_pact_SpellScript); - void FilterTargets(std::list<Unit*>& unitList) + SpellCastResult CheckCast() + { + // Check if we have valid targets, otherwise skip spell casting here + if (Player* player = GetCaster()->ToPlayer()) + for (Unit::ControlList::const_iterator itr = player->m_Controlled.begin(); itr != player->m_Controlled.end(); ++itr) + if (Creature* undeadPet = (*itr)->ToCreature()) + if (undeadPet->isAlive() && + undeadPet->GetOwnerGUID() == player->GetGUID() && + undeadPet->GetCreatureType() == CREATURE_TYPE_UNDEAD && + undeadPet->IsWithinDist(player, 100.0f, false)) + return SPELL_CAST_OK; + + return SPELL_FAILED_NO_PET; + } + + void FilterTargets(std::list<WorldObject*>& unitList) { Unit* unit_to_add = NULL; - for (std::list<Unit*>::iterator itr = unitList.begin(); itr != unitList.end(); ++itr) + for (std::list<WorldObject*>::iterator itr = unitList.begin(); itr != unitList.end(); ++itr) { - if ((*itr)->GetTypeId() == TYPEID_UNIT - && (*itr)->GetOwnerGUID() == GetCaster()->GetGUID() - && (*itr)->ToCreature()->GetCreatureTemplate()->type == CREATURE_TYPE_UNDEAD) + if (Unit* unit = (*itr)->ToUnit()) + if (unit->GetOwnerGUID() == GetCaster()->GetGUID() && unit->GetCreatureType() == CREATURE_TYPE_UNDEAD) { - unit_to_add = (*itr); + unit_to_add = unit; break; } } @@ -351,18 +366,12 @@ class spell_dk_death_pact : public SpellScriptLoader unitList.clear(); if (unit_to_add) unitList.push_back(unit_to_add); - else - { - // Pet not found - remove cooldown - if (Player* modOwner = GetCaster()->GetSpellModOwner()) - modOwner->RemoveSpellCooldown(GetSpellInfo()->Id, true); - FinishCast(SPELL_FAILED_NO_PET); - } } void Register() { - OnUnitTargetSelect += SpellUnitTargetFn(spell_dk_death_pact_SpellScript::FilterTargets, EFFECT_1, TARGET_UNIT_DEST_AREA_ALLY); + OnCheckCast += SpellCheckCastFn(spell_dk_death_pact_SpellScript::CheckCast); + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_dk_death_pact_SpellScript::FilterTargets, EFFECT_1, TARGET_UNIT_DEST_AREA_ALLY); } }; @@ -381,6 +390,13 @@ class spell_dk_scourge_strike : public SpellScriptLoader class spell_dk_scourge_strike_SpellScript : public SpellScript { PrepareSpellScript(spell_dk_scourge_strike_SpellScript); + float multiplier; + + bool Load() + { + multiplier = 1.0f; + return true; + } bool Validate(SpellInfo const* /*spellEntry*/) { @@ -394,7 +410,23 @@ class spell_dk_scourge_strike : public SpellScriptLoader Unit* caster = GetCaster(); if (Unit* unitTarget = GetHitUnit()) { - int32 bp = CalculatePctN(GetHitDamage(), GetEffectValue() * unitTarget->GetDiseasesByCaster(caster->GetGUID())); + multiplier = (GetEffectValue() * unitTarget->GetDiseasesByCaster(caster->GetGUID()) / 100.f); + // Death Knight T8 Melee 4P Bonus + if (AuraEffect const* aurEff = caster->GetAuraEffect(SPELL_DK_ITEM_T8_MELEE_4P_BONUS, EFFECT_0)) + AddPctF(multiplier, aurEff->GetAmount()); + } + } + + void HandleAfterHit() + { + Unit* caster = GetCaster(); + if (Unit* unitTarget = GetHitUnit()) + { + int32 bp = GetHitDamage() * multiplier; + + if (AuraEffect* aurEff = caster->GetAuraEffectOfRankedSpell(DK_SPELL_BLACK_ICE_R1, EFFECT_0)) + AddPctN(bp, aurEff->GetAmount()); + caster->CastCustomSpell(unitTarget, DK_SPELL_SCOURGE_STRIKE_TRIGGERED, &bp, NULL, NULL, true); } } @@ -402,6 +434,7 @@ class spell_dk_scourge_strike : public SpellScriptLoader void Register() { OnEffectHitTarget += SpellEffectFn(spell_dk_scourge_strike_SpellScript::HandleDummy, EFFECT_2, SPELL_EFFECT_DUMMY); + AfterHit += SpellHitFn(spell_dk_scourge_strike_SpellScript::HandleAfterHit); } }; @@ -588,7 +621,7 @@ public: if (!target->HasAura(DK_SPELL_BLOOD_PRESENCE) && !target->HasAura(DK_SPELL_IMPROVED_BLOOD_PRESENCE_TRIGGERED)) { int32 basePoints1 = aurEff->GetAmount(); - target->CastCustomSpell(target, 63611, NULL, &basePoints1, NULL, true, 0, aurEff); + target->CastCustomSpell(target, DK_SPELL_IMPROVED_BLOOD_PRESENCE_TRIGGERED, NULL, &basePoints1, NULL, true, 0, aurEff); } } @@ -723,14 +756,14 @@ class spell_dk_death_coil : public SpellScriptLoader { PrepareSpellScript(spell_dk_death_coil_SpellScript); - bool Validate(SpellInfo const* /*SpellEntry*/) + bool Validate(SpellInfo const* /*spell*/) { if (!sSpellMgr->GetSpellInfo(SPELL_DEATH_COIL_DAMAGE) || !sSpellMgr->GetSpellInfo(SPELL_DEATH_COIL_HEAL)) return false; return true; } - void HandleDummy(SpellEffIndex /* effIndex */) + void HandleDummy(SpellEffIndex /*effIndex*/) { int32 damage = GetEffectValue(); Unit* caster = GetCaster(); @@ -750,8 +783,26 @@ class spell_dk_death_coil : public SpellScriptLoader } } + SpellCastResult CheckCast() + { + Unit* caster = GetCaster(); + if (Unit* target = GetExplTargetUnit()) + { + if (!caster->IsFriendlyTo(target) && !caster->isInFront(target)) + return SPELL_FAILED_UNIT_NOT_INFRONT; + + if (target->IsFriendlyTo(caster) && target->GetCreatureType() != CREATURE_TYPE_UNDEAD) + return SPELL_FAILED_BAD_TARGETS; + } + else + return SPELL_FAILED_BAD_TARGETS; + + return SPELL_CAST_OK; + } + void Register() { + OnCheckCast += SpellCheckCastFn(spell_dk_death_coil_SpellScript::CheckCast); OnEffectHitTarget += SpellEffectFn(spell_dk_death_coil_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); } @@ -775,7 +826,7 @@ class spell_dk_death_grip : public SpellScriptLoader void HandleDummy(SpellEffIndex /*effIndex*/) { int32 damage = GetEffectValue(); - Position const* pos = GetTargetDest(); + Position const* pos = GetExplTargetDest(); if (Unit* target = GetHitUnit()) { if (!target->HasAuraType(SPELL_AURA_DEFLECT_SPELLS)) // Deterrence diff --git a/src/server/scripts/Spells/spell_druid.cpp b/src/server/scripts/Spells/spell_druid.cpp index 380cac4e5ee..b213f3df624 100644 --- a/src/server/scripts/Spells/spell_druid.cpp +++ b/src/server/scripts/Spells/spell_druid.cpp @@ -28,7 +28,12 @@ enum DruidSpells { DRUID_INCREASED_MOONFIRE_DURATION = 38414, - DRUID_NATURES_SPLENDOR = 57865 + DRUID_NATURES_SPLENDOR = 57865, + DRUID_LIFEBLOOM_FINAL_HEAL = 33778, + DRUID_LIFEBLOOM_ENERGIZE = 64372, + DRUID_SURVIVAL_INSTINCTS = 50322, + DRUID_SAVAGE_ROAR = 62071, + SPELL_DRUID_ITEM_T8_BALANCE_RELIC = 64950, }; // 54846 Glyph of Starfire @@ -154,7 +159,7 @@ class spell_dru_primal_tenacity : public SpellScriptLoader void Absorb(AuraEffect* /*aurEff*/, DamageInfo & dmgInfo, uint32 & absorbAmount) { // reduces all damage taken while Stunned in Cat Form - if (GetTarget()->GetShapeshiftForm() == FORM_CAT && GetTarget()->GetUInt32Value(UNIT_FIELD_FLAGS) & (UNIT_FLAG_STUNNED) && GetTarget()->HasAuraWithMechanic(1<<MECHANIC_STUN)) + if (GetTarget()->GetShapeshiftForm() == FORM_CAT && GetTarget()->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED) && GetTarget()->HasAuraWithMechanic(1<<MECHANIC_STUN)) absorbAmount = CalculatePctN(dmgInfo.GetDamage(), absorbPct); } @@ -228,37 +233,37 @@ class spell_dru_t10_restoration_4p_bonus : public SpellScriptLoader return GetCaster()->GetTypeId() == TYPEID_PLAYER; } - void FilterTargets(std::list<Unit*>& unitList) + void FilterTargets(std::list<WorldObject*>& targets) { if (!GetCaster()->ToPlayer()->GetGroup()) { - unitList.clear(); - unitList.push_back(GetCaster()); + targets.clear(); + targets.push_back(GetCaster()); } else { - unitList.remove(GetTargetUnit()); + targets.remove(GetExplTargetUnit()); std::list<Unit*> tempTargets; - for (std::list<Unit*>::const_iterator itr = unitList.begin(); itr != unitList.end(); ++itr) - if ((*itr)->GetTypeId() == TYPEID_PLAYER && GetCaster()->IsInRaidWith(*itr)) - tempTargets.push_back(*itr); + for (std::list<WorldObject*>::const_iterator itr = targets.begin(); itr != targets.end(); ++itr) + if ((*itr)->GetTypeId() == TYPEID_PLAYER && GetCaster()->IsInRaidWith((*itr)->ToUnit())) + tempTargets.push_back((*itr)->ToUnit()); if (tempTargets.empty()) { - unitList.clear(); + targets.clear(); FinishCast(SPELL_FAILED_DONT_REPORT); return; } Unit* target = Trinity::Containers::SelectRandomContainerElement(tempTargets); - unitList.clear(); - unitList.push_back(target); + targets.clear(); + targets.push_back(target); } } void Register() { - OnUnitTargetSelect += SpellUnitTargetFn(spell_dru_t10_restoration_4p_bonus_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_DEST_AREA_ALLY); + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_dru_t10_restoration_4p_bonus_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_DEST_AREA_ALLY); } }; @@ -277,14 +282,14 @@ class spell_dru_starfall_aoe : public SpellScriptLoader { PrepareSpellScript(spell_dru_starfall_aoe_SpellScript); - void FilterTargets(std::list<Unit*>& unitList) + void FilterTargets(std::list<WorldObject*>& targets) { - unitList.remove(GetTargetUnit()); + targets.remove(GetExplTargetUnit()); } void Register() { - OnUnitTargetSelect += SpellUnitTargetFn(spell_dru_starfall_aoe_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_DEST_AREA_ENEMY); + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_dru_starfall_aoe_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_DEST_AREA_ENEMY); } }; @@ -337,7 +342,12 @@ class spell_dru_starfall_dummy : public SpellScriptLoader { PrepareSpellScript(spell_dru_starfall_dummy_SpellScript); - void HandleDummy(SpellEffIndex /* effIndex */) + void FilterTargets(std::list<WorldObject*>& targets) + { + Trinity::Containers::RandomResizeList(targets, 2); + } + + void HandleDummy(SpellEffIndex /*effIndex*/) { Unit* caster = GetCaster(); // Shapeshifting into an animal form or mounting cancels the effect @@ -348,15 +358,16 @@ class spell_dru_starfall_dummy : public SpellScriptLoader return; } - //Any effect which causes you to lose control of your character will supress the starfall effect. + // Any effect which causes you to lose control of your character will supress the starfall effect. if (caster->HasUnitState(UNIT_STATE_CONTROLLED)) return; - caster->CastSpell(GetHitUnit(), GetEffectValue(), true); + caster->CastSpell(GetHitUnit(), uint32(GetEffectValue()), true); } void Register() { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_dru_starfall_dummy_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); OnEffectHitTarget += SpellEffectFn(spell_dru_starfall_dummy_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); } }; @@ -367,6 +378,272 @@ class spell_dru_starfall_dummy : public SpellScriptLoader } }; +class spell_dru_lifebloom : public SpellScriptLoader +{ + public: + spell_dru_lifebloom() : SpellScriptLoader("spell_dru_lifebloom") { } + + class spell_dru_lifebloom_AuraScript : public AuraScript + { + PrepareAuraScript(spell_dru_lifebloom_AuraScript); + + bool Validate(SpellInfo const* /*spell*/) + { + if (!sSpellMgr->GetSpellInfo(DRUID_LIFEBLOOM_FINAL_HEAL)) + return false; + if (!sSpellMgr->GetSpellInfo(DRUID_LIFEBLOOM_ENERGIZE)) + return false; + return true; + } + + void AfterRemove(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/) + { + // Final heal only on duration end + if (GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_EXPIRE) + return; + + // final heal + int32 stack = GetStackAmount(); + int32 healAmount = aurEff->GetAmount(); + if (Unit* caster = GetCaster()) + { + healAmount = caster->SpellHealingBonusDone(GetTarget(), GetSpellInfo(), healAmount, HEAL, stack); + healAmount = GetTarget()->SpellHealingBonusTaken(caster, GetSpellInfo(), healAmount, HEAL, stack); + + GetTarget()->CastCustomSpell(GetTarget(), DRUID_LIFEBLOOM_FINAL_HEAL, &healAmount, NULL, NULL, true, NULL, aurEff, GetCasterGUID()); + + // restore mana + int32 returnMana = CalculatePctU(caster->GetCreateMana(), GetSpellInfo()->ManaCostPercentage) * stack / 2; + caster->CastCustomSpell(caster, DRUID_LIFEBLOOM_ENERGIZE, &returnMana, NULL, NULL, true, NULL, aurEff, GetCasterGUID()); + return; + } + + GetTarget()->CastCustomSpell(GetTarget(), DRUID_LIFEBLOOM_FINAL_HEAL, &healAmount, NULL, NULL, true, NULL, aurEff, GetCasterGUID()); + } + + void HandleDispel(DispelInfo* dispelInfo) + { + if (Unit* target = GetUnitOwner()) + { + if (AuraEffect const* aurEff = GetEffect(EFFECT_1)) + { + // final heal + int32 healAmount = aurEff->GetAmount(); + if (Unit* caster = GetCaster()) + { + healAmount = caster->SpellHealingBonusDone(target, GetSpellInfo(), healAmount, HEAL, dispelInfo->GetRemovedCharges()); + healAmount = target->SpellHealingBonusTaken(caster, GetSpellInfo(), healAmount, HEAL, dispelInfo->GetRemovedCharges()); + target->CastCustomSpell(target, DRUID_LIFEBLOOM_FINAL_HEAL, &healAmount, NULL, NULL, true, NULL, NULL, GetCasterGUID()); + + // restore mana + int32 returnMana = CalculatePctU(caster->GetCreateMana(), GetSpellInfo()->ManaCostPercentage) * dispelInfo->GetRemovedCharges() / 2; + caster->CastCustomSpell(caster, DRUID_LIFEBLOOM_ENERGIZE, &returnMana, NULL, NULL, true, NULL, NULL, GetCasterGUID()); + return; + } + + target->CastCustomSpell(target, DRUID_LIFEBLOOM_FINAL_HEAL, &healAmount, NULL, NULL, true, NULL, NULL, GetCasterGUID()); + } + } + } + + void Register() + { + AfterEffectRemove += AuraEffectRemoveFn(spell_dru_lifebloom_AuraScript::AfterRemove, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); + AfterDispel += AuraDispelFn(spell_dru_lifebloom_AuraScript::HandleDispel); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_dru_lifebloom_AuraScript(); + } +}; + +class spell_dru_predatory_strikes : public SpellScriptLoader +{ + public: + spell_dru_predatory_strikes() : SpellScriptLoader("spell_dru_predatory_strikes") { } + + class spell_dru_predatory_strikes_AuraScript : public AuraScript + { + PrepareAuraScript(spell_dru_predatory_strikes_AuraScript); + + void UpdateAmount(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + if (Player* target = GetTarget()->ToPlayer()) + target->UpdateAttackPowerAndDamage(); + } + + void Register() + { + AfterEffectApply += AuraEffectApplyFn(spell_dru_predatory_strikes_AuraScript::UpdateAmount, EFFECT_ALL, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK); + AfterEffectRemove += AuraEffectRemoveFn(spell_dru_predatory_strikes_AuraScript::UpdateAmount, EFFECT_ALL, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_dru_predatory_strikes_AuraScript(); + } +}; + +class spell_dru_savage_roar : public SpellScriptLoader +{ + public: + spell_dru_savage_roar() : SpellScriptLoader("spell_dru_savage_roar") { } + + class spell_dru_savage_roar_SpellScript : public SpellScript + { + PrepareSpellScript(spell_dru_savage_roar_SpellScript); + + SpellCastResult CheckCast() + { + Unit* caster = GetCaster(); + if (caster->GetShapeshiftForm() != FORM_CAT) + return SPELL_FAILED_ONLY_SHAPESHIFT; + + return SPELL_CAST_OK; + } + + void Register() + { + OnCheckCast += SpellCheckCastFn(spell_dru_savage_roar_SpellScript::CheckCast); + } + }; + + class spell_dru_savage_roar_AuraScript : public AuraScript + { + PrepareAuraScript(spell_dru_savage_roar_AuraScript); + + bool Validate(SpellInfo const* /*spell*/) + { + if (!sSpellMgr->GetSpellInfo(DRUID_SAVAGE_ROAR)) + return false; + return true; + } + + void AfterApply(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/) + { + Unit* target = GetTarget(); + target->CastSpell(target, DRUID_SAVAGE_ROAR, true, NULL, aurEff, GetCasterGUID()); + } + + void AfterRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + GetTarget()->RemoveAurasDueToSpell(DRUID_SAVAGE_ROAR); + } + + void Register() + { + AfterEffectApply += AuraEffectApplyFn(spell_dru_savage_roar_AuraScript::AfterApply, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); + AfterEffectRemove += AuraEffectRemoveFn(spell_dru_savage_roar_AuraScript::AfterRemove, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_dru_savage_roar_SpellScript(); + } + + AuraScript* GetAuraScript() const + { + return new spell_dru_savage_roar_AuraScript(); + } +}; + +class spell_dru_survival_instincts : public SpellScriptLoader +{ + public: + spell_dru_survival_instincts() : SpellScriptLoader("spell_dru_survival_instincts") { } + + class spell_dru_survival_instincts_SpellScript : public SpellScript + { + PrepareSpellScript(spell_dru_survival_instincts_SpellScript); + + SpellCastResult CheckCast() + { + Unit* caster = GetCaster(); + if (!caster->IsInFeralForm()) + return SPELL_FAILED_ONLY_SHAPESHIFT; + + return SPELL_CAST_OK; + } + + void Register() + { + OnCheckCast += SpellCheckCastFn(spell_dru_survival_instincts_SpellScript::CheckCast); + } + }; + + class spell_dru_survival_instincts_AuraScript : public AuraScript + { + PrepareAuraScript(spell_dru_survival_instincts_AuraScript); + + bool Validate(SpellInfo const* /*spell*/) + { + if (!sSpellMgr->GetSpellInfo(DRUID_SURVIVAL_INSTINCTS)) + return false; + return true; + } + + void AfterApply(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/) + { + Unit* target = GetTarget(); + int32 bp0 = target->CountPctFromMaxHealth(aurEff->GetAmount()); + target->CastCustomSpell(target, DRUID_SURVIVAL_INSTINCTS, &bp0, NULL, NULL, true); + } + + void AfterRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + GetTarget()->RemoveAurasDueToSpell(DRUID_SURVIVAL_INSTINCTS); + } + + void Register() + { + AfterEffectApply += AuraEffectApplyFn(spell_dru_survival_instincts_AuraScript::AfterApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK); + AfterEffectRemove += AuraEffectRemoveFn(spell_dru_survival_instincts_AuraScript::AfterRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_dru_survival_instincts_SpellScript(); + } + + AuraScript* GetAuraScript() const + { + return new spell_dru_survival_instincts_AuraScript(); + } +}; + +class spell_dru_insect_swarm : public SpellScriptLoader +{ + public: + spell_dru_insect_swarm() : SpellScriptLoader("spell_dru_insect_swarm") { } + + class spell_dru_insect_swarm_AuraScript : public AuraScript + { + PrepareAuraScript(spell_dru_insect_swarm_AuraScript); + + void CalculateAmount(AuraEffect const* aurEff, int32 & amount, bool & /*canBeRecalculated*/) + { + if (Unit* caster = GetCaster()) + if (AuraEffect const* relicAurEff = caster->GetAuraEffect(SPELL_DRUID_ITEM_T8_BALANCE_RELIC, EFFECT_0)) + amount += relicAurEff->GetAmount() / aurEff->GetTotalTicks(); + } + + void Register() + { + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_dru_insect_swarm_AuraScript::CalculateAmount, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_dru_insect_swarm_AuraScript(); + } +}; + void AddSC_druid_spell_scripts() { new spell_dru_glyph_of_starfire(); @@ -377,4 +654,9 @@ void AddSC_druid_spell_scripts() new spell_dru_starfall_aoe(); new spell_dru_swift_flight_passive(); new spell_dru_starfall_dummy(); + new spell_dru_lifebloom(); + new spell_dru_predatory_strikes(); + new spell_dru_savage_roar(); + new spell_dru_survival_instincts(); + new spell_dru_insect_swarm(); } diff --git a/src/server/scripts/Spells/spell_generic.cpp b/src/server/scripts/Spells/spell_generic.cpp index 035f9ec98b2..9cbf81b39af 100644 --- a/src/server/scripts/Spells/spell_generic.cpp +++ b/src/server/scripts/Spells/spell_generic.cpp @@ -169,7 +169,7 @@ class spell_gen_burn_brutallus : public SpellScriptLoader } }; -enum eCannibalizeSpells +enum CannibalizeSpells { SPELL_CANNIBALIZE_TRIGGERED = 20578, }; @@ -224,7 +224,7 @@ class spell_gen_cannibalize : public SpellScriptLoader }; // 45472 Parachute -enum eParachuteSpells +enum ParachuteSpells { SPELL_PARACHUTE = 45472, SPELL_PARACHUTE_BUFF = 44795, @@ -239,7 +239,7 @@ class spell_gen_parachute : public SpellScriptLoader { PrepareAuraScript(spell_gen_parachute_AuraScript); - bool Validate(SpellInfo const* /*spellEntry*/) + bool Validate(SpellInfo const* /*spell*/) { if (!sSpellMgr->GetSpellInfo(SPELL_PARACHUTE) || !sSpellMgr->GetSpellInfo(SPELL_PARACHUTE_BUFF)) return false; @@ -365,7 +365,7 @@ class spell_gen_remove_flight_auras : public SpellScriptLoader }; // 66118 Leeching Swarm -enum eLeechingSwarmSpells +enum LeechingSwarmSpells { SPELL_LEECHING_SWARM_DMG = 66240, SPELL_LEECHING_SWARM_HEAL = 66125, @@ -481,7 +481,7 @@ class spell_gen_elune_candle : public SpellScriptLoader }; // 24750 Trick -enum eTrickSpells +enum TrickSpells { SPELL_PIRATE_COSTUME_MALE = 24708, SPELL_PIRATE_COSTUME_FEMALE = 24709, @@ -557,7 +557,7 @@ class spell_gen_trick : public SpellScriptLoader }; // 24751 Trick or Treat -enum eTrickOrTreatSpells +enum TrickOrTreatSpells { SPELL_TRICK = 24714, SPELL_TREAT = 24715, @@ -660,22 +660,16 @@ class spell_pvp_trinket_wotf_shared_cd : public SpellScriptLoader return true; } - void HandleScript(SpellEffIndex /*effIndex*/) + void HandleScript() { - Player* caster = GetCaster()->ToPlayer(); - SpellInfo const* spellInfo = GetSpellInfo(); - caster->AddSpellCooldown(spellInfo->Id, 0, time(NULL) + sSpellMgr->GetSpellInfo(SPELL_WILL_OF_THE_FORSAKEN_COOLDOWN_TRIGGER)->GetRecoveryTime() / IN_MILLISECONDS); - WorldPacket data(SMSG_SPELL_COOLDOWN, 8+1+4); - data << uint64(caster->GetGUID()); - data << uint8(0); - data << uint32(spellInfo->Id); - data << uint32(0); - caster->GetSession()->SendPacket(&data); + // This is only needed because spells cast from spell_linked_spell are triggered by default + // Spell::SendSpellCooldown() skips all spells with TRIGGERED_IGNORE_SPELL_AND_CATEGORY_CD + GetCaster()->ToPlayer()->AddSpellAndCategoryCooldowns(GetSpellInfo(), GetCastItem() ? GetCastItem()->GetEntry() : 0, GetSpell()); } void Register() { - OnEffectHit += SpellEffectFn(spell_pvp_trinket_wotf_shared_cd_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_DUMMY); + AfterCast += SpellCastFn(spell_pvp_trinket_wotf_shared_cd_SpellScript::HandleScript); } }; @@ -1282,7 +1276,7 @@ class spell_gen_launch : public SpellScriptLoader void Launch() { - WorldLocation const* const position = GetTargetDest(); + WorldLocation const* const position = GetExplTargetDest(); if (Player* player = GetHitPlayer()) { @@ -1513,7 +1507,7 @@ class spell_gen_luck_of_the_draw : public SpellScriptLoader if (group->isLFGGroup()) if (uint32 dungeonId = sLFGMgr->GetDungeon(group->GetGUID(), true)) if (LFGDungeonEntry const* dungeon = sLFGDungeonStore.LookupEntry(dungeonId)) - if (uint32(dungeon->map) == map->GetId() && dungeon->difficulty == map->GetDifficulty()) + if (uint32(dungeon->map) == map->GetId() && dungeon->difficulty == uint32(map->GetDifficulty())) if (randomDungeon && randomDungeon->type == LFG_TYPE_RANDOM) return; // in correct dungeon @@ -2052,9 +2046,9 @@ class spell_gen_defend : public SpellScriptLoader public: spell_gen_defend() : SpellScriptLoader("spell_gen_defend") { } - class spell_gen_defendAuraScript : public AuraScript + class spell_gen_defend_AuraScript : public AuraScript { - PrepareAuraScript(spell_gen_defendAuraScript); + PrepareAuraScript(spell_gen_defend_AuraScript); bool Validate(SpellInfo const* /*spellEntry*/) { @@ -2103,26 +2097,26 @@ class spell_gen_defend : public SpellScriptLoader // Defend spells casted by NPCs (add visuals) if (spell->Effects[EFFECT_0].ApplyAuraName == SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN) { - AfterEffectApply += AuraEffectApplyFn(spell_gen_defendAuraScript::RefreshVisualShields, EFFECT_0, SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK); - OnEffectRemove += AuraEffectRemoveFn(spell_gen_defendAuraScript::RemoveVisualShields, EFFECT_0, SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK); + AfterEffectApply += AuraEffectApplyFn(spell_gen_defend_AuraScript::RefreshVisualShields, EFFECT_0, SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK); + OnEffectRemove += AuraEffectRemoveFn(spell_gen_defend_AuraScript::RemoveVisualShields, EFFECT_0, SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK); } // Remove Defend spell from player when he dismounts if (spell->Effects[EFFECT_2].ApplyAuraName == SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN) - OnEffectRemove += AuraEffectRemoveFn(spell_gen_defendAuraScript::RemoveDummyFromDriver, EFFECT_2, SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, AURA_EFFECT_HANDLE_REAL); + OnEffectRemove += AuraEffectRemoveFn(spell_gen_defend_AuraScript::RemoveDummyFromDriver, EFFECT_2, SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, AURA_EFFECT_HANDLE_REAL); // Defend spells casted by players (add/remove visuals) if (spell->Effects[EFFECT_1].ApplyAuraName == SPELL_AURA_DUMMY) { - AfterEffectApply += AuraEffectApplyFn(spell_gen_defendAuraScript::RefreshVisualShields, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK); - OnEffectRemove += AuraEffectRemoveFn(spell_gen_defendAuraScript::RemoveVisualShields, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK); + AfterEffectApply += AuraEffectApplyFn(spell_gen_defend_AuraScript::RefreshVisualShields, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK); + OnEffectRemove += AuraEffectRemoveFn(spell_gen_defend_AuraScript::RemoveVisualShields, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK); } } }; AuraScript* GetAuraScript() const { - return new spell_gen_defendAuraScript(); + return new spell_gen_defend_AuraScript(); } }; @@ -2326,9 +2320,9 @@ class spell_gen_on_tournament_mount : public SpellScriptLoader public: spell_gen_on_tournament_mount() : SpellScriptLoader("spell_gen_on_tournament_mount") { } - class spell_gen_on_tournament_mountAuraScript : public AuraScript + class spell_gen_on_tournament_mount_AuraScript : public AuraScript { - PrepareAuraScript(spell_gen_on_tournament_mountAuraScript); + PrepareAuraScript(spell_gen_on_tournament_mount_AuraScript); uint32 _pennantSpellId; @@ -2468,14 +2462,14 @@ class spell_gen_on_tournament_mount : public SpellScriptLoader void Register() { - AfterEffectApply += AuraEffectApplyFn(spell_gen_on_tournament_mountAuraScript::HandleApplyEffect, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK); - OnEffectRemove += AuraEffectRemoveFn(spell_gen_on_tournament_mountAuraScript::HandleRemoveEffect, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK); + AfterEffectApply += AuraEffectApplyFn(spell_gen_on_tournament_mount_AuraScript::HandleApplyEffect, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK); + OnEffectRemove += AuraEffectRemoveFn(spell_gen_on_tournament_mount_AuraScript::HandleRemoveEffect, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK); } }; AuraScript* GetAuraScript() const { - return new spell_gen_on_tournament_mountAuraScript(); + return new spell_gen_on_tournament_mount_AuraScript(); } }; @@ -2484,9 +2478,9 @@ class spell_gen_tournament_pennant : public SpellScriptLoader public: spell_gen_tournament_pennant() : SpellScriptLoader("spell_gen_tournament_pennant") { } - class spell_gen_tournament_pennantAuraScript : public AuraScript + class spell_gen_tournament_pennant_AuraScript : public AuraScript { - PrepareAuraScript(spell_gen_tournament_pennantAuraScript); + PrepareAuraScript(spell_gen_tournament_pennant_AuraScript); bool Load() { @@ -2502,13 +2496,13 @@ class spell_gen_tournament_pennant : public SpellScriptLoader void Register() { - OnEffectApply += AuraEffectApplyFn(spell_gen_tournament_pennantAuraScript::HandleApplyEffect, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK); + OnEffectApply += AuraEffectApplyFn(spell_gen_tournament_pennant_AuraScript::HandleApplyEffect, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK); } }; AuraScript* GetAuraScript() const { - return new spell_gen_tournament_pennantAuraScript(); + return new spell_gen_tournament_pennant_AuraScript(); } }; @@ -2618,6 +2612,470 @@ class spell_gen_wg_water : public SpellScriptLoader } }; +class spell_gen_count_pct_from_max_hp : public SpellScriptLoader +{ + public: + spell_gen_count_pct_from_max_hp(char const* name, int32 damagePct = 0) : SpellScriptLoader(name), _damagePct(damagePct) { } + + class spell_gen_count_pct_from_max_hp_SpellScript : public SpellScript + { + PrepareSpellScript(spell_gen_count_pct_from_max_hp_SpellScript) + + public: + spell_gen_count_pct_from_max_hp_SpellScript(int32 damagePct) : SpellScript(), _damagePct(damagePct) { } + + void RecalculateDamage() + { + if (!_damagePct) + _damagePct = GetHitDamage(); + + SetHitDamage(GetHitUnit()->CountPctFromMaxHealth(_damagePct)); + } + + void Register() + { + OnHit += SpellHitFn(spell_gen_count_pct_from_max_hp_SpellScript::RecalculateDamage); + } + + private: + int32 _damagePct; + }; + + SpellScript* GetSpellScript() const + { + return new spell_gen_count_pct_from_max_hp_SpellScript(_damagePct); + } + + private: + int32 _damagePct; +}; + +class spell_gen_despawn_self : public SpellScriptLoader +{ +public: + spell_gen_despawn_self() : SpellScriptLoader("spell_gen_despawn_self") { } + + class spell_gen_despawn_self_SpellScript : public SpellScript + { + PrepareSpellScript(spell_gen_despawn_self_SpellScript); + + bool Load() + { + return GetCaster()->GetTypeId() == TYPEID_UNIT; + } + + void HandleDummy(SpellEffIndex effIndex) + { + if (GetSpellInfo()->Effects[effIndex].Effect == SPELL_EFFECT_DUMMY || GetSpellInfo()->Effects[effIndex].Effect == SPELL_EFFECT_SCRIPT_EFFECT) + GetCaster()->ToCreature()->DespawnOrUnsummon(); + } + + void Register() + { + OnEffectHitTarget += SpellEffectFn(spell_gen_despawn_self_SpellScript::HandleDummy, EFFECT_ALL, SPELL_EFFECT_ANY); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_gen_despawn_self_SpellScript(); + } +}; + +class spell_gen_touch_the_nightmare : public SpellScriptLoader +{ +public: + spell_gen_touch_the_nightmare() : SpellScriptLoader("spell_gen_touch_the_nightmare") { } + + class spell_gen_touch_the_nightmare_SpellScript : public SpellScript + { + PrepareSpellScript(spell_gen_touch_the_nightmare_SpellScript); + + void HandleDamageCalc(SpellEffIndex /*effIndex*/) + { + uint32 bp = GetCaster()->GetMaxHealth() * 0.3f; + SetHitDamage(bp); + } + + void Register() + { + OnEffectHitTarget += SpellEffectFn(spell_gen_touch_the_nightmare_SpellScript::HandleDamageCalc, EFFECT_2, SPELL_EFFECT_SCHOOL_DAMAGE); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_gen_touch_the_nightmare_SpellScript(); + } +}; + +class spell_gen_dream_funnel: public SpellScriptLoader +{ +public: + spell_gen_dream_funnel() : SpellScriptLoader("spell_gen_dream_funnel") { } + + class spell_gen_dream_funnel_AuraScript : public AuraScript + { + PrepareAuraScript(spell_gen_dream_funnel_AuraScript); + + void HandleEffectCalcAmount(AuraEffect const* /*aurEff*/, int32& amount, bool& canBeRecalculated) + { + if (GetCaster()) + amount = GetCaster()->GetMaxHealth() * 0.05f; + + canBeRecalculated = false; + } + + void Register() + { + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_gen_dream_funnel_AuraScript::HandleEffectCalcAmount, EFFECT_0, SPELL_AURA_PERIODIC_HEAL); + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_gen_dream_funnel_AuraScript::HandleEffectCalcAmount, EFFECT_2, SPELL_AURA_PERIODIC_DAMAGE); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_gen_dream_funnel_AuraScript(); + } +}; + +enum GenericBandage +{ + SPELL_RECENTLY_BANDAGED = 11196, +}; + +class spell_gen_bandage : public SpellScriptLoader +{ + public: + spell_gen_bandage() : SpellScriptLoader("spell_gen_bandage") { } + + class spell_gen_bandage_SpellScript : public SpellScript + { + PrepareSpellScript(spell_gen_bandage_SpellScript); + + bool Validate(SpellInfo const* /*spell*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_RECENTLY_BANDAGED)) + return false; + return true; + } + + SpellCastResult CheckCast() + { + if (Unit* target = GetExplTargetUnit()) + { + if (target->HasAura(SPELL_RECENTLY_BANDAGED)) + return SPELL_FAILED_TARGET_AURASTATE; + } + return SPELL_CAST_OK; + } + + void HandleScript() + { + if (Unit* target = GetHitUnit()) + GetCaster()->CastSpell(target, SPELL_RECENTLY_BANDAGED, true); + } + + void Register() + { + OnCheckCast += SpellCheckCastFn(spell_gen_bandage_SpellScript::CheckCast); + AfterHit += SpellHitFn(spell_gen_bandage_SpellScript::HandleScript); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_gen_bandage_SpellScript(); + } +}; + +enum GenericLifebloom +{ + SPELL_HEXLORD_MALACRASS_LIFEBLOOM_FINAL_HEAL = 43422, + SPELL_TUR_RAGEPAW_LIFEBLOOM_FINAL_HEAL = 52552, + SPELL_CENARION_SCOUT_LIFEBLOOM_FINAL_HEAL = 53692, + SPELL_TWISTED_VISAGE_LIFEBLOOM_FINAL_HEAL = 57763, + SPELL_FACTION_CHAMPIONS_DRU_LIFEBLOOM_FINAL_HEAL = 66094, +}; + +class spell_gen_lifebloom : public SpellScriptLoader +{ + public: + spell_gen_lifebloom(const char* name, uint32 spellId) : SpellScriptLoader(name), _spellId(spellId) { } + + class spell_gen_lifebloom_AuraScript : public AuraScript + { + PrepareAuraScript(spell_gen_lifebloom_AuraScript); + + public: + spell_gen_lifebloom_AuraScript(uint32 spellId) : AuraScript(), _spellId(spellId) { } + + bool Validate(SpellInfo const* /*spell*/) + { + if (!sSpellMgr->GetSpellInfo(_spellId)) + return false; + return true; + } + + void AfterRemove(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/) + { + // Final heal only on duration end + if (GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_EXPIRE && GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_ENEMY_SPELL) + return; + + // final heal + GetTarget()->CastSpell(GetTarget(), _spellId, true, NULL, aurEff, GetCasterGUID()); + } + + void Register() + { + AfterEffectRemove += AuraEffectRemoveFn(spell_gen_lifebloom_AuraScript::AfterRemove, EFFECT_0, SPELL_AURA_PERIODIC_HEAL, AURA_EFFECT_HANDLE_REAL); + } + + private: + uint32 _spellId; + }; + + AuraScript* GetAuraScript() const + { + return new spell_gen_lifebloom_AuraScript(_spellId); + } + + private: + uint32 _spellId; +}; + +enum SummonElemental +{ + SPELL_SUMMON_FIRE_ELEMENTAL = 8985, + SPELL_SUMMON_EARTH_ELEMENTAL = 19704 +}; + +class spell_gen_summon_elemental : public SpellScriptLoader +{ + public: + spell_gen_summon_elemental(const char* name, uint32 spellId) : SpellScriptLoader(name), _spellId(spellId) { } + + class spell_gen_summon_elemental_AuraScript : public AuraScript + { + PrepareAuraScript(spell_gen_summon_elemental_AuraScript); + + public: + spell_gen_summon_elemental_AuraScript(uint32 spellId) : AuraScript(), _spellId(spellId) { } + + bool Validate(SpellInfo const* /*spell*/) + { + if (!sSpellMgr->GetSpellInfo(_spellId)) + return false; + return true; + } + + void AfterApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + if (GetCaster()) + if (Unit* owner = GetCaster()->GetOwner()) + owner->CastSpell(owner, _spellId, true); + } + + void AfterRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + if (GetCaster()) + if (Unit* owner = GetCaster()->GetOwner()) + if (owner->GetTypeId() == TYPEID_PLAYER) // todo: this check is maybe wrong + owner->ToPlayer()->RemovePet(NULL, PET_SAVE_NOT_IN_SLOT, true); + } + + void Register() + { + AfterEffectApply += AuraEffectApplyFn(spell_gen_summon_elemental_AuraScript::AfterApply, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); + AfterEffectRemove += AuraEffectRemoveFn(spell_gen_summon_elemental_AuraScript::AfterRemove, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); + } + + private: + uint32 _spellId; + }; + + AuraScript* GetAuraScript() const + { + return new spell_gen_summon_elemental_AuraScript(_spellId); + } + + private: + uint32 _spellId; +}; + +enum Mounts +{ + SPELL_COLD_WEATHER_FLYING = 54197, + + // Magic Broom + SPELL_MAGIC_BROOM_60 = 42680, + SPELL_MAGIC_BROOM_100 = 42683, + SPELL_MAGIC_BROOM_150 = 42667, + SPELL_MAGIC_BROOM_280 = 42668, + + // Headless Horseman's Mount + SPELL_HEADLESS_HORSEMAN_MOUNT_60 = 51621, + SPELL_HEADLESS_HORSEMAN_MOUNT_100 = 48024, + SPELL_HEADLESS_HORSEMAN_MOUNT_150 = 51617, + SPELL_HEADLESS_HORSEMAN_MOUNT_280 = 48023, + + // Winged Steed of the Ebon Blade + SPELL_WINGED_STEED_150 = 54726, + SPELL_WINGED_STEED_280 = 54727, + + // Big Love Rocket + SPELL_BIG_LOVE_ROCKET_0 = 71343, + SPELL_BIG_LOVE_ROCKET_60 = 71344, + SPELL_BIG_LOVE_ROCKET_100 = 71345, + SPELL_BIG_LOVE_ROCKET_150 = 71346, + SPELL_BIG_LOVE_ROCKET_310 = 71347, + + // Invincible + SPELL_INVINCIBLE_60 = 72281, + SPELL_INVINCIBLE_100 = 72282, + SPELL_INVINCIBLE_150 = 72283, + SPELL_INVINCIBLE_310 = 72284, + + // Blazing Hippogryph + SPELL_BLAZING_HIPPOGRYPH_150 = 74854, + SPELL_BLAZING_HIPPOGRYPH_280 = 74855, + + // Celestial Steed + SPELL_CELESTIAL_STEED_60 = 75619, + SPELL_CELESTIAL_STEED_100 = 75620, + SPELL_CELESTIAL_STEED_150 = 75617, + SPELL_CELESTIAL_STEED_280 = 75618, + SPELL_CELESTIAL_STEED_310 = 76153, + + // X-53 Touring Rocket + SPELL_X53_TOURING_ROCKET_150 = 75957, + SPELL_X53_TOURING_ROCKET_280 = 75972, + SPELL_X53_TOURING_ROCKET_310 = 76154, +}; + +class spell_gen_mount : public SpellScriptLoader +{ + public: + spell_gen_mount(const char* name, uint32 mount0 = 0, uint32 mount60 = 0, uint32 mount100 = 0, uint32 mount150 = 0, uint32 mount280 = 0, uint32 mount310 = 0) : SpellScriptLoader(name), + _mount0(mount0), _mount60(mount60), _mount100(mount100), _mount150(mount150), _mount280(mount280), _mount310(mount310) { } + + class spell_gen_mount_SpellScript : public SpellScript + { + PrepareSpellScript(spell_gen_mount_SpellScript); + + public: + spell_gen_mount_SpellScript(uint32 mount0, uint32 mount60, uint32 mount100, uint32 mount150, uint32 mount280, uint32 mount310) : SpellScript(), + _mount0(mount0), _mount60(mount60), _mount100(mount100), _mount150(mount150), _mount280(mount280), _mount310(mount310) { } + + bool Validate(SpellInfo const* /*spell*/) + { + if (_mount0 && !sSpellMgr->GetSpellInfo(_mount0)) + return false; + if (_mount60 && !sSpellMgr->GetSpellInfo(_mount60)) + return false; + if (_mount100 && !sSpellMgr->GetSpellInfo(_mount100)) + return false; + if (_mount150 && !sSpellMgr->GetSpellInfo(_mount150)) + return false; + if (_mount280 && !sSpellMgr->GetSpellInfo(_mount280)) + return false; + if (_mount310 && !sSpellMgr->GetSpellInfo(_mount310)) + return false; + return true; + } + + void HandleMount(SpellEffIndex effIndex) + { + PreventHitDefaultEffect(effIndex); + + if (Player* target = GetHitPlayer()) + { + // Prevent stacking of mounts and client crashes upon dismounting + target->RemoveAurasByType(SPELL_AURA_MOUNTED, 0, GetHitAura()); + + // Triggered spell id dependent on riding skill and zone + bool canFly = false; + uint32 map = GetVirtualMapForMapAndZone(target->GetMapId(), target->GetZoneId()); + if (map == 530 || (map == 571 && target->HasSpell(SPELL_COLD_WEATHER_FLYING))) + canFly = true; + + float x, y, z; + target->GetPosition(x, y, z); + uint32 areaFlag = target->GetBaseMap()->GetAreaFlag(x, y, z); + AreaTableEntry const* area = sAreaStore.LookupEntry(areaFlag); + if (!area || (canFly && (area->flags & AREA_FLAG_NO_FLY_ZONE))) + canFly = false; + + uint32 mount = 0; + switch (target->GetBaseSkillValue(SKILL_RIDING)) + { + case 0: + mount = _mount0; + break; + case 75: + mount = _mount60; + break; + case 150: + mount = _mount100; + break; + case 225: + if (canFly) + mount = _mount150; + else + mount = _mount100; + break; + case 300: + if (canFly) + { + if (_mount310 && target->Has310Flyer(false)) + mount = _mount310; + else + mount = _mount280; + } + else + mount = _mount100; + break; + default: + break; + } + + if (mount) + { + PreventHitAura(); + target->CastSpell(target, mount, true); + } + } + } + + void Register() + { + OnEffectHitTarget += SpellEffectFn(spell_gen_mount_SpellScript::HandleMount, EFFECT_2, SPELL_EFFECT_SCRIPT_EFFECT); + } + + private: + uint32 _mount0; + uint32 _mount60; + uint32 _mount100; + uint32 _mount150; + uint32 _mount280; + uint32 _mount310; + }; + + SpellScript* GetSpellScript() const + { + return new spell_gen_mount_SpellScript(_mount0, _mount60, _mount100, _mount150, _mount280, _mount310); + } + + private: + uint32 _mount0; + uint32 _mount60; + uint32 _mount100; + uint32 _mount150; + uint32 _mount280; + uint32 _mount310; +}; + void AddSC_generic_spell_scripts() { new spell_gen_absorb0_hitlimit1(); @@ -2669,4 +3127,25 @@ void AddSC_generic_spell_scripts() new spell_gen_chaos_blast(); new spell_gen_ds_flush_knockback(); new spell_gen_wg_water(); + new spell_gen_count_pct_from_max_hp("spell_gen_default_count_pct_from_max_hp"); + new spell_gen_count_pct_from_max_hp("spell_gen_50pct_count_pct_from_max_hp", 50); + new spell_gen_despawn_self(); + new spell_gen_touch_the_nightmare(); + new spell_gen_dream_funnel(); + new spell_gen_bandage(); + new spell_gen_lifebloom("spell_hexlord_lifebloom", SPELL_HEXLORD_MALACRASS_LIFEBLOOM_FINAL_HEAL); + new spell_gen_lifebloom("spell_tur_ragepaw_lifebloom", SPELL_TUR_RAGEPAW_LIFEBLOOM_FINAL_HEAL); + new spell_gen_lifebloom("spell_cenarion_scout_lifebloom", SPELL_CENARION_SCOUT_LIFEBLOOM_FINAL_HEAL); + new spell_gen_lifebloom("spell_twisted_visage_lifebloom", SPELL_TWISTED_VISAGE_LIFEBLOOM_FINAL_HEAL); + new spell_gen_lifebloom("spell_faction_champion_dru_lifebloom", SPELL_FACTION_CHAMPIONS_DRU_LIFEBLOOM_FINAL_HEAL); + new spell_gen_summon_elemental("spell_gen_summon_fire_elemental", SPELL_SUMMON_FIRE_ELEMENTAL); + new spell_gen_summon_elemental("spell_gen_summon_earth_elemental", SPELL_SUMMON_EARTH_ELEMENTAL); + new spell_gen_mount("spell_magic_broom", 0, SPELL_MAGIC_BROOM_60, SPELL_MAGIC_BROOM_100, SPELL_MAGIC_BROOM_150, SPELL_MAGIC_BROOM_280); + new spell_gen_mount("spell_headless_horseman_mount", 0, SPELL_HEADLESS_HORSEMAN_MOUNT_60, SPELL_HEADLESS_HORSEMAN_MOUNT_100, SPELL_HEADLESS_HORSEMAN_MOUNT_150, SPELL_HEADLESS_HORSEMAN_MOUNT_280); + new spell_gen_mount("spell_winged_steed_of_the_ebon_blade", 0, 0, 0, SPELL_WINGED_STEED_150, SPELL_WINGED_STEED_280); + new spell_gen_mount("spell_big_love_rocket", SPELL_BIG_LOVE_ROCKET_0, SPELL_BIG_LOVE_ROCKET_60, SPELL_BIG_LOVE_ROCKET_100, SPELL_BIG_LOVE_ROCKET_150, SPELL_BIG_LOVE_ROCKET_310); + new spell_gen_mount("spell_invincible", 0, SPELL_INVINCIBLE_60, SPELL_INVINCIBLE_100, SPELL_INVINCIBLE_150, SPELL_INVINCIBLE_310); + new spell_gen_mount("spell_blazing_hippogryph", 0, 0, 0, SPELL_BLAZING_HIPPOGRYPH_150, SPELL_BLAZING_HIPPOGRYPH_280); + new spell_gen_mount("spell_celestial_steed", 0, SPELL_CELESTIAL_STEED_60, SPELL_CELESTIAL_STEED_100, SPELL_CELESTIAL_STEED_150, SPELL_CELESTIAL_STEED_280, SPELL_CELESTIAL_STEED_310); + new spell_gen_mount("spell_x53_touring_rocket", 0, 0, 0, SPELL_X53_TOURING_ROCKET_150, SPELL_X53_TOURING_ROCKET_280, SPELL_X53_TOURING_ROCKET_310); } diff --git a/src/server/scripts/Spells/spell_holiday.cpp b/src/server/scripts/Spells/spell_holiday.cpp index dabe978b58c..a1ecac6256a 100644 --- a/src/server/scripts/Spells/spell_holiday.cpp +++ b/src/server/scripts/Spells/spell_holiday.cpp @@ -20,7 +20,12 @@ * Scriptnames in this file should be prefixed with "spell_#holidayname_". */ -#include "ScriptPCH.h" +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "SpellScript.h" +#include "SpellAuraEffects.h" +#include "GridNotifiers.h" +#include "CellImpl.h" // 45102 Romantic Picnic enum SpellsPicnic diff --git a/src/server/scripts/Spells/spell_hunter.cpp b/src/server/scripts/Spells/spell_hunter.cpp index 5d8e8f84e6a..a2ee6c1c3a3 100644 --- a/src/server/scripts/Spells/spell_hunter.cpp +++ b/src/server/scripts/Spells/spell_hunter.cpp @@ -137,8 +137,9 @@ class spell_hun_chimera_shot : public SpellScriptLoader { int32 TickCount = aurEff->GetTotalTicks(); spellId = HUNTER_SPELL_CHIMERA_SHOT_SERPENT; - basePoint = caster->SpellDamageBonus(unitTarget, aura->GetSpellInfo(), aurEff->GetAmount(), DOT, aura->GetStackAmount()); + basePoint = caster->SpellDamageBonusDone(unitTarget, aura->GetSpellInfo(), aurEff->GetAmount(), DOT, aura->GetStackAmount()); ApplyPctN(basePoint, TickCount * 40); + basePoint = unitTarget->SpellDamageBonusTaken(caster, aura->GetSpellInfo(), basePoint, DOT, aura->GetStackAmount()); } // Viper Sting - Instantly restores mana to you equal to 60% of the total amount drained by your Viper Sting. else if (familyFlag[1] & 0x00000080) @@ -286,8 +287,8 @@ class spell_hun_masters_call : public SpellScriptLoader target->CastSpell(target, HUNTER_SPELL_MASTERS_CALL_TRIGGERED, castMask); // there is a possibility that this effect should access effect 0 (dummy) target, but i dubt that // it's more likely that on on retail it's possible to call target selector based on dbc values - // anyways, we're using GetTargetUnit() here and it's ok - if (Unit* ally = GetTargetUnit()) + // anyways, we're using GetExplTargetUnit() here and it's ok + if (Unit* ally = GetExplTargetUnit()) { target->CastSpell(ally, GetEffectValue(), castMask); target->CastSpell(ally, GetSpellInfo()->Effects[EFFECT_0].CalcValue(), castMask); @@ -617,6 +618,86 @@ class spell_hun_misdirection_proc : public SpellScriptLoader } }; +class spell_hun_disengage : public SpellScriptLoader +{ + public: + spell_hun_disengage() : SpellScriptLoader("spell_hun_disengage") { } + + class spell_hun_disengage_SpellScript : public SpellScript + { + PrepareSpellScript(spell_hun_disengage_SpellScript); + + SpellCastResult CheckCast() + { + Unit* caster = GetCaster(); + if (caster->GetTypeId() == TYPEID_PLAYER && !caster->isInCombat()) + return SPELL_FAILED_CANT_DO_THAT_RIGHT_NOW; + + return SPELL_CAST_OK; + } + + void Register() + { + OnCheckCast += SpellCheckCastFn(spell_hun_disengage_SpellScript::CheckCast); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_hun_disengage_SpellScript(); + } +}; + +class spell_hun_tame_beast : public SpellScriptLoader +{ + public: + spell_hun_tame_beast() : SpellScriptLoader("spell_hun_tame_beast") { } + + class spell_hun_tame_beast_SpellScript : public SpellScript + { + PrepareSpellScript(spell_hun_tame_beast_SpellScript); + + SpellCastResult CheckCast() + { + Unit* caster = GetCaster(); + if (caster->GetTypeId() != TYPEID_PLAYER) + return SPELL_FAILED_DONT_REPORT; + + if (!GetExplTargetUnit()) + return SPELL_FAILED_BAD_IMPLICIT_TARGETS; + + if (Creature* target = GetExplTargetUnit()->ToCreature()) + { + if (target->getLevel() > caster->getLevel()) + return SPELL_FAILED_HIGHLEVEL; + + // use SMSG_PET_TAME_FAILURE? + if (!target->GetCreatureTemplate()->isTameable(caster->ToPlayer()->CanTameExoticPets())) + return SPELL_FAILED_BAD_TARGETS; + + if (caster->GetPetGUID()) + return SPELL_FAILED_ALREADY_HAVE_SUMMON; + + if (caster->GetCharmGUID()) + return SPELL_FAILED_ALREADY_HAVE_CHARM; + } + else + return SPELL_FAILED_BAD_IMPLICIT_TARGETS; + + return SPELL_CAST_OK; + } + + void Register() + { + OnCheckCast += SpellCheckCastFn(spell_hun_tame_beast_SpellScript::CheckCast); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_hun_tame_beast_SpellScript(); + } +}; void AddSC_hunter_spell_scripts() { @@ -632,4 +713,6 @@ void AddSC_hunter_spell_scripts() new spell_hun_pet_carrion_feeder(); new spell_hun_misdirection(); new spell_hun_misdirection_proc(); + new spell_hun_disengage(); + new spell_hun_tame_beast(); } diff --git a/src/server/scripts/Spells/spell_item.cpp b/src/server/scripts/Spells/spell_item.cpp index 666477e68e7..3c89cb7005a 100644 --- a/src/server/scripts/Spells/spell_item.cpp +++ b/src/server/scripts/Spells/spell_item.cpp @@ -1095,7 +1095,7 @@ class spell_item_shimmering_vessel : public SpellScriptLoader void HandleDummy(SpellEffIndex /* effIndex */) { if (Creature* target = GetHitCreature()) - target->setDeathState(JUST_ALIVED); + target->setDeathState(JUST_RESPAWNED); } void Register() @@ -1535,7 +1535,7 @@ class spell_item_impale_leviroth : public SpellScriptLoader void HandleDummy(SpellEffIndex /* effIndex */) { if (Unit* target = GetHitCreature()) - if (target->GetEntry() == NPC_LEVIROTH && target->HealthBelowPct(95)) + if (target->GetEntry() == NPC_LEVIROTH && !target->HealthBelowPct(95)) target->CastSpell(target, SPELL_LEVIROTH_SELF_IMPALE, true); } @@ -1744,11 +1744,20 @@ class spell_item_rocket_boots : public SpellScriptLoader if (Battleground* bg = caster->GetBattleground()) bg->EventPlayerDroppedFlag(caster); + caster->RemoveSpellCooldown(SPELL_ROCKET_BOOTS_PROC); caster->CastSpell(caster, SPELL_ROCKET_BOOTS_PROC, true, NULL); } + SpellCastResult CheckCast() + { + if (GetCaster()->IsInWater()) + return SPELL_FAILED_ONLY_ABOVEWATER; + return SPELL_CAST_OK; + } + void Register() { + OnCheckCast += SpellCheckCastFn(spell_item_rocket_boots_SpellScript::CheckCast); OnEffectHitTarget += SpellEffectFn(spell_item_rocket_boots_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); } }; @@ -1839,60 +1848,6 @@ class spell_item_unusual_compass : public SpellScriptLoader } }; -enum UDED -{ - NPC_IRONWOOL_MAMMOTH = 53806, - SPELL_MAMMOTH_CARCASS = 57444, - SPELL_MAMMOTH_MEAT = 54625, -}; - -class spell_item_uded : public SpellScriptLoader -{ - public: - spell_item_uded() : SpellScriptLoader("spell_item_uded") { } - - class spell_item_uded_SpellScript : public SpellScript - { - PrepareSpellScript(spell_item_uded_SpellScript); - - bool Load() - { - if (GetHitCreature() && GetHitCreature()->GetEntry() == NPC_IRONWOOL_MAMMOTH) - return true; - return false; - } - - bool Validate(SpellInfo const* /*spell*/) - { - if (!sSpellMgr->GetSpellInfo(SPELL_MAMMOTH_CARCASS) || !sSpellMgr->GetSpellInfo(SPELL_MAMMOTH_MEAT)) - return false; - return true; - } - - void HandleDummy(SpellEffIndex /* effIndex */) - { - Unit* caster = GetCaster(); - Creature* creature = GetHitCreature(); - caster->CastSpell(caster,SPELL_MAMMOTH_CARCASS,true); - - for (uint8 i = 0; i < 4; ++i) - caster->CastSpell(caster,SPELL_MAMMOTH_MEAT,true); - - creature->Kill(creature); - } - - void Register() - { - OnEffectHitTarget += SpellEffectFn(spell_item_uded_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); - } - }; - - SpellScript* GetSpellScript() const - { - return new spell_item_uded_SpellScript(); - } -}; - enum ChickenCover { SPELL_CHICKEN_NET = 51959, @@ -2005,7 +1960,7 @@ class spell_item_muisek_vessel : public SpellScriptLoader { if (Creature* target = GetHitCreature()) if (target->isDead()) - target->ForcedDespawn(); + target->DespawnOrUnsummon(); } void Register() @@ -2020,6 +1975,37 @@ class spell_item_muisek_vessel : public SpellScriptLoader } }; +enum GreatmothersSoulcather +{ + SPELL_FORCE_CAST_SUMMON_GNOME_SOUL = 46486, +}; +class spell_item_greatmothers_soulcatcher : public SpellScriptLoader +{ +public: + spell_item_greatmothers_soulcatcher() : SpellScriptLoader("spell_item_greatmothers_soulcatcher") { } + + class spell_item_greatmothers_soulcatcher_SpellScript : public SpellScript + { + PrepareSpellScript(spell_item_greatmothers_soulcatcher_SpellScript); + + void HandleDummy(SpellEffIndex /*effIndex*/) + { + if (GetHitUnit()) + GetCaster()->CastSpell(GetCaster(),SPELL_FORCE_CAST_SUMMON_GNOME_SOUL); + } + + void Register() + { + OnEffectHitTarget += SpellEffectFn(spell_item_greatmothers_soulcatcher_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_item_greatmothers_soulcatcher_SpellScript(); + } +}; + void AddSC_item_spell_scripts() { // 23074 Arcanite Dragonling @@ -2069,7 +2055,7 @@ void AddSC_item_spell_scripts() new spell_item_rocket_boots(); new spell_item_pygmy_oil(); new spell_item_unusual_compass(); - new spell_item_uded(); new spell_item_chicken_cover(); new spell_item_muisek_vessel(); + new spell_item_greatmothers_soulcatcher(); } diff --git a/src/server/scripts/Spells/spell_mage.cpp b/src/server/scripts/Spells/spell_mage.cpp index 050741ffaba..0edfbaee437 100644 --- a/src/server/scripts/Spells/spell_mage.cpp +++ b/src/server/scripts/Spells/spell_mage.cpp @@ -342,13 +342,52 @@ public: } }; +class spell_mage_living_bomb : public SpellScriptLoader +{ + public: + spell_mage_living_bomb() : SpellScriptLoader("spell_mage_living_bomb") { } + + class spell_mage_living_bomb_AuraScript : public AuraScript + { + PrepareAuraScript(spell_mage_living_bomb_AuraScript); + + bool Validate(SpellInfo const* spell) + { + if (!sSpellMgr->GetSpellInfo(uint32(spell->Effects[EFFECT_1].CalcValue()))) + return false; + return true; + } + + void AfterRemove(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/) + { + AuraRemoveMode removeMode = GetTargetApplication()->GetRemoveMode(); + if (removeMode != AURA_REMOVE_BY_ENEMY_SPELL && removeMode != AURA_REMOVE_BY_EXPIRE) + return; + + if (Unit* caster = GetCaster()) + caster->CastSpell(GetTarget(), uint32(aurEff->GetAmount()), true, NULL, aurEff); + } + + void Register() + { + AfterEffectRemove += AuraEffectRemoveFn(spell_mage_living_bomb_AuraScript::AfterRemove, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_mage_living_bomb_AuraScript(); + } +}; + void AddSC_mage_spell_scripts() { - new spell_mage_blast_wave; - new spell_mage_cold_snap; + new spell_mage_blast_wave(); + new spell_mage_cold_snap(); new spell_mage_frost_warding_trigger(); new spell_mage_incanters_absorbtion_absorb(); new spell_mage_incanters_absorbtion_manashield(); - new spell_mage_polymorph_cast_visual; - new spell_mage_summon_water_elemental; + new spell_mage_polymorph_cast_visual(); + new spell_mage_summon_water_elemental(); + new spell_mage_living_bomb(); } diff --git a/src/server/scripts/Spells/spell_paladin.cpp b/src/server/scripts/Spells/spell_paladin.cpp index d823c629d4b..0bf2e5664a0 100644 --- a/src/server/scripts/Spells/spell_paladin.cpp +++ b/src/server/scripts/Spells/spell_paladin.cpp @@ -43,6 +43,10 @@ enum PaladinSpells SPELL_DIVINE_STORM = 53385, SPELL_DIVINE_STORM_DUMMY = 54171, SPELL_DIVINE_STORM_HEAL = 54172, + + SPELL_FORBEARANCE = 25771, + SPELL_AVENGING_WRATH_MARKER = 61987, + SPELL_IMMUNE_SHIELD_MARKER = 61988, }; // 31850 - Ardent Defender @@ -255,17 +259,18 @@ class spell_pal_holy_shock : public SpellScriptLoader class spell_pal_holy_shock_SpellScript : public SpellScript { - PrepareSpellScript(spell_pal_holy_shock_SpellScript) - bool Validate(SpellInfo const* spellEntry) + PrepareSpellScript(spell_pal_holy_shock_SpellScript); + + bool Validate(SpellInfo const* spell) { if (!sSpellMgr->GetSpellInfo(PALADIN_SPELL_HOLY_SHOCK_R1)) return false; // can't use other spell than holy shock due to spell_ranks dependency - if (sSpellMgr->GetFirstSpellInChain(PALADIN_SPELL_HOLY_SHOCK_R1) != sSpellMgr->GetFirstSpellInChain(spellEntry->Id)) + if (sSpellMgr->GetFirstSpellInChain(PALADIN_SPELL_HOLY_SHOCK_R1) != sSpellMgr->GetFirstSpellInChain(spell->Id)) return false; - uint8 rank = sSpellMgr->GetSpellRank(spellEntry->Id); + uint8 rank = sSpellMgr->GetSpellRank(spell->Id); if (!sSpellMgr->GetSpellWithRank(PALADIN_SPELL_HOLY_SHOCK_R1_DAMAGE, rank, true) || !sSpellMgr->GetSpellWithRank(PALADIN_SPELL_HOLY_SHOCK_R1_HEALING, rank, true)) return false; @@ -285,9 +290,29 @@ class spell_pal_holy_shock : public SpellScriptLoader } } + SpellCastResult CheckCast() + { + Unit* caster = GetCaster(); + if (Unit* target = GetExplTargetUnit()) + { + if (!caster->IsFriendlyTo(target)) + { + if (!caster->IsValidAttackTarget(target)) + return SPELL_FAILED_BAD_TARGETS; + + if (!caster->isInFront(target)) + return SPELL_FAILED_UNIT_NOT_INFRONT; + } + } + else + return SPELL_FAILED_BAD_TARGETS; + return SPELL_CAST_OK; + } + void Register() { // add dummy effect spell handler to Holy Shock + OnCheckCast += SpellCheckCastFn(spell_pal_holy_shock_SpellScript::CheckCast); OnEffectHitTarget += SpellEffectFn(spell_pal_holy_shock_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); } }; @@ -384,7 +409,7 @@ class spell_pal_divine_storm_dummy : public SpellScriptLoader return true; } - void CountTargets(std::list<Unit*>& targetList) + void CountTargets(std::list<WorldObject*>& targetList) { _targetCount = targetList.size(); } @@ -403,7 +428,7 @@ class spell_pal_divine_storm_dummy : public SpellScriptLoader void Register() { OnEffectHitTarget += SpellEffectFn(spell_pal_divine_storm_dummy_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); - OnUnitTargetSelect += SpellUnitTargetFn(spell_pal_divine_storm_dummy_SpellScript::CountTargets, EFFECT_0, TARGET_UNIT_CASTER_AREA_RAID); + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_pal_divine_storm_dummy_SpellScript::CountTargets, EFFECT_0, TARGET_UNIT_CASTER_AREA_RAID); } }; @@ -413,6 +438,134 @@ class spell_pal_divine_storm_dummy : public SpellScriptLoader } }; +class spell_pal_lay_on_hands : public SpellScriptLoader +{ + public: + spell_pal_lay_on_hands() : SpellScriptLoader("spell_pal_lay_on_hands") { } + + class spell_pal_lay_on_hands_SpellScript : public SpellScript + { + PrepareSpellScript(spell_pal_lay_on_hands_SpellScript); + + bool Validate(SpellInfo const* /*spell*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_FORBEARANCE)) + return false; + if (!sSpellMgr->GetSpellInfo(SPELL_AVENGING_WRATH_MARKER)) + return false; + if (!sSpellMgr->GetSpellInfo(SPELL_IMMUNE_SHIELD_MARKER)) + return false; + return true; + } + + SpellCastResult CheckCast() + { + Unit* caster = GetCaster(); + if (Unit* target = GetExplTargetUnit()) + if (caster == target) + if (target->HasAura(SPELL_FORBEARANCE) || target->HasAura(SPELL_AVENGING_WRATH_MARKER) || target->HasAura(SPELL_IMMUNE_SHIELD_MARKER)) + return SPELL_FAILED_TARGET_AURASTATE; + + return SPELL_CAST_OK; + } + + void HandleScript() + { + Unit* caster = GetCaster(); + if (caster == GetHitUnit()) + { + caster->CastSpell(caster, SPELL_FORBEARANCE, true); + caster->CastSpell(caster, SPELL_AVENGING_WRATH_MARKER, true); + caster->CastSpell(caster, SPELL_IMMUNE_SHIELD_MARKER, true); + } + } + + void Register() + { + OnCheckCast += SpellCheckCastFn(spell_pal_lay_on_hands_SpellScript::CheckCast); + AfterHit += SpellHitFn(spell_pal_lay_on_hands_SpellScript::HandleScript); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_pal_lay_on_hands_SpellScript(); + } +}; + +class spell_pal_righteous_defense : public SpellScriptLoader +{ + public: + spell_pal_righteous_defense() : SpellScriptLoader("spell_pal_righteous_defense") { } + + class spell_pal_righteous_defense_SpellScript : public SpellScript + { + PrepareSpellScript(spell_pal_righteous_defense_SpellScript); + + SpellCastResult CheckCast() + { + Unit* caster = GetCaster(); + if (caster->GetTypeId() != TYPEID_PLAYER) + return SPELL_FAILED_DONT_REPORT; + + if (Unit* target = GetExplTargetUnit()) + { + if (!target->IsFriendlyTo(caster) || target->getAttackers().empty()) + return SPELL_FAILED_BAD_TARGETS; + } + else + return SPELL_FAILED_BAD_TARGETS; + + return SPELL_CAST_OK; + } + + void Register() + { + OnCheckCast += SpellCheckCastFn(spell_pal_righteous_defense_SpellScript::CheckCast); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_pal_righteous_defense_SpellScript(); + } +}; + +class spell_pal_exorcism_and_holy_wrath_damage : public SpellScriptLoader +{ + public: + spell_pal_exorcism_and_holy_wrath_damage() : SpellScriptLoader("spell_pal_exorcism_and_holy_wrath_damage") { } + + class spell_pal_exorcism_and_holy_wrath_damage_AuraScript : public AuraScript + { + PrepareAuraScript(spell_pal_exorcism_and_holy_wrath_damage_AuraScript); + + void HandleEffectCalcSpellMod(AuraEffect const* aurEff, SpellModifier*& spellMod) + { + if (!spellMod) + { + spellMod = new SpellModifier(aurEff->GetBase()); + spellMod->op = SPELLMOD_DAMAGE; + spellMod->type = SPELLMOD_FLAT; + spellMod->spellId = GetId(); + spellMod->mask[1] = 0x200002; + } + + spellMod->value = aurEff->GetAmount(); + } + + void Register() + { + DoEffectCalcSpellMod += AuraEffectCalcSpellModFn(spell_pal_exorcism_and_holy_wrath_damage_AuraScript::HandleEffectCalcSpellMod, EFFECT_0, SPELL_AURA_DUMMY); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_pal_exorcism_and_holy_wrath_damage_AuraScript(); + } +}; + void AddSC_paladin_spell_scripts() { new spell_pal_ardent_defender(); @@ -423,4 +576,7 @@ void AddSC_paladin_spell_scripts() new spell_pal_judgement_of_command(); new spell_pal_divine_storm(); new spell_pal_divine_storm_dummy(); + new spell_pal_lay_on_hands(); + new spell_pal_righteous_defense(); + new spell_pal_exorcism_and_holy_wrath_damage(); } diff --git a/src/server/scripts/Spells/spell_pet.cpp b/src/server/scripts/Spells/spell_pet.cpp new file mode 100644 index 00000000000..7830d46260c --- /dev/null +++ b/src/server/scripts/Spells/spell_pet.cpp @@ -0,0 +1,1744 @@ +/* + * Copyright (C) 2008-2012 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/* + * Scripts for spells with SPELLFAMILY_DEATHKNIGHT and SPELLFAMILY_GENERIC spells used by deathknight players. + * Ordered alphabetically using scriptname. + * Scriptnames of files in this file should be prefixed with "spell_dk_". + */ + +#include "ScriptMgr.h" +#include "SpellScript.h" +#include "SpellAuraEffects.h" +#include "Unit.h" +#include "Player.h" +#include "Pet.h" + +enum HunterPetCalculate +{ + SPELL_TAMED_PET_PASSIVE_06 = 19591, + SPELL_TAMED_PET_PASSIVE_07 = 20784, + SPELL_TAMED_PET_PASSIVE_08 = 34666, + SPELL_TAMED_PET_PASSIVE_09 = 34667, + SPELL_TAMED_PET_PASSIVE_10 = 34675, + SPELL_HUNTER_PET_SCALING_01 = 34902, + SPELL_HUNTER_PET_SCALING_02 = 34903, + SPELL_HUNTER_PET_SCALING_03 = 34904, + SPELL_HUNTER_PET_SCALING_04 = 61017, + SPELL_HUNTER_ANIMAL_HANDLER = 34453, +}; + +enum WarlockPetCalculate +{ + SPELL_PET_PASSIVE_CRIT = 35695, + SPELL_PET_PASSIVE_DAMAGE_TAKEN = 35697, + SPELL_WARLOCK_PET_SCALING_01 = 34947, + SPELL_WARLOCK_PET_SCALING_02 = 34956, + SPELL_WARLOCK_PET_SCALING_03 = 34957, + SPELL_WARLOCK_PET_SCALING_04 = 34958, + SPELL_WARLOCK_PET_SCALING_05 = 61013, + ENTRY_FELGUARD = 17252, + ENTRY_VOIDWALKER = 1860, + ENTRY_FELHUNTER = 417, + ENTRY_SUCCUBUS = 1863, + ENTRY_IMP = 416, + SPELL_WARLOCK_GLYPH_OF_VOIDWALKER = 56247, +}; + +enum DKPetCalculate +{ + SPELL_DEATH_KNIGHT_RUNE_WEAPON_02 = 51906, + SPELL_DEATH_KNIGHT_PET_SCALING_01 = 54566, + SPELL_DEATH_KNIGHT_PET_SCALING_02 = 51996, + SPELL_DEATH_KNIGHT_PET_SCALING_03 = 61697, + SPELL_NIGHT_OF_THE_DEAD = 55620, + ENTRY_ARMY_OF_THE_DEAD_GHOUL = 24207, + SPELL_DEATH_KNIGHT_GLYPH_OF_GHOUL = 58686, +}; + +enum ShamanPetCalculate +{ + SPELL_FERAL_SPIRIT_PET_UNK_01 = 35674, + SPELL_FERAL_SPIRIT_PET_UNK_02 = 35675, + SPELL_FERAL_SPIRIT_PET_UNK_03 = 35676, + SPELL_FERAL_SPIRIT_PET_SCALING_04 = 61783, +}; + +enum MiscPetCalculate +{ + SPELL_MAGE_PET_PASSIVE_ELEMENTAL = 44559, + SPELL_PET_HEALTH_SCALING = 61679, + SPELL_PET_UNK_01 = 67561, + SPELL_PET_UNK_02 = 67557, +}; + +class spell_gen_pet_calculate : public SpellScriptLoader +{ + public: + spell_gen_pet_calculate() : SpellScriptLoader("spell_gen_pet_calculate") { } + + class spell_gen_pet_calculate_AuraScript : public AuraScript + { + PrepareAuraScript(spell_gen_pet_calculate_AuraScript); + + bool Load() + { + if (!GetCaster() || !GetCaster()->GetOwner() || GetCaster()->GetOwner()->GetTypeId() != TYPEID_PLAYER) + return false; + return true; + } + + void CalculateAmountCritSpell(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/) + { + if (Player* owner = GetCaster()->GetOwner()->ToPlayer()) + { + // For others recalculate it from: + float CritSpell = 0.0f; + // Crit from Intellect + CritSpell += owner->GetSpellCritFromIntellect(); + // Increase crit from SPELL_AURA_MOD_SPELL_CRIT_CHANCE + CritSpell += owner->GetTotalAuraModifier(SPELL_AURA_MOD_SPELL_CRIT_CHANCE); + // Increase crit from SPELL_AURA_MOD_CRIT_PCT + CritSpell += owner->GetTotalAuraModifier(SPELL_AURA_MOD_CRIT_PCT); + // Increase crit spell from spell crit ratings + CritSpell += owner->GetRatingBonusValue(CR_CRIT_SPELL); + + amount += int32(CritSpell); + } + } + + void CalculateAmountCritMelee(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/) + { + if (Player* owner = GetCaster()->GetOwner()->ToPlayer()) + { + // For others recalculate it from: + float CritMelee = 0.0f; + // Crit from Agility + CritMelee += owner->GetMeleeCritFromAgility(); + // Increase crit from SPELL_AURA_MOD_WEAPON_CRIT_PERCENT + CritMelee += owner->GetTotalAuraModifier(SPELL_AURA_MOD_WEAPON_CRIT_PERCENT); + // Increase crit from SPELL_AURA_MOD_CRIT_PCT + CritMelee += owner->GetTotalAuraModifier(SPELL_AURA_MOD_CRIT_PCT); + // Increase crit melee from melee crit ratings + CritMelee += owner->GetRatingBonusValue(CR_CRIT_MELEE); + + amount += int32(CritMelee); + } + } + + void CalculateAmountMeleeHit(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/) + { + if (Player* owner = GetCaster()->GetOwner()->ToPlayer()) + { + // For others recalculate it from: + float HitMelee = 0.0f; + // Increase hit from SPELL_AURA_MOD_HIT_CHANCE + HitMelee += owner->GetTotalAuraModifier(SPELL_AURA_MOD_HIT_CHANCE); + // Increase hit melee from meele hit ratings + HitMelee += owner->GetRatingBonusValue(CR_HIT_MELEE); + + amount += int32(HitMelee); + } + } + + void CalculateAmountSpellHit(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/) + { + if (Player* owner = GetCaster()->GetOwner()->ToPlayer()) + { + // For others recalculate it from: + float HitSpell = 0.0f; + // Increase hit from SPELL_AURA_MOD_SPELL_HIT_CHANCE + HitSpell += owner->GetTotalAuraModifier(SPELL_AURA_MOD_SPELL_HIT_CHANCE); + // Increase hit spell from spell hit ratings + HitSpell += owner->GetRatingBonusValue(CR_HIT_SPELL); + + amount += int32(HitSpell); + } + } + + void CalculateAmountExpertise(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/) + { + if (Player* owner = GetCaster()->GetOwner()->ToPlayer()) + { + // For others recalculate it from: + float Expertise = 0.0f; + // Increase hit from SPELL_AURA_MOD_EXPERTISE + Expertise += owner->GetTotalAuraModifier(SPELL_AURA_MOD_EXPERTISE); + // Increase Expertise from Expertise ratings + Expertise += owner->GetRatingBonusValue(CR_EXPERTISE); + + amount += int32(Expertise); + } + } + + void Register() + { + switch (m_scriptSpellId) + { + case SPELL_TAMED_PET_PASSIVE_06: + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_gen_pet_calculate_AuraScript::CalculateAmountCritMelee, EFFECT_0, SPELL_AURA_MOD_WEAPON_CRIT_PERCENT); + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_gen_pet_calculate_AuraScript::CalculateAmountCritSpell, EFFECT_1, SPELL_AURA_MOD_SPELL_CRIT_CHANCE); + break; + case SPELL_PET_PASSIVE_CRIT: + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_gen_pet_calculate_AuraScript::CalculateAmountCritSpell, EFFECT_0, SPELL_AURA_MOD_SPELL_CRIT_CHANCE); + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_gen_pet_calculate_AuraScript::CalculateAmountCritMelee, EFFECT_1, SPELL_AURA_MOD_WEAPON_CRIT_PERCENT); + break; + case SPELL_WARLOCK_PET_SCALING_05: + case SPELL_HUNTER_PET_SCALING_04: + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_gen_pet_calculate_AuraScript::CalculateAmountMeleeHit, EFFECT_0, SPELL_AURA_MOD_HIT_CHANCE); + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_gen_pet_calculate_AuraScript::CalculateAmountSpellHit, EFFECT_1, SPELL_AURA_MOD_SPELL_HIT_CHANCE); + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_gen_pet_calculate_AuraScript::CalculateAmountExpertise, EFFECT_2, SPELL_AURA_MOD_EXPERTISE); + break; + case SPELL_DEATH_KNIGHT_PET_SCALING_03: +// case SPELL_SHAMAN_PET_HIT: + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_gen_pet_calculate_AuraScript::CalculateAmountMeleeHit, EFFECT_0, SPELL_AURA_MOD_HIT_CHANCE); + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_gen_pet_calculate_AuraScript::CalculateAmountSpellHit, EFFECT_1, SPELL_AURA_MOD_SPELL_HIT_CHANCE); + break; + default: + break; + } + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_gen_pet_calculate_AuraScript(); + } +}; + +class spell_warl_pet_scaling_01 : public SpellScriptLoader +{ +public: + spell_warl_pet_scaling_01() : SpellScriptLoader("spell_warl_pet_scaling_01") { } + + class spell_warl_pet_scaling_01_AuraScript : public AuraScript + { + PrepareAuraScript(spell_warl_pet_scaling_01_AuraScript); + + bool Load() + { + if (!GetCaster() || !GetCaster()->GetOwner() || GetCaster()->GetOwner()->GetTypeId() != TYPEID_PLAYER) + return false; + _tempBonus = 0; + return true; + } + + void CalculateStaminaAmount(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/) + { + if (Unit* pet = GetUnitOwner()) + if (pet->isPet()) + if (Unit* owner = pet->ToPet()->GetOwner()) + { + float ownerBonus = CalculatePctN(owner->GetStat(STAT_STAMINA), 75); + + amount += ownerBonus; + } + } + + void ApplyEffect(AuraEffect const* /* aurEff */, AuraEffectHandleModes /*mode*/) + { + if (Unit* pet = GetUnitOwner()) + if (_tempBonus) + { + PetLevelInfo const* pInfo = sObjectMgr->GetPetLevelInfo(pet->GetEntry(), pet->getLevel()); + uint32 healthMod = 0; + uint32 baseHealth = pInfo->health; + switch (pet->GetEntry()) + { + case ENTRY_IMP: + healthMod = uint32(_tempBonus * 8.4f); + break; + case ENTRY_FELGUARD: + case ENTRY_VOIDWALKER: + healthMod = _tempBonus * 11; + break; + case ENTRY_SUCCUBUS: + healthMod = uint32(_tempBonus * 9.1f); + break; + case ENTRY_FELHUNTER: + healthMod = uint32(_tempBonus * 9.5f); + break; + default: + healthMod = 0; + break; + } + if (healthMod) + pet->ToPet()->SetCreateHealth(baseHealth + healthMod); + } + } + + void RemoveEffect(AuraEffect const* /* aurEff */, AuraEffectHandleModes /*mode*/) + { + if (Unit* pet = GetUnitOwner()) + if (pet->isPet()) + { + PetLevelInfo const* pInfo = sObjectMgr->GetPetLevelInfo(pet->GetEntry(), pet->getLevel()); + pet->ToPet()->SetCreateHealth(pInfo->health); + } + } + + void CalculateAttackPowerAmount(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/) + { + if (Unit* pet = GetUnitOwner()) + if (pet->isPet()) + + if (Unit* owner = pet->ToPet()->GetOwner()) + { + int32 fire = int32(owner->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS + SPELL_SCHOOL_FIRE)) - owner->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_NEG + SPELL_SCHOOL_FIRE); + int32 shadow = int32(owner->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS + SPELL_SCHOOL_SHADOW)) - owner->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_NEG + SPELL_SCHOOL_SHADOW); + int32 maximum = (fire > shadow) ? fire : shadow; + if (maximum < 0) + maximum = 0; + float bonusAP = maximum * 0.57f; + + amount += bonusAP; + + // Glyph of felguard + if (pet->GetEntry() == ENTRY_FELGUARD) + { + if (AuraEffect* /* aurEff */ect = owner->GetAuraEffect(56246, EFFECT_0)) + { + float base_attPower = pet->GetModifierValue(UNIT_MOD_ATTACK_POWER, BASE_VALUE) * pet->GetModifierValue(UNIT_MOD_ATTACK_POWER, BASE_PCT); + amount += CalculatePctN(amount+base_attPower, /* aurEff */ect->GetAmount()); + } + } + } + } + + void CalculateDamageDoneAmount(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/) + { + if (Unit* pet = GetUnitOwner()) + if (pet->isPet()) + if (Unit* owner = pet->ToPet()->GetOwner()) + { + //the damage bonus used for pets is either fire or shadow damage, whatever is higher + int32 fire = int32(owner->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS + SPELL_SCHOOL_FIRE)) - owner->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_NEG + SPELL_SCHOOL_FIRE); + int32 shadow = int32(owner->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS + SPELL_SCHOOL_SHADOW)) - owner->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_NEG + SPELL_SCHOOL_SHADOW); + int32 maximum = (fire > shadow) ? fire : shadow; + float bonusDamage = 0.0f; + + if (maximum > 0) + bonusDamage = maximum * 0.15f; + + amount += bonusDamage; + } + } + + void Register() + { + OnEffectRemove += AuraEffectRemoveFn(spell_warl_pet_scaling_01_AuraScript::RemoveEffect, EFFECT_0, SPELL_AURA_MOD_STAT, AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK); + AfterEffectApply += AuraEffectApplyFn(spell_warl_pet_scaling_01_AuraScript::ApplyEffect, EFFECT_0, SPELL_AURA_MOD_STAT, AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK); + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_warl_pet_scaling_01_AuraScript::CalculateStaminaAmount, EFFECT_0, SPELL_AURA_MOD_STAT); + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_warl_pet_scaling_01_AuraScript::CalculateAttackPowerAmount, EFFECT_1, SPELL_AURA_MOD_ATTACK_POWER); + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_warl_pet_scaling_01_AuraScript::CalculateDamageDoneAmount, EFFECT_2, SPELL_AURA_MOD_DAMAGE_DONE); + } + + private: + uint32 _tempBonus; + }; + + AuraScript* GetAuraScript() const + { + return new spell_warl_pet_scaling_01_AuraScript(); + } +}; + +class spell_warl_pet_scaling_02 : public SpellScriptLoader +{ +public: + spell_warl_pet_scaling_02() : SpellScriptLoader("spell_warl_pet_scaling_02") { } + + class spell_warl_pet_scaling_02_AuraScript : public AuraScript + { + PrepareAuraScript(spell_warl_pet_scaling_02_AuraScript); + + bool Load() + { + if (!GetCaster() || !GetCaster()->GetOwner() || GetCaster()->GetOwner()->GetTypeId() != TYPEID_PLAYER) + return false; + _tempBonus = 0; + return true; + } + + void CalculateIntellectAmount(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/) + { + if (Unit* pet = GetUnitOwner()) + if (pet->isPet()) + if (Unit* owner = pet->ToPet()->GetOwner()) + { + float ownerBonus = 0.0f; + + ownerBonus = CalculatePctN(owner->GetStat(STAT_INTELLECT), 30); + + amount += ownerBonus; + _tempBonus = ownerBonus; + } + } + + void ApplyEffect(AuraEffect const* /* aurEff */, AuraEffectHandleModes /*mode*/) + { + if (Unit* pet = GetUnitOwner()) + if (_tempBonus) + { + PetLevelInfo const* pInfo = sObjectMgr->GetPetLevelInfo(pet->GetEntry(), pet->getLevel()); + uint32 manaMod = 0; + uint32 baseMana = pInfo->mana; + switch (pet->GetEntry()) + { + case ENTRY_IMP: + manaMod = uint32(_tempBonus * 4.9f); + break; + case ENTRY_VOIDWALKER: + case ENTRY_SUCCUBUS: + case ENTRY_FELHUNTER: + case ENTRY_FELGUARD: + manaMod = uint32(_tempBonus * 11.5f); + break; + default: + manaMod = 0; + break; + } + if (manaMod) + pet->ToPet()->SetCreateMana(baseMana + manaMod); + } + } + + void RemoveEffect(AuraEffect const* /* aurEff */, AuraEffectHandleModes /*mode*/) + { + if (Unit* pet = GetUnitOwner()) + if (pet->isPet()) + { + PetLevelInfo const* pInfo = sObjectMgr->GetPetLevelInfo(pet->GetEntry(), pet->getLevel()); + pet->ToPet()->SetCreateMana(pInfo->mana); + } + } + + void CalculateArmorAmount(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/) + { + if (Unit* pet = GetUnitOwner()) + if (pet->isPet()) + if (Unit* owner = pet->ToPet()->GetOwner()) + { + float ownerBonus = 0.0f; + ownerBonus = CalculatePctN(owner->GetArmor(), 35); + amount += ownerBonus; + } + } + + void CalculateFireResistanceAmount(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/) + { + if (Unit* pet = GetUnitOwner()) + if (pet->isPet()) + if (Unit* owner = pet->ToPet()->GetOwner()) + { + float ownerBonus = 0.0f; + ownerBonus = CalculatePctN(owner->GetResistance(SPELL_SCHOOL_FIRE), 40); + amount += ownerBonus; + } + } + + void Register() + { + OnEffectRemove += AuraEffectRemoveFn(spell_warl_pet_scaling_02_AuraScript::RemoveEffect, EFFECT_0, SPELL_AURA_MOD_STAT, AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK); + AfterEffectApply += AuraEffectApplyFn(spell_warl_pet_scaling_02_AuraScript::ApplyEffect, EFFECT_0, SPELL_AURA_MOD_STAT, AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK); + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_warl_pet_scaling_02_AuraScript::CalculateIntellectAmount, EFFECT_0, SPELL_AURA_MOD_STAT); + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_warl_pet_scaling_02_AuraScript::CalculateArmorAmount, EFFECT_1, SPELL_AURA_MOD_RESISTANCE); + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_warl_pet_scaling_02_AuraScript::CalculateFireResistanceAmount, EFFECT_2, SPELL_AURA_MOD_RESISTANCE); + } + + private: + uint32 _tempBonus; + }; + + AuraScript* GetAuraScript() const + { + return new spell_warl_pet_scaling_02_AuraScript(); + } +}; + +class spell_warl_pet_scaling_03 : public SpellScriptLoader +{ +public: + spell_warl_pet_scaling_03() : SpellScriptLoader("spell_warl_pet_scaling_03") { } + + class spell_warl_pet_scaling_03_AuraScript : public AuraScript + { + PrepareAuraScript(spell_warl_pet_scaling_03_AuraScript); + + bool Load() + { + if (!GetCaster() || !GetCaster()->GetOwner() || GetCaster()->GetOwner()->GetTypeId() != TYPEID_PLAYER) + return false; + return true; + } + + void CalculateFrostResistanceAmount(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/) + { + if (Unit* pet = GetUnitOwner()) + if (pet->isPet()) + if (Unit* owner = pet->ToPet()->GetOwner()) + { + float ownerBonus = 0.0f; + ownerBonus = CalculatePctN(owner->GetResistance(SPELL_SCHOOL_FROST), 40); + amount += ownerBonus; + } + } + + void CalculateArcaneResistanceAmount(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/) + { + if (Unit* pet = GetUnitOwner()) + if (pet->isPet()) + if (Unit* owner = pet->ToPet()->GetOwner()) + { + float ownerBonus = 0.0f; + ownerBonus = CalculatePctN(owner->GetResistance(SPELL_SCHOOL_ARCANE), 40); + amount += ownerBonus; + } + } + + void CalculateNatureResistanceAmount(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/) + { + if (Unit* pet = GetUnitOwner()) + if (pet->isPet()) + if (Unit* owner = pet->ToPet()->GetOwner()) + { + float ownerBonus = 0.0f; + ownerBonus = CalculatePctN(owner->GetResistance(SPELL_SCHOOL_NATURE), 40); + amount += ownerBonus; + } + } + + void Register() + { + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_warl_pet_scaling_03_AuraScript::CalculateFrostResistanceAmount, EFFECT_0, SPELL_AURA_MOD_RESISTANCE); + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_warl_pet_scaling_03_AuraScript::CalculateArcaneResistanceAmount, EFFECT_1, SPELL_AURA_MOD_RESISTANCE); + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_warl_pet_scaling_03_AuraScript::CalculateNatureResistanceAmount, EFFECT_2, SPELL_AURA_MOD_RESISTANCE); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_warl_pet_scaling_03_AuraScript(); + } +}; + + +class spell_warl_pet_scaling_04 : public SpellScriptLoader +{ +public: + spell_warl_pet_scaling_04() : SpellScriptLoader("spell_warl_pet_scaling_04") { } + + class spell_warl_pet_scaling_04_AuraScript : public AuraScript + { + PrepareAuraScript(spell_warl_pet_scaling_04_AuraScript); + + bool Load() + { + if (!GetCaster() || !GetCaster()->GetOwner() || GetCaster()->GetOwner()->GetTypeId() != TYPEID_PLAYER) + return false; + return true; + } + + void CalculateShadowResistanceAmount(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/) + { + if (Unit* pet = GetUnitOwner()) + if (pet->isPet()) + if (Unit* owner = pet->ToPet()->GetOwner()) + { + float ownerBonus = 0.0f; + ownerBonus = CalculatePctN(owner->GetResistance(SPELL_SCHOOL_SHADOW), 40); + amount += ownerBonus; + } + } + + void Register() + { + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_warl_pet_scaling_04_AuraScript::CalculateShadowResistanceAmount, EFFECT_0, SPELL_AURA_MOD_RESISTANCE); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_warl_pet_scaling_04_AuraScript(); + } +}; + +class spell_warl_pet_scaling_05 : public SpellScriptLoader +{ +public: + spell_warl_pet_scaling_05() : SpellScriptLoader("spell_warl_pet_scaling_05") { } + + class spell_warl_pet_scaling_05_AuraScript : public AuraScript + { + PrepareAuraScript(spell_warl_pet_scaling_05_AuraScript); + + bool Load() + { + if (!GetCaster() || !GetCaster()->GetOwner() || GetCaster()->GetOwner()->GetTypeId() != TYPEID_PLAYER) + return false; + return true; + } + + void CalculateAmountMeleeHit(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/) + { + if (Player* owner = GetCaster()->GetOwner()->ToPlayer()) + { + // For others recalculate it from: + float HitMelee = 0.0f; + // Increase hit from SPELL_AURA_MOD_SPELL_HIT_CHANCE + HitMelee += owner->GetTotalAuraModifier(SPELL_AURA_MOD_SPELL_HIT_CHANCE); + // Increase hit spell from spell hit ratings + HitMelee += owner->GetRatingBonusValue(CR_HIT_SPELL); + + amount += int32(HitMelee); + } + } + + void CalculateAmountSpellHit(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/) + { + if (Player* owner = GetCaster()->GetOwner()->ToPlayer()) + { + // For others recalculate it from: + float HitSpell = 0.0f; + // Increase hit from SPELL_AURA_MOD_SPELL_HIT_CHANCE + HitSpell += owner->GetTotalAuraModifier(SPELL_AURA_MOD_SPELL_HIT_CHANCE); + // Increase hit spell from spell hit ratings + HitSpell += owner->GetRatingBonusValue(CR_HIT_SPELL); + + amount += int32(HitSpell); + } + } + + void CalculateAmountExpertise(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/) + { + if (Player* owner = GetCaster()->GetOwner()->ToPlayer()) + { + // For others recalculate it from: + float Expertise = 0.0f; + // Increase hit from SPELL_AURA_MOD_SPELL_HIT_CHANCE + Expertise += owner->GetTotalAuraModifier(SPELL_AURA_MOD_SPELL_HIT_CHANCE); + // Increase hit spell from spell hit ratings + Expertise += owner->GetRatingBonusValue(CR_HIT_SPELL); + + amount += int32(Expertise); + } + } + + void Register() + { + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_warl_pet_scaling_05_AuraScript::CalculateAmountMeleeHit, EFFECT_0, SPELL_AURA_MOD_HIT_CHANCE); + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_warl_pet_scaling_05_AuraScript::CalculateAmountSpellHit, EFFECT_1, SPELL_AURA_MOD_SPELL_HIT_CHANCE); + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_warl_pet_scaling_05_AuraScript::CalculateAmountExpertise, EFFECT_2, SPELL_AURA_MOD_EXPERTISE); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_warl_pet_scaling_05_AuraScript(); + } +}; + +class spell_warl_pet_passive : public SpellScriptLoader +{ +public: + spell_warl_pet_passive() : SpellScriptLoader("spell_warl_pet_passive") { } + + class spell_warl_pet_passive_AuraScript : public AuraScript + { + PrepareAuraScript(spell_warl_pet_passive_AuraScript); + + bool Load() + { + if (!GetCaster() || !GetCaster()->GetOwner() || GetCaster()->GetOwner()->GetTypeId() != TYPEID_PLAYER) + return false; + return true; + } + + void CalculateAmountCritSpell(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/) + { + if (Player* owner = GetCaster()->GetOwner()->ToPlayer()) + { + // For others recalculate it from: + float CritSpell = 0.0f; + // Crit from Intellect + CritSpell += owner->GetSpellCritFromIntellect(); + // Increase crit from SPELL_AURA_MOD_SPELL_CRIT_CHANCE + CritSpell += owner->GetTotalAuraModifier(SPELL_AURA_MOD_SPELL_CRIT_CHANCE); + // Increase crit from SPELL_AURA_MOD_CRIT_PCT + CritSpell += owner->GetTotalAuraModifier(SPELL_AURA_MOD_CRIT_PCT); + // Increase crit spell from spell crit ratings + CritSpell += owner->GetRatingBonusValue(CR_CRIT_SPELL); + + if (AuraApplication* improvedDemonicTacticsApp = owner->GetAuraApplicationOfRankedSpell(54347)) + if (Aura* improvedDemonicTactics = improvedDemonicTacticsApp->GetBase()) + if (AuraEffect* improvedDemonicTacticsEffect = improvedDemonicTactics->GetEffect(EFFECT_0)) + amount += CalculatePctN(CritSpell, improvedDemonicTacticsEffect->GetAmount()); + } + } + + void CalculateAmountCritMelee(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/) + { + if (Player* owner = GetCaster()->GetOwner()->ToPlayer()) + { + // For others recalculate it from: + float CritMelee = 0.0f; + // Crit from Agility + CritMelee += owner->GetMeleeCritFromAgility(); + // Increase crit from SPELL_AURA_MOD_WEAPON_CRIT_PERCENT + CritMelee += owner->GetTotalAuraModifier(SPELL_AURA_MOD_WEAPON_CRIT_PERCENT); + // Increase crit from SPELL_AURA_MOD_CRIT_PCT + CritMelee += owner->GetTotalAuraModifier(SPELL_AURA_MOD_CRIT_PCT); + // Increase crit melee from melee crit ratings + CritMelee += owner->GetRatingBonusValue(CR_CRIT_MELEE); + + if (AuraApplication* improvedDemonicTacticsApp = owner->GetAuraApplicationOfRankedSpell(54347)) + if (Aura* improvedDemonicTactics = improvedDemonicTacticsApp->GetBase()) + if (AuraEffect* improvedDemonicTacticsEffect = improvedDemonicTactics->GetEffect(EFFECT_0)) + amount += CalculatePctN(CritMelee, improvedDemonicTacticsEffect->GetAmount()); + } + } + + void Register() + { + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_warl_pet_passive_AuraScript::CalculateAmountCritSpell, EFFECT_0, SPELL_AURA_MOD_SPELL_CRIT_CHANCE); + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_warl_pet_passive_AuraScript::CalculateAmountCritMelee, EFFECT_1, SPELL_AURA_MOD_WEAPON_CRIT_PERCENT); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_warl_pet_passive_AuraScript(); + } +}; +// this doesnt actually fit in here +class spell_warl_pet_passive_damage_done : public SpellScriptLoader +{ +public: + spell_warl_pet_passive_damage_done() : SpellScriptLoader("spell_warl_pet_passive_damage_done") { } + + class spell_warl_pet_passive_damage_done_AuraScript : public AuraScript + { + PrepareAuraScript(spell_warl_pet_passive_damage_done_AuraScript); + + bool Load() + { + if (!GetCaster() || !GetCaster()->GetOwner() || GetCaster()->GetOwner()->GetTypeId() != TYPEID_PLAYER) + return false; + return true; + } + + void CalculateAmountDamageDone(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/) + { + if (!GetCaster() || !GetCaster()->GetOwner()) + return; + if (GetCaster()->GetOwner()->ToPlayer()) + { + switch (GetCaster()->GetEntry()) + { + case ENTRY_VOIDWALKER: + amount += -16; + break; + case ENTRY_FELHUNTER: + amount += -20; + break; + case ENTRY_SUCCUBUS: + case ENTRY_FELGUARD: + amount += 5; + break; + } + } + } + + void Register() + { + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_warl_pet_passive_damage_done_AuraScript::CalculateAmountDamageDone, EFFECT_0, SPELL_AURA_MOD_DAMAGE_PERCENT_DONE); + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_warl_pet_passive_damage_done_AuraScript::CalculateAmountDamageDone, EFFECT_1, SPELL_AURA_MOD_DAMAGE_PERCENT_DONE); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_warl_pet_passive_damage_done_AuraScript(); + } +}; + +class spell_warl_pet_passive_voidwalker : public SpellScriptLoader +{ +public: + spell_warl_pet_passive_voidwalker() : SpellScriptLoader("spell_warl_pet_passive_voidwalker") { } + + class spell_warl_pet_passive_voidwalker_AuraScript : public AuraScript + { + PrepareAuraScript(spell_warl_pet_passive_voidwalker_AuraScript); + + bool Load() + { + if (!GetCaster() || !GetCaster()->GetOwner() || GetCaster()->GetOwner()->GetTypeId() != TYPEID_PLAYER) + return false; + return true; + } + + void CalculateAmount(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/) + { + if (Unit* pet = GetUnitOwner()) + if (pet->isPet()) + if (Unit* owner = pet->ToPet()->GetOwner()) + if (AuraEffect* /* aurEff */ect = owner->GetAuraEffect(SPELL_WARLOCK_GLYPH_OF_VOIDWALKER, EFFECT_0)) + amount += /* aurEff */ect->GetAmount(); + } + + void Register() + { + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_warl_pet_passive_voidwalker_AuraScript::CalculateAmount, EFFECT_0, SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_warl_pet_passive_voidwalker_AuraScript(); + } +}; + + +class spell_sha_pet_scaling_04 : public SpellScriptLoader +{ +public: + spell_sha_pet_scaling_04() : SpellScriptLoader("spell_sha_pet_scaling_04") { } + + class spell_sha_pet_scaling_04_AuraScript : public AuraScript + { + PrepareAuraScript(spell_sha_pet_scaling_04_AuraScript); + + bool Load() + { + if (!GetCaster() || !GetCaster()->GetOwner() || GetCaster()->GetOwner()->GetTypeId() != TYPEID_PLAYER) + return false; + return true; + } + + void CalculateAmountMeleeHit(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/) + { + if (Player* owner = GetCaster()->GetOwner()->ToPlayer()) + { + // For others recalculate it from: + float HitMelee = 0.0f; + // Increase hit from SPELL_AURA_MOD_HIT_CHANCE + HitMelee += owner->GetTotalAuraModifier(SPELL_AURA_MOD_HIT_CHANCE); + // Increase hit melee from meele hit ratings + HitMelee += owner->GetRatingBonusValue(CR_HIT_MELEE); + + amount += int32(HitMelee); + } + } + + void CalculateAmountSpellHit(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/) + { + if (Player* owner = GetCaster()->GetOwner()->ToPlayer()) + { + // For others recalculate it from: + float HitSpell = 0.0f; + // Increase hit from SPELL_AURA_MOD_SPELL_HIT_CHANCE + HitSpell += owner->GetTotalAuraModifier(SPELL_AURA_MOD_SPELL_HIT_CHANCE); + // Increase hit spell from spell hit ratings + HitSpell += owner->GetRatingBonusValue(CR_HIT_SPELL); + + amount += int32(HitSpell); + } + } + + void Register() + { + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_sha_pet_scaling_04_AuraScript::CalculateAmountMeleeHit, EFFECT_0, SPELL_AURA_MOD_HIT_CHANCE); + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_sha_pet_scaling_04_AuraScript::CalculateAmountSpellHit, EFFECT_1, SPELL_AURA_MOD_SPELL_HIT_CHANCE); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_sha_pet_scaling_04_AuraScript(); + } +}; + +class spell_hun_pet_scaling_01 : public SpellScriptLoader +{ +public: + spell_hun_pet_scaling_01() : SpellScriptLoader("spell_hun_pet_scaling_01") { } + + class spell_hun_pet_scaling_01_AuraScript : public AuraScript + { + PrepareAuraScript(spell_hun_pet_scaling_01_AuraScript); + + void CalculateStaminaAmount(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/) + { + if (Unit* pet = GetUnitOwner()) + if (pet->isPet()) + if (Unit* owner = pet->ToPet()->GetOwner()) + { + float mod = 0.45f; + float ownerBonus = 0.0f; + + PetSpellMap::const_iterator itr = (pet->ToPet()->m_spells.find(62758)); // Wild Hunt rank 1 + if (itr == pet->ToPet()->m_spells.end()) + itr = pet->ToPet()->m_spells.find(62762); // Wild Hunt rank 2 + + if (itr != pet->ToPet()->m_spells.end()) // If pet has Wild Hunt + { + SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(itr->first); // Then get the SpellProto and add the dummy effect value + AddPctN(mod, spellInfo->Effects[EFFECT_0].CalcValue()); + } + + ownerBonus = owner->GetStat(STAT_STAMINA)*mod; + + amount += ownerBonus; + } + } + + void ApplyEffect(AuraEffect const* /* aurEff */, AuraEffectHandleModes /*mode*/) + { + if (Unit* pet = GetUnitOwner()) + if (_tempHealth) + pet->SetHealth(_tempHealth); + } + + void RemoveEffect(AuraEffect const* /* aurEff */, AuraEffectHandleModes /*mode*/) + { + if (Unit* pet = GetUnitOwner()) + _tempHealth = pet->GetHealth(); + } + + void CalculateAttackPowerAmount(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/) + { + if (Unit* pet = GetUnitOwner()) + { + if (!pet->isPet()) + return; + + Unit* owner = pet->ToPet()->GetOwner(); + if (!owner) + return; + + float mod = 1.0f; //Hunter contribution modifier + float bonusAP = 0.0f; + + PetSpellMap::const_iterator itr = (pet->ToPet()->m_spells.find(62758)); // Wild Hunt rank 1 + if (itr == pet->ToPet()->m_spells.end()) + itr = pet->ToPet()->m_spells.find(62762); // Wild Hunt rank 2 + + if (itr != pet->ToPet()->m_spells.end()) // If pet has Wild Hunt + { + SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(itr->first); // Then get the SpellProto and add the dummy effect value + mod += CalculatePctN(1.0f, spellInfo->Effects[EFFECT_1].CalcValue()); + } + + bonusAP = owner->GetTotalAttackPowerValue(RANGED_ATTACK) * 0.22f * mod; + + amount += bonusAP; + } + } + + void CalculateDamageDoneAmount(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/) + { + if (Unit* pet = GetUnitOwner()) + { + if (!pet->isPet()) + return; + + Unit* owner = pet->ToPet()->GetOwner(); + if (!owner) + return; + + float mod = 1.0f; //Hunter contribution modifier + float bonusDamage = 0.0f; + + PetSpellMap::const_iterator itr = (pet->ToPet()->m_spells.find(62758)); // Wild Hunt rank 1 + if (itr == pet->ToPet()->m_spells.end()) + itr = pet->ToPet()->m_spells.find(62762); // Wild Hunt rank 2 + + if (itr != pet->ToPet()->m_spells.end()) // If pet has Wild Hunt + { + SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(itr->first); // Then get the SpellProto and add the dummy effect value + mod += CalculatePctN(1.0f, spellInfo->Effects[EFFECT_1].CalcValue()); + } + + bonusDamage = owner->GetTotalAttackPowerValue(RANGED_ATTACK) * 0.1287f * mod; + + amount += bonusDamage; + } + } + + void Register() + { + OnEffectRemove += AuraEffectRemoveFn(spell_hun_pet_scaling_01_AuraScript::RemoveEffect, EFFECT_0, SPELL_AURA_MOD_STAT, AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK); + AfterEffectApply += AuraEffectApplyFn(spell_hun_pet_scaling_01_AuraScript::ApplyEffect, EFFECT_0, SPELL_AURA_MOD_STAT, AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK); + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_hun_pet_scaling_01_AuraScript::CalculateStaminaAmount, EFFECT_0, SPELL_AURA_MOD_STAT); + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_hun_pet_scaling_01_AuraScript::CalculateAttackPowerAmount, EFFECT_1, SPELL_AURA_MOD_ATTACK_POWER); + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_hun_pet_scaling_01_AuraScript::CalculateDamageDoneAmount, EFFECT_2, SPELL_AURA_MOD_DAMAGE_DONE); + } + + private: + uint32 _tempHealth; + }; + + AuraScript* GetAuraScript() const + { + return new spell_hun_pet_scaling_01_AuraScript(); + } +}; + +class spell_hun_pet_scaling_02 : public SpellScriptLoader +{ +public: + spell_hun_pet_scaling_02() : SpellScriptLoader("spell_hun_pet_scaling_02") { } + + class spell_hun_pet_scaling_02_AuraScript : public AuraScript + { + PrepareAuraScript(spell_hun_pet_scaling_02_AuraScript); + + bool Load() + { + if (!GetCaster() || !GetCaster()->GetOwner() || GetCaster()->GetOwner()->GetTypeId() != TYPEID_PLAYER) + return false; + return true; + } + + void CalculateFrostResistanceAmount(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/) + { + if (Unit* pet = GetUnitOwner()) + { + if (!pet->isPet()) + return; + + Unit* owner = pet->ToPet()->GetOwner(); + if (!owner) + return; + + float ownerBonus = 0.0f; + + ownerBonus = CalculatePctN(owner->GetResistance(SPELL_SCHOOL_FROST), 40); + + amount += ownerBonus; + } + } + + void CalculateFireResistanceAmount(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/) + { + if (Unit* pet = GetUnitOwner()) + { + if (!pet->isPet()) + return; + + Unit* owner = pet->ToPet()->GetOwner(); + if (!owner) + return; + + float ownerBonus = 0.0f; + + ownerBonus = CalculatePctN(owner->GetResistance(SPELL_SCHOOL_FIRE), 40); + + amount += ownerBonus; + } + } + + void CalculateNatureResistanceAmount(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/) + { + if (Unit* pet = GetUnitOwner()) + { + if (!pet->isPet()) + return; + + Unit* owner = pet->ToPet()->GetOwner(); + if (!owner) + return; + + float ownerBonus = 0.0f; + + ownerBonus = CalculatePctN(owner->GetResistance(SPELL_SCHOOL_NATURE), 40); + + amount += ownerBonus; + } + } + + void Register() + { + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_hun_pet_scaling_02_AuraScript::CalculateFrostResistanceAmount, EFFECT_1, SPELL_AURA_MOD_RESISTANCE); + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_hun_pet_scaling_02_AuraScript::CalculateFireResistanceAmount, EFFECT_0, SPELL_AURA_MOD_RESISTANCE); + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_hun_pet_scaling_02_AuraScript::CalculateNatureResistanceAmount, EFFECT_2, SPELL_AURA_MOD_RESISTANCE); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_hun_pet_scaling_02_AuraScript(); + } +}; + +class spell_hun_pet_scaling_03 : public SpellScriptLoader +{ +public: + spell_hun_pet_scaling_03() : SpellScriptLoader("spell_hun_pet_scaling_03") { } + + class spell_hun_pet_scaling_03_AuraScript : public AuraScript + { + PrepareAuraScript(spell_hun_pet_scaling_03_AuraScript); + + bool Load() + { + if (!GetCaster() || !GetCaster()->GetOwner() || GetCaster()->GetOwner()->GetTypeId() != TYPEID_PLAYER) + return false; + return true; + } + + void CalculateShadowResistanceAmount(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/) + { + if (Unit* pet = GetUnitOwner()) + { + if (!pet->isPet()) + return; + + Unit* owner = pet->ToPet()->GetOwner(); + if (!owner) + return; + + float ownerBonus = 0.0f; + + ownerBonus = CalculatePctN(owner->GetResistance(SPELL_SCHOOL_SHADOW), 40); + + amount += ownerBonus; + } + } + + void CalculateArcaneResistanceAmount(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/) + { + if (Unit* pet = GetUnitOwner()) + { + if (!pet->isPet()) + return; + + Unit* owner = pet->ToPet()->GetOwner(); + if (!owner) + return; + + float ownerBonus = 0.0f; + + ownerBonus = CalculatePctN(owner->GetResistance(SPELL_SCHOOL_ARCANE), 40); + + amount += ownerBonus; + } + } + + void CalculateArmorAmount(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/) + { + if (Unit* pet = GetUnitOwner()) + { + if (!pet->isPet()) + return; + + Unit* owner = pet->ToPet()->GetOwner(); + if (!owner) + return; + + float ownerBonus = 0.0f; + + ownerBonus = CalculatePctN(owner->GetArmor(), 35); + + amount += ownerBonus; + } + } + + void Register() + { + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_hun_pet_scaling_03_AuraScript::CalculateShadowResistanceAmount, EFFECT_0, SPELL_AURA_MOD_RESISTANCE); + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_hun_pet_scaling_03_AuraScript::CalculateArcaneResistanceAmount, EFFECT_1, SPELL_AURA_MOD_RESISTANCE); + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_hun_pet_scaling_03_AuraScript::CalculateArmorAmount, EFFECT_2, SPELL_AURA_MOD_RESISTANCE); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_hun_pet_scaling_03_AuraScript(); + } +}; + +class spell_hun_pet_scaling_04 : public SpellScriptLoader +{ +public: + spell_hun_pet_scaling_04() : SpellScriptLoader("spell_hun_pet_scaling_04") { } + + class spell_hun_pet_scaling_04_AuraScript : public AuraScript + { + PrepareAuraScript(spell_hun_pet_scaling_04_AuraScript); + + bool Load() + { + if (!GetCaster() || !GetCaster()->GetOwner() || GetCaster()->GetOwner()->GetTypeId() != TYPEID_PLAYER) + return false; + return true; + } + + void CalculateAmountMeleeHit(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/) + { + if (!GetCaster() || !GetCaster()->GetOwner()) + return; + if (Player* owner = GetCaster()->GetOwner()->ToPlayer()) + { + // For others recalculate it from: + float HitMelee = 0.0f; + // Increase hit from SPELL_AURA_MOD_HIT_CHANCE + HitMelee += owner->GetTotalAuraModifier(SPELL_AURA_MOD_HIT_CHANCE); + // Increase hit melee from meele hit ratings + HitMelee += owner->GetRatingBonusValue(CR_HIT_MELEE); + + amount += int32(HitMelee); + } + } + + void CalculateAmountSpellHit(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/) + { + if (!GetCaster() || !GetCaster()->GetOwner()) + return; + if (Player* owner = GetCaster()->GetOwner()->ToPlayer()) + { + // For others recalculate it from: + float HitSpell = 0.0f; + // Increase hit from SPELL_AURA_MOD_SPELL_HIT_CHANCE + HitSpell += owner->GetTotalAuraModifier(SPELL_AURA_MOD_SPELL_HIT_CHANCE); + // Increase hit spell from spell hit ratings + HitSpell += owner->GetRatingBonusValue(CR_HIT_SPELL); + + amount += int32(HitSpell); + } + } + + void CalculateAmountExpertise(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/) + { + if (!GetCaster() || !GetCaster()->GetOwner()) + return; + if (Player* owner = GetCaster()->GetOwner()->ToPlayer()) + { + // For others recalculate it from: + float Expertise = 0.0f; + // Increase hit from SPELL_AURA_MOD_EXPERTISE + Expertise += owner->GetTotalAuraModifier(SPELL_AURA_MOD_EXPERTISE); + // Increase Expertise from Expertise ratings + Expertise += owner->GetRatingBonusValue(CR_EXPERTISE); + + amount += int32(Expertise); + } + } + + void Register() + { + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_hun_pet_scaling_04_AuraScript::CalculateAmountMeleeHit, EFFECT_0, SPELL_AURA_MOD_HIT_CHANCE); + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_hun_pet_scaling_04_AuraScript::CalculateAmountSpellHit, EFFECT_1, SPELL_AURA_MOD_SPELL_HIT_CHANCE); + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_hun_pet_scaling_04_AuraScript::CalculateAmountExpertise, EFFECT_2, SPELL_AURA_MOD_EXPERTISE); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_hun_pet_scaling_04_AuraScript(); + } +}; + +class spell_hun_pet_passive_crit : public SpellScriptLoader +{ +public: + spell_hun_pet_passive_crit() : SpellScriptLoader("spell_hun_pet_passive_crit") { } + + class spell_hun_pet_passive_crit_AuraScript : public AuraScript + { + PrepareAuraScript(spell_hun_pet_passive_crit_AuraScript); + + bool Load() + { + if (!GetCaster() || !GetCaster()->GetOwner() || GetCaster()->GetOwner()->GetTypeId() != TYPEID_PLAYER) + return false; + return true; + } + + void CalculateAmountCritSpell(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/) + { + if (!GetCaster() || !GetCaster()->GetOwner()) + return; + if (GetCaster()->GetOwner()->ToPlayer()) + { + // For others recalculate it from: + float CritSpell = 0.0f; + // Crit from Intellect + // CritSpell += owner->GetSpellCritFromIntellect(); + // Increase crit from SPELL_AURA_MOD_SPELL_CRIT_CHANCE + // CritSpell += owner->GetTotalAuraModifier(SPELL_AURA_MOD_SPELL_CRIT_CHANCE); + // Increase crit from SPELL_AURA_MOD_CRIT_PCT + // CritSpell += owner->GetTotalAuraModifier(SPELL_AURA_MOD_CRIT_PCT); + // Increase crit spell from spell crit ratings + // CritSpell += owner->GetRatingBonusValue(CR_CRIT_SPELL); + + amount += (CritSpell*0.8f); + } + } + + void CalculateAmountCritMelee(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/) + { + if (!GetCaster() || !GetCaster()->GetOwner()) + return; + if (GetCaster()->GetOwner()->ToPlayer()) + { + // For others recalculate it from: + float CritMelee = 0.0f; + // Crit from Agility + // CritMelee += owner->GetMeleeCritFromAgility(); + // Increase crit from SPELL_AURA_MOD_WEAPON_CRIT_PERCENT + // CritMelee += owner->GetTotalAuraModifier(SPELL_AURA_MOD_WEAPON_CRIT_PERCENT); + // Increase crit from SPELL_AURA_MOD_CRIT_PCT + // CritMelee += owner->GetTotalAuraModifier(SPELL_AURA_MOD_CRIT_PCT); + // Increase crit melee from melee crit ratings + // CritMelee += owner->GetRatingBonusValue(CR_CRIT_MELEE); + + amount += (CritMelee*0.8f); + } + } + + void Register() + { + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_hun_pet_passive_crit_AuraScript::CalculateAmountCritSpell, EFFECT_1, SPELL_AURA_MOD_SPELL_CRIT_CHANCE); + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_hun_pet_passive_crit_AuraScript::CalculateAmountCritMelee, EFFECT_0, SPELL_AURA_MOD_WEAPON_CRIT_PERCENT); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_hun_pet_passive_crit_AuraScript(); + } +}; + +class spell_hun_pet_passive_damage_done : public SpellScriptLoader +{ +public: + spell_hun_pet_passive_damage_done() : SpellScriptLoader("spell_hun_pet_passive_damage_done") { } + + class spell_hun_pet_passive_damage_done_AuraScript : public AuraScript + { + PrepareAuraScript(spell_hun_pet_passive_damage_done_AuraScript); + + bool Load() + { + if (!GetCaster() || !GetCaster()->GetOwner() || GetCaster()->GetOwner()->GetTypeId() != TYPEID_PLAYER) + return false; + return true; + } + + void CalculateAmountDamageDone(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/) + { + if (!GetCaster() || !GetCaster()->GetOwner()) + return; + if (GetCaster()->GetOwner()->ToPlayer()) + { + // Pet's base damage changes depending on happiness + if (GetCaster()->isPet() && GetCaster()->ToPet()->isHunterPet()) + { + switch (GetCaster()->ToPet()->GetHappinessState()) + { + case HAPPY: + // 125% of normal damage + amount += 25.0f; + break; + case CONTENT: + // 100% of normal damage, nothing to modify + break; + case UNHAPPY: + // 75% of normal damage + amount += -25.0f; + break; + } + } + // Cobra Reflexes + if (AuraEffect* cobraReflexes = GetCaster()->GetAuraEffectOfRankedSpell(61682, EFFECT_0)) + amount -= cobraReflexes->GetAmount(); + } + } + + void Register() + { + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_hun_pet_passive_damage_done_AuraScript::CalculateAmountDamageDone, EFFECT_0, SPELL_AURA_MOD_DAMAGE_PERCENT_DONE); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_hun_pet_passive_damage_done_AuraScript(); + } +}; + +class spell_hun_animal_handler : public SpellScriptLoader +{ +public: + spell_hun_animal_handler() : SpellScriptLoader("spell_hun_animal_handler") { } + + class spell_hun_animal_handler_AuraScript : public AuraScript + { + PrepareAuraScript(spell_hun_animal_handler_AuraScript); + + bool Load() + { + if (!GetCaster() || !GetCaster()->GetOwner() || GetCaster()->GetOwner()->GetTypeId() != TYPEID_PLAYER) + return false; + return true; + } + + void CalculateAmountDamageDone(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/) + { + if (!GetCaster() || !GetCaster()->GetOwner()) + return; + if (Player* owner = GetCaster()->GetOwner()->ToPlayer()) + { + if (AuraEffect* /* aurEff */ect = owner->GetAuraEffectOfRankedSpell(SPELL_HUNTER_ANIMAL_HANDLER, EFFECT_1)) + amount = /* aurEff */ect->GetAmount(); + else + amount = 0; + } + } + + void Register() + { + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_hun_animal_handler_AuraScript::CalculateAmountDamageDone, EFFECT_0, SPELL_AURA_MOD_ATTACK_POWER_PCT); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_hun_animal_handler_AuraScript(); + } +}; + + +class spell_dk_avoidance_passive : public SpellScriptLoader +{ +public: + spell_dk_avoidance_passive() : SpellScriptLoader("spell_dk_avoidance_passive") { } + + class spell_dk_avoidance_passive_AuraScript : public AuraScript + { + PrepareAuraScript(spell_dk_avoidance_passive_AuraScript); + + bool Load() + { + if (!GetCaster() || !GetCaster()->GetOwner() || GetCaster()->GetOwner()->GetTypeId() != TYPEID_PLAYER) + return false; + return true; + } + + void CalculateAvoidanceAmount(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/) + { + if (Unit* pet = GetUnitOwner()) + { + if (Unit* owner = pet->GetOwner()) + { + // Army of the dead ghoul + if (pet->GetEntry() == ENTRY_ARMY_OF_THE_DEAD_GHOUL) + amount = -90; + // Night of the dead + else if ( Aura * aur = owner->GetAuraOfRankedSpell(SPELL_NIGHT_OF_THE_DEAD)) + amount = aur->GetSpellInfo()->Effects[EFFECT_2].CalcValue(); + } + } + } + + void Register() + { + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_dk_avoidance_passive_AuraScript::CalculateAvoidanceAmount, EFFECT_0, SPELL_AURA_MOD_CREATURE_AOE_DAMAGE_AVOIDANCE); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_dk_avoidance_passive_AuraScript(); + } +}; + +class spell_dk_pet_scaling_01 : public SpellScriptLoader +{ +public: + spell_dk_pet_scaling_01() : SpellScriptLoader("spell_dk_pet_scaling_01") { } + + class spell_dk_pet_scaling_01_AuraScript : public AuraScript + { + PrepareAuraScript(spell_dk_pet_scaling_01_AuraScript); + + bool Load() + { + if (!GetCaster() || !GetCaster()->GetOwner() || GetCaster()->GetOwner()->GetTypeId() != TYPEID_PLAYER) + return false; + _tempHealth = 0; + return true; + } + + void CalculateStaminaAmount(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/) + { + if (Unit* pet = GetUnitOwner()) + { + if (pet->isGuardian()) + { + if (Unit* owner = pet->GetOwner()) + { + float mod = 0.3f; + + // Ravenous Dead. Check just if owner has Ravenous Dead since it's effect is not an aura + if (AuraEffect const* aurEff = owner->GetAuraEffect(SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE, SPELLFAMILY_DEATHKNIGHT, 3010, 0)) + { + mod += aurEff->GetSpellInfo()->Effects[EFFECT_1].CalcValue()/100; // Ravenous Dead edits the original scale + } + // Glyph of the Ghoul + if (AuraEffect const* aurEff = owner->GetAuraEffect(SPELL_DEATH_KNIGHT_GLYPH_OF_GHOUL, 0)) + mod += aurEff->GetAmount()/100; + + float ownerBonus = float(owner->GetStat(STAT_STAMINA)) * mod; + amount += ownerBonus; + } + } + } + } + + void ApplyEffect(AuraEffect const* /* aurEff */, AuraEffectHandleModes /*mode*/) + { + if (Unit* pet = GetUnitOwner()) + if (_tempHealth) + pet->SetHealth(_tempHealth); + } + + void RemoveEffect(AuraEffect const* /* aurEff */, AuraEffectHandleModes /*mode*/) + { + if (Unit* pet = GetUnitOwner()) + _tempHealth = pet->GetHealth(); + } + + void CalculateStrengthAmount(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/) + { + if (Unit* pet = GetUnitOwner()) + { + if (!pet->isGuardian()) + return; + + Unit* owner = pet->GetOwner(); + if (!owner) + return; + + float mod = 0.7f; + + // Ravenous Dead + AuraEffect const* aurEff = NULL; + // Check just if owner has Ravenous Dead since it's effect is not an aura + aurEff = owner->GetAuraEffect(SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE, SPELLFAMILY_DEATHKNIGHT, 3010, 0); + if (aurEff) + { + mod += CalculatePctN(mod, aurEff->GetSpellInfo()->Effects[EFFECT_1].CalcValue()); // Ravenous Dead edits the original scale + } + // Glyph of the Ghoul + aurEff = owner->GetAuraEffect(58686, 0); + if (aurEff) + mod += CalculatePctN(1.0f, aurEff->GetAmount()); // Glyph of the Ghoul adds a flat value to the scale mod + float ownerBonus = float(owner->GetStat(STAT_STRENGTH)) * mod; + amount += ownerBonus; + } + } + + void Register() + { + OnEffectRemove += AuraEffectRemoveFn(spell_dk_pet_scaling_01_AuraScript::RemoveEffect, EFFECT_0, SPELL_AURA_MOD_STAT, AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK); + AfterEffectApply += AuraEffectApplyFn(spell_dk_pet_scaling_01_AuraScript::ApplyEffect, EFFECT_0, SPELL_AURA_MOD_STAT, AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK); + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_dk_pet_scaling_01_AuraScript::CalculateStaminaAmount, EFFECT_0, SPELL_AURA_MOD_STAT); + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_dk_pet_scaling_01_AuraScript::CalculateStrengthAmount, EFFECT_1, SPELL_AURA_MOD_STAT); + } + + private: + uint32 _tempHealth; + }; + + AuraScript* GetAuraScript() const + { + return new spell_dk_pet_scaling_01_AuraScript(); + } +}; + +class spell_dk_pet_scaling_02 : public SpellScriptLoader +{ +public: + spell_dk_pet_scaling_02() : SpellScriptLoader("spell_dk_pet_scaling_02") { } + + class spell_dk_pet_scaling_02_AuraScript : public AuraScript + { + PrepareAuraScript(spell_dk_pet_scaling_02_AuraScript); + + bool Load() + { + if (!GetCaster() || !GetCaster()->GetOwner() || GetCaster()->GetOwner()->GetTypeId() != TYPEID_PLAYER) + return false; + return true; + } + + void CalculateAmountMeleeHaste(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/) + { + if (!GetCaster() || !GetCaster()->GetOwner()) + return; + if (Player* owner = GetCaster()->GetOwner()->ToPlayer()) + { + // For others recalculate it from: + float HasteMelee = 0.0f; + // Increase hit from SPELL_AURA_MOD_HIT_CHANCE + HasteMelee += (1-owner->m_modAttackSpeedPct[BASE_ATTACK])*100; + + amount += int32(HasteMelee); + } + } + + void Register() + { + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_dk_pet_scaling_02_AuraScript::CalculateAmountMeleeHaste, EFFECT_1, SPELL_AURA_MELEE_SLOW); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_dk_pet_scaling_02_AuraScript(); + } +}; + +class spell_dk_pet_scaling_03 : public SpellScriptLoader +{ +public: + spell_dk_pet_scaling_03() : SpellScriptLoader("spell_dk_pet_scaling_03") { } + + class spell_dk_pet_scaling_03_AuraScript : public AuraScript + { + PrepareAuraScript(spell_dk_pet_scaling_03_AuraScript); + + bool Load() + { + if (!GetCaster() || !GetCaster()->GetOwner() || GetCaster()->GetOwner()->GetTypeId() != TYPEID_PLAYER) + return false; + return true; + } + + void CalculateAmountMeleeHit(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/) + { + if (!GetCaster() || !GetCaster()->GetOwner()) + return; + if (Player* owner = GetCaster()->GetOwner()->ToPlayer()) + { + // For others recalculate it from: + float HitMelee = 0.0f; + // Increase hit from SPELL_AURA_MOD_HIT_CHANCE + HitMelee += owner->GetTotalAuraModifier(SPELL_AURA_MOD_HIT_CHANCE); + // Increase hit melee from meele hit ratings + HitMelee += owner->GetRatingBonusValue(CR_HIT_MELEE); + + amount += int32(HitMelee); + } + } + + void CalculateAmountSpellHit(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/) + { + if (!GetCaster() || !GetCaster()->GetOwner()) + return; + if (Player* owner = GetCaster()->GetOwner()->ToPlayer()) + { + // For others recalculate it from: + float HitSpell = 0.0f; + // Increase hit from SPELL_AURA_MOD_SPELL_HIT_CHANCE + HitSpell += owner->GetTotalAuraModifier(SPELL_AURA_MOD_SPELL_HIT_CHANCE); + // Increase hit spell from spell hit ratings + HitSpell += owner->GetRatingBonusValue(CR_HIT_SPELL); + + amount += int32(HitSpell); + } + } + + void Register() + { + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_dk_pet_scaling_03_AuraScript::CalculateAmountMeleeHit, EFFECT_0, SPELL_AURA_MOD_HIT_CHANCE); + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_dk_pet_scaling_03_AuraScript::CalculateAmountSpellHit, EFFECT_1, SPELL_AURA_MOD_SPELL_HIT_CHANCE); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_dk_pet_scaling_03_AuraScript(); + } +}; + +class spell_dk_rune_weapon_scaling_02 : public SpellScriptLoader +{ +public: + spell_dk_rune_weapon_scaling_02() : SpellScriptLoader("spell_dk_rune_weapon_scaling_02") { } + + class spell_dk_rune_weapon_scaling_02_AuraScript : public AuraScript + { + PrepareAuraScript(spell_dk_rune_weapon_scaling_02_AuraScript); + + bool Load() + { + if (!GetCaster() || !GetCaster()->GetOwner() || GetCaster()->GetOwner()->GetTypeId() != TYPEID_PLAYER) + return false; + return true; + } + + void CalculateDamageDoneAmount(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/) + { + if (Unit* pet = GetUnitOwner()) + { + Unit* owner = pet->GetOwner(); + if (!owner) + return; + + if (pet->isGuardian()) + ((Guardian*)pet)->SetBonusDamage(owner->GetTotalAttackPowerValue(BASE_ATTACK)); + + amount += owner->CalculateDamage(BASE_ATTACK, true, true);; + } + } + + void CalculateAmountMeleeHaste(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/) + { + if (!GetCaster() || !GetCaster()->GetOwner()) + return; + if (Player* owner = GetCaster()->GetOwner()->ToPlayer()) + { + // For others recalculate it from: + float HasteMelee = 0.0f; + // Increase hit from SPELL_AURA_MOD_HIT_CHANCE + HasteMelee += (1-owner->m_modAttackSpeedPct[BASE_ATTACK])*100; + + amount += int32(HasteMelee); + } + } + + void Register() + { + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_dk_rune_weapon_scaling_02_AuraScript::CalculateDamageDoneAmount, EFFECT_0, SPELL_AURA_MOD_DAMAGE_DONE); + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_dk_rune_weapon_scaling_02_AuraScript::CalculateAmountMeleeHaste, EFFECT_1, SPELL_AURA_MELEE_SLOW); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_dk_rune_weapon_scaling_02_AuraScript(); + } +}; + +void AddSC_pet_spell_scripts() +{ + new spell_gen_pet_calculate(); +} diff --git a/src/server/scripts/Spells/spell_priest.cpp b/src/server/scripts/Spells/spell_priest.cpp index d2bba2b8bc3..3d8ca3e729b 100644 --- a/src/server/scripts/Spells/spell_priest.cpp +++ b/src/server/scripts/Spells/spell_priest.cpp @@ -34,6 +34,11 @@ enum PriestSpells PRIEST_SPELL_PENANCE_R1_HEAL = 47757, PRIEST_SPELL_REFLECTIVE_SHIELD_TRIGGERED = 33619, PRIEST_SPELL_REFLECTIVE_SHIELD_R1 = 33201, + PRIEST_SPELL_VAMPIRIC_TOUCH_DISPEL = 64085, + PRIEST_SPELL_EMPOWERED_RENEW = 63544, + PRIEST_ICON_ID_EMPOWERED_RENEW_TALENT = 3021, + PRIEST_ICON_ID_PAIN_AND_SUFFERING = 2874, + PRIEST_SHADOW_WORD_DEATH = 32409, }; // Guardian Spirit @@ -129,14 +134,14 @@ class spell_pri_mind_sear : public SpellScriptLoader { PrepareSpellScript(spell_pri_mind_sear_SpellScript); - void FilterTargets(std::list<Unit*>& unitList) + void FilterTargets(std::list<WorldObject*>& unitList) { - unitList.remove_if (Trinity::ObjectGUIDCheck(GetCaster()->GetUInt64Value(UNIT_FIELD_CHANNEL_OBJECT))); + unitList.remove_if(Trinity::ObjectGUIDCheck(GetCaster()->GetUInt64Value(UNIT_FIELD_CHANNEL_OBJECT))); } void Register() { - OnUnitTargetSelect += SpellUnitTargetFn(spell_pri_mind_sear_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_DEST_AREA_ENEMY); + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_pri_mind_sear_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_DEST_AREA_ENEMY); } }; @@ -227,10 +232,9 @@ class spell_pri_penance : public SpellScriptLoader SpellCastResult CheckCast() { Player* caster = GetCaster()->ToPlayer(); - if (GetTargetUnit()) - if (Player* target = GetTargetUnit()->ToPlayer()) - if (caster->GetTeam() != target->GetTeam() && !caster->IsValidAttackTarget(target)) - return SPELL_FAILED_BAD_TARGETS; + if (Unit* target = GetExplTargetUnit()) + if (!caster->IsFriendlyTo(target) && !caster->IsValidAttackTarget(target)) + return SPELL_FAILED_BAD_TARGETS; return SPELL_CAST_OK; } @@ -291,12 +295,170 @@ class spell_pri_reflective_shield_trigger : public SpellScriptLoader } }; +enum PrayerOfMending +{ + SPELL_T9_HEALING_2_PIECE = 67201, +}; +// Prayer of Mending Heal +class spell_pri_prayer_of_mending_heal : public SpellScriptLoader +{ +public: + spell_pri_prayer_of_mending_heal() : SpellScriptLoader("spell_pri_prayer_of_mending_heal") { } + + class spell_pri_prayer_of_mending_heal_SpellScript : public SpellScript + { + PrepareSpellScript(spell_pri_prayer_of_mending_heal_SpellScript); + + void HandleHeal(SpellEffIndex /*effIndex*/) + { + if (Unit* caster = GetOriginalCaster()) + { + if (AuraEffect* aurEff = caster->GetAuraEffect(SPELL_T9_HEALING_2_PIECE, EFFECT_0)) + { + int32 heal = GetHitHeal(); + AddPctN(heal, aurEff->GetAmount()); + SetHitHeal(heal); + } + } + + } + + void Register() + { + OnEffectHitTarget += SpellEffectFn(spell_pri_prayer_of_mending_heal_SpellScript::HandleHeal, EFFECT_0, SPELL_EFFECT_HEAL); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_pri_prayer_of_mending_heal_SpellScript(); + } +}; + +class spell_pri_vampiric_touch : public SpellScriptLoader +{ + public: + spell_pri_vampiric_touch() : SpellScriptLoader("spell_pri_vampiric_touch") { } + + class spell_pri_vampiric_touch_AuraScript : public AuraScript + { + PrepareAuraScript(spell_pri_vampiric_touch_AuraScript); + + bool Validate(SpellInfo const* /*spell*/) + { + if (!sSpellMgr->GetSpellInfo(PRIEST_SPELL_VAMPIRIC_TOUCH_DISPEL)) + return false; + return true; + } + + void HandleDispel(DispelInfo* /*dispelInfo*/) + { + if (Unit* caster = GetCaster()) + if (Unit* target = GetUnitOwner()) + if (AuraEffect const* aurEff = GetEffect(EFFECT_1)) + { + int32 damage = aurEff->GetAmount() * 8; + // backfire damage + caster->CastCustomSpell(target, PRIEST_SPELL_VAMPIRIC_TOUCH_DISPEL, &damage, NULL, NULL, true, NULL, aurEff); + } + } + + void Register() + { + AfterDispel += AuraDispelFn(spell_pri_vampiric_touch_AuraScript::HandleDispel); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_pri_vampiric_touch_AuraScript(); + } +}; + +class spell_priest_renew : public SpellScriptLoader +{ + public: + spell_priest_renew() : SpellScriptLoader("spell_priest_renew") { } + + class spell_priest_renew_AuraScript : public AuraScript + { + PrepareAuraScript(spell_priest_renew_AuraScript); + + bool Load() + { + return GetCaster() && GetCaster()->GetTypeId() == TYPEID_PLAYER; + } + + void HandleApplyEffect(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/) + { + if (Unit* caster = GetCaster()) + { + // Empowered Renew + if (AuraEffect const* empoweredRenewAurEff = caster->GetDummyAuraEffect(SPELLFAMILY_PRIEST, PRIEST_ICON_ID_EMPOWERED_RENEW_TALENT, EFFECT_1)) + { + uint32 heal = caster->SpellHealingBonusDone(GetTarget(), GetSpellInfo(), GetEffect(EFFECT_0)->GetAmount(), DOT); + heal = GetTarget()->SpellHealingBonusTaken(caster, GetSpellInfo(), heal, DOT); + + int32 basepoints0 = empoweredRenewAurEff->GetAmount() * GetEffect(EFFECT_0)->GetTotalTicks() * int32(heal) / 100; + caster->CastCustomSpell(GetTarget(), PRIEST_SPELL_EMPOWERED_RENEW, &basepoints0, NULL, NULL, true, NULL, aurEff); + } + } + } + + void Register() + { + OnEffectApply += AuraEffectApplyFn(spell_priest_renew_AuraScript::HandleApplyEffect, EFFECT_0, SPELL_AURA_PERIODIC_HEAL, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_priest_renew_AuraScript(); + } +}; + +class spell_pri_shadow_word_death : public SpellScriptLoader +{ + public: + spell_pri_shadow_word_death() : SpellScriptLoader("spell_pri_shadow_word_death") { } + + class spell_pri_shadow_word_death_SpellScript : public SpellScript + { + PrepareSpellScript(spell_pri_shadow_word_death_SpellScript); + + void HandleDamage() + { + int32 damage = GetHitDamage(); + + // Pain and Suffering reduces damage + if (AuraEffect* aurEff = GetCaster()->GetDummyAuraEffect(SPELLFAMILY_PRIEST, PRIEST_ICON_ID_PAIN_AND_SUFFERING, EFFECT_1)) + AddPctN(damage, aurEff->GetAmount()); + + GetCaster()->CastCustomSpell(GetCaster(), PRIEST_SHADOW_WORD_DEATH, &damage, 0, 0, true); + } + + void Register() + { + OnHit += SpellHitFn(spell_pri_shadow_word_death_SpellScript::HandleDamage); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_pri_shadow_word_death_SpellScript(); + } +}; + void AddSC_priest_spell_scripts() { new spell_pri_guardian_spirit(); - new spell_pri_mana_burn; - new spell_pri_pain_and_suffering_proc; - new spell_pri_penance; + new spell_pri_mana_burn(); + new spell_pri_pain_and_suffering_proc(); + new spell_pri_penance(); new spell_pri_reflective_shield_trigger(); new spell_pri_mind_sear(); + new spell_pri_prayer_of_mending_heal(); + new spell_pri_vampiric_touch(); + new spell_priest_renew(); + new spell_pri_shadow_word_death(); } diff --git a/src/server/scripts/Spells/spell_quest.cpp b/src/server/scripts/Spells/spell_quest.cpp index 48faf83cd2f..5648c510413 100644 --- a/src/server/scripts/Spells/spell_quest.cpp +++ b/src/server/scripts/Spells/spell_quest.cpp @@ -275,7 +275,7 @@ class spell_q11396_11399_scourging_crystal_controller : public SpellScriptLoader void HandleDummy(SpellEffIndex /*effIndex*/) { - if (Unit* target = GetTargetUnit()) + if (Unit* target = GetExplTargetUnit()) if (target->GetTypeId() == TYPEID_UNIT && target->HasAura(SPELL_FORCE_SHIELD_ARCANE_PURPLE_X3)) // Make sure nobody else is channeling the same target if (!target->HasAura(SPELL_SCOURGING_CRYSTAL_CONTROLLER)) @@ -639,7 +639,7 @@ class spell_q12851_going_bearback : public SpellScriptLoader // Already in fire if (target->HasAura(SPELL_ABLAZE)) return; - + if (Player* player = caster->GetCharmerOrOwnerPlayerOrPlayerItself()) { switch (target->GetEntry()) @@ -837,7 +837,7 @@ class spell_q12659_ahunaes_knife : public SpellScriptLoader Player* caster = GetCaster()->ToPlayer(); if (Creature* target = GetHitCreature()) { - target->ForcedDespawn(); + target->DespawnOrUnsummon(); caster->KilledMonsterCredit(NPC_SCALPS_KC_BUNNY, 0); } } @@ -1105,6 +1105,146 @@ public: } }; +enum LeaveNothingToChance +{ + NPC_UPPER_MINE_SHAFT = 27436, + NPC_LOWER_MINE_SHAFT = 27437, + + SPELL_UPPER_MINE_SHAFT_CREDIT = 48744, + SPELL_LOWER_MINE_SHAFT_CREDIT = 48745, +}; + +class spell_q12277_wintergarde_mine_explosion : public SpellScriptLoader +{ + public: + spell_q12277_wintergarde_mine_explosion() : SpellScriptLoader("spell_q12277_wintergarde_mine_explosion") { } + + class spell_q12277_wintergarde_mine_explosion_SpellScript : public SpellScript + { + PrepareSpellScript(spell_q12277_wintergarde_mine_explosion_SpellScript); + + void HandleDummy(SpellEffIndex /*effIndex*/) + { + if (Creature* unitTarget = GetHitCreature()) + { + if (Unit* caster = GetCaster()) + { + if (caster->GetTypeId() == TYPEID_UNIT) + { + if (Unit* owner = caster->GetOwner()) + { + switch (unitTarget->GetEntry()) + { + case NPC_UPPER_MINE_SHAFT: + caster->CastSpell(owner, SPELL_UPPER_MINE_SHAFT_CREDIT, true); + break; + case NPC_LOWER_MINE_SHAFT: + caster->CastSpell(owner, SPELL_LOWER_MINE_SHAFT_CREDIT, true); + break; + default: + break; + } + } + } + } + } + } + + void Register() + { + OnEffectHitTarget += SpellEffectFn(spell_q12277_wintergarde_mine_explosion_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_q12277_wintergarde_mine_explosion_SpellScript(); + } +}; + +enum FocusOnTheBeach +{ + SPELL_BUNNY_CREDIT_BEAM = 47390, +}; + +class spell_q12066_bunny_kill_credit : public SpellScriptLoader +{ +public: + spell_q12066_bunny_kill_credit() : SpellScriptLoader("spell_q12066_bunny_kill_credit") { } + + class spell_q12066_bunny_kill_credit_SpellScript : public SpellScript + { + PrepareSpellScript(spell_q12066_bunny_kill_credit_SpellScript); + + void HandleDummy(SpellEffIndex /*effIndex*/) + { + if (Creature* target = GetHitCreature()) + target->CastSpell(GetCaster(), SPELL_BUNNY_CREDIT_BEAM, false); + } + + void Register() + { + OnEffectHitTarget += SpellEffectFn(spell_q12066_bunny_kill_credit_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_q12066_bunny_kill_credit_SpellScript(); + } +}; + +enum ACleansingSong +{ + SPELL_SUMMON_SPIRIT_ATAH = 52954, + SPELL_SUMMON_SPIRIT_HAKHALAN = 52958, + SPELL_SUMMON_SPIRIT_KOOSU = 52959, + + AREA_BITTERTIDELAKE = 4385, + AREA_RIVERSHEART = 4290, + AREA_WINTERGRASPRIVER = 4388, +}; + +class spell_q12735_song_of_cleansing : public SpellScriptLoader +{ + public: + spell_q12735_song_of_cleansing() : SpellScriptLoader("spell_q12735_song_of_cleansing") { } + + class spell_q12735_song_of_cleansing_SpellScript : public SpellScript + { + PrepareSpellScript(spell_q12735_song_of_cleansing_SpellScript); + + void HandleScript(SpellEffIndex /*effIndex*/) + { + Unit* caster = GetCaster(); + switch (caster->GetAreaId()) + { + case AREA_BITTERTIDELAKE: + caster->CastSpell(caster, SPELL_SUMMON_SPIRIT_ATAH); + break; + case AREA_RIVERSHEART: + caster->CastSpell(caster, SPELL_SUMMON_SPIRIT_HAKHALAN); + break; + case AREA_WINTERGRASPRIVER: + caster->CastSpell(caster, SPELL_SUMMON_SPIRIT_KOOSU); + break; + default: + break; + } + } + + void Register() + { + OnEffectHitTarget += SpellEffectFn(spell_q12735_song_of_cleansing_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_q12735_song_of_cleansing_SpellScript(); + } +}; + void AddSC_quest_spell_scripts() { new spell_q55_sacred_cleansing(); @@ -1131,4 +1271,7 @@ void AddSC_quest_spell_scripts() new spell_q14112_14145_chum_the_water(); new spell_q9452_cast_net(); new spell_q12987_read_pronouncement(); + new spell_q12277_wintergarde_mine_explosion(); + new spell_q12066_bunny_kill_credit(); + new spell_q12735_song_of_cleansing(); } diff --git a/src/server/scripts/Spells/spell_rogue.cpp b/src/server/scripts/Spells/spell_rogue.cpp index 3a4132f62fe..ad437c5e431 100644 --- a/src/server/scripts/Spells/spell_rogue.cpp +++ b/src/server/scripts/Spells/spell_rogue.cpp @@ -350,7 +350,7 @@ class spell_rog_deadly_poison : public SpellScriptLoader SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(enchant->spellid[s]); if (!spellInfo) { - sLog->outError("Player::CastItemCombatSpell Enchant %i, player (Name: %s, GUID: %u) cast unknown spell %i", enchant->ID, player->GetName(), player->GetGUIDLow(), enchant->spellid[s]); + sLog->outError(LOG_FILTER_SPELLS_AURAS, "Player::CastItemCombatSpell Enchant %i, player (Name: %s, GUID: %u) cast unknown spell %i", enchant->ID, player->GetName(), player->GetGUIDLow(), enchant->spellid[s]); continue; } @@ -386,6 +386,34 @@ class spell_rog_deadly_poison : public SpellScriptLoader } }; +class spell_rog_shadowstep : public SpellScriptLoader +{ + public: + spell_rog_shadowstep() : SpellScriptLoader("spell_rog_shadowstep") { } + + class spell_rog_shadowstep_SpellScript : public SpellScript + { + PrepareSpellScript(spell_rog_shadowstep_SpellScript); + + SpellCastResult CheckCast() + { + if (GetCaster()->HasUnitState(UNIT_STATE_ROOT)) + return SPELL_FAILED_ROOTED; + return SPELL_CAST_OK; + } + + void Register() + { + OnCheckCast += SpellCheckCastFn(spell_rog_shadowstep_SpellScript::CheckCast); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_rog_shadowstep_SpellScript(); + } +}; + void AddSC_rogue_spell_scripts() { new spell_rog_cheat_death(); @@ -394,4 +422,5 @@ void AddSC_rogue_spell_scripts() new spell_rog_prey_on_the_weak(); new spell_rog_shiv(); new spell_rog_deadly_poison(); + new spell_rog_shadowstep(); } diff --git a/src/server/scripts/Spells/spell_shaman.cpp b/src/server/scripts/Spells/spell_shaman.cpp index 1a0f4576fea..c863c2363af 100644 --- a/src/server/scripts/Spells/spell_shaman.cpp +++ b/src/server/scripts/Spells/spell_shaman.cpp @@ -36,9 +36,18 @@ enum ShamanSpells SHAMAN_SPELL_SATED = 57724, SHAMAN_SPELL_EXHAUSTION = 57723, + SHAMAN_SPELL_STORM_EARTH_AND_FIRE = 51483, + EARTHBIND_TOTEM_SPELL_EARTHGRAB = 64695, + // For Earthen Power SHAMAN_TOTEM_SPELL_EARTHBIND_TOTEM = 6474, SHAMAN_TOTEM_SPELL_EARTHEN_POWER = 59566, + + SHAMAN_BIND_SIGHT = 6277, + + ICON_ID_SHAMAN_LAVA_FLOW = 3087, + SHAMAN_LAVA_FLOWS_R1 = 51480, + SHAMAN_LAVA_FLOWS_TRIGGERED_R1 = 64694, }; // 51474 - Astral shift @@ -210,20 +219,35 @@ class spell_sha_earthbind_totem : public SpellScriptLoader return true; } - void HandleEffectPeriodic(AuraEffect const* aurEff) + void HandleEffectPeriodic(AuraEffect const* /*aurEff*/) + { + if (!GetCaster()) + return; + if (Player* owner = GetCaster()->GetCharmerOrOwnerPlayerOrPlayerItself()) + if (AuraEffect* aur = owner->GetDummyAuraEffect(SPELLFAMILY_SHAMAN, 2289, 0)) + if (roll_chance_i(aur->GetBaseAmount())) + GetTarget()->CastSpell((Unit*)NULL, SHAMAN_TOTEM_SPELL_EARTHEN_POWER, true); + } + + void Apply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) { - if (Unit* target = GetTarget()) - if (Unit* caster = aurEff->GetBase()->GetCaster()) - if (TempSummon* summon = caster->ToTempSummon()) - if (Unit* owner = summon->GetOwner()) - if (AuraEffect* aur = owner->GetDummyAuraEffect(SPELLFAMILY_SHAMAN, 2289, 0)) - if (roll_chance_i(aur->GetBaseAmount()) && target->HasAuraWithMechanic(1 << MECHANIC_SNARE)) - caster->CastSpell(caster, SHAMAN_TOTEM_SPELL_EARTHEN_POWER, true, NULL, aurEff); + if (!GetCaster()) + return; + Player* owner = GetCaster()->GetCharmerOrOwnerPlayerOrPlayerItself(); + if (!owner) + return; + // Storm, Earth and Fire + if (AuraEffect* aurEff = owner->GetAuraEffectOfRankedSpell(SHAMAN_SPELL_STORM_EARTH_AND_FIRE, EFFECT_1)) + { + if (roll_chance_i(aurEff->GetAmount())) + GetCaster()->CastSpell(GetCaster(), EARTHBIND_TOTEM_SPELL_EARTHGRAB, false); + } } void Register() { OnEffectPeriodic += AuraEffectPeriodicFn(spell_sha_earthbind_totem_AuraScript::HandleEffectPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL); + OnEffectApply += AuraEffectApplyFn(spell_sha_earthbind_totem_AuraScript::Apply, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL, AURA_EFFECT_HANDLE_REAL); } }; @@ -233,6 +257,49 @@ class spell_sha_earthbind_totem : public SpellScriptLoader } }; +class EarthenPowerTargetSelector +{ + public: + EarthenPowerTargetSelector() { } + + bool operator() (WorldObject* target) + { + if (!target->ToUnit()) + return true; + + if (!target->ToUnit()->HasAuraWithMechanic(1 << MECHANIC_SNARE)) + return true; + + return false; + } +}; + +class spell_sha_earthen_power : public SpellScriptLoader +{ + public: + spell_sha_earthen_power() : SpellScriptLoader("spell_sha_earthen_power") { } + + class spell_sha_earthen_power_SpellScript : public SpellScript + { + PrepareSpellScript(spell_sha_earthen_power_SpellScript); + + void FilterTargets(std::list<WorldObject*>& unitList) + { + unitList.remove_if(EarthenPowerTargetSelector()); + } + + void Register() + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_sha_earthen_power_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ALLY); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_sha_earthen_power_SpellScript(); + } +}; + class spell_sha_bloodlust : public SpellScriptLoader { public: @@ -249,9 +316,9 @@ class spell_sha_bloodlust : public SpellScriptLoader return true; } - void RemoveInvalidTargets(std::list<Unit*>& targets) + void RemoveInvalidTargets(std::list<WorldObject*>& targets) { - targets.remove_if (Trinity::UnitAuraCheck(true, SHAMAN_SPELL_SATED)); + targets.remove_if(Trinity::UnitAuraCheck(true, SHAMAN_SPELL_SATED)); } void ApplyDebuff() @@ -262,9 +329,9 @@ class spell_sha_bloodlust : public SpellScriptLoader void Register() { - OnUnitTargetSelect += SpellUnitTargetFn(spell_sha_bloodlust_SpellScript::RemoveInvalidTargets, EFFECT_0, TARGET_UNIT_CASTER_AREA_RAID); - OnUnitTargetSelect += SpellUnitTargetFn(spell_sha_bloodlust_SpellScript::RemoveInvalidTargets, EFFECT_1, TARGET_UNIT_CASTER_AREA_RAID); - OnUnitTargetSelect += SpellUnitTargetFn(spell_sha_bloodlust_SpellScript::RemoveInvalidTargets, EFFECT_2, TARGET_UNIT_CASTER_AREA_RAID); + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_sha_bloodlust_SpellScript::RemoveInvalidTargets, EFFECT_0, TARGET_UNIT_CASTER_AREA_RAID); + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_sha_bloodlust_SpellScript::RemoveInvalidTargets, EFFECT_1, TARGET_UNIT_CASTER_AREA_RAID); + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_sha_bloodlust_SpellScript::RemoveInvalidTargets, EFFECT_2, TARGET_UNIT_CASTER_AREA_RAID); AfterHit += SpellHitFn(spell_sha_bloodlust_SpellScript::ApplyDebuff); } }; @@ -291,9 +358,9 @@ class spell_sha_heroism : public SpellScriptLoader return true; } - void RemoveInvalidTargets(std::list<Unit*>& targets) + void RemoveInvalidTargets(std::list<WorldObject*>& targets) { - targets.remove_if (Trinity::UnitAuraCheck(true, SHAMAN_SPELL_EXHAUSTION)); + targets.remove_if(Trinity::UnitAuraCheck(true, SHAMAN_SPELL_EXHAUSTION)); } void ApplyDebuff() @@ -304,9 +371,9 @@ class spell_sha_heroism : public SpellScriptLoader void Register() { - OnUnitTargetSelect += SpellUnitTargetFn(spell_sha_heroism_SpellScript::RemoveInvalidTargets, EFFECT_0, TARGET_UNIT_CASTER_AREA_RAID); - OnUnitTargetSelect += SpellUnitTargetFn(spell_sha_heroism_SpellScript::RemoveInvalidTargets, EFFECT_1, TARGET_UNIT_CASTER_AREA_RAID); - OnUnitTargetSelect += SpellUnitTargetFn(spell_sha_heroism_SpellScript::RemoveInvalidTargets, EFFECT_2, TARGET_UNIT_CASTER_AREA_RAID); + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_sha_heroism_SpellScript::RemoveInvalidTargets, EFFECT_0, TARGET_UNIT_CASTER_AREA_RAID); + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_sha_heroism_SpellScript::RemoveInvalidTargets, EFFECT_1, TARGET_UNIT_CASTER_AREA_RAID); + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_sha_heroism_SpellScript::RemoveInvalidTargets, EFFECT_2, TARGET_UNIT_CASTER_AREA_RAID); AfterHit += SpellHitFn(spell_sha_heroism_SpellScript::ApplyDebuff); } }; @@ -430,7 +497,7 @@ class spell_sha_healing_stream_totem : public SpellScriptLoader if (Unit* owner = caster->GetOwner()) { if (triggeringSpell) - damage = int32(owner->SpellHealingBonus(target, triggeringSpell, damage, HEAL)); + damage = int32(owner->SpellHealingBonusDone(target, triggeringSpell, damage, HEAL)); // Restorative Totems if (AuraEffect* dummy = owner->GetAuraEffect(SPELL_AURA_DUMMY, SPELLFAMILY_SHAMAN, ICON_ID_RESTORATIVE_TOTEMS, 1)) @@ -439,6 +506,8 @@ class spell_sha_healing_stream_totem : public SpellScriptLoader // Glyph of Healing Stream Totem if (AuraEffect const* aurEff = owner->GetAuraEffect(SPELL_GLYPH_OF_HEALING_STREAM_TOTEM, EFFECT_0)) AddPctN(damage, aurEff->GetAmount()); + + damage = int32(target->SpellHealingBonusTaken(owner, triggeringSpell, damage, HEAL)); } caster->CastCustomSpell(target, SPELL_HEALING_STREAM_TOTEM_HEAL, &damage, 0, 0, true, 0, 0, GetOriginalCaster()->GetGUID()); } @@ -592,12 +661,101 @@ class spell_sha_chain_heal : public SpellScriptLoader } }; +class spell_sha_flame_shock : public SpellScriptLoader +{ + public: + spell_sha_flame_shock() : SpellScriptLoader("spell_sha_flame_shock") { } + + class spell_sha_flame_shock_AuraScript : public AuraScript + { + PrepareAuraScript(spell_sha_flame_shock_AuraScript); + + bool Validate(SpellInfo const* /*spell*/) + { + if (!sSpellMgr->GetSpellInfo(SHAMAN_LAVA_FLOWS_R1)) + return false; + if (!sSpellMgr->GetSpellInfo(SHAMAN_LAVA_FLOWS_TRIGGERED_R1)) + return false; + return true; + } + + void HandleDispel(DispelInfo* /*dispelInfo*/) + { + if (Unit* caster = GetCaster()) + // Lava Flows + if (AuraEffect const* aurEff = caster->GetDummyAuraEffect(SPELLFAMILY_SHAMAN, ICON_ID_SHAMAN_LAVA_FLOW, EFFECT_0)) + { + if (sSpellMgr->GetFirstSpellInChain(SHAMAN_LAVA_FLOWS_R1) != sSpellMgr->GetFirstSpellInChain(aurEff->GetId())) + return; + + uint8 rank = sSpellMgr->GetSpellRank(aurEff->GetId()); + caster->CastSpell(caster, sSpellMgr->GetSpellWithRank(SHAMAN_LAVA_FLOWS_TRIGGERED_R1, rank), true); + } + } + + void Register() + { + AfterDispel += AuraDispelFn(spell_sha_flame_shock_AuraScript::HandleDispel); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_sha_flame_shock_AuraScript(); + } +}; + +class spell_sha_sentry_totem : public SpellScriptLoader +{ + public: + spell_sha_sentry_totem() : SpellScriptLoader("spell_sha_sentry_totem") { } + + class spell_sha_sentry_totem_AuraScript : public AuraScript + { + PrepareAuraScript(spell_sha_sentry_totem_AuraScript); + + bool Validate(SpellInfo const* /*spell*/) + { + if (!sSpellMgr->GetSpellInfo(SHAMAN_BIND_SIGHT)) + return false; + return true; + } + + void AfterApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + if (Unit* caster = GetCaster()) + if (Creature* totem = caster->GetMap()->GetCreature(caster->m_SummonSlot[4])) + if (totem->isTotem()) + caster->CastSpell(totem, SHAMAN_BIND_SIGHT, true); + } + + void AfterRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + if (Unit* caster = GetCaster()) + if (caster->GetTypeId() == TYPEID_PLAYER) + caster->ToPlayer()->StopCastingBindSight(); + } + + void Register() + { + AfterEffectApply += AuraEffectApplyFn(spell_sha_sentry_totem_AuraScript::AfterApply, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); + AfterEffectRemove += AuraEffectRemoveFn(spell_sha_sentry_totem_AuraScript::AfterRemove, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_sha_sentry_totem_AuraScript(); + } +}; + void AddSC_shaman_spell_scripts() { new spell_sha_astral_shift(); new spell_sha_fire_nova(); new spell_sha_mana_tide_totem(); new spell_sha_earthbind_totem(); + new spell_sha_earthen_power(); new spell_sha_bloodlust(); new spell_sha_heroism(); new spell_sha_ancestral_awakening_proc(); @@ -606,4 +764,6 @@ void AddSC_shaman_spell_scripts() new spell_sha_mana_spring_totem(); new spell_sha_lava_lash(); new spell_sha_chain_heal(); + new spell_sha_flame_shock(); + new spell_sha_sentry_totem(); } diff --git a/src/server/scripts/Spells/spell_warlock.cpp b/src/server/scripts/Spells/spell_warlock.cpp index 29a52406279..e0131190916 100644 --- a/src/server/scripts/Spells/spell_warlock.cpp +++ b/src/server/scripts/Spells/spell_warlock.cpp @@ -37,6 +37,10 @@ enum WarlockSpells WARLOCK_DEMONIC_CIRCLE_SUMMON = 48018, WARLOCK_DEMONIC_CIRCLE_TELEPORT = 48020, WARLOCK_DEMONIC_CIRCLE_ALLOW_CAST = 62388, + WARLOCK_HAUNT = 48181, + WARLOCK_HAUNT_HEAL = 48210, + WARLOCK_UNSTABLE_AFFLICTION_DISPEL = 31117, + WARLOCK_CURSE_OF_DOOM_EFFECT = 18662, }; class spell_warl_banish : public SpellScriptLoader @@ -172,6 +176,19 @@ class spell_warl_create_healthstone : public SpellScriptLoader return true; } + SpellCastResult CheckCast() + { + if (Player* caster = GetCaster()->ToPlayer()) + { + uint8 spellRank = sSpellMgr->GetSpellRank(GetSpellInfo()->Id); + ItemPosCountVec dest; + InventoryResult msg = caster->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, iTypes[spellRank - 1][0], 1, NULL); + if (msg != EQUIP_ERR_OK) + return SPELL_FAILED_TOO_MANY_OF_ITEM; + } + return SPELL_CAST_OK; + } + void HandleScriptEffect(SpellEffIndex effIndex) { if (Unit* unitTarget = GetHitUnit()) @@ -185,7 +202,7 @@ class spell_warl_create_healthstone : public SpellScriptLoader case WARLOCK_IMPROVED_HEALTHSTONE_R1: rank = 1; break; case WARLOCK_IMPROVED_HEALTHSTONE_R2: rank = 2; break; default: - sLog->outError("Unknown rank of Improved Healthstone id: %d", aurEff->GetId()); + sLog->outError(LOG_FILTER_SPELLS_AURAS, "Unknown rank of Improved Healthstone id: %d", aurEff->GetId()); break; } } @@ -198,6 +215,7 @@ class spell_warl_create_healthstone : public SpellScriptLoader void Register() { OnEffectHitTarget += SpellEffectFn(spell_warl_create_healthstone_SpellScript::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + OnCheckCast += SpellCheckCastFn(spell_warl_create_healthstone_SpellScript::CheckCast); } }; @@ -285,15 +303,15 @@ class spell_warl_seed_of_corruption : public SpellScriptLoader { PrepareSpellScript(spell_warl_seed_of_corruption_SpellScript); - void FilterTargets(std::list<Unit*>& unitList) + void FilterTargets(std::list<WorldObject*>& targets) { - if (GetTargetUnit()) - unitList.remove(GetTargetUnit()); + if (GetExplTargetUnit()) + targets.remove(GetExplTargetUnit()); } void Register() { - OnUnitTargetSelect += SpellUnitTargetFn(spell_warl_seed_of_corruption_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_DEST_AREA_ENEMY); + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_warl_seed_of_corruption_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_DEST_AREA_ENEMY); } }; @@ -509,6 +527,150 @@ class spell_warl_demonic_circle_teleport : public SpellScriptLoader } }; +class spell_warl_haunt : public SpellScriptLoader +{ + public: + spell_warl_haunt() : SpellScriptLoader("spell_warl_haunt") { } + + class spell_warl_haunt_SpellScript : public SpellScript + { + PrepareSpellScript(spell_warl_haunt_SpellScript); + + void HandleOnHit() + { + if (Aura* aura = GetHitAura()) + if (AuraEffect* aurEff = aura->GetEffect(EFFECT_1)) + aurEff->SetAmount(CalculatePctN(aurEff->GetAmount(), GetHitDamage())); + } + + void Register() + { + OnHit += SpellHitFn(spell_warl_haunt_SpellScript::HandleOnHit); + } + }; + + class spell_warl_haunt_AuraScript : public AuraScript + { + PrepareAuraScript(spell_warl_haunt_AuraScript); + + bool Validate(SpellInfo const* /*spell*/) + { + if (!sSpellMgr->GetSpellInfo(WARLOCK_HAUNT_HEAL)) + return false; + return true; + } + + void HandleRemove(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/) + { + if (Unit* caster = GetCaster()) + { + int32 amount = aurEff->GetAmount(); + GetTarget()->CastCustomSpell(caster, WARLOCK_HAUNT_HEAL, &amount, NULL, NULL, true, NULL, aurEff, GetCasterGUID()); + } + } + + void Register() + { + OnEffectRemove += AuraEffectApplyFn(spell_warl_haunt_AuraScript::HandleRemove, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_warl_haunt_SpellScript(); + } + + AuraScript* GetAuraScript() const + { + return new spell_warl_haunt_AuraScript(); + } +}; + +class spell_warl_unstable_affliction : public SpellScriptLoader +{ + public: + spell_warl_unstable_affliction() : SpellScriptLoader("spell_warl_unstable_affliction") { } + + class spell_warl_unstable_affliction_AuraScript : public AuraScript + { + PrepareAuraScript(spell_warl_unstable_affliction_AuraScript); + + bool Validate(SpellInfo const* /*spell*/) + { + if (!sSpellMgr->GetSpellInfo(WARLOCK_UNSTABLE_AFFLICTION_DISPEL)) + return false; + return true; + } + + void HandleDispel(DispelInfo* dispelInfo) + { + if (Unit* caster = GetCaster()) + if (AuraEffect const* aurEff = GetEffect(EFFECT_0)) + { + int32 damage = aurEff->GetAmount() * 9; + // backfire damage and silence + caster->CastCustomSpell(dispelInfo->GetDispeller(), WARLOCK_UNSTABLE_AFFLICTION_DISPEL, &damage, NULL, NULL, true, NULL, aurEff); + } + } + + void Register() + { + AfterDispel += AuraDispelFn(spell_warl_unstable_affliction_AuraScript::HandleDispel); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_warl_unstable_affliction_AuraScript(); + } +}; + +class spell_warl_curse_of_doom : public SpellScriptLoader +{ + public: + spell_warl_curse_of_doom() : SpellScriptLoader("spell_warl_curse_of_doom") { } + + class spell_warl_curse_of_doom_AuraScript : public AuraScript + { + PrepareAuraScript(spell_warl_curse_of_doom_AuraScript); + + bool Validate(SpellInfo const* /*spell*/) + { + if (!sSpellMgr->GetSpellInfo(WARLOCK_CURSE_OF_DOOM_EFFECT)) + return false; + return true; + } + + bool Load() + { + return GetCaster() && GetCaster()->GetTypeId() == TYPEID_PLAYER; + } + + void OnRemove(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/) + { + if (!GetCaster()) + return; + + AuraRemoveMode removeMode = GetTargetApplication()->GetRemoveMode(); + if (removeMode != AURA_REMOVE_BY_DEATH || !IsExpired()) + return; + + if (GetCaster()->ToPlayer()->isHonorOrXPTarget(GetTarget())) + GetCaster()->CastSpell(GetTarget(), WARLOCK_CURSE_OF_DOOM_EFFECT, true, NULL, aurEff); + } + + void Register() + { + AfterEffectRemove += AuraEffectRemoveFn(spell_warl_curse_of_doom_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE, AURA_EFFECT_HANDLE_REAL); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_warl_curse_of_doom_AuraScript(); + } +}; + void AddSC_warlock_spell_scripts() { new spell_warl_banish(); @@ -521,4 +683,7 @@ void AddSC_warlock_spell_scripts() new spell_warl_life_tap(); new spell_warl_demonic_circle_summon(); new spell_warl_demonic_circle_teleport(); + new spell_warl_haunt(); + new spell_warl_unstable_affliction(); + new spell_warl_curse_of_doom(); } diff --git a/src/server/scripts/Spells/spell_warrior.cpp b/src/server/scripts/Spells/spell_warrior.cpp index 2ce3c72580e..c64101e11ea 100644 --- a/src/server/scripts/Spells/spell_warrior.cpp +++ b/src/server/scripts/Spells/spell_warrior.cpp @@ -77,7 +77,7 @@ class spell_warr_improved_spell_reflection : public SpellScriptLoader { PrepareSpellScript(spell_warr_improved_spell_reflection_SpellScript); - void FilterTargets(std::list<Unit*>& unitList) + void FilterTargets(std::list<WorldObject*>& unitList) { if (GetCaster()) unitList.remove(GetCaster()); @@ -85,7 +85,7 @@ class spell_warr_improved_spell_reflection : public SpellScriptLoader void Register() { - OnUnitTargetSelect += SpellUnitTargetFn(spell_warr_improved_spell_reflection_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_CASTER_AREA_PARTY); + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_warr_improved_spell_reflection_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_CASTER_AREA_PARTY); } }; @@ -177,24 +177,27 @@ class spell_warr_deep_wounds : public SpellScriptLoader void HandleDummy(SpellEffIndex /* effIndex */) { int32 damage = GetEffectValue(); + Unit* caster = GetCaster(); if (Unit* target = GetHitUnit()) - if (Unit* caster = GetCaster()) - { - // apply percent damage mods - damage = caster->SpellDamageBonus(target, GetSpellInfo(), damage, SPELL_DIRECT_DAMAGE); + { + // apply percent damage mods + damage = caster->SpellDamageBonusDone(target, GetSpellInfo(), damage, SPELL_DIRECT_DAMAGE); - ApplyPctN(damage, 16 * sSpellMgr->GetSpellRank(GetSpellInfo()->Id)); + ApplyPctN(damage, 16 * sSpellMgr->GetSpellRank(GetSpellInfo()->Id)); - SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(SPELL_DEEP_WOUNDS_RANK_PERIODIC); - uint32 ticks = spellInfo->GetDuration() / spellInfo->Effects[EFFECT_0].Amplitude; + damage = target->SpellDamageBonusTaken(caster, GetSpellInfo(), damage, SPELL_DIRECT_DAMAGE); - // Add remaining ticks to damage done - if (AuraEffect const* aurEff = target->GetAuraEffect(SPELL_DEEP_WOUNDS_RANK_PERIODIC, EFFECT_0, caster->GetGUID())) - damage += aurEff->GetAmount() * (ticks - aurEff->GetTickNumber()); + SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(SPELL_DEEP_WOUNDS_RANK_PERIODIC); + uint32 ticks = spellInfo->GetDuration() / spellInfo->Effects[EFFECT_0].Amplitude; - damage = damage / ticks; - caster->CastCustomSpell(target, SPELL_DEEP_WOUNDS_RANK_PERIODIC, &damage, NULL, NULL, true); - } + // Add remaining ticks to damage done + if (AuraEffect const* aurEff = target->GetAuraEffect(SPELL_DEEP_WOUNDS_RANK_PERIODIC, EFFECT_0, caster->GetGUID())) + damage += aurEff->GetAmount() * (ticks - aurEff->GetTickNumber()); + + damage = damage / ticks; + + caster->CastCustomSpell(target, SPELL_DEEP_WOUNDS_RANK_PERIODIC, &damage, NULL, NULL, true); + } } void Register() @@ -365,7 +368,7 @@ class spell_warr_concussion_blow : public SpellScriptLoader void HandleDummy(SpellEffIndex /* effIndex */) { - SetHitDamage(GetHitDamage() + CalculatePctF(GetHitDamage(),GetCaster()->GetTotalAttackPowerValue(BASE_ATTACK))); + SetHitDamage(CalculatePctN(GetCaster()->GetTotalAttackPowerValue(BASE_ATTACK), GetEffectValue())); } void Register() @@ -394,16 +397,29 @@ class spell_warr_bloodthirst : public SpellScriptLoader { PrepareSpellScript(spell_warr_bloodthirst_SpellScript); - void HandleDummy(SpellEffIndex /* effIndex */) + void HandleDamage(SpellEffIndex /*effIndex*/) { int32 damage = GetEffectValue(); - if (GetHitUnit()) - GetCaster()->CastCustomSpell(GetHitUnit(), SPELL_BLOODTHIRST, &damage, NULL, NULL, true, NULL); + ApplyPctF(damage, GetCaster()->GetTotalAttackPowerValue(BASE_ATTACK)); + + if (Unit* target = GetHitUnit()) + { + damage = GetCaster()->SpellDamageBonusDone(target, GetSpellInfo(), uint32(damage), SPELL_DIRECT_DAMAGE); + damage = target->SpellDamageBonusTaken(GetCaster(), GetSpellInfo(), uint32(damage), SPELL_DIRECT_DAMAGE); + } + SetHitDamage(damage); + } + + void HandleDummy(SpellEffIndex /*effIndex*/) + { + int32 damage = GetEffectValue(); + GetCaster()->CastCustomSpell(GetCaster(), SPELL_BLOODTHIRST, &damage, NULL, NULL, true, NULL); } void Register() { - OnEffectHitTarget += SpellEffectFn(spell_warr_bloodthirst_SpellScript::HandleDummy, EFFECT_1, SPELL_EFFECT_DUMMY); + OnEffectHitTarget += SpellEffectFn(spell_warr_bloodthirst_SpellScript::HandleDamage, EFFECT_0, SPELL_EFFECT_SCHOOL_DAMAGE); + OnEffectHit += SpellEffectFn(spell_warr_bloodthirst_SpellScript::HandleDummy, EFFECT_1, SPELL_EFFECT_DUMMY); } }; @@ -413,6 +429,38 @@ class spell_warr_bloodthirst : public SpellScriptLoader } }; +enum BloodthirstHeal +{ + SPELL_BLOODTHIRST_DAMAGE = 23881, +}; + +class spell_warr_bloodthirst_heal : public SpellScriptLoader +{ + public: + spell_warr_bloodthirst_heal() : SpellScriptLoader("spell_warr_bloodthirst_heal") { } + + class spell_warr_bloodthirst_heal_SpellScript : public SpellScript + { + PrepareSpellScript(spell_warr_bloodthirst_heal_SpellScript); + + void HandleHeal(SpellEffIndex /*effIndex*/) + { + if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(SPELL_BLOODTHIRST_DAMAGE)) + SetHitHeal(GetCaster()->CountPctFromMaxHealth(spellInfo->Effects[EFFECT_1].CalcValue(GetCaster()))); + } + + void Register() + { + OnEffectHitTarget += SpellEffectFn(spell_warr_bloodthirst_heal_SpellScript::HandleHeal, EFFECT_0, SPELL_EFFECT_HEAL); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_warr_bloodthirst_heal_SpellScript(); + } +}; + enum Overpower { SPELL_UNRELENTING_ASSAULT_RANK_1 = 46859, @@ -441,9 +489,9 @@ public: if (!spellId) return; - Unit* target = GetHitUnit(); - if (target->HasUnitState(UNIT_STATE_CASTING)) - target->CastSpell(target, spellId, true); + if (Player* target = GetHitPlayer()) + if (target->HasUnitState(UNIT_STATE_CASTING)) + target->CastSpell(target, spellId, true); } void Register() @@ -469,5 +517,6 @@ void AddSC_warrior_spell_scripts() new spell_warr_execute(); new spell_warr_concussion_blow(); new spell_warr_bloodthirst(); + new spell_warr_bloodthirst_heal(); new spell_warr_overpower(); } |
