From c6dbd790c1b4559b5d6f052758a3906b37df97da Mon Sep 17 00:00:00 2001 From: hondacrx Date: Sun, 7 Nov 2021 17:02:09 -0500 Subject: [PATCH] Core/PacketIO: Updated SMSG_QUEST_PUSH_RESPONSE to 9.1.5 Port From (https://github.com/TrinityCore/TrinityCore/commit/122fe7549db0e499560b748156592862623cb6b4) --- Source/Framework/Constants/QuestConst.cs | 56 ++++++--- Source/Game/Entities/Player/Player.Quest.cs | 78 +++++++----- Source/Game/Handlers/QuestHandler.cs | 116 +++++++++++++++--- .../Game/Networking/Packets/QuestPackets.cs | 6 + 4 files changed, 188 insertions(+), 68 deletions(-) diff --git a/Source/Framework/Constants/QuestConst.cs b/Source/Framework/Constants/QuestConst.cs index 1b0c6d632..a17d9a2b9 100644 --- a/Source/Framework/Constants/QuestConst.cs +++ b/Source/Framework/Constants/QuestConst.cs @@ -317,20 +317,48 @@ namespace Framework.Constants public enum QuestPushReason { - Success = 0, - Invalid = 1, - Accepted = 2, - Declined = 3, - Busy = 4, - Dead = 5, - LogFull = 6, - OnQuest = 7, - AlreadyDone = 8, - NotDaily = 9, - TimerExpired = 10, - NotInParty = 11, - DifferentServerDaily = 12, - NotAllowed = 13 + Success = 0, // "Sharing quest with %s..." + Invalid = 1, // "%s is not eligible for that quest" + InvalidToRecipient = 2, // "%s's attempt to share quest "%s" failed. You are not eligible for that quest." + Accepted = 3, // "%s has accepted your quest" + Declined = 4, // "%s has declined your quest" + Busy = 5, // "%s is busy" + Dead = 6, // "%s is dead." + DeadToRecipient = 7, // "%s's attempt to share quest "%s" failed. You are dead." + LogFull = 8, // "%s's quest log is full" + LogFullToRecipient = 9, // "%s's attempt to share quest "%s" failed. Your quest log is full." + OnQuest = 10, // "%s is already on that quest" + OnQuestToRecipient = 11, // "%s's attempt to share quest "%s" failed. You are already on that quest." + AlreadyDone = 12, // "%s has completed that quest" + AlreadyDoneToRecipient = 13, // "%s's attempt to share quest "%s" failed. You have completed that quest." + NotDaily = 14, // "That quest cannot be shared today" + TimerExpired = 15, // "Quest sharing timer has expired" + NotInParty = 16, // "You are not in a party" + DifferentServerDaily = 17, // "%s is not eligible for that quest today" + DifferentServerDailyToRecipient = 18, // "%s's attempt to share quest "%s" failed. You are not eligible for that quest today." + NotAllowed = 19, // "That quest cannot be shared" + Prerequisite = 20, // "%s hasn't completed all of the prerequisite quests required for that quest." + PrerequisiteToRecipient = 21, // "%s's attempt to share quest "%s" failed. You must complete all of the prerequisite quests first." + LowLevel = 22, // "%s is too low level for that quest." + LowLevelToRecipient = 23, // "%s's attempt to share quest "%s" failed. You are too low level for that quest." + HighLevel = 24, // "%s is too high level for that quest." + HighLevelToRecipient = 25, // "%s's attempt to share quest "%s" failed. You are too high level for that quest." + Class = 26, // "%s is the wrong class for that quest." + ClassToRecipient = 27, // "%s's attempt to share quest "%s" failed. You are the wrong class for that quest." + Race = 28, // "%s is the wrong race for that quest." + RaceToRecipient = 29, // "%s's attempt to share quest "%s" failed. You are the wrong race for that quest." + LowFaction = 30, // "%s's reputation is too low for that quest." + LowFactionToRecipient = 31, // "%s's attempt to share quest "%s" failed. Your reputation is too low for that quest." + Expansion = 32, // "%s doesn't own the required expansion for that quest." + ExpansionToRecipient = 33, // "%s's attempt to share quest "%s" failed. You do not own the required expansion for that quest." + NotGarrisonOwner = 34, // "%s must own a garrison to accept that quest." + NotGarrisonOwnerToRecipient = 35, // "%s's attempt to share quest "%s" failed. You must own a garrison to accept that quest." + WrongCovenant = 36, // "%s is in the wrong covenant for that quest." + WrongCovenantToRecipient = 37, // "%s's attempt to share quest "%s" failed. You are in the wrong covenant for that quest." + NewPlayerExperience = 38, // "%s must complete Exile's Reach to accept that quest." + NewPlayerExperienceToRecipient = 39, // "%s's attempt to share quest "%s" failed. You must complete Exile's Reach to accept that quest." + WrongFaction = 40, // "%s is the wrong faction for that quest." + WrongFactionToRecipient = 41 // "%s's attempt to share quest "%s" failed. You are the wrong faction for that quest." } public enum QuestTradeSkill diff --git a/Source/Game/Entities/Player/Player.Quest.cs b/Source/Game/Entities/Player/Player.Quest.cs index 4f9827ccc..646e9e20f 100644 --- a/Source/Game/Entities/Player/Player.Quest.cs +++ b/Source/Game/Entities/Player/Player.Quest.cs @@ -1290,24 +1290,33 @@ namespace Game.Entities return true; } - public bool SatisfyQuestLevel(Quest qInfo, bool msg) + bool SatisfyQuestLevel(Quest qInfo, bool msg) + { + return SatisfyQuestMinLevel(qInfo, msg) && SatisfyQuestMaxLevel(qInfo, msg); + } + + public bool SatisfyQuestMinLevel(Quest qInfo, bool msg) { if (GetLevel() < GetQuestMinLevel(qInfo)) { if (msg) { SendCanTakeQuestResponse(QuestFailedReasons.FailedLowLevel); - Log.outDebug(LogFilter.Server, "SatisfyQuestLevel: Sent QuestFailedReasons.FailedLowLevel (questId: {0}) because player does not have required (min) level.", qInfo.Id); + Log.outDebug(LogFilter.Server, "SatisfyQuestMinLevel: Sent QuestFailedReasons.FailedLowLevel (questId: {0}) because player does not have required (min) level.", qInfo.Id); } return false; } + return true; + } + public bool SatisfyQuestMaxLevel(Quest qInfo, bool msg) + { if (qInfo.MaxLevel > 0 && GetLevel() > qInfo.MaxLevel) { if (msg) { SendCanTakeQuestResponse(QuestFailedReasons.None); // There doesn't seem to be a specific response for too high player level - Log.outDebug(LogFilter.Server, "SatisfyQuestLevel: Sent QuestFailedReasons.None (questId: {0}) because player does not have required (max) level.", qInfo.Id); + Log.outDebug(LogFilter.Server, "SatisfyQuestMaxLevel: Sent QuestFailedReasons.None (questId: {0}) because player does not have required (max) level.", qInfo.Id); } return false; } @@ -1326,7 +1335,7 @@ namespace Game.Entities return false; } - bool SatisfyQuestDependentQuests(Quest qInfo, bool msg) + public bool SatisfyQuestDependentQuests(Quest qInfo, bool msg) { return SatisfyQuestPreviousQuest(qInfo, msg) && SatisfyQuestDependentPreviousQuests(qInfo, msg); } @@ -1475,20 +1484,6 @@ namespace Game.Entities return false; } - /* @todo 6.x investigate if it's still needed - // ReputationObjective2 does not seem to be an objective requirement but a requirement - // to be able to accept the quest - uint fIdObj = qInfo.RequiredFactionId2; - if (fIdObj != 0 && GetReputationMgr().GetReputation(fIdObj) >= qInfo.RequiredFactionValue2) - { - if (msg) - { - SendCanTakeQuestResponse(QuestFailedReasons.DontHaveReq); - Log.outDebug(LogFilter.Misc, "SatisfyQuestReputation: Sent QuestFailedReason.None (questId: {0}) because player does not have required reputation (ReputationObjective2).", qInfo.Id); - } - return false; - } - */ return true; } @@ -1626,6 +1621,19 @@ namespace Game.Entities return !list.Contains(qInfo.Id); } + public bool SatisfyQuestExpansion(Quest qInfo, bool msg) + { + if ((int)GetSession().GetExpansion() < qInfo.Expansion) + { + if (msg) + SendCanTakeQuestResponse(QuestFailedReasons.FailedExpansion); + + Log.outDebug(LogFilter.Misc, $"Player.SatisfyQuestExpansion: Sent QUEST_ERR_FAILED_EXPANSION (QuestID: {qInfo.Id}) because player '{GetName()}' ({GetGUID()}) does not have required expansion."); + return false; + } + return true; + } + public bool SatisfyQuestMonth(Quest qInfo, bool msg) { if (!qInfo.IsMonthly() || m_monthlyquests.Empty()) @@ -1742,17 +1750,7 @@ namespace Game.Entities if (qInfo != null && qInfo.HasFlag(QuestFlags.Sharable)) { var questStatusData = m_QuestStatus.LookupByKey(quest_id); - if (questStatusData != null) - { - // in pool and not currently available (wintergrasp weekly, dalaran weekly) - can't share - if (Global.PoolMgr.IsPartOfAPool(quest_id) != 0 && !Global.PoolMgr.IsSpawnedObject(quest_id)) - { - SendPushToPartyResponse(this, QuestPushReason.NotDaily); - return false; - } - - return true; - } + return questStatusData != null; } return false; } @@ -2727,14 +2725,26 @@ namespace Game.Entities receiver.SendPacket(packet); } - public void SendPushToPartyResponse(Player player, QuestPushReason reason) + public void SendPushToPartyResponse(Player player, QuestPushReason reason, Quest quest = null) { if (player != null) { - QuestPushResultResponse data = new(); - data.SenderGUID = player.GetGUID(); - data.Result = reason; - SendPacket(data); + QuestPushResultResponse response = new(); + response.SenderGUID = player.GetGUID(); + response.Result = reason; + if (quest != null) + { + response.QuestTitle = quest.LogTitle; + Locale localeConstant = GetSession().GetSessionDbLocaleIndex(); + if (localeConstant != Locale.enUS) + { + QuestTemplateLocale questTemplateLocale = Global.ObjectMgr.GetQuestLocale(quest.Id); + if (questTemplateLocale != null) + ObjectManager.GetLocaleString(questTemplateLocale.LogTitle, localeConstant, ref response.QuestTitle); + } + } + + SendPacket(response); } } diff --git a/Source/Game/Handlers/QuestHandler.cs b/Source/Game/Handlers/QuestHandler.cs index 6e28159f8..8be4a4148 100644 --- a/Source/Game/Handlers/QuestHandler.cs +++ b/Source/Game/Handlers/QuestHandler.cs @@ -589,15 +589,25 @@ namespace Game [WorldPacketHandler(ClientOpcodes.PushQuestToParty)] void HandlePushQuestToParty(PushQuestToParty packet) { - if (!GetPlayer().CanShareQuest(packet.QuestID)) - return; - Quest quest = Global.ObjectMgr.GetQuestTemplate(packet.QuestID); if (quest == null) return; Player sender = GetPlayer(); + if (!_player.CanShareQuest(packet.QuestID)) + { + sender.SendPushToPartyResponse(sender, QuestPushReason.NotAllowed); + return; + } + + // in pool and not currently available (wintergrasp weekly, dalaran weekly) - can't share + if (Global.PoolMgr.IsPartOfAPool(packet.QuestID) != 0 && !Global.PoolMgr.IsSpawnedObject(packet.QuestID)) + { + sender.SendPushToPartyResponse(sender, QuestPushReason.NotDaily); + return; + } + Group group = sender.GetGroup(); if (!group) { @@ -612,39 +622,105 @@ namespace Game if (!receiver || receiver == sender) continue; - if (!receiver.SatisfyQuestStatus(quest, false)) + if (!receiver.GetPlayerSharingQuest().IsEmpty()) { - sender.SendPushToPartyResponse(receiver, QuestPushReason.OnQuest); + sender.SendPushToPartyResponse(receiver, QuestPushReason.Busy); continue; } - if (receiver.GetQuestStatus(packet.QuestID) == QuestStatus.Complete) + if (!receiver.IsAlive()) { - sender.SendPushToPartyResponse(receiver, QuestPushReason.AlreadyDone); + sender.SendPushToPartyResponse(receiver, QuestPushReason.Dead); + receiver.SendPushToPartyResponse(sender, QuestPushReason.DeadToRecipient, quest); + continue; + } + + switch (receiver.GetQuestStatus(packet.QuestID)) + { + case QuestStatus.Rewarded: + { + sender.SendPushToPartyResponse(receiver, QuestPushReason.AlreadyDone); + receiver.SendPushToPartyResponse(sender, QuestPushReason.AlreadyDoneToRecipient, quest); + continue; + } + case QuestStatus.Incomplete: + case QuestStatus.Complete: + { + sender.SendPushToPartyResponse(receiver, QuestPushReason.OnQuest); + receiver.SendPushToPartyResponse(sender, QuestPushReason.OnQuestToRecipient, quest); + continue; + } + default: + break; + } + + if (!receiver.SatisfyQuestLog(false)) + { + sender.SendPushToPartyResponse(receiver, QuestPushReason.LogFull); + receiver.SendPushToPartyResponse(sender, QuestPushReason.LogFullToRecipient, quest); continue; } if (!receiver.SatisfyQuestDay(quest, false)) { - sender.SendPushToPartyResponse(receiver, QuestPushReason.DifferentServerDaily); + sender.SendPushToPartyResponse(receiver, QuestPushReason.AlreadyDone); + receiver.SendPushToPartyResponse(sender, QuestPushReason.AlreadyDoneToRecipient, quest); + continue; + } + + if (!receiver.SatisfyQuestMinLevel(quest, false)) + { + sender.SendPushToPartyResponse(receiver, QuestPushReason.LowLevel); + receiver.SendPushToPartyResponse(sender, QuestPushReason.LowLevelToRecipient, quest); + continue; + } + + if (!receiver.SatisfyQuestMaxLevel(quest, false)) + { + sender.SendPushToPartyResponse(receiver, QuestPushReason.HighLevel); + receiver.SendPushToPartyResponse(sender, QuestPushReason.HighLevelToRecipient, quest); + continue; + } + + if (!receiver.SatisfyQuestClass(quest, false)) + { + sender.SendPushToPartyResponse(receiver, QuestPushReason.Class); + receiver.SendPushToPartyResponse(sender, QuestPushReason.ClassToRecipient, quest); + continue; + } + + if (!receiver.SatisfyQuestRace(quest, false)) + { + sender.SendPushToPartyResponse(receiver, QuestPushReason.Race); + receiver.SendPushToPartyResponse(sender, QuestPushReason.RaceToRecipient, quest); + continue; + } + + if (!receiver.SatisfyQuestReputation(quest, false)) + { + sender.SendPushToPartyResponse(receiver, QuestPushReason.LowFaction); + receiver.SendPushToPartyResponse(sender, QuestPushReason.LowFactionToRecipient, quest); + continue; + } + + if (!receiver.SatisfyQuestDependentQuests(quest, false)) + { + sender.SendPushToPartyResponse(receiver, QuestPushReason.Prerequisite); + receiver.SendPushToPartyResponse(sender, QuestPushReason.PrerequisiteToRecipient, quest); + continue; + } + + if (!receiver.SatisfyQuestExpansion(quest, false)) + { + sender.SendPushToPartyResponse(receiver, QuestPushReason.Expansion); + receiver.SendPushToPartyResponse(sender, QuestPushReason.ExpansionToRecipient, quest); continue; } if (!receiver.CanTakeQuest(quest, false)) { sender.SendPushToPartyResponse(receiver, QuestPushReason.Invalid); - continue; - } - - if (!receiver.SatisfyQuestLog(false)) - { - sender.SendPushToPartyResponse(receiver, QuestPushReason.LogFull); - continue; - } - - if (!receiver.GetPlayerSharingQuest().IsEmpty()) - { - sender.SendPushToPartyResponse(receiver, QuestPushReason.Busy); + receiver.SendPushToPartyResponse(sender, QuestPushReason.InvalidToRecipient, quest); continue; } diff --git a/Source/Game/Networking/Packets/QuestPackets.cs b/Source/Game/Networking/Packets/QuestPackets.cs index 8e563e801..f783ff265 100644 --- a/Source/Game/Networking/Packets/QuestPackets.cs +++ b/Source/Game/Networking/Packets/QuestPackets.cs @@ -704,10 +704,16 @@ namespace Game.Networking.Packets { _worldPacket.WritePackedGuid(SenderGUID); _worldPacket.WriteUInt8((byte)Result); + + _worldPacket.WriteBits(QuestTitle.GetByteCount(), 9); + _worldPacket.FlushBits(); + + _worldPacket.WriteString(QuestTitle); } public ObjectGuid SenderGUID; public QuestPushReason Result; + public string QuestTitle; } class QuestPushResult : ClientPacket