diff --git a/common/repositories/base/base_task_activities_repository.h b/common/repositories/base/base_task_activities_repository.h index 0e126fdda..c1a9e1e4f 100644 --- a/common/repositories/base/base_task_activities_repository.h +++ b/common/repositories/base/base_task_activities_repository.h @@ -29,6 +29,7 @@ public: std::string spell_list; std::string description_override; int goalid; + std::string goal_match_list; int goalmethod; int goalcount; int delivertonpc; @@ -54,6 +55,7 @@ public: "spell_list", "description_override", "goalid", + "goal_match_list", "goalmethod", "goalcount", "delivertonpc", @@ -75,6 +77,7 @@ public: "spell_list", "description_override", "goalid", + "goal_match_list", "goalmethod", "goalcount", "delivertonpc", @@ -130,6 +133,7 @@ public: entry.spell_list = "0"; entry.description_override = ""; entry.goalid = 0; + entry.goal_match_list = ""; entry.goalmethod = 0; entry.goalcount = 1; entry.delivertonpc = 0; @@ -180,11 +184,12 @@ public: entry.spell_list = row[7] ? row[7] : ""; entry.description_override = row[8] ? row[8] : ""; entry.goalid = atoi(row[9]); - entry.goalmethod = atoi(row[10]); - entry.goalcount = atoi(row[11]); - entry.delivertonpc = atoi(row[12]); - entry.zones = row[13] ? row[13] : ""; - entry.optional = atoi(row[14]); + entry.goal_match_list = row[10] ? row[10] : ""; + entry.goalmethod = atoi(row[11]); + entry.goalcount = atoi(row[12]); + entry.delivertonpc = atoi(row[13]); + entry.zones = row[14] ? row[14] : ""; + entry.optional = atoi(row[15]); return entry; } @@ -228,11 +233,12 @@ public: update_values.push_back(columns[7] + " = '" + EscapeString(task_activities_entry.spell_list) + "'"); update_values.push_back(columns[8] + " = '" + EscapeString(task_activities_entry.description_override) + "'"); update_values.push_back(columns[9] + " = " + std::to_string(task_activities_entry.goalid)); - update_values.push_back(columns[10] + " = " + std::to_string(task_activities_entry.goalmethod)); - update_values.push_back(columns[11] + " = " + std::to_string(task_activities_entry.goalcount)); - update_values.push_back(columns[12] + " = " + std::to_string(task_activities_entry.delivertonpc)); - update_values.push_back(columns[13] + " = '" + EscapeString(task_activities_entry.zones) + "'"); - update_values.push_back(columns[14] + " = " + std::to_string(task_activities_entry.optional)); + update_values.push_back(columns[10] + " = '" + EscapeString(task_activities_entry.goal_match_list) + "'"); + update_values.push_back(columns[11] + " = " + std::to_string(task_activities_entry.goalmethod)); + update_values.push_back(columns[12] + " = " + std::to_string(task_activities_entry.goalcount)); + update_values.push_back(columns[13] + " = " + std::to_string(task_activities_entry.delivertonpc)); + update_values.push_back(columns[14] + " = '" + EscapeString(task_activities_entry.zones) + "'"); + update_values.push_back(columns[15] + " = " + std::to_string(task_activities_entry.optional)); auto results = db.QueryDatabase( fmt::format( @@ -264,6 +270,7 @@ public: insert_values.push_back("'" + EscapeString(task_activities_entry.spell_list) + "'"); insert_values.push_back("'" + EscapeString(task_activities_entry.description_override) + "'"); insert_values.push_back(std::to_string(task_activities_entry.goalid)); + insert_values.push_back("'" + EscapeString(task_activities_entry.goal_match_list) + "'"); insert_values.push_back(std::to_string(task_activities_entry.goalmethod)); insert_values.push_back(std::to_string(task_activities_entry.goalcount)); insert_values.push_back(std::to_string(task_activities_entry.delivertonpc)); @@ -308,6 +315,7 @@ public: insert_values.push_back("'" + EscapeString(task_activities_entry.spell_list) + "'"); insert_values.push_back("'" + EscapeString(task_activities_entry.description_override) + "'"); insert_values.push_back(std::to_string(task_activities_entry.goalid)); + insert_values.push_back("'" + EscapeString(task_activities_entry.goal_match_list) + "'"); insert_values.push_back(std::to_string(task_activities_entry.goalmethod)); insert_values.push_back(std::to_string(task_activities_entry.goalcount)); insert_values.push_back(std::to_string(task_activities_entry.delivertonpc)); @@ -356,11 +364,12 @@ public: entry.spell_list = row[7] ? row[7] : ""; entry.description_override = row[8] ? row[8] : ""; entry.goalid = atoi(row[9]); - entry.goalmethod = atoi(row[10]); - entry.goalcount = atoi(row[11]); - entry.delivertonpc = atoi(row[12]); - entry.zones = row[13] ? row[13] : ""; - entry.optional = atoi(row[14]); + entry.goal_match_list = row[10] ? row[10] : ""; + entry.goalmethod = atoi(row[11]); + entry.goalcount = atoi(row[12]); + entry.delivertonpc = atoi(row[13]); + entry.zones = row[14] ? row[14] : ""; + entry.optional = atoi(row[15]); all_entries.push_back(entry); } @@ -395,11 +404,12 @@ public: entry.spell_list = row[7] ? row[7] : ""; entry.description_override = row[8] ? row[8] : ""; entry.goalid = atoi(row[9]); - entry.goalmethod = atoi(row[10]); - entry.goalcount = atoi(row[11]); - entry.delivertonpc = atoi(row[12]); - entry.zones = row[13] ? row[13] : ""; - entry.optional = atoi(row[14]); + entry.goal_match_list = row[10] ? row[10] : ""; + entry.goalmethod = atoi(row[11]); + entry.goalcount = atoi(row[12]); + entry.delivertonpc = atoi(row[13]); + entry.zones = row[14] ? row[14] : ""; + entry.optional = atoi(row[15]); all_entries.push_back(entry); } diff --git a/common/tasks.h b/common/tasks.h index 8d19910e7..680297a7a 100644 --- a/common/tasks.h +++ b/common/tasks.h @@ -61,6 +61,7 @@ struct ActivityInformation { int skill_id; // older clients, first id from above int spell_id; // older clients, first id from above int goal_id; + std::string goal_match_list; TaskMethodType goal_method; int goal_count; int deliver_to_npc; diff --git a/common/version.h b/common/version.h index c5c8a36a5..cd0b796fb 100644 --- a/common/version.h +++ b/common/version.h @@ -34,7 +34,7 @@ * Manifest: https://github.com/EQEmu/Server/blob/master/utils/sql/db_update_manifest.txt */ -#define CURRENT_BINARY_DATABASE_VERSION 9180 +#define CURRENT_BINARY_DATABASE_VERSION 9182 #ifdef BOTS #define CURRENT_BINARY_BOTS_DATABASE_VERSION 9028 diff --git a/utils/sql/db_update_manifest.txt b/utils/sql/db_update_manifest.txt index df6d14e17..608946c6b 100644 --- a/utils/sql/db_update_manifest.txt +++ b/utils/sql/db_update_manifest.txt @@ -434,6 +434,7 @@ 9178|2022_03_07_saylink_collation.sql|SELECT * FROM db_version WHERE version >= 9178|empty| 9179|2022_04_30_hp_regen_per_second.sql|SHOW COLUMNS FROM `npc_types` LIKE 'hp_regen_per_second'|empty| 9180|2022_05_01_character_peqzone_flags.sql|SHOW TABLES LIKE 'character_peqzone_flags'|empty| +9182|2022_05_03_task_activity_goal_match_list.sql|SHOW COLUMNS FROM `task_activities` LIKE 'goal_match_list'|empty| # Upgrade conditions: # This won't be needed after this system is implemented, but it is used database that are not diff --git a/utils/sql/git/required/2022_05_03_task_activity_goal_match_list.sql b/utils/sql/git/required/2022_05_03_task_activity_goal_match_list.sql new file mode 100644 index 000000000..ab4a486de --- /dev/null +++ b/utils/sql/git/required/2022_05_03_task_activity_goal_match_list.sql @@ -0,0 +1 @@ +ALTER TABLE task_activities ADD goal_match_list text AFTER goalid; diff --git a/zone/attack.cpp b/zone/attack.cpp index 8eca03213..d4153a7ae 100644 --- a/zone/attack.cpp +++ b/zone/attack.cpp @@ -2445,7 +2445,7 @@ bool NPC::Death(Mob* killer_mob, int32 damage, uint16 spell, EQ::skills::SkillTy give_exp_client->GetCleanName(), GetNPCTypeID() ); - task_manager->HandleUpdateTasksOnKill(give_exp_client, GetNPCTypeID()); + task_manager->HandleUpdateTasksOnKill(give_exp_client, GetNPCTypeID(), GetCleanName()); } if (kr) { diff --git a/zone/task_client_state.cpp b/zone/task_client_state.cpp index 4ef2ea5cc..6d79a41e1 100644 --- a/zone/task_client_state.cpp +++ b/zone/task_client_state.cpp @@ -644,6 +644,9 @@ bool ClientTaskState::UpdateTasksByNPC(Client *client, TaskActivityType activity if (!task_manager->m_goal_list_manager.IsInList( activity_info->goal_id, npc_type_id + ) && !TaskGoalListManager::IsInMatchList( + activity_info->goal_match_list, + std::to_string(npc_type_id) )) { continue; } @@ -827,6 +830,9 @@ void ClientTaskState::UpdateTasksForItem(Client *client, TaskActivityType activi if (!task_manager->m_goal_list_manager.IsInList( activity_info->goal_id, item_id + ) && !TaskGoalListManager::IsInMatchList( + activity_info->goal_match_list, + std::to_string(item_id) )) { continue; } break; @@ -896,6 +902,9 @@ void ClientTaskState::UpdateTasksOnExplore(Client *client, int explore_id) if (!task_manager->m_goal_list_manager.IsInList( activity_info->goal_id, explore_id + ) && !TaskGoalListManager::IsInMatchList( + activity_info->goal_match_list, + std::to_string(explore_id) )) { continue; } @@ -999,7 +1008,11 @@ bool ClientTaskState::UpdateTasksOnDeliver( case METHODLIST: if (!task_manager->m_goal_list_manager.IsInList( activity_info->goal_id, - item->GetID())) { + item->GetID() + ) && !TaskGoalListManager::IsInMatchList( + activity_info->goal_match_list, + std::to_string(item->GetID()) + )) { continue; } break; @@ -2227,7 +2240,7 @@ void ClientTaskState::RemoveTaskByTaskID(Client *client, uint32 task_id) } case TaskType::Quest: { for (int active_quest = 0; active_quest < MAXACTIVEQUESTS; active_quest++) { - if (m_active_quests[active_quest].task_id == task_id) { + if (m_active_quests[active_quest].task_id == task_id) { LogTasks("[UPDATE] RemoveTaskByTaskID found Quest [{}] at index [{}]", task_id, active_quest); CancelTask(client, active_quest, TaskType::Quest, true); } diff --git a/zone/task_goal_list_manager.cpp b/zone/task_goal_list_manager.cpp index 9a641c6eb..927099181 100644 --- a/zone/task_goal_list_manager.cpp +++ b/zone/task_goal_list_manager.cpp @@ -147,3 +147,26 @@ bool TaskGoalListManager::IsInList(int list_id, int entry) return true; } + +bool TaskGoalListManager::IsInMatchList(const std::string& match_list, const std::string& entry) +{ + for (auto &s: SplitString(match_list, '|')) { + if (s == entry) { + return true; + } + } + + return false; +} + +bool TaskGoalListManager::IsInMatchListPartial(const std::string &match_list, const std::string &entry) +{ + std::string entry_match = str_tolower(entry); + for (auto &s: SplitString(match_list, '|')) { + if (entry_match.find(str_tolower(s)) != std::string::npos) { + return true; + } + } + + return false; +} diff --git a/zone/task_goal_list_manager.h b/zone/task_goal_list_manager.h index 11146f6e3..b9c825123 100644 --- a/zone/task_goal_list_manager.h +++ b/zone/task_goal_list_manager.h @@ -27,6 +27,8 @@ public: bool IsInList(int list_id, int entry); int GetFirstEntry(int list_id); std::vector GetListContents(int list_index); + static bool IsInMatchList(const std::string& match_list, const std::string& entry); + static bool IsInMatchListPartial(const std::string& match_list, const std::string& entry); private: std::vector m_task_goal_lists; diff --git a/zone/task_manager.cpp b/zone/task_manager.cpp index 9204f4ee6..01c654eaa 100644 --- a/zone/task_manager.cpp +++ b/zone/task_manager.cpp @@ -233,6 +233,7 @@ bool TaskManager::LoadTasks(int single_task) activity_data->description_override = task_activity.description_override; activity_data->goal_id = task_activity.goalid; activity_data->goal_method = (TaskMethodType) task_activity.goalmethod; + activity_data->goal_match_list = task_activity.goal_match_list; activity_data->goal_count = task_activity.goalcount; activity_data->deliver_to_npc = task_activity.delivertonpc; @@ -1815,7 +1816,7 @@ void TaskManager::SyncClientSharedTaskStateToLocal( } } -void TaskManager::HandleUpdateTasksOnKill(Client *client, uint32 npc_type_id) +void TaskManager::HandleUpdateTasksOnKill(Client *client, uint32 npc_type_id, std::string npc_name) { for (auto &c: client->GetPartyMembers()) { if (!c->ClientDataLoaded() || !c->HasTaskState()) { @@ -1876,6 +1877,12 @@ void TaskManager::HandleUpdateTasksOnKill(Client *client, uint32 npc_type_id) if (!m_goal_list_manager.IsInList( activity_info->goal_id, (int) npc_type_id + ) && !TaskGoalListManager::IsInMatchList( + activity_info->goal_match_list, + std::to_string(npc_type_id) + ) && !TaskGoalListManager::IsInMatchListPartial( + activity_info->goal_match_list, + npc_name )) { LogTasksDetail("[HandleUpdateTasksOnKill] Matched list goal"); continue; diff --git a/zone/task_manager.h b/zone/task_manager.h index 16eb51fcd..1acac00d3 100644 --- a/zone/task_manager.h +++ b/zone/task_manager.h @@ -72,7 +72,7 @@ public: // shared tasks void SyncClientSharedTaskState(Client *c, ClientTaskState *cts); - void HandleUpdateTasksOnKill(Client *client, uint32 npc_type_id); + void HandleUpdateTasksOnKill(Client *client, uint32 npc_type_id, std::string npc_name); private: TaskGoalListManager m_goal_list_manager;