diff --git a/src/server/game/Miscellaneous/SharedDefines.h b/src/server/game/Miscellaneous/SharedDefines.h index 469bba9d508..12a135bb739 100644 --- a/src/server/game/Miscellaneous/SharedDefines.h +++ b/src/server/game/Miscellaneous/SharedDefines.h @@ -1738,7 +1738,7 @@ enum Targets TARGET_UNK_116 = 116, TARGET_UNK_117 = 117, TARGET_UNK_118 = 118, - TARGET_UNK_119 = 119, + TARGET_CORPSE_SRC_AREA_RAID = 119, TARGET_UNK_120 = 120, TARGET_UNK_121 = 121, TARGET_UNK_122 = 122, diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index f19825f325e..a1973d9b5b1 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -1872,6 +1872,12 @@ uint32 Spell::GetSearcherTypeMask(SpellTargetObjectTypes objType, ConditionConta { case TARGET_OBJECT_TYPE_UNIT: case TARGET_OBJECT_TYPE_UNIT_AND_DEST: + if (!m_spellInfo->HasAttribute(SPELL_ATTR2_CAN_TARGET_DEAD)) + { + retMask &= GRID_MAP_TYPE_MASK_PLAYER | GRID_MAP_TYPE_MASK_CREATURE; + break; + } + // No break here case TARGET_OBJECT_TYPE_CORPSE: case TARGET_OBJECT_TYPE_CORPSE_ENEMY: case TARGET_OBJECT_TYPE_CORPSE_ALLY: @@ -1884,8 +1890,7 @@ uint32 Spell::GetSearcherTypeMask(SpellTargetObjectTypes objType, ConditionConta default: break; } - if (!m_spellInfo->HasAttribute(SPELL_ATTR2_CAN_TARGET_DEAD)) - retMask &= ~GRID_MAP_TYPE_MASK_CORPSE; + if (m_spellInfo->HasAttribute(SPELL_ATTR3_ONLY_TARGET_PLAYERS)) retMask &= GRID_MAP_TYPE_MASK_CORPSE | GRID_MAP_TYPE_MASK_PLAYER; if (m_spellInfo->HasAttribute(SPELL_ATTR3_ONLY_TARGET_GHOSTS)) @@ -8213,19 +8218,19 @@ bool WorldObjectSpellTargetCheck::operator()(WorldObject* target) case TARGET_CHECK_ENEMY: if (unitTarget->IsTotem()) return false; - if (!_caster->_IsValidAttackTarget(unitTarget, _spellInfo)) + if (!target->IsCorpse() && !_caster->_IsValidAttackTarget(unitTarget, _spellInfo)) return false; break; case TARGET_CHECK_ALLY: if (unitTarget->IsTotem()) return false; - if (!_caster->_IsValidAssistTarget(unitTarget, _spellInfo)) + if (!target->IsCorpse() && !_caster->_IsValidAssistTarget(unitTarget, _spellInfo)) return false; break; case TARGET_CHECK_PARTY: if (unitTarget->IsTotem()) return false; - if (!_caster->_IsValidAssistTarget(unitTarget, _spellInfo)) + if (!target->IsCorpse() && !_caster->_IsValidAssistTarget(unitTarget, _spellInfo)) return false; if (!_referer->IsInPartyWith(unitTarget)) return false; @@ -8237,7 +8242,7 @@ bool WorldObjectSpellTargetCheck::operator()(WorldObject* target) case TARGET_CHECK_RAID: if (unitTarget->IsTotem()) return false; - if (!_caster->_IsValidAssistTarget(unitTarget, _spellInfo)) + if (!target->IsCorpse() && !_caster->_IsValidAssistTarget(unitTarget, _spellInfo)) return false; if (!_referer->IsInRaidWith(unitTarget)) return false; diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index 3125f128716..fc96a71253f 100644 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -267,25 +267,27 @@ void Spell::EffectResurrectNew(SpellEffIndex effIndex) if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) return; - if (!unitTarget || unitTarget->IsAlive()) + if (!corpseTarget && !unitTarget) return; - if (unitTarget->GetTypeId() != TYPEID_PLAYER) + Player* player = nullptr; + + if (corpseTarget) + player = ObjectAccessor::FindPlayer(corpseTarget->GetOwnerGUID()); + else if (unitTarget) + player = unitTarget->ToPlayer(); + + if (!player || player->IsAlive() || !player->IsInWorld()) return; - if (!unitTarget->IsInWorld()) - return; - - Player* target = unitTarget->ToPlayer(); - - if (target->IsResurrectRequested()) // already have one active request + if (player->IsResurrectRequested()) // already have one active request return; uint32 health = damage; uint32 mana = m_spellInfo->Effects[effIndex].MiscValue; - ExecuteLogEffectResurrect(effIndex, target); - target->SetResurrectRequestData(m_caster, health, mana, 0); - SendResurrectRequest(target); + ExecuteLogEffectResurrect(effIndex, player); + player->SetResurrectRequestData(m_caster, health, mana, 0); + SendResurrectRequest(player); } void Spell::EffectInstaKill(SpellEffIndex /*effIndex*/) @@ -5627,31 +5629,34 @@ void Spell::EffectResurrectWithAura(SpellEffIndex effIndex) if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) return; - if (!unitTarget || !unitTarget->IsInWorld()) + if (!corpseTarget && !unitTarget) return; - Player* target = unitTarget->ToPlayer(); - if (!target) + Player* player = nullptr; + + if (corpseTarget) + player = ObjectAccessor::FindPlayer(corpseTarget->GetOwnerGUID()); + else if (unitTarget) + player = unitTarget->ToPlayer(); + + if (!player || player->IsAlive() || !player->IsInWorld()) return; - if (unitTarget->IsAlive()) + if (player->IsResurrectRequested()) // already have one active request return; - if (target->IsResurrectRequested()) // already have one active request - return; - - uint32 health = target->CountPctFromMaxHealth(damage); - uint32 mana = CalculatePct(target->GetMaxPower(POWER_MANA), damage); + uint32 health = player->CountPctFromMaxHealth(damage); + uint32 mana = CalculatePct(player->GetMaxPower(POWER_MANA), damage); uint32 resurrectAura = 0; if (sSpellMgr->GetSpellInfo(GetSpellInfo()->Effects[effIndex].TriggerSpell)) resurrectAura = GetSpellInfo()->Effects[effIndex].TriggerSpell; - if (resurrectAura && target->HasAura(resurrectAura)) + if (resurrectAura && player->HasAura(resurrectAura)) return; - ExecuteLogEffectResurrect(effIndex, target); - target->SetResurrectRequestData(m_caster, health, mana, resurrectAura); - SendResurrectRequest(target); + ExecuteLogEffectResurrect(effIndex, player); + player->SetResurrectRequestData(m_caster, health, mana, resurrectAura); + SendResurrectRequest(player); } void Spell::EffectCreateAreaTrigger(SpellEffIndex effIndex) diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp index 70c78b7435a..b8d7a2d50d9 100644 --- a/src/server/game/Spells/SpellInfo.cpp +++ b/src/server/game/Spells/SpellInfo.cpp @@ -309,7 +309,7 @@ SpellImplicitTargetInfo::StaticData SpellImplicitTargetInfo::_data[TOTAL_SPELL_ {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_TARGET, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_CHECK_DEFAULT, TARGET_DIR_NONE}, // 90 TARGET_UNIT_TARGET_MINIPET {TARGET_OBJECT_TYPE_DEST, TARGET_REFERENCE_TYPE_DEST, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_CHECK_DEFAULT, TARGET_DIR_RANDOM}, // 91 TARGET_DEST_DEST_RADIUS {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_CHECK_DEFAULT, TARGET_DIR_NONE}, // 92 TARGET_UNIT_SUMMONER - {TARGET_OBJECT_TYPE_CORPSE, TARGET_REFERENCE_TYPE_SRC, TARGET_SELECT_CATEGORY_AREA, TARGET_CHECK_ENEMY, TARGET_DIR_NONE}, // 93 TARGET_CORPSE_SRC_AREA_ENEMY + {TARGET_OBJECT_TYPE_CORPSE, TARGET_REFERENCE_TYPE_SRC, TARGET_SELECT_CATEGORY_AREA, TARGET_CHECK_ENEMY, TARGET_DIR_NONE}, // 93 TARGET_CORPSE_SRC_AREA_ENEMY {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_CHECK_DEFAULT, TARGET_DIR_NONE}, // 94 TARGET_UNIT_VEHICLE {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_TARGET, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_CHECK_PASSENGER, TARGET_DIR_NONE}, // 95 TARGET_UNIT_TARGET_PASSENGER {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_CHECK_DEFAULT, TARGET_DIR_NONE}, // 96 TARGET_UNIT_PASSENGER_0 @@ -335,7 +335,7 @@ SpellImplicitTargetInfo::StaticData SpellImplicitTargetInfo::_data[TOTAL_SPELL_ {TARGET_OBJECT_TYPE_NONE, TARGET_REFERENCE_TYPE_NONE, TARGET_SELECT_CATEGORY_NYI, TARGET_CHECK_DEFAULT, TARGET_DIR_NONE}, // 116 {TARGET_OBJECT_TYPE_NONE, TARGET_REFERENCE_TYPE_NONE, TARGET_SELECT_CATEGORY_NYI, TARGET_CHECK_DEFAULT, TARGET_DIR_NONE}, // 117 {TARGET_OBJECT_TYPE_NONE, TARGET_REFERENCE_TYPE_NONE, TARGET_SELECT_CATEGORY_NYI, TARGET_CHECK_DEFAULT, TARGET_DIR_NONE}, // 118 - {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_AREA, TARGET_CHECK_RAID, TARGET_DIR_NONE}, // 119 + {TARGET_OBJECT_TYPE_CORPSE, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_AREA, TARGET_CHECK_RAID, TARGET_DIR_NONE}, // 119 TARGET_CORPSE_SRC_AREA_RAID {TARGET_OBJECT_TYPE_NONE, TARGET_REFERENCE_TYPE_NONE, TARGET_SELECT_CATEGORY_NYI, TARGET_CHECK_DEFAULT, TARGET_DIR_NONE}, // 120 {TARGET_OBJECT_TYPE_NONE, TARGET_REFERENCE_TYPE_NONE, TARGET_SELECT_CATEGORY_NYI, TARGET_CHECK_DEFAULT, TARGET_DIR_NONE}, // 121 {TARGET_OBJECT_TYPE_NONE, TARGET_REFERENCE_TYPE_NONE, TARGET_SELECT_CATEGORY_NYI, TARGET_CHECK_DEFAULT, TARGET_DIR_NONE}, // 122 @@ -839,7 +839,7 @@ SpellEffectInfo::StaticData SpellEffectInfo::_data[TOTAL_SPELL_EFFECTS] = {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_ITEM}, // 169 SPELL_EFFECT_DESTROY_ITEM {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 170 SPELL_EFFECT_170 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_DEST}, // 171 SPELL_EFFECT_171 - {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 172 SPELL_EFFECT_172 + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_CORPSE_ALLY}, // 172 SPELL_EFFECT_RESURRECT_WITH_AURA {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 173 SPELL_EFFECT_UNLOCK_GUILD_VAULT_TAB {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 174 SPELL_EFFECT_APPLY_AURA_2 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 175 SPELL_EFFECT_175 @@ -1352,7 +1352,14 @@ bool SpellInfo::IsRequiringDeadTarget() const bool SpellInfo::IsAllowingDeadTarget() const { - return HasAttribute(SPELL_ATTR2_CAN_TARGET_DEAD) || Targets & (TARGET_FLAG_CORPSE_ALLY | TARGET_FLAG_CORPSE_ENEMY | TARGET_FLAG_UNIT_DEAD); + if (HasAttribute(SPELL_ATTR2_CAN_TARGET_DEAD) || Targets & (TARGET_FLAG_CORPSE_ALLY | TARGET_FLAG_CORPSE_ENEMY | TARGET_FLAG_UNIT_DEAD)) + return true; + + for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) + if (Effects[i].TargetA.GetTarget() == TARGET_CORPSE_SRC_AREA_RAID) + return true; + + return false; } bool SpellInfo::IsGroupBuff() const