/* * Copyright (C) 2005-2010 MaNGOS * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef MANGOS_GRIDNOTIFIERS_H #define MANGOS_GRIDNOTIFIERS_H #include "ObjectGridLoader.h" #include "UpdateData.h" #include #include "Corpse.h" #include "Object.h" #include "DynamicObject.h" #include "GameObject.h" #include "Player.h" #include "Unit.h" #include "CreatureAI.h" class Player; //class Map; namespace MaNGOS { struct MANGOS_DLL_DECL VisibleNotifier { Camera& i_camera; UpdateData i_data; ObjectGuidSet i_clientGUIDs; std::set i_visibleNow; explicit VisibleNotifier(Camera &c) : i_camera(c), i_clientGUIDs(c.GetOwner()->m_clientGUIDs) {} template void Visit(GridRefManager &m); void Visit(CameraMapType &m) {} void Notify(void); }; struct MANGOS_DLL_DECL VisibleChangesNotifier { WorldObject &i_object; explicit VisibleChangesNotifier(WorldObject &object) : i_object(object) {} template void Visit(GridRefManager &) {} void Visit(CameraMapType &); }; struct MANGOS_DLL_DECL GridUpdater { GridType &i_grid; uint32 i_timeDiff; GridUpdater(GridType &grid, uint32 diff) : i_grid(grid), i_timeDiff(diff) {} template void updateObjects(GridRefManager &m) { for(typename GridRefManager::iterator iter = m.begin(); iter != m.end(); ++iter) iter->getSource()->Update(i_timeDiff); } void Visit(PlayerMapType &m) { updateObjects(m); } void Visit(CreatureMapType &m){ updateObjects(m); } void Visit(GameObjectMapType &m) { updateObjects(m); } void Visit(DynamicObjectMapType &m) { updateObjects(m); } void Visit(CorpseMapType &m) { updateObjects(m); } }; struct MANGOS_DLL_DECL MessageDeliverer { Player &i_player; WorldPacket *i_message; bool i_toSelf; MessageDeliverer(Player &pl, WorldPacket *msg, bool to_self) : i_player(pl), i_message(msg), i_toSelf(to_self) {} void Visit(CameraMapType &m); template void Visit(GridRefManager &) {} }; struct MessageDelivererExcept { uint32 i_phaseMask; WorldPacket* i_message; Player const* i_skipped_receiver; MessageDelivererExcept(WorldObject const* obj, WorldPacket *msg, Player const* skipped) : i_phaseMask(obj->GetPhaseMask()), i_message(msg), i_skipped_receiver(skipped) {} void Visit(CameraMapType &m); template void Visit(GridRefManager &) {} }; struct MANGOS_DLL_DECL ObjectMessageDeliverer { uint32 i_phaseMask; WorldPacket *i_message; explicit ObjectMessageDeliverer(WorldObject& obj, WorldPacket *msg) : i_phaseMask(obj.GetPhaseMask()), i_message(msg) {} void Visit(CameraMapType &m); template void Visit(GridRefManager &) {} }; struct MANGOS_DLL_DECL MessageDistDeliverer { Player &i_player; WorldPacket *i_message; bool i_toSelf; bool i_ownTeamOnly; float i_dist; MessageDistDeliverer(Player &pl, WorldPacket *msg, float dist, bool to_self, bool ownTeamOnly) : i_player(pl), i_message(msg), i_toSelf(to_self), i_ownTeamOnly(ownTeamOnly), i_dist(dist) {} void Visit(CameraMapType &m); template void Visit(GridRefManager &) {} }; struct MANGOS_DLL_DECL ObjectMessageDistDeliverer { WorldObject &i_object; WorldPacket *i_message; float i_dist; ObjectMessageDistDeliverer(WorldObject &obj, WorldPacket *msg, float dist) : i_object(obj), i_message(msg), i_dist(dist) {} void Visit(CameraMapType &m); template void Visit(GridRefManager &) {} }; struct MANGOS_DLL_DECL ObjectUpdater { uint32 i_timeDiff; explicit ObjectUpdater(const uint32 &diff) : i_timeDiff(diff) {} template void Visit(GridRefManager &m); void Visit(PlayerMapType &) {} void Visit(CorpseMapType &) {} void Visit(CameraMapType &) {} void Visit(CreatureMapType &); }; struct MANGOS_DLL_DECL PlayerRelocationNotifier { Player &i_player; PlayerRelocationNotifier(Player &pl) : i_player(pl) {} template void Visit(GridRefManager &) {} void Visit(CreatureMapType &); }; struct MANGOS_DLL_DECL CreatureRelocationNotifier { Creature &i_creature; CreatureRelocationNotifier(Creature &c) : i_creature(c) {} template void Visit(GridRefManager &) {} #ifdef WIN32 template<> void Visit(PlayerMapType &); #endif }; struct MANGOS_DLL_DECL DynamicObjectUpdater { DynamicObject &i_dynobject; Unit* i_check; DynamicObjectUpdater(DynamicObject &dynobject, Unit* caster) : i_dynobject(dynobject) { i_check = caster; Unit* owner = i_check->GetOwner(); if(owner) i_check = owner; } template inline void Visit(GridRefManager &) {} #ifdef WIN32 template<> inline void Visit(PlayerMapType &); template<> inline void Visit(CreatureMapType &); #endif void VisitHelper(Unit* target); }; // SEARCHERS & LIST SEARCHERS & WORKERS /* Model Searcher class: template struct MANGOS_DLL_DECL SomeSearcher { ResultType& i_result; Check & i_check; SomeSearcher(ResultType& result, Check & check) : i_phaseMask(check.GetFocusObject().GetPhaseMask()), i_result(result), i_check(check) {} void Visit(CreatureMapType &m); { ..some code fast return if result found for(CreatureMapType::iterator itr = m.begin(); itr != m.end(); ++itr) { if (!itr->getSource()->InSamePhase(i_phaseMask)) continue; if (!i_check(itr->getSource())) continue; ..some code for update result and possible stop search } } template void Visit(GridRefManager &) {} }; */ // WorldObject searchers & workers template struct MANGOS_DLL_DECL WorldObjectSearcher { uint32 i_phaseMask; WorldObject* &i_object; Check &i_check; WorldObjectSearcher(WorldObject* & result, Check& check) : i_phaseMask(check.GetFocusObject().GetPhaseMask()), i_object(result),i_check(check) {} void Visit(GameObjectMapType &m); void Visit(PlayerMapType &m); void Visit(CreatureMapType &m); void Visit(CorpseMapType &m); void Visit(DynamicObjectMapType &m); template void Visit(GridRefManager &) {} }; template struct MANGOS_DLL_DECL WorldObjectListSearcher { uint32 i_phaseMask; std::list &i_objects; Check& i_check; WorldObjectListSearcher(std::list &objects, Check & check) : i_phaseMask(check.GetFocusObject().GetPhaseMask()), i_objects(objects),i_check(check) {} void Visit(PlayerMapType &m); void Visit(CreatureMapType &m); void Visit(CorpseMapType &m); void Visit(GameObjectMapType &m); void Visit(DynamicObjectMapType &m); template void Visit(GridRefManager &) {} }; template struct MANGOS_DLL_DECL WorldObjectWorker { uint32 i_phaseMask; Do const& i_do; WorldObjectWorker(WorldObject const* searcher, Do const& _do) : i_phaseMask(searcher->GetPhaseMask()), i_do(_do) {} void Visit(GameObjectMapType &m) { for(GameObjectMapType::iterator itr=m.begin(); itr != m.end(); ++itr) if(itr->getSource()->InSamePhase(i_phaseMask)) i_do(itr->getSource()); } void Visit(PlayerMapType &m) { for(PlayerMapType::iterator itr=m.begin(); itr != m.end(); ++itr) if(itr->getSource()->InSamePhase(i_phaseMask)) i_do(itr->getSource()); } void Visit(CreatureMapType &m) { for(CreatureMapType::iterator itr=m.begin(); itr != m.end(); ++itr) if(itr->getSource()->InSamePhase(i_phaseMask)) i_do(itr->getSource()); } void Visit(CorpseMapType &m) { for(CorpseMapType::iterator itr=m.begin(); itr != m.end(); ++itr) if(itr->getSource()->InSamePhase(i_phaseMask)) i_do(itr->getSource()); } void Visit(DynamicObjectMapType &m) { for(DynamicObjectMapType::iterator itr=m.begin(); itr != m.end(); ++itr) if(itr->getSource()->InSamePhase(i_phaseMask)) i_do(itr->getSource()); } template void Visit(GridRefManager &) {} }; // Gameobject searchers template struct MANGOS_DLL_DECL GameObjectSearcher { uint32 i_phaseMask; GameObject* &i_object; Check &i_check; GameObjectSearcher(GameObject* & result, Check& check) : i_phaseMask(check.GetFocusObject().GetPhaseMask()), i_object(result),i_check(check) {} void Visit(GameObjectMapType &m); template void Visit(GridRefManager &) {} }; // Last accepted by Check GO if any (Check can change requirements at each call) template struct MANGOS_DLL_DECL GameObjectLastSearcher { uint32 i_phaseMask; GameObject* &i_object; Check& i_check; GameObjectLastSearcher(GameObject* & result, Check& check) : i_phaseMask(check.GetFocusObject().GetPhaseMask()), i_object(result), i_check(check) {} void Visit(GameObjectMapType &m); template void Visit(GridRefManager &) {} }; template struct MANGOS_DLL_DECL GameObjectListSearcher { uint32 i_phaseMask; std::list &i_objects; Check& i_check; GameObjectListSearcher(std::list &objects, Check & check) : i_phaseMask(check.GetFocusObject().GetPhaseMask()), i_objects(objects), i_check(check) {} void Visit(GameObjectMapType &m); template void Visit(GridRefManager &) {} }; // Unit searchers // First accepted by Check Unit if any template struct MANGOS_DLL_DECL UnitSearcher { uint32 i_phaseMask; Unit* &i_object; Check & i_check; UnitSearcher(Unit* & result, Check & check) : i_phaseMask(check.GetFocusObject().GetPhaseMask()), i_object(result),i_check(check) {} void Visit(CreatureMapType &m); void Visit(PlayerMapType &m); template void Visit(GridRefManager &) {} }; // Last accepted by Check Unit if any (Check can change requirements at each call) template struct MANGOS_DLL_DECL UnitLastSearcher { uint32 i_phaseMask; Unit* &i_object; Check & i_check; UnitLastSearcher(Unit* & result, Check & check) : i_phaseMask(check.GetFocusObject().GetPhaseMask()), i_object(result),i_check(check) {} void Visit(CreatureMapType &m); void Visit(PlayerMapType &m); template void Visit(GridRefManager &) {} }; // All accepted by Check units if any template struct MANGOS_DLL_DECL UnitListSearcher { uint32 i_phaseMask; std::list &i_objects; Check& i_check; UnitListSearcher(std::list &objects, Check & check) : i_phaseMask(check.GetFocusObject().GetPhaseMask()), i_objects(objects),i_check(check) {} void Visit(PlayerMapType &m); void Visit(CreatureMapType &m); template void Visit(GridRefManager &) {} }; // Creature searchers template struct MANGOS_DLL_DECL CreatureSearcher { uint32 i_phaseMask; Creature* &i_object; Check & i_check; CreatureSearcher(Creature* & result, Check & check) : i_phaseMask(check.GetFocusObject().GetPhaseMask()), i_object(result),i_check(check) {} void Visit(CreatureMapType &m); template void Visit(GridRefManager &) {} }; // Last accepted by Check Creature if any (Check can change requirements at each call) template struct MANGOS_DLL_DECL CreatureLastSearcher { uint32 i_phaseMask; Creature* &i_object; Check & i_check; CreatureLastSearcher(Creature* & result, Check & check) : i_phaseMask(check.GetFocusObject().GetPhaseMask()), i_object(result),i_check(check) {} void Visit(CreatureMapType &m); template void Visit(GridRefManager &) {} }; template struct MANGOS_DLL_DECL CreatureListSearcher { uint32 i_phaseMask; std::list &i_objects; Check& i_check; CreatureListSearcher(std::list &objects, Check & check) : i_phaseMask(check.GetFocusObject().GetPhaseMask()), i_objects(objects),i_check(check) {} void Visit(CreatureMapType &m); template void Visit(GridRefManager &) {} }; template struct MANGOS_DLL_DECL CreatureWorker { uint32 i_phaseMask; Do& i_do; CreatureWorker(WorldObject const* searcher, Do& _do) : i_phaseMask(searcher->GetPhaseMask()), i_do(_do) {} void Visit(CreatureMapType &m) { for(CreatureMapType::iterator itr=m.begin(); itr != m.end(); ++itr) if(itr->getSource()->InSamePhase(i_phaseMask)) i_do(itr->getSource()); } template void Visit(GridRefManager &) {} }; // Player searchers template struct MANGOS_DLL_DECL PlayerSearcher { uint32 i_phaseMask; Player* &i_object; Check & i_check; PlayerSearcher(Player* & result, Check & check) : i_phaseMask(check.GetFocusObject().GetPhaseMask()), i_object(result),i_check(check) {} void Visit(PlayerMapType &m); template void Visit(GridRefManager &) {} }; template struct MANGOS_DLL_DECL PlayerWorker { uint32 i_phaseMask; Do& i_do; PlayerWorker(WorldObject const* searcher, Do& _do) : i_phaseMask(searcher->GetPhaseMask()), i_do(_do) {} void Visit(PlayerMapType &m) { for(PlayerMapType::iterator itr=m.begin(); itr != m.end(); ++itr) if(itr->getSource()->InSamePhase(i_phaseMask)) i_do(itr->getSource()); } template void Visit(GridRefManager &) {} }; template struct MANGOS_DLL_DECL CameraDistWorker { WorldObject const* i_searcher; float i_dist; Do& i_do; CameraDistWorker(WorldObject const* searcher, float _dist, Do& _do) : i_searcher(searcher), i_dist(_dist), i_do(_do) {} void Visit(CameraMapType &m) { for(CameraMapType::iterator itr=m.begin(); itr != m.end(); ++itr) if (itr->getSource()->GetBody()->InSamePhase(i_searcher) && itr->getSource()->GetBody()->IsWithinDist(i_searcher,i_dist)) i_do(itr->getSource()->GetOwner()); } template void Visit(GridRefManager &) {} }; // CHECKS && DO classes /* Model Check class: class SomeCheck { public: SomeCheck(SomeObjecType const* fobj, ..some other args) : i_fobj(fobj), ...other inits {} WorldObject const& GetFocusObject() const { return *i_fobj; } bool operator()(Creature* u) and for other intresting typs (Player/GameObject/Camera { return ..(code return true if Object fit to requirenment); } template bool operator()(NOT_INTERESTED*) { return false; } private: SomeObjecType const* i_fobj; // Focus object used for check distance from, phase, so place in world ..other values need for check }; */ // WorldObject check classes class RaiseDeadObjectCheck { public: RaiseDeadObjectCheck(Player const* fobj, float range) : i_fobj(fobj), i_range(range) {} WorldObject const& GetFocusObject() const { return *i_fobj; } bool operator()(Creature* u) { if (i_fobj->isHonorOrXPTarget(u) || u->getDeathState() != CORPSE || u->IsDeadByDefault() || u->IsTaxiFlying() || ( u->GetCreatureTypeMask() & (1 << (CREATURE_TYPE_HUMANOID-1)) )==0 || (u->GetDisplayId() != u->GetNativeDisplayId())) return false; return i_fobj->IsWithinDistInMap(u, i_range); } template bool operator()(NOT_INTERESTED*) { return false; } private: Player const* i_fobj; float i_range; }; class ExplodeCorpseObjectCheck { public: ExplodeCorpseObjectCheck(WorldObject const* fobj, float range) : i_fobj(fobj), i_range(range) {} WorldObject const& GetFocusObject() const { return *i_fobj; } bool operator()(Player* u) { if (u->getDeathState()!=CORPSE || u->IsTaxiFlying() || u->HasAuraType(SPELL_AURA_GHOST) || (u->GetDisplayId() != u->GetNativeDisplayId())) return false; return i_fobj->IsWithinDistInMap(u, i_range); } bool operator()(Creature* u) { if (u->getDeathState()!=CORPSE || u->IsTaxiFlying() || u->IsDeadByDefault() || (u->GetDisplayId() != u->GetNativeDisplayId()) || (u->GetCreatureTypeMask() & CREATURE_TYPEMASK_MECHANICAL_OR_ELEMENTAL)!=0) return false; return i_fobj->IsWithinDistInMap(u, i_range); } template bool operator()(NOT_INTERESTED*) { return false; } private: WorldObject const* i_fobj; float i_range; }; class CannibalizeObjectCheck { public: CannibalizeObjectCheck(WorldObject const* fobj, float range) : i_fobj(fobj), i_range(range) {} WorldObject const& GetFocusObject() const { return *i_fobj; } bool operator()(Player* u) { if( i_fobj->IsFriendlyTo(u) || u->isAlive() || u->IsTaxiFlying() ) return false; return i_fobj->IsWithinDistInMap(u, i_range); } bool operator()(Corpse* u); bool operator()(Creature* u) { if (i_fobj->IsFriendlyTo(u) || u->isAlive() || u->IsTaxiFlying() || (u->GetCreatureTypeMask() & CREATURE_TYPEMASK_HUMANOID_OR_UNDEAD)==0) return false; return i_fobj->IsWithinDistInMap(u, i_range); } template bool operator()(NOT_INTERESTED*) { return false; } private: WorldObject const* i_fobj; float i_range; }; // WorldObject do classes class RespawnDo { public: RespawnDo() {} void operator()(Creature* u) const; void operator()(GameObject* u) const; void operator()(WorldObject*) const {} void operator()(Corpse*) const {} }; // GameObject checks class GameObjectFocusCheck { public: GameObjectFocusCheck(Unit const* unit,uint32 focusId) : i_unit(unit), i_focusId(focusId) {} WorldObject const& GetFocusObject() const { return *i_unit; } bool operator()(GameObject* go) const { if(go->GetGOInfo()->type != GAMEOBJECT_TYPE_SPELL_FOCUS) return false; if(go->GetGOInfo()->spellFocus.focusId != i_focusId) return false; float dist = (float)go->GetGOInfo()->spellFocus.dist; return go->IsWithinDistInMap(i_unit, dist); } private: Unit const* i_unit; uint32 i_focusId; }; // Find the nearest Fishing hole and return true only if source object is in range of hole class NearestGameObjectFishingHoleCheck { public: NearestGameObjectFishingHoleCheck(WorldObject const& obj, float range) : i_obj(obj), i_range(range) {} WorldObject const& GetFocusObject() const { return i_obj; } bool operator()(GameObject* go) { if(go->GetGOInfo()->type == GAMEOBJECT_TYPE_FISHINGHOLE && go->isSpawned() && i_obj.IsWithinDistInMap(go, i_range) && i_obj.IsWithinDistInMap(go, (float)go->GetGOInfo()->fishinghole.radius)) { i_range = i_obj.GetDistance(go); return true; } return false; } float GetLastRange() const { return i_range; } private: WorldObject const& i_obj; float i_range; // prevent clone NearestGameObjectFishingHoleCheck(NearestGameObjectFishingHoleCheck const&); }; // Success at unit in range, range update for next check (this can be use with GameobjectLastSearcher to find nearest GO) class NearestGameObjectEntryInObjectRangeCheck { public: NearestGameObjectEntryInObjectRangeCheck(WorldObject const& obj,uint32 entry, float range) : i_obj(obj), i_entry(entry), i_range(range) {} WorldObject const& GetFocusObject() const { return i_obj; } bool operator()(GameObject* go) { if(go->GetEntry() == i_entry && i_obj.IsWithinDistInMap(go, i_range)) { i_range = i_obj.GetDistance(go); // use found GO range as new range limit for next check return true; } return false; } float GetLastRange() const { return i_range; } private: WorldObject const& i_obj; uint32 i_entry; float i_range; // prevent clone this object NearestGameObjectEntryInObjectRangeCheck(NearestGameObjectEntryInObjectRangeCheck const&); }; class GameObjectWithDbGUIDCheck { public: GameObjectWithDbGUIDCheck(WorldObject const& obj,uint32 db_guid) : i_obj(obj), i_db_guid(db_guid) {} WorldObject const& GetFocusObject() const { return i_obj; } bool operator()(GameObject const* go) const { return go->GetDBTableGUIDLow() == i_db_guid; } private: WorldObject const& i_obj; uint32 i_db_guid; }; // Unit checks class MostHPMissingInRangeCheck { public: MostHPMissingInRangeCheck(Unit const* obj, float range, uint32 hp) : i_obj(obj), i_range(range), i_hp(hp) {} WorldObject const& GetFocusObject() const { return *i_obj; } bool operator()(Unit* u) { if(u->isAlive() && u->isInCombat() && !i_obj->IsHostileTo(u) && i_obj->IsWithinDistInMap(u, i_range) && u->GetMaxHealth() - u->GetHealth() > i_hp) { i_hp = u->GetMaxHealth() - u->GetHealth(); return true; } return false; } private: Unit const* i_obj; float i_range; uint32 i_hp; }; class FriendlyCCedInRangeCheck { public: FriendlyCCedInRangeCheck(WorldObject const* obj, float range) : i_obj(obj), i_range(range) {} WorldObject const& GetFocusObject() const { return *i_obj; } bool operator()(Unit* u) { if(u->isAlive() && u->isInCombat() && !i_obj->IsHostileTo(u) && i_obj->IsWithinDistInMap(u, i_range) && (u->isCharmed() || u->isFrozen() || u->hasUnitState(UNIT_STAT_CAN_NOT_REACT))) { return true; } return false; } private: WorldObject const* i_obj; float i_range; }; class FriendlyMissingBuffInRangeCheck { public: FriendlyMissingBuffInRangeCheck(WorldObject const* obj, float range, uint32 spellid) : i_obj(obj), i_range(range), i_spell(spellid) {} WorldObject const& GetFocusObject() const { return *i_obj; } bool operator()(Unit* u) { if(u->isAlive() && u->isInCombat() && !i_obj->IsHostileTo(u) && i_obj->IsWithinDistInMap(u, i_range) && !(u->HasAura(i_spell, EFFECT_INDEX_0) || u->HasAura(i_spell, EFFECT_INDEX_1) || u->HasAura(i_spell, EFFECT_INDEX_2))) { return true; } return false; } private: WorldObject const* i_obj; float i_range; uint32 i_spell; }; class AnyUnfriendlyUnitInObjectRangeCheck { public: AnyUnfriendlyUnitInObjectRangeCheck(WorldObject const* obj, Unit const* funit, float range) : i_obj(obj), i_funit(funit), i_range(range) {} WorldObject const& GetFocusObject() const { return *i_obj; } bool operator()(Unit* u) { if(u->isAlive() && i_obj->IsWithinDistInMap(u, i_range) && !i_funit->IsFriendlyTo(u)) return true; else return false; } private: WorldObject const* i_obj; Unit const* i_funit; float i_range; }; class AnyUnfriendlyVisibleUnitInObjectRangeCheck { public: AnyUnfriendlyVisibleUnitInObjectRangeCheck(WorldObject const* obj, Unit const* funit, float range) : i_obj(obj), i_funit(funit), i_range(range) {} WorldObject const& GetFocusObject() const { return *i_obj; } bool operator()(Unit* u) { return u->isAlive() && i_obj->IsWithinDistInMap(u, i_range) && !i_funit->IsFriendlyTo(u) && u->isVisibleForOrDetect(i_funit,i_funit,false); } private: WorldObject const* i_obj; Unit const* i_funit; float i_range; }; class AnyFriendlyUnitInObjectRangeCheck { public: AnyFriendlyUnitInObjectRangeCheck(WorldObject const* obj, float range) : i_obj(obj), i_range(range) {} WorldObject const& GetFocusObject() const { return *i_obj; } bool operator()(Unit* u) { if(u->isAlive() && i_obj->IsWithinDistInMap(u, i_range) && i_obj->IsFriendlyTo(u)) return true; else return false; } private: WorldObject const* i_obj; float i_range; }; class AnyUnitInObjectRangeCheck { public: AnyUnitInObjectRangeCheck(WorldObject const* obj, float range) : i_obj(obj), i_range(range) {} WorldObject const& GetFocusObject() const { return *i_obj; } bool operator()(Unit* u) { if(u->isAlive() && i_obj->IsWithinDistInMap(u, i_range)) return true; return false; } private: WorldObject const* i_obj; float i_range; }; // Success at unit in range, range update for next check (this can be use with UnitLastSearcher to find nearest unit) class NearestAttackableUnitInObjectRangeCheck { public: NearestAttackableUnitInObjectRangeCheck(WorldObject const* obj, Unit const* funit, float range) : i_obj(obj), i_funit(funit), i_range(range) {} WorldObject const& GetFocusObject() const { return *i_obj; } bool operator()(Unit* u) { if( u->isTargetableForAttack() && i_obj->IsWithinDistInMap(u, i_range) && !i_funit->IsFriendlyTo(u) && u->isVisibleForOrDetect(i_funit,i_funit,false) ) { i_range = i_obj->GetDistance(u); // use found unit range as new range limit for next check return true; } return false; } private: WorldObject const* i_obj; Unit const* i_funit; float i_range; // prevent clone this object NearestAttackableUnitInObjectRangeCheck(NearestAttackableUnitInObjectRangeCheck const&); }; class AnyAoEVisibleTargetUnitInObjectRangeCheck { public: AnyAoEVisibleTargetUnitInObjectRangeCheck(WorldObject const* obj, WorldObject const* originalCaster, float range) : i_obj(obj), i_originalCaster(originalCaster), i_range(range) { i_targetForUnit = i_originalCaster->isType(TYPEMASK_UNIT); i_targetForPlayer = (i_originalCaster->GetTypeId() == TYPEID_PLAYER); } WorldObject const& GetFocusObject() const { return *i_obj; } bool operator()(Unit* u) { // Check contains checks for: live, non-selectable, non-attackable flags, flight check and GM check, ignore totems if (!u->isTargetableForAttack()) return false; // ignore totems as AoE targets if(u->GetTypeId()==TYPEID_UNIT && ((Creature*)u)->IsTotem()) return false; // check visibility only for unit-like original casters if (i_targetForUnit && !u->isVisibleForOrDetect((Unit const*)i_originalCaster, i_originalCaster, false)) return false; if ((i_targetForPlayer ? !i_originalCaster->IsFriendlyTo(u) : i_originalCaster->IsHostileTo(u)) && i_obj->IsWithinDistInMap(u, i_range)) return true; return false; } private: bool i_targetForUnit; bool i_targetForPlayer; WorldObject const* i_obj; WorldObject const* i_originalCaster; float i_range; }; class AnyAoETargetUnitInObjectRangeCheck { public: AnyAoETargetUnitInObjectRangeCheck(WorldObject const* obj, float range) : i_obj(obj), i_range(range) { i_targetForPlayer = i_obj->IsControlledByPlayer(); } WorldObject const& GetFocusObject() const { return *i_obj; } bool operator()(Unit* u) { // Check contains checks for: live, non-selectable, non-attackable flags, flight check and GM check, ignore totems if (!u->isTargetableForAttack()) return false; if(u->GetTypeId()==TYPEID_UNIT && ((Creature*)u)->IsTotem()) return false; if(( i_targetForPlayer ? !i_obj->IsFriendlyTo(u) : i_obj->IsHostileTo(u) )&& i_obj->IsWithinDistInMap(u, i_range)) return true; return false; } private: bool i_targetForPlayer; WorldObject const* i_obj; float i_range; }; // do attack at call of help to friendly crearture class CallOfHelpCreatureInRangeDo { public: CallOfHelpCreatureInRangeDo(Unit* funit, Unit* enemy, float range) : i_funit(funit), i_enemy(enemy), i_range(range) {} void operator()(Creature* u) { if (u == i_funit) return; if (!u->CanAssistTo(i_funit, i_enemy, false)) return; // too far if (!i_funit->IsWithinDistInMap(u, i_range)) return; // only if see assisted creature if (!i_funit->IsWithinLOSInMap(u)) return; if (u->AI()) u->AI()->AttackStart(i_enemy); } private: Unit* const i_funit; Unit* const i_enemy; float i_range; }; class AnyDeadUnitCheck { public: explicit AnyDeadUnitCheck(WorldObject const* fobj) : i_fobj(fobj) {} WorldObject const& GetFocusObject() const { return *i_fobj; } bool operator()(Unit* u) { return !u->isAlive(); } private: WorldObject const* i_fobj; }; class AnyStealthedCheck { public: explicit AnyStealthedCheck(WorldObject const* fobj) : i_fobj(fobj) {} WorldObject const& GetFocusObject() const { return *i_fobj; } bool operator()(Unit* u) { return u->GetVisibility()==VISIBILITY_GROUP_STEALTH; } private: WorldObject const* i_fobj; }; // Creature checks class InAttackDistanceFromAnyHostileCreatureCheck { public: explicit InAttackDistanceFromAnyHostileCreatureCheck(Unit* funit) : i_funit(funit) {} WorldObject const& GetFocusObject() const { return *i_funit; } bool operator()(Creature* u) { if(u->isAlive() && u->IsHostileTo(i_funit) && i_funit->IsWithinDistInMap(u, u->GetAttackDistance(i_funit))) return true; return false; } private: Unit* const i_funit; }; class AnyAssistCreatureInRangeCheck { public: AnyAssistCreatureInRangeCheck(Unit* funit, Unit* enemy, float range) : i_funit(funit), i_enemy(enemy), i_range(range) { } WorldObject const& GetFocusObject() const { return *i_funit; } bool operator()(Creature* u) { if(u == i_funit) return false; if ( !u->CanAssistTo(i_funit, i_enemy) ) return false; // too far if( !i_funit->IsWithinDistInMap(u, i_range) ) return false; // only if see assisted creature if( !i_funit->IsWithinLOSInMap(u) ) return false; return true; } private: Unit* const i_funit; Unit* const i_enemy; float i_range; }; class NearestAssistCreatureInCreatureRangeCheck { public: NearestAssistCreatureInCreatureRangeCheck(Creature* obj, Unit* enemy, float range) : i_obj(obj), i_enemy(enemy), i_range(range) {} WorldObject const& GetFocusObject() const { return *i_obj; } bool operator()(Creature* u) { if(u == i_obj) return false; if(!u->CanAssistTo(i_obj,i_enemy)) return false; if(!i_obj->IsWithinDistInMap(u, i_range)) return false; if(!i_obj->IsWithinLOSInMap(u)) return false; i_range = i_obj->GetDistance(u); // use found unit range as new range limit for next check return true; } float GetLastRange() const { return i_range; } private: Creature* const i_obj; Unit* const i_enemy; float i_range; // prevent clone this object NearestAssistCreatureInCreatureRangeCheck(NearestAssistCreatureInCreatureRangeCheck const&); }; // Success at unit in range, range update for next check (this can be use with CreatureLastSearcher to find nearest creature) class NearestCreatureEntryWithLiveStateInObjectRangeCheck { public: NearestCreatureEntryWithLiveStateInObjectRangeCheck(WorldObject const& obj,uint32 entry, bool alive, float range) : i_obj(obj), i_entry(entry), i_alive(alive), i_range(range) {} WorldObject const& GetFocusObject() const { return i_obj; } bool operator()(Creature* u) { if(u->GetEntry() == i_entry && u->isAlive()==i_alive && i_obj.IsWithinDistInMap(u, i_range)) { i_range = i_obj.GetDistance(u); // use found unit range as new range limit for next check return true; } return false; } float GetLastRange() const { return i_range; } private: WorldObject const& i_obj; uint32 i_entry; bool i_alive; float i_range; // prevent clone this object NearestCreatureEntryWithLiveStateInObjectRangeCheck(NearestCreatureEntryWithLiveStateInObjectRangeCheck const&); }; class AnyPlayerInObjectRangeCheck { public: AnyPlayerInObjectRangeCheck(WorldObject const* obj, float range) : i_obj(obj), i_range(range) {} WorldObject const& GetFocusObject() const { return *i_obj; } bool operator()(Player* u) { if(u->isAlive() && i_obj->IsWithinDistInMap(u, i_range)) return true; return false; } private: WorldObject const* i_obj; float i_range; }; // Player checks and do // Prepare using Builder localized packets with caching and send to player template class LocalizedPacketDo { public: explicit LocalizedPacketDo(Builder& builder) : i_builder(builder) {} ~LocalizedPacketDo() { for(size_t i = 0; i < i_data_cache.size(); ++i) delete i_data_cache[i]; } void operator()( Player* p ); private: Builder& i_builder; std::vector i_data_cache; // 0 = default, i => i-1 locale index }; // Prepare using Builder localized packets with caching and send to player template class LocalizedPacketListDo { public: typedef std::vector WorldPacketList; explicit LocalizedPacketListDo(Builder& builder) : i_builder(builder) {} ~LocalizedPacketListDo() { for(size_t i = 0; i < i_data_cache.size(); ++i) for(size_t j = 0; j < i_data_cache[i].size(); ++j) delete i_data_cache[i][j]; } void operator()( Player* p ); private: Builder& i_builder; std::vector i_data_cache; // 0 = default, i => i-1 locale index }; #ifndef WIN32 template<> void PlayerRelocationNotifier::Visit(CreatureMapType &); template<> void CreatureRelocationNotifier::Visit(PlayerMapType &); template<> void CreatureRelocationNotifier::Visit(CreatureMapType &); template<> inline void DynamicObjectUpdater::Visit(CreatureMapType &); template<> inline void DynamicObjectUpdater::Visit(PlayerMapType &); #endif } #endif