2 * Copyright (C) 2005-2009 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 #include "GameEventMgr.h"
21 #include "ObjectMgr.h"
22 #include "PoolHandler.h"
23 #include "ProgressBar.h"
26 #include "MapManager.h"
27 #include "Policies/SingletonImp.h"
29 INSTANTIATE_SINGLETON_1(GameEventMgr
);
31 bool GameEventMgr::CheckOneGameEvent(uint16 entry
) const
33 // Get the event information
34 time_t currenttime
= time(NULL
);
35 if( mGameEvent
[entry
].start
< currenttime
&& currenttime
< mGameEvent
[entry
].end
&&
36 ((currenttime
- mGameEvent
[entry
].start
) % (mGameEvent
[entry
].occurence
* MINUTE
)) < (mGameEvent
[entry
].length
* MINUTE
) )
42 uint32
GameEventMgr::NextCheck(uint16 entry
) const
44 time_t currenttime
= time(NULL
);
46 // outdated event: we return max
47 if (currenttime
> mGameEvent
[entry
].end
)
48 return max_ge_check_delay
;
50 // never started event, we return delay before start
51 if (mGameEvent
[entry
].start
> currenttime
)
52 return (mGameEvent
[entry
].start
- currenttime
);
55 // in event, we return the end of it
56 if ((((currenttime
- mGameEvent
[entry
].start
) % (mGameEvent
[entry
].occurence
* 60)) < (mGameEvent
[entry
].length
* 60)))
57 // we return the delay before it ends
58 delay
= (mGameEvent
[entry
].length
* MINUTE
) - ((currenttime
- mGameEvent
[entry
].start
) % (mGameEvent
[entry
].occurence
* MINUTE
));
59 else // not in window, we return the delay before next start
60 delay
= (mGameEvent
[entry
].occurence
* MINUTE
) - ((currenttime
- mGameEvent
[entry
].start
) % (mGameEvent
[entry
].occurence
* MINUTE
));
61 // In case the end is before next check
62 if (mGameEvent
[entry
].end
< time_t(currenttime
+ delay
))
63 return (mGameEvent
[entry
].end
- currenttime
);
68 void GameEventMgr::StartEvent( uint16 event_id
, bool overwrite
)
70 AddActiveEvent(event_id
);
71 ApplyNewEvent(event_id
);
74 mGameEvent
[event_id
].start
= time(NULL
);
75 if(mGameEvent
[event_id
].end
<= mGameEvent
[event_id
].start
)
76 mGameEvent
[event_id
].end
= mGameEvent
[event_id
].start
+mGameEvent
[event_id
].length
;
80 void GameEventMgr::StopEvent( uint16 event_id
, bool overwrite
)
82 RemoveActiveEvent(event_id
);
83 UnApplyEvent(event_id
);
86 mGameEvent
[event_id
].start
= time(NULL
) - mGameEvent
[event_id
].length
* MINUTE
;
87 if(mGameEvent
[event_id
].end
<= mGameEvent
[event_id
].start
)
88 mGameEvent
[event_id
].end
= mGameEvent
[event_id
].start
+mGameEvent
[event_id
].length
;
92 void GameEventMgr::LoadFromDB()
95 QueryResult
*result
= WorldDatabase
.Query("SELECT MAX(entry) FROM game_event");
98 sLog
.outString(">> Table game_event is empty.");
103 Field
*fields
= result
->Fetch();
105 uint32 max_event_id
= fields
[0].GetUInt16();
108 mGameEvent
.resize(max_event_id
+1);
111 QueryResult
*result
= WorldDatabase
.Query("SELECT entry,UNIX_TIMESTAMP(start_time),UNIX_TIMESTAMP(end_time),occurence,length,holiday,description FROM game_event");
115 sLog
.outString(">> Table game_event is empty!");
123 barGoLink
bar( result
->GetRowCount() );
127 Field
*fields
= result
->Fetch();
131 uint16 event_id
= fields
[0].GetUInt16();
134 sLog
.outErrorDb("`game_event` game event id (%i) is reserved and can't be used.",event_id
);
138 GameEventData
& pGameEvent
= mGameEvent
[event_id
];
139 uint64 starttime
= fields
[1].GetUInt64();
140 pGameEvent
.start
= time_t(starttime
);
141 uint64 endtime
= fields
[2].GetUInt64();
142 pGameEvent
.end
= time_t(endtime
);
143 pGameEvent
.occurence
= fields
[3].GetUInt32();
144 pGameEvent
.length
= fields
[4].GetUInt32();
145 pGameEvent
.holiday_id
= fields
[5].GetUInt32();
148 if(pGameEvent
.length
==0) // length>0 is validity check
150 sLog
.outErrorDb("`game_event` game event id (%i) have length 0 and can't be used.",event_id
);
154 if(pGameEvent
.holiday_id
)
156 if(!sHolidaysStore
.LookupEntry(pGameEvent
.holiday_id
))
158 sLog
.outErrorDb("`game_event` game event id (%i) have not existed holiday id %u.",event_id
,pGameEvent
.holiday_id
);
159 pGameEvent
.holiday_id
= 0;
163 pGameEvent
.description
= fields
[6].GetCppString();
165 } while( result
->NextRow() );
169 sLog
.outString( ">> Loaded %u game events", count
);
172 mGameEventCreatureGuids
.resize(mGameEvent
.size()*2-1);
174 result
= WorldDatabase
.Query("SELECT creature.guid, game_event_creature.event "
175 "FROM creature JOIN game_event_creature ON creature.guid = game_event_creature.guid");
184 sLog
.outString(">> Loaded %u creatures in game events", count
);
189 barGoLink
bar( result
->GetRowCount() );
192 Field
*fields
= result
->Fetch();
196 uint32 guid
= fields
[0].GetUInt32();
197 int16 event_id
= fields
[1].GetInt16();
199 int32 internal_event_id
= mGameEvent
.size() + event_id
- 1;
201 if(internal_event_id
< 0 || internal_event_id
>= mGameEventCreatureGuids
.size())
203 sLog
.outErrorDb("`game_event_creature` game event id (%i) is out of range compared to max event id in `game_event`",event_id
);
208 GuidList
& crelist
= mGameEventCreatureGuids
[internal_event_id
];
209 crelist
.push_back(guid
);
211 } while( result
->NextRow() );
215 sLog
.outString( ">> Loaded %u creatures in game events", count
);
218 mGameEventGameobjectGuids
.resize(mGameEvent
.size()*2-1);
220 result
= WorldDatabase
.Query("SELECT gameobject.guid, game_event_gameobject.event "
221 "FROM gameobject JOIN game_event_gameobject ON gameobject.guid=game_event_gameobject.guid");
230 sLog
.outString(">> Loaded %u gameobjects in game events", count
);
235 barGoLink
bar( result
->GetRowCount() );
238 Field
*fields
= result
->Fetch();
242 uint32 guid
= fields
[0].GetUInt32();
243 int16 event_id
= fields
[1].GetInt16();
245 int32 internal_event_id
= mGameEvent
.size() + event_id
- 1;
247 if(internal_event_id
< 0 || internal_event_id
>= mGameEventGameobjectGuids
.size())
249 sLog
.outErrorDb("`game_event_gameobject` game event id (%i) is out of range compared to max event id in `game_event`",event_id
);
254 GuidList
& golist
= mGameEventGameobjectGuids
[internal_event_id
];
255 golist
.push_back(guid
);
257 } while( result
->NextRow() );
261 sLog
.outString( ">> Loaded %u gameobjects in game events", count
);
264 mGameEventModelEquip
.resize(mGameEvent
.size());
266 result
= WorldDatabase
.Query("SELECT creature.guid, game_event_model_equip.event, game_event_model_equip.modelid,"
268 "game_event_model_equip.equipment_id "
269 "FROM creature JOIN game_event_model_equip ON creature.guid=game_event_model_equip.guid");
278 sLog
.outString(">> Loaded %u model/equipment changes in game events", count
);
283 barGoLink
bar( result
->GetRowCount() );
286 Field
*fields
= result
->Fetch();
289 uint32 guid
= fields
[0].GetUInt32();
290 uint16 event_id
= fields
[1].GetUInt16();
292 if(event_id
>= mGameEventModelEquip
.size())
294 sLog
.outErrorDb("`game_event_model_equip` game event id (%u) is out of range compared to max event id in `game_event`",event_id
);
299 ModelEquipList
& equiplist
= mGameEventModelEquip
[event_id
];
300 ModelEquip newModelEquipSet
;
301 newModelEquipSet
.modelid
= fields
[2].GetUInt32();
302 newModelEquipSet
.equipment_id
= fields
[3].GetUInt32();
303 newModelEquipSet
.equipement_id_prev
= 0;
304 newModelEquipSet
.modelid_prev
= 0;
306 if(newModelEquipSet
.equipment_id
> 0)
308 if(!objmgr
.GetEquipmentInfo(newModelEquipSet
.equipment_id
))
310 sLog
.outErrorDb("Table `game_event_model_equip` have creature (Guid: %u) with equipment_id %u not found in table `creature_equip_template`, set to no equipment.", guid
, newModelEquipSet
.equipment_id
);
315 equiplist
.push_back(std::pair
<uint32
, ModelEquip
>(guid
, newModelEquipSet
));
317 } while( result
->NextRow() );
321 sLog
.outString( ">> Loaded %u model/equipment changes in game events", count
);
324 mGameEventQuests
.resize(mGameEvent
.size());
326 result
= WorldDatabase
.Query("SELECT id, quest, event FROM game_event_creature_quest");
335 sLog
.outString(">> Loaded %u quests additions in game events", count
);
340 barGoLink
bar( result
->GetRowCount() );
343 Field
*fields
= result
->Fetch();
346 uint32 id
= fields
[0].GetUInt32();
347 uint32 quest
= fields
[1].GetUInt32();
348 uint16 event_id
= fields
[2].GetUInt16();
350 if(event_id
>= mGameEventQuests
.size())
352 sLog
.outErrorDb("`game_event_creature_quest` game event id (%u) is out of range compared to max event id in `game_event`",event_id
);
357 QuestRelList
& questlist
= mGameEventQuests
[event_id
];
358 questlist
.push_back(QuestRelation(id
, quest
));
360 } while( result
->NextRow() );
364 sLog
.outString( ">> Loaded %u quests additions in game events", count
);
367 mGameEventPoolIds
.resize(mGameEvent
.size()*2-1);
369 result
= WorldDatabase
.Query("SELECT pool_template.entry, game_event_pool.event "
370 "FROM pool_template JOIN game_event_pool ON pool_template.entry = game_event_pool.pool_entry");
379 sLog
.outString(">> Loaded %u pools in game events", count
);
384 barGoLink
bar2( result
->GetRowCount() );
387 Field
*fields
= result
->Fetch();
391 uint32 entry
= fields
[0].GetUInt16();
392 int16 event_id
= fields
[1].GetInt16();
394 int32 internal_event_id
= mGameEvent
.size() + event_id
- 1;
396 if(internal_event_id
< 0 || internal_event_id
>= mGameEventPoolIds
.size())
398 sLog
.outErrorDb("`game_event_pool` game event id (%i) is out of range compared to max event id in `game_event`",event_id
);
402 if (!poolhandler
.CheckPool(entry
))
404 sLog
.outErrorDb("Pool Id (%u) has all creatures or gameobjects with explicit chance sum <>100 and no equal chance defined. The pool system cannot pick one to spawn.", entry
);
409 IdList
& poollist
= mGameEventPoolIds
[internal_event_id
];
410 poollist
.push_back(entry
);
412 } while( result
->NextRow() );
414 sLog
.outString( ">> Loaded %u pools in game events", count
);
419 uint32
GameEventMgr::Initialize() // return the next event delay in ms
421 m_ActiveEvents
.clear();
422 uint32 delay
= Update();
423 sLog
.outBasic("Game Event system initialized." );
428 uint32
GameEventMgr::Update() // return the next event delay in ms
430 uint32 nextEventDelay
= max_ge_check_delay
; // 1 day
432 for (uint16 itr
= 1; itr
< mGameEvent
.size(); ++itr
)
434 //sLog.outErrorDb("Checking event %u",itr);
435 if (CheckOneGameEvent(itr
))
437 //sLog.outDebug("GameEvent %u is active",itr->first);
438 if (!IsActiveEvent(itr
))
443 //sLog.outDebug("GameEvent %u is not active",itr->first);
444 if (IsActiveEvent(itr
))
450 int16 event_nid
= (-1) * (itr
);
451 // spawn all negative ones for this event
452 GameEventSpawn(event_nid
);
456 calcDelay
= NextCheck(itr
);
457 if (calcDelay
< nextEventDelay
)
458 nextEventDelay
= calcDelay
;
460 sLog
.outBasic("Next game event check in %u seconds.", nextEventDelay
+ 1);
461 return (nextEventDelay
+ 1) * IN_MILISECONDS
; // Add 1 second to be sure event has started/stopped at next call
464 void GameEventMgr::UnApplyEvent(uint16 event_id
)
466 sLog
.outString("GameEvent %u \"%s\" removed.", event_id
, mGameEvent
[event_id
].description
.c_str());
467 // un-spawn positive event tagged objects
468 GameEventUnspawn(event_id
);
469 // spawn negative event tagget objects
470 int16 event_nid
= (-1) * event_id
;
471 GameEventSpawn(event_nid
);
472 // restore equipment or model
473 ChangeEquipOrModel(event_id
, false);
474 // Remove quests that are events only to non event npc
475 UpdateEventQuests(event_id
, false);
478 void GameEventMgr::ApplyNewEvent(uint16 event_id
)
480 switch(sWorld
.getConfig(CONFIG_EVENT_ANNOUNCE
))
484 case 1: // announce events
485 sWorld
.SendWorldText(LANG_EVENTMESSAGE
, mGameEvent
[event_id
].description
.c_str());
489 sLog
.outString("GameEvent %u \"%s\" started.", event_id
, mGameEvent
[event_id
].description
.c_str());
490 // spawn positive event tagget objects
491 GameEventSpawn(event_id
);
492 // un-spawn negative event tagged objects
493 int16 event_nid
= (-1) * event_id
;
494 GameEventUnspawn(event_nid
);
495 // Change equipement or model
496 ChangeEquipOrModel(event_id
, true);
497 // Add quests that are events only to non event npc
498 UpdateEventQuests(event_id
, true);
501 void GameEventMgr::GameEventSpawn(int16 event_id
)
503 int32 internal_event_id
= mGameEvent
.size() + event_id
- 1;
505 if(internal_event_id
< 0 || internal_event_id
>= mGameEventCreatureGuids
.size())
507 sLog
.outError("GameEventMgr::GameEventSpawn attempt access to out of range mGameEventCreatureGuids element %i (size: %u)",internal_event_id
,mGameEventCreatureGuids
.size());
511 for (GuidList::iterator itr
= mGameEventCreatureGuids
[internal_event_id
].begin();itr
!= mGameEventCreatureGuids
[internal_event_id
].end();++itr
)
513 // Add to correct cell
514 CreatureData
const* data
= objmgr
.GetCreatureData(*itr
);
517 objmgr
.AddCreatureToGrid(*itr
, data
);
519 // Spawn if necessary (loaded grids only)
520 Map
* map
= const_cast<Map
*>(MapManager::Instance().GetBaseMap(data
->mapid
));
521 // We use spawn coords to spawn
522 if(!map
->Instanceable() && !map
->IsRemovalGrid(data
->posX
,data
->posY
))
524 Creature
* pCreature
= new Creature
;
525 //sLog.outDebug("Spawning creature %u",*itr);
526 if (!pCreature
->LoadFromDB(*itr
, map
))
538 if(internal_event_id
< 0 || internal_event_id
>= mGameEventGameobjectGuids
.size())
540 sLog
.outError("GameEventMgr::GameEventSpawn attempt access to out of range mGameEventGameobjectGuids element %i (size: %u)",internal_event_id
,mGameEventGameobjectGuids
.size());
544 for (GuidList::iterator itr
= mGameEventGameobjectGuids
[internal_event_id
].begin();itr
!= mGameEventGameobjectGuids
[internal_event_id
].end();++itr
)
546 // Add to correct cell
547 GameObjectData
const* data
= objmgr
.GetGOData(*itr
);
550 objmgr
.AddGameobjectToGrid(*itr
, data
);
551 // Spawn if necessary (loaded grids only)
552 // this base map checked as non-instanced and then only existed
553 Map
* map
= const_cast<Map
*>(MapManager::Instance().GetBaseMap(data
->mapid
));
554 // We use current coords to unspawn, not spawn coords since creature can have changed grid
555 if(!map
->Instanceable() && !map
->IsRemovalGrid(data
->posX
, data
->posY
))
557 GameObject
* pGameobject
= new GameObject
;
558 //sLog.outDebug("Spawning gameobject %u", *itr);
559 if (!pGameobject
->LoadFromDB(*itr
, map
))
565 if(pGameobject
->isSpawnedByDefault())
566 map
->Add(pGameobject
);
572 if(internal_event_id
< 0 || internal_event_id
>= mGameEventPoolIds
.size())
574 sLog
.outError("GameEventMgr::GameEventSpawn attempt access to out of range mGameEventPoolIds element %i (size: %u)",internal_event_id
,mGameEventPoolIds
.size());
578 for (IdList::iterator itr
= mGameEventPoolIds
[internal_event_id
].begin();itr
!= mGameEventPoolIds
[internal_event_id
].end();++itr
)
580 poolhandler
.SpawnPool(*itr
);
584 void GameEventMgr::GameEventUnspawn(int16 event_id
)
586 int32 internal_event_id
= mGameEvent
.size() + event_id
- 1;
588 if(internal_event_id
< 0 || internal_event_id
>= mGameEventCreatureGuids
.size())
590 sLog
.outError("GameEventMgr::GameEventUnspawn attempt access to out of range mGameEventCreatureGuids element %i (size: %u)",internal_event_id
,mGameEventCreatureGuids
.size());
594 for (GuidList::iterator itr
= mGameEventCreatureGuids
[internal_event_id
].begin();itr
!= mGameEventCreatureGuids
[internal_event_id
].end();++itr
)
596 // Remove the creature from grid
597 if( CreatureData
const* data
= objmgr
.GetCreatureData(*itr
) )
599 objmgr
.RemoveCreatureFromGrid(*itr
, data
);
601 if( Creature
* pCreature
= ObjectAccessor::Instance().GetObjectInWorld(MAKE_NEW_GUID(*itr
, data
->id
, HIGHGUID_UNIT
), (Creature
*)NULL
) )
603 pCreature
->CleanupsBeforeDelete();
604 pCreature
->AddObjectToRemoveList();
609 if(internal_event_id
< 0 || internal_event_id
>= mGameEventGameobjectGuids
.size())
611 sLog
.outError("GameEventMgr::GameEventUnspawn attempt access to out of range mGameEventGameobjectGuids element %i (size: %u)",internal_event_id
,mGameEventGameobjectGuids
.size());
615 for (GuidList::iterator itr
= mGameEventGameobjectGuids
[internal_event_id
].begin();itr
!= mGameEventGameobjectGuids
[internal_event_id
].end();++itr
)
617 // Remove the gameobject from grid
618 if(GameObjectData
const* data
= objmgr
.GetGOData(*itr
))
620 objmgr
.RemoveGameobjectFromGrid(*itr
, data
);
622 if( GameObject
* pGameobject
= ObjectAccessor::Instance().GetObjectInWorld(MAKE_NEW_GUID(*itr
, data
->id
, HIGHGUID_GAMEOBJECT
), (GameObject
*)NULL
) )
623 pGameobject
->AddObjectToRemoveList();
626 if(internal_event_id
< 0 || internal_event_id
>= mGameEventPoolIds
.size())
628 sLog
.outError("GameEventMgr::GameEventUnspawn attempt access to out of range mGameEventPoolIds element %i (size: %u)",internal_event_id
,mGameEventPoolIds
.size());
632 for (IdList::iterator itr
= mGameEventPoolIds
[internal_event_id
].begin();itr
!= mGameEventPoolIds
[internal_event_id
].end();++itr
)
634 poolhandler
.DespawnPool(*itr
);
638 void GameEventMgr::ChangeEquipOrModel(int16 event_id
, bool activate
)
640 for(ModelEquipList::iterator itr
= mGameEventModelEquip
[event_id
].begin();itr
!= mGameEventModelEquip
[event_id
].end();++itr
)
642 // Remove the creature from grid
643 CreatureData
const* data
= objmgr
.GetCreatureData(itr
->first
);
648 Creature
* pCreature
= ObjectAccessor::Instance().GetObjectInWorld(MAKE_NEW_GUID(itr
->first
, data
->id
,HIGHGUID_UNIT
), (Creature
*)NULL
);
653 itr
->second
.equipement_id_prev
= pCreature
->GetCurrentEquipmentId();
654 itr
->second
.modelid_prev
= pCreature
->GetDisplayId();
655 pCreature
->LoadEquipment(itr
->second
.equipment_id
, true);
656 if (itr
->second
.modelid
>0 && itr
->second
.modelid_prev
!= itr
->second
.modelid
)
658 CreatureModelInfo
const *minfo
= objmgr
.GetCreatureModelInfo(itr
->second
.modelid
);
661 pCreature
->SetDisplayId(itr
->second
.modelid
);
662 pCreature
->SetNativeDisplayId(itr
->second
.modelid
);
663 pCreature
->SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS
,minfo
->bounding_radius
);
664 pCreature
->SetFloatValue(UNIT_FIELD_COMBATREACH
,minfo
->combat_reach
);
670 pCreature
->LoadEquipment(itr
->second
.equipement_id_prev
, true);
671 if (itr
->second
.modelid_prev
>0 && itr
->second
.modelid_prev
!= itr
->second
.modelid
)
673 CreatureModelInfo
const *minfo
= objmgr
.GetCreatureModelInfo(itr
->second
.modelid_prev
);
676 pCreature
->SetDisplayId(itr
->second
.modelid_prev
);
677 pCreature
->SetNativeDisplayId(itr
->second
.modelid_prev
);
678 pCreature
->SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS
,minfo
->bounding_radius
);
679 pCreature
->SetFloatValue(UNIT_FIELD_COMBATREACH
,minfo
->combat_reach
);
684 else // If not spawned
686 CreatureData
const* data
= objmgr
.GetCreatureData(itr
->first
);
687 if (data
&& activate
)
689 CreatureInfo
const *cinfo
= objmgr
.GetCreatureTemplate(data
->id
);
690 uint32 display_id
= objmgr
.ChooseDisplayId(0,cinfo
,data
);
691 CreatureModelInfo
const *minfo
= objmgr
.GetCreatureModelRandomGender(display_id
);
693 display_id
= minfo
->modelid
;
694 if (data
->equipmentId
== 0)
695 itr
->second
.equipement_id_prev
= cinfo
->equipmentId
;
696 else if (data
->equipmentId
!= -1)
697 itr
->second
.equipement_id_prev
= data
->equipmentId
;
698 itr
->second
.modelid_prev
= display_id
;
701 // now last step: put in data
702 // just to have write access to it
703 CreatureData
& data2
= objmgr
.NewOrExistCreatureData(itr
->first
);
706 data2
.displayid
= itr
->second
.modelid
;
707 data2
.equipmentId
= itr
->second
.equipment_id
;
711 data2
.displayid
= itr
->second
.modelid_prev
;
712 data2
.equipmentId
= itr
->second
.equipement_id_prev
;
717 void GameEventMgr::UpdateEventQuests(uint16 event_id
, bool Activate
)
719 QuestRelList::iterator itr
;
720 for (itr
= mGameEventQuests
[event_id
].begin();itr
!= mGameEventQuests
[event_id
].end();++itr
)
722 QuestRelations
&CreatureQuestMap
= objmgr
.mCreatureQuestRelations
;
723 if (Activate
) // Add the pair(id,quest) to the multimap
724 CreatureQuestMap
.insert(QuestRelations::value_type(itr
->first
, itr
->second
));
726 { // Remove the pair(id,quest) from the multimap
727 QuestRelations::iterator qitr
= CreatureQuestMap
.find(itr
->first
);
728 if (qitr
== CreatureQuestMap
.end())
730 QuestRelations::iterator lastElement
= CreatureQuestMap
.upper_bound(itr
->first
);
731 for ( ;qitr
!= lastElement
;++qitr
)
733 if (qitr
->second
== itr
->second
)
735 CreatureQuestMap
.erase(qitr
); // iterator is now no more valid
736 break; // but we can exit loop since the element is found
743 GameEventMgr::GameEventMgr()
745 isSystemInit
= false;
748 MANGOS_DLL_SPEC
bool IsHolidayActive( HolidayIds id
)
750 GameEventMgr::GameEventDataMap
const& events
= gameeventmgr
.GetEventMap();
751 GameEventMgr::ActiveEvents
const& ae
= gameeventmgr
.GetActiveEventList();
753 for(GameEventMgr::ActiveEvents::const_iterator itr
= ae
.begin(); itr
!= ae
.end(); ++itr
)
754 if(events
[id
].holiday_id
==id
)