diff --git a/src/server/database/Database/Implementation/CharacterDatabase.cpp b/src/server/database/Database/Implementation/CharacterDatabase.cpp index 939dd0919..829a96197 100644 --- a/src/server/database/Database/Implementation/CharacterDatabase.cpp +++ b/src/server/database/Database/Implementation/CharacterDatabase.cpp @@ -523,6 +523,9 @@ void CharacterDatabaseConnection::DoPrepareStatements() PrepareStatement(CHAR_UPD_CHAR_QUESTSTATUS_REWARDED_FACTION_CHANGE, "UPDATE character_queststatus_rewarded SET quest = ? WHERE quest = ? AND guid = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_UPD_CHAR_QUESTSTATUS_REWARDED_ACTIVE, "UPDATE character_queststatus_rewarded SET active = 1 WHERE guid = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_UPD_CHAR_QUESTSTATUS_REWARDED_ACTIVE_BY_QUEST, "UPDATE character_queststatus_rewarded SET active = 0 WHERE quest = ? AND guid = ?", CONNECTION_ASYNC); + PrepareStatement(CHAR_SEL_CHAR_QUESTSTATUS_BY_QUEST, "SELECT status FROM character_queststatus WHERE guid = ? AND quest = ?", CONNECTION_SYNCH); + PrepareStatement(CHAR_SEL_CHAR_QUESTSTATUS_SEASONAL_BY_QUEST, "SELECT 1 FROM character_queststatus_seasonal WHERE guid = ? AND quest = ? AND event = ?", CONNECTION_SYNCH); + PrepareStatement(CHAR_SEL_CHAR_QUESTSTATUS_REWARDED_BY_QUEST, "SELECT 1 FROM character_queststatus_rewarded WHERE guid = ? AND quest = ? AND active = 1", CONNECTION_SYNCH); PrepareStatement(CHAR_DEL_CHAR_SKILL_BY_SKILL, "DELETE FROM character_skills WHERE guid = ? AND skill = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_INS_CHAR_SKILLS, "INSERT INTO character_skills (guid, skill, value, max) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC); PrepareStatement(CHAR_UDP_CHAR_SKILLS, "UPDATE character_skills SET value = ?, max = ? WHERE guid = ? AND skill = ?", CONNECTION_ASYNC); diff --git a/src/server/database/Database/Implementation/CharacterDatabase.h b/src/server/database/Database/Implementation/CharacterDatabase.h index 666be5255..0ca6e40c9 100644 --- a/src/server/database/Database/Implementation/CharacterDatabase.h +++ b/src/server/database/Database/Implementation/CharacterDatabase.h @@ -446,6 +446,9 @@ enum CharacterDatabaseStatements : uint32 CHAR_UPD_CHAR_QUESTSTATUS_REWARDED_FACTION_CHANGE, CHAR_UPD_CHAR_QUESTSTATUS_REWARDED_ACTIVE, CHAR_UPD_CHAR_QUESTSTATUS_REWARDED_ACTIVE_BY_QUEST, + CHAR_SEL_CHAR_QUESTSTATUS_BY_QUEST, + CHAR_SEL_CHAR_QUESTSTATUS_SEASONAL_BY_QUEST, + CHAR_SEL_CHAR_QUESTSTATUS_REWARDED_BY_QUEST, CHAR_DEL_CHAR_SKILL_BY_SKILL, CHAR_INS_CHAR_SKILLS, CHAR_UDP_CHAR_SKILLS, diff --git a/src/server/scripts/Commands/cs_quest.cpp b/src/server/scripts/Commands/cs_quest.cpp index bc1faf49b..8f7063665 100644 --- a/src/server/scripts/Commands/cs_quest.cpp +++ b/src/server/scripts/Commands/cs_quest.cpp @@ -729,6 +729,25 @@ public: return true; } + static char const* QuestStatusToString(QuestStatus status) + { + switch (status) + { + case QUEST_STATUS_NONE: + return "Not Taken"; + case QUEST_STATUS_COMPLETE: + return "Complete"; + case QUEST_STATUS_INCOMPLETE: + return "Incomplete"; + case QUEST_STATUS_FAILED: + return "Failed"; + case QUEST_STATUS_REWARDED: + return "Rewarded"; + default: + return "Unknown"; + } + } + static bool HandleQuestStatus(ChatHandler* handler, Quest const* quest, Optional playerTarget) { if (!playerTarget) @@ -741,33 +760,10 @@ public: } uint32 entry = quest->GetQuestId(); - std::string status; + if (Player* player = playerTarget->GetConnectedPlayer()) { - QuestStatus qs = player->GetQuestStatus(entry); - switch (qs) - { - case QUEST_STATUS_NONE: - status = "Not Taken"; - break; - case QUEST_STATUS_COMPLETE: - status = "Complete"; - break; - case QUEST_STATUS_INCOMPLETE: - status = "Incomplete"; - break; - case QUEST_STATUS_FAILED: - status = "Failed"; - break; - case QUEST_STATUS_REWARDED: - status = "Rewarded"; - break; - default: - status = "Unknown"; - break; - } - - handler->PSendSysMessage(LANG_CMD_QUEST_STATUS, quest->GetTitle(), entry, status); + handler->PSendSysMessage(LANG_CMD_QUEST_STATUS, quest->GetTitle(), entry, QuestStatusToString(player->GetQuestStatus(entry))); if (!player->CanTakeQuest(quest, false)) { @@ -846,8 +842,35 @@ public: } else { - handler->SendErrorMessage(LANG_PLAYER_NOT_FOUND); - return false; + ObjectGuid::LowType guid = playerTarget->GetGUID().GetCounter(); + char const* status; + + CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_QUESTSTATUS_BY_QUEST); + stmt->SetData(0, guid); + stmt->SetData(1, entry); + + if (PreparedQueryResult result = CharacterDatabase.Query(stmt)) + status = QuestStatusToString(QuestStatus(result->Fetch()[0].Get())); + else if (quest->IsSeasonal()) + { + stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_QUESTSTATUS_SEASONAL_BY_QUEST); + stmt->SetData(0, guid); + stmt->SetData(1, entry); + stmt->SetData(2, quest->GetEventIdForQuest()); + status = CharacterDatabase.Query(stmt) ? "Rewarded" : "Not Taken"; + } + // rewarded repeatable quests report Not Taken, matching Player::GetQuestStatus + else if (!quest->IsRepeatable()) + { + stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_QUESTSTATUS_REWARDED_BY_QUEST); + stmt->SetData(0, guid); + stmt->SetData(1, entry); + status = CharacterDatabase.Query(stmt) ? "Rewarded" : "Not Taken"; + } + else + status = "Not Taken"; + + handler->PSendSysMessage(LANG_CMD_QUEST_STATUS, quest->GetTitle(), entry, status); } return true;