From 0f2c092df7b43793956265866b3d4c5c3e305789 Mon Sep 17 00:00:00 2001 From: UltraNix <80540499+UltraNix@users.noreply.github.com> Date: Mon, 17 Jan 2022 04:25:17 +0100 Subject: [PATCH] =?UTF-8?q?fix(Core/Events):=20Prevent=20seasonal=20quests?= =?UTF-8?q?=20from=20resetting=20at=20server=20re=E2=80=A6=20(#9708)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix(Core/Events): Prevent seasonal quests from resetting at server restart. Source: TrinityCore. Fixes #6973 * Update. * Update. * Update. --- src/server/game/Events/GameEventMgr.cpp | 23 +++++++++++++++++++++-- src/server/game/Events/GameEventMgr.h | 2 ++ src/server/scripts/World/npcs_special.cpp | 7 ++++++- 3 files changed, 29 insertions(+), 3 deletions(-) diff --git a/src/server/game/Events/GameEventMgr.cpp b/src/server/game/Events/GameEventMgr.cpp index 60cfd0925..2d4acc183 100644 --- a/src/server/game/Events/GameEventMgr.cpp +++ b/src/server/game/Events/GameEventMgr.cpp @@ -153,6 +153,13 @@ bool GameEventMgr::StartEvent(uint16 event_id, bool overwrite) if (IsActiveEvent(event_id)) sScriptMgr->OnGameEventStart(event_id); + // When event is started, set its worldstate to current time + auto itr = _gameEventSeasonalQuestsMap.find(event_id); + if (itr != _gameEventSeasonalQuestsMap.end() && !itr->second.empty()) + { + sWorld->setWorldState(event_id, sWorld->GetGameTime()); + } + return false; } else @@ -191,6 +198,9 @@ void GameEventMgr::StopEvent(uint16 event_id, bool overwrite) RemoveActiveEvent(event_id); UnApplyEvent(event_id); + // When event is stopped, clean up its worldstate + sWorld->setWorldState(event_id, 0); + if (overwrite && !serverwide_evt) { data.start = time(nullptr) - data.length * MINUTE; @@ -832,6 +842,7 @@ void GameEventMgr::LoadFromDB() } questTemplate->SetEventIdForQuest((uint16)eventEntry); + _gameEventSeasonalQuestsMap[eventEntry].push_back(questId); ++count; } while (result->NextRow()); @@ -1150,6 +1161,9 @@ uint32 GameEventMgr::Update() // return the next e } else { + // If event is inactive, periodically clean up its worldstate + sWorld->setWorldState(itr, 0); + if (IsActiveEvent(itr)) { // Xinef: do not deactivate internal events on whim @@ -1207,8 +1221,6 @@ void GameEventMgr::UnApplyEvent(uint16 event_id) UpdateEventNPCVendor(event_id, false); // update bg holiday UpdateBattlegroundSettings(); - // check for seasonal quest reset. - sWorld->ResetEventSeasonalQuests(event_id); } void GameEventMgr::ApplyNewEvent(uint16 event_id) @@ -1238,6 +1250,13 @@ void GameEventMgr::ApplyNewEvent(uint16 event_id) UpdateEventNPCVendor(event_id, true); // update bg holiday UpdateBattlegroundSettings(); + + // If event's worldstate is 0, it means the event hasn't been started yet. In that case, reset seasonal quests. + // When event ends (if it expires or if it's stopped via commands) worldstate will be set to 0 again, ready for another seasonal quest reset. + if (sWorld->getWorldState(event_id) == 0) + { + sWorld->ResetEventSeasonalQuests(event_id); + } } void GameEventMgr::UpdateEventNPCFlags(uint16 event_id) diff --git a/src/server/game/Events/GameEventMgr.h b/src/server/game/Events/GameEventMgr.h index dc68aaaa0..fb591035d 100644 --- a/src/server/game/Events/GameEventMgr.h +++ b/src/server/game/Events/GameEventMgr.h @@ -161,6 +161,7 @@ private: typedef std::list NPCFlagList; typedef std::vector GameEventNPCFlagMap; typedef std::vector GameEventBitmask; + typedef std::unordered_map> GameEventSeasonalQuestsMap; GameEventQuestMap mGameEventCreatureQuests; GameEventQuestMap mGameEventGameObjectQuests; GameEventNPCVendorMap mGameEventVendors; @@ -174,6 +175,7 @@ private: GameEventNPCFlagMap mGameEventNPCFlags; ActiveEvents m_ActiveEvents; bool isSystemInit; + GameEventSeasonalQuestsMap _gameEventSeasonalQuestsMap; public: GameEventGuidMap mGameEventCreatureGuids; GameEventGuidMap mGameEventGameobjectGuids; diff --git a/src/server/scripts/World/npcs_special.cpp b/src/server/scripts/World/npcs_special.cpp index 3a425b5ce..451635a91 100644 --- a/src/server/scripts/World/npcs_special.cpp +++ b/src/server/scripts/World/npcs_special.cpp @@ -219,6 +219,8 @@ enum riggleBassbait QUEST_MASTER_ANGLER = 8193, DATA_ANGLER_FINISHED = 1, + + GAME_EVENT_FISHING = 62 }; class npc_riggle_bassbait : public CreatureScript @@ -232,7 +234,7 @@ public: { events.Reset(); events.ScheduleEvent(EVENT_RIGGLE_ANNOUNCE, 1000, 1, 0); - finished = false; + finished = sWorld->getWorldState(GAME_EVENT_FISHING) == 1; startWarning = false; finishWarning = false; } @@ -253,7 +255,10 @@ public: void DoAction(int32 param) override { if (param == DATA_ANGLER_FINISHED) + { finished = true; + sWorld->setWorldState(GAME_EVENT_FISHING, 1); + } } void UpdateAI(uint32 diff) override