[8483] Implement glyph 43361.
[getmangos.git] / src / game / GameEventMgr.cpp
blob868bc87e541f4225e0c073907b2f63fc66974cfb
1 /*
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"
20 #include "World.h"
21 #include "ObjectMgr.h"
22 #include "PoolHandler.h"
23 #include "ProgressBar.h"
24 #include "Language.h"
25 #include "Log.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) )
37 return true;
38 else
39 return false;
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);
54 uint32 delay;
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);
64 else
65 return delay;
68 void GameEventMgr::StartEvent( uint16 event_id, bool overwrite )
70 AddActiveEvent(event_id);
71 ApplyNewEvent(event_id);
72 if(overwrite)
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);
84 if(overwrite)
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");
96 if( !result )
98 sLog.outString(">> Table game_event is empty.");
99 sLog.outString();
100 return;
103 Field *fields = result->Fetch();
105 uint32 max_event_id = fields[0].GetUInt16();
106 delete result;
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");
112 if( !result )
114 mGameEvent.clear();
115 sLog.outString(">> Table game_event is empty!");
116 sLog.outString();
117 return;
120 uint32 count = 0;
123 barGoLink bar( result->GetRowCount() );
126 ++count;
127 Field *fields = result->Fetch();
129 bar.step();
131 uint16 event_id = fields[0].GetUInt16();
132 if(event_id==0)
134 sLog.outErrorDb("`game_event` game event id (%i) is reserved and can't be used.",event_id);
135 continue;
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);
151 continue;
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() );
166 delete result;
168 sLog.outString();
169 sLog.outString( ">> Loaded %u game events", count );
172 mGameEventCreatureGuids.resize(mGameEvent.size()*2-1);
173 // 1 2
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");
177 count = 0;
178 if( !result )
180 barGoLink bar(1);
181 bar.step();
183 sLog.outString();
184 sLog.outString(">> Loaded %u creatures in game events", count );
186 else
189 barGoLink bar( result->GetRowCount() );
192 Field *fields = result->Fetch();
194 bar.step();
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);
204 continue;
207 ++count;
208 GuidList& crelist = mGameEventCreatureGuids[internal_event_id];
209 crelist.push_back(guid);
211 } while( result->NextRow() );
212 delete result;
214 sLog.outString();
215 sLog.outString( ">> Loaded %u creatures in game events", count );
218 mGameEventGameobjectGuids.resize(mGameEvent.size()*2-1);
219 // 1 2
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");
223 count = 0;
224 if( !result )
226 barGoLink bar(1);
227 bar.step();
229 sLog.outString();
230 sLog.outString(">> Loaded %u gameobjects in game events", count );
232 else
235 barGoLink bar( result->GetRowCount() );
238 Field *fields = result->Fetch();
240 bar.step();
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);
250 continue;
253 ++count;
254 GuidList& golist = mGameEventGameobjectGuids[internal_event_id];
255 golist.push_back(guid);
257 } while( result->NextRow() );
258 delete result;
260 sLog.outString();
261 sLog.outString( ">> Loaded %u gameobjects in game events", count );
264 mGameEventModelEquip.resize(mGameEvent.size());
265 // 0 1 2
266 result = WorldDatabase.Query("SELECT creature.guid, game_event_model_equip.event, game_event_model_equip.modelid,"
267 // 3
268 "game_event_model_equip.equipment_id "
269 "FROM creature JOIN game_event_model_equip ON creature.guid=game_event_model_equip.guid");
271 count = 0;
272 if( !result )
274 barGoLink bar(1);
275 bar.step();
277 sLog.outString();
278 sLog.outString(">> Loaded %u model/equipment changes in game events", count );
280 else
283 barGoLink bar( result->GetRowCount() );
286 Field *fields = result->Fetch();
288 bar.step();
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);
295 continue;
298 ++count;
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);
311 continue;
315 equiplist.push_back(std::pair<uint32, ModelEquip>(guid, newModelEquipSet));
317 } while( result->NextRow() );
318 delete result;
320 sLog.outString();
321 sLog.outString( ">> Loaded %u model/equipment changes in game events", count );
324 mGameEventQuests.resize(mGameEvent.size());
325 // 0 1 2
326 result = WorldDatabase.Query("SELECT id, quest, event FROM game_event_creature_quest");
328 count = 0;
329 if( !result )
331 barGoLink bar(1);
332 bar.step();
334 sLog.outString();
335 sLog.outString(">> Loaded %u quests additions in game events", count );
337 else
340 barGoLink bar( result->GetRowCount() );
343 Field *fields = result->Fetch();
345 bar.step();
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);
353 continue;
356 ++count;
357 QuestRelList& questlist = mGameEventQuests[event_id];
358 questlist.push_back(QuestRelation(id, quest));
360 } while( result->NextRow() );
361 delete result;
363 sLog.outString();
364 sLog.outString( ">> Loaded %u quests additions in game events", count );
367 mGameEventPoolIds.resize(mGameEvent.size()*2-1);
368 // 1 2
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");
372 count = 0;
373 if( !result )
375 barGoLink bar2(1);
376 bar2.step();
378 sLog.outString();
379 sLog.outString(">> Loaded %u pools in game events", count );
381 else
384 barGoLink bar2( result->GetRowCount() );
387 Field *fields = result->Fetch();
389 bar2.step();
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);
399 continue;
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);
405 continue;
408 ++count;
409 IdList& poollist = mGameEventPoolIds[internal_event_id];
410 poollist.push_back(entry);
412 } while( result->NextRow() );
413 sLog.outString();
414 sLog.outString( ">> Loaded %u pools in game events", count );
415 delete result;
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." );
424 isSystemInit = true;
425 return delay;
428 uint32 GameEventMgr::Update() // return the next event delay in ms
430 uint32 nextEventDelay = max_ge_check_delay; // 1 day
431 uint32 calcDelay;
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))
439 StartEvent(itr);
441 else
443 //sLog.outDebug("GameEvent %u is not active",itr->first);
444 if (IsActiveEvent(itr))
445 StopEvent(itr);
446 else
448 if (!isSystemInit)
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))
482 case 0: // disable
483 break;
484 case 1: // announce events
485 sWorld.SendWorldText(LANG_EVENTMESSAGE, mGameEvent[event_id].description.c_str());
486 break;
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: " SIZEFMTD ")",internal_event_id,mGameEventCreatureGuids.size());
508 return;
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);
515 if (data)
517 objmgr.AddCreatureToGrid(*itr, data);
519 // Spawn if necessary (loaded grids only)
520 Map* map = const_cast<Map*>(MapManager::Instance().CreateBaseMap(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))
528 delete pCreature;
530 else
532 map->Add(pCreature);
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: " SIZEFMTD ")",internal_event_id,mGameEventGameobjectGuids.size());
541 return;
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);
548 if (data)
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().CreateBaseMap(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))
561 delete pGameobject;
563 else
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: " SIZEFMTD ")",internal_event_id,mGameEventPoolIds.size());
575 return;
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: " SIZEFMTD ")",internal_event_id,mGameEventCreatureGuids.size());
591 return;
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) )
602 pCreature->AddObjectToRemoveList();
606 if(internal_event_id < 0 || internal_event_id >= mGameEventGameobjectGuids.size())
608 sLog.outError("GameEventMgr::GameEventUnspawn attempt access to out of range mGameEventGameobjectGuids element %i (size: " SIZEFMTD ")",internal_event_id,mGameEventGameobjectGuids.size());
609 return;
612 for (GuidList::iterator itr = mGameEventGameobjectGuids[internal_event_id].begin();itr != mGameEventGameobjectGuids[internal_event_id].end();++itr)
614 // Remove the gameobject from grid
615 if(GameObjectData const* data = objmgr.GetGOData(*itr))
617 objmgr.RemoveGameobjectFromGrid(*itr, data);
619 if( GameObject* pGameobject = ObjectAccessor::Instance().GetObjectInWorld(MAKE_NEW_GUID(*itr, data->id, HIGHGUID_GAMEOBJECT), (GameObject*)NULL) )
620 pGameobject->AddObjectToRemoveList();
623 if(internal_event_id < 0 || internal_event_id >= mGameEventPoolIds.size())
625 sLog.outError("GameEventMgr::GameEventUnspawn attempt access to out of range mGameEventPoolIds element %i (size: " SIZEFMTD ")",internal_event_id,mGameEventPoolIds.size());
626 return;
629 for (IdList::iterator itr = mGameEventPoolIds[internal_event_id].begin();itr != mGameEventPoolIds[internal_event_id].end();++itr)
631 poolhandler.DespawnPool(*itr);
635 void GameEventMgr::ChangeEquipOrModel(int16 event_id, bool activate)
637 for(ModelEquipList::iterator itr = mGameEventModelEquip[event_id].begin();itr != mGameEventModelEquip[event_id].end();++itr)
639 // Remove the creature from grid
640 CreatureData const* data = objmgr.GetCreatureData(itr->first);
641 if(!data)
642 continue;
644 // Update if spawned
645 Creature* pCreature = ObjectAccessor::Instance().GetObjectInWorld(MAKE_NEW_GUID(itr->first, data->id,HIGHGUID_UNIT), (Creature*)NULL);
646 if (pCreature)
648 if (activate)
650 itr->second.equipement_id_prev = pCreature->GetCurrentEquipmentId();
651 itr->second.modelid_prev = pCreature->GetDisplayId();
652 pCreature->LoadEquipment(itr->second.equipment_id, true);
653 if (itr->second.modelid >0 && itr->second.modelid_prev != itr->second.modelid)
655 CreatureModelInfo const *minfo = objmgr.GetCreatureModelInfo(itr->second.modelid);
656 if (minfo)
658 pCreature->SetDisplayId(itr->second.modelid);
659 pCreature->SetNativeDisplayId(itr->second.modelid);
660 pCreature->SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS,minfo->bounding_radius);
661 pCreature->SetFloatValue(UNIT_FIELD_COMBATREACH,minfo->combat_reach );
665 else
667 pCreature->LoadEquipment(itr->second.equipement_id_prev, true);
668 if (itr->second.modelid_prev >0 && itr->second.modelid_prev != itr->second.modelid)
670 CreatureModelInfo const *minfo = objmgr.GetCreatureModelInfo(itr->second.modelid_prev);
671 if (minfo)
673 pCreature->SetDisplayId(itr->second.modelid_prev);
674 pCreature->SetNativeDisplayId(itr->second.modelid_prev);
675 pCreature->SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS,minfo->bounding_radius);
676 pCreature->SetFloatValue(UNIT_FIELD_COMBATREACH,minfo->combat_reach );
681 else // If not spawned
683 CreatureData const* data2 = objmgr.GetCreatureData(itr->first);
684 if (data2 && activate)
686 CreatureInfo const *cinfo = objmgr.GetCreatureTemplate(data2->id);
687 uint32 display_id = objmgr.ChooseDisplayId(0,cinfo,data2);
688 CreatureModelInfo const *minfo = objmgr.GetCreatureModelRandomGender(display_id);
689 if (minfo)
690 display_id = minfo->modelid;
692 if (data2->equipmentId == 0)
693 itr->second.equipement_id_prev = cinfo->equipmentId;
694 else if (data2->equipmentId != -1)
695 itr->second.equipement_id_prev = data->equipmentId;
696 itr->second.modelid_prev = display_id;
699 // now last step: put in data
700 // just to have write access to it
701 CreatureData& data2 = objmgr.NewOrExistCreatureData(itr->first);
702 if (activate)
704 data2.displayid = itr->second.modelid;
705 data2.equipmentId = itr->second.equipment_id;
707 else
709 data2.displayid = itr->second.modelid_prev;
710 data2.equipmentId = itr->second.equipement_id_prev;
715 void GameEventMgr::UpdateEventQuests(uint16 event_id, bool Activate)
717 QuestRelList::iterator itr;
718 for (itr = mGameEventQuests[event_id].begin();itr != mGameEventQuests[event_id].end();++itr)
720 QuestRelations &CreatureQuestMap = objmgr.mCreatureQuestRelations;
721 if (Activate) // Add the pair(id,quest) to the multimap
722 CreatureQuestMap.insert(QuestRelations::value_type(itr->first, itr->second));
723 else
724 { // Remove the pair(id,quest) from the multimap
725 QuestRelations::iterator qitr = CreatureQuestMap.find(itr->first);
726 if (qitr == CreatureQuestMap.end())
727 continue;
728 QuestRelations::iterator lastElement = CreatureQuestMap.upper_bound(itr->first);
729 for ( ;qitr != lastElement;++qitr)
731 if (qitr->second == itr->second)
733 CreatureQuestMap.erase(qitr); // iterator is now no more valid
734 break; // but we can exit loop since the element is found
741 GameEventMgr::GameEventMgr()
743 isSystemInit = false;
746 MANGOS_DLL_SPEC bool IsHolidayActive( HolidayIds id )
748 GameEventMgr::GameEventDataMap const& events = gameeventmgr.GetEventMap();
749 GameEventMgr::ActiveEvents const& ae = gameeventmgr.GetActiveEventList();
751 for(GameEventMgr::ActiveEvents::const_iterator itr = ae.begin(); itr != ae.end(); ++itr)
752 if(events[*itr].holiday_id==id)
753 return true;
755 return false;