mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-03-15 21:45:12 +00:00
fix(Core/Events): Fix multi-stage holiday events ending early on restart (#25032)
Co-authored-by: blinkysc <blinkysc@users.noreply.github.com> Co-authored-by: sudlud <sudlud@users.noreply.github.com>
This commit is contained in:
@@ -1961,21 +1961,23 @@ void GameEventMgr::SetHolidayEventTime(GameEventData& event)
|
||||
bool singleDate = ((holiday->Date[0] >> 24) & 0x1F) == 31; // Events with fixed date within year have - 1
|
||||
|
||||
time_t curTime = GameTime::GetGameTime().count();
|
||||
for (uint8 i = 0; i < MAX_HOLIDAY_DATES && holiday->Date[i]; ++i)
|
||||
|
||||
if (!singleDate)
|
||||
{
|
||||
time_t start = HolidayDateCalculator::FindStartTimeForStage(
|
||||
holiday->Date, MAX_HOLIDAY_DATES, stageOffset, event.Length, curTime);
|
||||
if (start)
|
||||
event.Start = start;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
for (uint8 i = 0; i < MAX_HOLIDAY_DATES && holiday->Date[i]; ++i)
|
||||
{
|
||||
uint32 date = holiday->Date[i];
|
||||
|
||||
tm timeInfo;
|
||||
if (singleDate)
|
||||
{
|
||||
timeInfo = Acore::Time::TimeBreakdown(curTime);
|
||||
timeInfo.tm_year -= 1; // First try last year (event active through New Year)
|
||||
}
|
||||
else
|
||||
{
|
||||
timeInfo.tm_year = ((date >> 24) & 0x1F) + 100;
|
||||
}
|
||||
tm timeInfo = Acore::Time::TimeBreakdown(curTime);
|
||||
timeInfo.tm_year -= 1; // First try last year (event active through New Year)
|
||||
|
||||
timeInfo.tm_mon = (date >> 20) & 0xF;
|
||||
timeInfo.tm_mday = ((date >> 14) & 0x3F) + 1;
|
||||
@@ -1986,12 +1988,12 @@ void GameEventMgr::SetHolidayEventTime(GameEventData& event)
|
||||
|
||||
// try to get next start time (skip past dates)
|
||||
time_t startTime = mktime(&timeInfo);
|
||||
if (curTime < startTime + event.Length * MINUTE)
|
||||
if (curTime < startTime + stageOffset + event.Length * MINUTE)
|
||||
{
|
||||
event.Start = startTime + stageOffset;
|
||||
break;
|
||||
}
|
||||
else if (singleDate)
|
||||
else
|
||||
{
|
||||
tm tmCopy = Acore::Time::TimeBreakdown(curTime);
|
||||
int year = tmCopy.tm_year; // This year
|
||||
@@ -2000,11 +2002,6 @@ void GameEventMgr::SetHolidayEventTime(GameEventData& event)
|
||||
event.Start = mktime(&tmCopy) + stageOffset;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
// date is due and not a singleDate event, try with next DBC date (dynamically calculated or overridden by game_event.start_time)
|
||||
// if none is found we don't modify start date and use the one in game_event
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -580,3 +580,27 @@ std::vector<uint32_t> HolidayDateCalculator::GetDarkmoonFaireDates(int locationO
|
||||
|
||||
return dates;
|
||||
}
|
||||
|
||||
time_t HolidayDateCalculator::FindStartTimeForStage(const uint32_t* packedDates, uint8_t numDates,
|
||||
time_t stageOffset, uint32_t stageLengthMinutes, time_t curTime)
|
||||
{
|
||||
for (uint8_t i = 0; i < numDates && packedDates[i]; ++i)
|
||||
{
|
||||
uint32_t date = packedDates[i];
|
||||
|
||||
std::tm timeInfo = {};
|
||||
timeInfo.tm_year = static_cast<int>(((date >> 24) & 0x1F)) + 100;
|
||||
timeInfo.tm_mon = static_cast<int>((date >> 20) & 0xF);
|
||||
timeInfo.tm_mday = static_cast<int>(((date >> 14) & 0x3F)) + 1;
|
||||
timeInfo.tm_hour = static_cast<int>((date >> 6) & 0x1F);
|
||||
timeInfo.tm_min = static_cast<int>(date & 0x3F);
|
||||
timeInfo.tm_sec = 0;
|
||||
timeInfo.tm_isdst = -1;
|
||||
|
||||
time_t startTime = mktime(&timeInfo);
|
||||
if (curTime < startTime + stageOffset + static_cast<time_t>(stageLengthMinutes) * 60)
|
||||
return startTime + stageOffset;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -100,6 +100,13 @@ public:
|
||||
// Returns packed dates for all occurrences in the year range
|
||||
static std::vector<uint32_t> GetDarkmoonFaireDates(int locationOffset, int startYear, int numYears, int dayOffset = 0);
|
||||
|
||||
// Find the correct stage start time from a list of packed holiday dates.
|
||||
// For multi-stage holidays, stageOffset is the cumulative duration (in seconds) of all prior stages.
|
||||
// stageLengthMinutes is the duration of the current stage in minutes.
|
||||
// Returns the computed stage start time (startTime + stageOffset), or 0 if no valid date found.
|
||||
static time_t FindStartTimeForStage(const uint32_t* packedDates, uint8_t numDates,
|
||||
time_t stageOffset, uint32_t stageLengthMinutes, time_t curTime);
|
||||
|
||||
private:
|
||||
// Julian Date conversions for lunar calculations
|
||||
static double DateToJulianDay(int year, int month, double day);
|
||||
|
||||
Reference in New Issue
Block a user