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:
hondacrx
2022-07-04 01:15:52 -04:00
parent 3a402854aa
commit c7123ad860
8 changed files with 69 additions and 27 deletions
@@ -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");
+13 -4
View File
@@ -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,15 +2133,19 @@ namespace Game.Entities
if (m_seasonalquests.Empty())
return;
foreach (var iter in m_seasonalquests)
foreach (var (eventId, dictionary) in m_seasonalquests)
{
foreach (var (questId, completedTime) in dictionary)
{
stmt = DB.Characters.GetPreparedStatement(CharStatements.INS_CHARACTER_QUESTSTATUS_SEASONAL);
stmt.AddValue(0, GetGUID().GetCounter());
stmt.AddValue(1, iter.Value);
stmt.AddValue(2, iter.Key);
stmt.AddValue(1, questId);
stmt.AddValue(2, eventId);
stmt.AddValue(3, completedTime);
trans.Append(stmt);
}
}
}
void _SaveMonthlyQuestStatus(SQLTransaction trans)
{
if (!m_MonthlyQuestChanged || m_monthlyquests.Empty())
+1 -1
View File
@@ -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();
+18 -7
View File
@@ -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())
{
if (completedTime < eventStartTime)
{
uint questBit = Global.DB2Mgr.GetQuestUniqueBitFlag(questId);
if (questBit != 0)
SetQuestCompletedBit(questBit, false);
eventList.Remove(questId);
}
}
if (eventList.Empty())
m_seasonalquests.Remove(event_id);
// DB data deleted in caller
m_SeasonalQuestChanged = false;
}
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;
}
+16 -1
View File
@@ -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)
+3 -3
View File
@@ -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()
+3 -1
View File
@@ -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;