From b5da6103885771bbb5becc5bd726c46379a5d39c Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Thu, 29 Jan 2009 02:47:28 +0300 Subject: [PATCH] Phase system development continue. * Use WorldObject phase mask field instead explicit aura scan. This allow have phase for any world objects. * Add phase checks to packet broadcasters/object searchers. This let correctly work say/yell/area and multi/random target spells/aggro assistance in phased areas or target selection. * In GM-mode character presense (see and visible) in all phases except normal visibility efects including GM-visibility. TODO: summoned objects phase set base at owner phase, load phase mask for creatures/gameobjects from DB, in game commands. --- src/game/Chat.cpp | 2 +- src/game/Creature.cpp | 2 +- src/game/GameObject.cpp | 8 ++-- src/game/GridNotifiers.cpp | 14 +++++- src/game/GridNotifiers.h | 78 ++++++++++++++++++++++--------- src/game/GridNotifiersImpl.h | 91 ++++++++++++++++++++++++++++-------- src/game/Level3.cpp | 2 +- src/game/Map.cpp | 2 +- src/game/Object.cpp | 22 +++------ src/game/Object.h | 24 ++++++++-- src/game/Player.cpp | 8 +++- src/game/Spell.cpp | 14 +++--- src/game/SpellAuras.cpp | 34 ++++++++++---- src/game/TotemAI.cpp | 2 +- src/game/Unit.cpp | 35 +++----------- src/game/World.cpp | 6 +-- 16 files changed, 223 insertions(+), 121 deletions(-) diff --git a/src/game/Chat.cpp b/src/game/Chat.cpp index a4bd89b97..c03ca2bfe 100644 --- a/src/game/Chat.cpp +++ b/src/game/Chat.cpp @@ -1243,7 +1243,7 @@ GameObject* ChatHandler::GetObjectGlobalyWithGuidOrNearWithDbGuid(uint32 lowguid cell.data.Part.reserved = ALL_DISTRICT; MaNGOS::GameObjectWithDbGUIDCheck go_check(*pl,lowguid); - MaNGOS::GameObjectSearcher checker(obj,go_check); + MaNGOS::GameObjectSearcher checker(pl,obj,go_check); TypeContainerVisitor, GridTypeMapContainer > object_checker(checker); CellLock cell_lock(cell, p); diff --git a/src/game/Creature.cpp b/src/game/Creature.cpp index 28cb26d94..25cf16b12 100644 --- a/src/game/Creature.cpp +++ b/src/game/Creature.cpp @@ -1701,7 +1701,7 @@ void Creature::CallAssistance() cell.SetNoCreate(); MaNGOS::AnyAssistCreatureInRangeCheck u_check(this, getVictim(), radius); - MaNGOS::CreatureListSearcher searcher(assistList, u_check); + MaNGOS::CreatureListSearcher searcher(this, assistList, u_check); TypeContainerVisitor, GridTypeMapContainer > grid_creature_searcher(searcher); diff --git a/src/game/GameObject.cpp b/src/game/GameObject.cpp index 764baea96..3001c85a6 100644 --- a/src/game/GameObject.cpp +++ b/src/game/GameObject.cpp @@ -320,7 +320,7 @@ void GameObject::Update(uint32 /*p_time*/) if(owner && NeedDespawn) // hunter trap { MaNGOS::AnyUnfriendlyUnitInObjectRangeCheck u_check(this, owner, radius); - MaNGOS::UnitSearcher checker(ok, u_check); + MaNGOS::UnitSearcher checker(this,ok, u_check); CellLock cell_lock(cell, p); @@ -341,7 +341,7 @@ void GameObject::Update(uint32 /*p_time*/) // affect only players Player* p_ok = NULL; MaNGOS::AnyPlayerInObjectRangeCheck p_check(this, radius); - MaNGOS::PlayerSearcher checker(p_ok, p_check); + MaNGOS::PlayerSearcher checker(this,p_ok, p_check); CellLock cell_lock(cell, p); @@ -799,7 +799,7 @@ void GameObject::TriggeringLinkedGameObject( uint32 trapEntry, Unit* target) cell.data.Part.reserved = ALL_DISTRICT; MaNGOS::NearestGameObjectEntryInObjectRangeCheck go_check(*target,trapEntry,range); - MaNGOS::GameObjectLastSearcher checker(trapGO,go_check); + MaNGOS::GameObjectLastSearcher checker(this, trapGO,go_check); TypeContainerVisitor, GridTypeMapContainer > object_checker(checker); CellLock cell_lock(cell, p); @@ -820,7 +820,7 @@ GameObject* GameObject::LookupFishingHoleAround(float range) Cell cell(p); cell.data.Part.reserved = ALL_DISTRICT; MaNGOS::NearestGameObjectFishingHole u_check(*this, range); - MaNGOS::GameObjectSearcher checker(ok, u_check); + MaNGOS::GameObjectSearcher checker(this, ok, u_check); CellLock cell_lock(cell, p); diff --git a/src/game/GridNotifiers.cpp b/src/game/GridNotifiers.cpp index fc1bc3f88..56de6adaa 100644 --- a/src/game/GridNotifiers.cpp +++ b/src/game/GridNotifiers.cpp @@ -142,8 +142,11 @@ MessageDeliverer::Visit(PlayerMapType &m) { for(PlayerMapType::iterator iter=m.begin(); iter != m.end(); ++iter) { - if( i_toSelf || iter->getSource() != &i_player) + if (i_toSelf || iter->getSource() != &i_player) { + if (!i_player.InSamePhase(iter->getSource())) + continue; + if(WorldSession* session = iter->getSource()->GetSession()) session->SendPacket(i_message); } @@ -155,6 +158,9 @@ ObjectMessageDeliverer::Visit(PlayerMapType &m) { for(PlayerMapType::iterator iter=m.begin(); iter != m.end(); ++iter) { + if(!iter->getSource()->InSamePhase(i_phaseMask)) + continue; + if(WorldSession* session = iter->getSource()->GetSession()) session->SendPacket(i_message); } @@ -169,6 +175,9 @@ MessageDistDeliverer::Visit(PlayerMapType &m) (!i_ownTeamOnly || iter->getSource()->GetTeam() == i_player.GetTeam() ) && (!i_dist || iter->getSource()->GetDistance(&i_player) <= i_dist) ) { + if (!i_player.InSamePhase(iter->getSource())) + continue; + if(WorldSession* session = iter->getSource()->GetSession()) session->SendPacket(i_message); } @@ -182,6 +191,9 @@ ObjectMessageDistDeliverer::Visit(PlayerMapType &m) { if( !i_dist || iter->getSource()->GetDistance(&i_object) <= i_dist ) { + if( !i_object.InSamePhase(iter->getSource())) + continue; + if(WorldSession* session = iter->getSource()->GetSession()) session->SendPacket(i_message); } diff --git a/src/game/GridNotifiers.h b/src/game/GridNotifiers.h index f0f4e406f..a000dd927 100644 --- a/src/game/GridNotifiers.h +++ b/src/game/GridNotifiers.h @@ -99,8 +99,10 @@ namespace MaNGOS struct MANGOS_DLL_DECL ObjectMessageDeliverer { + uint32 i_phaseMask; WorldPacket *i_message; - explicit ObjectMessageDeliverer(WorldPacket *msg) : i_message(msg) {} + explicit ObjectMessageDeliverer(WorldObject& obj, WorldPacket *msg) + : i_phaseMask(obj.GetPhaseMask()), i_message(msg) {} void Visit(PlayerMapType &m); template void Visit(GridRefManager &) {} }; @@ -211,10 +213,12 @@ namespace MaNGOS template struct MANGOS_DLL_DECL WorldObjectSearcher { + uint32 i_phaseMask; WorldObject* &i_object; Check &i_check; - WorldObjectSearcher(WorldObject* & result, Check& check) : i_object(result),i_check(check) {} + WorldObjectSearcher(WorldObject const* searcher, WorldObject* & result, Check& check) + : i_phaseMask(searcher->GetPhaseMask()), i_object(result),i_check(check) {} void Visit(GameObjectMapType &m); void Visit(PlayerMapType &m); @@ -228,10 +232,12 @@ namespace MaNGOS template struct MANGOS_DLL_DECL WorldObjectListSearcher { + uint32 i_phaseMask; std::list &i_objects; Check& i_check; - WorldObjectListSearcher(std::list &objects, Check & check) : i_objects(objects),i_check(check) {} + WorldObjectListSearcher(WorldObject const* searcher, std::list &objects, Check & check) + : i_phaseMask(searcher->GetPhaseMask()), i_objects(objects),i_check(check) {} void Visit(PlayerMapType &m); void Visit(CreatureMapType &m); @@ -245,37 +251,44 @@ namespace MaNGOS template struct MANGOS_DLL_DECL WorldObjectWorker { + uint32 i_phaseMask; Do const& i_do; - explicit WorldObjectWorker(Do const& _do) : i_do(_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) - i_do(itr->getSource()); + if(itr->getSource()->InSamePhase(i_phaseMask)) + i_do(itr->getSource()); } void Visit(PlayerMapType &m) { for(PlayerMapType::iterator itr=m.begin(); itr != m.end(); ++itr) - i_do(itr->getSource()); + if(itr->getSource()->InSamePhase(i_phaseMask)) + i_do(itr->getSource()); } void Visit(CreatureMapType &m) { for(CreatureMapType::iterator itr=m.begin(); itr != m.end(); ++itr) - i_do(itr->getSource()); + if(itr->getSource()->InSamePhase(i_phaseMask)) + i_do(itr->getSource()); } void Visit(CorpseMapType &m) { for(CorpseMapType::iterator itr=m.begin(); itr != m.end(); ++itr) - i_do(itr->getSource()); + if(itr->getSource()->InSamePhase(i_phaseMask)) + i_do(itr->getSource()); } void Visit(DynamicObjectMapType &m) { for(DynamicObjectMapType::iterator itr=m.begin(); itr != m.end(); ++itr) - i_do(itr->getSource()); + if(itr->getSource()->InSamePhase(i_phaseMask)) + i_do(itr->getSource()); } template void Visit(GridRefManager &) {} @@ -286,10 +299,12 @@ namespace MaNGOS template struct MANGOS_DLL_DECL GameObjectSearcher { + uint32 i_phaseMask; GameObject* &i_object; Check &i_check; - GameObjectSearcher(GameObject* & result, Check& check) : i_object(result),i_check(check) {} + GameObjectSearcher(WorldObject const* searcher, GameObject* & result, Check& check) + : i_phaseMask(searcher->GetPhaseMask()), i_object(result),i_check(check) {} void Visit(GameObjectMapType &m); @@ -300,10 +315,12 @@ namespace MaNGOS template struct MANGOS_DLL_DECL GameObjectLastSearcher { + uint32 i_phaseMask; GameObject* &i_object; Check& i_check; - GameObjectLastSearcher(GameObject* & result, Check& check) : i_object(result),i_check(check) {} + GameObjectLastSearcher(WorldObject const* searcher, GameObject* & result, Check& check) + : i_phaseMask(searcher->GetPhaseMask()), i_object(result), i_check(check) {} void Visit(GameObjectMapType &m); @@ -313,10 +330,12 @@ namespace MaNGOS template struct MANGOS_DLL_DECL GameObjectListSearcher { + uint32 i_phaseMask; std::list &i_objects; Check& i_check; - GameObjectListSearcher(std::list &objects, Check & check) : i_objects(objects),i_check(check) {} + GameObjectListSearcher(WorldObject const* searcher, std::list &objects, Check & check) + : i_phaseMask(searcher->GetPhaseMask()), i_objects(objects), i_check(check) {} void Visit(GameObjectMapType &m); @@ -329,10 +348,12 @@ namespace MaNGOS template struct MANGOS_DLL_DECL UnitSearcher { + uint32 i_phaseMask; Unit* &i_object; Check & i_check; - UnitSearcher(Unit* & result, Check & check) : i_object(result),i_check(check) {} + UnitSearcher(WorldObject const* searcher, Unit* & result, Check & check) + : i_phaseMask(searcher->GetPhaseMask()), i_object(result),i_check(check) {} void Visit(CreatureMapType &m); void Visit(PlayerMapType &m); @@ -344,10 +365,12 @@ namespace MaNGOS template struct MANGOS_DLL_DECL UnitLastSearcher { + uint32 i_phaseMask; Unit* &i_object; Check & i_check; - UnitLastSearcher(Unit* & result, Check & check) : i_object(result),i_check(check) {} + UnitLastSearcher(WorldObject const* searcher, Unit* & result, Check & check) + : i_phaseMask(searcher->GetPhaseMask()), i_object(result),i_check(check) {} void Visit(CreatureMapType &m); void Visit(PlayerMapType &m); @@ -359,10 +382,12 @@ namespace MaNGOS template struct MANGOS_DLL_DECL UnitListSearcher { + uint32 i_phaseMask; std::list &i_objects; Check& i_check; - UnitListSearcher(std::list &objects, Check & check) : i_objects(objects),i_check(check) {} + UnitListSearcher(WorldObject const* searcher, std::list &objects, Check & check) + : i_phaseMask(searcher->GetPhaseMask()), i_objects(objects),i_check(check) {} void Visit(PlayerMapType &m); void Visit(CreatureMapType &m); @@ -375,10 +400,12 @@ namespace MaNGOS template struct MANGOS_DLL_DECL CreatureSearcher { + uint32 i_phaseMask; Creature* &i_object; Check & i_check; - CreatureSearcher(Creature* & result, Check & check) : i_object(result),i_check(check) {} + CreatureSearcher(WorldObject const* searcher, Creature* & result, Check & check) + : i_phaseMask(searcher->GetPhaseMask()), i_object(result),i_check(check) {} void Visit(CreatureMapType &m); @@ -389,10 +416,12 @@ namespace MaNGOS template struct MANGOS_DLL_DECL CreatureLastSearcher { + uint32 i_phaseMask; Creature* &i_object; Check & i_check; - CreatureLastSearcher(Creature* & result, Check & check) : i_object(result),i_check(check) {} + CreatureLastSearcher(WorldObject const* searcher, Creature* & result, Check & check) + : i_phaseMask(searcher->GetPhaseMask()), i_object(result),i_check(check) {} void Visit(CreatureMapType &m); @@ -402,10 +431,12 @@ namespace MaNGOS template struct MANGOS_DLL_DECL CreatureListSearcher { + uint32 i_phaseMask; std::list &i_objects; Check& i_check; - CreatureListSearcher(std::list &objects, Check & check) : i_objects(objects),i_check(check) {} + CreatureListSearcher(WorldObject const* searcher, std::list &objects, Check & check) + : i_phaseMask(searcher->GetPhaseMask()), i_objects(objects),i_check(check) {} void Visit(CreatureMapType &m); @@ -417,10 +448,12 @@ namespace MaNGOS template struct MANGOS_DLL_DECL PlayerSearcher { + uint32 i_phaseMask; Player* &i_object; Check & i_check; - PlayerSearcher(Player* & result, Check & check) : i_object(result),i_check(check) {} + PlayerSearcher(WorldObject const* searcher, Player* & result, Check & check) + : i_phaseMask(searcher->GetPhaseMask()), i_object(result),i_check(check) {} void Visit(PlayerMapType &m); @@ -430,14 +463,17 @@ namespace MaNGOS template struct MANGOS_DLL_DECL PlayerWorker { + uint32 i_phaseMask; Do& i_do; - explicit PlayerWorker(Do& _do) : i_do(_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) - i_do(itr->getSource()); + if(itr->getSource()->InSamePhase(i_phaseMask)) + i_do(itr->getSource()); } template void Visit(GridRefManager &) {} diff --git a/src/game/GridNotifiersImpl.h b/src/game/GridNotifiersImpl.h index 590fc68c9..d0815bc35 100644 --- a/src/game/GridNotifiersImpl.h +++ b/src/game/GridNotifiersImpl.h @@ -153,7 +153,7 @@ inline void MaNGOS::DynamicObjectUpdater::VisitHelper(Unit* target) if( target->GetTypeId()==TYPEID_PLAYER && target != i_check && (((Player*)target)->isGameMaster() || ((Player*)target)->GetVisibility()==VISIBILITY_OFF) ) return; - if( i_check->GetTypeId()==TYPEID_PLAYER ) + if (i_check->GetTypeId()==TYPEID_PLAYER ) { if (i_check->IsFriendlyTo( target )) return; @@ -207,7 +207,10 @@ void MaNGOS::WorldObjectSearcher::Visit(GameObjectMapType &m) for(GameObjectMapType::iterator itr=m.begin(); itr != m.end(); ++itr) { - if(i_check(itr->getSource())) + if(!itr->getSource()->InSamePhase(i_phaseMask)) + continue; + + if (i_check(itr->getSource())) { i_object = itr->getSource(); return; @@ -224,6 +227,9 @@ void MaNGOS::WorldObjectSearcher::Visit(PlayerMapType &m) for(PlayerMapType::iterator itr=m.begin(); itr != m.end(); ++itr) { + if(!itr->getSource()->InSamePhase(i_phaseMask)) + continue; + if(i_check(itr->getSource())) { i_object = itr->getSource(); @@ -241,6 +247,9 @@ void MaNGOS::WorldObjectSearcher::Visit(CreatureMapType &m) for(CreatureMapType::iterator itr=m.begin(); itr != m.end(); ++itr) { + if(!itr->getSource()->InSamePhase(i_phaseMask)) + continue; + if(i_check(itr->getSource())) { i_object = itr->getSource(); @@ -258,6 +267,9 @@ void MaNGOS::WorldObjectSearcher::Visit(CorpseMapType &m) for(CorpseMapType::iterator itr=m.begin(); itr != m.end(); ++itr) { + if(!itr->getSource()->InSamePhase(i_phaseMask)) + continue; + if(i_check(itr->getSource())) { i_object = itr->getSource(); @@ -275,6 +287,9 @@ void MaNGOS::WorldObjectSearcher::Visit(DynamicObjectMapType &m) for(DynamicObjectMapType::iterator itr=m.begin(); itr != m.end(); ++itr) { + if(!itr->getSource()->InSamePhase(i_phaseMask)) + continue; + if(i_check(itr->getSource())) { i_object = itr->getSource(); @@ -287,40 +302,45 @@ template void MaNGOS::WorldObjectListSearcher::Visit(PlayerMapType &m) { for(PlayerMapType::iterator itr=m.begin(); itr != m.end(); ++itr) - if(i_check(itr->getSource())) - i_objects.push_back(itr->getSource()); + if(itr->getSource()->InSamePhase(i_phaseMask)) + if(i_check(itr->getSource())) + i_objects.push_back(itr->getSource()); } template void MaNGOS::WorldObjectListSearcher::Visit(CreatureMapType &m) { for(CreatureMapType::iterator itr=m.begin(); itr != m.end(); ++itr) - if(i_check(itr->getSource())) - i_objects.push_back(itr->getSource()); + if(itr->getSource()->InSamePhase(i_phaseMask)) + if(i_check(itr->getSource())) + i_objects.push_back(itr->getSource()); } template void MaNGOS::WorldObjectListSearcher::Visit(CorpseMapType &m) { for(CorpseMapType::iterator itr=m.begin(); itr != m.end(); ++itr) - if(i_check(itr->getSource())) - i_objects.push_back(itr->getSource()); + if(itr->getSource()->InSamePhase(i_phaseMask)) + if(i_check(itr->getSource())) + i_objects.push_back(itr->getSource()); } template void MaNGOS::WorldObjectListSearcher::Visit(GameObjectMapType &m) { for(GameObjectMapType::iterator itr=m.begin(); itr != m.end(); ++itr) - if(i_check(itr->getSource())) - i_objects.push_back(itr->getSource()); + if(itr->getSource()->InSamePhase(i_phaseMask)) + if(i_check(itr->getSource())) + i_objects.push_back(itr->getSource()); } template void MaNGOS::WorldObjectListSearcher::Visit(DynamicObjectMapType &m) { for(DynamicObjectMapType::iterator itr=m.begin(); itr != m.end(); ++itr) - if(i_check(itr->getSource())) - i_objects.push_back(itr->getSource()); + if(itr->getSource()->InSamePhase(i_phaseMask)) + if(i_check(itr->getSource())) + i_objects.push_back(itr->getSource()); } // Gameobject searchers @@ -334,6 +354,9 @@ void MaNGOS::GameObjectSearcher::Visit(GameObjectMapType &m) for(GameObjectMapType::iterator itr=m.begin(); itr != m.end(); ++itr) { + if(!itr->getSource()->InSamePhase(i_phaseMask)) + continue; + if(i_check(itr->getSource())) { i_object = itr->getSource(); @@ -347,6 +370,9 @@ void MaNGOS::GameObjectLastSearcher::Visit(GameObjectMapType &m) { for(GameObjectMapType::iterator itr=m.begin(); itr != m.end(); ++itr) { + if(!itr->getSource()->InSamePhase(i_phaseMask)) + continue; + if(i_check(itr->getSource())) i_object = itr->getSource(); } @@ -356,8 +382,9 @@ template void MaNGOS::GameObjectListSearcher::Visit(GameObjectMapType &m) { for(GameObjectMapType::iterator itr=m.begin(); itr != m.end(); ++itr) - if(i_check(itr->getSource())) - i_objects.push_back(itr->getSource()); + if(itr->getSource()->InSamePhase(i_phaseMask)) + if(i_check(itr->getSource())) + i_objects.push_back(itr->getSource()); } // Unit searchers @@ -371,6 +398,9 @@ void MaNGOS::UnitSearcher::Visit(CreatureMapType &m) for(CreatureMapType::iterator itr=m.begin(); itr != m.end(); ++itr) { + if(!itr->getSource()->InSamePhase(i_phaseMask)) + continue; + if(i_check(itr->getSource())) { i_object = itr->getSource(); @@ -388,6 +418,9 @@ void MaNGOS::UnitSearcher::Visit(PlayerMapType &m) for(PlayerMapType::iterator itr=m.begin(); itr != m.end(); ++itr) { + if(!itr->getSource()->InSamePhase(i_phaseMask)) + continue; + if(i_check(itr->getSource())) { i_object = itr->getSource(); @@ -401,6 +434,9 @@ void MaNGOS::UnitLastSearcher::Visit(CreatureMapType &m) { for(CreatureMapType::iterator itr=m.begin(); itr != m.end(); ++itr) { + if(!itr->getSource()->InSamePhase(i_phaseMask)) + continue; + if(i_check(itr->getSource())) i_object = itr->getSource(); } @@ -411,6 +447,9 @@ void MaNGOS::UnitLastSearcher::Visit(PlayerMapType &m) { for(PlayerMapType::iterator itr=m.begin(); itr != m.end(); ++itr) { + if(!itr->getSource()->InSamePhase(i_phaseMask)) + continue; + if(i_check(itr->getSource())) i_object = itr->getSource(); } @@ -420,16 +459,18 @@ template void MaNGOS::UnitListSearcher::Visit(PlayerMapType &m) { for(PlayerMapType::iterator itr=m.begin(); itr != m.end(); ++itr) - if(i_check(itr->getSource())) - i_objects.push_back(itr->getSource()); + if(itr->getSource()->InSamePhase(i_phaseMask)) + if(i_check(itr->getSource())) + i_objects.push_back(itr->getSource()); } template void MaNGOS::UnitListSearcher::Visit(CreatureMapType &m) { for(CreatureMapType::iterator itr=m.begin(); itr != m.end(); ++itr) - if(i_check(itr->getSource())) - i_objects.push_back(itr->getSource()); + if(itr->getSource()->InSamePhase(i_phaseMask)) + if(i_check(itr->getSource())) + i_objects.push_back(itr->getSource()); } // Creature searchers @@ -443,6 +484,9 @@ void MaNGOS::CreatureSearcher::Visit(CreatureMapType &m) for(CreatureMapType::iterator itr=m.begin(); itr != m.end(); ++itr) { + if(!itr->getSource()->InSamePhase(i_phaseMask)) + continue; + if(i_check(itr->getSource())) { i_object = itr->getSource(); @@ -456,6 +500,9 @@ void MaNGOS::CreatureLastSearcher::Visit(CreatureMapType &m) { for(CreatureMapType::iterator itr=m.begin(); itr != m.end(); ++itr) { + if(!itr->getSource()->InSamePhase(i_phaseMask)) + continue; + if(i_check(itr->getSource())) i_object = itr->getSource(); } @@ -465,8 +512,9 @@ template void MaNGOS::CreatureListSearcher::Visit(CreatureMapType &m) { for(CreatureMapType::iterator itr=m.begin(); itr != m.end(); ++itr) - if(i_check(itr->getSource())) - i_objects.push_back(itr->getSource()); + if(itr->getSource()->InSamePhase(i_phaseMask)) + if( i_check(itr->getSource())) + i_objects.push_back(itr->getSource()); } template @@ -478,6 +526,9 @@ void MaNGOS::PlayerSearcher::Visit(PlayerMapType &m) for(PlayerMapType::iterator itr=m.begin(); itr != m.end(); ++itr) { + if(!itr->getSource()->InSamePhase(i_phaseMask)) + continue; + if(i_check(itr->getSource())) { i_object = itr->getSource(); diff --git a/src/game/Level3.cpp b/src/game/Level3.cpp index f018d8b6d..f7c699bac 100644 --- a/src/game/Level3.cpp +++ b/src/game/Level3.cpp @@ -5443,7 +5443,7 @@ bool ChatHandler::HandleRespawnCommand(const char* /*args*/) cell.SetNoCreate(); MaNGOS::RespawnDo u_do; - MaNGOS::WorldObjectWorker worker(u_do); + MaNGOS::WorldObjectWorker worker(pl,u_do); TypeContainerVisitor, GridTypeMapContainer > obj_worker(worker); CellLock cell_lock(cell, p); diff --git a/src/game/Map.cpp b/src/game/Map.cpp index c9acc2151..9244b6d27 100644 --- a/src/game/Map.cpp +++ b/src/game/Map.cpp @@ -507,7 +507,7 @@ void Map::MessageBroadcast(WorldObject *obj, WorldPacket *msg) if( !loaded(GridPair(cell.data.Part.grid_x, cell.data.Part.grid_y)) ) return; - MaNGOS::ObjectMessageDeliverer post_man(msg); + MaNGOS::ObjectMessageDeliverer post_man(*obj,msg); TypeContainerVisitor message(post_man); CellLock cell_lock(cell, p); cell_lock->Visit(cell_lock, message, *this); diff --git a/src/game/Object.cpp b/src/game/Object.cpp index d0be145ce..dbf475e7e 100644 --- a/src/game/Object.cpp +++ b/src/game/Object.cpp @@ -1022,18 +1022,10 @@ bool Object::PrintIndexError(uint32 index, bool set) const } WorldObject::WorldObject() + : m_mapId(0), m_InstanceId(0), m_phaseMask(PHASEMASK_NORMAL), + m_positionX(0.0f), m_positionY(0.0f), m_positionZ(0.0f), m_orientation(0.0f), + mSemaphoreTeleport(false) { - m_positionX = 0.0f; - m_positionY = 0.0f; - m_positionZ = 0.0f; - m_orientation = 0.0f; - - m_mapId = 0; - m_InstanceId = 0; - - m_name = ""; - - mSemaphoreTeleport = false; } void WorldObject::_Create( uint32 guidlow, HighGuid guidhigh, uint32 mapid ) @@ -1317,7 +1309,7 @@ void WorldObject::MonsterSay(int32 textId, uint32 language, uint64 TargetGuid) cell.SetNoCreate(); MaNGOS::MessageChatLocaleCacheDo say_do(*this, CHAT_MSG_MONSTER_SAY, textId,language,TargetGuid,sWorld.getConfig(CONFIG_LISTEN_RANGE_SAY)); - MaNGOS::PlayerWorker say_worker(say_do); + MaNGOS::PlayerWorker say_worker(this,say_do); TypeContainerVisitor, WorldTypeMapContainer > message(say_worker); CellLock cell_lock(cell, p); cell_lock->Visit(cell_lock, message, *GetMap()); @@ -1332,7 +1324,7 @@ void WorldObject::MonsterYell(int32 textId, uint32 language, uint64 TargetGuid) cell.SetNoCreate(); MaNGOS::MessageChatLocaleCacheDo say_do(*this, CHAT_MSG_MONSTER_YELL, textId,language,TargetGuid,sWorld.getConfig(CONFIG_LISTEN_RANGE_YELL)); - MaNGOS::PlayerWorker say_worker(say_do); + MaNGOS::PlayerWorker say_worker(this,say_do); TypeContainerVisitor, WorldTypeMapContainer > message(say_worker); CellLock cell_lock(cell, p); cell_lock->Visit(cell_lock, message, *GetMap()); @@ -1347,7 +1339,7 @@ void WorldObject::MonsterTextEmote(int32 textId, uint64 TargetGuid, bool IsBossE cell.SetNoCreate(); MaNGOS::MessageChatLocaleCacheDo say_do(*this, IsBossEmote ? CHAT_MSG_RAID_BOSS_EMOTE : CHAT_MSG_MONSTER_EMOTE, textId,LANG_UNIVERSAL,TargetGuid,sWorld.getConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE)); - MaNGOS::PlayerWorker say_worker(say_do); + MaNGOS::PlayerWorker say_worker(this,say_do); TypeContainerVisitor, WorldTypeMapContainer > message(say_worker); CellLock cell_lock(cell, p); cell_lock->Visit(cell_lock, message, *GetMap()); @@ -1618,7 +1610,7 @@ void WorldObject::GetNearPoint(WorldObject const* searcher, float &x, float &y, cell.SetNoCreate(); MaNGOS::NearUsedPosDo u_do(*this,searcher,absAngle,selector); - MaNGOS::WorldObjectWorker worker(u_do); + MaNGOS::WorldObjectWorker worker(this,u_do); TypeContainerVisitor, GridTypeMapContainer > grid_obj_worker(worker); TypeContainerVisitor, WorldTypeMapContainer > world_obj_worker(worker); diff --git a/src/game/Object.h b/src/game/Object.h index 587167136..efc638135 100644 --- a/src/game/Object.h +++ b/src/game/Object.h @@ -80,6 +80,12 @@ enum TempSummonType TEMPSUMMON_MANUAL_DESPAWN = 8 // despawns when UnSummon() is called }; +enum PhaseMasks +{ + PHASEMASK_NORMAL = 0x00000001, + PHASEMASK_ANYWHERE = 0xFFFFFFFF +}; + class WorldPacket; class UpdateData; class ByteBuffer; @@ -399,9 +405,13 @@ class MANGOS_DLL_SPEC WorldObject : public Object void GetRandomPoint( float x, float y, float z, float distance, float &rand_x, float &rand_y, float &rand_z ) const; void SetMapId(uint32 newMap) { m_mapId = newMap; } - uint32 GetMapId() const { return m_mapId; } + void SetPhaseMask(uint32 newPhaseMask) { m_phaseMask = newPhaseMask; } + uint32 GetPhaseMask() const { return m_phaseMask; } + bool InSamePhase(WorldObject const* obj) const { return InSamePhase(obj->GetPhaseMask()); } + bool InSamePhase(uint32 phasemask) const { return GetPhaseMask()==0 && phasemask==0 || (GetPhaseMask() & phasemask); } + uint32 GetZoneId() const; uint32 GetAreaId() const; @@ -417,7 +427,11 @@ class MANGOS_DLL_SPEC WorldObject : public Object float GetDistance2d(const WorldObject* obj) const; float GetDistance2d(const float x, const float y) const; float GetDistanceZ(const WorldObject* obj) const; - bool IsInMap(const WorldObject* obj) const { return IsInWorld() && obj->IsInWorld() && GetMapId()==obj->GetMapId() && GetInstanceId()==obj->GetInstanceId(); } + bool IsInMap(const WorldObject* obj) const + { + return IsInWorld() && obj->IsInWorld() && GetMapId()==obj->GetMapId() && + GetInstanceId()==obj->GetInstanceId() && InSamePhase(obj); + } bool IsWithinDistInMap(const WorldObject* obj, const float dist2compare, const bool is3D = true) const; bool IsWithinLOS(const float x, const float y, const float z ) const; bool IsWithinLOSInMap(const WorldObject* obj) const; @@ -467,7 +481,9 @@ class MANGOS_DLL_SPEC WorldObject : public Object std::string m_name; private: - uint32 m_mapId; + uint32 m_mapId; // object at map with map_id + uint32 m_InstanceId; // in map copy with instance id + uint32 m_phaseMask; // in area phase state float m_positionX; float m_positionY; @@ -475,7 +491,5 @@ class MANGOS_DLL_SPEC WorldObject : public Object float m_orientation; bool mSemaphoreTeleport; - - uint32 m_InstanceId; }; #endif diff --git a/src/game/Player.cpp b/src/game/Player.cpp index c8cd91aa3..1e46858e7 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -1984,9 +1984,15 @@ void Player::SetGameMaster(bool on) getHostilRefManager().setOnlineOfflineState(false); CombatStop(); + + SetPhaseMask(PHASEMASK_ANYWHERE); // see and visible in all phases } else { + // restore phase + AuraList const& phases = GetAurasByType(SPELL_AURA_PHASE); + SetPhaseMask(!phases.empty() ? phases.front()->GetMiscValue() : PHASEMASK_NORMAL); + m_ExtraFlags &= ~ PLAYER_EXTRA_GM_ON; setFactionForRace(getRace()); RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_GM); @@ -16894,7 +16900,7 @@ void Player::HandleStealthedUnitsDetection() cell.SetNoCreate(); MaNGOS::AnyStealthedCheck u_check; - MaNGOS::UnitListSearcher searcher(stealthedUnits, u_check); + MaNGOS::UnitListSearcher searcher(this,stealthedUnits, u_check); TypeContainerVisitor, WorldTypeMapContainer > world_unit_searcher(searcher); TypeContainerVisitor, GridTypeMapContainer > grid_unit_searcher(searcher); diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index 61a3477d3..54825b266 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -485,7 +485,7 @@ void Spell::FillTargetMap() WorldObject* result = NULL; MaNGOS::CannibalizeObjectCheck u_check(m_caster, max_range); - MaNGOS::WorldObjectSearcher searcher(result, u_check); + MaNGOS::WorldObjectSearcher searcher(m_caster, result, u_check); TypeContainerVisitor, GridTypeMapContainer > grid_searcher(searcher); CellLock cell_lock(cell, p); @@ -1321,7 +1321,7 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,std::list &TagUnitMap) { MaNGOS::AnyAoETargetUnitInObjectRangeCheck u_check(m_caster, m_caster, max_range); - MaNGOS::UnitListSearcher searcher(tempUnitMap, u_check); + MaNGOS::UnitListSearcher searcher(m_caster, tempUnitMap, u_check); TypeContainerVisitor, WorldTypeMapContainer > world_unit_searcher(searcher); TypeContainerVisitor, GridTypeMapContainer > grid_unit_searcher(searcher); @@ -1390,7 +1390,7 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,std::list &TagUnitMap) std::list tempUnitMap; { MaNGOS::AnyFriendlyUnitInObjectRangeCheck u_check(m_caster, m_caster, max_range); - MaNGOS::UnitListSearcher searcher(tempUnitMap, u_check); + MaNGOS::UnitListSearcher searcher(m_caster, tempUnitMap, u_check); TypeContainerVisitor, WorldTypeMapContainer > world_unit_searcher(searcher); TypeContainerVisitor, GridTypeMapContainer > grid_unit_searcher(searcher); @@ -1487,7 +1487,7 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,std::list &TagUnitMap) { MaNGOS::AnyAoETargetUnitInObjectRangeCheck u_check(pUnitTarget, originalCaster, max_range); - MaNGOS::UnitListSearcher searcher(tempUnitMap, u_check); + MaNGOS::UnitListSearcher searcher(m_caster, tempUnitMap, u_check); TypeContainerVisitor, WorldTypeMapContainer > world_unit_searcher(searcher); TypeContainerVisitor, GridTypeMapContainer > grid_unit_searcher(searcher); @@ -3878,7 +3878,7 @@ uint8 Spell::CanCast(bool strict) cell.data.Part.reserved = ALL_DISTRICT; MaNGOS::NearestGameObjectEntryInObjectRangeCheck go_check(*m_caster,i_spellST->second.targetEntry,range); - MaNGOS::GameObjectLastSearcher checker(p_GameObject,go_check); + MaNGOS::GameObjectLastSearcher checker(m_caster, p_GameObject,go_check); TypeContainerVisitor, GridTypeMapContainer > object_checker(checker); CellLock cell_lock(cell, p); @@ -3916,7 +3916,7 @@ uint8 Spell::CanCast(bool strict) cell.SetNoCreate(); // Really don't know what is that??? MaNGOS::NearestCreatureEntryWithLiveStateInObjectRangeCheck u_check(*m_caster,i_spellST->second.targetEntry,i_spellST->second.type!=SPELL_TARGET_TYPE_DEAD,range); - MaNGOS::CreatureLastSearcher searcher(p_Creature, u_check); + MaNGOS::CreatureLastSearcher searcher(m_caster, p_Creature, u_check); TypeContainerVisitor, GridTypeMapContainer > grid_creature_searcher(searcher); @@ -4969,7 +4969,7 @@ uint8 Spell::CheckItems() GameObject* ok = NULL; MaNGOS::GameObjectFocusCheck go_check(m_caster,m_spellInfo->RequiresSpellFocus); - MaNGOS::GameObjectSearcher checker(ok,go_check); + MaNGOS::GameObjectSearcher checker(m_caster,ok,go_check); TypeContainerVisitor, GridTypeMapContainer > object_checker(checker); CellLock cell_lock(cell, p); diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index 7e183034a..1be74d10d 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -716,7 +716,7 @@ void AreaAura::Update(uint32 diff) cell.SetNoCreate(); MaNGOS::AnyFriendlyUnitInObjectRangeCheck u_check(caster, owner, m_radius); - MaNGOS::UnitListSearcher searcher(targets, u_check); + MaNGOS::UnitListSearcher searcher(caster,targets, u_check); TypeContainerVisitor, WorldTypeMapContainer > world_unit_searcher(searcher); TypeContainerVisitor, GridTypeMapContainer > grid_unit_searcher(searcher); CellLock cell_lock(cell, p); @@ -732,7 +732,7 @@ void AreaAura::Update(uint32 diff) cell.SetNoCreate(); MaNGOS::AnyAoETargetUnitInObjectRangeCheck u_check(caster, owner, m_radius); // No GetCharmer in searcher - MaNGOS::UnitListSearcher searcher(targets, u_check); + MaNGOS::UnitListSearcher searcher(caster, targets, u_check); TypeContainerVisitor, WorldTypeMapContainer > world_unit_searcher(searcher); TypeContainerVisitor, GridTypeMapContainer > grid_unit_searcher(searcher); CellLock cell_lock(cell, p); @@ -6570,22 +6570,36 @@ void Aura::HandleAuraConvertRune(bool apply, bool Real) void Aura::HandlePhase(bool apply, bool Real) { + if(!Real) + return; + + // always non stackable + if(apply) + { + Unit::AuraList const& phases = m_target->GetAurasByType(SPELL_AURA_PHASE); + if(!phases.empty()) + m_target->RemoveAurasDueToSpell(phases.front()->GetId(),this); + } + // no-phase is also phase state so same code for apply and remove - // phase auras normaly not expected at BG but anyway better check - if(Real && m_target->GetTypeId()==TYPEID_PLAYER) + // phase auras normally not expected at BG but anyway better check + if(m_target->GetTypeId()==TYPEID_PLAYER) { // drop flag at invisible in bg if(((Player*)m_target)->InBattleGround()) if(BattleGround *bg = ((Player*)m_target)->GetBattleGround()) bg->EventPlayerDroppedFlag((Player*)m_target); - } - // apply/remove only if not in GM invisibility - if(m_target->GetVisibility()!=VISIBILITY_OFF) - { - // just need triggering visibility update base at aura presence - m_target->SetVisibility(m_target->GetVisibility()); + // GM-mode have mask 0xFFFFFFFF + if(!((Player*)m_target)->isGameMaster()) + m_target->SetPhaseMask(apply ? GetMiscValue() : PHASEMASK_NORMAL); } + else + m_target->SetPhaseMask(apply ? GetMiscValue() : PHASEMASK_NORMAL); + + // need triggering visibility update base at phase update of not GM invisible (other GMs anyway see in any phases) + if(m_target->GetVisibility()!=VISIBILITY_OFF) + m_target->SetVisibility(m_target->GetVisibility()); } diff --git a/src/game/TotemAI.cpp b/src/game/TotemAI.cpp index d86b86a71..e79804313 100644 --- a/src/game/TotemAI.cpp +++ b/src/game/TotemAI.cpp @@ -87,7 +87,7 @@ TotemAI::UpdateAI(const uint32 /*diff*/) victim = NULL; MaNGOS::NearestAttackableUnitInObjectRangeCheck u_check(&i_totem, &i_totem, max_range); - MaNGOS::UnitLastSearcher checker(victim, u_check); + MaNGOS::UnitLastSearcher checker(&i_totem,victim, u_check); TypeContainerVisitor, GridTypeMapContainer > grid_object_checker(checker); TypeContainerVisitor, WorldTypeMapContainer > world_object_checker(checker); diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index ec7cc2643..54381912b 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -3489,6 +3489,7 @@ bool Unit::RemoveNoStackAurasDueToAura(Aura *Aur) return false; uint32 spellId = Aur->GetId(); + uint32 effIndex = Aur->GetEffIndex(); // passive spell special case (only non stackable with ranks) if(IsPassiveSpell(spellId)) @@ -3497,8 +3498,6 @@ bool Unit::RemoveNoStackAurasDueToAura(Aura *Aur) return true; } - uint32 effIndex = Aur->GetEffIndex(); - SpellSpecific spellId_spec = GetSpellSpecific(spellId); AuraMap::iterator i,next; @@ -8741,14 +8740,11 @@ bool Unit::isVisibleForOrDetect(Unit const* u, bool detect, bool inVisibleList, return false; } - AuraList const& thisPhaseList = GetAurasByType (SPELL_AURA_PHASE); - AuraList const& uPhaseList = u->GetAurasByType (SPELL_AURA_PHASE); - // Visible units, always are visible for all units, except for units under invisibility and phases - if (m_Visibility == VISIBILITY_ON && u->m_invisibilityMask==0 && thisPhaseList.empty() && uPhaseList.empty()) + if (m_Visibility == VISIBILITY_ON && u->m_invisibilityMask==0 && InSamePhase(u)) return true; - // GMs see any players, not higher GMs and all units + // GMs see any players, not higher GMs and all units in any phase if (u->GetTypeId() == TYPEID_PLAYER && ((Player *)u)->isGameMaster()) { if(GetTypeId() == TYPEID_PLAYER) @@ -8761,29 +8757,10 @@ bool Unit::isVisibleForOrDetect(Unit const* u, bool detect, bool inVisibleList, if (m_Visibility == VISIBILITY_OFF) return false; - // phased visibility (both must phased or not phased) - if(thisPhaseList.empty() != uPhaseList.empty()) + // phased visibility (both must phased in same way) + if(!InSamePhase(u)) return false; - // phased visibility (in phased state work normal rules but both must have same phase) - if(!thisPhaseList.empty()) - { - bool samePhase = false; - for(AuraList::const_iterator thisItr = thisPhaseList.begin(); thisItr != thisPhaseList.end(); ++thisItr) - { - uint32 thisPhase = (*thisItr)->GetMiscValue(); - for(AuraList::const_iterator uItr = uPhaseList.begin(); uItr != uPhaseList.end(); ++uItr) - { - if((*uItr)->GetMiscValue()==thisPhase) - { - samePhase = true; - break; - } - } - } - if(!samePhase) - return false; - } // raw invisibility bool invisible = (m_invisibilityMask != 0 || u->m_invisibilityMask !=0); @@ -10879,7 +10856,7 @@ Unit* Unit::SelectNearbyTarget() const { MaNGOS::AnyUnfriendlyUnitInObjectRangeCheck u_check(this, this, ATTACK_DISTANCE); - MaNGOS::UnitListSearcher searcher(targets, u_check); + MaNGOS::UnitListSearcher searcher(this, targets, u_check); TypeContainerVisitor, WorldTypeMapContainer > world_unit_searcher(searcher); TypeContainerVisitor, GridTypeMapContainer > grid_unit_searcher(searcher); diff --git a/src/game/World.cpp b/src/game/World.cpp index 83379eb94..621239791 100644 --- a/src/game/World.cpp +++ b/src/game/World.cpp @@ -1954,7 +1954,7 @@ void World::ScriptsProcess() cell.data.Part.reserved = ALL_DISTRICT; MaNGOS::GameObjectWithDbGUIDCheck go_check(*summoner,step.script->datalong); - MaNGOS::GameObjectSearcher checker(go,go_check); + MaNGOS::GameObjectSearcher checker(summoner, go,go_check); TypeContainerVisitor, GridTypeMapContainer > object_checker(checker); CellLock cell_lock(cell, p); @@ -2015,7 +2015,7 @@ void World::ScriptsProcess() cell.data.Part.reserved = ALL_DISTRICT; MaNGOS::GameObjectWithDbGUIDCheck go_check(*caster,step.script->datalong); - MaNGOS::GameObjectSearcher checker(door,go_check); + MaNGOS::GameObjectSearcher checker(caster,door,go_check); TypeContainerVisitor, GridTypeMapContainer > object_checker(checker); CellLock cell_lock(cell, p); @@ -2071,7 +2071,7 @@ void World::ScriptsProcess() cell.data.Part.reserved = ALL_DISTRICT; MaNGOS::GameObjectWithDbGUIDCheck go_check(*caster,step.script->datalong); - MaNGOS::GameObjectSearcher checker(door,go_check); + MaNGOS::GameObjectSearcher checker(caster,door,go_check); TypeContainerVisitor, GridTypeMapContainer > object_checker(checker); CellLock cell_lock(cell, p);