Calendar/GameEvents: Store + send holiday data (#20117)

Close: #16845
(cherry picked from commit 951fa46fe9)
This commit is contained in:
Gerhood
2017-10-27 14:59:22 +02:00
committed by funjoker
parent 2cb3d9514d
commit 4024df122a
3 changed files with 106 additions and 8 deletions

View File

@@ -0,0 +1,9 @@
ALTER TABLE `game_event` ADD COLUMN `holidayStage` TINYINT UNSIGNED NOT NULL DEFAULT '0' AFTER `holiday`;
UPDATE `game_event` SET `holiday` = 424 WHERE `eventEntry` = 64; -- Correct Kalu'ak Fishing Derby
UPDATE `game_event` SET `holiday` = 0 WHERE `eventEntry` = 63;
UPDATE `game_event` SET `holiday` = 374 WHERE `eventEntry` = 23; -- Darkmoon construction
-- UPDATE `game_event` SET `holiday` = 375 WHERE `eventEntry` = 110;
UPDATE `game_event` SET `holiday` = 376 WHERE `eventEntry` = 62;
UPDATE `game_event` SET `holidayStage` = 1 WHERE `eventEntry` IN (1, 2, 7, 8, 9, 10, 11, 12, 18, 19, 20, 21, 23, 26, 50, 51, 53, 54, 62/*, 110*/);
UPDATE `game_event` SET `holidayStage` = 2 WHERE `eventEntry` IN (3, 4, 5, 24);

View File

@@ -219,8 +219,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();
@@ -248,10 +248,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
{
@@ -265,12 +268,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;
}
SetHolidayEventTime(pGameEvent);
}
pGameEvent.description = fields[6].GetString();
++count;
}
while (result->NextRow());
@@ -1682,6 +1691,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)

View File

@@ -67,6 +67,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
@@ -138,6 +139,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;