mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-14 11:31:30 +00:00
[Shared Tasks] Task Kill Update Fix (#1573)
* Revert "Revert "Shared task kill update fix"" This reverts commit 859751f74d671ecaa36d777450803ece85a72bf4. * Swap return for continue in this context * Slight tweak * Slight tweak * Remove no longer needed task methods * Update scope for IncrementDoneCount * Create helper method Client::GetPartyMembers() and add client->HasTaskState() * Move HandleUpdateTasksOnKill responsibility to TaskManager * Remove unnecessary pointer
This commit is contained in:
parent
bb5c491794
commit
9a413cf553
@ -2357,9 +2357,7 @@ bool NPC::Death(Mob* killer_mob, int32 damage, uint16 spell, EQ::skills::SkillTy
|
|||||||
give_exp_client->GetCleanName(),
|
give_exp_client->GetCleanName(),
|
||||||
GetNPCTypeID()
|
GetNPCTypeID()
|
||||||
);
|
);
|
||||||
give_exp_client
|
task_manager->HandleUpdateTasksOnKill(give_exp_client, GetNPCTypeID());
|
||||||
->GetTaskState()
|
|
||||||
->HandleUpdateTasksOnKill(give_exp_client, GetNPCTypeID());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (kr) {
|
if (kr) {
|
||||||
|
|||||||
@ -10529,3 +10529,41 @@ void Client::SetDoorToolEntityId(uint16 door_tool_entity_id)
|
|||||||
{
|
{
|
||||||
Client::m_door_tool_entity_id = door_tool_entity_id;
|
Client::m_door_tool_entity_id = door_tool_entity_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// this will fetch raid clients if exists
|
||||||
|
// fallback to group if raid doesn't exist
|
||||||
|
// fallback to self if group doesn't exist
|
||||||
|
std::vector<Client *> Client::GetPartyMembers()
|
||||||
|
{
|
||||||
|
// get clients to update
|
||||||
|
std::vector<Client *> clients_to_update = {};
|
||||||
|
|
||||||
|
// raid
|
||||||
|
Raid *raid = entity_list.GetRaidByClient(this);
|
||||||
|
if (raid) {
|
||||||
|
for (auto &e : raid->members) {
|
||||||
|
if (e.member && e.member->IsClient()) {
|
||||||
|
clients_to_update.push_back(e.member->CastToClient());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// group
|
||||||
|
if (clients_to_update.empty()) {
|
||||||
|
Group *group = entity_list.GetGroupByClient(this);
|
||||||
|
if (group) {
|
||||||
|
for (auto &m : group->members) {
|
||||||
|
if (m && m->IsClient()) {
|
||||||
|
clients_to_update.push_back(m->CastToClient());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// solo
|
||||||
|
if (clients_to_update.empty()) {
|
||||||
|
clients_to_update.push_back(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
return clients_to_update;
|
||||||
|
}
|
||||||
|
|||||||
@ -1040,6 +1040,7 @@ public:
|
|||||||
void SendTaskRequestCooldownTimerMessage();
|
void SendTaskRequestCooldownTimerMessage();
|
||||||
void StartTaskRequestCooldownTimer();
|
void StartTaskRequestCooldownTimer();
|
||||||
inline ClientTaskState *GetTaskState() const { return task_state; }
|
inline ClientTaskState *GetTaskState() const { return task_state; }
|
||||||
|
inline bool HasTaskState() { if (task_state) { return true; } return false; }
|
||||||
inline void CancelTask(int task_index, TaskType task_type)
|
inline void CancelTask(int task_index, TaskType task_type)
|
||||||
{
|
{
|
||||||
if (task_state) {
|
if (task_state) {
|
||||||
@ -1094,15 +1095,6 @@ public:
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
inline void UpdateTasksOnKill(int npc_type_id)
|
|
||||||
{
|
|
||||||
if (task_state) {
|
|
||||||
task_state->UpdateTasksOnKill(
|
|
||||||
this,
|
|
||||||
npc_type_id
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
inline void UpdateTasksForItem(
|
inline void UpdateTasksForItem(
|
||||||
TaskActivityType activity_type,
|
TaskActivityType activity_type,
|
||||||
int item_id,
|
int item_id,
|
||||||
@ -1281,6 +1273,9 @@ public:
|
|||||||
bool m_shared_task_update = false;
|
bool m_shared_task_update = false;
|
||||||
bool m_requested_shared_task_removal = false;
|
bool m_requested_shared_task_removal = false;
|
||||||
|
|
||||||
|
std::vector<Client*> GetPartyMembers();
|
||||||
|
void HandleUpdateTasksOnKill(uint32 npc_type_id);
|
||||||
|
|
||||||
inline const EQ::versions::ClientVersion ClientVersion() const { return m_ClientVersion; }
|
inline const EQ::versions::ClientVersion ClientVersion() const { return m_ClientVersion; }
|
||||||
inline const uint32 ClientVersionBit() const { return m_ClientVersionBit; }
|
inline const uint32 ClientVersionBit() const { return m_ClientVersionBit; }
|
||||||
inline void SetClientVersion(EQ::versions::ClientVersion client_version) { m_ClientVersion = client_version; }
|
inline void SetClientVersion(EQ::versions::ClientVersion client_version) { m_ClientVersion = client_version; }
|
||||||
|
|||||||
@ -67,6 +67,8 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||||||
#include "../common/repositories/criteria/content_filter_criteria.h"
|
#include "../common/repositories/criteria/content_filter_criteria.h"
|
||||||
#include "../common/shared_tasks.h"
|
#include "../common/shared_tasks.h"
|
||||||
#include "gm_commands/door_manipulation.h"
|
#include "gm_commands/door_manipulation.h"
|
||||||
|
#include "client.h"
|
||||||
|
|
||||||
|
|
||||||
#ifdef BOTS
|
#ifdef BOTS
|
||||||
#include "bot.h"
|
#include "bot.h"
|
||||||
|
|||||||
@ -581,11 +581,6 @@ bool ClientTaskState::UnlockActivities(int character_id, ClientTaskInformation &
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClientTaskState::UpdateTasksOnKill(Client *client, int npc_type_id)
|
|
||||||
{
|
|
||||||
UpdateTasksByNPC(client, TaskActivityType::Kill, npc_type_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ClientTaskState::UpdateTasksOnSpeakWith(Client *client, int npc_type_id)
|
bool ClientTaskState::UpdateTasksOnSpeakWith(Client *client, int npc_type_id)
|
||||||
{
|
{
|
||||||
return UpdateTasksByNPC(client, TaskActivityType::SpeakWith, npc_type_id);
|
return UpdateTasksByNPC(client, TaskActivityType::SpeakWith, npc_type_id);
|
||||||
@ -2734,112 +2729,6 @@ void ClientTaskState::SyncSharedTaskZoneClientDoneCountState(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClientTaskState::HandleUpdateTasksOnKill(Client *client, uint32 npc_type_id)
|
|
||||||
{
|
|
||||||
if (!HasActiveTasks()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// loop over the union of tasks and quests
|
|
||||||
for (auto &active_task : m_active_tasks) {
|
|
||||||
auto current_task = &active_task;
|
|
||||||
if (current_task->task_id == TASKSLOTEMPTY) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if there are any active kill activities for this p_task_data
|
|
||||||
auto p_task_data = task_manager->m_task_data[current_task->task_id];
|
|
||||||
if (p_task_data == nullptr) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int activity_id = 0; activity_id < p_task_data->activity_count; activity_id++) {
|
|
||||||
ClientActivityInformation *client_activity = ¤t_task->activity[activity_id];
|
|
||||||
ActivityInformation *activity_info = &p_task_data->activity_information[activity_id];
|
|
||||||
|
|
||||||
// We are not interested in completed or hidden activities
|
|
||||||
if (client_activity->activity_state != ActivityActive) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// We are only interested in Kill activities
|
|
||||||
if (activity_info->activity_type != TaskActivityType::Kill) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Is there a zone restriction on the activity_information ?
|
|
||||||
if (!activity_info->CheckZone(zone->GetZoneID())) {
|
|
||||||
LogTasks(
|
|
||||||
"[HandleUpdateTasksOnKill] character [{}] task_id [{}] activity_id [{}] activity_type [{}] for NPC [{}] failed zone check",
|
|
||||||
client->GetName(),
|
|
||||||
current_task->task_id,
|
|
||||||
activity_id,
|
|
||||||
static_cast<int32_t>(TaskActivityType::Kill),
|
|
||||||
npc_type_id
|
|
||||||
);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// Is the activity_information to kill this type of NPC ?
|
|
||||||
switch (activity_info->goal_method) {
|
|
||||||
case METHODSINGLEID:
|
|
||||||
if (activity_info->goal_id != npc_type_id) {
|
|
||||||
LogTasksDetail("[HandleUpdateTasksOnKill] Matched single goal");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case METHODLIST:
|
|
||||||
if (!task_manager->m_goal_list_manager.IsInList(
|
|
||||||
activity_info->goal_id,
|
|
||||||
(int) npc_type_id
|
|
||||||
)) {
|
|
||||||
LogTasksDetail("[HandleUpdateTasksOnKill] Matched list goal");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
// If METHODQUEST, don't updated the activity_information here
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
LogTasksDetail("[HandleUpdateTasksOnKill] passed checks");
|
|
||||||
|
|
||||||
// handle actual update
|
|
||||||
// legacy eqemu task update logic loops through group on kill of npc to update a single task
|
|
||||||
if (p_task_data->type != TaskType::Shared) {
|
|
||||||
LogTasksDetail("[HandleUpdateTasksOnKill] Non-Shared Update");
|
|
||||||
|
|
||||||
Raid *raid = entity_list.GetRaidByClient(client);
|
|
||||||
if (raid) {
|
|
||||||
for (auto &e : raid->members) {
|
|
||||||
if (e.member && e.member->IsClient()) {
|
|
||||||
Client *c = e.member->CastToClient();
|
|
||||||
c->UpdateTasksOnKill(npc_type_id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Group *group = entity_list.GetGroupByClient(client);
|
|
||||||
if (group) {
|
|
||||||
for (auto &m : group->members) {
|
|
||||||
if (m && m->IsClient()) {
|
|
||||||
Client *c = m->CastToClient();
|
|
||||||
c->UpdateTasksOnKill(npc_type_id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LogTasksDetail("[HandleUpdateTasksOnKill] Shared update");
|
|
||||||
|
|
||||||
// shared tasks only require one client to receive an update to propagate
|
|
||||||
client->UpdateTasksOnKill(npc_type_id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
bool ClientTaskState::HasActiveTasks()
|
bool ClientTaskState::HasActiveTasks()
|
||||||
{
|
{
|
||||||
if (!task_manager) {
|
if (!task_manager) {
|
||||||
|
|||||||
@ -34,7 +34,6 @@ public:
|
|||||||
void RemoveTask(Client *client, int sequence_number, TaskType task_type);
|
void RemoveTask(Client *client, int sequence_number, TaskType task_type);
|
||||||
void RemoveTaskByTaskID(Client *client, uint32 task_id);
|
void RemoveTaskByTaskID(Client *client, uint32 task_id);
|
||||||
bool UpdateTasksByNPC(Client *client, TaskActivityType activity_type, int npc_type_id);
|
bool UpdateTasksByNPC(Client *client, TaskActivityType activity_type, int npc_type_id);
|
||||||
void UpdateTasksOnKill(Client *client, int npc_type_id);
|
|
||||||
void UpdateTasksForItem(Client *client, TaskActivityType activity_type, int item_id, int count = 1);
|
void UpdateTasksForItem(Client *client, TaskActivityType activity_type, int item_id, int count = 1);
|
||||||
void UpdateTasksOnExplore(Client *client, int explore_id);
|
void UpdateTasksOnExplore(Client *client, int explore_id);
|
||||||
bool UpdateTasksOnSpeakWith(Client *client, int npc_type_id);
|
bool UpdateTasksOnSpeakWith(Client *client, int npc_type_id);
|
||||||
@ -74,8 +73,6 @@ public:
|
|||||||
const ClientTaskInformation &GetActiveSharedTask() const;
|
const ClientTaskInformation &GetActiveSharedTask() const;
|
||||||
bool HasActiveSharedTask();
|
bool HasActiveSharedTask();
|
||||||
|
|
||||||
|
|
||||||
void HandleUpdateTasksOnKill(Client *client, uint32 npc_type_id);
|
|
||||||
private:
|
private:
|
||||||
void AddReplayTimer(Client *client, ClientTaskInformation& client_task, TaskInformation& task);
|
void AddReplayTimer(Client *client, ClientTaskInformation& client_task, TaskInformation& task);
|
||||||
|
|
||||||
|
|||||||
@ -1814,3 +1814,96 @@ void TaskManager::SyncClientSharedTaskStateToLocal(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TaskManager::HandleUpdateTasksOnKill(Client *client, uint32 npc_type_id)
|
||||||
|
{
|
||||||
|
for (auto &c: client->GetPartyMembers()) {
|
||||||
|
if (!c->ClientDataLoaded() || !c->HasTaskState()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
LogTasksDetail("[HandleUpdateTasksOnKill] Looping through client [{}]", c->GetCleanName());
|
||||||
|
|
||||||
|
// loop over the union of tasks and quests
|
||||||
|
for (auto &active_task : c->GetTaskState()->m_active_tasks) {
|
||||||
|
auto current_task = &active_task;
|
||||||
|
if (current_task->task_id == TASKSLOTEMPTY) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if there are any active kill activities for this p_task_data
|
||||||
|
auto p_task_data = m_task_data[current_task->task_id];
|
||||||
|
if (p_task_data == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int activity_id = 0; activity_id < p_task_data->activity_count; activity_id++) {
|
||||||
|
ClientActivityInformation *client_activity = ¤t_task->activity[activity_id];
|
||||||
|
ActivityInformation *activity_info = &p_task_data->activity_information[activity_id];
|
||||||
|
|
||||||
|
// We are not interested in completed or hidden activities
|
||||||
|
if (client_activity->activity_state != ActivityActive) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We are only interested in Kill activities
|
||||||
|
if (activity_info->activity_type != TaskActivityType::Kill) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Is there a zone restriction on the activity_information ?
|
||||||
|
if (!activity_info->CheckZone(zone->GetZoneID())) {
|
||||||
|
LogTasks(
|
||||||
|
"[HandleUpdateTasksOnKill] character [{}] task_id [{}] activity_id [{}] activity_type [{}] for NPC [{}] failed zone check",
|
||||||
|
client->GetName(),
|
||||||
|
current_task->task_id,
|
||||||
|
activity_id,
|
||||||
|
static_cast<int32_t>(TaskActivityType::Kill),
|
||||||
|
npc_type_id
|
||||||
|
);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// Is the activity_information to kill this type of NPC ?
|
||||||
|
switch (activity_info->goal_method) {
|
||||||
|
case METHODSINGLEID:
|
||||||
|
if (activity_info->goal_id != npc_type_id) {
|
||||||
|
LogTasksDetail("[HandleUpdateTasksOnKill] Matched single goal");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case METHODLIST:
|
||||||
|
if (!m_goal_list_manager.IsInList(
|
||||||
|
activity_info->goal_id,
|
||||||
|
(int) npc_type_id
|
||||||
|
)) {
|
||||||
|
LogTasksDetail("[HandleUpdateTasksOnKill] Matched list goal");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
// If METHODQUEST, don't updated the activity_information here
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
LogTasksDetail("[HandleUpdateTasksOnKill] passed checks");
|
||||||
|
|
||||||
|
// handle actual update
|
||||||
|
// legacy eqemu task update logic loops through group on kill of npc to update a single task
|
||||||
|
if (p_task_data->type != TaskType::Shared) {
|
||||||
|
LogTasksDetail("[HandleUpdateTasksOnKill] Non-Shared Update");
|
||||||
|
c->GetTaskState()->IncrementDoneCount(c, p_task_data, current_task->slot, activity_id);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
LogTasksDetail("[HandleUpdateTasksOnKill] Shared update");
|
||||||
|
|
||||||
|
// shared tasks only require one client to receive an update to propagate
|
||||||
|
if (c == client) {
|
||||||
|
c->GetTaskState()->IncrementDoneCount(c, p_task_data, current_task->slot, activity_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -72,6 +72,8 @@ public:
|
|||||||
// shared tasks
|
// shared tasks
|
||||||
void SyncClientSharedTaskState(Client *c, ClientTaskState *cts);
|
void SyncClientSharedTaskState(Client *c, ClientTaskState *cts);
|
||||||
|
|
||||||
|
void HandleUpdateTasksOnKill(Client *client, uint32 npc_type_id);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TaskGoalListManager m_goal_list_manager;
|
TaskGoalListManager m_goal_list_manager;
|
||||||
TaskProximityManager m_proximity_manager;
|
TaskProximityManager m_proximity_manager;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user