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 #include "GameEventMgr.h"
21 #include "ObjectMgr.h"
22 #include "ObjectGuid.h"
23 #include "PoolManager.h"
24 #include "ProgressBar.h"
27 #include "MapManager.h"
28 #include "BattleGroundMgr.h"
29 #include "Policies/SingletonImp.h"
31 INSTANTIATE_SINGLETON_1(GameEventMgr
);
33 bool GameEventMgr::CheckOneGameEvent(uint16 entry
) const
35 // Get the event information
36 time_t currenttime
= time(NULL
);
37 if( mGameEvent
[entry
].start
< currenttime
&& currenttime
< mGameEvent
[entry
].end
&&
38 ((currenttime
- mGameEvent
[entry
].start
) % (mGameEvent
[entry
].occurence
* MINUTE
)) < (mGameEvent
[entry
].length
* MINUTE
) )
44 uint32
GameEventMgr::NextCheck(uint16 entry
) const
46 time_t currenttime
= time(NULL
);
48 // outdated event: we return max
49 if (currenttime
> mGameEvent
[entry
].end
)
50 return max_ge_check_delay
;
52 // never started event, we return delay before start
53 if (mGameEvent
[entry
].start
> currenttime
)
54 return uint32(mGameEvent
[entry
].start
- currenttime
);
57 // in event, we return the end of it
58 if ((((currenttime
- mGameEvent
[entry
].start
) % (mGameEvent
[entry
].occurence
* 60)) < (mGameEvent
[entry
].length
* 60)))
59 // we return the delay before it ends
60 delay
= (mGameEvent
[entry
].length
* MINUTE
) - ((currenttime
- mGameEvent
[entry
].start
) % (mGameEvent
[entry
].occurence
* MINUTE
));
61 else // not in window, we return the delay before next start
62 delay
= (mGameEvent
[entry
].occurence
* MINUTE
) - ((currenttime
- mGameEvent
[entry
].start
) % (mGameEvent
[entry
].occurence
* MINUTE
));
63 // In case the end is before next check
64 if (mGameEvent
[entry
].end
< time_t(currenttime
+ delay
))
65 return uint32(mGameEvent
[entry
].end
- currenttime
);
70 void GameEventMgr::StartEvent( uint16 event_id
, bool overwrite
)
72 AddActiveEvent(event_id
);
73 ApplyNewEvent(event_id
);
76 mGameEvent
[event_id
].start
= time(NULL
);
77 if(mGameEvent
[event_id
].end
<= mGameEvent
[event_id
].start
)
78 mGameEvent
[event_id
].end
= mGameEvent
[event_id
].start
+mGameEvent
[event_id
].length
;
82 void GameEventMgr::StopEvent( uint16 event_id
, bool overwrite
)
84 RemoveActiveEvent(event_id
);
85 UnApplyEvent(event_id
);
88 mGameEvent
[event_id
].start
= time(NULL
) - mGameEvent
[event_id
].length
* MINUTE
;
89 if(mGameEvent
[event_id
].end
<= mGameEvent
[event_id
].start
)
90 mGameEvent
[event_id
].end
= mGameEvent
[event_id
].start
+mGameEvent
[event_id
].length
;
94 void GameEventMgr::LoadFromDB()
97 QueryResult
*result
= WorldDatabase
.Query("SELECT MAX(entry) FROM game_event");
100 sLog
.outString(">> Table game_event is empty.");
105 Field
*fields
= result
->Fetch();
107 uint32 max_event_id
= fields
[0].GetUInt16();
110 mGameEvent
.resize(max_event_id
+1);
113 QueryResult
*result
= WorldDatabase
.Query("SELECT entry,UNIX_TIMESTAMP(start_time),UNIX_TIMESTAMP(end_time),occurence,length,holiday,description FROM game_event");
117 sLog
.outString(">> Table game_event is empty!");
125 barGoLink
bar( (int)result
->GetRowCount() );
129 Field
*fields
= result
->Fetch();
133 uint16 event_id
= fields
[0].GetUInt16();
136 sLog
.outErrorDb("`game_event` game event id (%i) is reserved and can't be used.",event_id
);
140 GameEventData
& pGameEvent
= mGameEvent
[event_id
];
141 uint64 starttime
= fields
[1].GetUInt64();
142 pGameEvent
.start
= time_t(starttime
);
143 uint64 endtime
= fields
[2].GetUInt64();
144 pGameEvent
.end
= time_t(endtime
);
145 pGameEvent
.occurence
= fields
[3].GetUInt32();
146 pGameEvent
.length
= fields
[4].GetUInt32();
147 pGameEvent
.holiday_id
= HolidayIds(fields
[5].GetUInt32());
150 if(pGameEvent
.length
==0) // length>0 is validity check
152 sLog
.outErrorDb("`game_event` game event id (%i) have length 0 and can't be used.",event_id
);
156 if(pGameEvent
.holiday_id
!= HOLIDAY_NONE
)
158 if(!sHolidaysStore
.LookupEntry(pGameEvent
.holiday_id
))
160 sLog
.outErrorDb("`game_event` game event id (%i) have not existed holiday id %u.",event_id
,pGameEvent
.holiday_id
);
161 pGameEvent
.holiday_id
= HOLIDAY_NONE
;
165 pGameEvent
.description
= fields
[6].GetCppString();
167 } while( result
->NextRow() );
171 sLog
.outString( ">> Loaded %u game events", count
);
174 mGameEventCreatureGuids
.resize(mGameEvent
.size()*2-1);
176 result
= WorldDatabase
.Query("SELECT creature.guid, game_event_creature.event "
177 "FROM creature JOIN game_event_creature ON creature.guid = game_event_creature.guid");
186 sLog
.outString(">> Loaded %u creatures in game events", count
);
191 barGoLink
bar( (int)result
->GetRowCount() );
194 Field
*fields
= result
->Fetch();
198 uint32 guid
= fields
[0].GetUInt32();
199 int16 event_id
= fields
[1].GetInt16();
201 int32 internal_event_id
= mGameEvent
.size() + event_id
- 1;
203 if(internal_event_id
< 0 || (size_t)internal_event_id
>= mGameEventCreatureGuids
.size())
205 sLog
.outErrorDb("`game_event_creature` game event id (%i) is out of range compared to max event id in `game_event`",event_id
);
210 GuidList
& crelist
= mGameEventCreatureGuids
[internal_event_id
];
211 crelist
.push_back(guid
);
213 } while( result
->NextRow() );
217 sLog
.outString( ">> Loaded %u creatures in game events", count
);
220 mGameEventGameobjectGuids
.resize(mGameEvent
.size()*2-1);
222 result
= WorldDatabase
.Query("SELECT gameobject.guid, game_event_gameobject.event "
223 "FROM gameobject JOIN game_event_gameobject ON gameobject.guid=game_event_gameobject.guid");
232 sLog
.outString(">> Loaded %u gameobjects in game events", count
);
237 barGoLink
bar( (int)result
->GetRowCount() );
240 Field
*fields
= result
->Fetch();
244 uint32 guid
= fields
[0].GetUInt32();
245 int16 event_id
= fields
[1].GetInt16();
247 int32 internal_event_id
= mGameEvent
.size() + event_id
- 1;
249 if(internal_event_id
< 0 || (size_t)internal_event_id
>= mGameEventGameobjectGuids
.size())
251 sLog
.outErrorDb("`game_event_gameobject` game event id (%i) is out of range compared to max event id in `game_event`",event_id
);
256 GuidList
& golist
= mGameEventGameobjectGuids
[internal_event_id
];
257 golist
.push_back(guid
);
259 } while( result
->NextRow() );
263 sLog
.outString( ">> Loaded %u gameobjects in game events", count
);
266 mGameEventModelEquip
.resize(mGameEvent
.size());
268 result
= WorldDatabase
.Query("SELECT creature.guid, game_event_model_equip.event, game_event_model_equip.modelid,"
270 "game_event_model_equip.equipment_id "
271 "FROM creature JOIN game_event_model_equip ON creature.guid=game_event_model_equip.guid");
280 sLog
.outString(">> Loaded %u model/equipment changes in game events", count
);
285 barGoLink
bar( (int)result
->GetRowCount() );
288 Field
*fields
= result
->Fetch();
291 uint32 guid
= fields
[0].GetUInt32();
292 uint16 event_id
= fields
[1].GetUInt16();
294 if(event_id
>= mGameEventModelEquip
.size())
296 sLog
.outErrorDb("`game_event_model_equip` game event id (%u) is out of range compared to max event id in `game_event`",event_id
);
301 ModelEquipList
& equiplist
= mGameEventModelEquip
[event_id
];
302 ModelEquip newModelEquipSet
;
303 newModelEquipSet
.modelid
= fields
[2].GetUInt32();
304 newModelEquipSet
.equipment_id
= fields
[3].GetUInt32();
305 newModelEquipSet
.equipement_id_prev
= 0;
306 newModelEquipSet
.modelid_prev
= 0;
308 if(newModelEquipSet
.equipment_id
> 0)
310 if(!sObjectMgr
.GetEquipmentInfo(newModelEquipSet
.equipment_id
))
312 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
);
317 equiplist
.push_back(std::pair
<uint32
, ModelEquip
>(guid
, newModelEquipSet
));
319 } while( result
->NextRow() );
323 sLog
.outString( ">> Loaded %u model/equipment changes in game events", count
);
326 mGameEventQuests
.resize(mGameEvent
.size());
328 result
= WorldDatabase
.Query("SELECT id, quest, event FROM game_event_creature_quest");
337 sLog
.outString(">> Loaded %u quests additions in game events", count
);
342 barGoLink
bar( (int)result
->GetRowCount() );
345 Field
*fields
= result
->Fetch();
348 uint32 id
= fields
[0].GetUInt32();
349 uint32 quest
= fields
[1].GetUInt32();
350 uint16 event_id
= fields
[2].GetUInt16();
352 if(event_id
>= mGameEventQuests
.size())
354 sLog
.outErrorDb("`game_event_creature_quest` game event id (%u) is out of range compared to max event id in `game_event`",event_id
);
359 QuestRelList
& questlist
= mGameEventQuests
[event_id
];
360 questlist
.push_back(QuestRelation(id
, quest
));
362 } while( result
->NextRow() );
366 sLog
.outString( ">> Loaded %u quests additions in game events", count
);
369 mGameEventPoolIds
.resize(mGameEvent
.size()*2-1);
371 result
= WorldDatabase
.Query("SELECT pool_template.entry, game_event_pool.event "
372 "FROM pool_template JOIN game_event_pool ON pool_template.entry = game_event_pool.pool_entry");
381 sLog
.outString(">> Loaded %u pools in game events", count
);
386 barGoLink
bar2( (int)result
->GetRowCount() );
389 Field
*fields
= result
->Fetch();
393 uint32 entry
= fields
[0].GetUInt16();
394 int16 event_id
= fields
[1].GetInt16();
396 int32 internal_event_id
= mGameEvent
.size() + event_id
- 1;
398 if (internal_event_id
< 0 || (size_t)internal_event_id
>= mGameEventPoolIds
.size())
400 sLog
.outErrorDb("`game_event_pool` game event id (%i) is out of range compared to max event id in `game_event`",event_id
);
404 if (!sPoolMgr
.CheckPool(entry
))
406 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
);
411 IdList
& poollist
= mGameEventPoolIds
[internal_event_id
];
412 poollist
.push_back(entry
);
414 } while( result
->NextRow() );
416 sLog
.outString( ">> Loaded %u pools in game events", count
);
421 uint32
GameEventMgr::Initialize() // return the next event delay in ms
423 m_ActiveEvents
.clear();
424 uint32 delay
= Update();
425 BASIC_LOG("Game Event system initialized." );
426 m_IsGameEventsInit
= true;
430 uint32
GameEventMgr::Update() // return the next event delay in ms
432 uint32 nextEventDelay
= max_ge_check_delay
; // 1 day
434 for (uint16 itr
= 1; itr
< mGameEvent
.size(); ++itr
)
436 //sLog.outErrorDb("Checking event %u",itr);
437 if (CheckOneGameEvent(itr
))
439 //DEBUG_LOG("GameEvent %u is active",itr->first);
440 if (!IsActiveEvent(itr
))
445 //DEBUG_LOG("GameEvent %u is not active",itr->first);
446 if (IsActiveEvent(itr
))
450 if (!m_IsGameEventsInit
)
452 int16 event_nid
= (-1) * (itr
);
453 // spawn all negative ones for this event
454 GameEventSpawn(event_nid
);
456 // disable any event specific quest (for cases where creature is spawned, but event not active).
457 UpdateEventQuests(itr
, false);
458 UpdateWorldStates(itr
, false);
462 calcDelay
= NextCheck(itr
);
463 if (calcDelay
< nextEventDelay
)
464 nextEventDelay
= calcDelay
;
466 BASIC_LOG("Next game event check in %u seconds.", nextEventDelay
+ 1);
467 return (nextEventDelay
+ 1) * IN_MILLISECONDS
; // Add 1 second to be sure event has started/stopped at next call
470 void GameEventMgr::UnApplyEvent(uint16 event_id
)
472 sLog
.outString("GameEvent %u \"%s\" removed.", event_id
, mGameEvent
[event_id
].description
.c_str());
473 // un-spawn positive event tagged objects
474 GameEventUnspawn(event_id
);
475 // spawn negative event tagget objects
476 int16 event_nid
= (-1) * event_id
;
477 GameEventSpawn(event_nid
);
478 // restore equipment or model
479 ChangeEquipOrModel(event_id
, false);
480 // Remove quests that are events only to non event npc
481 UpdateEventQuests(event_id
, false);
482 UpdateWorldStates(event_id
, false);
485 void GameEventMgr::ApplyNewEvent(uint16 event_id
)
487 if (sWorld
.getConfig(CONFIG_BOOL_EVENT_ANNOUNCE
))
488 sWorld
.SendWorldText(LANG_EVENTMESSAGE
, mGameEvent
[event_id
].description
.c_str());
490 sLog
.outString("GameEvent %u \"%s\" started.", event_id
, mGameEvent
[event_id
].description
.c_str());
491 // spawn positive event tagget objects
492 GameEventSpawn(event_id
);
493 // un-spawn negative event tagged objects
494 int16 event_nid
= (-1) * event_id
;
495 GameEventUnspawn(event_nid
);
496 // Change equipement or model
497 ChangeEquipOrModel(event_id
, true);
498 // Add quests that are events only to non event npc
499 UpdateEventQuests(event_id
, true);
500 UpdateWorldStates(event_id
, true);
503 void GameEventMgr::GameEventSpawn(int16 event_id
)
505 int32 internal_event_id
= mGameEvent
.size() + event_id
- 1;
507 if (internal_event_id
< 0 || (size_t)internal_event_id
>= mGameEventCreatureGuids
.size())
509 sLog
.outError("GameEventMgr::GameEventSpawn attempt access to out of range mGameEventCreatureGuids element %i (size: " SIZEFMTD
")",internal_event_id
,mGameEventCreatureGuids
.size());
513 for (GuidList::iterator itr
= mGameEventCreatureGuids
[internal_event_id
].begin();itr
!= mGameEventCreatureGuids
[internal_event_id
].end();++itr
)
515 // Add to correct cell
516 CreatureData
const* data
= sObjectMgr
.GetCreatureData(*itr
);
519 sObjectMgr
.AddCreatureToGrid(*itr
, data
);
521 // Spawn if necessary (loaded grids only)
522 Map
* map
= const_cast<Map
*>(sMapMgr
.CreateBaseMap(data
->mapid
));
523 // We use spawn coords to spawn
524 if(!map
->Instanceable() && map
->IsLoaded(data
->posX
,data
->posY
))
526 Creature
* pCreature
= new Creature
;
527 //DEBUG_LOG("Spawning creature %u",*itr);
528 if (!pCreature
->LoadFromDB(*itr
, map
))
540 if (internal_event_id
< 0 || (size_t)internal_event_id
>= mGameEventGameobjectGuids
.size())
542 sLog
.outError("GameEventMgr::GameEventSpawn attempt access to out of range mGameEventGameobjectGuids element %i (size: " SIZEFMTD
")",internal_event_id
,mGameEventGameobjectGuids
.size());
546 for (GuidList::iterator itr
= mGameEventGameobjectGuids
[internal_event_id
].begin();itr
!= mGameEventGameobjectGuids
[internal_event_id
].end();++itr
)
548 // Add to correct cell
549 GameObjectData
const* data
= sObjectMgr
.GetGOData(*itr
);
552 sObjectMgr
.AddGameobjectToGrid(*itr
, data
);
553 // Spawn if necessary (loaded grids only)
554 // this base map checked as non-instanced and then only existed
555 Map
* map
= const_cast<Map
*>(sMapMgr
.CreateBaseMap(data
->mapid
));
556 // We use current coords to unspawn, not spawn coords since creature can have changed grid
557 if(!map
->Instanceable() && map
->IsLoaded(data
->posX
, data
->posY
))
559 GameObject
* pGameobject
= new GameObject
;
560 //DEBUG_LOG("Spawning gameobject %u", *itr);
561 if (!pGameobject
->LoadFromDB(*itr
, map
))
567 if(pGameobject
->isSpawnedByDefault())
568 map
->Add(pGameobject
);
574 if (internal_event_id
< 0 || (size_t)internal_event_id
>= mGameEventPoolIds
.size())
576 sLog
.outError("GameEventMgr::GameEventSpawn attempt access to out of range mGameEventPoolIds element %i (size: " SIZEFMTD
")",internal_event_id
,mGameEventPoolIds
.size());
580 for (IdList::iterator itr
= mGameEventPoolIds
[internal_event_id
].begin();itr
!= mGameEventPoolIds
[internal_event_id
].end();++itr
)
581 sPoolMgr
.SpawnPool(*itr
, true);
584 void GameEventMgr::GameEventUnspawn(int16 event_id
)
586 int32 internal_event_id
= mGameEvent
.size() + event_id
- 1;
588 if (internal_event_id
< 0 || (size_t)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());
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
= sObjectMgr
.GetCreatureData(*itr
) )
599 sObjectMgr
.RemoveCreatureFromGrid(*itr
, data
);
601 if (Creature
* pCreature
= ObjectAccessor::GetCreatureInWorld(ObjectGuid(HIGHGUID_UNIT
, data
->id
, *itr
)))
602 pCreature
->AddObjectToRemoveList();
606 if (internal_event_id
< 0 || (size_t)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());
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
= sObjectMgr
.GetGOData(*itr
))
617 sObjectMgr
.RemoveGameobjectFromGrid(*itr
, data
);
619 if( GameObject
* pGameobject
= ObjectAccessor::GetGameObjectInWorld(ObjectGuid(HIGHGUID_GAMEOBJECT
, data
->id
, *itr
)) )
620 pGameobject
->AddObjectToRemoveList();
623 if (internal_event_id
< 0 || (size_t)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());
629 for (IdList::iterator itr
= mGameEventPoolIds
[internal_event_id
].begin();itr
!= mGameEventPoolIds
[internal_event_id
].end();++itr
)
631 sPoolMgr
.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
= sObjectMgr
.GetCreatureData(itr
->first
);
645 if (Creature
* pCreature
= ObjectAccessor::GetCreatureInWorld(ObjectGuid(HIGHGUID_UNIT
, data
->id
, itr
->first
)))
649 itr
->second
.equipement_id_prev
= pCreature
->GetCurrentEquipmentId();
650 itr
->second
.modelid_prev
= pCreature
->GetDisplayId();
651 pCreature
->LoadEquipment(itr
->second
.equipment_id
, true);
652 if (itr
->second
.modelid
>0 && itr
->second
.modelid_prev
!= itr
->second
.modelid
)
654 CreatureModelInfo
const *minfo
= sObjectMgr
.GetCreatureModelInfo(itr
->second
.modelid
);
657 pCreature
->SetDisplayId(itr
->second
.modelid
);
658 pCreature
->SetNativeDisplayId(itr
->second
.modelid
);
659 pCreature
->SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS
,minfo
->bounding_radius
);
660 pCreature
->SetFloatValue(UNIT_FIELD_COMBATREACH
,minfo
->combat_reach
);
666 pCreature
->LoadEquipment(itr
->second
.equipement_id_prev
, true);
667 if (itr
->second
.modelid_prev
>0 && itr
->second
.modelid_prev
!= itr
->second
.modelid
)
669 CreatureModelInfo
const *minfo
= sObjectMgr
.GetCreatureModelInfo(itr
->second
.modelid_prev
);
672 pCreature
->SetDisplayId(itr
->second
.modelid_prev
);
673 pCreature
->SetNativeDisplayId(itr
->second
.modelid_prev
);
674 pCreature
->SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS
,minfo
->bounding_radius
);
675 pCreature
->SetFloatValue(UNIT_FIELD_COMBATREACH
,minfo
->combat_reach
);
680 else // If not spawned
682 CreatureData
const* data2
= sObjectMgr
.GetCreatureData(itr
->first
);
683 if (data2
&& activate
)
685 CreatureInfo
const *cinfo
= ObjectMgr::GetCreatureTemplate(data2
->id
);
686 uint32 display_id
= sObjectMgr
.ChooseDisplayId(0,cinfo
,data2
);
687 CreatureModelInfo
const *minfo
= sObjectMgr
.GetCreatureModelRandomGender(display_id
);
689 display_id
= minfo
->modelid
;
691 if (data2
->equipmentId
== 0)
692 itr
->second
.equipement_id_prev
= cinfo
->equipmentId
;
693 else if (data2
->equipmentId
!= -1)
694 itr
->second
.equipement_id_prev
= data
->equipmentId
;
695 itr
->second
.modelid_prev
= display_id
;
698 // now last step: put in data
699 // just to have write access to it
700 CreatureData
& data2
= sObjectMgr
.NewOrExistCreatureData(itr
->first
);
703 data2
.displayid
= itr
->second
.modelid
;
704 data2
.equipmentId
= itr
->second
.equipment_id
;
708 data2
.displayid
= itr
->second
.modelid_prev
;
709 data2
.equipmentId
= itr
->second
.equipement_id_prev
;
714 void GameEventMgr::UpdateEventQuests(uint16 event_id
, bool Activate
)
716 QuestRelList::iterator itr
;
717 for (itr
= mGameEventQuests
[event_id
].begin();itr
!= mGameEventQuests
[event_id
].end();++itr
)
719 QuestRelations
&CreatureQuestMap
= sObjectMgr
.mCreatureQuestRelations
;
720 if (Activate
) // Add the pair(id,quest) to the multimap
721 CreatureQuestMap
.insert(QuestRelations::value_type(itr
->first
, itr
->second
));
723 { // Remove the pair(id,quest) from the multimap
724 QuestRelations::iterator qitr
= CreatureQuestMap
.find(itr
->first
);
725 if (qitr
== CreatureQuestMap
.end())
727 QuestRelations::iterator lastElement
= CreatureQuestMap
.upper_bound(itr
->first
);
728 for ( ;qitr
!= lastElement
;++qitr
)
730 if (qitr
->second
== itr
->second
)
732 CreatureQuestMap
.erase(qitr
); // iterator is now no more valid
733 break; // but we can exit loop since the element is found
740 void GameEventMgr::UpdateWorldStates(uint16 event_id
, bool Activate
)
742 GameEventData
const& event
= mGameEvent
[event_id
];
743 if (event
.holiday_id
!= HOLIDAY_NONE
)
745 BattleGroundTypeId bgTypeId
= BattleGroundMgr::WeekendHolidayIdToBGType(event
.holiday_id
);
746 if (bgTypeId
!= BATTLEGROUND_TYPE_NONE
)
748 BattlemasterListEntry
const * bl
= sBattlemasterListStore
.LookupEntry(bgTypeId
);
749 if (bl
&& bl
->HolidayWorldStateId
)
752 sBattleGroundMgr
.BuildUpdateWorldStatePacket(&data
, bl
->HolidayWorldStateId
, Activate
? 1 : 0);
753 sWorld
.SendGlobalMessage(&data
);
759 GameEventMgr::GameEventMgr()
761 m_IsGameEventsInit
= false;
764 MANGOS_DLL_SPEC
bool IsHolidayActive( HolidayIds id
)
766 if (id
== HOLIDAY_NONE
)
769 GameEventMgr::GameEventDataMap
const& events
= sGameEventMgr
.GetEventMap();
770 GameEventMgr::ActiveEvents
const& ae
= sGameEventMgr
.GetActiveEventList();
772 for(GameEventMgr::ActiveEvents::const_iterator itr
= ae
.begin(); itr
!= ae
.end(); ++itr
)
773 if (events
[*itr
].holiday_id
== id
)