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 "ObjectDefines.h"
23 #include "PoolManager.h"
24 #include "ProgressBar.h"
27 #include "MapManager.h"
28 #include "Policies/SingletonImp.h"
30 INSTANTIATE_SINGLETON_1(GameEventMgr
);
32 bool GameEventMgr::CheckOneGameEvent(uint16 entry
) const
34 // Get the event information
35 time_t currenttime
= time(NULL
);
36 if( mGameEvent
[entry
].start
< currenttime
&& currenttime
< mGameEvent
[entry
].end
&&
37 ((currenttime
- mGameEvent
[entry
].start
) % (mGameEvent
[entry
].occurence
* MINUTE
)) < (mGameEvent
[entry
].length
* MINUTE
) )
43 uint32
GameEventMgr::NextCheck(uint16 entry
) const
45 time_t currenttime
= time(NULL
);
47 // outdated event: we return max
48 if (currenttime
> mGameEvent
[entry
].end
)
49 return max_ge_check_delay
;
51 // never started event, we return delay before start
52 if (mGameEvent
[entry
].start
> currenttime
)
53 return (mGameEvent
[entry
].start
- currenttime
);
56 // in event, we return the end of it
57 if ((((currenttime
- mGameEvent
[entry
].start
) % (mGameEvent
[entry
].occurence
* 60)) < (mGameEvent
[entry
].length
* 60)))
58 // we return the delay before it ends
59 delay
= (mGameEvent
[entry
].length
* MINUTE
) - ((currenttime
- mGameEvent
[entry
].start
) % (mGameEvent
[entry
].occurence
* MINUTE
));
60 else // not in window, we return the delay before next start
61 delay
= (mGameEvent
[entry
].occurence
* MINUTE
) - ((currenttime
- mGameEvent
[entry
].start
) % (mGameEvent
[entry
].occurence
* MINUTE
));
62 // In case the end is before next check
63 if (mGameEvent
[entry
].end
< time_t(currenttime
+ delay
))
64 return (mGameEvent
[entry
].end
- currenttime
);
69 void GameEventMgr::StartEvent( uint16 event_id
, bool overwrite
)
71 AddActiveEvent(event_id
);
72 ApplyNewEvent(event_id
);
75 mGameEvent
[event_id
].start
= time(NULL
);
76 if(mGameEvent
[event_id
].end
<= mGameEvent
[event_id
].start
)
77 mGameEvent
[event_id
].end
= mGameEvent
[event_id
].start
+mGameEvent
[event_id
].length
;
81 void GameEventMgr::StopEvent( uint16 event_id
, bool overwrite
)
83 RemoveActiveEvent(event_id
);
84 UnApplyEvent(event_id
);
87 mGameEvent
[event_id
].start
= time(NULL
) - mGameEvent
[event_id
].length
* MINUTE
;
88 if(mGameEvent
[event_id
].end
<= mGameEvent
[event_id
].start
)
89 mGameEvent
[event_id
].end
= mGameEvent
[event_id
].start
+mGameEvent
[event_id
].length
;
93 void GameEventMgr::LoadFromDB()
96 QueryResult
*result
= WorldDatabase
.Query("SELECT MAX(entry) FROM game_event");
99 sLog
.outString(">> Table game_event is empty.");
104 Field
*fields
= result
->Fetch();
106 uint32 max_event_id
= fields
[0].GetUInt16();
109 mGameEvent
.resize(max_event_id
+1);
112 QueryResult
*result
= WorldDatabase
.Query("SELECT entry,UNIX_TIMESTAMP(start_time),UNIX_TIMESTAMP(end_time),occurence,length,holiday,description FROM game_event");
116 sLog
.outString(">> Table game_event is empty!");
124 barGoLink
bar( result
->GetRowCount() );
128 Field
*fields
= result
->Fetch();
132 uint16 event_id
= fields
[0].GetUInt16();
135 sLog
.outErrorDb("`game_event` game event id (%i) is reserved and can't be used.",event_id
);
139 GameEventData
& pGameEvent
= mGameEvent
[event_id
];
140 uint64 starttime
= fields
[1].GetUInt64();
141 pGameEvent
.start
= time_t(starttime
);
142 uint64 endtime
= fields
[2].GetUInt64();
143 pGameEvent
.end
= time_t(endtime
);
144 pGameEvent
.occurence
= fields
[3].GetUInt32();
145 pGameEvent
.length
= fields
[4].GetUInt32();
146 pGameEvent
.holiday_id
= fields
[5].GetUInt32();
149 if(pGameEvent
.length
==0) // length>0 is validity check
151 sLog
.outErrorDb("`game_event` game event id (%i) have length 0 and can't be used.",event_id
);
155 if(pGameEvent
.holiday_id
)
157 if(!sHolidaysStore
.LookupEntry(pGameEvent
.holiday_id
))
159 sLog
.outErrorDb("`game_event` game event id (%i) have not existed holiday id %u.",event_id
,pGameEvent
.holiday_id
);
160 pGameEvent
.holiday_id
= 0;
164 pGameEvent
.description
= fields
[6].GetCppString();
166 } while( result
->NextRow() );
170 sLog
.outString( ">> Loaded %u game events", count
);
173 mGameEventCreatureGuids
.resize(mGameEvent
.size()*2-1);
175 result
= WorldDatabase
.Query("SELECT creature.guid, game_event_creature.event "
176 "FROM creature JOIN game_event_creature ON creature.guid = game_event_creature.guid");
185 sLog
.outString(">> Loaded %u creatures in game events", count
);
190 barGoLink
bar( result
->GetRowCount() );
193 Field
*fields
= result
->Fetch();
197 uint32 guid
= fields
[0].GetUInt32();
198 int16 event_id
= fields
[1].GetInt16();
200 int32 internal_event_id
= mGameEvent
.size() + event_id
- 1;
202 if(internal_event_id
< 0 || (size_t)internal_event_id
>= mGameEventCreatureGuids
.size())
204 sLog
.outErrorDb("`game_event_creature` game event id (%i) is out of range compared to max event id in `game_event`",event_id
);
209 GuidList
& crelist
= mGameEventCreatureGuids
[internal_event_id
];
210 crelist
.push_back(guid
);
212 } while( result
->NextRow() );
216 sLog
.outString( ">> Loaded %u creatures in game events", count
);
219 mGameEventGameobjectGuids
.resize(mGameEvent
.size()*2-1);
221 result
= WorldDatabase
.Query("SELECT gameobject.guid, game_event_gameobject.event "
222 "FROM gameobject JOIN game_event_gameobject ON gameobject.guid=game_event_gameobject.guid");
231 sLog
.outString(">> Loaded %u gameobjects in game events", count
);
236 barGoLink
bar( result
->GetRowCount() );
239 Field
*fields
= result
->Fetch();
243 uint32 guid
= fields
[0].GetUInt32();
244 int16 event_id
= fields
[1].GetInt16();
246 int32 internal_event_id
= mGameEvent
.size() + event_id
- 1;
248 if(internal_event_id
< 0 || (size_t)internal_event_id
>= mGameEventGameobjectGuids
.size())
250 sLog
.outErrorDb("`game_event_gameobject` game event id (%i) is out of range compared to max event id in `game_event`",event_id
);
255 GuidList
& golist
= mGameEventGameobjectGuids
[internal_event_id
];
256 golist
.push_back(guid
);
258 } while( result
->NextRow() );
262 sLog
.outString( ">> Loaded %u gameobjects in game events", count
);
265 mGameEventModelEquip
.resize(mGameEvent
.size());
267 result
= WorldDatabase
.Query("SELECT creature.guid, game_event_model_equip.event, game_event_model_equip.modelid,"
269 "game_event_model_equip.equipment_id "
270 "FROM creature JOIN game_event_model_equip ON creature.guid=game_event_model_equip.guid");
279 sLog
.outString(">> Loaded %u model/equipment changes in game events", count
);
284 barGoLink
bar( result
->GetRowCount() );
287 Field
*fields
= result
->Fetch();
290 uint32 guid
= fields
[0].GetUInt32();
291 uint16 event_id
= fields
[1].GetUInt16();
293 if(event_id
>= mGameEventModelEquip
.size())
295 sLog
.outErrorDb("`game_event_model_equip` game event id (%u) is out of range compared to max event id in `game_event`",event_id
);
300 ModelEquipList
& equiplist
= mGameEventModelEquip
[event_id
];
301 ModelEquip newModelEquipSet
;
302 newModelEquipSet
.modelid
= fields
[2].GetUInt32();
303 newModelEquipSet
.equipment_id
= fields
[3].GetUInt32();
304 newModelEquipSet
.equipement_id_prev
= 0;
305 newModelEquipSet
.modelid_prev
= 0;
307 if(newModelEquipSet
.equipment_id
> 0)
309 if(!sObjectMgr
.GetEquipmentInfo(newModelEquipSet
.equipment_id
))
311 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
);
316 equiplist
.push_back(std::pair
<uint32
, ModelEquip
>(guid
, newModelEquipSet
));
318 } while( result
->NextRow() );
322 sLog
.outString( ">> Loaded %u model/equipment changes in game events", count
);
325 mGameEventQuests
.resize(mGameEvent
.size());
327 result
= WorldDatabase
.Query("SELECT id, quest, event FROM game_event_creature_quest");
336 sLog
.outString(">> Loaded %u quests additions in game events", count
);
341 barGoLink
bar( result
->GetRowCount() );
344 Field
*fields
= result
->Fetch();
347 uint32 id
= fields
[0].GetUInt32();
348 uint32 quest
= fields
[1].GetUInt32();
349 uint16 event_id
= fields
[2].GetUInt16();
351 if(event_id
>= mGameEventQuests
.size())
353 sLog
.outErrorDb("`game_event_creature_quest` game event id (%u) is out of range compared to max event id in `game_event`",event_id
);
358 QuestRelList
& questlist
= mGameEventQuests
[event_id
];
359 questlist
.push_back(QuestRelation(id
, quest
));
361 } while( result
->NextRow() );
365 sLog
.outString( ">> Loaded %u quests additions in game events", count
);
368 mGameEventPoolIds
.resize(mGameEvent
.size()*2-1);
370 result
= WorldDatabase
.Query("SELECT pool_template.entry, game_event_pool.event "
371 "FROM pool_template JOIN game_event_pool ON pool_template.entry = game_event_pool.pool_entry");
380 sLog
.outString(">> Loaded %u pools in game events", count
);
385 barGoLink
bar2( result
->GetRowCount() );
388 Field
*fields
= result
->Fetch();
392 uint32 entry
= fields
[0].GetUInt16();
393 int16 event_id
= fields
[1].GetInt16();
395 int32 internal_event_id
= mGameEvent
.size() + event_id
- 1;
397 if (internal_event_id
< 0 || (size_t)internal_event_id
>= mGameEventPoolIds
.size())
399 sLog
.outErrorDb("`game_event_pool` game event id (%i) is out of range compared to max event id in `game_event`",event_id
);
403 if (!sPoolMgr
.CheckPool(entry
))
405 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
);
410 IdList
& poollist
= mGameEventPoolIds
[internal_event_id
];
411 poollist
.push_back(entry
);
413 } while( result
->NextRow() );
415 sLog
.outString( ">> Loaded %u pools in game events", count
);
420 uint32
GameEventMgr::Initialize() // return the next event delay in ms
422 m_ActiveEvents
.clear();
423 uint32 delay
= Update();
424 sLog
.outBasic("Game Event system initialized." );
425 m_IsGameEventsInit
= true;
429 uint32
GameEventMgr::Update() // return the next event delay in ms
431 uint32 nextEventDelay
= max_ge_check_delay
; // 1 day
433 for (uint16 itr
= 1; itr
< mGameEvent
.size(); ++itr
)
435 //sLog.outErrorDb("Checking event %u",itr);
436 if (CheckOneGameEvent(itr
))
438 //sLog.outDebug("GameEvent %u is active",itr->first);
439 if (!IsActiveEvent(itr
))
444 //sLog.outDebug("GameEvent %u is not active",itr->first);
445 if (IsActiveEvent(itr
))
449 if (!m_IsGameEventsInit
)
451 int16 event_nid
= (-1) * (itr
);
452 // spawn all negative ones for this event
453 GameEventSpawn(event_nid
);
455 // disable any event specific quest (for cases where creature is spawned, but event not active).
456 UpdateEventQuests(itr
, false);
460 calcDelay
= NextCheck(itr
);
461 if (calcDelay
< nextEventDelay
)
462 nextEventDelay
= calcDelay
;
464 sLog
.outBasic("Next game event check in %u seconds.", nextEventDelay
+ 1);
465 return (nextEventDelay
+ 1) * IN_MILISECONDS
; // Add 1 second to be sure event has started/stopped at next call
468 void GameEventMgr::UnApplyEvent(uint16 event_id
)
470 sLog
.outString("GameEvent %u \"%s\" removed.", event_id
, mGameEvent
[event_id
].description
.c_str());
471 // un-spawn positive event tagged objects
472 GameEventUnspawn(event_id
);
473 // spawn negative event tagget objects
474 int16 event_nid
= (-1) * event_id
;
475 GameEventSpawn(event_nid
);
476 // restore equipment or model
477 ChangeEquipOrModel(event_id
, false);
478 // Remove quests that are events only to non event npc
479 UpdateEventQuests(event_id
, false);
482 void GameEventMgr::ApplyNewEvent(uint16 event_id
)
484 switch(sWorld
.getConfig(CONFIG_EVENT_ANNOUNCE
))
488 case 1: // announce events
489 sWorld
.SendWorldText(LANG_EVENTMESSAGE
, mGameEvent
[event_id
].description
.c_str());
493 sLog
.outString("GameEvent %u \"%s\" started.", event_id
, mGameEvent
[event_id
].description
.c_str());
494 // spawn positive event tagget objects
495 GameEventSpawn(event_id
);
496 // un-spawn negative event tagged objects
497 int16 event_nid
= (-1) * event_id
;
498 GameEventUnspawn(event_nid
);
499 // Change equipement or model
500 ChangeEquipOrModel(event_id
, true);
501 // Add quests that are events only to non event npc
502 UpdateEventQuests(event_id
, true);
505 void GameEventMgr::GameEventSpawn(int16 event_id
)
507 int32 internal_event_id
= mGameEvent
.size() + event_id
- 1;
509 if (internal_event_id
< 0 || (size_t)internal_event_id
>= mGameEventCreatureGuids
.size())
511 sLog
.outError("GameEventMgr::GameEventSpawn attempt access to out of range mGameEventCreatureGuids element %i (size: " SIZEFMTD
")",internal_event_id
,mGameEventCreatureGuids
.size());
515 for (GuidList::iterator itr
= mGameEventCreatureGuids
[internal_event_id
].begin();itr
!= mGameEventCreatureGuids
[internal_event_id
].end();++itr
)
517 // Add to correct cell
518 CreatureData
const* data
= sObjectMgr
.GetCreatureData(*itr
);
521 sObjectMgr
.AddCreatureToGrid(*itr
, data
);
523 // Spawn if necessary (loaded grids only)
524 Map
* map
= const_cast<Map
*>(sMapMgr
.CreateBaseMap(data
->mapid
));
525 // We use spawn coords to spawn
526 if(!map
->Instanceable() && map
->IsLoaded(data
->posX
,data
->posY
))
528 Creature
* pCreature
= new Creature
;
529 //sLog.outDebug("Spawning creature %u",*itr);
530 if (!pCreature
->LoadFromDB(*itr
, map
))
542 if (internal_event_id
< 0 || (size_t)internal_event_id
>= mGameEventGameobjectGuids
.size())
544 sLog
.outError("GameEventMgr::GameEventSpawn attempt access to out of range mGameEventGameobjectGuids element %i (size: " SIZEFMTD
")",internal_event_id
,mGameEventGameobjectGuids
.size());
548 for (GuidList::iterator itr
= mGameEventGameobjectGuids
[internal_event_id
].begin();itr
!= mGameEventGameobjectGuids
[internal_event_id
].end();++itr
)
550 // Add to correct cell
551 GameObjectData
const* data
= sObjectMgr
.GetGOData(*itr
);
554 sObjectMgr
.AddGameobjectToGrid(*itr
, data
);
555 // Spawn if necessary (loaded grids only)
556 // this base map checked as non-instanced and then only existed
557 Map
* map
= const_cast<Map
*>(sMapMgr
.CreateBaseMap(data
->mapid
));
558 // We use current coords to unspawn, not spawn coords since creature can have changed grid
559 if(!map
->Instanceable() && map
->IsLoaded(data
->posX
, data
->posY
))
561 GameObject
* pGameobject
= new GameObject
;
562 //sLog.outDebug("Spawning gameobject %u", *itr);
563 if (!pGameobject
->LoadFromDB(*itr
, map
))
569 if(pGameobject
->isSpawnedByDefault())
570 map
->Add(pGameobject
);
576 if (internal_event_id
< 0 || (size_t)internal_event_id
>= mGameEventPoolIds
.size())
578 sLog
.outError("GameEventMgr::GameEventSpawn attempt access to out of range mGameEventPoolIds element %i (size: " SIZEFMTD
")",internal_event_id
,mGameEventPoolIds
.size());
582 for (IdList::iterator itr
= mGameEventPoolIds
[internal_event_id
].begin();itr
!= mGameEventPoolIds
[internal_event_id
].end();++itr
)
584 sPoolMgr
.SpawnPool(*itr
, 0, 0);
585 sPoolMgr
.SpawnPool(*itr
, 0, TYPEID_GAMEOBJECT
);
586 sPoolMgr
.SpawnPool(*itr
, 0, TYPEID_UNIT
);
590 void GameEventMgr::GameEventUnspawn(int16 event_id
)
592 int32 internal_event_id
= mGameEvent
.size() + event_id
- 1;
594 if (internal_event_id
< 0 || (size_t)internal_event_id
>= mGameEventCreatureGuids
.size())
596 sLog
.outError("GameEventMgr::GameEventUnspawn attempt access to out of range mGameEventCreatureGuids element %i (size: " SIZEFMTD
")",internal_event_id
,mGameEventCreatureGuids
.size());
600 for (GuidList::iterator itr
= mGameEventCreatureGuids
[internal_event_id
].begin();itr
!= mGameEventCreatureGuids
[internal_event_id
].end();++itr
)
602 // Remove the creature from grid
603 if( CreatureData
const* data
= sObjectMgr
.GetCreatureData(*itr
) )
605 sObjectMgr
.RemoveCreatureFromGrid(*itr
, data
);
607 if( Creature
* pCreature
= ObjectAccessor::GetCreatureInWorld(MAKE_NEW_GUID(*itr
, data
->id
, HIGHGUID_UNIT
)) )
608 pCreature
->AddObjectToRemoveList();
612 if (internal_event_id
< 0 || (size_t)internal_event_id
>= mGameEventGameobjectGuids
.size())
614 sLog
.outError("GameEventMgr::GameEventUnspawn attempt access to out of range mGameEventGameobjectGuids element %i (size: " SIZEFMTD
")",internal_event_id
,mGameEventGameobjectGuids
.size());
618 for (GuidList::iterator itr
= mGameEventGameobjectGuids
[internal_event_id
].begin();itr
!= mGameEventGameobjectGuids
[internal_event_id
].end();++itr
)
620 // Remove the gameobject from grid
621 if(GameObjectData
const* data
= sObjectMgr
.GetGOData(*itr
))
623 sObjectMgr
.RemoveGameobjectFromGrid(*itr
, data
);
625 if( GameObject
* pGameobject
= ObjectAccessor::GetGameObjectInWorld(MAKE_NEW_GUID(*itr
, data
->id
, HIGHGUID_GAMEOBJECT
)) )
626 pGameobject
->AddObjectToRemoveList();
629 if (internal_event_id
< 0 || (size_t)internal_event_id
>= mGameEventPoolIds
.size())
631 sLog
.outError("GameEventMgr::GameEventUnspawn attempt access to out of range mGameEventPoolIds element %i (size: " SIZEFMTD
")",internal_event_id
,mGameEventPoolIds
.size());
635 for (IdList::iterator itr
= mGameEventPoolIds
[internal_event_id
].begin();itr
!= mGameEventPoolIds
[internal_event_id
].end();++itr
)
637 sPoolMgr
.DespawnPool(*itr
);
641 void GameEventMgr::ChangeEquipOrModel(int16 event_id
, bool activate
)
643 for(ModelEquipList::iterator itr
= mGameEventModelEquip
[event_id
].begin();itr
!= mGameEventModelEquip
[event_id
].end();++itr
)
645 // Remove the creature from grid
646 CreatureData
const* data
= sObjectMgr
.GetCreatureData(itr
->first
);
651 Creature
* pCreature
= ObjectAccessor::GetCreatureInWorld(MAKE_NEW_GUID(itr
->first
, data
->id
,HIGHGUID_UNIT
));
656 itr
->second
.equipement_id_prev
= pCreature
->GetCurrentEquipmentId();
657 itr
->second
.modelid_prev
= pCreature
->GetDisplayId();
658 pCreature
->LoadEquipment(itr
->second
.equipment_id
, true);
659 if (itr
->second
.modelid
>0 && itr
->second
.modelid_prev
!= itr
->second
.modelid
)
661 CreatureModelInfo
const *minfo
= sObjectMgr
.GetCreatureModelInfo(itr
->second
.modelid
);
664 pCreature
->SetDisplayId(itr
->second
.modelid
);
665 pCreature
->SetNativeDisplayId(itr
->second
.modelid
);
666 pCreature
->SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS
,minfo
->bounding_radius
);
667 pCreature
->SetFloatValue(UNIT_FIELD_COMBATREACH
,minfo
->combat_reach
);
673 pCreature
->LoadEquipment(itr
->second
.equipement_id_prev
, true);
674 if (itr
->second
.modelid_prev
>0 && itr
->second
.modelid_prev
!= itr
->second
.modelid
)
676 CreatureModelInfo
const *minfo
= sObjectMgr
.GetCreatureModelInfo(itr
->second
.modelid_prev
);
679 pCreature
->SetDisplayId(itr
->second
.modelid_prev
);
680 pCreature
->SetNativeDisplayId(itr
->second
.modelid_prev
);
681 pCreature
->SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS
,minfo
->bounding_radius
);
682 pCreature
->SetFloatValue(UNIT_FIELD_COMBATREACH
,minfo
->combat_reach
);
687 else // If not spawned
689 CreatureData
const* data2
= sObjectMgr
.GetCreatureData(itr
->first
);
690 if (data2
&& activate
)
692 CreatureInfo
const *cinfo
= ObjectMgr::GetCreatureTemplate(data2
->id
);
693 uint32 display_id
= sObjectMgr
.ChooseDisplayId(0,cinfo
,data2
);
694 CreatureModelInfo
const *minfo
= sObjectMgr
.GetCreatureModelRandomGender(display_id
);
696 display_id
= minfo
->modelid
;
698 if (data2
->equipmentId
== 0)
699 itr
->second
.equipement_id_prev
= cinfo
->equipmentId
;
700 else if (data2
->equipmentId
!= -1)
701 itr
->second
.equipement_id_prev
= data
->equipmentId
;
702 itr
->second
.modelid_prev
= display_id
;
705 // now last step: put in data
706 // just to have write access to it
707 CreatureData
& data2
= sObjectMgr
.NewOrExistCreatureData(itr
->first
);
710 data2
.displayid
= itr
->second
.modelid
;
711 data2
.equipmentId
= itr
->second
.equipment_id
;
715 data2
.displayid
= itr
->second
.modelid_prev
;
716 data2
.equipmentId
= itr
->second
.equipement_id_prev
;
721 void GameEventMgr::UpdateEventQuests(uint16 event_id
, bool Activate
)
723 QuestRelList::iterator itr
;
724 for (itr
= mGameEventQuests
[event_id
].begin();itr
!= mGameEventQuests
[event_id
].end();++itr
)
726 QuestRelations
&CreatureQuestMap
= sObjectMgr
.mCreatureQuestRelations
;
727 if (Activate
) // Add the pair(id,quest) to the multimap
728 CreatureQuestMap
.insert(QuestRelations::value_type(itr
->first
, itr
->second
));
730 { // Remove the pair(id,quest) from the multimap
731 QuestRelations::iterator qitr
= CreatureQuestMap
.find(itr
->first
);
732 if (qitr
== CreatureQuestMap
.end())
734 QuestRelations::iterator lastElement
= CreatureQuestMap
.upper_bound(itr
->first
);
735 for ( ;qitr
!= lastElement
;++qitr
)
737 if (qitr
->second
== itr
->second
)
739 CreatureQuestMap
.erase(qitr
); // iterator is now no more valid
740 break; // but we can exit loop since the element is found
747 GameEventMgr::GameEventMgr()
749 m_IsGameEventsInit
= false;
752 MANGOS_DLL_SPEC
bool IsHolidayActive( HolidayIds id
)
754 GameEventMgr::GameEventDataMap
const& events
= sGameEventMgr
.GetEventMap();
755 GameEventMgr::ActiveEvents
const& ae
= sGameEventMgr
.GetActiveEventList();
757 for(GameEventMgr::ActiveEvents::const_iterator itr
= ae
.begin(); itr
!= ae
.end(); ++itr
)
758 if (events
[*itr
].holiday_id
== id
)