diff --git a/src/game/Creature.h b/src/game/Creature.h index 9404d4cb1..c71106a8d 100644 --- a/src/game/Creature.h +++ b/src/game/Creature.h @@ -615,6 +615,7 @@ class MANGOS_DLL_SPEC Creature : public Unit bool IsVisibleInGridForPlayer(Player* 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 c4eddee21..daf393eff 100644 --- a/src/game/GridNotifiers.h +++ b/src/game/GridNotifiers.h @@ -504,6 +504,53 @@ namespace MaNGOS // 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 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 bool operator()(NOT_INTERESTED*) { return false; } + private: + Unit* const i_funit; + float i_range; + }; + class CannibalizeObjectCheck { public: @@ -513,22 +560,16 @@ namespace MaNGOS 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 bool operator()(NOT_INTERESTED*) { return false; } private: diff --git a/src/game/SharedDefines.h b/src/game/SharedDefines.h index b68e364ce..54ff80ae5 100644 --- a/src/game/SharedDefines.h +++ b/src/game/SharedDefines.h @@ -1766,6 +1766,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 ba99e4c6c..91ec801b2 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -423,6 +423,36 @@ Spell::~Spell() { } +template +WorldObject* Spell::FindCorpseUsing() +{ + // non-standard target selection + SpellRangeEntry const* srange = sSpellRangeStore.LookupEntry(m_spellInfo->rangeIndex); + float max_range = GetSpellMaxRange(srange); + + 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 searcher(m_caster, result, u_check); + + TypeContainerVisitor, GridTypeMapContainer > grid_searcher(searcher); + CellLock cell_lock(cell, p); + cell_lock->Visit(cell_lock, grid_searcher, *m_caster->GetMap()); + + if (!result) + { + TypeContainerVisitor, WorldTypeMapContainer > world_searcher(searcher); + cell_lock->Visit(cell_lock, world_searcher, *m_caster->GetMap()); + } + + return result; +} + void Spell::FillTargetMap() { // TODO: ADD the correct target FILLS!!!!!! @@ -537,29 +567,7 @@ void Spell::FillTargetMap() { case 20577: // Cannibalize { - // non-standard target selection - SpellRangeEntry const* srange = sSpellRangeStore.LookupEntry(m_spellInfo->rangeIndex); - float max_range = GetSpellMaxRange(srange); - - CellPair p(MaNGOS::ComputeCellPair(m_caster->GetPositionX(), m_caster->GetPositionY())); - Cell cell(p); - cell.data.Part.reserved = ALL_DISTRICT; - cell.SetNoCreate(); - - WorldObject* result = NULL; - - MaNGOS::CannibalizeObjectCheck u_check(m_caster, max_range); - MaNGOS::WorldObjectSearcher searcher(m_caster, result, u_check); - - TypeContainerVisitor, GridTypeMapContainer > grid_searcher(searcher); - CellLock cell_lock(cell, p); - cell_lock->Visit(cell_lock, grid_searcher, *m_caster->GetMap()); - - if(!result) - { - TypeContainerVisitor, WorldTypeMapContainer > world_searcher(searcher); - cell_lock->Visit(cell_lock, world_searcher, *m_caster->GetMap()); - } + WorldObject* result = FindCorpseUsing (); if(result) { diff --git a/src/game/Spell.h b/src/game/Spell.h index fc2eb2314..ac2544b59 100644 --- a/src/game/Spell.h +++ b/src/game/Spell.h @@ -381,6 +381,8 @@ class Spell void SetTargetMap(uint32 i,uint32 cur,UnitList& TagUnitMap); void FillAreaTargets( UnitList& TagUnitMap, float x, float y, float radius, SpellNotifyPushType pushType, SpellTargets spellTargets ); + template WorldObject* FindCorpseUsing(); + bool CheckTarget( Unit* target, uint32 eff ); bool CanAutoCast(Unit* target); diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index baa878e89..f1fe7bb42 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "7807" + #define REVISION_NR "7808" #endif // __REVISION_NR_H__