[7808] Move corpse search code in function with template arg for class-check.

This let reuse code for other similar near corpse target selection spells.
Also provided currently not used class-checks for 2 spells

Signed-off-by: VladimirMangos <vladimir@getmangos.com>
This commit is contained in:
Astellar 2009-05-09 18:45:19 +04:00 committed by VladimirMangos
parent 1feff6365f
commit 09046df744
6 changed files with 86 additions and 33 deletions

View file

@ -615,6 +615,7 @@ class MANGOS_DLL_SPEC Creature : public Unit
bool IsVisibleInGridForPlayer(Player* pl) const; bool IsVisibleInGridForPlayer(Player* pl) const;
void RemoveCorpse(); void RemoveCorpse();
bool isDeadByDefault() const { return m_isDeadByDefault; };
time_t const& GetRespawnTime() const { return m_respawnTime; } time_t const& GetRespawnTime() const { return m_respawnTime; }
time_t GetRespawnTimeEx() const; time_t GetRespawnTimeEx() const;

View file

@ -504,6 +504,53 @@ namespace MaNGOS
// CHECKS && DO classes // CHECKS && DO classes
// WorldObject check 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 class CannibalizeObjectCheck
{ {
public: public:
@ -513,22 +560,16 @@ namespace MaNGOS
if( i_funit->IsFriendlyTo(u) || u->isAlive() || u->isInFlight() ) if( i_funit->IsFriendlyTo(u) || u->isAlive() || u->isInFlight() )
return false; return false;
if(i_funit->IsWithinDistInMap(u, i_range) ) return i_funit->IsWithinDistInMap(u, i_range);
return true;
return false;
} }
bool operator()(Corpse* u); bool operator()(Corpse* u);
bool operator()(Creature* 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) (u->GetCreatureTypeMask() & CREATURE_TYPEMASK_HUMANOID_OR_UNDEAD)==0)
return false; return false;
if(i_funit->IsWithinDistInMap(u, i_range) ) return i_funit->IsWithinDistInMap(u, i_range);
return true;
return false;
} }
template<class NOT_INTERESTED> bool operator()(NOT_INTERESTED*) { return false; } template<class NOT_INTERESTED> bool operator()(NOT_INTERESTED*) { return false; }
private: private:

View file

@ -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_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 // CreatureFamily.dbc
enum CreatureFamily enum CreatureFamily

View file

@ -423,6 +423,36 @@ Spell::~Spell()
{ {
} }
template<typename T>
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<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() void Spell::FillTargetMap()
{ {
// TODO: ADD the correct target FILLS!!!!!! // TODO: ADD the correct target FILLS!!!!!!
@ -537,29 +567,7 @@ void Spell::FillTargetMap()
{ {
case 20577: // Cannibalize case 20577: // Cannibalize
{ {
// non-standard target selection WorldObject* result = FindCorpseUsing<MaNGOS::CannibalizeObjectCheck> ();
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<MaNGOS::CannibalizeObjectCheck > searcher(m_caster, result, u_check);
TypeContainerVisitor<MaNGOS::WorldObjectSearcher<MaNGOS::CannibalizeObjectCheck >, 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<MaNGOS::CannibalizeObjectCheck >, WorldTypeMapContainer > world_searcher(searcher);
cell_lock->Visit(cell_lock, world_searcher, *m_caster->GetMap());
}
if(result) if(result)
{ {

View file

@ -381,6 +381,8 @@ class Spell
void SetTargetMap(uint32 i,uint32 cur,UnitList& TagUnitMap); void SetTargetMap(uint32 i,uint32 cur,UnitList& TagUnitMap);
void FillAreaTargets( UnitList& TagUnitMap, float x, float y, float radius, SpellNotifyPushType pushType, SpellTargets spellTargets ); void FillAreaTargets( UnitList& TagUnitMap, float x, float y, float radius, SpellNotifyPushType pushType, SpellTargets spellTargets );
template<typename T> WorldObject* FindCorpseUsing();
bool CheckTarget( Unit* target, uint32 eff ); bool CheckTarget( Unit* target, uint32 eff );
bool CanAutoCast(Unit* target); bool CanAutoCast(Unit* target);

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__ #ifndef __REVISION_NR_H__
#define __REVISION_NR_H__ #define __REVISION_NR_H__
#define REVISION_NR "7807" #define REVISION_NR "7808"
#endif // __REVISION_NR_H__ #endif // __REVISION_NR_H__