diff options
| author | Gerhood <mrambrius@gmail.com> | 2017-10-27 14:59:22 +0200 |
|---|---|---|
| committer | Keader <keader.android@gmail.com> | 2017-10-27 10:59:22 -0200 |
| commit | 951fa46fe9b14a9e275ac9306b2346959e40e3e5 (patch) | |
| tree | 920c104065c90d759e156222fc5b596d1327ad5e /src | |
| parent | 04271388f8ba5160de0411451673a67a6828ae8a (diff) | |
Calendar/GameEvents: Store + send holiday data (#20117)
Close: #16845
Diffstat (limited to 'src')
| -rw-r--r-- | src/server/game/Events/GameEventMgr.cpp | 142 | ||||
| -rw-r--r-- | src/server/game/Events/GameEventMgr.h | 4 | ||||
| -rw-r--r-- | src/server/game/Handlers/CalendarHandler.cpp | 9 | ||||
| -rw-r--r-- | src/server/game/World/World.cpp | 3 |
4 files changed, 144 insertions, 14 deletions
diff --git a/src/server/game/Events/GameEventMgr.cpp b/src/server/game/Events/GameEventMgr.cpp index 307f5674b9c..db79a5a37a0 100644 --- a/src/server/game/Events/GameEventMgr.cpp +++ b/src/server/game/Events/GameEventMgr.cpp @@ -218,8 +218,8 @@ void GameEventMgr::LoadFromDB() { { uint32 oldMSTime = getMSTime(); - // 0 1 2 3 4 5 6 7 8 - QueryResult result = WorldDatabase.Query("SELECT eventEntry, UNIX_TIMESTAMP(start_time), UNIX_TIMESTAMP(end_time), occurence, length, holiday, description, world_event, announce FROM game_event"); + // 0 1 2 3 4 5 6 7 8 9 + QueryResult result = WorldDatabase.Query("SELECT eventEntry, UNIX_TIMESTAMP(start_time), UNIX_TIMESTAMP(end_time), occurence, length, holiday, holidayStage, description, world_event, announce FROM game_event"); if (!result) { mGameEvent.clear(); @@ -247,10 +247,13 @@ void GameEventMgr::LoadFromDB() pGameEvent.occurence = fields[3].GetUInt64(); pGameEvent.length = fields[4].GetUInt64(); pGameEvent.holiday_id = HolidayIds(fields[5].GetUInt32()); - - pGameEvent.state = (GameEventState)(fields[7].GetUInt8()); + pGameEvent.holidayStage = fields[6].GetUInt8(); + pGameEvent.description = fields[7].GetString(); + pGameEvent.state = (GameEventState)(fields[8].GetUInt8()); + pGameEvent.announce = fields[9].GetUInt8(); pGameEvent.nextstart = 0; - pGameEvent.announce = fields[8].GetUInt8(); + + ++count; if (pGameEvent.length == 0 && pGameEvent.state == GAMEEVENT_NORMAL) // length>0 is validity check { @@ -264,12 +267,18 @@ void GameEventMgr::LoadFromDB() { TC_LOG_ERROR("sql.sql", "`game_event`: game event id (%i) contains nonexisting holiday id %u.", event_id, pGameEvent.holiday_id); pGameEvent.holiday_id = HOLIDAY_NONE; + continue; + } + if (pGameEvent.holidayStage > MAX_HOLIDAY_DURATIONS) + { + TC_LOG_ERROR("sql.sql", "`game_event` game event id (%i) has out of range holidayStage %u.", event_id, pGameEvent.holidayStage); + pGameEvent.holidayStage = 0; + continue; } - } - pGameEvent.description = fields[6].GetString(); + SetHolidayEventTime(pGameEvent); + } - ++count; } while (result->NextRow()); @@ -929,6 +938,45 @@ void GameEventMgr::LoadFromDB() } } +void GameEventMgr::LoadHolidayDates() +{ + uint32 oldMSTime = getMSTime(); + + // 0 1 2 + QueryResult result = WorldDatabase.Query("SELECT id, date_id, date_value FROM holiday_dates"); + + if (!result) + { + TC_LOG_INFO("server.loading", ">> Loaded 0 holiday dates. DB table `holiday_dates` is empty."); + return; + } + + uint32 count = 0; + do + { + Field* fields = result->Fetch(); + uint32 holidayId = fields[0].GetUInt32(); + HolidaysEntry* entry = const_cast<HolidaysEntry*>(sHolidaysStore.LookupEntry(holidayId)); + if (!entry) + { + TC_LOG_ERROR("sql.sql", "holiday_dates entry has invalid holiday id %u.", holidayId); + continue; + } + uint8 dateId = fields[1].GetUInt8(); + if (dateId >= MAX_HOLIDAY_DATES) + { + TC_LOG_ERROR("sql.sql", "holiday_dates entry has out of range date_id %u.", dateId); + continue; + } + entry->Date[dateId] = fields[2].GetUInt32(); + modifiedHolidays.insert(entry->Id); + ++count; + + } while (result->NextRow()); + + TC_LOG_INFO("server.loading", ">> Loaded %u holiday dates in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); +} + uint32 GameEventMgr::GetNPCFlag(Creature* cr) { uint32 mask = 0; @@ -1667,6 +1715,84 @@ void GameEventMgr::RunSmartAIScripts(uint16 event_id, bool activate) }); } +void GameEventMgr::SetHolidayEventTime(GameEventData& event) +{ + if (!event.holidayStage) // Ignore holiday + return; + + const HolidaysEntry* holiday = sHolidaysStore.LookupEntry(event.holiday_id); + + if (!holiday->Date[0] || !holiday->Duration[0]) // Invalid definitions + { + TC_LOG_ERROR("sql.sql", "Missing date or duration for holiday %u.", event.holiday_id); + return; + } + + uint8 stageIndex = event.holidayStage - 1; + event.length = holiday->Duration[stageIndex] * HOUR / MINUTE; + + time_t stageOffset = 0; + for (int i = 0; i < stageIndex; ++i) + stageOffset += holiday->Duration[i] * HOUR; + + switch (holiday->CalendarFilterType) + { + case -1: // Yearly + event.occurence = YEAR / MINUTE; // Not all too useful + break; + case 0: // Weekly + event.occurence = WEEK / MINUTE; + break; + case 1: // Defined dates only (Darkmoon Faire) + break; + case 2: // Only used for looping events (Call to Arms) + break; + } + + if (holiday->Looping) + { + event.occurence = 0; + for (int i = 0; i < MAX_HOLIDAY_DURATIONS && holiday->Duration[i]; ++i) + event.occurence += holiday->Duration[i] * HOUR / MINUTE; + } + + bool singleDate = ((holiday->Date[0] >> 24) & 0x1F) == 31; // Events with fixed date within year have - 1 + + time_t curTime = time(NULL); + for (int i = 0; i < MAX_HOLIDAY_DATES && holiday->Date[i]; ++i) + { + uint32 date = holiday->Date[i]; + + tm timeInfo; + if (singleDate) + timeInfo.tm_year = localtime(&curTime)->tm_year - 1; // First try last year (event active through New Year) + else + timeInfo.tm_year = ((date >> 24) & 0x1F) + 100; + + timeInfo.tm_mon = (date >> 20) & 0xF; + timeInfo.tm_mday = ((date >> 14) & 0x3F) + 1; + timeInfo.tm_hour = (date >> 6) & 0x1F; + timeInfo.tm_min = date & 0x3F; + timeInfo.tm_sec = 0; + timeInfo.tm_isdst = -1; + tm tmCopy = timeInfo; + + time_t startTime = mktime(&timeInfo); + if (curTime < startTime + event.length * MINUTE) + { + event.start = startTime + stageOffset; + return; + } + else if (singleDate) + { + tmCopy.tm_year = localtime(&curTime)->tm_year; // This year + event.start = mktime(&tmCopy) + stageOffset; + return; + } + } + TC_LOG_ERROR("sql.sql", "No suitable start date found for holiday %u.", event.holiday_id); +} + bool IsHolidayActive(HolidayIds id) { if (id == HOLIDAY_NONE) diff --git a/src/server/game/Events/GameEventMgr.h b/src/server/game/Events/GameEventMgr.h index bee6dfc8fb3..f7f88ebfdd5 100644 --- a/src/server/game/Events/GameEventMgr.h +++ b/src/server/game/Events/GameEventMgr.h @@ -68,6 +68,7 @@ struct GameEventData uint32 occurence; // time between end and start uint32 length; // length of the event (minutes) after finishing all conditions HolidayIds holiday_id; + uint8 holidayStage; GameEventState state; // state of the game event, these are saved into the game_event table on change! GameEventConditionMap conditions; // conditions to finish std::set<uint16 /*gameevent id*/> prerequisite_events; // events that must be completed before starting this event @@ -114,6 +115,7 @@ class TC_GAME_API GameEventMgr bool CheckOneGameEvent(uint16 entry) const; uint32 NextCheck(uint16 entry) const; void LoadFromDB(); + void LoadHolidayDates(); uint32 Update(); bool IsActiveEvent(uint16 event_id) { return (m_ActiveEvents.find(event_id) != m_ActiveEvents.end()); } uint32 StartSystem(); @@ -147,6 +149,7 @@ class TC_GAME_API GameEventMgr bool hasGameObjectQuestActiveEventExcept(uint32 quest_id, uint16 event_id); bool hasCreatureActiveEventExcept(ObjectGuid::LowType creature_guid, uint16 event_id); bool hasGameObjectActiveEventExcept(ObjectGuid::LowType go_guid, uint16 event_id); + void SetHolidayEventTime(GameEventData& event); typedef std::list<ObjectGuid::LowType> GuidList; typedef std::list<uint32> IdList; @@ -181,6 +184,7 @@ class TC_GAME_API GameEventMgr public: GameEventGuidMap mGameEventCreatureGuids; GameEventGuidMap mGameEventGameobjectGuids; + std::set<uint32> modifiedHolidays; }; #define sGameEventMgr GameEventMgr::instance() diff --git a/src/server/game/Handlers/CalendarHandler.cpp b/src/server/game/Handlers/CalendarHandler.cpp index 6d884ca2ee9..4384ff82474 100644 --- a/src/server/game/Handlers/CalendarHandler.cpp +++ b/src/server/game/Handlers/CalendarHandler.cpp @@ -41,6 +41,7 @@ Copied events should probably have a new owner #include "CharacterCache.h" #include "DatabaseEnv.h" #include "DBCStores.h" +#include "GameEventMgr.h" #include "Guild.h" #include "GuildMgr.h" #include "InstanceSaveMgr.h" @@ -151,12 +152,10 @@ void WorldSession::HandleCalendarGetCalendar(WorldPacket& /*recvData*/) data << uint32(boundCounter); data.append(dataBuffer); - /// @todo Fix this, how we do know how many and what holidays to send? - uint32 holidayCount = 0; - data << uint32(holidayCount); - for (uint32 i = 0; i < holidayCount; ++i) + data << uint32(sGameEventMgr->modifiedHolidays.size()); + for (uint32 entry : sGameEventMgr->modifiedHolidays) { - HolidaysEntry const* holiday = sHolidaysStore.LookupEntry(666); + HolidaysEntry const* holiday = sHolidaysStore.LookupEntry(entry); data << uint32(holiday->Id); // m_ID data << uint32(holiday->Region); // m_region, might be looping diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index a403ec9e848..f4e1a7b2d74 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -1766,7 +1766,8 @@ void World::SetInitialWorldSettings() sPoolMgr->LoadFromDB(); TC_LOG_INFO("server.loading", "Loading Game Event Data..."); // must be after loading pools fully - sGameEventMgr->LoadFromDB(); + sGameEventMgr->LoadHolidayDates(); // Must be after loading DBC + sGameEventMgr->LoadFromDB(); // Must be after loading holiday dates TC_LOG_INFO("server.loading", "Loading UNIT_NPC_FLAG_SPELLCLICK Data..."); // must be after LoadQuests sObjectMgr->LoadNPCSpellClickSpells(); |
