[10041] Use for spell 49145 and ranks for decrease SPELL_DIRECT_DAMAGE damage.
[getmangos.git] / src / game / GameEventMgr.cpp
blob04275c311d7922b477642c1fbc988a6fb7a22fd3
1 /*
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"
20 #include "World.h"
21 #include "ObjectMgr.h"
22 #include "ObjectGuid.h"
23 #include "PoolManager.h"
24 #include "ProgressBar.h"
25 #include "Language.h"
26 #include "Log.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) )
39 return true;
40 else
41 return false;
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);
56 uint32 delay;
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);
66 else
67 return delay;
70 void GameEventMgr::StartEvent( uint16 event_id, bool overwrite )
72 AddActiveEvent(event_id);
73 ApplyNewEvent(event_id);
74 if(overwrite)
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);
86 if(overwrite)
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");
98 if( !result )
100 sLog.outString(">> Table game_event is empty.");
101 sLog.outString();
102 return;
105 Field *fields = result->Fetch();
107 uint32 max_event_id = fields[0].GetUInt16();
108 delete result;
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");
114 if( !result )
116 mGameEvent.clear();
117 sLog.outString(">> Table game_event is empty!");
118 sLog.outString();
119 return;
122 uint32 count = 0;
125 barGoLink bar( (int)result->GetRowCount() );
128 ++count;
129 Field *fields = result->Fetch();
131 bar.step();
133 uint16 event_id = fields[0].GetUInt16();
134 if(event_id==0)
136 sLog.outErrorDb("`game_event` game event id (%i) is reserved and can't be used.",event_id);
137 continue;
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);
153 continue;
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() );
168 delete result;
170 sLog.outString();
171 sLog.outString( ">> Loaded %u game events", count );
174 mGameEventCreatureGuids.resize(mGameEvent.size()*2-1);
175 // 1 2
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");
179 count = 0;
180 if( !result )
182 barGoLink bar(1);
183 bar.step();
185 sLog.outString();
186 sLog.outString(">> Loaded %u creatures in game events", count );
188 else
191 barGoLink bar( (int)result->GetRowCount() );
194 Field *fields = result->Fetch();
196 bar.step();
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);
206 continue;
209 ++count;
210 GuidList& crelist = mGameEventCreatureGuids[internal_event_id];
211 crelist.push_back(guid);
213 } while( result->NextRow() );
214 delete result;
216 sLog.outString();
217 sLog.outString( ">> Loaded %u creatures in game events", count );
220 mGameEventGameobjectGuids.resize(mGameEvent.size()*2-1);
221 // 1 2
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");
225 count = 0;
226 if( !result )
228 barGoLink bar(1);
229 bar.step();
231 sLog.outString();
232 sLog.outString(">> Loaded %u gameobjects in game events", count );
234 else
237 barGoLink bar( (int)result->GetRowCount() );
240 Field *fields = result->Fetch();
242 bar.step();
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);
252 continue;
255 ++count;
256 GuidList& golist = mGameEventGameobjectGuids[internal_event_id];
257 golist.push_back(guid);
259 } while( result->NextRow() );
260 delete result;
262 sLog.outString();
263 sLog.outString( ">> Loaded %u gameobjects in game events", count );
266 mGameEventModelEquip.resize(mGameEvent.size());
267 // 0 1 2
268 result = WorldDatabase.Query("SELECT creature.guid, game_event_model_equip.event, game_event_model_equip.modelid,"
269 // 3
270 "game_event_model_equip.equipment_id "
271 "FROM creature JOIN game_event_model_equip ON creature.guid=game_event_model_equip.guid");
273 count = 0;
274 if( !result )
276 barGoLink bar(1);
277 bar.step();
279 sLog.outString();
280 sLog.outString(">> Loaded %u model/equipment changes in game events", count );
282 else
285 barGoLink bar( (int)result->GetRowCount() );
288 Field *fields = result->Fetch();
290 bar.step();
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);
297 continue;
300 ++count;
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);
313 continue;
317 equiplist.push_back(std::pair<uint32, ModelEquip>(guid, newModelEquipSet));
319 } while( result->NextRow() );
320 delete result;
322 sLog.outString();
323 sLog.outString( ">> Loaded %u model/equipment changes in game events", count );
326 mGameEventQuests.resize(mGameEvent.size());
327 // 0 1 2
328 result = WorldDatabase.Query("SELECT id, quest, event FROM game_event_creature_quest");
330 count = 0;
331 if( !result )
333 barGoLink bar(1);
334 bar.step();
336 sLog.outString();
337 sLog.outString(">> Loaded %u quests additions in game events", count );
339 else
342 barGoLink bar( (int)result->GetRowCount() );
345 Field *fields = result->Fetch();
347 bar.step();
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);
355 continue;
358 ++count;
359 QuestRelList& questlist = mGameEventQuests[event_id];
360 questlist.push_back(QuestRelation(id, quest));
362 } while( result->NextRow() );
363 delete result;
365 sLog.outString();
366 sLog.outString( ">> Loaded %u quests additions in game events", count );
369 mGameEventPoolIds.resize(mGameEvent.size()*2-1);
370 // 1 2
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");
374 count = 0;
375 if( !result )
377 barGoLink bar2(1);
378 bar2.step();
380 sLog.outString();
381 sLog.outString(">> Loaded %u pools in game events", count );
383 else
386 barGoLink bar2( (int)result->GetRowCount() );
389 Field *fields = result->Fetch();
391 bar2.step();
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);
401 continue;
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);
407 continue;
410 ++count;
411 IdList& poollist = mGameEventPoolIds[internal_event_id];
412 poollist.push_back(entry);
414 } while( result->NextRow() );
415 sLog.outString();
416 sLog.outString( ">> Loaded %u pools in game events", count );
417 delete result;
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;
427 return delay;
430 uint32 GameEventMgr::Update() // return the next event delay in ms
432 uint32 nextEventDelay = max_ge_check_delay; // 1 day
433 uint32 calcDelay;
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))
441 StartEvent(itr);
443 else
445 //DEBUG_LOG("GameEvent %u is not active",itr->first);
446 if (IsActiveEvent(itr))
447 StopEvent(itr);
448 else
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());
510 return;
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);
517 if (data)
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))
530 delete pCreature;
532 else
534 map->Add(pCreature);
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());
543 return;
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);
550 if (data)
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))
563 delete pGameobject;
565 else
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());
577 return;
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());
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 = 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());
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 = 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());
626 return;
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);
641 if(!data)
642 continue;
644 // Update if spawned
645 if (Creature* pCreature = ObjectAccessor::GetCreatureInWorld(ObjectGuid(HIGHGUID_UNIT, data->id, itr->first)))
647 if (activate)
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);
655 if (minfo)
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 );
664 else
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);
670 if (minfo)
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);
688 if (minfo)
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);
701 if (activate)
703 data2.displayid = itr->second.modelid;
704 data2.equipmentId = itr->second.equipment_id;
706 else
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));
722 else
723 { // Remove the pair(id,quest) from the multimap
724 QuestRelations::iterator qitr = CreatureQuestMap.find(itr->first);
725 if (qitr == CreatureQuestMap.end())
726 continue;
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)
751 WorldPacket data;
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)
767 return false;
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)
774 return true;
776 return false;