More work on tasks

This commit is contained in:
Michael Cook (mackal) 2018-06-16 22:42:26 -04:00
parent 9bd5f36129
commit 6708cd3d75
3 changed files with 76 additions and 64 deletions

View File

@ -322,6 +322,7 @@
#define FAILED_TAUNT 5811 //You have failed to taunt your target. #define FAILED_TAUNT 5811 //You have failed to taunt your target.
#define PHYSICAL_RESIST_FAIL 5817 //Your target avoided your %1 ability. #define PHYSICAL_RESIST_FAIL 5817 //Your target avoided your %1 ability.
#define AA_NO_TARGET 5825 //You must first select a target for this ability! #define AA_NO_TARGET 5825 //You must first select a target for this ability!
#define MAX_ACTIVE_TASKS 6010 //Sorry %3, you already have the maximum number of active tasks.
#define FORAGE_MASTERY 6012 //Your forage mastery has enabled you to find something else! #define FORAGE_MASTERY 6012 //Your forage mastery has enabled you to find something else!
#define GUILD_BANK_CANNOT_DEPOSIT 6097 // Cannot deposit this item. Containers must be empty, and only one of each LORE and no NO TRADE or TEMPORARY items may be deposited. #define GUILD_BANK_CANNOT_DEPOSIT 6097 // Cannot deposit this item. Containers must be empty, and only one of each LORE and no NO TRADE or TEMPORARY items may be deposited.
#define GUILD_BANK_FULL 6098 // There is no more room in the Guild Bank. #define GUILD_BANK_FULL 6098 // There is no more room in the Guild Bank.

View File

@ -34,6 +34,7 @@ Copyright (C) 2001-2008 EQEMu Development Team (http://eqemulator.net)
#include "client.h" #include "client.h"
#include "entity.h" #include "entity.h"
#include "mob.h" #include "mob.h"
#include "string_ids.h"
#include "queryserv.h" #include "queryserv.h"
#include "quest_parser_collection.h" #include "quest_parser_collection.h"
@ -846,6 +847,27 @@ int ClientTaskState::CompletedTasksInSet(int TaskSetID) {
return Count; return Count;
} }
bool ClientTaskState::HasSlotForTask(TaskInformation *task)
{
if (task == nullptr)
return false;
switch (task->type) {
case TaskType::Task:
return ActiveTask.TaskID == TASKSLOTEMPTY;
case TaskType::Shared:
return false; // todo
case TaskType::Quest:
for (int i = 0; i < MAXACTIVEQUESTS; ++i)
if (ActiveQuests[i].TaskID == TASKSLOTEMPTY)
return true;
case TaskType::E:
return false; // removed on live
}
return false;
}
int TaskManager::FirstTaskInSet(int TaskSetID) { int TaskManager::FirstTaskInSet(int TaskSetID) {
if((TaskSetID<=0) || (TaskSetID>=MAXTASKSETS)) return 0; if((TaskSetID<=0) || (TaskSetID>=MAXTASKSETS)) return 0;
@ -917,78 +939,58 @@ int TaskManager::GetTaskMaxLevel(int TaskID)
return -1; return -1;
} }
void TaskManager::TaskSetSelector(Client *c, ClientTaskState *state, Mob *mob, int TaskSetID) { void TaskManager::TaskSetSelector(Client *c, ClientTaskState *state, Mob *mob, int TaskSetID)
{
unsigned int EnabledTaskIndex = 0; unsigned int EnabledTaskIndex = 0;
unsigned int TaskSetIndex = 0; unsigned int TaskSetIndex = 0;
int TaskList[MAXCHOOSERENTRIES]; int TaskList[MAXCHOOSERENTRIES];
int TaskListIndex = 0; int TaskListIndex = 0;
int PlayerLevel = c->GetLevel(); int PlayerLevel = c->GetLevel();
Log(Logs::General, Logs::Tasks, "[UPDATE] TaskSetSelector called for taskset %i. EnableTaskSize is %i", TaskSetID, Log(Logs::General, Logs::Tasks, "[UPDATE] TaskSetSelector called for taskset %i. EnableTaskSize is %i",
state->EnabledTasks.size()); TaskSetID, state->EnabledTasks.size());
if((TaskSetID<=0) || (TaskSetID>=MAXTASKSETS)) return;
if(!TaskSets[TaskSetID].empty()) { if (TaskSetID <= 0 || TaskSetID >= MAXTASKSETS)
return;
if (TaskSets[TaskSetID].empty()) {
c->Message_StringID(15, MAX_ACTIVE_TASKS, c->GetName()); // check color
return;
}
bool all_enabled = false;
// A TaskID of 0 in a TaskSet indicates that all Tasks in the set are enabled for all players. // A TaskID of 0 in a TaskSet indicates that all Tasks in the set are enabled for all players.
if (TaskSets[TaskSetID][0] == 0) { if (TaskSets[TaskSetID][0] == 0) {
Log(Logs::General, Logs::Tasks, "[UPDATE] TaskSets[%i][0] == 0. All Tasks in Set enabled.", TaskSetID); Log(Logs::General, Logs::Tasks, "[UPDATE] TaskSets[%i][0] == 0. All Tasks in Set enabled.", TaskSetID);
all_enabled = true;
}
auto Iterator = TaskSets[TaskSetID].begin(); auto Iterator = TaskSets[TaskSetID].begin();
while((Iterator != TaskSets[TaskSetID].end()) && (TaskListIndex < MAXCHOOSERENTRIES)) { if (all_enabled)
if(AppropriateLevel((*Iterator), PlayerLevel) && !state->IsTaskActive((*Iterator)) && ++Iterator; // skip first when all enabled since it's useless data
(IsTaskRepeatable((*Iterator)) || !state->IsTaskCompleted((*Iterator))))
TaskList[TaskListIndex++] = (*Iterator); while (Iterator != TaskSets[TaskSetID].end() && TaskListIndex < MAXCHOOSERENTRIES) {
auto task = *Iterator;
// verify level, we're not currently on it, repeatable status, if it's a (shared) task
// we aren't currently on another, and if it's enabled if not all_enabled
if ((all_enabled || state->IsTaskEnabled(task)) && AppropriateLevel(task, PlayerLevel) &&
!state->IsTaskActive(task) && state->HasSlotForTask(Tasks[task]) && // this slot checking is a bit silly, but we allow mixing of task types ...
(IsTaskRepeatable(task) || !state->IsTaskCompleted(task)))
TaskList[TaskListIndex++] = task;
++Iterator; ++Iterator;
} }
if(TaskListIndex > 0)
{ if (TaskListIndex > 0) {
SendTaskSelector(c, mob, TaskListIndex, TaskList); SendTaskSelector(c, mob, TaskListIndex, TaskList);
} else {
c->Message_StringID(15, MAX_ACTIVE_TASKS, c->GetName()); // check color, I think this might be only for (Shared) Tasks, w/e
} }
return; return;
} }
}
while((EnabledTaskIndex < state->EnabledTasks.size()) && (TaskSetIndex < TaskSets[TaskSetID].size()) &&
(TaskListIndex < MAXCHOOSERENTRIES)) {
Log(Logs::General, Logs::Tasks, "[UPDATE] Comparing EnabledTasks[%i] (%i) with TaskSets[%i][%i] (%i)",
EnabledTaskIndex, state->EnabledTasks[EnabledTaskIndex], TaskSetID, TaskSetIndex,
TaskSets[TaskSetID][TaskSetIndex]);
if((TaskSets[TaskSetID][TaskSetIndex] > 0) &&
(state->EnabledTasks[EnabledTaskIndex] == TaskSets[TaskSetID][TaskSetIndex])) {
if(AppropriateLevel(TaskSets[TaskSetID][TaskSetIndex], PlayerLevel) &&
!state->IsTaskActive(TaskSets[TaskSetID][TaskSetIndex]) &&
(IsTaskRepeatable(TaskSets[TaskSetID][TaskSetIndex]) ||
!state->IsTaskCompleted(TaskSets[TaskSetID][TaskSetIndex]))) {
TaskList[TaskListIndex++] = TaskSets[TaskSetID][TaskSetIndex];
EnabledTaskIndex++;
TaskSetIndex++;
continue;
}
}
if(state->EnabledTasks[EnabledTaskIndex] < TaskSets[TaskSetID][TaskSetIndex])
EnabledTaskIndex++;
else
TaskSetIndex++;
}
if(TaskListIndex == 0) return;
SendTaskSelector(c, mob, TaskListIndex, TaskList);
}
void TaskManager::SendTaskSelector(Client *c, Mob *mob, int TaskCount, int *TaskList) { void TaskManager::SendTaskSelector(Client *c, Mob *mob, int TaskCount, int *TaskList) {
@ -1998,16 +2000,19 @@ void ClientTaskState::RewardTask(Client *c, TaskInformation *Task) {
c->SendSound(); c->SendSound();
} }
bool ClientTaskState::IsTaskActive(int TaskID) { bool ClientTaskState::IsTaskActive(int TaskID)
{
if((ActiveTaskCount == 0) || (TaskID == 0)) return false; if (ActiveTaskCount == 0 || TaskID == 0)
return false;
for (int i = 0; i < MAXACTIVEQUESTS; i++) { for (int i = 0; i < MAXACTIVEQUESTS; i++) {
if (ActiveQuests[i].TaskID == TaskID)
if(ActiveQuests[i].TaskID==TaskID) return true; return true;
} }
if (ActiveTask.TaskID == TaskID)
return true;
return false; return false;
} }

View File

@ -28,7 +28,7 @@ Copyright (C) 2001-2004 EQEMu Development Team (http://eqemulator.net)
#define MAXTASKS 10000 #define MAXTASKS 10000
#define MAXTASKSETS 1000 #define MAXTASKSETS 1000
// The Client has a hard cap of 19 active tasks, 29 in RoF2 // The Client has a hard cap of 19 active quests, 29 in SoD+
#define MAXACTIVEQUESTS 19 #define MAXACTIVEQUESTS 19
// The Max Chooser (Task Selector entries) is capped at 40 in the Titanium Client. // The Max Chooser (Task Selector entries) is capped at 40 in the Titanium Client.
#define MAXCHOOSERENTRIES 40 #define MAXCHOOSERENTRIES 40
@ -222,13 +222,19 @@ public:
int ActiveSpeakActivity(int NPCID, int TaskID); int ActiveSpeakActivity(int NPCID, int TaskID);
int ActiveTasksInSet(int TaskSetID); int ActiveTasksInSet(int TaskSetID);
int CompletedTasksInSet(int TaskSetID); int CompletedTasksInSet(int TaskSetID);
bool HasSlotForTask(TaskInformation *task);
inline bool HasFreeTaskSlot() { return ActiveTask.TaskID == TASKSLOTEMPTY; }
friend class TaskManager; friend class TaskManager;
private: private:
bool UnlockActivities(int CharID, int TaskIndex); bool UnlockActivities(int CharID, int TaskIndex);
void IncrementDoneCount(Client *c, TaskInformation *Task, int TaskIndex, int ActivityID, int Count = 1, bool ignore_quest_update = false); void IncrementDoneCount(Client *c, TaskInformation *Task, int TaskIndex, int ActivityID, int Count = 1, bool ignore_quest_update = false);
int ActiveTaskCount; int ActiveTaskCount;
ClientTaskInformation ActiveTask; // only one
ClientTaskInformation ActiveQuests[MAXACTIVEQUESTS]; ClientTaskInformation ActiveQuests[MAXACTIVEQUESTS];
// Shared tasks should be limited to 1 as well
std::vector<int> EnabledTasks; std::vector<int> EnabledTasks;
std::vector<CompletedTaskInformation> CompletedTasks; std::vector<CompletedTaskInformation> CompletedTasks;
int LastCompletedTaskLoaded; int LastCompletedTaskLoaded;