From 695b5387e1cc7bcc1b7fdc4ba808873f8c48d2d2 Mon Sep 17 00:00:00 2001 From: Elmsroth Date: Sun, 18 Oct 2020 20:01:27 +0200 Subject: [PATCH] Fix : Warlock Soul Drain will not give a second Soul Shard if victim is under "Shadowburn" (#110) * Fix : Warlock Soul Drain will not give a second Soul Shard if victim is under "Shadowburn" * Implement SPELL_EFFECT_TELEPORT_GRAVEYARD Ported from CMangos https://github.com/cmangos/mangos-classic/commit/b05bb50b9e0baa38be53414ecc81e53cd9be8525 * Fixes players not receiving Soul Shards when multiple players are using Drain Soul and/or Shadowburn See https://github.com/cmangos/mangos-classic/commit/d46bf1b4ca03e7cb22f4ead55bbc09f56937ddb7 --- src/game/WorldHandlers/Spell.h | 1 + src/game/WorldHandlers/SpellAuras.cpp | 25 +++++++++++++++++++++---- src/game/WorldHandlers/SpellEffects.cpp | 11 ++++++++++- 3 files changed, 32 insertions(+), 5 deletions(-) diff --git a/src/game/WorldHandlers/Spell.h b/src/game/WorldHandlers/Spell.h index 0192e17a..2c843f98 100644 --- a/src/game/WorldHandlers/Spell.h +++ b/src/game/WorldHandlers/Spell.h @@ -236,6 +236,7 @@ class Spell void EffectPowerDrain(SpellEffectIndex eff_idx); void EffectHeal(SpellEffectIndex eff_idx); void EffectBind(SpellEffectIndex eff_idx); + void EffectTeleportGraveyard(SpellEffectIndex eff_idx); void EffectHealthLeech(SpellEffectIndex eff_idx); void EffectQuestComplete(SpellEffectIndex eff_idx); void EffectCreateItem(SpellEffectIndex eff_idx); diff --git a/src/game/WorldHandlers/SpellAuras.cpp b/src/game/WorldHandlers/SpellAuras.cpp index 64cb42bc..4f8ef8cc 100644 --- a/src/game/WorldHandlers/SpellAuras.cpp +++ b/src/game/WorldHandlers/SpellAuras.cpp @@ -255,6 +255,10 @@ pAuraHandler AuraHandler[TOTAL_AURAS] = static AuraType const frozenAuraTypes[] = { SPELL_AURA_MOD_ROOT, SPELL_AURA_MOD_STUN, SPELL_AURA_NONE }; +enum SpellCreatedItems { + ITEM_SOUL_SHARD = 6265 +}; + Aura::Aura(SpellEntry const* spellproto, SpellEffectIndex eff, int32* currentBasePoints, SpellAuraHolder* holder, Unit* target, Unit* caster, Item* castItem) : m_spellmod(NULL), m_periodicTimer(0), m_periodicTick(0), m_removeMode(AURA_REMOVE_BY_DEFAULT), m_effIndex(eff), m_positive(false), m_isPeriodic(false), m_isAreaAura(false), @@ -2192,8 +2196,10 @@ void Aura::HandleChannelDeathItem(bool apply, bool Real) return; } + uint32 createdItemId = spellInfo->EffectItemType[m_effIndex]; + // Soul Shard (target req.) - if (spellInfo->EffectItemType[m_effIndex] == 6265) + if (createdItemId == ITEM_SOUL_SHARD) { // Only from non-grey units if (!((Player*)caster)->isHonorOrXPTarget(victim) || @@ -2201,6 +2207,17 @@ void Aura::HandleChannelDeathItem(bool apply, bool Real) { return; } + + // Avoid awarding multiple souls on the same target + // 1.11.0: If you cast Drain Soul while shadowburn is on the victim, you will no longer receive two soul shards upon the victim's death. + for (auto const& aura : victim->GetAurasByType(SPELL_AURA_CHANNEL_DEATH_ITEM)) + { + if (aura != this && caster->GetObjectGuid() == aura->GetCasterGuid() && aura->GetSpellProto()->EffectItemType[aura->GetEffIndex()] == ITEM_SOUL_SHARD) + { + return; + } + } + } // Adding items @@ -2208,18 +2225,18 @@ void Aura::HandleChannelDeathItem(bool apply, bool Real) uint32 count = m_modifier.m_amount; ItemPosCountVec dest; - InventoryResult msg = ((Player*)caster)->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, spellInfo->EffectItemType[m_effIndex], count, &noSpaceForCount); + InventoryResult msg = ((Player*)caster)->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, createdItemId, count, &noSpaceForCount); if (msg != EQUIP_ERR_OK) { count -= noSpaceForCount; - ((Player*)caster)->SendEquipError(msg, NULL, NULL, spellInfo->EffectItemType[m_effIndex]); + ((Player*)caster)->SendEquipError(msg, NULL, NULL, createdItemId); if (count == 0) { return; } } - Item* newitem = ((Player*)caster)->StoreNewItem(dest, spellInfo->EffectItemType[m_effIndex], true); + Item* newitem = ((Player*)caster)->StoreNewItem(dest, createdItemId, true); ((Player*)caster)->SendNewItem(newitem, count, true, true); } } diff --git a/src/game/WorldHandlers/SpellEffects.cpp b/src/game/WorldHandlers/SpellEffects.cpp index 20732f81..ed7b7124 100644 --- a/src/game/WorldHandlers/SpellEffects.cpp +++ b/src/game/WorldHandlers/SpellEffects.cpp @@ -178,7 +178,7 @@ pEffect SpellEffects[TOTAL_SPELL_EFFECTS] = &Spell::EffectSpiritHeal, // 117 SPELL_EFFECT_SPIRIT_HEAL one spell: Spirit Heal &Spell::EffectSkill, // 118 SPELL_EFFECT_SKILL professions and more &Spell::EffectApplyAreaAura, // 119 SPELL_EFFECT_APPLY_AREA_AURA_PET - &Spell::EffectUnused, // 120 SPELL_EFFECT_TELEPORT_GRAVEYARD one spell: Graveyard Teleport Test + &Spell::EffectTeleportGraveyard, // 120 SPELL_EFFECT_TELEPORT_GRAVEYARD one spell: Graveyard Teleport Test &Spell::EffectWeaponDmg, // 121 SPELL_EFFECT_NORMALIZED_WEAPON_DMG &Spell::EffectUnused, // 122 SPELL_EFFECT_122 unused &Spell::EffectSendTaxi, // 123 SPELL_EFFECT_SEND_TAXI taxi/flight related (misc value is taxi path id) @@ -6163,3 +6163,12 @@ void Spell::EffectBind(SpellEffectIndex eff_idx) data << uint32(area_id); player->SendDirectMessage(&data); } + +void Spell::EffectTeleportGraveyard(SpellEffectIndex eff_idx) +{ + if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER || !unitTarget->GetMap()->IsBattleGround()) + return; + + Player* player = static_cast(unitTarget); + player->RepopAtGraveyard(); +}