From ca2072e7bffd6f612efd8930e093e917cec4f456 Mon Sep 17 00:00:00 2001 From: Aeadoin <109764533+Aeadoin@users.noreply.github.com> Date: Fri, 31 Mar 2023 21:37:52 -0400 Subject: [PATCH] [Bots] Remove Bot Groups Functionality (#3165) * [Bots] Remove Bot Groups Functionality * in-class initializers for member variables. --- common/version.h | 2 +- .../sql/git/bots/bots_db_update_manifest.txt | 1 + .../required/2023_03_31_remove_bot_groups.sql | 4 + zone/bot.cpp | 316 ++----- zone/bot.h | 2 - zone/bot_command.cpp | 853 +----------------- zone/bot_command.h | 8 +- zone/bot_database.cpp | 518 +---------- zone/bot_database.h | 45 - zone/groups.h | 10 +- 10 files changed, 73 insertions(+), 1686 deletions(-) create mode 100644 utils/sql/git/bots/required/2023_03_31_remove_bot_groups.sql diff --git a/common/version.h b/common/version.h index 2da502a90..e546e01a0 100644 --- a/common/version.h +++ b/common/version.h @@ -44,7 +44,7 @@ #define CURRENT_BINARY_DATABASE_VERSION 9227 -#define CURRENT_BINARY_BOTS_DATABASE_VERSION 9038 +#define CURRENT_BINARY_BOTS_DATABASE_VERSION 9039 #endif diff --git a/utils/sql/git/bots/bots_db_update_manifest.txt b/utils/sql/git/bots/bots_db_update_manifest.txt index 32191b95a..6a6851d7b 100644 --- a/utils/sql/git/bots/bots_db_update_manifest.txt +++ b/utils/sql/git/bots/bots_db_update_manifest.txt @@ -37,6 +37,7 @@ 9036|2023_01_19_drop_bot_views.sql|SHOW TABLES LIKE 'vw_groups'|not_empty| 9037|2023_01_22_add_name_index.sql||show index from bot_data WHERE key_name = 'name`|empty| 9038|2023_02_16_add_caster_range.sql|SHOW COLUMNS FROM `bot_data` LIKE 'caster_range'|empty| +9039|2023_03_31_remove_bot_groups.sql|SHOW TABLES LIKE 'bot_groups'|not_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/bots/required/2023_03_31_remove_bot_groups.sql b/utils/sql/git/bots/required/2023_03_31_remove_bot_groups.sql new file mode 100644 index 000000000..8139544f3 --- /dev/null +++ b/utils/sql/git/bots/required/2023_03_31_remove_bot_groups.sql @@ -0,0 +1,4 @@ +SET FOREIGN_KEY_CHECKS = 0; +DROP TABLE IF EXISTS `bot_groups`; +DROP TABLE IF EXISTS `bot_group_members`; +SET FOREIGN_KEY_CHECKS = 1; \ No newline at end of file diff --git a/zone/bot.cpp b/zone/bot.cpp index b5eb6f5f4..eab55d45f 100644 --- a/zone/bot.cpp +++ b/zone/bot.cpp @@ -1376,17 +1376,6 @@ bool Bot::DeleteBot() std::string error_message; - if (!database.botdb.RemoveMemberFromBotGroup(GetBotID())) { - bot_owner->Message( - Chat::White, - fmt::format( - "Failed to remove {} from their bot-group.", - GetCleanName() - ).c_str() - ); - return false; - } - if (!database.botdb.DeleteItems(GetBotID())) { bot_owner->Message( Chat::White, @@ -3491,92 +3480,71 @@ Bot* Bot::LoadBot(uint32 botID) // Load and spawn all zoned bots by bot owner character void Bot::LoadAndSpawnAllZonedBots(Client* bot_owner) { - if (bot_owner) { - std::list> auto_spawn_botgroups; - if (bot_owner->HasGroup()) { - std::vector bot_class_spawn_limits; - std::vector bot_class_spawned_count = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + if (bot_owner && bot_owner->HasGroup()) { + std::vector bot_class_spawn_limits; + std::vector bot_class_spawned_count = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - for (uint8 class_id = WARRIOR; class_id <= BERSERKER; class_id++) { - auto bot_class_limit = bot_owner->GetBotSpawnLimit(class_id); - bot_class_spawn_limits.push_back(bot_class_limit); - } + for (uint8 class_id = WARRIOR; class_id <= BERSERKER; class_id++) { + auto bot_class_limit = bot_owner->GetBotSpawnLimit(class_id); + bot_class_spawn_limits.push_back(bot_class_limit); + } - auto* g = bot_owner->GetGroup(); - if (g) { - uint32 group_id = g->GetID(); - std::list active_bots; + auto* g = bot_owner->GetGroup(); + if (g) { + uint32 group_id = g->GetID(); + std::list active_bots; - auto spawned_bots_count = 0; - auto bot_spawn_limit = bot_owner->GetBotSpawnLimit(); + auto spawned_bots_count = 0; + auto bot_spawn_limit = bot_owner->GetBotSpawnLimit(); - if (!database.botdb.LoadAutoSpawnBotGroupsByOwnerID(bot_owner->CharacterID(), auto_spawn_botgroups)) { - bot_owner->Message(Chat::White, "Failed to load auto spawn bot groups by group ID."); - return; - } - - for (const auto& botgroup : auto_spawn_botgroups) { - Bot::SpawnBotGroupByName(bot_owner, botgroup.second, botgroup.first); - } - - if (!database.botdb.LoadGroupedBotsByGroupID(bot_owner->CharacterID(), group_id, active_bots)) { - bot_owner->Message(Chat::White, "Failed to load grouped bots by group ID."); - return; - } - - if (!active_bots.empty()) { - for (const auto& bot_id : active_bots) { - auto* b = Bot::LoadBot(bot_id); - if (!b) { - continue; - } - - if (bot_spawn_limit >= 0 && spawned_bots_count >= bot_spawn_limit) { - database.SetGroupID(b->GetCleanName(), 0, b->GetBotID()); - g->UpdatePlayer(bot_owner); - continue; - } - - auto spawned_bot_count_class = bot_class_spawned_count[b->GetClass() - 1]; - - if ( - auto bot_spawn_limit_class = bot_class_spawn_limits[b->GetClass() - 1]; - bot_spawn_limit_class >= 0 && - spawned_bot_count_class >= bot_spawn_limit_class - ) { - database.SetGroupID(b->GetCleanName(), 0, b->GetBotID()); - g->UpdatePlayer(bot_owner); - continue; - } - - if (!b->Spawn(bot_owner)) { - safe_delete(b); - continue; - } - - spawned_bots_count++; - bot_class_spawned_count[b->GetClass() - 1]++; - - g->UpdatePlayer(b); - - if (g->IsGroupMember(bot_owner) && g->IsGroupMember(b)) { - b->SetFollowID(bot_owner->GetID()); - } - - if (!bot_owner->HasGroup()) { - database.SetGroupID(b->GetCleanName(), 0, b->GetBotID()); - } - } - } - } - } else { - if (!database.botdb.LoadAutoSpawnBotGroupsByOwnerID(bot_owner->CharacterID(), auto_spawn_botgroups)) { - bot_owner->Message(Chat::White, "Failed to load auto spawn bot groups by group ID."); + if (!database.botdb.LoadGroupedBotsByGroupID(bot_owner->CharacterID(), group_id, active_bots)) { + bot_owner->Message(Chat::White, "Failed to load grouped bots by group ID."); return; } - for (const auto& botgroup : auto_spawn_botgroups) { - Bot::SpawnBotGroupByName(bot_owner, botgroup.second, botgroup.first); + if (!active_bots.empty()) { + for (const auto& bot_id : active_bots) { + auto* b = Bot::LoadBot(bot_id); + if (!b) { + continue; + } + + if (bot_spawn_limit >= 0 && spawned_bots_count >= bot_spawn_limit) { + database.SetGroupID(b->GetCleanName(), 0, b->GetBotID()); + g->UpdatePlayer(bot_owner); + continue; + } + + auto spawned_bot_count_class = bot_class_spawned_count[b->GetClass() - 1]; + + if ( + auto bot_spawn_limit_class = bot_class_spawn_limits[b->GetClass() - 1]; + bot_spawn_limit_class >= 0 && + spawned_bot_count_class >= bot_spawn_limit_class + ) { + database.SetGroupID(b->GetCleanName(), 0, b->GetBotID()); + g->UpdatePlayer(bot_owner); + continue; + } + + if (!b->Spawn(bot_owner)) { + safe_delete(b); + continue; + } + + spawned_bots_count++; + bot_class_spawned_count[b->GetClass() - 1]++; + + g->UpdatePlayer(b); + + if (g->IsGroupMember(bot_owner) && g->IsGroupMember(b)) { + b->SetFollowID(bot_owner->GetID()); + } + + if (!bot_owner->HasGroup()) { + database.SetGroupID(b->GetCleanName(), 0, b->GetBotID()); + } + } } } } @@ -8198,174 +8166,6 @@ std::string Bot::CreateSayLink(Client* c, const char* message, const char* name) return saylink; } -void Bot::SpawnBotGroupByName(Client* c, const std::string& botgroup_name, uint32 leader_id) -{ - auto leader = Bot::LoadBot(leader_id); - if (!leader) { - c->Message( - Chat::White, - fmt::format( - "Could not load bot-group leader for '{}'.", - botgroup_name - ).c_str() - ); - safe_delete(leader); - return; - } - - if (!leader->spawned) { - if (!leader->Spawn(c)) { - c->Message( - Chat::White, - fmt::format( - "Could not spawn bot-group leader {} for '{}'.", - leader->GetName(), - botgroup_name - ).c_str() - ); - safe_delete(leader); - return; - } - } - - auto group = leader->GetGroupByLeaderName(); - auto raid = leader->GetRaid(); - - if (!raid && group) { - group->SetLeader(leader); - } - else if (!raid) { - group = new Group(leader); - entity_list.AddGroup(group); - database.SetGroupID(leader->GetCleanName(), group->GetID(), leader->GetBotID()); - database.SetGroupLeaderName(group->GetID(), leader->GetCleanName()); - } - - leader->SetFollowID(c->GetID()); - - uint32 botgroup_id = 0; - database.botdb.LoadBotGroupIDByBotGroupName(botgroup_name, botgroup_id); - - std::map> member_list; - if (!database.botdb.LoadBotGroup(botgroup_name, member_list)) { - c->Message( - Chat::White, - fmt::format( - "Failed to load bot-group '{}'.", - botgroup_name - ).c_str() - ); - return; - } - - if (member_list.find(botgroup_id) == member_list.end() || member_list[botgroup_id].empty()) { - c->Message( - Chat::White, - fmt::format( - "Could not locate member list for bot-group '{}'.", - botgroup_name - ).c_str() - ); - return; - } - - member_list[botgroup_id].remove(0); - member_list[botgroup_id].remove(leader->GetBotID()); - - auto bot_spawn_limit = c->GetBotSpawnLimit(); - auto spawned_bot_count = 0; - - std::vector bot_class_spawn_limits; - std::vector bot_class_spawned_count = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - - for (uint8 class_id = WARRIOR; class_id <= BERSERKER; class_id++) { - auto bot_class_limit = c->GetBotSpawnLimit(class_id); - bot_class_spawn_limits.push_back(bot_class_limit); - } - - for (const auto& member_iter : member_list[botgroup_id]) { - auto member = Bot::LoadBot(member_iter); - if (!member) { - c->Message( - Chat::White, - fmt::format( - "Could not load bot id {}.", - member_iter - ).c_str() - ); - safe_delete(member); - return; - } - - if (bot_spawn_limit >= 0 && spawned_bot_count >= bot_spawn_limit) { - c->Message( - Chat::White, - fmt::format( - "Failed to spawn {} because you have a max of {} bot{} spawned.", - member->GetCleanName(), - bot_spawn_limit, - bot_spawn_limit != 1 ? "s" : "" - ).c_str() - ); - return; - } - - auto spawned_bot_count_class = bot_class_spawned_count[member->GetClass() - 1]; - auto bot_spawn_limit_class = bot_class_spawn_limits[member->GetClass() - 1]; - - if (bot_spawn_limit_class >= 0 && spawned_bot_count_class >= bot_spawn_limit_class) { - c->Message( - Chat::White, - fmt::format( - "Failed to spawn {} because you have a max of {} {} bot{} spawned.", - member->GetCleanName(), - bot_spawn_limit_class, - GetClassIDName(member->GetClass()), - bot_spawn_limit_class != 1 ? "s" : "" - ).c_str() - ); - continue; - } - - if (!member->spawned) { - if (!member->Spawn(c)) { - c->Message( - Chat::White, - fmt::format( - "Could not spawn bot '{}' (ID {}).", - member->GetName(), - member_iter - ).c_str() - ); - safe_delete(member); - return; - } - - spawned_bot_count++; - bot_class_spawned_count[member->GetClass() - 1]++; - - if (group) { - Bot::AddBotToGroup(member, group); - } - } - } - - if (raid) { - raid->VerifyRaid(); - } - else if (group) { - group->VerifyGroup(); - } - - c->Message( - Chat::White, - fmt::format( - "Successfully loaded bot-group {}.", - botgroup_name - ).c_str() - ); -} - void Bot::Signal(int signal_id) { if (parse->BotHasQuestSub(EVENT_SIGNAL)) { diff --git a/zone/bot.h b/zone/bot.h index e36b19461..e3946d2fc 100644 --- a/zone/bot.h +++ b/zone/bot.h @@ -645,8 +645,6 @@ public: void SetBotEnforceSpellSetting(bool enforcespellsettings, bool save = false); bool GetBotEnforceSpellSetting() const { return m_enforce_spell_settings; } - static void SpawnBotGroupByName(Client* c, const std::string& botgroup_name, uint32 leader_id); - std::string CreateSayLink(Client* botOwner, const char* message, const char* name); // Class Destructors diff --git a/zone/bot_command.cpp b/zone/bot_command.cpp index f0c4827ce..a77a48562 100644 --- a/zone/bot_command.cpp +++ b/zone/bot_command.cpp @@ -1361,14 +1361,6 @@ int bot_command_init(void) bot_command_add("boteyes", "Changes the eye colors of a bot", AccountStatus::Player, bot_subcommand_bot_eyes) || bot_command_add("botface", "Changes the facial appearance of your bot", AccountStatus::Player, bot_subcommand_bot_face) || bot_command_add("botfollowdistance", "Changes the follow distance(s) of a bot(s)", AccountStatus::Player, bot_subcommand_bot_follow_distance) || - bot_command_add("botgroup", "Lists the available bot-group [subcommands]", AccountStatus::Player, bot_command_botgroup) || - bot_command_add("botgroupaddmember", "Adds a member to a bot-group", AccountStatus::Player, bot_subcommand_botgroup_add_member) || - bot_command_add("botgroupautospawn", "Toggles auto spawning for a bot-group, spawning the bot group when you zone automatically", AccountStatus::Player, bot_subcommand_botgroup_auto_spawn) || - bot_command_add("botgroupcreate", "Creates a bot-group and designates a leader", AccountStatus::Player, bot_subcommand_botgroup_create) || - bot_command_add("botgroupdelete", "Deletes a bot-group and releases its members", AccountStatus::Player, bot_subcommand_botgroup_delete) || - bot_command_add("botgrouplist", "Lists all of your existing bot-groups", AccountStatus::Player, bot_subcommand_botgroup_list) || - bot_command_add("botgroupload", "Loads all members of a bot-group", AccountStatus::Player, bot_subcommand_botgroup_load) || - bot_command_add("botgroupremovemember", "Removes a bot from its bot-group", AccountStatus::Player, bot_subcommand_botgroup_remove_member) || bot_command_add("bothaircolor", "Changes the hair color of a bot", AccountStatus::Player, bot_subcommand_bot_hair_color) || bot_command_add("bothairstyle", "Changes the hairstyle of a bot", AccountStatus::Player, bot_subcommand_bot_hairstyle) || bot_command_add("botheritage", "Changes the Drakkin heritage of a bot", AccountStatus::Player, bot_subcommand_bot_heritage) || @@ -1911,43 +1903,6 @@ namespace MyBots sbl.remove(nullptr); } - static void PopulateSBL_ByBotGroup(Client *bot_owner, std::list &sbl, const char* name, bool clear_list = true) { - if (clear_list) - sbl.clear(); - if (!bot_owner || !name) - return; - - std::string group_name = name; - - uint32 botgroup_id = 0; - if (!database.botdb.LoadBotGroupIDForLoadBotGroup(bot_owner->CharacterID(), group_name, botgroup_id) || !botgroup_id) - return; - - std::map> botgroup_list; - if (!database.botdb.LoadBotGroup(group_name, botgroup_list) || botgroup_list.find(botgroup_id) == botgroup_list.end() || !botgroup_list[botgroup_id].size()) - return; - - std::list selectable_bot_list; - PopulateSBL_BySpawnedBots(bot_owner, selectable_bot_list); - if (selectable_bot_list.empty()) - return; - - selectable_bot_list.remove(nullptr); - for (auto group_iter : botgroup_list[botgroup_id]) { - for (auto bot_iter : selectable_bot_list) { - if (bot_iter->GetBotID() != group_iter) - continue; - - if (IsMyBot(bot_owner, bot_iter)) { - sbl.push_back(bot_iter); - break; - } - } - } - - if (!clear_list) - UniquifySBL(sbl); - } } namespace ActionableTarget @@ -2166,7 +2121,6 @@ namespace ActionableBots ABM_Target = (1 << (ABT_Target - 1)), ABM_ByName = (1 << (ABT_ByName - 1)), ABM_OwnerGroup = (1 << (ABT_OwnerGroup - 1)), - ABM_BotGroup = (1 << (ABT_BotGroup - 1)), ABM_TargetGroup = (1 << (ABT_TargetGroup - 1)), ABM_NamesGroup = (1 << (ABT_NamesGroup - 1)), ABM_HealRotation = (1 << (ABT_HealRotation - 1)), @@ -2177,8 +2131,8 @@ namespace ActionableBots ABM_Spawned_All = (3 << (ABT_Spawned - 1)), ABM_NoFilter = ~0, // grouped values - ABM_Type1 = (ABM_Target | ABM_ByName | ABM_OwnerGroup | ABM_BotGroup | ABM_TargetGroup | ABM_NamesGroup | ABM_HealRotationTargets | ABM_Spawned), - ABM_Type2 = (ABM_ByName | ABM_OwnerGroup | ABM_BotGroup | ABM_NamesGroup | ABM_HealRotation | ABM_Spawned) + ABM_Type1 = (ABM_Target | ABM_ByName | ABM_OwnerGroup | ABM_TargetGroup | ABM_NamesGroup | ABM_HealRotationTargets | ABM_Spawned), + ABM_Type2 = (ABM_ByName | ABM_OwnerGroup | ABM_NamesGroup | ABM_HealRotation | ABM_Spawned) }; // Populates 'sbl' @@ -2195,8 +2149,6 @@ namespace ActionableBots ab_type = ABT_ByName; else if (!ab_type_arg.compare("ownergroup")) ab_type = ABT_OwnerGroup; - else if (!ab_type_arg.compare("botgroup")) - ab_type = ABT_BotGroup; else if (!ab_type_arg.compare("targetgroup")) ab_type = ABT_TargetGroup; else if (!ab_type_arg.compare("namesgroup")) @@ -2228,10 +2180,6 @@ namespace ActionableBots if (ab_mask & ABM_OwnerGroup) MyBots::PopulateSBL_ByMyGroupedBots(bot_owner, sbl, clear_list); break; - case ABT_BotGroup: - if (ab_mask & ABM_BotGroup) - MyBots::PopulateSBL_ByBotGroup(bot_owner, sbl, name, clear_list); - break; case ABT_TargetGroup: if (ab_mask & ABM_TargetGroup) MyBots::PopulateSBL_ByTargetsGroupedBots(bot_owner, sbl, clear_list); @@ -7157,803 +7105,6 @@ void bot_subcommand_bot_woad(Client *c, const Seperator *sep) helper_bot_appearance_form_final(c, my_bot); } -void bot_subcommand_botgroup_add_member(Client *c, const Seperator *sep) -{ - if (helper_command_alias_fail(c, "bot_subcommand_botgroup_add_member", sep->arg[0], "botgroupaddmember")) { - return; - } - - if (helper_is_help_or_usage(sep->arg[1])) { - c->Message( - Chat::White, - fmt::format( - "Usage: () {} [member_name] ([leader_name])", - sep->arg[0] - ).c_str() - ); - return; - } - - std::list sbl; - MyBots::PopulateSBL_ByNamedBot(c, sbl, sep->arg[1]); - if (sbl.empty()) { - c->Message( - Chat::White, - fmt::format( - "Usage: () {} [member_name]", - sep->arg[0] - ).c_str() - ); - return; - } - - auto new_member = sbl.front(); - if (!new_member) { - c->Message(Chat::White, "Error: New member bot dereferenced to nullptr"); - return; - } - - if (new_member->HasGroup()) { - c->Message( - Chat::White, - fmt::format( - "{} is already member of a group.", - new_member->GetCleanName() - ).c_str() - ); - return; - } - - uint32 botgroup_id = 0; - if (!database.botdb.LoadBotGroupIDByMemberID(new_member->GetBotID(), botgroup_id)) { - c->Message( - Chat::White, - fmt::format( - "Failed to load bot-group id by member ID for '{}'.", - new_member->GetCleanName() - ).c_str() - ); - return; - } - - if (botgroup_id) { - c->Message( - Chat::White, - fmt::format( - "{} is already a member of a bot-group.", - new_member->GetCleanName() - ).c_str() - ); - return; - } - - MyBots::PopulateSBL_ByNamedBot(c, sbl, sep->arg[2]); - - if (sbl.empty()) { - MyBots::PopulateSBL_ByTargetedBot(c, sbl); - } - - if (sbl.empty()) { - c->Message(Chat::White, "You must target or name a group leader as a bot that you own to use this command."); - return; - } - - auto leader = sbl.front(); - if (!leader) { - c->Message(Chat::White, "Error: Group leader bot dereferenced to nullptr."); - return; - } - - auto* g = leader->GetGroup(); - if (!g || g->GetLeader() != leader) { - c->Message( - Chat::White, - fmt::format( - "{} is not the leader of a group.", - leader->GetCleanName() - ).c_str() - ); - return; - } - - botgroup_id = 0; - if (!database.botdb.LoadBotGroupIDByLeaderID(leader->GetBotID(), botgroup_id)) { - c->Message( - Chat::White, - fmt::format( - "Failed to load bot-group ID by leader ID for '{}'.", - leader->GetCleanName() - ).c_str() - ); - return; - } - - if (!botgroup_id) { - c->Message( - Chat::White, - fmt::format( - "{} is not the leader of a bot-group.", - leader->GetCleanName() - ).c_str() - ); - return; - } - - if (!Bot::AddBotToGroup(new_member, g)) { - c->Message( - Chat::White, - fmt::format( - "Could not add {} as a new member to a group with {}.", - new_member->GetCleanName(), - leader->GetCleanName() - ).c_str() - ); - return; - } - - database.SetGroupID(new_member->GetName(), g->GetID(), new_member->GetBotID()); - - if (!database.botdb.AddMemberToBotGroup(leader->GetBotID(), new_member->GetBotID())) { - c->Message( - Chat::White, - fmt::format( - "Failed to add member to bot-group, {} could not be added to a group with {}.", - new_member->GetCleanName(), - leader->GetCleanName() - ).c_str() - ); - Bot::RemoveBotFromGroup(new_member, leader->GetGroup()); - return; - } - - std::string botgroup_name; - if (!database.botdb.LoadBotGroupNameByLeaderID(leader->GetBotID(), botgroup_name)) { - c->Message( - Chat::White, - fmt::format( - "Failed to load bot-group name by leader ID for bot ID {}.", - leader->GetBotID() - ).c_str() - ); - } - - c->Message( - Chat::White, - fmt::format( - "Successfully added {} to bot-group {}.", - new_member->GetCleanName(), - botgroup_name - ).c_str() - ); -} - -void bot_subcommand_botgroup_auto_spawn(Client *c, const Seperator *sep) -{ - if (helper_command_alias_fail(c, "bot_subcommand_botgroup_auto_spawn", sep->arg[0], "botgroupautospawn")) { - return; - } - - if (helper_is_help_or_usage(sep->arg[1])) { - c->Message( - Chat::White, - fmt::format( - "Usage: () {} ([leader_name])", - sep->arg[0] - ).c_str() - ); - return; - } - - std::list sbl; - - if (sbl.empty()) { - MyBots::PopulateSBL_ByTargetedBot(c, sbl); - } - - if (sbl.empty()) { - c->Message(Chat::White, "You must target or name a group leader as a bot that you own to use this command."); - return; - } - - auto leader = sbl.front(); - if (!leader) { - c->Message(Chat::White, "Error: Group leader bot dereferenced to nullptr."); - return; - } - - auto* g = leader->GetGroup(); - if (!g || g->GetLeader() != leader) { - c->Message( - Chat::White, - fmt::format( - "{} is not the leader of a group.", - leader->GetCleanName() - ).c_str() - ); - return; - } - - uint32 botgroup_id = 0; - if (!database.botdb.LoadBotGroupIDByLeaderID(leader->GetBotID(), botgroup_id)) { - c->Message( - Chat::White, - fmt::format( - "Failed to load bot-group ID by leader ID for '{}'.", - leader->GetCleanName() - ).c_str() - ); - return; - } - - if (!botgroup_id) { - c->Message( - Chat::White, - fmt::format( - "{} is not the leader of a bot-group.", - leader->GetCleanName() - ).c_str() - ); - return; - } - - std::string botgroup_name; - if (!database.botdb.LoadBotGroupNameByLeaderID(leader->GetBotID(), botgroup_name)) { - c->Message(Chat::White, "Failed to load bot-group name by leader ID."); - return; - } - - if (!database.botdb.ToggleBotGroupAutoSpawn(botgroup_id)) { - c->Message( - Chat::White, - fmt::format( - "Failed to toggle auto spawn for bot-group '{}'.", - botgroup_name - ).c_str() - ); - return; - } - - bool auto_spawn = database.botdb.IsBotGroupAutoSpawn(botgroup_name); - - c->Message( - Chat::White, - fmt::format( - "Auto spawn is now {}active bot-group '{}'.", - !auto_spawn ? "in" : "", - botgroup_name - ).c_str() - ); -} - -void bot_subcommand_botgroup_create(Client *c, const Seperator *sep) -{ - if (helper_command_alias_fail(c, "bot_subcommand_botgroup_create", sep->arg[0], "botgroupcreate")) { - return; - } - - if (helper_is_help_or_usage(sep->arg[1])) { - c->Message( - Chat::White, - fmt::format( - "Usage: () {} [group_name] ([leader_name])", - sep->arg[0] - ).c_str() - ); - return; - } - - std::string botgroup_name = sep->argplus[1]; - if (botgroup_name.empty()) { - c->Message(Chat::White, "You must specify a name for this bot-group to use this command."); - return; - } - - if (database.botdb.QueryBotGroupExistence(botgroup_name)) { - c->Message( - Chat::White, - fmt::format( - "The name '{}' already exists for a bot-group. Please choose another.", - botgroup_name - ).c_str() - ); - return; - } - - std::list sbl; - MyBots::PopulateSBL_ByNamedBot(c, sbl, sep->arg[2]); - - if (sbl.empty()) { - MyBots::PopulateSBL_ByTargetedBot(c, sbl); - } - - if (sbl.empty()) { - c->Message(Chat::White, "You must target or name a group leader as a bot that you own to use this command."); - return; - } - - auto leader = sbl.front(); - if (!leader) { - c->Message(Chat::White, "Error: Group leader bot dereferenced to nullptr."); - return; - } - - if (leader->HasGroup()) { - c->Message( - Chat::White, - fmt::format( - "{} is already a current member of a group.", - leader->GetCleanName() - ).c_str() - ); - return; - } - - uint32 botgroup_id = 0; - if (!database.botdb.LoadBotGroupIDByLeaderID(leader->GetBotID(), botgroup_id)) { - c->Message( - Chat::White, - fmt::format( - "Failed to load bot-group ID by leader ID for '{}'.", - leader->GetCleanName() - ).c_str() - ); - return; - } - - if (botgroup_id) { - c->Message( - Chat::White, - fmt::format( - "{} is already the current leader of a bot-group.", - leader->GetCleanName() - ).c_str() - ); - return; - } - - botgroup_id = 0; - if (!database.botdb.LoadBotGroupIDByMemberID(leader->GetBotID(), botgroup_id)) { - c->Message( - Chat::White, - fmt::format( - "Failed to load bot-group id by member ID for '{}'.", - leader->GetCleanName() - ).c_str() - ); - return; - } - - if (botgroup_id) { - c->Message( - Chat::White, - fmt::format( - "{} is already a current member of a bot-group.", - leader->GetCleanName() - ).c_str() - ); - return; - } - - auto* g = new Group(leader); - if (!g) { - c->Message(Chat::White, "Could not create a new group instance."); - return; - } - - if (!database.botdb.CreateBotGroup(botgroup_name, leader->GetBotID())) { - c->Message( - Chat::White, - fmt::format( - "Failed to create bot-group '{}'.", - botgroup_name - ).c_str() - ); - safe_delete(g); - return; - } - - entity_list.AddGroup(g); - database.SetGroupID(leader->GetCleanName(), g->GetID(), leader->GetBotID()); - database.SetGroupLeaderName(g->GetID(), leader->GetCleanName()); - leader->SetFollowID(c->GetID()); - - c->Message( - Chat::White, - fmt::format( - "Successfully created bot-group '{}' with '{}' as its leader.", - botgroup_name, - leader->GetCleanName() - ).c_str() - ); -} - -void bot_subcommand_botgroup_delete(Client *c, const Seperator *sep) -{ - if (helper_command_alias_fail(c, "bot_subcommand_botgroup_delete", sep->arg[0], "botgroupdelete")) { - return; - } - - if (helper_is_help_or_usage(sep->arg[1])) { - c->Message(Chat::White, "usage: %s [botgroup_name]", sep->arg[0]); - return; - } - - std::string botgroup_name = sep->argplus[1]; - if (botgroup_name.empty()) { - c->Message(Chat::White, "You must specify a [name] for this bot-group to use this command"); - return; - } - - uint32 botgroup_id = 0; - if (!database.botdb.LoadBotGroupIDForLoadBotGroup(c->CharacterID(), botgroup_name, botgroup_id)) { - c->Message( - Chat::White, - fmt::format( - "Failed to load bot-group ID for load bot-group for '{}'.", - botgroup_name - ).c_str() - ); - return; - } - - if (!botgroup_id) { - c->Message( - Chat::White, - fmt::format( - "Could not locate group ID for '{}'.", - botgroup_name - ).c_str() - ); - return; - } - - uint32 leader_id = 0; - if (!database.botdb.LoadLeaderIDByBotGroupID(botgroup_id, leader_id)) { - c->Message( - Chat::White, - fmt::format( - "Failed to load leader ID by bot-group ID for '{}'.", - botgroup_name - ).c_str() - ); - return; - } - - if (!leader_id) { - c->Message( - Chat::White, - fmt::format( - "Could not locate leader ID for '{}'.", - botgroup_name - ).c_str() - ); - return; - } - - std::list gbl; - std::list sbl; - MyBots::PopulateSBL_BySpawnedBots(c, sbl); - - std::map> member_list; - if (!database.botdb.LoadBotGroup(botgroup_name, member_list)) { - c->Message( - Chat::White, - fmt::format( - "Failed to load bot-group '{}'.", - botgroup_name - ).c_str() - ); - return; - } - - if (member_list.find(botgroup_id) == member_list.end() || member_list[botgroup_id].empty()) { - c->Message( - Chat::White, - fmt::format( - "Could not locate member list for bot-group '{}'.", - botgroup_name - ).c_str() - ); - return; - } - - for (auto bot_iter : sbl) { - for (auto group_iter : member_list[botgroup_id]) { - if (bot_iter->GetBotID() == group_iter) { - gbl.push_back(bot_iter); - break; - } - } - } - - gbl.unique(); - - for (auto group_member : gbl) { - if (group_member->HasGroup()) { - Bot::RemoveBotFromGroup(group_member, group_member->GetGroup()); - } - } - - if (!database.botdb.DeleteBotGroup(leader_id)) { - c->Message( - Chat::White, - fmt::format( - "Failed to delete bot-group '{}'.", - botgroup_name - ).c_str() - ); - return; - } - - c->Message( - Chat::White, - fmt::format( - "Successfully deleted bot-group '{}'.", - botgroup_name - ).c_str() - ); -} - -void bot_subcommand_botgroup_list(Client *c, const Seperator *sep) -{ - if (helper_command_alias_fail(c, "bot_subcommand_botgroup_list", sep->arg[0], "botgrouplist")) { - return; - } - - if (helper_is_help_or_usage(sep->arg[1])) { - c->Message( - Chat::White, - fmt::format( - "Usage: {}", - sep->arg[0] - ).c_str() - ); - return; - } - - std::list> botgroups_list; - if (!database.botdb.LoadBotGroupsListByOwnerID(c->CharacterID(), botgroups_list)) { - c->Message(Chat::White, "Failed to load bot-group."); - return; - } - - if (botgroups_list.empty()) { - c->Message(Chat::White, "You have no saved bot-groups."); - return; - } - - uint32 botgroup_count = 0; - - for (const auto& [group_name, group_leader_id] : botgroups_list) { - c->Message( - Chat::White, - fmt::format( - "Bot-group {} | Name: {} | Leader: {}{} | {}", - (botgroup_count + 1), - group_name, - database.botdb.GetBotNameByID(group_leader_id), - database.botdb.IsBotGroupAutoSpawn(group_name) ? " (Auto Spawn)" : "", - Saylink::Silent( - fmt::format("^botgroupload {}", group_name), - "Load" - ) - ).c_str() - ); - - botgroup_count++; - } - - c->Message( - Chat::White, - fmt::format( - "{} Bot-group{} listed.", - botgroup_count, - botgroup_count != 1 ? "s" : "" - ).c_str() - ); -} - -void bot_subcommand_botgroup_load(Client *c, const Seperator *sep) -{ - if (helper_command_alias_fail(c, "bot_subcommand_botgroup_load", sep->arg[0], "botgroupload")) { - return; - } - - if (helper_is_help_or_usage(sep->arg[1])) { - c->Message( - Chat::White, - fmt::format( - "Usage: {} [botgroup_name]", - sep->arg[0] - ).c_str() - ); - return; - } - - std::string botgroup_name = sep->argplus[1]; - if (botgroup_name.empty()) { - c->Message(Chat::White, "You must specify the name of a bot-group to load to use this command."); - return; - } - - if (!database.botdb.QueryBotGroupExistence(botgroup_name)) { - c->Message( - Chat::White, - fmt::format( - "Failed to query bot-group existence for '{}'.", - botgroup_name - ).c_str() - ); - return; - } - - if (!Bot::CheckSpawnConditions(c)) { - return; - } - - uint32 botgroup_id = 0; - if (!database.botdb.LoadBotGroupIDForLoadBotGroup(c->CharacterID(), botgroup_name, botgroup_id) || !botgroup_id) { - c->Message( - Chat::White, - fmt::format( - "Failed to load bot-group ID for load bot-group for '{}'.", - botgroup_name - ).c_str() - ); - return; - } - - std::map> member_list; - if (!database.botdb.LoadBotGroup(botgroup_name, member_list)) { - c->Message( - Chat::White, - fmt::format( - "Failed to load bot-group for '{}'.", - botgroup_name - ).c_str() - ); - return; - } - - if (member_list.find(botgroup_id) == member_list.end() || member_list[botgroup_id].empty()) { - c->Message( - Chat::White, - fmt::format( - "Database returned an empty list for bot-group '{}'.", - botgroup_name - ).c_str() - ); - return; - } - - auto spawned_bot_count = Bot::SpawnedBotCount(c->CharacterID()); - - auto bot_spawn_limit = c->GetBotSpawnLimit(); - if ( - bot_spawn_limit >= 0 && - ( - spawned_bot_count >= bot_spawn_limit || - (spawned_bot_count + member_list.begin()->second.size()) > bot_spawn_limit - ) - ) { - std::string message; - if (bot_spawn_limit) { - message = fmt::format( - "You cannot have more than {} spawned bot{}.", - bot_spawn_limit, - bot_spawn_limit != 1 ? "s" : "" - ); - } else { - message = "You are not currently allowed to spawn any bots."; - } - - c->Message(Chat::White, message.c_str()); - return; - } - - uint32 leader_id = 0; - if (!database.botdb.LoadLeaderIDByBotGroupName(botgroup_name, leader_id)) { - c->Message( - Chat::White, - fmt::format( - "Failed to load leader ID by bot-group name for '{}'.", - botgroup_name - ).c_str() - ); - return; - } - - if (!leader_id) { - c->Message( - Chat::White, - fmt::format( - "Cannot locate bot-group leader ID for '{}'.", - botgroup_name - ).c_str() - ); - return; - } - - Bot::SpawnBotGroupByName(c, botgroup_name, leader_id); -} - -void bot_subcommand_botgroup_remove_member(Client *c, const Seperator *sep) -{ - if (helper_command_alias_fail(c, "bot_subcommand_botgroup_remove_member", sep->arg[0], "botgroupremovemember")) { - return; - } - - if (helper_is_help_or_usage(sep->arg[1])) { - c->Message( - Chat::White, - fmt::format( - "Usage: () {} ([member_name])", - sep->arg[0] - ).c_str() - ); - return; - } - - std::list sbl; - MyBots::PopulateSBL_ByNamedBot(c, sbl, sep->arg[1]); - - if (sbl.empty()) { - MyBots::PopulateSBL_ByTargetedBot(c, sbl); - } - - if (sbl.empty()) { - c->Message(Chat::White, "You must target or name a group member as a bot that you own to use this command."); - return; - } - - auto group_member = sbl.front(); - if (!group_member) { - c->Message(Chat::White, "Error: Group member bot dereferenced to nullptr."); - return; - } - - if (!group_member->HasGroup()) { - c->Message( - Chat::White, - fmt::format( - "{} is not a current member of a group.", - group_member->GetCleanName() - ).c_str() - ); - return; - } - - if (!Bot::RemoveBotFromGroup(group_member, group_member->GetGroup())) { - c->Message( - Chat::White, - fmt::format( - "Could not remove {} from their group.", - group_member->GetCleanName() - ).c_str() - ); - return; - } - - if (!database.botdb.RemoveMemberFromBotGroup(group_member->GetBotID())) { - c->Message( - Chat::White, - fmt::format( - "Could not remove {} from their bot-group.", - group_member->GetCleanName() - ).c_str() - ); - return; - } - - c->Message( - Chat::White, - fmt::format( - "Successfully removed {} from their bot-group.", - group_member->GetCleanName() - ).c_str() - ); -} - void bot_subcommand_circle(Client *c, const Seperator *sep) { bcst_list* local_list = &bot_command_spells[BCEnum::SpT_Depart]; diff --git a/zone/bot_command.h b/zone/bot_command.h index 723597df7..312038096 100644 --- a/zone/bot_command.h +++ b/zone/bot_command.h @@ -631,13 +631,7 @@ void bot_subcommand_bot_toggle_archer(Client *c, const Seperator *sep); void bot_subcommand_bot_toggle_helm(Client *c, const Seperator *sep); void bot_subcommand_bot_update(Client *c, const Seperator *sep); void bot_subcommand_bot_woad(Client *c, const Seperator *sep); -void bot_subcommand_botgroup_add_member(Client *c, const Seperator *sep); -void bot_subcommand_botgroup_auto_spawn(Client *c, const Seperator *sep); -void bot_subcommand_botgroup_create(Client *c, const Seperator *sep); -void bot_subcommand_botgroup_delete(Client *c, const Seperator *sep); -void bot_subcommand_botgroup_list(Client *c, const Seperator *sep); -void bot_subcommand_botgroup_load(Client *c, const Seperator *sep); -void bot_subcommand_botgroup_remove_member(Client *c, const Seperator *sep); + void bot_subcommand_circle(Client *c, const Seperator *sep); void bot_subcommand_heal_rotation_adaptive_targeting(Client *c, const Seperator *sep); void bot_subcommand_heal_rotation_add_member(Client *c, const Seperator *sep); diff --git a/zone/bot_database.cpp b/zone/bot_database.cpp index 6057ce8aa..dddcd293e 100644 --- a/zone/bot_database.cpp +++ b/zone/bot_database.cpp @@ -2204,523 +2204,6 @@ bool BotDatabase::SaveOwnerOption(const uint32 owner_id, const std::pair>& member_list) -{ - if (group_name.empty()) { - return false; - } - - uint32 botgroup_id = 0; - if (!LoadBotGroupIDByBotGroupName(group_name, botgroup_id)) { - return false; - } - - if (!botgroup_id) { - return true; - } - - query = fmt::format( - "SELECT `bot_id` FROM `bot_group_members` WHERE `groups_index` = {} LIMIT 6", - botgroup_id - ); - - auto results = database.QueryDatabase(query); - if (!results.Success()) { - return false; - } - - if (!results.RowCount()) { - return true; - } - - for (auto row : results) { - member_list[botgroup_id].push_back(Strings::ToUnsignedInt(row[0])); - } - - return true; -} - -bool BotDatabase::LoadBotGroupsListByOwnerID(const uint32 owner_id, std::list>& botgroups_list) -{ - if (!owner_id) { - return false; - } - - - query = fmt::format( - "SELECT DISTINCT(group_name), group_leader_id FROM " - "bot_groups bg INNER JOIN bot_group_members bgm " - "ON bg.groups_index = bgm.groups_index " - "WHERE bgm.bot_id IN " - "(SELECT bot_id FROM bot_data WHERE owner_id = {})", - owner_id - ); - - auto results = database.QueryDatabase(query); - if (!results.Success()) { - return false; - } - - if (!results.RowCount()) { - return true; - } - - for (auto row : results) { - botgroups_list.push_back(std::pair(row[0], Strings::ToUnsignedInt(row[1]))); - } - - return true; -} - -bool BotDatabase::IsBotGroupAutoSpawn(const std::string& botgroup_name) -{ - if (botgroup_name.empty()) { - return false; - } - - query = fmt::format( - "SELECT group_name FROM bot_groups WHERE group_name = '{}' AND auto_spawn = 1", - botgroup_name - ); - - auto results = database.QueryDatabase(query); - if (!results.RowCount() || !results.Success()) { - return false; - } - - return true; -} - -bool BotDatabase::ToggleBotGroupAutoSpawn(const uint32 group_id) -{ - if (!group_id) { - return false; - } - - query = fmt::format( - "UPDATE bot_groups SET auto_spawn = 1 - auto_spawn WHERE groups_index = {}", - group_id - ); - - auto results = database.QueryDatabase(query); - if (!results.Success() || !results.RowsAffected()) { - return false; - } - - return true; -} - -bool BotDatabase::LoadAutoSpawnBotGroupsByOwnerID(const uint32 owner_id, std::list>& group_list) -{ - if (!owner_id) { - return false; - } - - query = fmt::format( - SQL( - SELECT group_leader_id, group_name FROM bot_groups WHERE groups_index IN ( - SELECT groups_index FROM bot_group_members WHERE bot_id IN ( - SELECT bot_id FROM bot_data WHERE owner_id = {} - ) - ) AND auto_spawn = 1 - ), - owner_id - ); - - auto results = database.QueryDatabase(query); - if (!results.Success()) { - return false; - } - - if (!results.RowCount()) { - return true; - } - - for (auto row : results) { - group_list.push_back( - std::pair(Strings::ToUnsignedInt(row[0]), row[1]) - ); - } - - return true; -} - /* Bot owner group functions */ // added owner ID to this function to fix groups with mulitple players grouped with bots. bool BotDatabase::LoadGroupedBotsByGroupID(const uint32 owner_id, const uint32 group_id, std::list& group_list) @@ -3238,3 +2721,4 @@ const char* BotDatabase::fail::DeleteAllHealRotations() { return "Failed to dele /* fail::Bot miscellaneous functions */ const char* BotDatabase::fail::GetBotNameByID() { return "Failed to get bot name by bot ID"; } +const char* BotDatabase::fail::LoadGroupedBotsByGroupID() { return "Failed to load grouped bots by group ID."; } diff --git a/zone/bot_database.h b/zone/bot_database.h index 8107c0ed2..fa4259325 100644 --- a/zone/bot_database.h +++ b/zone/bot_database.h @@ -148,36 +148,8 @@ public: bool SaveBotCasterRange(const uint32 owner_id, const uint32 bot_id, const uint32 bot_caster_range_value); - /* Bot bot-group functions */ - bool QueryBotGroupExistence(const std::string& botgroup_name); - - bool LoadBotGroupIDByBotGroupName(const std::string& botgroup_name, uint32& botgroup_id); - bool LoadBotGroupIDByLeaderID(const uint32 leader_id, uint32& botgroup_id); - bool LoadBotGroupIDByMemberID(const uint32 member_id, uint32& botgroup_id); - - bool LoadLeaderIDByBotGroupName(const std::string& botgroup_name, uint32& leader_id); - bool LoadLeaderIDByBotGroupID(const uint32 botgroup_id, uint32& leader_id); - - bool LoadBotGroupNameByBotGroupID(const uint32 botgroup_id, std::string& botgroup_name); - bool LoadBotGroupNameByLeaderID(const uint32 leader_id, std::string& botgroup_name); - - bool CreateBotGroup(const std::string& botgroup_name, const uint32 leader_id); - bool DeleteBotGroup(const uint32 leader_id); - bool AddMemberToBotGroup(const uint32 leader_id, const uint32 member_id); - bool RemoveMemberFromBotGroup(const uint32 member_id); - - bool LoadBotGroupIDForLoadBotGroup(const uint32 owner_id, std::string_view botgroup_name, uint32& botgroup_id); - bool LoadBotGroup(const std::string& botgroup_name, std::map>& member_list); - - bool LoadBotGroupsListByOwnerID(const uint32 owner_id, std::list>& botgroups_list); - - /* Bot group functions */ - bool IsBotGroupAutoSpawn(const std::string& botgroup_name); - bool LoadAutoSpawnBotGroupsByOwnerID(const uint32 owner_id, std::list>& group_list); bool LoadGroupedBotsByGroupID(const uint32 owner_id, const uint32 group_id, std::list& group_list); - bool ToggleBotGroupAutoSpawn(const uint32 group_id); - /* Bot heal rotation functions */ bool LoadHealRotationIDByBotID(const uint32 bot_id, uint32& hr_index); @@ -254,23 +226,6 @@ public: static const char* SaveStopMeleeLevel(); static const char* SaveBotCasterRange(); - /* fail::Bot bot-group functions */ - static const char* QueryBotGroupExistence(); - static const char* LoadBotGroupIDByBotGroupName(); - static const char* LoadBotGroupIDByLeaderID(); - static const char* LoadBotGroupIDByMemberID(); - static const char* LoadLeaderIDByBotGroupName(); - static const char* LoadLeaderIDByBotGroupID(); - static const char* LoadBotGroupNameByBotGroupID(); - static const char* LoadBotGroupNameByLeaderID(); - static const char* CreateBotGroup(); - static const char* DeleteBotGroup(); - static const char* AddMemberToBotGroup(); - static const char* RemoveMemberFromBotGroup(); - static const char* LoadBotGroupIDForLoadBotGroup(); - static const char* LoadBotGroup(); - static const char* LoadBotGroupsListByOwnerID(); - /* fail::Bot group functions */ static const char* LoadGroupedBotsByGroupID(); diff --git a/zone/groups.h b/zone/groups.h index 51d9164c9..85a85ccae 100644 --- a/zone/groups.h +++ b/zone/groups.h @@ -153,11 +153,11 @@ public: bool DoesAnyMemberHaveExpeditionLockout(const std::string& expedition_name, const std::string& event_name, int max_check_count = 0); - Mob* members[MAX_GROUP_MEMBERS]; - char membername[MAX_GROUP_MEMBERS][64]; - uint8 MemberRoles[MAX_GROUP_MEMBERS]; - bool disbandcheck; - bool castspell; + Mob* members[MAX_GROUP_MEMBERS] {nullptr}; + char membername[MAX_GROUP_MEMBERS][64] {""}; + uint8 MemberRoles[MAX_GROUP_MEMBERS] {0}; + bool disbandcheck {false}; + bool castspell {false}; private: Mob* leader;