2 * Copyright (C) 2005-2010 MaNGOS <http://getmangos.com/>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 #ifndef MANGOS_GRIDNOTIFIERSIMPL_H
20 #define MANGOS_GRIDNOTIFIERSIMPL_H
22 #include "GridNotifiers.h"
23 #include "WorldPacket.h"
26 #include "UpdateData.h"
27 #include "CreatureAI.h"
28 #include "SpellAuras.h"
32 MaNGOS::VisibleNotifier::Visit(GridRefManager
<T
> &m
)
34 WorldObject
const* viewPoint
= i_player
.GetViewPoint();
36 for(typename GridRefManager
<T
>::iterator iter
= m
.begin(); iter
!= m
.end(); ++iter
)
38 i_player
.UpdateVisibilityOf(viewPoint
,iter
->getSource(),i_data
,i_data_updates
,i_visibleNow
);
39 i_clientGUIDs
.erase(iter
->getSource()->GetGUID());
44 MaNGOS::ObjectUpdater::Visit(CreatureMapType
&m
)
46 for(CreatureMapType::iterator iter
=m
.begin(); iter
!= m
.end(); ++iter
)
47 iter
->getSource()->Update(i_timeDiff
);
51 MaNGOS::PlayerRelocationNotifier::Visit(PlayerMapType
&m
)
53 for(PlayerMapType::iterator iter
=m
.begin(); iter
!= m
.end(); ++iter
)
55 if(&i_player
==iter
->getSource())
58 // visibility for players updated by ObjectAccessor::UpdateVisibilityFor calls in appropriate places
61 if(i_player
.GetTrader()==iter
->getSource())
62 // iteraction distance
63 if(!i_player
.IsWithinDistInMap(iter
->getSource(), 5))
64 i_player
.GetSession()->SendCancelTrade(); // will clode both side trade windows
68 inline void PlayerCreatureRelocationWorker(Player
* pl
, WorldObject
const* viewPoint
, Creature
* c
)
70 // update creature visibility at player/creature move
71 pl
->UpdateVisibilityOf(viewPoint
,c
);
73 // Creature AI reaction
74 if(!c
->hasUnitState(UNIT_STAT_FLEEING
))
76 if( c
->AI() && c
->AI()->IsVisible(pl
) && !c
->IsInEvadeMode() )
77 c
->AI()->MoveInLineOfSight(pl
);
81 inline void CreatureCreatureRelocationWorker(Creature
* c1
, Creature
* c2
)
83 if(!c1
->hasUnitState(UNIT_STAT_FLEEING
))
85 if( c1
->AI() && c1
->AI()->IsVisible(c2
) && !c1
->IsInEvadeMode() )
86 c1
->AI()->MoveInLineOfSight(c2
);
89 if(!c2
->hasUnitState(UNIT_STAT_FLEEING
))
91 if( c2
->AI() && c2
->AI()->IsVisible(c1
) && !c2
->IsInEvadeMode() )
92 c2
->AI()->MoveInLineOfSight(c1
);
97 MaNGOS::PlayerRelocationNotifier::Visit(CreatureMapType
&m
)
99 if(!i_player
.isAlive() || i_player
.isInFlight())
102 WorldObject
const* viewPoint
= i_player
.GetViewPoint();
104 for(CreatureMapType::iterator iter
=m
.begin(); iter
!= m
.end(); ++iter
)
105 if (iter
->getSource()->isAlive())
106 PlayerCreatureRelocationWorker(&i_player
,viewPoint
,iter
->getSource());
111 MaNGOS::CreatureRelocationNotifier::Visit(PlayerMapType
&m
)
113 if(!i_creature
.isAlive())
116 for(PlayerMapType::iterator iter
=m
.begin(); iter
!= m
.end(); ++iter
)
117 if (Player
* player
= iter
->getSource())
118 if (player
->isAlive() && !player
->isInFlight())
119 PlayerCreatureRelocationWorker(player
, player
->GetViewPoint(), &i_creature
);
124 MaNGOS::CreatureRelocationNotifier::Visit(CreatureMapType
&m
)
126 if(!i_creature
.isAlive())
129 for(CreatureMapType::iterator iter
=m
.begin(); iter
!= m
.end(); ++iter
)
131 Creature
* c
= iter
->getSource();
132 if( c
!= &i_creature
&& c
->isAlive())
133 CreatureCreatureRelocationWorker(c
, &i_creature
);
137 inline void MaNGOS::DynamicObjectUpdater::VisitHelper(Unit
* target
)
139 if(!target
->isAlive() || target
->isInFlight() )
142 if(target
->GetTypeId()==TYPEID_UNIT
&& ((Creature
*)target
)->isTotem())
145 if (!i_dynobject
.IsWithinDistInMap(target
, i_dynobject
.GetRadius()))
148 //Check targets for not_selectable unit flag and remove
149 if (target
->HasFlag(UNIT_FIELD_FLAGS
, UNIT_FLAG_NON_ATTACKABLE
| UNIT_FLAG_NOT_SELECTABLE
))
153 if( target
->GetTypeId()==TYPEID_UNIT
&& ((Creature
*)target
)->IsInEvadeMode() )
156 //Check player targets and remove if in GM mode or GM invisibility (for not self casting case)
157 if( target
->GetTypeId()==TYPEID_PLAYER
&& target
!= i_check
&& (((Player
*)target
)->isGameMaster() || ((Player
*)target
)->GetVisibility()==VISIBILITY_OFF
) )
160 if (i_check
->GetTypeId()==TYPEID_PLAYER
)
162 if (i_check
->IsFriendlyTo( target
))
167 if (!i_check
->IsHostileTo( target
))
171 if (i_dynobject
.IsAffecting(target
))
174 SpellEntry
const *spellInfo
= sSpellStore
.LookupEntry(i_dynobject
.GetSpellId());
175 uint32 eff_index
= i_dynobject
.GetEffIndex();
176 // Check target immune to spell or aura
177 if (target
->IsImmunedToSpell(spellInfo
) || target
->IsImmunedToSpellEffect(spellInfo
, eff_index
))
179 // Apply PersistentAreaAura on target
180 PersistentAreaAura
* Aur
= new PersistentAreaAura(spellInfo
, eff_index
, NULL
, target
, i_dynobject
.GetCaster());
181 target
->AddAura(Aur
);
182 i_dynobject
.AddAffected(target
);
187 MaNGOS::DynamicObjectUpdater::Visit(CreatureMapType
&m
)
189 for(CreatureMapType::iterator itr
=m
.begin(); itr
!= m
.end(); ++itr
)
190 VisitHelper(itr
->getSource());
195 MaNGOS::DynamicObjectUpdater::Visit(PlayerMapType
&m
)
197 for(PlayerMapType::iterator itr
=m
.begin(); itr
!= m
.end(); ++itr
)
198 VisitHelper(itr
->getSource());
201 // SEARCHERS & LIST SEARCHERS & WORKERS
203 // WorldObject searchers & workers
205 template<class Check
>
206 void MaNGOS::WorldObjectSearcher
<Check
>::Visit(GameObjectMapType
&m
)
212 for(GameObjectMapType::iterator itr
=m
.begin(); itr
!= m
.end(); ++itr
)
214 if(!itr
->getSource()->InSamePhase(i_phaseMask
))
217 if (i_check(itr
->getSource()))
219 i_object
= itr
->getSource();
225 template<class Check
>
226 void MaNGOS::WorldObjectSearcher
<Check
>::Visit(PlayerMapType
&m
)
232 for(PlayerMapType::iterator itr
=m
.begin(); itr
!= m
.end(); ++itr
)
234 if(!itr
->getSource()->InSamePhase(i_phaseMask
))
237 if(i_check(itr
->getSource()))
239 i_object
= itr
->getSource();
245 template<class Check
>
246 void MaNGOS::WorldObjectSearcher
<Check
>::Visit(CreatureMapType
&m
)
252 for(CreatureMapType::iterator itr
=m
.begin(); itr
!= m
.end(); ++itr
)
254 if(!itr
->getSource()->InSamePhase(i_phaseMask
))
257 if(i_check(itr
->getSource()))
259 i_object
= itr
->getSource();
265 template<class Check
>
266 void MaNGOS::WorldObjectSearcher
<Check
>::Visit(CorpseMapType
&m
)
272 for(CorpseMapType::iterator itr
=m
.begin(); itr
!= m
.end(); ++itr
)
274 if(!itr
->getSource()->InSamePhase(i_phaseMask
))
277 if(i_check(itr
->getSource()))
279 i_object
= itr
->getSource();
285 template<class Check
>
286 void MaNGOS::WorldObjectSearcher
<Check
>::Visit(DynamicObjectMapType
&m
)
292 for(DynamicObjectMapType::iterator itr
=m
.begin(); itr
!= m
.end(); ++itr
)
294 if(!itr
->getSource()->InSamePhase(i_phaseMask
))
297 if(i_check(itr
->getSource()))
299 i_object
= itr
->getSource();
305 template<class Check
>
306 void MaNGOS::WorldObjectListSearcher
<Check
>::Visit(PlayerMapType
&m
)
308 for(PlayerMapType::iterator itr
=m
.begin(); itr
!= m
.end(); ++itr
)
309 if(itr
->getSource()->InSamePhase(i_phaseMask
))
310 if(i_check(itr
->getSource()))
311 i_objects
.push_back(itr
->getSource());
314 template<class Check
>
315 void MaNGOS::WorldObjectListSearcher
<Check
>::Visit(CreatureMapType
&m
)
317 for(CreatureMapType::iterator itr
=m
.begin(); itr
!= m
.end(); ++itr
)
318 if(itr
->getSource()->InSamePhase(i_phaseMask
))
319 if(i_check(itr
->getSource()))
320 i_objects
.push_back(itr
->getSource());
323 template<class Check
>
324 void MaNGOS::WorldObjectListSearcher
<Check
>::Visit(CorpseMapType
&m
)
326 for(CorpseMapType::iterator itr
=m
.begin(); itr
!= m
.end(); ++itr
)
327 if(itr
->getSource()->InSamePhase(i_phaseMask
))
328 if(i_check(itr
->getSource()))
329 i_objects
.push_back(itr
->getSource());
332 template<class Check
>
333 void MaNGOS::WorldObjectListSearcher
<Check
>::Visit(GameObjectMapType
&m
)
335 for(GameObjectMapType::iterator itr
=m
.begin(); itr
!= m
.end(); ++itr
)
336 if(itr
->getSource()->InSamePhase(i_phaseMask
))
337 if(i_check(itr
->getSource()))
338 i_objects
.push_back(itr
->getSource());
341 template<class Check
>
342 void MaNGOS::WorldObjectListSearcher
<Check
>::Visit(DynamicObjectMapType
&m
)
344 for(DynamicObjectMapType::iterator itr
=m
.begin(); itr
!= m
.end(); ++itr
)
345 if(itr
->getSource()->InSamePhase(i_phaseMask
))
346 if(i_check(itr
->getSource()))
347 i_objects
.push_back(itr
->getSource());
350 // Gameobject searchers
352 template<class Check
>
353 void MaNGOS::GameObjectSearcher
<Check
>::Visit(GameObjectMapType
&m
)
359 for(GameObjectMapType::iterator itr
=m
.begin(); itr
!= m
.end(); ++itr
)
361 if(!itr
->getSource()->InSamePhase(i_phaseMask
))
364 if(i_check(itr
->getSource()))
366 i_object
= itr
->getSource();
372 template<class Check
>
373 void MaNGOS::GameObjectLastSearcher
<Check
>::Visit(GameObjectMapType
&m
)
375 for(GameObjectMapType::iterator itr
=m
.begin(); itr
!= m
.end(); ++itr
)
377 if(!itr
->getSource()->InSamePhase(i_phaseMask
))
380 if(i_check(itr
->getSource()))
381 i_object
= itr
->getSource();
385 template<class Check
>
386 void MaNGOS::GameObjectListSearcher
<Check
>::Visit(GameObjectMapType
&m
)
388 for(GameObjectMapType::iterator itr
=m
.begin(); itr
!= m
.end(); ++itr
)
389 if(itr
->getSource()->InSamePhase(i_phaseMask
))
390 if(i_check(itr
->getSource()))
391 i_objects
.push_back(itr
->getSource());
396 template<class Check
>
397 void MaNGOS::UnitSearcher
<Check
>::Visit(CreatureMapType
&m
)
403 for(CreatureMapType::iterator itr
=m
.begin(); itr
!= m
.end(); ++itr
)
405 if(!itr
->getSource()->InSamePhase(i_phaseMask
))
408 if(i_check(itr
->getSource()))
410 i_object
= itr
->getSource();
416 template<class Check
>
417 void MaNGOS::UnitSearcher
<Check
>::Visit(PlayerMapType
&m
)
423 for(PlayerMapType::iterator itr
=m
.begin(); itr
!= m
.end(); ++itr
)
425 if(!itr
->getSource()->InSamePhase(i_phaseMask
))
428 if(i_check(itr
->getSource()))
430 i_object
= itr
->getSource();
436 template<class Check
>
437 void MaNGOS::UnitLastSearcher
<Check
>::Visit(CreatureMapType
&m
)
439 for(CreatureMapType::iterator itr
=m
.begin(); itr
!= m
.end(); ++itr
)
441 if(!itr
->getSource()->InSamePhase(i_phaseMask
))
444 if(i_check(itr
->getSource()))
445 i_object
= itr
->getSource();
449 template<class Check
>
450 void MaNGOS::UnitLastSearcher
<Check
>::Visit(PlayerMapType
&m
)
452 for(PlayerMapType::iterator itr
=m
.begin(); itr
!= m
.end(); ++itr
)
454 if(!itr
->getSource()->InSamePhase(i_phaseMask
))
457 if(i_check(itr
->getSource()))
458 i_object
= itr
->getSource();
462 template<class Check
>
463 void MaNGOS::UnitListSearcher
<Check
>::Visit(PlayerMapType
&m
)
465 for(PlayerMapType::iterator itr
=m
.begin(); itr
!= m
.end(); ++itr
)
466 if(itr
->getSource()->InSamePhase(i_phaseMask
))
467 if(i_check(itr
->getSource()))
468 i_objects
.push_back(itr
->getSource());
471 template<class Check
>
472 void MaNGOS::UnitListSearcher
<Check
>::Visit(CreatureMapType
&m
)
474 for(CreatureMapType::iterator itr
=m
.begin(); itr
!= m
.end(); ++itr
)
475 if(itr
->getSource()->InSamePhase(i_phaseMask
))
476 if(i_check(itr
->getSource()))
477 i_objects
.push_back(itr
->getSource());
480 // Creature searchers
482 template<class Check
>
483 void MaNGOS::CreatureSearcher
<Check
>::Visit(CreatureMapType
&m
)
489 for(CreatureMapType::iterator itr
=m
.begin(); itr
!= m
.end(); ++itr
)
491 if(!itr
->getSource()->InSamePhase(i_phaseMask
))
494 if(i_check(itr
->getSource()))
496 i_object
= itr
->getSource();
502 template<class Check
>
503 void MaNGOS::CreatureLastSearcher
<Check
>::Visit(CreatureMapType
&m
)
505 for(CreatureMapType::iterator itr
=m
.begin(); itr
!= m
.end(); ++itr
)
507 if(!itr
->getSource()->InSamePhase(i_phaseMask
))
510 if(i_check(itr
->getSource()))
511 i_object
= itr
->getSource();
515 template<class Check
>
516 void MaNGOS::CreatureListSearcher
<Check
>::Visit(CreatureMapType
&m
)
518 for(CreatureMapType::iterator itr
=m
.begin(); itr
!= m
.end(); ++itr
)
519 if(itr
->getSource()->InSamePhase(i_phaseMask
))
520 if( i_check(itr
->getSource()))
521 i_objects
.push_back(itr
->getSource());
524 template<class Check
>
525 void MaNGOS::PlayerSearcher
<Check
>::Visit(PlayerMapType
&m
)
531 for(PlayerMapType::iterator itr
=m
.begin(); itr
!= m
.end(); ++itr
)
533 if(!itr
->getSource()->InSamePhase(i_phaseMask
))
536 if(i_check(itr
->getSource()))
538 i_object
= itr
->getSource();
544 template<class Builder
>
545 void MaNGOS::LocalizedPacketDo
<Builder
>::operator()( Player
* p
)
547 int32 loc_idx
= p
->GetSession()->GetSessionDbLocaleIndex();
548 uint32 cache_idx
= loc_idx
+1;
551 // create if not cached yet
552 if(i_data_cache
.size() < cache_idx
+1 || !i_data_cache
[cache_idx
])
554 if(i_data_cache
.size() < cache_idx
+1)
555 i_data_cache
.resize(cache_idx
+1);
557 data
= new WorldPacket(SMSG_MESSAGECHAT
, 200);
559 i_builder(*data
,loc_idx
);
561 i_data_cache
[cache_idx
] = data
;
564 data
= i_data_cache
[cache_idx
];
566 p
->SendDirectMessage(data
);
569 template<class Builder
>
570 void MaNGOS::LocalizedPacketListDo
<Builder
>::operator()( Player
* p
)
572 int32 loc_idx
= p
->GetSession()->GetSessionDbLocaleIndex();
573 uint32 cache_idx
= loc_idx
+1;
574 WorldPacketList
* data_list
;
576 // create if not cached yet
577 if(i_data_cache
.size() < cache_idx
+1 || i_data_cache
[cache_idx
].empty())
579 if(i_data_cache
.size() < cache_idx
+1)
580 i_data_cache
.resize(cache_idx
+1);
582 data_list
= &i_data_cache
[cache_idx
];
584 i_builder(*data_list
,loc_idx
);
587 data_list
= &i_data_cache
[cache_idx
];
589 for(size_t i
= 0; i
< data_list
->size(); ++i
)
590 p
->SendDirectMessage((*data_list
)[i
]);
593 #endif // MANGOS_GRIDNOTIFIERSIMPL_H