Added bot command option 'follow chain' to allow linear assignment of follow ids to eligible bots

This commit is contained in:
Uleat 2019-12-08 23:54:51 -05:00
parent 08b8deaa4b
commit e306e9ad0c
4 changed files with 98 additions and 4 deletions

View File

@ -1371,7 +1371,7 @@ int bot_command_init(void)
bot_command_add("depart", "Orders a bot to open a magical doorway to a specified destination", 0, bot_command_depart) || bot_command_add("depart", "Orders a bot to open a magical doorway to a specified destination", 0, bot_command_depart) ||
bot_command_add("escape", "Orders a bot to send a target group to a safe location within the zone", 0, bot_command_escape) || bot_command_add("escape", "Orders a bot to send a target group to a safe location within the zone", 0, bot_command_escape) ||
bot_command_add("findaliases", "Find available aliases for a bot command", 0, bot_command_find_aliases) || bot_command_add("findaliases", "Find available aliases for a bot command", 0, bot_command_find_aliases) ||
bot_command_add("follow", "Orders bots to follow a designated target", 0, bot_command_follow) || bot_command_add("follow", "Orders bots to follow a designated target (option 'chain' auto-links eligible spawned bots)", 0, bot_command_follow) ||
bot_command_add("guard", "Orders bots to guard their current positions", 0, bot_command_guard) || bot_command_add("guard", "Orders bots to guard their current positions", 0, bot_command_guard) ||
bot_command_add("healrotation", "Lists the available bot heal rotation [subcommands]", 0, bot_command_heal_rotation) || bot_command_add("healrotation", "Lists the available bot heal rotation [subcommands]", 0, bot_command_heal_rotation) ||
bot_command_add("healrotationadaptivetargeting", "Enables or disables adaptive targeting within the heal rotation instance", 0, bot_subcommand_heal_rotation_adaptive_targeting) || bot_command_add("healrotationadaptivetargeting", "Enables or disables adaptive targeting within the heal rotation instance", 0, bot_subcommand_heal_rotation_adaptive_targeting) ||
@ -3213,6 +3213,7 @@ void bot_command_follow(Client *c, const Seperator *sep)
return; return;
if (helper_is_help_or_usage(sep->arg[1])) { if (helper_is_help_or_usage(sep->arg[1])) {
c->Message(m_usage, "usage: (<friendly_target>) %s ([option: reset]) [actionable: byname | ownergroup | botgroup | namesgroup | healrotation | spawned] ([actionable_name])", sep->arg[0]); c->Message(m_usage, "usage: (<friendly_target>) %s ([option: reset]) [actionable: byname | ownergroup | botgroup | namesgroup | healrotation | spawned] ([actionable_name])", sep->arg[0]);
c->Message(m_usage, "usage: %s chain", sep->arg[0]);
return; return;
} }
const int ab_mask = ActionableBots::ABM_Type2; const int ab_mask = ActionableBots::ABM_Type2;
@ -3222,8 +3223,15 @@ void bot_command_follow(Client *c, const Seperator *sep)
int name_arg = 2; int name_arg = 2;
Mob* target_mob = nullptr; Mob* target_mob = nullptr;
std::string reset_arg = sep->arg[1]; std::string optional_arg = sep->arg[1];
if (!reset_arg.compare("reset")) { if (!optional_arg.compare("chain")) {
auto chain_count = helper_bot_follow_option_chain(c);
c->Message(m_action, "%i of your bot%s are now chain following", chain_count, (chain_count == 1 ? "" : "s"));
return;
}
else if (!optional_arg.compare("reset")) {
reset = true; reset = true;
ab_arg = 2; ab_arg = 2;
name_arg = 3; name_arg = 3;
@ -3250,16 +3258,21 @@ void bot_command_follow(Client *c, const Seperator *sep)
bot_iter->SetFollowID(c->GetID()); bot_iter->SetFollowID(c->GetID());
else else
bot_iter->SetFollowID(my_group->GetLeader()->GetID()); bot_iter->SetFollowID(my_group->GetLeader()->GetID());
bot_iter->SetManualFollow(false);
} }
else { else {
if (bot_iter == target_mob) if (bot_iter == target_mob)
bot_iter->SetFollowID(c->GetID()); bot_iter->SetFollowID(c->GetID());
else else
bot_iter->SetFollowID(target_mob->GetID()); bot_iter->SetFollowID(target_mob->GetID());
bot_iter->SetManualFollow(true);
} }
} }
else { else {
bot_iter->SetFollowID(0); bot_iter->SetFollowID(0);
bot_iter->SetManualFollow(false);
} }
if (!bot_iter->GetPet()) if (!bot_iter->GetPet())
continue; continue;
@ -8622,6 +8635,75 @@ void helper_bot_out_of_combat(Client *bot_owner, Bot *my_bot)
} }
} }
int helper_bot_follow_option_chain(Client* bot_owner)
{
if (!bot_owner) {
return 0;
}
std::list<Bot*> sbl;
MyBots::PopulateSBL_BySpawnedBots(bot_owner, sbl);
if (sbl.empty()) {
return 0;
}
int chain_follow_count = 0;
Mob* followee = bot_owner;
// only add groups that do not belong to bot_owner
std::map<uint32, Group*> bot_group_map;
for (auto bot_iter : sbl) {
if (!bot_iter || bot_iter->GetManualFollow() || bot_iter->GetGroup() == bot_owner->GetGroup()) {
continue;
}
Group* bot_group = bot_iter->GetGroup();
if (!bot_iter->GetGroup()) {
continue;
}
bot_group_map[bot_group->GetID()] = bot_group;
}
std::list<Bot*> bot_member_list;
if (bot_owner->GetGroup()) {
bot_owner->GetGroup()->GetBotList(bot_member_list);
for (auto bot_member_iter : bot_member_list) {
if (!bot_member_iter || bot_member_iter->GetBotOwnerCharacterID() != bot_owner->CharacterID() || bot_member_iter == followee || bot_member_iter->GetManualFollow()) {
continue;
}
bot_member_iter->SetFollowID(followee->GetID());
followee = bot_member_iter;
++chain_follow_count;
}
}
for (auto bot_group_iter : bot_group_map) {
if (!bot_group_iter.second) {
continue;
}
bot_group_iter.second->GetBotList(bot_member_list);
for (auto bot_member_iter : bot_member_list) {
if (!bot_member_iter || bot_member_iter->GetBotOwnerCharacterID() != bot_owner->CharacterID() || bot_member_iter == followee || bot_member_iter->GetManualFollow()) {
continue;
}
bot_member_iter->SetFollowID(followee->GetID());
followee = bot_member_iter;
++chain_follow_count;
}
}
return chain_follow_count;
}
bool helper_cast_standard_spell(Bot* casting_bot, Mob* target_mob, int spell_id, bool annouce_cast, uint32* dont_root_before) bool helper_cast_standard_spell(Bot* casting_bot, Mob* target_mob, int spell_id, bool annouce_cast, uint32* dont_root_before)
{ {
if (!casting_bot || !target_mob) if (!casting_bot || !target_mob)

View File

@ -672,6 +672,7 @@ void helper_bot_appearance_form_final(Client *bot_owner, Bot *my_bot);
void helper_bot_appearance_form_update(Bot *my_bot); void helper_bot_appearance_form_update(Bot *my_bot);
uint32 helper_bot_create(Client *bot_owner, std::string bot_name, uint8 bot_class, uint16 bot_race, uint8 bot_gender); uint32 helper_bot_create(Client *bot_owner, std::string bot_name, uint8 bot_class, uint16 bot_race, uint8 bot_gender);
void helper_bot_out_of_combat(Client *bot_owner, Bot *my_bot); void helper_bot_out_of_combat(Client *bot_owner, Bot *my_bot);
int helper_bot_follow_option_chain(Client *bot_owner);
bool helper_cast_standard_spell(Bot* casting_bot, Mob* target_mob, int spell_id, bool annouce_cast = true, uint32* dont_root_before = nullptr); bool helper_cast_standard_spell(Bot* casting_bot, Mob* target_mob, int spell_id, bool annouce_cast = true, uint32* dont_root_before = nullptr);
bool helper_command_disabled(Client *bot_owner, bool rule_value, const char *command); bool helper_command_disabled(Client *bot_owner, bool rule_value, const char *command);
bool helper_command_alias_fail(Client *bot_owner, const char* command_handler, const char *alias, const char *command); bool helper_command_alias_fail(Client *bot_owner, const char* command_handler, const char *alias, const char *command);

View File

@ -453,6 +453,10 @@ Mob::Mob(
PrimaryAggro = false; PrimaryAggro = false;
AssistAggro = false; AssistAggro = false;
npc_assist_cap = 0; npc_assist_cap = 0;
#ifdef BOTS
m_manual_follow = false;
#endif
} }
Mob::~Mob() Mob::~Mob()

View File

@ -1188,8 +1188,8 @@ public:
int32 GetManaRegen() const; int32 GetManaRegen() const;
// Bots HealRotation methods
#ifdef BOTS #ifdef BOTS
// Bots HealRotation methods
bool IsHealRotationTarget() { return (m_target_of_heal_rotation.use_count() && m_target_of_heal_rotation.get()); } bool IsHealRotationTarget() { return (m_target_of_heal_rotation.use_count() && m_target_of_heal_rotation.get()); }
bool JoinHealRotationTargetPool(std::shared_ptr<HealRotation>* heal_rotation); bool JoinHealRotationTargetPool(std::shared_ptr<HealRotation>* heal_rotation);
bool LeaveHealRotationTargetPool(); bool LeaveHealRotationTargetPool();
@ -1200,6 +1200,11 @@ public:
float HealRotationExtendedHealFrequency(); float HealRotationExtendedHealFrequency();
const std::shared_ptr<HealRotation>* TargetOfHealRotation() const { return &m_target_of_heal_rotation; } const std::shared_ptr<HealRotation>* TargetOfHealRotation() const { return &m_target_of_heal_rotation; }
// not Bots HealRotation methods
void SetManualFollow(bool flag) { m_manual_follow = flag; }
bool GetManualFollow() const { return m_manual_follow; }
#endif #endif
protected: protected:
@ -1581,6 +1586,8 @@ private:
#ifdef BOTS #ifdef BOTS
std::shared_ptr<HealRotation> m_target_of_heal_rotation; std::shared_ptr<HealRotation> m_target_of_heal_rotation;
bool m_manual_follow;
#endif #endif
}; };