diff --git a/zone/client.h b/zone/client.h index 367263579..1c435bd55 100644 --- a/zone/client.h +++ b/zone/client.h @@ -1275,6 +1275,10 @@ public: } else { return 0; } } + inline bool CompleteTask(uint32 task_id) + { + return task_state ? task_state->CompleteTask(this, task_id) : false; + } inline void FailTask(int task_id) { if (task_state) { task_state->FailTask(this, task_id); }} inline int TaskTimeLeft(int task_id) { return (task_state ? task_state->TaskTimeLeft(task_id) : 0); } inline int EnabledTaskCount(int task_set_id) diff --git a/zone/gm_commands/task.cpp b/zone/gm_commands/task.cpp index 723e461bc..37aafc84b 100755 --- a/zone/gm_commands/task.cpp +++ b/zone/gm_commands/task.cpp @@ -8,7 +8,7 @@ extern WorldServer worldserver; void command_task(Client *c, const Seperator *sep) { - int arguments = sep->argnum; + const int arguments = sep->argnum; if (!arguments) { c->Message(Chat::White, "Syntax: #task [subcommand]"); c->Message(Chat::White, "------------------------------------------------"); @@ -23,6 +23,7 @@ void command_task(Client *c, const Seperator *sep) ); c->Message(Chat::White, "--- update [count] | Updates task"); c->Message(Chat::White, "--- assign | Assigns task to client"); + c->Message(Chat::White, "--- complete | Completes a task if a client has it assigned to them"); c->Message(Chat::White, "--- uncomplete | Uncompletes a task if a client has completed it"); c->Message( Chat::White, @@ -73,22 +74,24 @@ void command_task(Client *c, const Seperator *sep) return; } - Client *target = c; + Client *t = c; if (c->GetTarget() && c->GetTarget()->IsClient()) { - target = c->GetTarget()->CastToClient(); + t = c->GetTarget()->CastToClient(); } - bool is_assign = !strcasecmp(sep->arg[1], "assign"); - bool is_purgetimers = !strcasecmp(sep->arg[1], "purgetimers"); - bool is_reload = !strcasecmp(sep->arg[1], "reload"); - bool is_reloadall = !strcasecmp(sep->arg[1], "reloadall"); - bool is_sharedpurge = !strcasecmp(sep->arg[1], "sharedpurge"); - bool is_show = !strcasecmp(sep->arg[1], "show"); - bool is_uncomplete = !strcasecmp(sep->arg[1], "uncomplete"); - bool is_update = !strcasecmp(sep->arg[1], "update"); + const bool is_assign = !strcasecmp(sep->arg[1], "assign"); + const bool is_complete = !strcasecmp(sep->arg[1], "complete"); + const bool is_purgetimers = !strcasecmp(sep->arg[1], "purgetimers"); + const bool is_reload = !strcasecmp(sep->arg[1], "reload"); + const bool is_reloadall = !strcasecmp(sep->arg[1], "reloadall"); + const bool is_sharedpurge = !strcasecmp(sep->arg[1], "sharedpurge"); + const bool is_show = !strcasecmp(sep->arg[1], "show"); + const bool is_uncomplete = !strcasecmp(sep->arg[1], "uncomplete"); + const bool is_update = !strcasecmp(sep->arg[1], "update"); if ( !is_assign && + !is_complete && !is_purgetimers && !is_reload && !is_reloadall && @@ -161,70 +164,117 @@ void command_task(Client *c, const Seperator *sep) } if (is_assign) { - auto task_id = std::strtoul(sep->arg[2], nullptr, 10); + const uint32 task_id = Strings::ToUnsignedInt(sep->arg[2]); if (task_id) { - target->AssignTask(task_id, 0, false); + t->AssignTask(task_id, 0, false); c->Message( - Chat::Yellow, + Chat::White, fmt::format( - "Assigned task ID {} to {}.", + "Assigned {} (ID {}) to {}.", + task_manager->GetTaskName(task_id), task_id, - c->GetTargetDescription(target) + c->GetTargetDescription(t) ).c_str() ); } - return; + } else if (is_complete) { + if (sep->IsNumber(2)) { + const uint32 task_id = Strings::ToUnsignedInt(sep->arg[2]); + if (!task_id) { + c->Message(Chat::White, "Invalid task ID specified."); + return; + } + + if (t->IsTaskActive(task_id)) { + const bool did_complete = t->CompleteTask(task_id); + if (did_complete) { + c->Message( + Chat::White, + fmt::format( + "Successfully completed {} (ID {}) for {}.", + task_manager->GetTaskName(task_id), + task_id, + c->GetTargetDescription(t) + ).c_str() + ); + } else { + c->Message( + Chat::White, + fmt::format( + "Failed to complete {} (ID {}) for {}.", + task_manager->GetTaskName(task_id), + task_id, + c->GetTargetDescription(t) + ).c_str() + ); + } + } else { + c->Message( + Chat::White, + fmt::format( + "{} {} not have not {} (ID {}) assigned to them.", + c->GetTargetDescription(t, TargetDescriptionType::UCYou), + c == t ? "do" : "does", + task_manager->GetTaskName(task_id), + task_id + ).c_str() + ); + } + } } else if (is_purgetimers) { c->Message( - Chat::Yellow, + Chat::White, fmt::format( "Task timers have been purged for {}.", - c->GetTargetDescription(target) + c->GetTargetDescription(t) ).c_str() ); - if (c != target) { - target->Message(Chat::Yellow, "Your task timers have been purged by a GM."); + if (c != t) { + t->Message(Chat::White, "Your task timers have been purged by a GM."); } - target->PurgeTaskTimers(); - return; + t->PurgeTaskTimers(); } else if (is_reload) { if (arguments >= 2) { - if (!strcasecmp(sep->arg[2], "sets")) { - c->Message(Chat::Yellow, "Attempting to reload task sets."); + const bool is_sets = !strcasecmp(sep->arg[2], "sets"); + const bool is_task = !strcasecmp(sep->arg[2], "task"); + + if (is_sets) { + c->Message(Chat::White, "Attempting to reload task sets."); worldserver.SendReloadTasks(RELOADTASKSETS); - c->Message(Chat::Yellow, "Successfully reloaded task sets."); - return; - } else if (!strcasecmp(sep->arg[2], "task") && arguments == 3) { - int task_id = std::strtoul(sep->arg[3], nullptr, 10); + c->Message(Chat::White, "Successfully reloaded task sets."); + } else if (is_task && arguments == 3 && sep->IsNumber(3)) { + const uint32 task_id = Strings::ToUnsignedInt(sep->arg[3]); if (task_id) { c->Message( - Chat::Yellow, + Chat::White, fmt::format( - "Attempted to reload task ID {}.", + "Attempting to reload {} (ID {}).", + task_manager->GetTaskName(task_id), task_id ).c_str() ); worldserver.SendReloadTasks(RELOADTASKS, task_id); c->Message( - Chat::Yellow, + Chat::White, fmt::format( - "Successfully reloaded task ID {}.", + "Successfully reloaded {} (ID {}).", + task_manager->GetTaskName(task_id), task_id ).c_str() ); - return; } } } } else if (is_reloadall) { - c->Message(Chat::Yellow, "Attempting to reload tasks."); + c->Message(Chat::White, "Attempting to reload tasks."); worldserver.SendReloadTasks(RELOADTASKS); - c->Message(Chat::Yellow, "Successfully reloaded tasks."); - return; + c->Message(Chat::White, "Successfully reloaded tasks."); } else if (is_sharedpurge) { - if (!strcasecmp(sep->arg[2], "confirm")) { + const bool is_confirm = !strcasecmp(sep->arg[2], "confirm"); + + if (is_confirm) { LogTasksDetail("Sending purge request"); auto pack = new ServerPacket(ServerOP_SharedTaskPurgeAllCommand, 0); worldserver.SendPacket(pack); @@ -239,14 +289,11 @@ void command_task(Client *c, const Seperator *sep) Saylink::Silent("#task sharedpurge confirm", "confirm") ).c_str() ); - - return; } else if (is_show) { - target->ShowClientTasks(c); - return; + t->ShowClientTasks(c); } else if (is_uncomplete) { if (sep->IsNumber(2)) { - auto task_id = Strings::ToUnsignedInt(sep->arg[2]); + const uint32 task_id = Strings::ToUnsignedInt(sep->arg[2]); if (!task_id) { c->Message(Chat::White, "Invalid task ID specified."); return; @@ -257,57 +304,60 @@ void command_task(Client *c, const Seperator *sep) database, fmt::format( "charid = {} AND taskid = {}", - target->CharacterID(), - task_id + t->CharacterID(), + task_id ) ) ) { c->Message( - Chat::Yellow, + Chat::White, fmt::format( - "Successfully uncompleted task ID {} for {}.", + "Successfully uncompleted {} (ID {}) for {}.", + task_manager->GetTaskName(task_id), task_id, - c->GetTargetDescription(target) + c->GetTargetDescription(t) ).c_str() ); } else { c->Message( - Chat::Yellow, + Chat::White, fmt::format( - "{} {} not completed task ID {}.", - c->GetTargetDescription(target, TargetDescriptionType::UCYou), - c == target ? "have" : "has", + "{} {} not completed {} (ID {}).", + c->GetTargetDescription(t, TargetDescriptionType::UCYou), + c == t ? "have" : "has", + task_manager->GetTaskName(task_id), task_id ).c_str() ); } } } else if (is_update) { - if (arguments >= 3) { - auto task_id = std::strtoul(sep->arg[2], nullptr, 10); - auto activity_id = std::strtoul(sep->arg[3], nullptr, 10); - int count = 1; + if (arguments >= 3 && sep->IsNumber(2) && sep->IsNumber(3)) { + const uint32 task_id = Strings::ToUnsignedInt(sep->arg[2]); + const uint32 activity_id = Strings::ToUnsignedInt(sep->arg[3]); + int count = 1; - if (arguments >= 4) { - count = std::strtol(sep->arg[4], nullptr, 10); + if (arguments == 4 && sep->IsNumber(4)) { + count = Strings::ToInt(sep->arg[4]); if (count <= 0) { count = 1; } } c->Message( - Chat::Yellow, + Chat::White, fmt::format( - "Updating task ID {}, activity {} with a count of {} for {}.", + "Updating {} (ID {}), activity {} with a count of {} for {}.", + task_manager->GetTaskName(task_id), task_id, activity_id, count, - c->GetTargetDescription(target) + c->GetTargetDescription(t) ).c_str() ); - target->UpdateTaskActivity(task_id, activity_id, count); - target->ShowClientTasks(c); + t->UpdateTaskActivity(task_id, activity_id, count); + t->ShowClientTasks(c); } } } diff --git a/zone/task_client_state.cpp b/zone/task_client_state.cpp index 54d581fce..369aebec9 100644 --- a/zone/task_client_state.cpp +++ b/zone/task_client_state.cpp @@ -1396,6 +1396,28 @@ void ClientTaskState::ResetTaskActivity(Client *client, int task_id, int activit ); } +bool ClientTaskState::CompleteTask(Client *c, uint32 task_id) +{ + const auto task_data = task_manager->GetTaskData(task_id); + if (!task_data) { + return false; + } + + for ( + int activity_id = 0; + activity_id < task_manager->GetActivityCount(task_id); + activity_id++ + ) { + c->UpdateTaskActivity( + task_id, + activity_id, + task_data->activity_information[activity_id].goal_count + ); + } + + return true; +} + void ClientTaskState::ShowClientTaskInfoMessage(ClientTaskInformation *task, Client *c) { const auto task_data = task_manager->GetTaskData(task->task_id); @@ -1565,7 +1587,7 @@ int ClientTaskState::IsTaskCompleted(int task_id) } for (auto &completed_task : m_completed_tasks) { - LogTasks("Comparing compelted task [{}] with [{}]", completed_task.task_id, task_id); + LogTasks("Comparing completed task [{}] with [{}]", completed_task.task_id, task_id); if (completed_task.task_id == task_id) { return 1; } diff --git a/zone/task_client_state.h b/zone/task_client_state.h index f1c1d6009..4430f17d6 100644 --- a/zone/task_client_state.h +++ b/zone/task_client_state.h @@ -84,6 +84,7 @@ public: bool CanAcceptNewTask(Client* client, int task_id, int npc_entity_id) const; bool HasExploreTask(Client* client) const; void EndSharedTask(Client* client, bool send_fail); + bool CompleteTask(Client *c, uint32 task_id); inline bool HasFreeTaskSlot() { return m_active_task.task_id == TASKSLOTEMPTY; }