diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 15d66bf90ca..7d1196d9281 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -11938,9 +11938,16 @@ uint32 Unit::GetPowerIndex(uint32 powerType) const /// With the current implementation, the core only gives them /// POWER_RAGE, so we enforce the class to hunter so that they /// effectively get focus power. + /// Also, Death Knight ghouls are of Mage class. + /// this is necessary so they get energy uint32 classId = getClass(); - if (ToPet() && ToPet()->getPetType() == HUNTER_PET) - classId = CLASS_HUNTER; + if (Pet const* pet = ToPet()) + { + if (pet->getPetType() == HUNTER_PET) + classId = CLASS_HUNTER; + else if (pet->IsPetGhoul()) + classId = CLASS_ROGUE; + } return GetPowerIndexByClass(powerType, classId); } diff --git a/src/server/scripts/Spells/spell_dk.cpp b/src/server/scripts/Spells/spell_dk.cpp index ba9efa1d819..4192fad2297 100644 --- a/src/server/scripts/Spells/spell_dk.cpp +++ b/src/server/scripts/Spells/spell_dk.cpp @@ -60,7 +60,6 @@ enum DeathKnightSpells SPELL_DK_ITEM_SIGIL_VENGEFUL_HEART = 64962, SPELL_DK_ITEM_T8_MELEE_4P_BONUS = 64736, SPELL_DK_MASTER_OF_GHOULS = 52143, - SPELL_DK_RAISE_DEAD_USE_REAGENT = 48289, SPELL_DK_RUNIC_POWER_ENERGIZE = 49088, SPELL_DK_RUNE_TAP = 48982, SPELL_DK_SCENT_OF_BLOOD = 50422, @@ -1218,30 +1217,6 @@ class spell_dk_presence : public SpellScriptLoader } }; -class RaiseDeadCheck -{ -public: - explicit RaiseDeadCheck(Player const* caster) : _caster(caster) { } - - bool operator()(WorldObject* obj) const - { - if (Unit* target = obj->ToUnit()) - { - if (!target->IsAlive() - && _caster->isHonorOrXPTarget(target) - && target->GetCreatureType() == CREATURE_TYPE_HUMANOID - && target->GetDisplayId() == target->GetNativeDisplayId()) - return false; - } - - return true; - } - -private: - Player const* _caster; -}; - - // 46584 - Raise Dead class spell_dk_raise_dead : public SpellScriptLoader { @@ -1252,19 +1227,10 @@ class spell_dk_raise_dead : public SpellScriptLoader { PrepareSpellScript(spell_dk_raise_dead_SpellScript); - public: - spell_dk_raise_dead_SpellScript() - { - _result = SPELL_CAST_OK; - _corpse = false; - } - - private: bool Validate(SpellInfo const* spellInfo) override { - if (!sSpellMgr->GetSpellInfo(spellInfo->Effects[EFFECT_1].CalcValue()) - || !sSpellMgr->GetSpellInfo(spellInfo->Effects[EFFECT_2].CalcValue()) - || !sSpellMgr->GetSpellInfo(SPELL_DK_RAISE_DEAD_USE_REAGENT) + if (!sSpellMgr->GetSpellInfo(spellInfo->Effects[EFFECT_0].CalcValue()) + || !sSpellMgr->GetSpellInfo(spellInfo->Effects[EFFECT_1].CalcValue()) || !sSpellMgr->GetSpellInfo(SPELL_DK_MASTER_OF_GHOULS)) return false; return true; @@ -1275,114 +1241,27 @@ class spell_dk_raise_dead : public SpellScriptLoader return GetCaster()->GetTypeId() == TYPEID_PLAYER; } - SpellCastResult CheckCast() - { - /// process spell target selection before cast starts - /// targets of effect_1 are used to check cast - GetSpell()->SelectSpellTargets(); - /// cleanup spell target map, and fill it again on normal way - GetSpell()->CleanupTargetList(); - /// _result is set in spell target selection - return _result; - } - - SpellCastResult CheckReagents() - { - /// @workaround: there is no access to castresult of other spells, check it manually - SpellInfo const* reagentSpell = sSpellMgr->GetSpellInfo(SPELL_DK_RAISE_DEAD_USE_REAGENT); - Player* player = GetCaster()->ToPlayer(); - if (!player->CanNoReagentCast(reagentSpell)) - { - for (uint32 i = 0; i < MAX_SPELL_REAGENTS; i++) - { - if (reagentSpell->Reagent[i] <= 0) - continue; - - if (!player->HasItemCount(reagentSpell->Reagent[i], reagentSpell->ReagentCount[i])) - { - Spell::SendCastResult(player, reagentSpell, 0, SPELL_FAILED_REAGENTS); - return SPELL_FAILED_DONT_REPORT; - } - } - } - return SPELL_CAST_OK; - } - - void CheckTargets(std::list& targets) - { - targets.remove_if(RaiseDeadCheck(GetCaster()->ToPlayer())); - - if (targets.empty()) - { - if (GetSpell()->getState() == SPELL_STATE_PREPARING) - _result = CheckReagents(); - - return; - } - - WorldObject* target = Trinity::Containers::SelectRandomContainerElement(targets); - targets.clear(); - targets.push_back(target); - _corpse = true; - } - - void CheckTarget(WorldObject*& target) - { - // Don't add caster to target map, if we found a corpse to raise dead - if (_corpse) - target = NULL; - } - - void ConsumeReagents() - { - // No corpse found, take reagents - if (!_corpse) - GetCaster()->CastSpell(GetCaster(), SPELL_DK_RAISE_DEAD_USE_REAGENT, TriggerCastFlags(TRIGGERED_FULL_MASK & ~TRIGGERED_IGNORE_POWER_AND_REAGENT_COST)); - } - uint32 GetGhoulSpellId() { // Do we have talent Master of Ghouls? if (GetCaster()->HasAura(SPELL_DK_MASTER_OF_GHOULS)) // summon as pet - return GetSpellInfo()->Effects[EFFECT_2].CalcValue(); + return GetSpellInfo()->Effects[EFFECT_1].CalcValue(); // or guardian - return GetSpellInfo()->Effects[EFFECT_1].CalcValue(); + return GetSpellInfo()->Effects[EFFECT_0].CalcValue(); } - void HandleRaiseDead(SpellEffIndex /*effIndex*/) + void HandleRaiseDead() { SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(GetGhoulSpellId()); - SpellCastTargets targets; - targets.SetDst(*GetHitUnit()); - - GetCaster()->CastSpell(targets, spellInfo, NULL, TRIGGERED_FULL_MASK); - } - - void OverrideCooldown() - { - // Because the ghoul is summoned by one of triggered spells SendCooldownEvent is not sent for this spell - // but the client has locked it by itself so we need some link between this spell and the real spell summoning. - // Luckily such link already exists - spell category - // This starts infinite category cooldown which can later be used by SendCooldownEvent to send packet for this spell - GetCaster()->GetSpellHistory()->StartCooldown(GetSpellInfo(), 0, nullptr, true); + GetCaster()->CastSpell((Unit*)nullptr, spellInfo, TRIGGERED_FULL_MASK); } void Register() override { - OnCheckCast += SpellCheckCastFn(spell_dk_raise_dead_SpellScript::CheckCast); - OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_dk_raise_dead_SpellScript::CheckTargets, EFFECT_1, TARGET_UNIT_DEST_AREA_ENTRY); - OnObjectTargetSelect += SpellObjectTargetSelectFn(spell_dk_raise_dead_SpellScript::CheckTarget, EFFECT_2, TARGET_UNIT_CASTER); - OnCast += SpellCastFn(spell_dk_raise_dead_SpellScript::ConsumeReagents); - OnEffectHitTarget += SpellEffectFn(spell_dk_raise_dead_SpellScript::HandleRaiseDead, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT); - OnEffectHitTarget += SpellEffectFn(spell_dk_raise_dead_SpellScript::HandleRaiseDead, EFFECT_2, SPELL_EFFECT_DUMMY); - AfterCast += SpellCastFn(spell_dk_raise_dead_SpellScript::OverrideCooldown); + OnCast += SpellCastFn(spell_dk_raise_dead_SpellScript::HandleRaiseDead); } - - private: - SpellCastResult _result; - bool _corpse; }; SpellScript* GetSpellScript() const override