diff --git a/zone/client.h b/zone/client.h index 5c5694e7a..1eefb3737 100644 --- a/zone/client.h +++ b/zone/client.h @@ -1420,7 +1420,11 @@ public: { return (task_state ? task_state->EnabledTaskCount(task_set_id) : -1); } - inline int IsTaskCompleted(int task_id) { return (task_state ? task_state->IsTaskCompleted(task_id) : -1); } + inline bool IsTaskCompleted(int task_id) { return (task_state ? task_state->IsTaskCompleted(task_id) : false); } + inline bool AreTasksCompleted(std::vector task_ids) + { + return (task_state ? task_state->AreTasksCompleted(task_ids) : false); + } inline void ShowClientTasks(Client *client) { if (task_state) { task_state->ShowClientTasks(this, client); }} inline void CancelAllTasks() { if (task_state) { task_state->CancelAllTasks(this); }} inline int GetActiveTaskCount() { return (task_state ? task_state->GetActiveTaskCount() : 0); } diff --git a/zone/embparser_api.cpp b/zone/embparser_api.cpp index 9d6618360..f33759d1a 100644 --- a/zone/embparser_api.cpp +++ b/zone/embparser_api.cpp @@ -1276,7 +1276,7 @@ int Perl__tasktimeleft(int task_id) return quest_manager.tasktimeleft(task_id); } -int Perl__istaskcompleted(int task_id) +bool Perl__istaskcompleted(int task_id) { return quest_manager.istaskcompleted(task_id); } @@ -5967,6 +5967,17 @@ bool Perl__send_parcel(perl::reference table_ref) return out; } +bool Perl__aretaskscompleted(perl::array task_ids) +{ + std::vector v; + + for (const auto& e : task_ids) { + v.emplace_back(static_cast(e)); + } + + return quest_manager.aretaskscompleted(v); +} + void perl_register_quest() { perl::interpreter perl(PERL_GET_THX); @@ -6290,6 +6301,7 @@ void perl_register_quest() package.add("addloot", (void(*)(int, int))&Perl__addloot); package.add("addloot", (void(*)(int, int, bool))&Perl__addloot); package.add("addskill", &Perl__addskill); + package.add("aretaskscompleted", &Perl__aretaskscompleted); package.add("assigntask", (void(*)(int))&Perl__assigntask); package.add("assigntask", (void(*)(int, bool))&Perl__assigntask); package.add("attack", &Perl__attack); diff --git a/zone/lua_client.cpp b/zone/lua_client.cpp index 932774561..7534c0e14 100644 --- a/zone/lua_client.cpp +++ b/zone/lua_client.cpp @@ -1409,9 +1409,9 @@ void Lua_Client::FailTask(int task) { self->FailTask(task); } -bool Lua_Client::IsTaskCompleted(int task) { +bool Lua_Client::IsTaskCompleted(int task_id) { Lua_Safe_Call_Bool(); - return self->IsTaskCompleted(task) != 0; + return self->IsTaskCompleted(task_id); } bool Lua_Client::IsTaskActive(int task) { @@ -3379,6 +3379,39 @@ uint8 Lua_Client::GetSkillTrainLevel(int skill_id) return self->GetSkillTrainLevel(static_cast(skill_id), self->GetClass()); } +bool Lua_Client::AreTasksCompleted(luabind::object task_ids) +{ + Lua_Safe_Call_Int(); + + if (luabind::type(task_ids) != LUA_TTABLE) { + return false; + } + + std::vector v; + int index = 1; + while (luabind::type(task_ids[index]) != LUA_TNIL) { + auto current_id = task_ids[index]; + int task_id = 0; + if (luabind::type(current_id) != LUA_TNIL) { + try { + task_id = luabind::object_cast(current_id); + } catch(luabind::cast_failed &) { + } + } else { + break; + } + + v.push_back(task_id); + ++index; + } + + if (v.empty()) { + return false; + } + + return self->AreTasksCompleted(v); +} + luabind::scope lua_register_client() { return luabind::class_("Client") .def(luabind::constructor<>()) @@ -3425,6 +3458,7 @@ luabind::scope lua_register_client() { .def("ApplySpellRaid", (void(Lua_Client::*)(int,int,int,bool))&Lua_Client::ApplySpellRaid) .def("ApplySpellRaid", (void(Lua_Client::*)(int,int,int,bool,bool))&Lua_Client::ApplySpellRaid) .def("ApplySpellRaid", (void(Lua_Client::*)(int,int,int,bool,bool,bool))&Lua_Client::ApplySpellRaid) + .def("AreTasksCompleted", (bool(Lua_Client::*)(luabind::object))&Lua_Client::AreTasksCompleted) .def("AssignTask", (void(Lua_Client::*)(int))&Lua_Client::AssignTask) .def("AssignTask", (void(Lua_Client::*)(int,int))&Lua_Client::AssignTask) .def("AssignTask", (void(Lua_Client::*)(int,int,bool))&Lua_Client::AssignTask) diff --git a/zone/lua_client.h b/zone/lua_client.h index 54ec7b589..f36a20e3d 100644 --- a/zone/lua_client.h +++ b/zone/lua_client.h @@ -360,7 +360,7 @@ public: void AssignTask(int task_id, int npc_id); void AssignTask(int task_id, int npc_id, bool enforce_level_requirement); void FailTask(int task); - bool IsTaskCompleted(int task); + bool IsTaskCompleted(int task_id); bool IsTaskActive(int task); bool IsTaskActivityActive(int task, int activity); void LockSharedTask(bool lock); @@ -577,6 +577,7 @@ public: void CampAllBots(uint8 class_id); bool RemoveAAPoints(uint32 points); bool RemoveAlternateCurrencyValue(uint32 currency_id, uint32 amount); + bool AreTasksCompleted(luabind::object task_ids); void DialogueWindow(std::string markdown); diff --git a/zone/lua_general.cpp b/zone/lua_general.cpp index eddbc3473..d3a893488 100644 --- a/zone/lua_general.cpp +++ b/zone/lua_general.cpp @@ -5604,6 +5604,37 @@ uint32 lua_get_zone_uptime() return Timer::GetCurrentTime() / 1000; } +int lua_are_tasks_completed(luabind::object task_ids) +{ + if (luabind::type(task_ids) != LUA_TTABLE) { + return 0; + } + + std::vector v; + int index = 1; + while (luabind::type(task_ids[index]) != LUA_TNIL) { + auto current_id = task_ids[index]; + int task_id = 0; + if (luabind::type(current_id) != LUA_TNIL) { + try { + task_id = luabind::object_cast(current_id); + } catch(luabind::cast_failed &) { + } + } else { + break; + } + + v.push_back(task_id); + ++index; + } + + if (v.empty()) { + return 0; + } + + return quest_manager.aretaskscompleted(v); +} + #define LuaCreateNPCParse(name, c_type, default_value) do { \ cur = table[#name]; \ if(luabind::type(cur) != LUA_TNIL) { \ @@ -6410,6 +6441,7 @@ luabind::scope lua_register_general() { luabind::def("get_zone_short_name_by_long_name", &lua_get_zone_short_name_by_long_name), luabind::def("send_parcel", &lua_send_parcel), luabind::def("get_zone_uptime", &lua_get_zone_uptime), + luabind::def("are_tasks_completed", &lua_are_tasks_completed), /* Cross Zone */ diff --git a/zone/perl_client.cpp b/zone/perl_client.cpp index 596069f90..cf90ef024 100644 --- a/zone/perl_client.cpp +++ b/zone/perl_client.cpp @@ -3176,6 +3176,17 @@ uint8 Perl_Client_GetSkillTrainLevel(Client* self, int skill_id) return self->GetSkillTrainLevel(static_cast(skill_id), self->GetClass()); } +bool Perl_Client_AreTasksCompleted(Client* self, perl::array task_ids) +{ + std::vector v; + + for (const auto& e : task_ids) { + v.push_back(static_cast(e)); + } + + return self->AreTasksCompleted(v); +} + void perl_register_client() { perl::interpreter perl(PERL_GET_THX); @@ -3225,6 +3236,7 @@ void perl_register_client() package.add("ApplySpellRaid", (void(*)(Client*, int, int, int, bool))&Perl_Client_ApplySpellRaid); package.add("ApplySpellRaid", (void(*)(Client*, int, int, int, bool, bool))&Perl_Client_ApplySpellRaid); package.add("ApplySpellRaid", (void(*)(Client*, int, int, int, bool, bool, bool))&Perl_Client_ApplySpellRaid); + package.add("AreTasksCompleted", (bool(*)(Client*, perl::array))&Perl_Client_AreTasksCompleted); package.add("AssignTask", (void(*)(Client*, int))&Perl_Client_AssignTask); package.add("AssignTask", (void(*)(Client*, int, int))&Perl_Client_AssignTask); package.add("AssignTask", (void(*)(Client*, int, int, bool))&Perl_Client_AssignTask); diff --git a/zone/questmgr.cpp b/zone/questmgr.cpp index b3df21f1d..0cf61bb9d 100644 --- a/zone/questmgr.cpp +++ b/zone/questmgr.cpp @@ -3251,13 +3251,26 @@ int QuestManager::activespeakactivity(int taskid) { return 0; } -int QuestManager::istaskcompleted(int taskid) { +bool QuestManager::istaskcompleted(int task_id) +{ QuestManagerCurrentQuestVars(); - if(RuleB(TaskSystem, EnableTaskSystem) && initiator) - return initiator->IsTaskCompleted(taskid); + if (initiator && RuleB(TaskSystem, EnableTaskSystem)) { + return initiator->IsTaskCompleted(task_id); + } - return -1; + return false; +} + +bool QuestManager::aretaskscompleted(const std::vector& task_ids) +{ + QuestManagerCurrentQuestVars(); + + if (initiator && RuleB(TaskSystem, EnableTaskSystem)) { + return initiator->AreTasksCompleted(task_ids); + } + + return false; } int QuestManager::activetasksinset(int taskset) { diff --git a/zone/questmgr.h b/zone/questmgr.h index 164ba9159..31e177ed6 100644 --- a/zone/questmgr.h +++ b/zone/questmgr.h @@ -225,7 +225,8 @@ public: void assigntask(int taskid, bool enforce_level_requirement = false); void failtask(int taskid); int tasktimeleft(int taskid); - int istaskcompleted(int taskid); + bool istaskcompleted(int task_id); + bool aretaskscompleted(const std::vector& task_ids); int enabledtaskcount(int taskset); int firsttaskinset(int taskset); int lasttaskinset(int taskset); diff --git a/zone/task_client_state.cpp b/zone/task_client_state.cpp index 66c4ea91c..31790135c 100644 --- a/zone/task_client_state.cpp +++ b/zone/task_client_state.cpp @@ -1578,25 +1578,35 @@ int ClientTaskState::TaskTimeLeft(int task_id) return -1; } -int ClientTaskState::IsTaskCompleted(int task_id) +bool ClientTaskState::IsTaskCompleted(int task_id) { - - // Returns: -1 if RecordCompletedTasks is not true - // +1 if the task has been completed - // 0 if the task has not been completed - - if (!(RuleB(TaskSystem, RecordCompletedTasks))) { - return -1; + if (!RuleB(TaskSystem, RecordCompletedTasks)) { + return false; } - for (auto &completed_task : m_completed_tasks) { - LogTasks("Comparing completed task [{}] with [{}]", completed_task.task_id, task_id); - if (completed_task.task_id == task_id) { - return 1; + for (const auto& e : m_completed_tasks) { + LogTasks("Comparing completed task [{}] with [{}]", e.task_id, task_id); + if (e.task_id == task_id) { + return true; } } - return 0; + return false; +} + +bool ClientTaskState::AreTasksCompleted(const std::vector& task_ids) +{ + if (!RuleB(TaskSystem, RecordCompletedTasks)) { + return false; + } + + for (const auto& e : task_ids) { + if (!IsTaskCompleted(e)) { + return false; + } + } + + return true; } bool ClientTaskState::TaskOutOfTime(TaskType task_type, int index) diff --git a/zone/task_client_state.h b/zone/task_client_state.h index 4430f17d6..6f22feb4a 100644 --- a/zone/task_client_state.h +++ b/zone/task_client_state.h @@ -45,7 +45,8 @@ 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); - int IsTaskCompleted(int task_id); + bool IsTaskCompleted(int task_id); + bool AreTasksCompleted(const std::vector& task_ids); bool IsTaskActive(int task_id); bool IsTaskActivityActive(int task_id, int activity_id); ActivityState GetTaskActivityState(TaskType task_type, int index, int activity_id);