Add actual support for multi-zone task activities

This commit is contained in:
Michael Cook (mackal) 2018-08-01 13:50:09 -04:00
parent 060f8aadfe
commit 93749bc509
2 changed files with 23 additions and 14 deletions

View File

@ -249,7 +249,9 @@ bool TaskManager::LoadTasks(int singleTask)
Tasks[taskID]->Activity[Tasks[taskID]->ActivityCount].GoalCount = atoi(row[11]);
Tasks[taskID]->Activity[Tasks[taskID]->ActivityCount].DeliverToNPC = atoi(row[12]);
Tasks[taskID]->Activity[Tasks[taskID]->ActivityCount].zones = row[13];
Tasks[taskID]->Activity[Tasks[taskID]->ActivityCount].ZoneID = atoi(row[13]); // for older clients
auto zones = SplitString(Tasks[taskID]->Activity[Tasks[taskID]->ActivityCount].zones, ';');
for (auto && e : zones)
Tasks[taskID]->Activity[Tasks[taskID]->ActivityCount].ZoneIDs.push_back(std::stoi(e));
Tasks[taskID]->Activity[Tasks[taskID]->ActivityCount].Optional = atoi(row[14]);
Log(Logs::General, Logs::Tasks,
@ -1144,7 +1146,7 @@ void TaskManager::SendTaskSelector(Client *c, Mob *mob, int TaskCount, int *Task
buf.WriteInt32(activity.skill_id);
buf.WriteInt32(activity.spell_id);
buf.WriteInt32(activity.ZoneID);
buf.WriteInt32(activity.ZoneIDs.empty() ? 0 : activity.ZoneIDs.front());
buf.WriteString(activity.desc_override);
}
}
@ -1534,7 +1536,7 @@ bool ClientTaskState::UpdateTasksByNPC(Client *c, int ActivityType, int NPCTypeI
if (Task->Activity[j].Type != ActivityType)
continue;
// Is there a zone restriction on the activity ?
if ((Task->Activity[j].ZoneID > 0) && (Task->Activity[j].ZoneID != (int)zone->GetZoneID())) {
if (!Task->Activity[j].CheckZone(zone->GetZoneID())) {
Log(Logs::General, Logs::Tasks,
"[UPDATE] Char: %s Task: %i, Activity %i, Activity type %i for NPC %i failed zone "
"check",
@ -1594,7 +1596,7 @@ int ClientTaskState::ActiveSpeakTask(int NPCTypeID) {
if (Task->Activity[j].Type != ActivitySpeakWith)
continue;
// Is there a zone restriction on the activity ?
if (Task->Activity[j].ZoneID > 0 && Task->Activity[j].ZoneID != (int)zone->GetZoneID())
if (!Task->Activity[j].CheckZone(zone->GetZoneID()))
continue;
// Is the activity to speak with this type of NPC ?
if (Task->Activity[j].GoalMethod == METHODQUEST && Task->Activity[j].GoalID == NPCTypeID)
@ -1632,7 +1634,7 @@ int ClientTaskState::ActiveSpeakActivity(int NPCTypeID, int TaskID) {
if (Task->Activity[j].Type != ActivitySpeakWith)
continue;
// Is there a zone restriction on the activity ?
if (Task->Activity[j].ZoneID > 0 && Task->Activity[j].ZoneID != (int)zone->GetZoneID())
if (!Task->Activity[j].CheckZone(zone->GetZoneID()))
continue;
// Is the activity to speak with this type of NPC ?
if (Task->Activity[j].GoalMethod == METHODQUEST && Task->Activity[j].GoalID == NPCTypeID)
@ -1678,7 +1680,7 @@ void ClientTaskState::UpdateTasksForItem(Client *c, ActivityType Type, int ItemI
if (Task->Activity[j].Type != (int)Type)
continue;
// Is there a zone restriction on the activity ?
if (Task->Activity[j].ZoneID > 0 && Task->Activity[j].ZoneID != (int)zone->GetZoneID()) {
if (!Task->Activity[j].CheckZone(zone->GetZoneID())) {
Log(Logs::General, Logs::Tasks, "[UPDATE] Char: %s Activity type %i for Item %i failed zone check",
c->GetName(), Type, ItemID);
continue;
@ -1737,7 +1739,7 @@ void ClientTaskState::UpdateTasksOnExplore(Client *c, int ExploreID)
// We are only interested in explore activities
if (Task->Activity[j].Type != ActivityExplore)
continue;
if (Task->Activity[j].ZoneID > 0 && Task->Activity[j].ZoneID != (int)zone->GetZoneID()) {
if (!Task->Activity[j].CheckZone(zone->GetZoneID())) {
Log(Logs::General, Logs::Tasks,
"[UPDATE] Char: %s Explore exploreid %i failed zone check", c->GetName(),
ExploreID);
@ -1801,11 +1803,11 @@ bool ClientTaskState::UpdateTasksOnDeliver(Client *c, std::list<EQEmu::ItemInsta
if (Task->Activity[j].Type != ActivityDeliver && Task->Activity[j].Type != ActivityGiveCash)
continue;
// Is there a zone restriction on the activity ?
if (Task->Activity[j].ZoneID > 0 && Task->Activity[j].ZoneID != (int)zone->GetZoneID()) {
if (!Task->Activity[j].CheckZone(zone->GetZoneID())) {
Log(Logs::General, Logs::Tasks,
"[UPDATE] Char: %s Deliver activity failed zone check (current zone %i, need zone "
"%i",
c->GetName(), zone->GetZoneID(), Task->Activity[j].ZoneID);
"%s",
c->GetName(), zone->GetZoneID(), Task->Activity[j].zones.c_str());
continue;
}
// Is the activity to deliver to this NPCTypeID ?
@ -1878,7 +1880,7 @@ void ClientTaskState::UpdateTasksOnTouch(Client *c, int ZoneID)
continue;
if (Task->Activity[j].GoalMethod != METHODSINGLEID)
continue;
if (Task->Activity[j].ZoneID != ZoneID) {
if (!Task->Activity[j].CheckZone(ZoneID)) {
Log(Logs::General, Logs::Tasks, "[UPDATE] Char: %s Touch activity failed zone check",
c->GetName());
continue;
@ -2568,7 +2570,7 @@ void ClientTaskState::SendTaskHistory(Client *c, int TaskIndex) {
thd2->GoalCount = Task->Activity[i].GoalCount;
thd2->unknown04 = 0xffffffff;
thd2->unknown08 = 0xffffffff;
thd2->ZoneID = Task->Activity[i].ZoneID;
thd2->ZoneID = Task->Activity[i].ZoneIDs.empty() ? 0 : Task->Activity[i].ZoneIDs.front();
thd2->unknown16 = 0x00000000;
Ptr = (char *)thd2 + sizeof(TaskHistoryReplyData2_Struct);
VARSTRUCT_ENCODE_STRING(Ptr, Task->Activity[i].desc_override.c_str());
@ -2772,7 +2774,7 @@ void TaskManager::SendTaskActivityLong(Client *c, int TaskID, int ActivityID, in
buf.WriteUInt32(Tasks[TaskID]->Activity[ActivityID].skill_id);
buf.WriteUInt32(Tasks[TaskID]->Activity[ActivityID].spell_id);
buf.WriteUInt32(Tasks[TaskID]->Activity[ActivityID].ZoneID);
buf.WriteUInt32(Tasks[TaskID]->Activity[ActivityID].ZoneIDs.empty() ? 0 : Tasks[TaskID]->Activity[ActivityID].ZoneIDs.front());
buf.WriteUInt32(0);
buf.WriteString(Tasks[TaskID]->Activity[ActivityID].desc_override);

View File

@ -25,6 +25,7 @@ Copyright (C) 2001-2004 EQEMu Development Team (http://eqemulator.net)
#include <list>
#include <vector>
#include <string>
#include <algorithm>
#define MAXTASKS 10000
#define MAXTASKSETS 1000
@ -113,9 +114,15 @@ struct ActivityInformation {
TaskMethodType GoalMethod;
int GoalCount;
int DeliverToNPC;
int ZoneID;
std::vector<int> ZoneIDs;
std::string zones; // IDs ; searated, ZoneID is the first in this list for older clients -- default empty string
bool Optional;
inline bool CheckZone(int zone_id) {
if (ZoneIDs.empty())
return true;
return std::find(ZoneIDs.begin(), ZoneIDs.end(), zone_id) != ZoneIDs.end();
}
};
typedef enum { ActivitiesSequential = 0, ActivitiesStepped = 1 } SequenceType;