[Commands] Add #task complete Command (#3711)

# Notes
- `#task complete [Task ID]` allows operators to complete an entire task without updating individual activities.
This commit is contained in:
Alex King 2023-11-26 00:27:08 -05:00 committed by GitHub
parent 692a90f3f0
commit f8c3c03185
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 141 additions and 64 deletions

View File

@ -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)

View File

@ -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 <task_id> <activity_id> [count] | Updates task");
c->Message(Chat::White, "--- assign <task_id> | Assigns task to client");
c->Message(Chat::White, "--- complete <task_id> | Completes a task if a client has it assigned to them");
c->Message(Chat::White, "--- uncomplete <task_id> | 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);
}
}
}

View File

@ -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;
}

View File

@ -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; }