aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGiacomo Pozzoni <giacomopoz@gmail.com>2020-06-29 21:03:03 +0000
committerGitHub <noreply@github.com>2020-06-29 23:03:03 +0200
commitcc71da35b5dc74abf71f8691161525a23d870bb5 (patch)
tree8fdf213ae1f8247af541624ee3253f08444a70f4 /src
parent65a204c5b24746237177e5ce8abbaca5a1bbdcf0 (diff)
Core/Spells: implement corpse target type support and properly fix resurrections (#24921)
* Core/Spells: implement corpse target type support and properly fix resurrections (cherry picked from commit df193945d9aff8596985a20e2c654105354b0af7) # Conflicts: # src/server/game/Spells/Spell.cpp # src/server/game/Spells/Spell.h * Core/Spells: implement TARGET_CORPSE_SRC_AREA_RAID and updated remaining resurrection effect handlers for updated corpse targeting (cherry picked from commit 98b075cb4b0da126d409ab42daa63a1f531a70ea) # Conflicts: # src/server/game/Miscellaneous/SharedDefines.h # src/server/game/Spells/Spell.cpp # src/server/game/Spells/SpellEffects.cpp # src/server/game/Spells/SpellInfo.cpp * Fix no-pch Co-authored-by: Ovahlord <dreadkiller@gmx.de>
Diffstat (limited to 'src')
-rw-r--r--src/server/game/Entities/Object/Object.h6
-rw-r--r--src/server/game/Spells/Spell.cpp142
-rw-r--r--src/server/game/Spells/Spell.h13
-rw-r--r--src/server/game/Spells/SpellEffects.cpp60
4 files changed, 172 insertions, 49 deletions
diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h
index c648b1d2914..16bf0455951 100644
--- a/src/server/game/Entities/Object/Object.h
+++ b/src/server/game/Entities/Object/Object.h
@@ -157,31 +157,37 @@ class TC_GAME_API Object
// FG: some hacky helpers
void ForceValuesUpdateAtIndex(uint32);
+ inline bool IsPlayer() const { return GetTypeId() == TYPEID_PLAYER; }
static Player* ToPlayer(Object* o) { if (o && o->GetTypeId() == TYPEID_PLAYER) return reinterpret_cast<Player*>(o); else return nullptr; }
static Player const* ToPlayer(Object const* o) { if (o && o->GetTypeId() == TYPEID_PLAYER) return reinterpret_cast<Player const*>(o); else return nullptr; }
Player* ToPlayer() { return ToPlayer(this); }
Player const* ToPlayer() const { return ToPlayer(this); }
+ inline bool IsCreature() const { return GetTypeId() == TYPEID_UNIT; }
static Creature* ToCreature(Object* o) { if (o && o->GetTypeId() == TYPEID_UNIT) return reinterpret_cast<Creature*>(o); else return nullptr; }
static Creature const* ToCreature(Object const* o) { if (o && o->GetTypeId() == TYPEID_UNIT) return reinterpret_cast<Creature const*>(o); else return nullptr; }
Creature* ToCreature() { return ToCreature(this); }
Creature const* ToCreature() const { return ToCreature(this); }
+ inline bool IsUnit() const { return isType(TYPEMASK_UNIT); }
static Unit* ToUnit(Object* o) { if (o && o->isType(TYPEMASK_UNIT)) return reinterpret_cast<Unit*>(o); else return nullptr; }
static Unit const* ToUnit(Object const* o) { if (o && o->isType(TYPEMASK_UNIT)) return reinterpret_cast<Unit const*>(o); else return nullptr; }
Unit* ToUnit() { return ToUnit(this); }
Unit const* ToUnit() const { return ToUnit(this); }
+ inline bool IsGameObject() const { return GetTypeId() == TYPEID_GAMEOBJECT; }
static GameObject* ToGameObject(Object* o) { if (o && o->GetTypeId() == TYPEID_GAMEOBJECT) return reinterpret_cast<GameObject*>(o); else return nullptr; }
static GameObject const* ToGameObject(Object const* o) { if (o && o->GetTypeId() == TYPEID_GAMEOBJECT) return reinterpret_cast<GameObject const*>(o); else return nullptr; }
GameObject* ToGameObject() { return ToGameObject(this); }
GameObject const* ToGameObject() const { return ToGameObject(this); }
+ inline bool IsCorpse() const { return GetTypeId() == TYPEID_CORPSE; }
static Corpse* ToCorpse(Object* o) { if (o && o->GetTypeId() == TYPEID_CORPSE) return reinterpret_cast<Corpse*>(o); else return nullptr; }
static Corpse const* ToCorpse(Object const* o) { if (o && o->GetTypeId() == TYPEID_CORPSE) return reinterpret_cast<Corpse const*>(o); else return nullptr; }
Corpse* ToCorpse() { return ToCorpse(this); }
Corpse const* ToCorpse() const { return ToCorpse(this); }
+ inline bool IsDynObject() const { return GetTypeId() == TYPEID_DYNAMICOBJECT; }
static DynamicObject* ToDynObject(Object* o) { if (o && o->GetTypeId() == TYPEID_DYNAMICOBJECT) return reinterpret_cast<DynamicObject*>(o); else return nullptr; }
static DynamicObject const* ToDynObject(Object const* o) { if (o && o->GetTypeId() == TYPEID_DYNAMICOBJECT) return reinterpret_cast<DynamicObject const*>(o); else return nullptr; }
DynamicObject* ToDynObject() { return ToDynObject(this); }
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp
index 4eb9b163c3a..740b22c8855 100644
--- a/src/server/game/Spells/Spell.cpp
+++ b/src/server/game/Spells/Spell.cpp
@@ -578,6 +578,7 @@ m_caster((info->HasAttribute(SPELL_ATTR6_CAST_BY_CHARMER) && caster->GetCharmerO
unitTarget = nullptr;
itemTarget = nullptr;
gameObjTarget = nullptr;
+ corpseTarget = nullptr;
destTarget = nullptr;
damage = 0;
targetMissInfo = SPELL_MISS_NONE;
@@ -1135,6 +1136,17 @@ void Spell::SelectImplicitNearbyTargets(SpellEffIndex effIndex, SpellImplicitTar
return;
}
break;
+ case TARGET_OBJECT_TYPE_CORPSE:
+ if (Corpse* corpseTarget = target->ToCorpse())
+ AddCorpseTarget(corpseTarget, effMask);
+ else
+ {
+ TC_LOG_DEBUG("spells", "Spell::SelectImplicitNearbyTargets: OnObjectTargetSelect script hook for spell Id %u set object of wrong type, expected corpse, got %s, effect %u", m_spellInfo->Id, target->GetGUID().GetTypeName(), effMask);
+ SendCastResult(SPELL_FAILED_BAD_IMPLICIT_TARGETS);
+ finish(false);
+ return;
+ }
+ break;
case TARGET_OBJECT_TYPE_DEST:
{
SpellDestination dest(*target);
@@ -1188,12 +1200,14 @@ void Spell::SelectImplicitConeTargets(SpellEffIndex effIndex, SpellImplicitTarge
Trinity::Containers::RandomResize(targets, maxTargets);
}
- for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end(); ++itr)
+ for (WorldObject* itr : targets)
{
- if (Unit* unit = (*itr)->ToUnit())
+ if (Unit* unit = itr->ToUnit())
AddUnitTarget(unit, effMask, false);
- else if (GameObject* gObjTarget = (*itr)->ToGameObject())
+ else if (GameObject* gObjTarget = itr->ToGameObject())
AddGOTarget(gObjTarget, effMask);
+ else if (Corpse* corpse = itr->ToCorpse())
+ AddCorpseTarget(corpse, effMask);
}
}
}
@@ -1272,12 +1286,14 @@ void Spell::SelectImplicitAreaTargets(SpellEffIndex effIndex, SpellImplicitTarge
Trinity::Containers::RandomResize(targets, maxTargets);
}
- for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end(); ++itr)
+ for (WorldObject* itr : targets)
{
- if (Unit* unit = (*itr)->ToUnit())
+ if (Unit* unit = itr->ToUnit())
AddUnitTarget(unit, effMask, false, true, center);
- else if (GameObject* gObjTarget = (*itr)->ToGameObject())
+ else if (GameObject* gObjTarget = itr->ToGameObject())
AddGOTarget(gObjTarget, effMask);
+ else if (Corpse* corpse = itr->ToCorpse())
+ AddCorpseTarget(corpse, effMask);
}
}
}
@@ -1538,6 +1554,8 @@ void Spell::SelectImplicitTargetObjectTargets(SpellEffIndex effIndex, SpellImpli
AddUnitTarget(unit, 1 << effIndex, true, false);
else if (GameObject* gobj = target->ToGameObject())
AddGOTarget(gobj, 1 << effIndex);
+ else if (Corpse* corpse = target->ToCorpse())
+ AddCorpseTarget(corpse, 1 << effIndex);
SelectImplicitChainTargets(effIndex, targetType, target, 1 << effIndex);
}
@@ -1700,7 +1718,7 @@ void Spell::SelectEffectTypeImplicitTargets(uint8 effIndex)
if (player->IsImmunedToSpellEffect(spell->GetSpellInfo(), effIndex, nullptr))
return;
- spell->HandleEffects(player, nullptr, nullptr, effIndex, SPELL_EFFECT_HANDLE_HIT_TARGET);
+ spell->HandleEffects(player, nullptr, nullptr, nullptr, effIndex, SPELL_EFFECT_HANDLE_HIT_TARGET);
}, std::placeholders::_1, this, effIndex, target->GetGUID()));
}
}
@@ -1732,11 +1750,7 @@ void Spell::SelectEffectTypeImplicitTargets(uint8 effIndex)
else if (targetMask & TARGET_FLAG_CORPSE_MASK)
{
if (Corpse* corpseTarget = m_targets.GetCorpseTarget())
- {
- /// @todo this is a workaround - corpses should be added to spell target map too, but we can't do that so we add owner instead
- if (Player* owner = ObjectAccessor::FindPlayer(corpseTarget->GetOwnerGUID()))
- target = owner;
- }
+ target = corpseTarget;
}
else //if (targetMask & TARGET_FLAG_UNIT_MASK)
target = m_caster;
@@ -1767,6 +1781,8 @@ void Spell::SelectEffectTypeImplicitTargets(uint8 effIndex)
AddUnitTarget(target->ToUnit(), 1 << effIndex, false);
else if (target->ToGameObject())
AddGOTarget(target->ToGameObject(), 1 << effIndex);
+ else if (target->ToCorpse())
+ AddCorpseTarget(target->ToCorpse(), 1 << effIndex);
}
}
@@ -1780,6 +1796,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:
@@ -1792,8 +1814,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))
@@ -2241,6 +2262,54 @@ void Spell::AddItemTarget(Item* item, uint32 effectMask)
m_UniqueItemInfo.emplace_back(std::move(target));
}
+void Spell::AddCorpseTarget(Corpse* corpse, uint32 effectMask)
+{
+ {
+ for (uint32 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
+ if (!m_spellInfo->Effects[effIndex].IsEffect())
+ effectMask &= ~(1 << effIndex);
+
+ if (!effectMask)
+ return;
+
+ ObjectGuid targetGUID = corpse->GetGUID();
+
+ // Lookup target in already in list
+ for (CorpseTargetInfo ihit : m_UniqueCorpseTargetInfo)
+ {
+ if (targetGUID == ihit.TargetGUID) // Found in list
+ {
+ ihit.EffectMask |= effectMask; // Add only effect mask
+ return;
+ }
+ }
+
+ // This is new target calculate data for him
+ CorpseTargetInfo target;
+ target.TargetGUID = targetGUID;
+ target.EffectMask = effectMask;
+
+ // Spell have speed - need calculate incoming time
+ if (m_spellInfo->Speed > 0.0f)
+ {
+ // calculate spell incoming interval
+ float dist = m_caster->GetDistance(corpse->GetPositionX(), corpse->GetPositionY(), corpse->GetPositionZ());
+ if (dist < 5.0f)
+ dist = 5.0f;
+
+ target.TimeDelay = uint64(floor(dist / m_spellInfo->Speed * 1000.0f));
+
+ if (!m_delayMoment || m_delayMoment > target.TimeDelay)
+ m_delayMoment = target.TimeDelay;
+ }
+ else
+ target.TimeDelay = 0LL;
+
+ // Add target to list
+ m_UniqueCorpseTargetInfo.push_back(target);
+ }
+}
+
void Spell::AddDestTarget(SpellDestination const& dest, uint32 effIndex)
{
m_destTargets[effIndex] = dest;
@@ -2576,7 +2645,7 @@ void Spell::GOTargetInfo::DoTargetSpellHit(Spell* spell, uint8 effIndex)
spell->CallScriptBeforeHitHandlers(SPELL_MISS_NONE);
- spell->HandleEffects(nullptr, nullptr, go, effIndex, SPELL_EFFECT_HANDLE_HIT_TARGET);
+ spell->HandleEffects(nullptr, nullptr, go, nullptr, effIndex, SPELL_EFFECT_HANDLE_HIT_TARGET);
// AI functions
if (go->AI())
@@ -2595,7 +2664,21 @@ void Spell::ItemTargetInfo::DoTargetSpellHit(Spell* spell, uint8 effIndex)
{
spell->CallScriptBeforeHitHandlers(SPELL_MISS_NONE);
- spell->HandleEffects(nullptr, TargetItem, nullptr, effIndex, SPELL_EFFECT_HANDLE_HIT_TARGET);
+ spell->HandleEffects(nullptr, TargetItem, nullptr, nullptr, effIndex, SPELL_EFFECT_HANDLE_HIT_TARGET);
+
+ spell->CallScriptOnHitHandlers();
+ spell->CallScriptAfterHitHandlers();
+}
+
+void Spell::CorpseTargetInfo::DoTargetSpellHit(Spell* spell, uint8 effIndex)
+{
+ Corpse* corpse = ObjectAccessor::GetCorpse(*spell->m_caster, TargetGUID);
+ if (!corpse)
+ return;
+
+ spell->CallScriptBeforeHitHandlers(SPELL_MISS_NONE);
+
+ spell->HandleEffects(nullptr, nullptr, nullptr, corpse, effIndex, SPELL_EFFECT_HANDLE_HIT_TARGET);
spell->CallScriptOnHitHandlers();
spell->CallScriptAfterHitHandlers();
@@ -2797,7 +2880,7 @@ void Spell::DoSpellEffectHit(Unit* unit, uint8 effIndex, TargetInfo& hitInfo)
}
_spellAura = hitInfo.HitAura;
- HandleEffects(unit, nullptr, nullptr, effIndex, SPELL_EFFECT_HANDLE_HIT_TARGET);
+ HandleEffects(unit, nullptr, nullptr, nullptr, effIndex, SPELL_EFFECT_HANDLE_HIT_TARGET);
_spellAura = nullptr;
}
@@ -3491,6 +3574,8 @@ void Spell::handle_immediate()
DoProcessTargetContainer(m_UniqueGOTargetInfo);
+ DoProcessTargetContainer(m_UniqueCorpseTargetInfo);
+
FinishTargetProcessing();
// spell is finished, perform some last features of the spell here
@@ -3608,7 +3693,7 @@ void Spell::_handle_immediate_phase()
continue;
// call effect handlers to handle destination hit
- HandleEffects(nullptr, nullptr, nullptr, j, SPELL_EFFECT_HANDLE_HIT);
+ HandleEffects(nullptr, nullptr, nullptr, nullptr, j, SPELL_EFFECT_HANDLE_HIT);
}
// process items
@@ -4986,12 +5071,13 @@ void Spell::HandleThreatSpells()
TC_LOG_DEBUG("spells", "Spell %u, added an additional %f threat for %s %u target(s)", m_spellInfo->Id, threat, IsPositive() ? "assisting" : "harming", uint32(m_UniqueTargetInfo.size()));
}
-void Spell::HandleEffects(Unit* pUnitTarget, Item* pItemTarget, GameObject* pGOTarget, uint32 i, SpellEffectHandleMode mode)
+void Spell::HandleEffects(Unit* pUnitTarget, Item* pItemTarget, GameObject* pGoTarget, Corpse* pCorpseTarget, uint32 i, SpellEffectHandleMode mode)
{
effectHandleMode = mode;
unitTarget = pUnitTarget;
itemTarget = pItemTarget;
- gameObjTarget = pGOTarget;
+ gameObjTarget = pGoTarget;
+ corpseTarget = pCorpseTarget;
destTarget = &m_destTargets[i]._position;
unitCaster = m_originalCaster ? m_originalCaster : m_caster->ToUnit();
@@ -7455,7 +7541,7 @@ void Spell::HandleLaunchPhase()
if (!m_spellInfo->Effects[i].IsEffect())
continue;
- HandleEffects(nullptr, nullptr, nullptr, i, SPELL_EFFECT_HANDLE_LAUNCH);
+ HandleEffects(nullptr, nullptr, nullptr, nullptr, i, SPELL_EFFECT_HANDLE_LAUNCH);
}
PrepareTargetProcessing();
@@ -7514,7 +7600,7 @@ void Spell::DoEffectOnLaunchTarget(TargetInfo& targetInfo, float multiplier, uin
m_damage = 0;
m_healing = 0;
- HandleEffects(unit, nullptr, nullptr, effIndex, SPELL_EFFECT_HANDLE_LAUNCH_TARGET);
+ HandleEffects(unit, nullptr, nullptr, nullptr, effIndex, SPELL_EFFECT_HANDLE_LAUNCH_TARGET);
if (m_originalCaster && m_damage > 0)
{
@@ -8094,13 +8180,15 @@ bool WorldObjectSpellTargetCheck::operator()(WorldObject* target) const
case TARGET_CHECK_ENEMY:
if (unitTarget->IsTotem())
return false;
- if (!_caster->IsValidAttackTarget(unitTarget, _spellInfo))
+ // TODO: restore IsValidAttackTarget for corpses using corpse owner (faction, etc)
+ if (!target->IsCorpse() && !_caster->IsValidAttackTarget(unitTarget, _spellInfo))
return false;
break;
case TARGET_CHECK_ALLY:
if (unitTarget->IsTotem())
return false;
- if (!_caster->IsValidAssistTarget(unitTarget, _spellInfo))
+ // TODO: restore IsValidAttackTarget for corpses using corpse owner (faction, etc)
+ if (!target->IsCorpse() && !_caster->IsValidAssistTarget(unitTarget, _spellInfo))
return false;
break;
case TARGET_CHECK_PARTY:
@@ -8108,7 +8196,8 @@ bool WorldObjectSpellTargetCheck::operator()(WorldObject* target) const
return false;
if (unitTarget->IsTotem())
return false;
- if (!_caster->IsValidAssistTarget(unitTarget, _spellInfo))
+ // TODO: restore IsValidAttackTarget for corpses using corpse owner (faction, etc)
+ if (!target->IsCorpse() && !_caster->IsValidAssistTarget(unitTarget, _spellInfo))
return false;
if (!refUnit->IsInPartyWith(unitTarget))
return false;
@@ -8124,7 +8213,8 @@ bool WorldObjectSpellTargetCheck::operator()(WorldObject* target) const
return false;
if (unitTarget->IsTotem())
return false;
- if (!_caster->IsValidAssistTarget(unitTarget, _spellInfo))
+ // TODO: restore IsValidAttackTarget for corpses using corpse owner (faction, etc)
+ if (!target->IsCorpse() && !_caster->IsValidAssistTarget(unitTarget, _spellInfo))
return false;
if (!refUnit->IsInRaidWith(unitTarget))
return false;
diff --git a/src/server/game/Spells/Spell.h b/src/server/game/Spells/Spell.h
index dddeddf2f71..0c60aac51b4 100644
--- a/src/server/game/Spells/Spell.h
+++ b/src/server/game/Spells/Spell.h
@@ -492,7 +492,7 @@ class TC_GAME_API Spell
void SendChannelStart(uint32 duration);
void SendResurrectRequest(Player* target);
- void HandleEffects(Unit* pUnitTarget, Item* pItemTarget, GameObject* pGOTarget, uint32 i, SpellEffectHandleMode mode);
+ void HandleEffects(Unit* pUnitTarget, Item* pItemTarget, GameObject* pGoTarget, Corpse* pCorpseTarget, uint32 i, SpellEffectHandleMode mode);
void HandleThreatSpells();
SpellInfo const* const m_spellInfo;
@@ -618,6 +618,7 @@ class TC_GAME_API Spell
Unit* unitTarget;
Item* itemTarget;
GameObject* gameObjTarget;
+ Corpse* corpseTarget;
WorldLocation* destTarget;
int32 damage;
SpellMissInfo targetMissInfo;
@@ -709,6 +710,15 @@ class TC_GAME_API Spell
};
std::vector<ItemTargetInfo> m_UniqueItemInfo;
+ struct CorpseTargetInfo : public TargetInfoBase
+ {
+ void DoTargetSpellHit(Spell* spell, uint8 effIndex) override;
+
+ ObjectGuid TargetGUID;
+ uint64 TimeDelay = 0ULL;
+ };
+ std::vector<CorpseTargetInfo> m_UniqueCorpseTargetInfo;
+
template <class Container>
void DoProcessTargetContainer(Container& targetContainer);
@@ -717,6 +727,7 @@ class TC_GAME_API Spell
void AddUnitTarget(Unit* target, uint32 effectMask, bool checkIfValid = true, bool implicit = true, Position const* losPosition = nullptr);
void AddGOTarget(GameObject* target, uint32 effectMask);
void AddItemTarget(Item* item, uint32 effectMask);
+ void AddCorpseTarget(Corpse* target, uint32 effectMask);
void AddDestTarget(SpellDestination const& dest, uint32 effIndex);
SpellMissInfo PreprocessSpellHit(Unit* unit, bool scaleAura, TargetInfo& targetInfo);
diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp
index 874294f5809..e8defc90144 100644
--- a/src/server/game/Spells/SpellEffects.cpp
+++ b/src/server/game/Spells/SpellEffects.cpp
@@ -36,6 +36,7 @@
#include "LootMgr.h"
#include "MiscPackets.h"
#include "MotionMaster.h"
+#include "ObjectAccessor.h"
#include "ObjectMgr.h"
#include "Opcodes.h"
#include "OutdoorPvPMgr.h"
@@ -244,25 +245,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)
- return;
+ Player* player = nullptr;
- if (!unitTarget->IsInWorld())
- return;
+ if (corpseTarget)
+ player = ObjectAccessor::FindPlayer(corpseTarget->GetOwnerGUID());
+ else if (unitTarget)
+ player = unitTarget->ToPlayer();
- Player* target = unitTarget->ToPlayer();
+ if (!player || player->IsAlive() || !player->IsInWorld())
+ return;
- 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*/)
@@ -694,7 +697,7 @@ void Spell::EffectDummy(SpellEffIndex effIndex)
if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET)
return;
- if (!unitTarget && !gameObjTarget && !itemTarget)
+ if (!unitTarget && !gameObjTarget && !itemTarget && !corpseTarget)
return;
// pet auras
@@ -1150,6 +1153,8 @@ void Spell::EffectSendEvent(SpellEffIndex effIndex)
target = unitTarget;
else if (gameObjTarget)
target = gameObjTarget;
+ else if (corpseTarget)
+ target = corpseTarget;
}
else // if (effectHandleMode == SPELL_EFFECT_HANDLE_HIT)
{
@@ -4000,24 +4005,29 @@ void Spell::EffectResurrect(SpellEffIndex effIndex)
if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET)
return;
- if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER)
+ if (!corpseTarget && !unitTarget)
return;
- if (unitTarget->IsAlive() || !unitTarget->IsInWorld())
- return;
+ Player* player = nullptr;
- Player* target = unitTarget->ToPlayer();
+ if (corpseTarget)
+ player = ObjectAccessor::FindPlayer(corpseTarget->GetOwnerGUID());
+ else if (unitTarget)
+ player = unitTarget->ToPlayer();
+
+ if (!player || player->IsAlive() || !player->IsInWorld())
+ return;
- if (target->IsResurrectRequested()) // already have one active request
+ if (player->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);
- ExecuteLogEffectResurrect(effIndex, target);
+ ExecuteLogEffectResurrect(effIndex, player);
- target->SetResurrectRequestData(m_caster, health, mana, 0);
- SendResurrectRequest(target);
+ player->SetResurrectRequestData(m_caster, health, mana, 0);
+ SendResurrectRequest(player);
}
void Spell::EffectAddExtraAttacks(SpellEffIndex effIndex)
@@ -4848,7 +4858,13 @@ void Spell::EffectSkinPlayerCorpse(SpellEffIndex /*effIndex*/)
TC_LOG_DEBUG("spells", "Effect: SkinPlayerCorpse");
Player* player = m_caster->ToPlayer();
- Player* target = unitTarget->ToPlayer();
+
+ Player* target = nullptr;
+ if (unitTarget)
+ target = unitTarget->ToPlayer();
+ else if (corpseTarget)
+ target = ObjectAccessor::FindPlayer(corpseTarget->GetOwnerGUID());
+
if (!player || !target || target->IsAlive())
return;