Core/Quests: Reset seasonal quests based on saved completion time and intended holiday start time
Port From (https://github.com/TrinityCore/TrinityCore/commit/49ad0d2d495a9f817ad2820f8e616f3a6564b480)
This commit is contained in:
@@ -101,7 +101,7 @@ namespace Framework.Database
|
||||
PrepareStatement(CharStatements.SEL_CHARACTER_QUESTSTATUS_DAILY, "SELECT quest, time FROM character_queststatus_daily WHERE guid = ?");
|
||||
PrepareStatement(CharStatements.SEL_CHARACTER_QUESTSTATUS_WEEKLY, "SELECT quest FROM character_queststatus_weekly WHERE guid = ?");
|
||||
PrepareStatement(CharStatements.SEL_CHARACTER_QUESTSTATUS_MONTHLY, "SELECT quest FROM character_queststatus_monthly WHERE guid = ?");
|
||||
PrepareStatement(CharStatements.SEL_CHARACTER_QUESTSTATUS_SEASONAL, "SELECT quest, event FROM character_queststatus_seasonal WHERE guid = ?");
|
||||
PrepareStatement(CharStatements.SEL_CHARACTER_QUESTSTATUS_SEASONAL, "SELECT quest, event, completedTime FROM character_queststatus_seasonal WHERE guid = ?");
|
||||
PrepareStatement(CharStatements.DEL_CHARACTER_QUESTSTATUS_DAILY, "DELETE FROM character_queststatus_daily WHERE guid = ?");
|
||||
PrepareStatement(CharStatements.DEL_CHARACTER_QUESTSTATUS_WEEKLY, "DELETE FROM character_queststatus_weekly WHERE guid = ?");
|
||||
PrepareStatement(CharStatements.DEL_CHARACTER_QUESTSTATUS_MONTHLY, "DELETE FROM character_queststatus_monthly WHERE guid = ?");
|
||||
@@ -109,11 +109,11 @@ namespace Framework.Database
|
||||
PrepareStatement(CharStatements.INS_CHARACTER_QUESTSTATUS_DAILY, "INSERT INTO character_queststatus_daily (guid, quest, time) VALUES (?, ?, ?)");
|
||||
PrepareStatement(CharStatements.INS_CHARACTER_QUESTSTATUS_WEEKLY, "INSERT INTO character_queststatus_weekly (guid, quest) VALUES (?, ?)");
|
||||
PrepareStatement(CharStatements.INS_CHARACTER_QUESTSTATUS_MONTHLY, "INSERT INTO character_queststatus_monthly (guid, quest) VALUES (?, ?)");
|
||||
PrepareStatement(CharStatements.INS_CHARACTER_QUESTSTATUS_SEASONAL, "INSERT INTO character_queststatus_seasonal (guid, quest, event) VALUES (?, ?, ?)");
|
||||
PrepareStatement(CharStatements.INS_CHARACTER_QUESTSTATUS_SEASONAL, "INSERT INTO character_queststatus_seasonal (guid, quest, event, completedTime) VALUES (?, ?, ?, ?)");
|
||||
PrepareStatement(CharStatements.DEL_RESET_CHARACTER_QUESTSTATUS_DAILY, "DELETE FROM character_queststatus_daily");
|
||||
PrepareStatement(CharStatements.DEL_RESET_CHARACTER_QUESTSTATUS_WEEKLY, "DELETE FROM character_queststatus_weekly");
|
||||
PrepareStatement(CharStatements.DEL_RESET_CHARACTER_QUESTSTATUS_MONTHLY, "DELETE FROM character_queststatus_monthly");
|
||||
PrepareStatement(CharStatements.DEL_RESET_CHARACTER_QUESTSTATUS_SEASONAL_BY_EVENT, "DELETE FROM character_queststatus_seasonal WHERE event = ?");
|
||||
PrepareStatement(CharStatements.DEL_RESET_CHARACTER_QUESTSTATUS_SEASONAL_BY_EVENT, "DELETE FROM character_queststatus_seasonal WHERE event = ? AND completedTime < ?");
|
||||
|
||||
PrepareStatement(CharStatements.SEL_CHARACTER_REPUTATION, "SELECT faction, standing, flags FROM character_reputation WHERE guid = ?");
|
||||
PrepareStatement(CharStatements.SEL_CHARACTER_INVENTORY, "SELECT " + SelectItemInstanceContent + ", bag, slot FROM character_inventory ci JOIN item_instance ii ON ci.item = ii.guid LEFT JOIN item_instance_gems ig ON ii.guid = ig.itemGuid LEFT JOIN item_instance_transmog iit ON ii.guid = iit.itemGuid LEFT JOIN item_instance_modifiers im ON ii.guid = im.itemGuid WHERE ci.guid = ? ORDER BY (ii.flags & 0x80000) ASC, bag ASC, slot ASC");
|
||||
|
||||
@@ -931,11 +931,16 @@ namespace Game.Entities
|
||||
{
|
||||
uint quest_id = result.Read<uint>(0);
|
||||
uint event_id = result.Read<uint>(1);
|
||||
long completedTime = result.Read<long>(2);
|
||||
Quest quest = Global.ObjectMgr.GetQuestTemplate(quest_id);
|
||||
if (quest == null)
|
||||
continue;
|
||||
|
||||
m_seasonalquests.Add(event_id, quest_id);
|
||||
if (!m_seasonalquests.ContainsKey(event_id))
|
||||
m_seasonalquests[event_id] = new();
|
||||
|
||||
m_seasonalquests[event_id][quest_id] = completedTime;
|
||||
|
||||
uint questBit = Global.DB2Mgr.GetQuestUniqueBitFlag(quest_id);
|
||||
if (questBit != 0)
|
||||
SetQuestCompletedBit(questBit, true);
|
||||
@@ -2128,13 +2133,17 @@ namespace Game.Entities
|
||||
if (m_seasonalquests.Empty())
|
||||
return;
|
||||
|
||||
foreach (var iter in m_seasonalquests)
|
||||
foreach (var (eventId, dictionary) in m_seasonalquests)
|
||||
{
|
||||
stmt = DB.Characters.GetPreparedStatement(CharStatements.INS_CHARACTER_QUESTSTATUS_SEASONAL);
|
||||
stmt.AddValue(0, GetGUID().GetCounter());
|
||||
stmt.AddValue(1, iter.Value);
|
||||
stmt.AddValue(2, iter.Key);
|
||||
trans.Append(stmt);
|
||||
foreach (var (questId, completedTime) in dictionary)
|
||||
{
|
||||
stmt = DB.Characters.GetPreparedStatement(CharStatements.INS_CHARACTER_QUESTSTATUS_SEASONAL);
|
||||
stmt.AddValue(0, GetGUID().GetCounter());
|
||||
stmt.AddValue(1, questId);
|
||||
stmt.AddValue(2, eventId);
|
||||
stmt.AddValue(3, completedTime);
|
||||
trans.Append(stmt);
|
||||
}
|
||||
}
|
||||
}
|
||||
void _SaveMonthlyQuestStatus(SQLTransaction trans)
|
||||
|
||||
@@ -164,7 +164,7 @@ namespace Game.Entities
|
||||
List<uint> m_timedquests = new();
|
||||
List<uint> m_weeklyquests = new();
|
||||
List<uint> m_monthlyquests = new();
|
||||
MultiMap<uint, uint> m_seasonalquests = new();
|
||||
Dictionary<uint, Dictionary<uint, long>> m_seasonalquests = new();
|
||||
Dictionary<uint, QuestStatusData> m_QuestStatus = new();
|
||||
MultiMap<(QuestObjectiveType Type, int ObjectID), QuestObjectiveStatusData> m_questObjectiveStatus = new();
|
||||
Dictionary<uint, QuestSaveType> m_QuestStatusSave = new();
|
||||
|
||||
@@ -28,6 +28,7 @@ using Game.Networking.Packets;
|
||||
using Game.Spells;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Game.Entities
|
||||
{
|
||||
@@ -200,22 +201,29 @@ namespace Game.Entities
|
||||
|
||||
}
|
||||
|
||||
public void ResetSeasonalQuestStatus(ushort event_id)
|
||||
public void ResetSeasonalQuestStatus(ushort event_id, long eventStartTime)
|
||||
{
|
||||
// DB data deleted in caller
|
||||
m_SeasonalQuestChanged = false;
|
||||
|
||||
var eventList = m_seasonalquests.LookupByKey(event_id);
|
||||
if (eventList.Empty())
|
||||
return;
|
||||
|
||||
foreach (uint questId in eventList)
|
||||
foreach (var (questId, completedTime) in eventList.ToList())
|
||||
{
|
||||
uint questBit = Global.DB2Mgr.GetQuestUniqueBitFlag(questId);
|
||||
if (questBit != 0)
|
||||
SetQuestCompletedBit(questBit, false);
|
||||
if (completedTime < eventStartTime)
|
||||
{
|
||||
uint questBit = Global.DB2Mgr.GetQuestUniqueBitFlag(questId);
|
||||
if (questBit != 0)
|
||||
SetQuestCompletedBit(questBit, false);
|
||||
|
||||
eventList.Remove(questId);
|
||||
}
|
||||
}
|
||||
|
||||
m_seasonalquests.Remove(event_id);
|
||||
// DB data deleted in caller
|
||||
m_SeasonalQuestChanged = false;
|
||||
if (eventList.Empty())
|
||||
m_seasonalquests.Remove(event_id);
|
||||
}
|
||||
|
||||
public void ResetMonthlyQuestStatus()
|
||||
@@ -1673,7 +1681,7 @@ namespace Game.Entities
|
||||
return true;
|
||||
|
||||
// if not found in cooldown list
|
||||
return !list.Contains(qInfo.Id);
|
||||
return !list.ContainsKey(qInfo.Id);
|
||||
}
|
||||
|
||||
public bool SatisfyQuestExpansion(Quest qInfo, bool msg)
|
||||
@@ -1864,7 +1872,7 @@ namespace Game.Entities
|
||||
ushort eventId = qInfo.GetEventIdForQuest();
|
||||
if (m_seasonalquests.ContainsKey(eventId))
|
||||
{
|
||||
m_seasonalquests.Remove(eventId, questId);
|
||||
m_seasonalquests[eventId].Remove(questId);
|
||||
m_SeasonalQuestChanged = true;
|
||||
}
|
||||
}
|
||||
@@ -3041,7 +3049,10 @@ namespace Game.Entities
|
||||
if (quest == null)
|
||||
return;
|
||||
|
||||
m_seasonalquests.Add(quest.GetEventIdForQuest(), quest_id);
|
||||
if (!m_seasonalquests.ContainsKey(quest.GetEventIdForQuest()))
|
||||
m_seasonalquests[quest.GetEventIdForQuest()] = new();
|
||||
|
||||
m_seasonalquests[quest.GetEventIdForQuest()][quest_id] = GameTime.GetGameTime();
|
||||
m_SeasonalQuestChanged = true;
|
||||
}
|
||||
|
||||
|
||||
@@ -1100,7 +1100,7 @@ namespace Game
|
||||
RunSmartAIScripts(event_id, true);
|
||||
|
||||
// check for seasonal quest reset.
|
||||
Global.WorldMgr.ResetEventSeasonalQuests(event_id);
|
||||
Global.WorldMgr.ResetEventSeasonalQuests(event_id, GetLastStartTime(event_id));
|
||||
}
|
||||
|
||||
void UpdateEventNPCFlags(ushort event_id)
|
||||
@@ -1676,6 +1676,21 @@ namespace Game
|
||||
}
|
||||
}
|
||||
|
||||
long GetLastStartTime(ushort event_id)
|
||||
{
|
||||
if (event_id >= mGameEvent.Length)
|
||||
return 0;
|
||||
|
||||
if (mGameEvent[event_id].state != GameEventState.Normal)
|
||||
return 0;
|
||||
|
||||
DateTime now = GameTime.GetSystemTime();
|
||||
DateTime eventInitialStart = Time.UnixTimeToDateTime(mGameEvent[event_id].start);
|
||||
TimeSpan occurence = TimeSpan.FromMinutes(mGameEvent[event_id].occurence);
|
||||
TimeSpan durationSinceLastStart = TimeSpan.FromTicks((now - eventInitialStart).Ticks % occurence.Ticks);
|
||||
return Time.DateTimeToUnixTime(now - durationSinceLastStart);
|
||||
}
|
||||
|
||||
public bool IsHolidayActive(HolidayIds id)
|
||||
{
|
||||
if (id == HolidayIds.None)
|
||||
|
||||
@@ -2215,15 +2215,15 @@ namespace Game
|
||||
SetWorldState(WorldStates.CurrencyResetTime, (ulong)m_NextCurrencyReset);
|
||||
}
|
||||
|
||||
public void ResetEventSeasonalQuests(ushort event_id)
|
||||
public void ResetEventSeasonalQuests(ushort event_id, long eventStartTime)
|
||||
{
|
||||
PreparedStatement stmt = DB.Characters.GetPreparedStatement(CharStatements.DEL_RESET_CHARACTER_QUESTSTATUS_SEASONAL_BY_EVENT);
|
||||
stmt.AddValue(0, event_id);
|
||||
stmt.AddValue(1, eventStartTime);
|
||||
DB.Characters.Execute(stmt);
|
||||
|
||||
foreach (var session in m_sessions.Values)
|
||||
if (session.GetPlayer())
|
||||
session.GetPlayer().ResetSeasonalQuestStatus(event_id);
|
||||
session.GetPlayer()?.ResetSeasonalQuestStatus(event_id, eventStartTime);
|
||||
}
|
||||
|
||||
void ResetRandomBG()
|
||||
|
||||
@@ -1426,6 +1426,7 @@ CREATE TABLE `character_queststatus_seasonal` (
|
||||
`guid` bigint unsigned NOT NULL DEFAULT '0' COMMENT 'Global Unique Identifier',
|
||||
`quest` int unsigned NOT NULL DEFAULT '0' COMMENT 'Quest Identifier',
|
||||
`event` int unsigned NOT NULL DEFAULT '0' COMMENT 'Event Identifier',
|
||||
`completedTime` bigint NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`guid`,`quest`),
|
||||
KEY `idx_guid` (`guid`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='Player System';
|
||||
@@ -3670,7 +3671,8 @@ INSERT INTO `updates` VALUES
|
||||
('2022_02_28_00_characters_2020_09_27_00_characters.sql','2292A1ED0E7F46DEC41384F75FA6D9461464EEB8','ARCHIVED','2022-02-28 12:43:58',0),
|
||||
('2022_03_06_00_characters.sql','474AAF9D03E6A56017899C968DC9875368301934','ARCHIVED','2022-03-06 15:12:24',0),
|
||||
('2022_03_11_00_characters_2021_07_18_00_characters.sql','0BA579ED21F4E75AC2B4797421B5029568B3F6E2','RELEASED','2022-03-11 18:56:07',0),
|
||||
('2022_06_01_00_characters.sql','582AC6E256F8365F83AB70BA165CCC8B218E19FF','RELEASED','2022-06-01 21:16:56',0);
|
||||
('2022_06_01_00_characters.sql','582AC6E256F8365F83AB70BA165CCC8B218E19FF','RELEASED','2022-06-01 21:16:56',0),
|
||||
('2022_07_03_00_characters.sql','D3F04078C0846BCF7C8330AC20C39B8C3AEE7002','RELEASED','2022-07-03 23:37:24',0);
|
||||
/*!40000 ALTER TABLE `updates` ENABLE KEYS */;
|
||||
UNLOCK TABLES;
|
||||
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
ALTER TABLE `character_queststatus_seasonal` ADD `completedTime` bigint NOT NULL DEFAULT '0' AFTER `event`;
|
||||
|
||||
UPDATE `character_queststatus_seasonal` SET `completedTime` = UNIX_TIMESTAMP();
|
||||
|
||||
DELETE FROM `worldstates` WHERE `entry` BETWEEN 1 AND 85;
|
||||
Reference in New Issue
Block a user