[Tasks] Implement Task Goal Match List (#2097)

* [Tasks] Implement Task Goal Match List

* Migration

* Add npc_type_id to match types for npc kill

* Flip str_tolower
This commit is contained in:
Chris Miles 2022-05-07 15:37:06 -05:00 committed by GitHub
parent dca34cc2ff
commit 862e1e33bf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 84 additions and 26 deletions

View File

@ -29,6 +29,7 @@ public:
std::string spell_list; std::string spell_list;
std::string description_override; std::string description_override;
int goalid; int goalid;
std::string goal_match_list;
int goalmethod; int goalmethod;
int goalcount; int goalcount;
int delivertonpc; int delivertonpc;
@ -54,6 +55,7 @@ public:
"spell_list", "spell_list",
"description_override", "description_override",
"goalid", "goalid",
"goal_match_list",
"goalmethod", "goalmethod",
"goalcount", "goalcount",
"delivertonpc", "delivertonpc",
@ -75,6 +77,7 @@ public:
"spell_list", "spell_list",
"description_override", "description_override",
"goalid", "goalid",
"goal_match_list",
"goalmethod", "goalmethod",
"goalcount", "goalcount",
"delivertonpc", "delivertonpc",
@ -130,6 +133,7 @@ public:
entry.spell_list = "0"; entry.spell_list = "0";
entry.description_override = ""; entry.description_override = "";
entry.goalid = 0; entry.goalid = 0;
entry.goal_match_list = "";
entry.goalmethod = 0; entry.goalmethod = 0;
entry.goalcount = 1; entry.goalcount = 1;
entry.delivertonpc = 0; entry.delivertonpc = 0;
@ -180,11 +184,12 @@ public:
entry.spell_list = row[7] ? row[7] : ""; entry.spell_list = row[7] ? row[7] : "";
entry.description_override = row[8] ? row[8] : ""; entry.description_override = row[8] ? row[8] : "";
entry.goalid = atoi(row[9]); entry.goalid = atoi(row[9]);
entry.goalmethod = atoi(row[10]); entry.goal_match_list = row[10] ? row[10] : "";
entry.goalcount = atoi(row[11]); entry.goalmethod = atoi(row[11]);
entry.delivertonpc = atoi(row[12]); entry.goalcount = atoi(row[12]);
entry.zones = row[13] ? row[13] : ""; entry.delivertonpc = atoi(row[13]);
entry.optional = atoi(row[14]); entry.zones = row[14] ? row[14] : "";
entry.optional = atoi(row[15]);
return entry; return entry;
} }
@ -228,11 +233,12 @@ public:
update_values.push_back(columns[7] + " = '" + EscapeString(task_activities_entry.spell_list) + "'"); 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[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[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[10] + " = '" + EscapeString(task_activities_entry.goal_match_list) + "'");
update_values.push_back(columns[11] + " = " + std::to_string(task_activities_entry.goalcount)); 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.delivertonpc)); update_values.push_back(columns[12] + " = " + std::to_string(task_activities_entry.goalcount));
update_values.push_back(columns[13] + " = '" + EscapeString(task_activities_entry.zones) + "'"); update_values.push_back(columns[13] + " = " + std::to_string(task_activities_entry.delivertonpc));
update_values.push_back(columns[14] + " = " + std::to_string(task_activities_entry.optional)); 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( auto results = db.QueryDatabase(
fmt::format( 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.spell_list) + "'");
insert_values.push_back("'" + EscapeString(task_activities_entry.description_override) + "'"); 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(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.goalmethod));
insert_values.push_back(std::to_string(task_activities_entry.goalcount)); insert_values.push_back(std::to_string(task_activities_entry.goalcount));
insert_values.push_back(std::to_string(task_activities_entry.delivertonpc)); 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.spell_list) + "'");
insert_values.push_back("'" + EscapeString(task_activities_entry.description_override) + "'"); 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(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.goalmethod));
insert_values.push_back(std::to_string(task_activities_entry.goalcount)); insert_values.push_back(std::to_string(task_activities_entry.goalcount));
insert_values.push_back(std::to_string(task_activities_entry.delivertonpc)); insert_values.push_back(std::to_string(task_activities_entry.delivertonpc));
@ -356,11 +364,12 @@ public:
entry.spell_list = row[7] ? row[7] : ""; entry.spell_list = row[7] ? row[7] : "";
entry.description_override = row[8] ? row[8] : ""; entry.description_override = row[8] ? row[8] : "";
entry.goalid = atoi(row[9]); entry.goalid = atoi(row[9]);
entry.goalmethod = atoi(row[10]); entry.goal_match_list = row[10] ? row[10] : "";
entry.goalcount = atoi(row[11]); entry.goalmethod = atoi(row[11]);
entry.delivertonpc = atoi(row[12]); entry.goalcount = atoi(row[12]);
entry.zones = row[13] ? row[13] : ""; entry.delivertonpc = atoi(row[13]);
entry.optional = atoi(row[14]); entry.zones = row[14] ? row[14] : "";
entry.optional = atoi(row[15]);
all_entries.push_back(entry); all_entries.push_back(entry);
} }
@ -395,11 +404,12 @@ public:
entry.spell_list = row[7] ? row[7] : ""; entry.spell_list = row[7] ? row[7] : "";
entry.description_override = row[8] ? row[8] : ""; entry.description_override = row[8] ? row[8] : "";
entry.goalid = atoi(row[9]); entry.goalid = atoi(row[9]);
entry.goalmethod = atoi(row[10]); entry.goal_match_list = row[10] ? row[10] : "";
entry.goalcount = atoi(row[11]); entry.goalmethod = atoi(row[11]);
entry.delivertonpc = atoi(row[12]); entry.goalcount = atoi(row[12]);
entry.zones = row[13] ? row[13] : ""; entry.delivertonpc = atoi(row[13]);
entry.optional = atoi(row[14]); entry.zones = row[14] ? row[14] : "";
entry.optional = atoi(row[15]);
all_entries.push_back(entry); all_entries.push_back(entry);
} }

View File

@ -61,6 +61,7 @@ struct ActivityInformation {
int skill_id; // older clients, first id from above int skill_id; // older clients, first id from above
int spell_id; // older clients, first id from above int spell_id; // older clients, first id from above
int goal_id; int goal_id;
std::string goal_match_list;
TaskMethodType goal_method; TaskMethodType goal_method;
int goal_count; int goal_count;
int deliver_to_npc; int deliver_to_npc;

View File

@ -34,7 +34,7 @@
* Manifest: https://github.com/EQEmu/Server/blob/master/utils/sql/db_update_manifest.txt * 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 #ifdef BOTS
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 9028 #define CURRENT_BINARY_BOTS_DATABASE_VERSION 9028

View File

@ -434,6 +434,7 @@
9178|2022_03_07_saylink_collation.sql|SELECT * FROM db_version WHERE version >= 9178|empty| 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| 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| 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: # Upgrade conditions:
# This won't be needed after this system is implemented, but it is used database that are not # This won't be needed after this system is implemented, but it is used database that are not

View File

@ -0,0 +1 @@
ALTER TABLE task_activities ADD goal_match_list text AFTER goalid;

View File

@ -2445,7 +2445,7 @@ bool NPC::Death(Mob* killer_mob, int32 damage, uint16 spell, EQ::skills::SkillTy
give_exp_client->GetCleanName(), give_exp_client->GetCleanName(),
GetNPCTypeID() GetNPCTypeID()
); );
task_manager->HandleUpdateTasksOnKill(give_exp_client, GetNPCTypeID()); task_manager->HandleUpdateTasksOnKill(give_exp_client, GetNPCTypeID(), GetCleanName());
} }
if (kr) { if (kr) {

View File

@ -644,6 +644,9 @@ bool ClientTaskState::UpdateTasksByNPC(Client *client, TaskActivityType activity
if (!task_manager->m_goal_list_manager.IsInList( if (!task_manager->m_goal_list_manager.IsInList(
activity_info->goal_id, activity_info->goal_id,
npc_type_id npc_type_id
) && !TaskGoalListManager::IsInMatchList(
activity_info->goal_match_list,
std::to_string(npc_type_id)
)) { )) {
continue; continue;
} }
@ -827,6 +830,9 @@ void ClientTaskState::UpdateTasksForItem(Client *client, TaskActivityType activi
if (!task_manager->m_goal_list_manager.IsInList( if (!task_manager->m_goal_list_manager.IsInList(
activity_info->goal_id, activity_info->goal_id,
item_id item_id
) && !TaskGoalListManager::IsInMatchList(
activity_info->goal_match_list,
std::to_string(item_id)
)) { continue; } )) { continue; }
break; break;
@ -896,6 +902,9 @@ void ClientTaskState::UpdateTasksOnExplore(Client *client, int explore_id)
if (!task_manager->m_goal_list_manager.IsInList( if (!task_manager->m_goal_list_manager.IsInList(
activity_info->goal_id, activity_info->goal_id,
explore_id explore_id
) && !TaskGoalListManager::IsInMatchList(
activity_info->goal_match_list,
std::to_string(explore_id)
)) { )) {
continue; continue;
} }
@ -999,7 +1008,11 @@ bool ClientTaskState::UpdateTasksOnDeliver(
case METHODLIST: case METHODLIST:
if (!task_manager->m_goal_list_manager.IsInList( if (!task_manager->m_goal_list_manager.IsInList(
activity_info->goal_id, activity_info->goal_id,
item->GetID())) { item->GetID()
) && !TaskGoalListManager::IsInMatchList(
activity_info->goal_match_list,
std::to_string(item->GetID())
)) {
continue; continue;
} }
break; break;

View File

@ -147,3 +147,26 @@ bool TaskGoalListManager::IsInList(int list_id, int entry)
return true; 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;
}

View File

@ -27,6 +27,8 @@ public:
bool IsInList(int list_id, int entry); bool IsInList(int list_id, int entry);
int GetFirstEntry(int list_id); int GetFirstEntry(int list_id);
std::vector<int> GetListContents(int list_index); std::vector<int> 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: private:
std::vector<TaskGoalList_Struct> m_task_goal_lists; std::vector<TaskGoalList_Struct> m_task_goal_lists;

View File

@ -233,6 +233,7 @@ bool TaskManager::LoadTasks(int single_task)
activity_data->description_override = task_activity.description_override; activity_data->description_override = task_activity.description_override;
activity_data->goal_id = task_activity.goalid; activity_data->goal_id = task_activity.goalid;
activity_data->goal_method = (TaskMethodType) task_activity.goalmethod; 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->goal_count = task_activity.goalcount;
activity_data->deliver_to_npc = task_activity.delivertonpc; 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()) { for (auto &c: client->GetPartyMembers()) {
if (!c->ClientDataLoaded() || !c->HasTaskState()) { if (!c->ClientDataLoaded() || !c->HasTaskState()) {
@ -1876,6 +1877,12 @@ void TaskManager::HandleUpdateTasksOnKill(Client *client, uint32 npc_type_id)
if (!m_goal_list_manager.IsInList( if (!m_goal_list_manager.IsInList(
activity_info->goal_id, activity_info->goal_id,
(int) npc_type_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"); LogTasksDetail("[HandleUpdateTasksOnKill] Matched list goal");
continue; continue;

View File

@ -72,7 +72,7 @@ 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); void HandleUpdateTasksOnKill(Client *client, uint32 npc_type_id, std::string npc_name);
private: private:
TaskGoalListManager m_goal_list_manager; TaskGoalListManager m_goal_list_manager;