aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/game/Creature.h1
-rw-r--r--src/game/GridNotifiers.h59
-rw-r--r--src/game/SharedDefines.h1
-rw-r--r--src/game/Spell.cpp41
-rw-r--r--src/game/Spell.h2
5 files changed, 84 insertions, 20 deletions
diff --git a/src/game/Creature.h b/src/game/Creature.h
index 76470495e91..b90642547dd 100644
--- a/src/game/Creature.h
+++ b/src/game/Creature.h
@@ -650,6 +650,7 @@ class TRINITY_DLL_SPEC Creature : public Unit
bool IsVisibleInGridForPlayer(Player const* pl) const;
void RemoveCorpse();
+ bool isDeadByDefault() const { return m_isDeadByDefault; };
time_t const& GetRespawnTime() const { return m_respawnTime; }
time_t GetRespawnTimeEx() const;
diff --git a/src/game/GridNotifiers.h b/src/game/GridNotifiers.h
index 03d8ea11b16..195f7206264 100644
--- a/src/game/GridNotifiers.h
+++ b/src/game/GridNotifiers.h
@@ -499,6 +499,53 @@ namespace Trinity
// CHECKS && DO classes
// WorldObject check classes
+ class RaiseDeadObjectCheck
+ {
+ public:
+ RaiseDeadObjectCheck(Unit* funit, float range) : i_funit(funit), i_range(range) {}
+ bool operator()(Creature* u)
+ {
+ if (i_funit->GetTypeId()!=TYPEID_PLAYER || !((Player*)i_funit)->isHonorOrXPTarget(u) ||
+ u->getDeathState() != CORPSE || u->isDeadByDefault() || u->isInFlight() ||
+ ( u->GetCreatureTypeMask() & (1 << (CREATURE_TYPE_HUMANOID-1)) )==0 ||
+ (u->GetDisplayId() != u->GetNativeDisplayId()))
+ return false;
+
+ return i_funit->IsWithinDistInMap(u, i_range);
+ }
+ template<class NOT_INTERESTED> bool operator()(NOT_INTERESTED*) { return false; }
+ private:
+ Unit* const i_funit;
+ float i_range;
+ };
+
+ class ExplodeCorpseObjectCheck
+ {
+ public:
+ ExplodeCorpseObjectCheck(Unit* funit, float range) : i_funit(funit), i_range(range) {}
+ bool operator()(Player* u)
+ {
+ if (u->getDeathState()!=CORPSE || u->isInFlight() ||
+ u->HasAuraType(SPELL_AURA_GHOST) || (u->GetDisplayId() != u->GetNativeDisplayId()))
+ return false;
+
+ return i_funit->IsWithinDistInMap(u, i_range);
+ }
+ bool operator()(Creature* u)
+ {
+ if (u->getDeathState()!=CORPSE || u->isInFlight() || u->isDeadByDefault() ||
+ (u->GetDisplayId() != u->GetNativeDisplayId()) ||
+ (u->GetCreatureTypeMask() & CREATURE_TYPEMASK_MECHANICAL_OR_ELEMENTAL)!=0)
+ return false;
+
+ return i_funit->IsWithinDistInMap(u, i_range);
+ }
+ template<class NOT_INTERESTED> bool operator()(NOT_INTERESTED*) { return false; }
+ private:
+ Unit* const i_funit;
+ float i_range;
+ };
+
class CannibalizeObjectCheck
{
public:
@@ -508,22 +555,16 @@ namespace Trinity
if( i_funit->IsFriendlyTo(u) || u->isAlive() || u->isInFlight() )
return false;
- if(i_funit->IsWithinDistInMap(u, i_range) )
- return true;
-
- return false;
+ return i_funit->IsWithinDistInMap(u, i_range);
}
bool operator()(Corpse* u);
bool operator()(Creature* u)
{
- if( i_funit->IsFriendlyTo(u) || u->isAlive() || u->isInFlight() ||
+ if (i_funit->IsFriendlyTo(u) || u->isAlive() || u->isInFlight() ||
(u->GetCreatureTypeMask() & CREATURE_TYPEMASK_HUMANOID_OR_UNDEAD)==0)
return false;
- if(i_funit->IsWithinDistInMap(u, i_range) )
- return true;
-
- return false;
+ return i_funit->IsWithinDistInMap(u, i_range);
}
template<class NOT_INTERESTED> bool operator()(NOT_INTERESTED*) { return false; }
private:
diff --git a/src/game/SharedDefines.h b/src/game/SharedDefines.h
index 5a32744da7c..e592bebf1de 100644
--- a/src/game/SharedDefines.h
+++ b/src/game/SharedDefines.h
@@ -1820,6 +1820,7 @@ enum CreatureType
};
uint32 const CREATURE_TYPEMASK_HUMANOID_OR_UNDEAD = (1 << (CREATURE_TYPE_HUMANOID-1)) | (1 << (CREATURE_TYPE_UNDEAD-1));
+uint32 const CREATURE_TYPEMASK_MECHANICAL_OR_ELEMENTAL = (1 << (CREATURE_TYPE_MECHANICAL-1)) | (1 << (CREATURE_TYPE_ELEMENTAL-1));
// CreatureFamily.dbc
enum CreatureFamily
diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp
index 5b53647fe4c..0835273a36c 100644
--- a/src/game/Spell.cpp
+++ b/src/game/Spell.cpp
@@ -476,6 +476,35 @@ Spell::~Spell()
delete m_spellValue;
}
+template<typename T>
+WorldObject* Spell::FindCorpseUsing()
+{
+ // non-standard target selection
+ float max_range = GetSpellMaxRange(m_spellInfo, false);
+
+ CellPair p(MaNGOS::ComputeCellPair(m_caster->GetPositionX(), m_caster->GetPositionY()));
+ Cell cell(p);
+ cell.data.Part.reserved = ALL_DISTRICT;
+ cell.SetNoCreate();
+
+ WorldObject* result = NULL;
+
+ T u_check(m_caster, max_range);
+ MaNGOS::WorldObjectSearcher<T> searcher(m_caster, result, u_check);
+
+ TypeContainerVisitor<MaNGOS::WorldObjectSearcher<T>, GridTypeMapContainer > grid_searcher(searcher);
+ CellLock<GridReadGuard> cell_lock(cell, p);
+ cell_lock->Visit(cell_lock, grid_searcher, *m_caster->GetMap());
+
+ if (!result)
+ {
+ TypeContainerVisitor<MaNGOS::WorldObjectSearcher<T>, WorldTypeMapContainer > world_searcher(searcher);
+ cell_lock->Visit(cell_lock, world_searcher, *m_caster->GetMap());
+ }
+
+ return result;
+}
+
void Spell::FillTargetMap()
{
for(uint32 i = 0; i < 3; ++i)
@@ -535,17 +564,7 @@ void Spell::FillTargetMap()
{
case 20577: // Cannibalize
{
- // non-standard target selection
- SpellRangeEntry const* srange = sSpellRangeStore.LookupEntry(m_spellInfo->rangeIndex);
- float max_range = GetSpellMaxRangeForHostile(srange);
- WorldObject* result = NULL;
-
- Trinity::CannibalizeObjectCheck u_check(m_caster, max_range);
- Trinity::WorldObjectSearcher<Trinity::CannibalizeObjectCheck > searcher(m_caster, result, u_check);
- m_caster->VisitNearbyGridObject(max_range, searcher);
- if(!result)
- m_caster->VisitNearbyWorldObject(max_range, searcher);
-
+ WorldObject* result = FindCorpseUsing<MaNGOS::CannibalizeObjectCheck> ();
if(result)
{
diff --git a/src/game/Spell.h b/src/game/Spell.h
index 6dc8477dcdb..642c40de474 100644
--- a/src/game/Spell.h
+++ b/src/game/Spell.h
@@ -412,6 +412,8 @@ class Spell
void SetTargetMap(uint32 i, uint32 cur);
+ template<typename T> WorldObject* FindCorpseUsing();
+
bool CheckTarget( Unit* target, uint32 eff );
bool CanAutoCast(Unit* target);
void CheckSrc() { if(!m_targets.HasSrc()) m_targets.setSrc(m_caster); }