diff options
Diffstat (limited to 'src/game/GridNotifiersImpl.h')
-rw-r--r-- | src/game/GridNotifiersImpl.h | 112 |
1 files changed, 112 insertions, 0 deletions
diff --git a/src/game/GridNotifiersImpl.h b/src/game/GridNotifiersImpl.h index a8e0116a7cf..d9e27cc8bcc 100644 --- a/src/game/GridNotifiersImpl.h +++ b/src/game/GridNotifiersImpl.h @@ -17,8 +17,10 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + #ifndef TRINITY_GRIDNOTIFIERSIMPL_H #define TRINITY_GRIDNOTIFIERSIMPL_H + #include "GridNotifiers.h" #include "WorldPacket.h" #include "Corpse.h" @@ -26,6 +28,7 @@ #include "UpdateData.h" #include "CreatureAI.h" #include "SpellAuras.h" + inline void Trinity::ObjectUpdater::Visit(CreatureMapType &m) { @@ -33,24 +36,29 @@ Trinity::ObjectUpdater::Visit(CreatureMapType &m) if(iter->getSource()->IsInWorld() && !iter->getSource()->isSpiritService()) iter->getSource()->Update(i_timeDiff); } + inline void PlayerCreatureRelocationWorker(Player* pl, Creature* c) { if(!pl->isAlive() || !c->isAlive() || pl->isInFlight()) return; + // Creature AI reaction if(c->HasReactState(REACT_AGGRESSIVE) && !c->hasUnitState(UNIT_STAT_SIGHTLESS)) if(c->_IsWithinDist(pl, c->m_SightDistance, true) && c->IsAIEnabled) c->AI()->MoveInLineOfSight(pl); } + inline void CreatureCreatureRelocationWorker(Creature* c1, Creature* c2) { if(c1->HasReactState(REACT_AGGRESSIVE) && !c1->hasUnitState(UNIT_STAT_SIGHTLESS)) if(c1->_IsWithinDist(c2, c1->m_SightDistance, true) && c1->IsAIEnabled) c1->AI()->MoveInLineOfSight(c2); + if(c2->HasReactState(REACT_AGGRESSIVE) && !c2->hasUnitState(UNIT_STAT_SIGHTLESS)) if(c1->_IsWithinDist(c2, c2->m_SightDistance, true) && c2->IsAIEnabled) c2->AI()->MoveInLineOfSight(c1); } + template<class T> inline void Trinity::PlayerVisibilityNotifier::Visit(GridRefManager<T> &m) @@ -61,6 +69,7 @@ Trinity::PlayerVisibilityNotifier::Visit(GridRefManager<T> &m) i_clientGUIDs.erase(iter->getSource()->GetGUID()); } } + template<> inline void Trinity::PlayerRelocationNotifier::Visit(PlayerMapType &m) @@ -68,19 +77,24 @@ Trinity::PlayerRelocationNotifier::Visit(PlayerMapType &m) for(PlayerMapType::iterator iter = m.begin(); iter != m.end(); ++iter) { i_clientGUIDs.erase(iter->getSource()->GetGUID()); + if(iter->getSource()->m_Notified) //self is also skipped in this check continue; + i_player.UpdateVisibilityOf(iter->getSource(),i_data,i_visibleNow); iter->getSource()->UpdateVisibilityOf(&i_player); + //if (!i_player.GetSharedVisionList().empty()) // for (SharedVisionList::const_iterator it = i_player.GetSharedVisionList().begin(); it != i_player.GetSharedVisionList().end(); ++it) // (*it)->UpdateVisibilityOf(iter->getSource()); + // Cancel Trade if(i_player.GetTrader()==iter->getSource()) if(!i_player.IsWithinDistInMap(iter->getSource(), 5)) // iteraction distance i_player.GetSession()->SendCancelTrade(); // will clode both side trade windows } } + template<> inline void Trinity::PlayerRelocationNotifier::Visit(CreatureMapType &m) @@ -88,12 +102,16 @@ Trinity::PlayerRelocationNotifier::Visit(CreatureMapType &m) for(CreatureMapType::iterator iter = m.begin(); iter != m.end(); ++iter) { i_clientGUIDs.erase(iter->getSource()->GetGUID()); + if(iter->getSource()->m_Notified) continue; + i_player.UpdateVisibilityOf(iter->getSource(),i_data,i_visibleNow); + PlayerCreatureRelocationWorker(&i_player, iter->getSource()); } } + template<> inline void Trinity::CreatureRelocationNotifier::Visit(PlayerMapType &m) @@ -102,53 +120,70 @@ Trinity::CreatureRelocationNotifier::Visit(PlayerMapType &m) { if(iter->getSource()->m_Notified) continue; + iter->getSource()->UpdateVisibilityOf(&i_creature); + PlayerCreatureRelocationWorker(iter->getSource(), &i_creature); } } + template<> inline void Trinity::CreatureRelocationNotifier::Visit(CreatureMapType &m) { if(!i_creature.isAlive()) return; + for(CreatureMapType::iterator iter = m.begin(); iter != m.end(); ++iter) { if(iter->getSource()->m_Notified) continue; + if(!iter->getSource()->isAlive()) continue; + CreatureCreatureRelocationWorker(iter->getSource(), &i_creature); } } + inline void Trinity::DynamicObjectUpdater::VisitHelper(Unit* target) { if(!target->isAlive() || target->isInFlight() ) return; + if(target->GetTypeId()==TYPEID_UNIT && ((Creature*)target)->isTotem()) return; + if (!i_dynobject.IsWithinDistInMap(target, i_dynobject.GetRadius())) return; + //Check targets for not_selectable unit flag and remove if (target->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE)) return; + // Evade target if( target->GetTypeId()==TYPEID_UNIT && ((Creature*)target)->IsInEvadeMode() ) return; + //Check player targets and remove if in GM mode or GM invisibility (for not self casting case) if( target->GetTypeId()==TYPEID_PLAYER && target != i_check && (((Player*)target)->isGameMaster() || ((Player*)target)->GetVisibility()==VISIBILITY_OFF) ) return; + if (i_dynobject.IsAffecting(target)) return; + if(target->HasAura(i_dynobject.GetSpellId(), i_check->GetGUID())) return; + uint32 eff_index = 0; for(; eff_index < MAX_SPELL_EFFECTS; ++eff_index) if(i_dynobject.HasEffect(eff_index)) break; + if(eff_index == MAX_SPELL_EFFECTS) return; + SpellEntry const *spellInfo = sSpellStore.LookupEntry(i_dynobject.GetSpellId()); if(spellInfo->EffectImplicitTargetB[eff_index] == TARGET_DEST_DYNOBJ_ALLY || spellInfo->EffectImplicitTargetB[eff_index] == TARGET_UNIT_AREA_ALLY_DST) @@ -160,23 +195,28 @@ inline void Trinity::DynamicObjectUpdater::VisitHelper(Unit* target) { if (i_check->IsFriendlyTo( target )) return; + i_check->CombatStart(target); } else { if (!i_check->IsHostileTo( target )) return; + i_check->CombatStart(target); } + // Check target immune to spell or aura if (target->IsImmunedToSpell(spellInfo) || target->IsImmunedToSpellEffect(spellInfo, eff_index)) return; + // Apply PersistentAreaAura on target Aura *aur = new Aura(spellInfo, i_dynobject.GetEffectMask(), target, &i_dynobject, i_check); aur->SetAuraDuration(i_dynobject.GetDuration()); if(target->AddAura(aur, true)) i_dynobject.AddAffected(target); } + template<> inline void Trinity::DynamicObjectUpdater::Visit(CreatureMapType &m) @@ -184,6 +224,7 @@ Trinity::DynamicObjectUpdater::Visit(CreatureMapType &m) for(CreatureMapType::iterator itr=m.begin(); itr != m.end(); ++itr) VisitHelper(itr->getSource()); } + template<> inline void Trinity::DynamicObjectUpdater::Visit(PlayerMapType &m) @@ -191,18 +232,23 @@ Trinity::DynamicObjectUpdater::Visit(PlayerMapType &m) for(PlayerMapType::iterator itr=m.begin(); itr != m.end(); ++itr) VisitHelper(itr->getSource()); } + // SEARCHERS & LIST SEARCHERS & WORKERS + // WorldObject searchers & workers + template<class Check> void Trinity::WorldObjectSearcher<Check>::Visit(GameObjectMapType &m) { // already found if(i_object) return; + 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(); @@ -210,16 +256,19 @@ void Trinity::WorldObjectSearcher<Check>::Visit(GameObjectMapType &m) } } } + template<class Check> void Trinity::WorldObjectSearcher<Check>::Visit(PlayerMapType &m) { // already found if(i_object) return; + 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(); @@ -227,16 +276,19 @@ void Trinity::WorldObjectSearcher<Check>::Visit(PlayerMapType &m) } } } + template<class Check> void Trinity::WorldObjectSearcher<Check>::Visit(CreatureMapType &m) { // already found if(i_object) return; + 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(); @@ -244,16 +296,19 @@ void Trinity::WorldObjectSearcher<Check>::Visit(CreatureMapType &m) } } } + template<class Check> void Trinity::WorldObjectSearcher<Check>::Visit(CorpseMapType &m) { // already found if(i_object) return; + 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(); @@ -261,16 +316,19 @@ void Trinity::WorldObjectSearcher<Check>::Visit(CorpseMapType &m) } } } + template<class Check> void Trinity::WorldObjectSearcher<Check>::Visit(DynamicObjectMapType &m) { // already found if(i_object) return; + 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(); @@ -278,6 +336,7 @@ void Trinity::WorldObjectSearcher<Check>::Visit(DynamicObjectMapType &m) } } } + template<class Check> void Trinity::WorldObjectListSearcher<Check>::Visit(PlayerMapType &m) { @@ -286,6 +345,7 @@ void Trinity::WorldObjectListSearcher<Check>::Visit(PlayerMapType &m) if(i_check(itr->getSource())) i_objects.push_back(itr->getSource()); } + template<class Check> void Trinity::WorldObjectListSearcher<Check>::Visit(CreatureMapType &m) { @@ -294,6 +354,7 @@ void Trinity::WorldObjectListSearcher<Check>::Visit(CreatureMapType &m) if(i_check(itr->getSource())) i_objects.push_back(itr->getSource()); } + template<class Check> void Trinity::WorldObjectListSearcher<Check>::Visit(CorpseMapType &m) { @@ -302,6 +363,7 @@ void Trinity::WorldObjectListSearcher<Check>::Visit(CorpseMapType &m) if(i_check(itr->getSource())) i_objects.push_back(itr->getSource()); } + template<class Check> void Trinity::WorldObjectListSearcher<Check>::Visit(GameObjectMapType &m) { @@ -310,6 +372,7 @@ void Trinity::WorldObjectListSearcher<Check>::Visit(GameObjectMapType &m) if(i_check(itr->getSource())) i_objects.push_back(itr->getSource()); } + template<class Check> void Trinity::WorldObjectListSearcher<Check>::Visit(DynamicObjectMapType &m) { @@ -318,17 +381,21 @@ void Trinity::WorldObjectListSearcher<Check>::Visit(DynamicObjectMapType &m) if(i_check(itr->getSource())) i_objects.push_back(itr->getSource()); } + // Gameobject searchers + template<class Check> void Trinity::GameObjectSearcher<Check>::Visit(GameObjectMapType &m) { // already found if(i_object) return; + 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(); @@ -336,6 +403,7 @@ void Trinity::GameObjectSearcher<Check>::Visit(GameObjectMapType &m) } } } + template<class Check> void Trinity::GameObjectLastSearcher<Check>::Visit(GameObjectMapType &m) { @@ -343,10 +411,12 @@ void Trinity::GameObjectLastSearcher<Check>::Visit(GameObjectMapType &m) { if(!itr->getSource()->InSamePhase(i_phaseMask)) continue; + if(i_check(itr->getSource())) i_object = itr->getSource(); } } + template<class Check> void Trinity::GameObjectListSearcher<Check>::Visit(GameObjectMapType &m) { @@ -355,17 +425,21 @@ void Trinity::GameObjectListSearcher<Check>::Visit(GameObjectMapType &m) if(i_check(itr->getSource())) i_objects.push_back(itr->getSource()); } + // Unit searchers + template<class Check> void Trinity::UnitSearcher<Check>::Visit(CreatureMapType &m) { // already found if(i_object) return; + 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(); @@ -373,16 +447,19 @@ void Trinity::UnitSearcher<Check>::Visit(CreatureMapType &m) } } } + template<class Check> void Trinity::UnitSearcher<Check>::Visit(PlayerMapType &m) { // already found if(i_object) return; + 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(); @@ -390,6 +467,7 @@ void Trinity::UnitSearcher<Check>::Visit(PlayerMapType &m) } } } + template<class Check> void Trinity::UnitLastSearcher<Check>::Visit(CreatureMapType &m) { @@ -397,10 +475,12 @@ void Trinity::UnitLastSearcher<Check>::Visit(CreatureMapType &m) { if(!itr->getSource()->InSamePhase(i_phaseMask)) continue; + if(i_check(itr->getSource())) i_object = itr->getSource(); } } + template<class Check> void Trinity::UnitLastSearcher<Check>::Visit(PlayerMapType &m) { @@ -408,10 +488,12 @@ void Trinity::UnitLastSearcher<Check>::Visit(PlayerMapType &m) { if(!itr->getSource()->InSamePhase(i_phaseMask)) continue; + if(i_check(itr->getSource())) i_object = itr->getSource(); } } + template<class Check> void Trinity::UnitListSearcher<Check>::Visit(PlayerMapType &m) { @@ -420,6 +502,7 @@ void Trinity::UnitListSearcher<Check>::Visit(PlayerMapType &m) if(i_check(itr->getSource())) i_objects.push_back(itr->getSource()); } + template<class Check> void Trinity::UnitListSearcher<Check>::Visit(CreatureMapType &m) { @@ -428,17 +511,21 @@ void Trinity::UnitListSearcher<Check>::Visit(CreatureMapType &m) if(i_check(itr->getSource())) i_objects.push_back(itr->getSource()); } + // Creature searchers + template<class Check> void Trinity::CreatureSearcher<Check>::Visit(CreatureMapType &m) { // already found if(i_object) return; + 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(); @@ -446,6 +533,7 @@ void Trinity::CreatureSearcher<Check>::Visit(CreatureMapType &m) } } } + template<class Check> void Trinity::CreatureLastSearcher<Check>::Visit(CreatureMapType &m) { @@ -453,10 +541,12 @@ void Trinity::CreatureLastSearcher<Check>::Visit(CreatureMapType &m) { if(!itr->getSource()->InSamePhase(i_phaseMask)) continue; + if(i_check(itr->getSource())) i_object = itr->getSource(); } } + template<class Check> void Trinity::CreatureListSearcher<Check>::Visit(CreatureMapType &m) { @@ -465,6 +555,7 @@ void Trinity::CreatureListSearcher<Check>::Visit(CreatureMapType &m) if( i_check(itr->getSource())) i_objects.push_back(itr->getSource()); } + template<class Check> void Trinity::PlayerListSearcher<Check>::Visit(PlayerMapType &m) { @@ -473,16 +564,19 @@ void Trinity::PlayerListSearcher<Check>::Visit(PlayerMapType &m) if( i_check(itr->getSource())) i_objects.push_back(itr->getSource()); } + template<class Check> void Trinity::PlayerSearcher<Check>::Visit(PlayerMapType &m) { // already found if(i_object) return; + 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(); @@ -490,60 +584,78 @@ void Trinity::PlayerSearcher<Check>::Visit(PlayerMapType &m) } } } + template<class Builder> void MaNGOS::LocalizedPacketDo<Builder>::operator()( Player* p ) { int32 loc_idx = p->GetSession()->GetSessionDbLocaleIndex(); uint32 cache_idx = loc_idx+1; WorldPacket* data; + // create if not cached yet if(i_data_cache.size() < cache_idx+1 || !i_data_cache[cache_idx]) { if(i_data_cache.size() < cache_idx+1) i_data_cache.resize(cache_idx+1); + data = new WorldPacket(SMSG_MESSAGECHAT, 200); + i_builder(*data,loc_idx); + i_data_cache[cache_idx] = data; } else data = i_data_cache[cache_idx]; + p->SendDirectMessage(data); } + template<class Builder> void MaNGOS::LocalizedPacketListDo<Builder>::operator()( Player* p ) { int32 loc_idx = p->GetSession()->GetSessionDbLocaleIndex(); uint32 cache_idx = loc_idx+1; WorldPacketList* data_list; + // create if not cached yet if(i_data_cache.size() < cache_idx+1 || i_data_cache[cache_idx].empty()) { if(i_data_cache.size() < cache_idx+1) i_data_cache.resize(cache_idx+1); + data_list = &i_data_cache[cache_idx]; + i_builder(*data_list,loc_idx); } else data_list = &i_data_cache[cache_idx]; + for(size_t i = 0; i < data_list->size(); ++i) p->SendDirectMessage((*data_list)[i]); } + struct ObjectDistanceOrder : public std::binary_function<const WorldObject, const WorldObject, bool> { const Unit* m_pSource; + ObjectDistanceOrder(const Unit* pSource) : m_pSource(pSource) {}; + bool operator()(const WorldObject* pLeft, const WorldObject* pRight) const { return m_pSource->GetDistanceOrder(pLeft, pRight); } }; + struct ObjectDistanceOrderReversed : public std::binary_function<const WorldObject, const WorldObject, bool> { const Unit* m_pSource; + ObjectDistanceOrderReversed(const Unit* pSource) : m_pSource(pSource) {}; + bool operator()(const WorldObject* pLeft, const WorldObject* pRight) const { return !m_pSource->GetDistanceOrder(pLeft, pRight); } }; + #endif // MANGOS_GRIDNOTIFIERSIMPL_H |