From fa2ab116765ead59fd384ec4364ed0da319a51ce Mon Sep 17 00:00:00 2001 From: Chris Miles Date: Mon, 24 Feb 2025 16:31:35 -0600 Subject: [PATCH] [Tasks] Extend IsTaskCompleted to also be aware of shared task completion (#4714) * [Tasks] Extend IsTaskCompleted to also be aware of shared task completion * Fix my stupidity * Update client.h --- zone/client.h | 28 +++++++++++++++++++++++++++- zone/task_client_state.cpp | 12 +++++++++++- zone/task_client_state.h | 2 +- zone/tasks.cpp | 3 ++- 4 files changed, 41 insertions(+), 4 deletions(-) diff --git a/zone/client.h b/zone/client.h index 1e332c17e..ef597fd35 100644 --- a/zone/client.h +++ b/zone/client.h @@ -1289,6 +1289,27 @@ public: void SendSpellTypePrompts(bool commanded_types = false, bool client_only_types = false); // Task System Methods + inline void LoadClientSharedCompletedTasks() + { + std::string query = fmt::format(R"( + SELECT + cst.task_id + FROM completed_shared_task_members cstm + JOIN completed_shared_tasks cst ON cstm.shared_task_id = cst.id + WHERE cstm.character_id = {} + GROUP BY cst.task_id; + )", CharacterID()); + + auto results = database.QueryDatabase(query); + if (!results.Success()) { + return; + } + + for (auto row = results.begin(); row != results.end(); ++row) { + m_completed_shared_tasks.push_back(std::stoi(row[0])); + } + }; + inline std::vector GetCompletedSharedTasks() const { return m_completed_shared_tasks; }; void LoadClientTaskState(); void RemoveClientTaskState(); void SendTaskActivityComplete(int task_id, int activity_id, int task_index, TaskType task_type, int task_incomplete=1); @@ -1459,7 +1480,10 @@ public: { return (task_state ? task_state->EnabledTaskCount(task_set_id) : -1); } - inline bool IsTaskCompleted(int task_id) { return (task_state ? task_state->IsTaskCompleted(task_id) : false); } + inline bool IsTaskCompleted(int task_id) + { + return (task_state ? task_state->IsTaskCompleted(task_id, this) : false); + } inline bool AreTasksCompleted(std::vector task_ids) { return (task_state ? task_state->AreTasksCompleted(task_ids) : false); @@ -2290,6 +2314,8 @@ private: bool m_has_quest_compass = false; std::vector m_dynamic_zone_ids; + std::vector m_completed_shared_tasks; + public: enum BotOwnerOption : size_t { booDeathMarquee, diff --git a/zone/task_client_state.cpp b/zone/task_client_state.cpp index 39767a7c0..1509db8af 100644 --- a/zone/task_client_state.cpp +++ b/zone/task_client_state.cpp @@ -952,6 +952,8 @@ int ClientTaskState::IncrementDoneCount( client->CancelTask(task_index, task_data->type); } + + client->LoadClientSharedCompletedTasks(); } } else { @@ -1561,7 +1563,7 @@ int ClientTaskState::TaskTimeLeft(int task_id) return -1; } -bool ClientTaskState::IsTaskCompleted(int task_id) +bool ClientTaskState::IsTaskCompleted(int task_id, Client *c) { if (!RuleB(TaskSystem, RecordCompletedTasks)) { return false; @@ -1574,6 +1576,14 @@ bool ClientTaskState::IsTaskCompleted(int task_id) } } + if (c) { + for (auto &e: c->GetCompletedSharedTasks()) { + if (e == task_id) { + return true; + } + } + } + return false; } diff --git a/zone/task_client_state.h b/zone/task_client_state.h index 6f22feb4a..c767070d0 100644 --- a/zone/task_client_state.h +++ b/zone/task_client_state.h @@ -45,7 +45,7 @@ public: void AcceptNewTask(Client *client, int task_id, int npc_type_id, time_t accept_time, bool enforce_level_requirement = false); void FailTask(Client *client, int task_id); int TaskTimeLeft(int task_id); - bool IsTaskCompleted(int task_id); + bool IsTaskCompleted(int task_id, Client *c = nullptr); bool AreTasksCompleted(const std::vector& task_ids); bool IsTaskActive(int task_id); bool IsTaskActivityActive(int task_id, int activity_id); diff --git a/zone/tasks.cpp b/zone/tasks.cpp index f0619db9c..33c5150a6 100644 --- a/zone/tasks.cpp +++ b/zone/tasks.cpp @@ -15,8 +15,9 @@ extern QueryServ *QServ; void Client::LoadClientTaskState() { if (RuleB(TaskSystem, EnableTaskSystem) && task_manager) { - safe_delete(task_state); + LoadClientSharedCompletedTasks(); + safe_delete(task_state); task_state = new ClientTaskState(); if (!task_manager->LoadClientState(this, task_state)) { safe_delete(task_state);