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"
33 MaNGOS::VisibleNotifier::Visit(GridRefManager
<T
> &m
)
35 WorldObject
const* viewPoint
= i_player
.GetViewPoint();
37 for(typename GridRefManager
<T
>::iterator iter
= m
.begin(); iter
!= m
.end(); ++iter
)
39 i_player
.UpdateVisibilityOf(viewPoint
,iter
->getSource(),i_data
,i_data_updates
,i_visibleNow
);
40 i_clientGUIDs
.erase(iter
->getSource()->GetGUID());
45 MaNGOS::ObjectUpdater::Visit(CreatureMapType
&m
)
47 for(CreatureMapType::iterator iter
=m
.begin(); iter
!= m
.end(); ++iter
)
48 iter
->getSource()->Update(i_timeDiff
);
52 MaNGOS::PlayerRelocationNotifier::Visit(PlayerMapType
&m
)
54 for(PlayerMapType::iterator iter
=m
.begin(); iter
!= m
.end(); ++iter
)
56 if(&i_player
==iter
->getSource())
59 // visibility for players updated by ObjectAccessor::UpdateVisibilityFor calls in appropriate places
62 if(i_player
.GetTrader()==iter
->getSource())
63 // iteraction distance
64 if(!i_player
.IsWithinDistInMap(iter
->getSource(), 5))
65 i_player
.GetSession()->SendCancelTrade(); // will clode both side trade windows
69 inline void PlayerCreatureRelocationWorker(Player
* pl
, WorldObject
const* viewPoint
, Creature
* c
)
71 // update creature visibility at player/creature move
72 pl
->UpdateVisibilityOf(viewPoint
,c
);
74 // Creature AI reaction
75 if(!c
->hasUnitState(UNIT_STAT_FLEEING
))
77 if( c
->AI() && c
->AI()->IsVisible(pl
) && !c
->IsInEvadeMode() )
78 c
->AI()->MoveInLineOfSight(pl
);
82 inline void CreatureCreatureRelocationWorker(Creature
* c1
, Creature
* c2
)
84 if(!c1
->hasUnitState(UNIT_STAT_FLEEING
))
86 if( c1
->AI() && c1
->AI()->IsVisible(c2
) && !c1
->IsInEvadeMode() )
87 c1
->AI()->MoveInLineOfSight(c2
);
90 if(!c2
->hasUnitState(UNIT_STAT_FLEEING
))
92 if( c2
->AI() && c2
->AI()->IsVisible(c1
) && !c2
->IsInEvadeMode() )
93 c2
->AI()->MoveInLineOfSight(c1
);
98 MaNGOS::PlayerRelocationNotifier::Visit(CreatureMapType
&m
)
100 if(!i_player
.isAlive() || i_player
.isInFlight())
103 WorldObject
const* viewPoint
= i_player
.GetViewPoint();
105 for(CreatureMapType::iterator iter
=m
.begin(); iter
!= m
.end(); ++iter
)
106 if (iter
->getSource()->isAlive())
107 PlayerCreatureRelocationWorker(&i_player
,viewPoint
,iter
->getSource());
112 MaNGOS::CreatureRelocationNotifier::Visit(PlayerMapType
&m
)
114 if(!i_creature
.isAlive())
117 for(PlayerMapType::iterator iter
=m
.begin(); iter
!= m
.end(); ++iter
)
118 if (Player
* player
= iter
->getSource())
119 if (player
->isAlive() && !player
->isInFlight())
120 PlayerCreatureRelocationWorker(player
, player
->GetViewPoint(), &i_creature
);
125 MaNGOS::CreatureRelocationNotifier::Visit(CreatureMapType
&m
)
127 if(!i_creature
.isAlive())
130 for(CreatureMapType::iterator iter
=m
.begin(); iter
!= m
.end(); ++iter
)
132 Creature
* c
= iter
->getSource();
133 if( c
!= &i_creature
&& c
->isAlive())
134 CreatureCreatureRelocationWorker(c
, &i_creature
);
138 inline void MaNGOS::DynamicObjectUpdater::VisitHelper(Unit
* target
)
140 if(!target
->isAlive() || target
->isInFlight() )
143 if(target
->GetTypeId()==TYPEID_UNIT
&& ((Creature
*)target
)->isTotem())
146 if (!i_dynobject
.IsWithinDistInMap(target
, i_dynobject
.GetRadius()))
149 //Check targets for not_selectable unit flag and remove
150 if (target
->HasFlag(UNIT_FIELD_FLAGS
, UNIT_FLAG_NON_ATTACKABLE
| UNIT_FLAG_NOT_SELECTABLE
))
154 if( target
->GetTypeId()==TYPEID_UNIT
&& ((Creature
*)target
)->IsInEvadeMode() )
157 //Check player targets and remove if in GM mode or GM invisibility (for not self casting case)
158 if( target
->GetTypeId()==TYPEID_PLAYER
&& target
!= i_check
&& (((Player
*)target
)->isGameMaster() || ((Player
*)target
)->GetVisibility()==VISIBILITY_OFF
) )
161 if (i_check
->GetTypeId()==TYPEID_PLAYER
)
163 if (i_check
->IsFriendlyTo( target
))
168 if (!i_check
->IsHostileTo( target
))
172 if (i_dynobject
.IsAffecting(target
))
175 SpellEntry
const *spellInfo
= sSpellStore
.LookupEntry(i_dynobject
.GetSpellId());
176 SpellEffectIndex eff_index
= i_dynobject
.GetEffIndex();
177 // Check target immune to spell or aura
178 if (target
->IsImmunedToSpell(spellInfo
) || target
->IsImmunedToSpellEffect(spellInfo
, eff_index
))
180 // Apply PersistentAreaAura on target
181 PersistentAreaAura
* Aur
= new PersistentAreaAura(spellInfo
, eff_index
, NULL
, target
, i_dynobject
.GetCaster());
182 target
->AddAura(Aur
);
183 i_dynobject
.AddAffected(target
);
188 MaNGOS::DynamicObjectUpdater::Visit(CreatureMapType
&m
)
190 for(CreatureMapType::iterator itr
=m
.begin(); itr
!= m
.end(); ++itr
)
191 VisitHelper(itr
->getSource());
196 MaNGOS::DynamicObjectUpdater::Visit(PlayerMapType
&m
)
198 for(PlayerMapType::iterator itr
=m
.begin(); itr
!= m
.end(); ++itr
)
199 VisitHelper(itr
->getSource());
202 // SEARCHERS & LIST SEARCHERS & WORKERS
204 // WorldObject searchers & workers
206 template<class Check
>
207 void MaNGOS::WorldObjectSearcher
<Check
>::Visit(GameObjectMapType
&m
)
213 for(GameObjectMapType::iterator itr
=m
.begin(); itr
!= m
.end(); ++itr
)
215 if(!itr
->getSource()->InSamePhase(i_phaseMask
))
218 if (i_check(itr
->getSource()))
220 i_object
= itr
->getSource();
226 template<class Check
>
227 void MaNGOS::WorldObjectSearcher
<Check
>::Visit(PlayerMapType
&m
)
233 for(PlayerMapType::iterator itr
=m
.begin(); itr
!= m
.end(); ++itr
)
235 if(!itr
->getSource()->InSamePhase(i_phaseMask
))
238 if(i_check(itr
->getSource()))
240 i_object
= itr
->getSource();
246 template<class Check
>
247 void MaNGOS::WorldObjectSearcher
<Check
>::Visit(CreatureMapType
&m
)
253 for(CreatureMapType::iterator itr
=m
.begin(); itr
!= m
.end(); ++itr
)
255 if(!itr
->getSource()->InSamePhase(i_phaseMask
))
258 if(i_check(itr
->getSource()))
260 i_object
= itr
->getSource();
266 template<class Check
>
267 void MaNGOS::WorldObjectSearcher
<Check
>::Visit(CorpseMapType
&m
)
273 for(CorpseMapType::iterator itr
=m
.begin(); itr
!= m
.end(); ++itr
)
275 if(!itr
->getSource()->InSamePhase(i_phaseMask
))
278 if(i_check(itr
->getSource()))
280 i_object
= itr
->getSource();
286 template<class Check
>
287 void MaNGOS::WorldObjectSearcher
<Check
>::Visit(DynamicObjectMapType
&m
)
293 for(DynamicObjectMapType::iterator itr
=m
.begin(); itr
!= m
.end(); ++itr
)
295 if(!itr
->getSource()->InSamePhase(i_phaseMask
))
298 if(i_check(itr
->getSource()))
300 i_object
= itr
->getSource();
306 template<class Check
>
307 void MaNGOS::WorldObjectListSearcher
<Check
>::Visit(PlayerMapType
&m
)
309 for(PlayerMapType::iterator itr
=m
.begin(); itr
!= m
.end(); ++itr
)
310 if(itr
->getSource()->InSamePhase(i_phaseMask
))
311 if(i_check(itr
->getSource()))
312 i_objects
.push_back(itr
->getSource());
315 template<class Check
>
316 void MaNGOS::WorldObjectListSearcher
<Check
>::Visit(CreatureMapType
&m
)
318 for(CreatureMapType::iterator itr
=m
.begin(); itr
!= m
.end(); ++itr
)
319 if(itr
->getSource()->InSamePhase(i_phaseMask
))
320 if(i_check(itr
->getSource()))
321 i_objects
.push_back(itr
->getSource());
324 template<class Check
>
325 void MaNGOS::WorldObjectListSearcher
<Check
>::Visit(CorpseMapType
&m
)
327 for(CorpseMapType::iterator itr
=m
.begin(); itr
!= m
.end(); ++itr
)
328 if(itr
->getSource()->InSamePhase(i_phaseMask
))
329 if(i_check(itr
->getSource()))
330 i_objects
.push_back(itr
->getSource());
333 template<class Check
>
334 void MaNGOS::WorldObjectListSearcher
<Check
>::Visit(GameObjectMapType
&m
)
336 for(GameObjectMapType::iterator itr
=m
.begin(); itr
!= m
.end(); ++itr
)
337 if(itr
->getSource()->InSamePhase(i_phaseMask
))
338 if(i_check(itr
->getSource()))
339 i_objects
.push_back(itr
->getSource());
342 template<class Check
>
343 void MaNGOS::WorldObjectListSearcher
<Check
>::Visit(DynamicObjectMapType
&m
)
345 for(DynamicObjectMapType::iterator itr
=m
.begin(); itr
!= m
.end(); ++itr
)
346 if(itr
->getSource()->InSamePhase(i_phaseMask
))
347 if(i_check(itr
->getSource()))
348 i_objects
.push_back(itr
->getSource());
351 // Gameobject searchers
353 template<class Check
>
354 void MaNGOS::GameObjectSearcher
<Check
>::Visit(GameObjectMapType
&m
)
360 for(GameObjectMapType::iterator itr
=m
.begin(); itr
!= m
.end(); ++itr
)
362 if(!itr
->getSource()->InSamePhase(i_phaseMask
))
365 if(i_check(itr
->getSource()))
367 i_object
= itr
->getSource();
373 template<class Check
>
374 void MaNGOS::GameObjectLastSearcher
<Check
>::Visit(GameObjectMapType
&m
)
376 for(GameObjectMapType::iterator itr
=m
.begin(); itr
!= m
.end(); ++itr
)
378 if(!itr
->getSource()->InSamePhase(i_phaseMask
))
381 if(i_check(itr
->getSource()))
382 i_object
= itr
->getSource();
386 template<class Check
>
387 void MaNGOS::GameObjectListSearcher
<Check
>::Visit(GameObjectMapType
&m
)
389 for(GameObjectMapType::iterator itr
=m
.begin(); itr
!= m
.end(); ++itr
)
390 if(itr
->getSource()->InSamePhase(i_phaseMask
))
391 if(i_check(itr
->getSource()))
392 i_objects
.push_back(itr
->getSource());
397 template<class Check
>
398 void MaNGOS::UnitSearcher
<Check
>::Visit(CreatureMapType
&m
)
404 for(CreatureMapType::iterator itr
=m
.begin(); itr
!= m
.end(); ++itr
)
406 if(!itr
->getSource()->InSamePhase(i_phaseMask
))
409 if(i_check(itr
->getSource()))
411 i_object
= itr
->getSource();
417 template<class Check
>
418 void MaNGOS::UnitSearcher
<Check
>::Visit(PlayerMapType
&m
)
424 for(PlayerMapType::iterator itr
=m
.begin(); itr
!= m
.end(); ++itr
)
426 if(!itr
->getSource()->InSamePhase(i_phaseMask
))
429 if(i_check(itr
->getSource()))
431 i_object
= itr
->getSource();
437 template<class Check
>
438 void MaNGOS::UnitLastSearcher
<Check
>::Visit(CreatureMapType
&m
)
440 for(CreatureMapType::iterator itr
=m
.begin(); itr
!= m
.end(); ++itr
)
442 if(!itr
->getSource()->InSamePhase(i_phaseMask
))
445 if(i_check(itr
->getSource()))
446 i_object
= itr
->getSource();
450 template<class Check
>
451 void MaNGOS::UnitLastSearcher
<Check
>::Visit(PlayerMapType
&m
)
453 for(PlayerMapType::iterator itr
=m
.begin(); itr
!= m
.end(); ++itr
)
455 if(!itr
->getSource()->InSamePhase(i_phaseMask
))
458 if(i_check(itr
->getSource()))
459 i_object
= itr
->getSource();
463 template<class Check
>
464 void MaNGOS::UnitListSearcher
<Check
>::Visit(PlayerMapType
&m
)
466 for(PlayerMapType::iterator itr
=m
.begin(); itr
!= m
.end(); ++itr
)
467 if(itr
->getSource()->InSamePhase(i_phaseMask
))
468 if(i_check(itr
->getSource()))
469 i_objects
.push_back(itr
->getSource());
472 template<class Check
>
473 void MaNGOS::UnitListSearcher
<Check
>::Visit(CreatureMapType
&m
)
475 for(CreatureMapType::iterator itr
=m
.begin(); itr
!= m
.end(); ++itr
)
476 if(itr
->getSource()->InSamePhase(i_phaseMask
))
477 if(i_check(itr
->getSource()))
478 i_objects
.push_back(itr
->getSource());
481 // Creature searchers
483 template<class Check
>
484 void MaNGOS::CreatureSearcher
<Check
>::Visit(CreatureMapType
&m
)
490 for(CreatureMapType::iterator itr
=m
.begin(); itr
!= m
.end(); ++itr
)
492 if(!itr
->getSource()->InSamePhase(i_phaseMask
))
495 if(i_check(itr
->getSource()))
497 i_object
= itr
->getSource();
503 template<class Check
>
504 void MaNGOS::CreatureLastSearcher
<Check
>::Visit(CreatureMapType
&m
)
506 for(CreatureMapType::iterator itr
=m
.begin(); itr
!= m
.end(); ++itr
)
508 if(!itr
->getSource()->InSamePhase(i_phaseMask
))
511 if(i_check(itr
->getSource()))
512 i_object
= itr
->getSource();
516 template<class Check
>
517 void MaNGOS::CreatureListSearcher
<Check
>::Visit(CreatureMapType
&m
)
519 for(CreatureMapType::iterator itr
=m
.begin(); itr
!= m
.end(); ++itr
)
520 if(itr
->getSource()->InSamePhase(i_phaseMask
))
521 if( i_check(itr
->getSource()))
522 i_objects
.push_back(itr
->getSource());
525 template<class Check
>
526 void MaNGOS::PlayerSearcher
<Check
>::Visit(PlayerMapType
&m
)
532 for(PlayerMapType::iterator itr
=m
.begin(); itr
!= m
.end(); ++itr
)
534 if(!itr
->getSource()->InSamePhase(i_phaseMask
))
537 if(i_check(itr
->getSource()))
539 i_object
= itr
->getSource();
545 template<class Builder
>
546 void MaNGOS::LocalizedPacketDo
<Builder
>::operator()( Player
* p
)
548 int32 loc_idx
= p
->GetSession()->GetSessionDbLocaleIndex();
549 uint32 cache_idx
= loc_idx
+1;
552 // create if not cached yet
553 if(i_data_cache
.size() < cache_idx
+1 || !i_data_cache
[cache_idx
])
555 if(i_data_cache
.size() < cache_idx
+1)
556 i_data_cache
.resize(cache_idx
+1);
558 data
= new WorldPacket(SMSG_MESSAGECHAT
, 200);
560 i_builder(*data
,loc_idx
);
562 i_data_cache
[cache_idx
] = data
;
565 data
= i_data_cache
[cache_idx
];
567 p
->SendDirectMessage(data
);
570 template<class Builder
>
571 void MaNGOS::LocalizedPacketListDo
<Builder
>::operator()( Player
* p
)
573 int32 loc_idx
= p
->GetSession()->GetSessionDbLocaleIndex();
574 uint32 cache_idx
= loc_idx
+1;
575 WorldPacketList
* data_list
;
577 // create if not cached yet
578 if(i_data_cache
.size() < cache_idx
+1 || i_data_cache
[cache_idx
].empty())
580 if(i_data_cache
.size() < cache_idx
+1)
581 i_data_cache
.resize(cache_idx
+1);
583 data_list
= &i_data_cache
[cache_idx
];
585 i_builder(*data_list
,loc_idx
);
588 data_list
= &i_data_cache
[cache_idx
];
590 for(size_t i
= 0; i
< data_list
->size(); ++i
)
591 p
->SendDirectMessage((*data_list
)[i
]);
594 #endif // MANGOS_GRIDNOTIFIERSIMPL_H