mirror of
https://github.com/EQEmu/Server.git
synced 2026-06-18 20:08:21 +00:00
Bot Rework
This commit is contained in:
@@ -3,22 +3,61 @@
|
||||
void bot_command_actionable(Client* c, const Seperator* sep)
|
||||
{
|
||||
if (helper_command_alias_fail(c, "bot_command_actionable", sep->arg[0], "actionable")) {
|
||||
c->Message(Chat::White, "note: Lists actionable command arguments and use descriptions");
|
||||
return;
|
||||
}
|
||||
|
||||
c->Message(Chat::White, "Actionable command arguments:");
|
||||
c->Message(Chat::White, "target - selects target as single bot .. use ^command [target] or imply by empty actionable argument");
|
||||
c->Message(Chat::White, "byname [name] - selects single bot by name");
|
||||
c->Message(Chat::White, "ownergroup - selects all bots in the owner's group");
|
||||
c->Message(Chat::White, "ownerraid - selects all bots in the owner's raid");
|
||||
c->Message(Chat::White, "targetgroup - selects all bots in target's group");
|
||||
c->Message(Chat::White, "namesgroup [name] - selects all bots in name's group");
|
||||
c->Message(Chat::White, "healrotation [name] - selects all member and target bots of a heal rotation where name is a member");
|
||||
c->Message(Chat::White, "healrotationmembers [name] - selects all member bots of a heal rotation where name is a member");
|
||||
c->Message(Chat::White, "healrotationtargets [name] - selects all target bots of a heal rotation where name is a member");
|
||||
c->Message(Chat::White, "byclass - selects all bots of the chosen class");
|
||||
c->Message(Chat::White, "byrace - selects all bots of the chosen rsce");
|
||||
c->Message(Chat::White, "spawned - selects all spawned bots");
|
||||
c->Message(Chat::White, "all - selects all spawned bots .. argument use indicates en masse database updating");
|
||||
c->Message(Chat::White, "You may only select your bots as actionable");
|
||||
std::vector<std::string> description =
|
||||
{
|
||||
"Lists actionable command arguments and use descriptions."
|
||||
};
|
||||
|
||||
std::vector<std::string> notes =
|
||||
{
|
||||
"[target] - uses the command on the target. Some commands will default to target if no actionable is selected.",
|
||||
"[byname] [name] - selects a bot by name their name.",
|
||||
"[ownergroup] - selects all bots in the owner's group.",
|
||||
"[ownerraid] - selects all bots in the owner's raid.",
|
||||
"[targetgroup] - selects all bots in the target's group.",
|
||||
"[namesgroup] [name] - selects all bots in [name]'s group.",
|
||||
"[healrotation] [name] - selects all member and target bots of a heal rotation where [name] is a member.",
|
||||
"[healrotationmembers] [name] - selects all member bots of a heal rotation where [name] is a member.",
|
||||
"[healrotationtargets] [name] - selects all target bots of a heal rotation where [name] is a member.",
|
||||
"[mmr] - selects all bots that are currently at max melee range.",
|
||||
"[byclass] - selects all bots of the chosen class.",
|
||||
"[byrace] - selects all bots of the chosen race.",
|
||||
"[spawned] - selects all spawned bots.",
|
||||
"[all] - selects all spawned bots.",
|
||||
"<br>",
|
||||
"You may only select your bots as actionable"
|
||||
};
|
||||
|
||||
std::vector<std::string> example_format = { };
|
||||
std::vector<std::string> examples_one = { };
|
||||
std::vector<std::string> examples_two = { };
|
||||
std::vector<std::string> examples_three = { };
|
||||
|
||||
std::vector<std::string> actionables = { };
|
||||
|
||||
std::vector<std::string> options = { };
|
||||
std::vector<std::string> options_one = { };
|
||||
std::vector<std::string> options_two = { };
|
||||
std::vector<std::string> options_three = { };
|
||||
|
||||
std::string popup_text = c->SendCommandHelpWindow(
|
||||
c,
|
||||
description,
|
||||
notes,
|
||||
example_format,
|
||||
examples_one, examples_two, examples_three,
|
||||
actionables,
|
||||
options,
|
||||
options_one, options_two, options_three
|
||||
);
|
||||
|
||||
popup_text = DialogueWindow::Table(popup_text);
|
||||
|
||||
c->SendPopupToClient(sep->arg[0], popup_text.c_str());
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -7,32 +7,26 @@ void bot_command_aggressive(Client* c, const Seperator* sep)
|
||||
helper_command_alias_fail(c, "bot_command_aggressive", sep->arg[0], "aggressive")) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (helper_is_help_or_usage(sep->arg[1])) {
|
||||
c->Message(
|
||||
Chat::White,
|
||||
"usage: %s ([actionable: target | byname | ownergroup | ownerraid | targetgroup | namesgroup | healrotationtargets | byclass | byrace | spawned] ([actionable_name]))",
|
||||
sep->arg[0]
|
||||
);
|
||||
c->Message(Chat::White, "usage: %s ([actionable: target | byname | ownergroup | ownerraid | targetgroup | namesgroup | healrotationtargets | mmr | byclass | byrace | spawned] ([actionable_name]))", sep->arg[0]);
|
||||
c->Message(Chat::White, "note: Orders a bot to use a aggressive discipline");
|
||||
helper_send_usage_required_bots(c, BCEnum::SpT_Stance);
|
||||
return;
|
||||
}
|
||||
const int ab_mask = ActionableBots::ABM_Type1;
|
||||
|
||||
std::string class_race_arg = sep->arg[1];
|
||||
bool class_race_check = false;
|
||||
const int ab_mask = ActionableBots::ABM_Type1;
|
||||
int ab_arg = 1;
|
||||
std::string class_race_arg = sep->arg[ab_arg];
|
||||
bool class_race_check = false;
|
||||
|
||||
if (!class_race_arg.compare("byclass") || !class_race_arg.compare("byrace")) {
|
||||
class_race_check = true;
|
||||
}
|
||||
|
||||
std::list<Bot*> sbl;
|
||||
if (ActionableBots::PopulateSBL(
|
||||
c,
|
||||
sep->arg[1],
|
||||
sbl,
|
||||
ab_mask,
|
||||
!class_race_check ? sep->arg[2] : nullptr,
|
||||
class_race_check ? atoi(sep->arg[2]) : 0
|
||||
) == ActionableBots::ABT_None) {
|
||||
|
||||
if (ActionableBots::PopulateSBL(c, sep->arg[ab_arg], sbl, ab_mask, !class_race_check ? sep->arg[ab_arg + 1] : nullptr, class_race_check ? atoi(sep->arg[ab_arg + 1]) : 0) == ActionableBots::ABT_None) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -158,7 +158,7 @@ void bot_command_dye_armor(Client *c, const Seperator *sep)
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Usage: {} [Material Slot] [Red: 0-255] [Green: 0-255] [Blue: 0-255] ([actionable: target | byname | ownergroup | targetgroup | namesgroup | healrotation | spawned] ([actionable_name]))",
|
||||
"Usage: {} [Material Slot] [Red: 0-255] [Green: 0-255] [Blue: 0-255] ([actionable: target | byname | ownergroup | ownerraid | targetgroup | namesgroup | healrotationmembers | healrotationtargets | mmr | byclass | byrace | spawned] ([actionable_name]))",
|
||||
sep->arg[0]
|
||||
).c_str()
|
||||
);
|
||||
|
||||
@@ -11,6 +11,7 @@ void bot_command_apply_poison(Client* c, const Seperator* sep)
|
||||
if (helper_is_help_or_usage(sep->arg[1])) {
|
||||
|
||||
c->Message(Chat::White, "usage: <rogue_bot_target> %s", sep->arg[0]);
|
||||
c->Message(Chat::White, "note: Applies cursor-held poison to a rogue bot's weapon");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,14 +5,17 @@ void bot_command_attack(Client *c, const Seperator *sep)
|
||||
if (helper_command_alias_fail(c, "bot_command_attack", sep->arg[0], "attack")) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (helper_is_help_or_usage(sep->arg[1])) {
|
||||
|
||||
c->Message(Chat::White, "usage: <enemy_target> %s [actionable: byname | ownergroup | ownerraid | namesgroup | healrotation | byclass | byrace | default: spawned] ([actionable_name])", sep->arg[0]);
|
||||
c->Message(Chat::White, "usage: <enemy_target> %s [actionable: byname | ownergroup | ownerraid | namesgroup | healrotation | mmr | byclass | byrace | default: spawned] ([actionable_name])", sep->arg[0]);
|
||||
c->Message(Chat::White, "note: Orders bots to attack a designated target");
|
||||
return;
|
||||
}
|
||||
const int ab_mask = ActionableBots::ABM_Type2;
|
||||
|
||||
const int ab_mask = ActionableBots::ABM_Type2;
|
||||
Mob* target_mob = ActionableTarget::AsSingle_ByAttackable(c);
|
||||
|
||||
if (!target_mob) {
|
||||
|
||||
c->Message(Chat::White, "You must <target> an enemy to use this command");
|
||||
@@ -26,11 +29,13 @@ void bot_command_attack(Client *c, const Seperator *sep)
|
||||
|
||||
std::string class_race_arg(sep->arg[1]);
|
||||
bool class_race_check = false;
|
||||
|
||||
if (!class_race_arg.compare("byclass") || !class_race_arg.compare("byrace")) {
|
||||
class_race_check = true;
|
||||
}
|
||||
|
||||
std::list<Bot*> sbl;
|
||||
|
||||
if (ActionableBots::PopulateSBL(c, ab_arg.c_str(), sbl, ab_mask, !class_race_check ? sep->arg[2] : nullptr, class_race_check ? atoi(sep->arg[2]) : 0) == ActionableBots::ABT_None) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,173 @@
|
||||
#include "../bot_command.h"
|
||||
|
||||
void bot_command_behind_mob(Client* c, const Seperator* sep)
|
||||
{
|
||||
if (helper_command_alias_fail(c, "bot_command_behind_mob", sep->arg[0], "behindmob")) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (helper_is_help_or_usage(sep->arg[1])) {
|
||||
std::vector<std::string> description =
|
||||
{
|
||||
"Toggles whether or not bots will stay behind the mob during combat."
|
||||
};
|
||||
|
||||
std::vector<std::string> notes = { };
|
||||
|
||||
std::vector<std::string> example_format =
|
||||
{
|
||||
fmt::format(
|
||||
"{} [value] [actionable]"
|
||||
, sep->arg[0]
|
||||
)
|
||||
};
|
||||
|
||||
std::vector<std::string> examples_one =
|
||||
{
|
||||
"To set Monks to stay behind the mob:",
|
||||
fmt::format(
|
||||
"{} 1 byclass 7",
|
||||
sep->arg[0]
|
||||
)
|
||||
};
|
||||
std::vector<std::string> examples_two = { };
|
||||
std::vector<std::string> examples_three =
|
||||
{
|
||||
"To check the behind mob status for all bots:",
|
||||
fmt::format(
|
||||
"{} current spawned",
|
||||
sep->arg[0]
|
||||
)
|
||||
};
|
||||
|
||||
std::vector<std::string> actionables =
|
||||
{
|
||||
"target, byname, ownergroup, ownerraid, targetgroup, namesgroup, healrotationtargets, mmr, byclass, byrace, spawned"
|
||||
};
|
||||
|
||||
std::vector<std::string> options = { };
|
||||
std::vector<std::string> options_one = { };
|
||||
std::vector<std::string> options_two = { };
|
||||
std::vector<std::string> options_three = { };
|
||||
|
||||
std::string popup_text = c->SendCommandHelpWindow(
|
||||
c,
|
||||
description,
|
||||
notes,
|
||||
example_format,
|
||||
examples_one, examples_two, examples_three,
|
||||
actionables,
|
||||
options,
|
||||
options_one, options_two, options_three
|
||||
);
|
||||
|
||||
popup_text = DialogueWindow::Table(popup_text);
|
||||
|
||||
c->SendPopupToClient(sep->arg[0], popup_text.c_str());
|
||||
c->Message(
|
||||
Chat::Yellow,
|
||||
fmt::format(
|
||||
"Use {} for information about race/class IDs.",
|
||||
Saylink::Silent("^classracelist")
|
||||
).c_str()
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
std::string arg1 = sep->arg[1];
|
||||
|
||||
if (!arg1.compare("listid") || !arg1.compare("listname")) {
|
||||
c->CastToBot()->SendSpellTypesWindow(c, sep->arg[0], sep->arg[1], sep->arg[2]);
|
||||
return;
|
||||
}
|
||||
|
||||
int ab_arg = 1;
|
||||
bool current_check = false;
|
||||
uint32 typeValue = 0;
|
||||
|
||||
if (sep->IsNumber(1)) {
|
||||
typeValue = atoi(sep->arg[1]);
|
||||
++ab_arg;
|
||||
if (typeValue < 0 || typeValue > 1) {
|
||||
c->Message(Chat::Yellow, "You must enter either 0 for disabled or 1 for enabled.");
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (!arg1.compare("current")) {
|
||||
++ab_arg;
|
||||
current_check = true;
|
||||
}
|
||||
else {
|
||||
c->Message(
|
||||
Chat::Yellow,
|
||||
fmt::format(
|
||||
"Incorrect argument, use {} for information regarding this command.",
|
||||
Saylink::Silent(
|
||||
fmt::format("{} help", sep->arg[0])
|
||||
)
|
||||
).c_str()
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const int ab_mask = ActionableBots::ABM_Type1;
|
||||
std::string class_race_arg = sep->arg[ab_arg];
|
||||
bool class_race_check = false;
|
||||
if (!class_race_arg.compare("byclass") || !class_race_arg.compare("byrace")) {
|
||||
class_race_check = true;
|
||||
}
|
||||
|
||||
std::list<Bot*> sbl;
|
||||
if (ActionableBots::PopulateSBL(c, sep->arg[ab_arg], sbl, ab_mask, !class_race_check ? sep->arg[ab_arg + 1] : nullptr, class_race_check ? atoi(sep->arg[ab_arg + 1]) : 0) == ActionableBots::ABT_None) {
|
||||
return;
|
||||
}
|
||||
|
||||
sbl.remove(nullptr);
|
||||
|
||||
Bot* first_found = nullptr;
|
||||
int success_count = 0;
|
||||
for (auto my_bot : sbl) {
|
||||
if (!first_found) {
|
||||
first_found = my_bot;
|
||||
}
|
||||
if (current_check) {
|
||||
c->Message(
|
||||
Chat::Green,
|
||||
fmt::format(
|
||||
"{} says, 'I {} stay behind mobs.'",
|
||||
my_bot->GetCleanName(),
|
||||
my_bot->GetBehindMob() ? "will" : "will not"
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
else {
|
||||
my_bot->SetBehindMob(typeValue);
|
||||
++success_count;
|
||||
}
|
||||
}
|
||||
if (!current_check) {
|
||||
if (success_count == 1 && first_found) {
|
||||
c->Message(
|
||||
Chat::Green,
|
||||
fmt::format(
|
||||
"{} says, 'I {} stay behind mobs.'",
|
||||
first_found->GetCleanName(),
|
||||
first_found->GetBehindMob() ? "will now" : "will no longer"
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
else {
|
||||
c->Message(
|
||||
Chat::Green,
|
||||
fmt::format(
|
||||
"{} of your bots {} stay behind mobs.",
|
||||
success_count,
|
||||
typeValue ? "will now" : "will no longer"
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,7 @@ void bot_command_bind_affinity(Client *c, const Seperator *sep)
|
||||
return;
|
||||
if (helper_is_help_or_usage(sep->arg[1])) {
|
||||
c->Message(Chat::White, "usage: (<friendly_target>) %s", sep->arg[0]);
|
||||
c->Message(Chat::White, "note: Orders a bot to attempt an affinity binding", sep->arg[0]);
|
||||
helper_send_usage_required_bots(c, BCEnum::SpT_BindAffinity);
|
||||
return;
|
||||
}
|
||||
|
||||
+212
-161
@@ -18,7 +18,7 @@ void bot_command_bot(Client *c, const Seperator *sep)
|
||||
subcommand_list.push_back("botstance");
|
||||
subcommand_list.push_back("botstopmeleelevel");
|
||||
subcommand_list.push_back("botsummon");
|
||||
subcommand_list.push_back("bottogglearcher");
|
||||
subcommand_list.push_back("bottoggleranged");
|
||||
subcommand_list.push_back("bottogglehelm");
|
||||
subcommand_list.push_back("botupdate");
|
||||
|
||||
@@ -33,7 +33,7 @@ void bot_command_camp(Client *c, const Seperator *sep)
|
||||
if (helper_command_alias_fail(c, "bot_command_camp", sep->arg[0], "botcamp"))
|
||||
return;
|
||||
if (helper_is_help_or_usage(sep->arg[1])) {
|
||||
c->Message(Chat::White, "usage: %s ([actionable: target | byname | ownergroup | ownerraid | targetgroup | namesgroup | healrotationtargets | byclass | byrace | spawned] ([actionable_name]))", sep->arg[0]);
|
||||
c->Message(Chat::White, "usage: %s ([actionable: target | byname | ownergroup | ownerraid | targetgroup | namesgroup | healrotationtargets | mmr | byclass | byrace | spawned] ([actionable_name]))", sep->arg[0]);
|
||||
return;
|
||||
}
|
||||
const int ab_mask = ActionableBots::ABM_Type1;
|
||||
@@ -452,8 +452,8 @@ void bot_command_follow_distance(Client *c, const Seperator *sep)
|
||||
if (helper_command_alias_fail(c, "bot_command_follow_distance", sep->arg[0], "botfollowdistance"))
|
||||
return;
|
||||
if (helper_is_help_or_usage(sep->arg[1])) {
|
||||
c->Message(Chat::White, "usage: %s [set] [distance] ([actionable: target | byname | ownergroup | targetgroup | namesgroup | healrotation | spawned] ([actionable_name]))", sep->arg[0]);
|
||||
c->Message(Chat::White, "usage: %s [clear] ([actionable: target | byname | ownergroup | targetgroup | namesgroup | healrotation | spawned] ([actionable_name]))", sep->arg[0]);
|
||||
c->Message(Chat::White, "usage: %s [set [1 to %i]] [distance] ([actionable: target | byname | ownergroup | ownerraid | targetgroup | namesgroup | healrotationmembers | healrotationtargets | mmr | byclass | byrace | spawned] ([actionable_name]))", sep->arg[0], BOT_FOLLOW_DISTANCE_DEFAULT_MAX);
|
||||
c->Message(Chat::White, "usage: %s [clear] ([actionable: target | byname | ownergroup | ownerraid | targetgroup | namesgroup | healrotationmembers | healrotationtargets | mmr | byclass | byrace | spawned] ([actionable_name]))", sep->arg[0]);
|
||||
return;
|
||||
}
|
||||
const int ab_mask = ActionableBots::ABM_NoFilter;
|
||||
@@ -464,7 +464,7 @@ void bot_command_follow_distance(Client *c, const Seperator *sep)
|
||||
|
||||
if (!strcasecmp(sep->arg[1], "set")) {
|
||||
if (!sep->IsNumber(2)) {
|
||||
c->Message(Chat::White, "A numeric [distance] is required to use this command");
|
||||
c->Message(Chat::White, "A numeric [distance] is required to use this command. [1 to %i]", BOT_FOLLOW_DISTANCE_DEFAULT_MAX);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -492,22 +492,15 @@ void bot_command_follow_distance(Client *c, const Seperator *sep)
|
||||
continue;
|
||||
|
||||
bot_iter->SetFollowDistance(bfd);
|
||||
if (ab_type != ActionableBots::ABT_All && !database.botdb.SaveFollowDistance(bot_iter->GetBotID(), bfd)) {
|
||||
return;
|
||||
}
|
||||
|
||||
++bot_count;
|
||||
}
|
||||
|
||||
if (ab_type == ActionableBots::ABT_All) {
|
||||
if (!database.botdb.SaveAllFollowDistances(c->CharacterID(), bfd)) {
|
||||
return;
|
||||
}
|
||||
|
||||
c->Message(Chat::White, "%s all of your bot follow distances", set_flag ? "Set" : "Cleared");
|
||||
c->Message(Chat::White, "%s all of your bot follow distances to %i", set_flag ? "Set" : "Cleared", bfd);
|
||||
}
|
||||
else {
|
||||
c->Message(Chat::White, "%s %i of your spawned bot follow distances", (set_flag ? "Set" : "Cleared"), bot_count);
|
||||
c->Message(Chat::White, "%s %i of your spawned bot follow distances to %i", (set_flag ? "Set" : "Cleared"), bot_count, bfd);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -516,7 +509,7 @@ void bot_command_inspect_message(Client *c, const Seperator *sep)
|
||||
if (helper_command_alias_fail(c, "bot_command_inspect_message", sep->arg[0], "botinspectmessage"))
|
||||
return;
|
||||
if (helper_is_help_or_usage(sep->arg[1])) {
|
||||
c->Message(Chat::White, "usage: %s [set | clear] ([actionable: target | byname | ownergroup | targetgroup | namesgroup | healrotation | spawned] ([actionable_name]))", sep->arg[0]);
|
||||
c->Message(Chat::White, "usage: %s [set | clear] ([actionable: target | byname | ownergroup | ownerraid | targetgroup | namesgroup | healrotationmembers | healrotationtargets | mmr | byclass | byrace | spawned] ([actionable_name]))", sep->arg[0]);
|
||||
c->Message(Chat::White, "Notes:");
|
||||
if (c->ClientVersion() >= EQ::versions::ClientVersion::SoF) {
|
||||
c->Message(Chat::White, "- Self-inspect and type your bot's inspect message");
|
||||
@@ -764,75 +757,31 @@ void bot_command_list_bots(Client *c, const Seperator *sep)
|
||||
}
|
||||
}
|
||||
|
||||
void bot_command_out_of_combat(Client *c, const Seperator *sep)
|
||||
{
|
||||
if (helper_command_alias_fail(c, "bot_command_out_of_combat", sep->arg[0], "botoutofcombat"))
|
||||
return;
|
||||
if (helper_is_help_or_usage(sep->arg[1])) {
|
||||
c->Message(Chat::White, "usage: %s ([option: on | off]) ([actionable: target | byname] ([actionable_name]))", sep->arg[0]);
|
||||
return;
|
||||
}
|
||||
const int ab_mask = (ActionableBots::ABM_Target | ActionableBots::ABM_ByName);
|
||||
|
||||
std::string arg1 = sep->arg[1];
|
||||
|
||||
bool behavior_state = false;
|
||||
bool toggle_behavior = true;
|
||||
int ab_arg = 1;
|
||||
if (!arg1.compare("on")) {
|
||||
behavior_state = true;
|
||||
toggle_behavior = false;
|
||||
ab_arg = 2;
|
||||
}
|
||||
else if (!arg1.compare("off")) {
|
||||
toggle_behavior = false;
|
||||
ab_arg = 2;
|
||||
}
|
||||
|
||||
std::list<Bot*> sbl;
|
||||
if (ActionableBots::PopulateSBL(c, sep->arg[ab_arg], sbl, ab_mask, sep->arg[(ab_arg + 1)]) == ActionableBots::ABT_None)
|
||||
return;
|
||||
|
||||
for (auto bot_iter : sbl) {
|
||||
if (!bot_iter)
|
||||
continue;
|
||||
|
||||
if (toggle_behavior)
|
||||
bot_iter->SetAltOutOfCombatBehavior(!bot_iter->GetAltOutOfCombatBehavior());
|
||||
else
|
||||
bot_iter->SetAltOutOfCombatBehavior(behavior_state);
|
||||
|
||||
helper_bot_out_of_combat(c, bot_iter);
|
||||
}
|
||||
}
|
||||
|
||||
void bot_command_report(Client *c, const Seperator *sep)
|
||||
{
|
||||
if (helper_command_alias_fail(c, "bot_command_report", sep->arg[0], "botreport"))
|
||||
return;
|
||||
if (helper_is_help_or_usage(sep->arg[1])) {
|
||||
c->Message(Chat::White, "usage: %s ([actionable: target | byname | ownergroup | targetgroup | namesgroup | healrotation | spawned] ([actionable_name]))", sep->arg[0]);
|
||||
c->Message(Chat::White, "usage: %s ([actionable: target | byname | ownergroup | ownerraid | targetgroup | namesgroup | healrotationmembers | healrotationtargets | mmr | byclass | byrace | spawned] ([actionable_name]))", sep->arg[0]);
|
||||
return;
|
||||
}
|
||||
const int ab_mask = ActionableBots::ABM_NoFilter;
|
||||
|
||||
const int ab_mask = ActionableBots::ABM_Type1;
|
||||
|
||||
std::string ab_type_arg = sep->arg[1];
|
||||
if (ab_type_arg.empty()) {
|
||||
auto t = c->GetTarget();
|
||||
if (t && t->IsClient()) {
|
||||
if (t->CastToClient() == c) {
|
||||
ab_type_arg = "ownergroup";
|
||||
} else {
|
||||
ab_type_arg = "targetgroup";
|
||||
}
|
||||
} else {
|
||||
ab_type_arg = "spawned";
|
||||
}
|
||||
std::string arg1 = sep->arg[1];
|
||||
int ab_arg = 1;
|
||||
|
||||
std::string class_race_arg = sep->arg[ab_arg];
|
||||
bool class_race_check = false;
|
||||
|
||||
if (!class_race_arg.compare("byclass") || !class_race_arg.compare("byrace")) {
|
||||
class_race_check = true;
|
||||
}
|
||||
|
||||
std::list<Bot*> sbl;
|
||||
if (ActionableBots::PopulateSBL(c, ab_type_arg, sbl, ab_mask, sep->arg[2]) == ActionableBots::ABT_None)
|
||||
if (ActionableBots::PopulateSBL(c, sep->arg[ab_arg], sbl, ab_mask, !class_race_check ? sep->arg[ab_arg + 1] : nullptr, class_race_check ? atoi(sep->arg[ab_arg + 1]) : 0) == ActionableBots::ABT_None) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto bot_iter : sbl) {
|
||||
if (!bot_iter)
|
||||
@@ -1062,65 +1011,74 @@ void bot_command_spawn(Client *c, const Seperator *sep)
|
||||
|
||||
void bot_command_stance(Client *c, const Seperator *sep)
|
||||
{
|
||||
if (helper_command_alias_fail(c, "bot_command_stance", sep->arg[0], "botstance"))
|
||||
if (helper_command_alias_fail(c, "bot_command_stance", sep->arg[0], "botstance")) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (helper_is_help_or_usage(sep->arg[1])) {
|
||||
c->Message(Chat::White, "usage: %s [current | value: 1-9] ([actionable: target | byname] ([actionable_name]))", sep->arg[0]);
|
||||
c->Message(Chat::White, "usage: %s [current | value: 1-9] ([actionable: target | byname | ownergroup | ownerraid | targetgroup | namesgroup | healrotationtargets | mmr | byclass | byrace | spawned] ([actionable_name]))", sep->arg[0]);
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Value: {} ({}), {} ({}), {} ({}), {} ({}), {} ({}), {} ({}), {} ({}), {} ({}), {} ({})",
|
||||
"Value: {} ({}), {} ({}), {} ({})",
|
||||
Stance::Passive,
|
||||
Stance::GetName(Stance::Passive),
|
||||
Stance::Balanced,
|
||||
Stance::GetName(Stance::Balanced),
|
||||
Stance::Efficient,
|
||||
Stance::GetName(Stance::Efficient),
|
||||
Stance::Reactive,
|
||||
Stance::GetName(Stance::Reactive),
|
||||
Stance::Aggressive,
|
||||
Stance::GetName(Stance::Aggressive),
|
||||
Stance::Assist,
|
||||
Stance::GetName(Stance::Assist),
|
||||
Stance::Burn,
|
||||
Stance::GetName(Stance::Burn),
|
||||
Stance::Efficient2,
|
||||
Stance::GetName(Stance::Efficient2),
|
||||
Stance::AEBurn,
|
||||
Stance::GetName(Stance::AEBurn)
|
||||
Stance::GetName(Stance::Aggressive)
|
||||
).c_str()
|
||||
);
|
||||
return;
|
||||
}
|
||||
int ab_mask = (ActionableBots::ABM_Target | ActionableBots::ABM_ByName);
|
||||
|
||||
bool current_flag = false;
|
||||
uint8 bst = Stance::Unknown;
|
||||
const int ab_mask = ActionableBots::ABM_Type1;
|
||||
|
||||
if (!strcasecmp(sep->arg[1], "current"))
|
||||
current_flag = true;
|
||||
else if (sep->IsNumber(1)) {
|
||||
bst = static_cast<uint8>(Strings::ToUnsignedInt(sep->arg[1]));
|
||||
if (!Stance::IsValid(bst)) {
|
||||
bst = Stance::Unknown;
|
||||
std::string arg1 = sep->arg[1];
|
||||
int ab_arg = 1;
|
||||
bool current_check = false;
|
||||
uint32 value = 0;
|
||||
|
||||
if (sep->IsNumber(1)) {
|
||||
++ab_arg;
|
||||
value = atoi(sep->arg[1]);
|
||||
if (value < 0 || value > 300) {
|
||||
c->Message(Chat::White, "You must enter a value within the range of 0 - 300.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!current_flag && bst == Stance::Unknown) {
|
||||
c->Message(Chat::White, "A [current] argument or valid numeric [value] is required to use this command");
|
||||
else if (!arg1.compare("current")) {
|
||||
++ab_arg;
|
||||
current_check = true;
|
||||
}
|
||||
else {
|
||||
c->Message(Chat::White, "Incorrect argument, use %s help for a list of options.", sep->arg[0]);
|
||||
return;
|
||||
}
|
||||
|
||||
std::string class_race_arg = sep->arg[ab_arg];
|
||||
bool class_race_check = false;
|
||||
|
||||
if (!class_race_arg.compare("byclass") || !class_race_arg.compare("byrace")) {
|
||||
class_race_check = true;
|
||||
}
|
||||
|
||||
std::list<Bot*> sbl;
|
||||
if (ActionableBots::PopulateSBL(c, sep->arg[2], sbl, ab_mask, sep->arg[3]) == ActionableBots::ABT_None)
|
||||
if (ActionableBots::PopulateSBL(c, sep->arg[ab_arg], sbl, ab_mask, !class_race_check ? sep->arg[ab_arg + 1] : nullptr, class_race_check ? atoi(sep->arg[ab_arg + 1]) : 0) == ActionableBots::ABT_None) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!current_check && (value == Stance::Unknown || (value != Stance::Passive && value != Stance::Balanced && value != Stance::Aggressive))) {
|
||||
c->Message(Chat::White, "A [current] argument or valid numeric [value] is required to use this command");
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto bot_iter : sbl) {
|
||||
if (!bot_iter)
|
||||
continue;
|
||||
|
||||
if (!current_flag) {
|
||||
bot_iter->SetBotStance(bst);
|
||||
if (!current_check) {
|
||||
bot_iter->SetBotStance(value);
|
||||
bot_iter->Save();
|
||||
}
|
||||
|
||||
@@ -1135,50 +1093,138 @@ void bot_command_stance(Client *c, const Seperator *sep)
|
||||
}
|
||||
}
|
||||
|
||||
void bot_command_stop_melee_level(Client *c, const Seperator *sep)
|
||||
void bot_command_stop_melee_level(Client* c, const Seperator* sep)
|
||||
{
|
||||
if (helper_command_alias_fail(c, "bot_command_stop_melee_level", sep->arg[0], "botstopmeleelevel"))
|
||||
if (helper_command_alias_fail(c, "bot_command_stop_melee_level", sep->arg[0], "botstopmeleelevel")) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (helper_is_help_or_usage(sep->arg[1])) {
|
||||
c->Message(Chat::White, "usage: <target_bot> %s [current | reset | sync | value: 0-255]", sep->arg[0]);
|
||||
c->Message(Chat::White, "usage: %s [current | reset | sync | value: 0-255] ([actionable: target | byname | ownergroup | ownerraid | targetgroup | namesgroup | mmr | byclass | byrace | spawned] ([actionable_name]))", sep->arg[0]);
|
||||
c->Message(Chat::White, "note: Only caster or hybrid class bots may be modified");
|
||||
c->Message(Chat::White, "note: Use [reset] to set stop melee level to server rule");
|
||||
c->Message(Chat::White, "note: Use [sync] to set stop melee level to current bot level");
|
||||
return;
|
||||
}
|
||||
|
||||
auto my_bot = ActionableBots::AsTarget_ByBot(c);
|
||||
if (!my_bot) {
|
||||
c->Message(Chat::White, "You must <target> a bot that you own to use this command");
|
||||
return;
|
||||
}
|
||||
if (!IsCasterClass(my_bot->GetClass()) && !IsHybridClass(my_bot->GetClass())) {
|
||||
c->Message(Chat::White, "You must <target> a caster or hybrid class bot to use this command");
|
||||
return;
|
||||
}
|
||||
const int ab_mask = ActionableBots::ABM_Type1;
|
||||
|
||||
std::string arg1 = sep->arg[1];
|
||||
int ab_arg = 1;
|
||||
uint8 sml = RuleI(Bots, CasterStopMeleeLevel);
|
||||
bool sync_sml = false;
|
||||
bool reset_sml = false;
|
||||
bool current_check = false;
|
||||
|
||||
if (sep->IsNumber(1)) {
|
||||
ab_arg = 2;
|
||||
sml = Strings::ToInt(sep->arg[1]);
|
||||
if (sml <= 0 || sml > 255) {
|
||||
c->Message(Chat::White, "You must provide a value between 0-255.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (!strcasecmp(sep->arg[1], "sync")) {
|
||||
sml = my_bot->GetLevel();
|
||||
ab_arg = 2;
|
||||
sync_sml = true;
|
||||
}
|
||||
else if (!strcasecmp(sep->arg[1], "current")) {
|
||||
c->Message(Chat::White, "My current melee stop level is %u", my_bot->GetStopMeleeLevel());
|
||||
else if (!arg1.compare("current")) {
|
||||
ab_arg = 2;
|
||||
current_check = true;
|
||||
}
|
||||
else if (!strcasecmp(sep->arg[1], "reset")) {
|
||||
ab_arg = 2;
|
||||
reset_sml = true;
|
||||
}
|
||||
else {
|
||||
c->Message(Chat::White, "Incorrect argument, use %s help for a list of options.", sep->arg[0]);
|
||||
return;
|
||||
}
|
||||
else if (strcasecmp(sep->arg[1], "reset")) {
|
||||
c->Message(Chat::White, "A [current] or [reset] argument, or numeric [value] is required to use this command");
|
||||
|
||||
std::string class_race_arg = sep->arg[ab_arg];
|
||||
bool class_race_check = false;
|
||||
|
||||
if (!class_race_arg.compare("byclass") || !class_race_arg.compare("byrace")) {
|
||||
class_race_check = true;
|
||||
}
|
||||
|
||||
std::list<Bot*> sbl;
|
||||
|
||||
if (ActionableBots::PopulateSBL(c, sep->arg[ab_arg], sbl, ab_mask, !class_race_check ? sep->arg[ab_arg + 1] : nullptr, class_race_check ? atoi(sep->arg[ab_arg + 1]) : 0) == ActionableBots::ABT_None) {
|
||||
return;
|
||||
}
|
||||
// [reset] falls through with initialization value
|
||||
|
||||
my_bot->SetStopMeleeLevel(sml);
|
||||
database.botdb.SaveStopMeleeLevel(my_bot->GetBotID(), sml);
|
||||
sbl.remove(nullptr);
|
||||
|
||||
c->Message(Chat::White, "Successfully set stop melee level for %s to %u", my_bot->GetCleanName(), sml);
|
||||
Bot* first_found = nullptr;
|
||||
int success_count = 0;
|
||||
|
||||
for (auto my_bot : sbl) {
|
||||
if (!IsCasterClass(my_bot->GetClass()) && !IsHybridClass(my_bot->GetClass())) {
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"{} says, 'This command only works on caster or hybrid classes.'",
|
||||
my_bot->GetCleanName()
|
||||
).c_str()
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!first_found) {
|
||||
first_found = my_bot;
|
||||
}
|
||||
|
||||
if (sync_sml) {
|
||||
sml = my_bot->GetLevel();
|
||||
}
|
||||
|
||||
if (reset_sml) {
|
||||
sml = my_bot->GetDefaultBotBaseSetting(BotBaseSettings::StopMeleeLevel);
|
||||
}
|
||||
|
||||
if (current_check) {
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"{} says, 'My current stop melee level is {}.'",
|
||||
my_bot->GetCleanName(),
|
||||
my_bot->GetStopMeleeLevel()
|
||||
).c_str()
|
||||
);
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
my_bot->SetStopMeleeLevel(sml);
|
||||
++success_count;
|
||||
}
|
||||
}
|
||||
|
||||
if (!current_check) {
|
||||
if (success_count == 1 && first_found) {
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"{} says, 'My stop melee level was {} to {}.'",
|
||||
first_found->GetCleanName(),
|
||||
reset_sml ? "reset" : "set",
|
||||
sml
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
else {
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"{} of your bots {} their stop melee{}'", // level to {}.
|
||||
success_count,
|
||||
reset_sml ? "reset" : "set",
|
||||
fmt::format("{}", reset_sml ? "." : fmt::format(" level to {}.", sml).c_str()).c_str(),
|
||||
sml
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void bot_command_summon(Client *c, const Seperator *sep)
|
||||
@@ -1188,19 +1234,24 @@ void bot_command_summon(Client *c, const Seperator *sep)
|
||||
}
|
||||
|
||||
if (helper_is_help_or_usage(sep->arg[1])) {
|
||||
c->Message(Chat::White, "usage: %s ([actionable: target | byname | ownergroup | ownerraid | targetgroup | namesgroup | healrotationtargets | byclass | byrace | spawned] ([actionable_name]))", sep->arg[0]);
|
||||
c->Message(Chat::White, "usage: %s ([actionable: target | byname | ownergroup | ownerraid | targetgroup | namesgroup | healrotationtargets | mmr | byclass | byrace | spawned] ([actionable_name]))", sep->arg[0]);
|
||||
return;
|
||||
}
|
||||
|
||||
const int ab_mask = ActionableBots::ABM_Type1;
|
||||
|
||||
std::string class_race_arg = sep->arg[1];
|
||||
std::string arg1 = sep->arg[1];
|
||||
int ab_arg = 1;
|
||||
|
||||
std::string class_race_arg = sep->arg[ab_arg];
|
||||
bool class_race_check = false;
|
||||
|
||||
if (!class_race_arg.compare("byclass") || !class_race_arg.compare("byrace")) {
|
||||
class_race_check = true;
|
||||
}
|
||||
|
||||
std::list<Bot*> sbl;
|
||||
if (ActionableBots::PopulateSBL(c, sep->arg[1], sbl, ab_mask, !class_race_check ? sep->arg[2] : nullptr, class_race_check ? atoi(sep->arg[2]) : 0) == ActionableBots::ABT_None) {
|
||||
if (ActionableBots::PopulateSBL(c, sep->arg[ab_arg], sbl, ab_mask, !class_race_check ? sep->arg[ab_arg + 1] : nullptr, class_race_check ? atoi(sep->arg[ab_arg + 1]) : 0) == ActionableBots::ABT_None) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1245,34 +1296,44 @@ void bot_command_summon(Client *c, const Seperator *sep)
|
||||
}
|
||||
}
|
||||
|
||||
void bot_command_toggle_archer(Client *c, const Seperator *sep)
|
||||
void bot_command_toggle_ranged(Client *c, const Seperator *sep)
|
||||
{
|
||||
if (helper_command_alias_fail(c, "bot_command_toggle_archer", sep->arg[0], "bottogglearcher")) {
|
||||
if (helper_command_alias_fail(c, "bot_command_toggle_ranged", sep->arg[0], "bottoggleranged")) {
|
||||
return;
|
||||
}
|
||||
if (helper_is_help_or_usage(sep->arg[1])) {
|
||||
c->Message(Chat::White, "usage: %s ([option: on | off]) ([actionable: target | byname] ([actionable_name]))", sep->arg[0]);
|
||||
c->Message(Chat::White, "usage: %s ([option: on | off]) ([actionable: target | byname | ownergroup | ownerraid | targetgroup | namesgroup | healrotationtargets | mmr | byclass | byrace | spawned] ([actionable_name]))", sep->arg[0]);
|
||||
c->Message(Chat::White, "note: Toggles a ranged bot between melee and ranged weapon use");
|
||||
return;
|
||||
}
|
||||
const int ab_mask = (ActionableBots::ABM_Target | ActionableBots::ABM_ByName);
|
||||
|
||||
const int ab_mask = ActionableBots::ABM_Type1;
|
||||
|
||||
std::string arg1 = sep->arg[1];
|
||||
|
||||
bool archer_state = false;
|
||||
bool toggle_archer = true;
|
||||
bool ranged_state = false;
|
||||
bool toggle_ranged = true;
|
||||
int ab_arg = 1;
|
||||
if (!arg1.compare("on")) {
|
||||
archer_state = true;
|
||||
toggle_archer = false;
|
||||
ab_arg = 2;
|
||||
ranged_state = true;
|
||||
toggle_ranged = false;
|
||||
++ab_arg;
|
||||
}
|
||||
else if (!arg1.compare("off")) {
|
||||
toggle_archer = false;
|
||||
ab_arg = 2;
|
||||
toggle_ranged = false;
|
||||
++ab_arg;
|
||||
}
|
||||
|
||||
std::string class_race_arg = sep->arg[ab_arg];
|
||||
bool class_race_check = false;
|
||||
|
||||
if (!class_race_arg.compare("byclass") || !class_race_arg.compare("byrace")) {
|
||||
class_race_check = true;
|
||||
}
|
||||
|
||||
std::list<Bot*> sbl;
|
||||
if (ActionableBots::PopulateSBL(c, sep->arg[ab_arg], sbl, ab_mask, sep->arg[(ab_arg + 1)]) == ActionableBots::ABT_None) {
|
||||
|
||||
if (ActionableBots::PopulateSBL(c, sep->arg[ab_arg], sbl, ab_mask, !class_race_check ? sep->arg[ab_arg + 1] : nullptr, class_race_check ? atoi(sep->arg[ab_arg + 1]) : 0) == ActionableBots::ABT_None) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1281,17 +1342,18 @@ void bot_command_toggle_archer(Client *c, const Seperator *sep)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (toggle_archer) {
|
||||
bot_iter->SetBotArcherySetting(!bot_iter->IsBotArcher(), true);
|
||||
if (bot_iter->GetBotRangedValue() < RuleI(Combat, MinRangedAttackDist)) {
|
||||
c->Message(Chat::Yellow, "%s does not have proper weapons or ammo to be at range.", bot_iter->GetCleanName());
|
||||
continue;
|
||||
}
|
||||
|
||||
if (toggle_ranged) {
|
||||
bot_iter->SetBotRangedSetting(!bot_iter->IsBotRanged());
|
||||
}
|
||||
else {
|
||||
bot_iter->SetBotArcherySetting(archer_state, true);
|
||||
}
|
||||
bot_iter->ChangeBotArcherWeapons(bot_iter->IsBotArcher());
|
||||
|
||||
if (bot_iter->GetClass() == Class::Ranger && bot_iter->GetLevel() >= 61) {
|
||||
bot_iter->SetRangerAutoWeaponSelect(bot_iter->IsBotArcher());
|
||||
bot_iter->SetBotRangedSetting(ranged_state);
|
||||
}
|
||||
bot_iter->ChangeBotRangedWeapons(bot_iter->IsBotRanged());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1300,7 +1362,7 @@ void bot_command_toggle_helm(Client *c, const Seperator *sep)
|
||||
if (helper_command_alias_fail(c, "bot_command_toggle_helm", sep->arg[0], "bottogglehelm"))
|
||||
return;
|
||||
if (helper_is_help_or_usage(sep->arg[1])) {
|
||||
c->Message(Chat::White, "usage: %s ([option: on | off]) ([actionable: target | byname | ownergroup | targetgroup | namesgroup | healrotation | spawned] ([actionable_name]))", sep->arg[0]);
|
||||
c->Message(Chat::White, "usage: %s ([option: on | off]) ([actionable: target | byname | ownergroup | ownerraid | targetgroup | namesgroup | healrotationmembers | healrotationtargets | mmr | byclass | byrace | spawned] ([actionable_name]))", sep->arg[0]);
|
||||
return;
|
||||
}
|
||||
const int ab_mask = ActionableBots::ABM_NoFilter;
|
||||
@@ -1313,11 +1375,11 @@ void bot_command_toggle_helm(Client *c, const Seperator *sep)
|
||||
if (!arg1.compare("on")) {
|
||||
helm_state = true;
|
||||
toggle_helm = false;
|
||||
ab_arg = 2;
|
||||
++ab_arg;
|
||||
}
|
||||
else if (!arg1.compare("off")) {
|
||||
toggle_helm = false;
|
||||
ab_arg = 2;
|
||||
++ab_arg;
|
||||
}
|
||||
|
||||
std::list<Bot*> sbl;
|
||||
@@ -1336,9 +1398,6 @@ void bot_command_toggle_helm(Client *c, const Seperator *sep)
|
||||
bot_iter->SetShowHelm(helm_state);
|
||||
|
||||
if (ab_type != ActionableBots::ABT_All) {
|
||||
if (!database.botdb.SaveHelmAppearance(bot_iter->GetBotID(), bot_iter->GetShowHelm())) {
|
||||
return;
|
||||
}
|
||||
|
||||
EQApplicationPacket* outapp = new EQApplicationPacket(OP_SpawnAppearance, sizeof(SpawnAppearance_Struct));
|
||||
SpawnAppearance_Struct* saptr = (SpawnAppearance_Struct*)outapp->pBuffer;
|
||||
@@ -1355,13 +1414,6 @@ void bot_command_toggle_helm(Client *c, const Seperator *sep)
|
||||
}
|
||||
|
||||
if (ab_type == ActionableBots::ABT_All) {
|
||||
if (toggle_helm) {
|
||||
database.botdb.ToggleAllHelmAppearances(c->CharacterID());
|
||||
}
|
||||
else {
|
||||
database.botdb.SaveAllHelmAppearances(c->CharacterID(), helm_state);
|
||||
}
|
||||
|
||||
c->Message(Chat::White, "%s all of your bot show helm flags", toggle_helm ? "Toggled" : (helm_state ? "Set" : "Cleared"));
|
||||
}
|
||||
else {
|
||||
@@ -1439,7 +1491,6 @@ void bot_command_update(Client *c, const Seperator *sep)
|
||||
if (!bot_iter || bot_iter->IsEngaged() || bot_iter->GetLevel() == c->GetLevel())
|
||||
continue;
|
||||
|
||||
bot_iter->SetPetChooser(false);
|
||||
bot_iter->CalcBotStats(c->GetBotOption(Client::booStatsUpdate));
|
||||
bot_iter->SendAppearancePacket(AppearanceType::WhoLevel, bot_iter->GetLevel(), true, true);
|
||||
++bot_count;
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
#include "../bot_command.h"
|
||||
|
||||
void bot_command_bot_settings(Client* c, const Seperator* sep)
|
||||
{
|
||||
std::list<const char*> subcommand_list;
|
||||
subcommand_list.push_back("behindmob");
|
||||
subcommand_list.push_back("casterrange");
|
||||
subcommand_list.push_back("copysettings");
|
||||
subcommand_list.push_back("defaultsettings");
|
||||
subcommand_list.push_back("enforcespelllist");
|
||||
subcommand_list.push_back("follow");
|
||||
subcommand_list.push_back("followdistance");
|
||||
subcommand_list.push_back("illusionblock");
|
||||
subcommand_list.push_back("maxmeleerange");
|
||||
subcommand_list.push_back("owneroption");
|
||||
subcommand_list.push_back("petsettype");
|
||||
subcommand_list.push_back("sithppercent");
|
||||
subcommand_list.push_back("sitincombat");
|
||||
subcommand_list.push_back("sitmanapercent");
|
||||
subcommand_list.push_back("sithppercent");
|
||||
subcommand_list.push_back("spellaggrocheck");
|
||||
subcommand_list.push_back("spelldelays");
|
||||
subcommand_list.push_back("spellengagedpriority");
|
||||
subcommand_list.push_back("spellholds");
|
||||
subcommand_list.push_back("spellidlepriority");
|
||||
subcommand_list.push_back("spellmaxhppct");
|
||||
subcommand_list.push_back("spellmaxmanapct");
|
||||
subcommand_list.push_back("spellmaxthresholds");
|
||||
subcommand_list.push_back("spellminhppct");
|
||||
subcommand_list.push_back("spellminmanapct");
|
||||
subcommand_list.push_back("spellminthresholds");
|
||||
subcommand_list.push_back("spellpursuepriority");
|
||||
subcommand_list.push_back("spelltargetcount");
|
||||
subcommand_list.push_back("spelllist");
|
||||
subcommand_list.push_back("stance");
|
||||
subcommand_list.push_back("togglehelm");
|
||||
subcommand_list.push_back("bottoggleranged");
|
||||
|
||||
if (helper_command_alias_fail(c, "bot_command_bot_settings", sep->arg[0], "botsettings"))
|
||||
return;
|
||||
|
||||
helper_send_available_subcommands(c, "botsettings", subcommand_list);
|
||||
}
|
||||
@@ -0,0 +1,301 @@
|
||||
#include "../bot_command.h"
|
||||
|
||||
void bot_command_cast(Client* c, const Seperator* sep)
|
||||
{
|
||||
if (helper_is_help_or_usage(sep->arg[1])) {
|
||||
std::vector<std::string> description =
|
||||
{
|
||||
"Commands bots to force cast a specific spell type, ignoring all settings (holds, delays, thresholds, etc)"
|
||||
};
|
||||
|
||||
std::vector<std::string> notes =
|
||||
{
|
||||
"- This will interrupt any spell currently being cast by bots told to use the command.",
|
||||
"- Bots will still check to see if they have the spell in their spell list, whether the target is immune, spell is allowed and all other sanity checks for spells"
|
||||
};
|
||||
|
||||
std::vector<std::string> example_format =
|
||||
{
|
||||
fmt::format(
|
||||
"{} [Type Shortname] [actionable]"
|
||||
, sep->arg[0]
|
||||
),
|
||||
fmt::format(
|
||||
"{} [Type ID] [actionable]"
|
||||
, sep->arg[0]
|
||||
)
|
||||
};
|
||||
std::vector<std::string> examples_one =
|
||||
{
|
||||
"To tell everyone to Nuke the target:",
|
||||
fmt::format(
|
||||
"{} {} spawned",
|
||||
sep->arg[0],
|
||||
c->GetSpellTypeShortNameByID(BotSpellTypes::Nuke)
|
||||
),
|
||||
fmt::format(
|
||||
"{} {} spawned",
|
||||
sep->arg[0],
|
||||
BotSpellTypes::Nuke
|
||||
)
|
||||
};
|
||||
std::vector<std::string> examples_two =
|
||||
{
|
||||
"To tell all Enchanters to slow the target:",
|
||||
fmt::format(
|
||||
"{} {} byclass {}",
|
||||
sep->arg[0],
|
||||
Class::Enchanter,
|
||||
c->GetSpellTypeShortNameByID(BotSpellTypes::Slow)
|
||||
),
|
||||
fmt::format(
|
||||
"{} {} byclass {}",
|
||||
sep->arg[0],
|
||||
Class::Enchanter,
|
||||
BotSpellTypes::Slow
|
||||
)
|
||||
};
|
||||
std::vector<std::string> examples_three =
|
||||
{
|
||||
"To tell Clrbot to resurrect the targeted corpse:",
|
||||
fmt::format(
|
||||
"{} {} byname Clrbot",
|
||||
sep->arg[0],
|
||||
c->GetSpellTypeShortNameByID(BotSpellTypes::Resurrect)
|
||||
),
|
||||
fmt::format(
|
||||
"{} {} byname Clrbot",
|
||||
sep->arg[0],
|
||||
BotSpellTypes::Resurrect
|
||||
)
|
||||
};
|
||||
|
||||
std::vector<std::string> actionables =
|
||||
{
|
||||
"target, byname, ownergroup, ownerraid, targetgroup, namesgroup, healrotationtargets mmr, byclass, byrace, spawned"
|
||||
};
|
||||
|
||||
std::vector<std::string> options = { };
|
||||
std::vector<std::string> options_one = { };
|
||||
std::vector<std::string> options_two = { };
|
||||
std::vector<std::string> options_three = { };
|
||||
|
||||
std::string popup_text = c->SendCommandHelpWindow(
|
||||
c,
|
||||
description,
|
||||
notes,
|
||||
example_format,
|
||||
examples_one, examples_two, examples_three,
|
||||
actionables,
|
||||
options,
|
||||
options_one, options_two, options_three
|
||||
);
|
||||
|
||||
popup_text = DialogueWindow::Table(popup_text);
|
||||
|
||||
c->SendPopupToClient(sep->arg[0], popup_text.c_str());
|
||||
c->CastToBot()->SendSpellTypesWindow(c, sep->arg[0], "", "", true);
|
||||
c->Message(
|
||||
Chat::Yellow,
|
||||
fmt::format(
|
||||
"Use {} for information about race/class IDs.",
|
||||
Saylink::Silent("^classracelist")
|
||||
).c_str()
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
std::string arg1 = sep->arg[1];
|
||||
|
||||
if (!arg1.compare("listid") || !arg1.compare("listname")) {
|
||||
c->CastToBot()->SendSpellTypesWindow(c, sep->arg[0], sep->arg[1], sep->arg[2]);
|
||||
return;
|
||||
}
|
||||
|
||||
int ab_arg = 2;
|
||||
uint16 spellType = 0;
|
||||
|
||||
// String/Int type checks
|
||||
if (sep->IsNumber(1)) {
|
||||
spellType = atoi(sep->arg[1]);
|
||||
|
||||
if (spellType < BotSpellTypes::START || spellType > BotSpellTypes::END) {
|
||||
c->Message(Chat::Yellow, "You must choose a valid spell type. Spell types range from %i to %i", BotSpellTypes::START, BotSpellTypes::END);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (c->GetSpellTypeIDByShortName(arg1) != UINT16_MAX) {
|
||||
spellType = c->GetSpellTypeIDByShortName(arg1);
|
||||
}
|
||||
else {
|
||||
c->Message(
|
||||
Chat::Yellow,
|
||||
fmt::format(
|
||||
"Incorrect argument, use {} for information regarding this command.",
|
||||
Saylink::Silent(
|
||||
fmt::format("{} help", sep->arg[0])
|
||||
)
|
||||
).c_str()
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
spellType == BotSpellTypes::PetBuffs ||
|
||||
spellType == BotSpellTypes::PetCompleteHeals ||
|
||||
spellType == BotSpellTypes::PetFastHeals ||
|
||||
spellType == BotSpellTypes::PetHoTHeals ||
|
||||
spellType == BotSpellTypes::PetRegularHeals ||
|
||||
spellType == BotSpellTypes::PetVeryFastHeals
|
||||
) {
|
||||
c->Message(Chat::Yellow, "Pet type heals and buffs are not supported, use the regular spell type.");
|
||||
return;
|
||||
}
|
||||
|
||||
Mob* tar = c->GetTarget();
|
||||
LogTestDebug("{}: Attempting {} on {}", __LINE__, c->GetSpellTypeNameByID(spellType), (tar ? tar->GetCleanName() : "NOBODY")); //deleteme
|
||||
if (spellType != BotSpellTypes::Escape && spellType != BotSpellTypes::Pet) {
|
||||
if (!tar) {
|
||||
c->Message(Chat::Yellow, "You need a target for that.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (BOT_SPELL_TYPES_DETRIMENTAL(spellType) && !c->IsAttackAllowed(tar)) {
|
||||
c->Message(Chat::Yellow, "You cannot attack [%s].", tar->GetCleanName());
|
||||
return;
|
||||
}
|
||||
|
||||
if (BOT_SPELL_TYPES_BENEFICIAL(spellType)) {
|
||||
if (!tar->IsOfClientBot() && !(tar->IsPet() && tar->GetOwner() && tar->GetOwner()->IsOfClientBot())) {
|
||||
c->Message(Chat::Yellow, "[%s] is an invalid target.", tar->GetCleanName());
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
LogTestDebug("{}: Attempting {} on {}", __LINE__, c->GetSpellTypeNameByID(spellType), (tar ? tar->GetCleanName() : "NOBODY")); //deleteme
|
||||
switch (spellType) {
|
||||
case BotSpellTypes::Stun:
|
||||
case BotSpellTypes::AEStun:
|
||||
if (tar->GetSpecialAbility(SpecialAbility::StunImmunity)) {
|
||||
c->Message(Chat::Yellow, "[%s] is immune to stuns.", tar->GetCleanName());
|
||||
return;
|
||||
}
|
||||
|
||||
break;
|
||||
case BotSpellTypes::Resurrect:
|
||||
if (!tar->IsCorpse() || !tar->CastToCorpse()->IsPlayerCorpse()) {
|
||||
c->Message(Chat::Yellow, "[%s] is an invalid target. I can only resurrect player corpses.", tar->GetCleanName());
|
||||
return;
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
const int ab_mask = ActionableBots::ABM_Type1;
|
||||
std::string class_race_arg = sep->arg[ab_arg];
|
||||
bool class_race_check = false;
|
||||
|
||||
if (!class_race_arg.compare("byclass") || !class_race_arg.compare("byrace")) {
|
||||
class_race_check = true;
|
||||
}
|
||||
|
||||
std::list<Bot*> sbl;
|
||||
|
||||
if (ActionableBots::PopulateSBL(c, sep->arg[ab_arg], sbl, ab_mask, !class_race_check ? sep->arg[ab_arg + 1] : nullptr, class_race_check ? atoi(sep->arg[ab_arg + 1]) : 0) == ActionableBots::ABT_None) {
|
||||
return;
|
||||
}
|
||||
|
||||
sbl.remove(nullptr);
|
||||
|
||||
BotSpell botSpell;
|
||||
botSpell.SpellId = 0;
|
||||
botSpell.SpellIndex = 0;
|
||||
botSpell.ManaCost = 0;
|
||||
bool isSuccess = false;
|
||||
uint16 successCount = 0;
|
||||
Bot* firstFound = nullptr;
|
||||
|
||||
for (auto bot_iter : sbl) {
|
||||
if (!bot_iter->IsInGroupOrRaid()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
TODO bot rewrite -
|
||||
FIX: Snares, Group Cures, OOC Song, Precombat, HateRedux, Fear/AE Fear
|
||||
ICB (SK) casting hate on friendly but not hostile?
|
||||
NEED TO CHECK: precombat, AE Dispel, AE Lifetap
|
||||
DO I NEED A PBAE CHECK???
|
||||
*/
|
||||
if (bot_iter->GetHoldFlag() || bot_iter->GetAppearance() == eaDead || bot_iter->IsFeared() || bot_iter->IsStunned() || bot_iter->IsMezzed() || bot_iter->DivineAura() || bot_iter->GetHP() < 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Mob* newTar = tar;
|
||||
LogTestDebug("{}: Attempting {} on {}", __LINE__, c->GetSpellTypeNameByID(spellType), (newTar ? newTar->GetCleanName() : "NOBODY")); //deleteme
|
||||
if (!SpellTypeRequiresTarget(spellType, bot_iter->GetClass())) {
|
||||
newTar = bot_iter;
|
||||
}
|
||||
|
||||
if (!newTar) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (BOT_SPELL_TYPES_DETRIMENTAL(spellType, bot_iter->GetClass()) && !bot_iter->IsAttackAllowed(newTar)) {
|
||||
bot_iter->BotGroupSay(
|
||||
bot_iter,
|
||||
fmt::format(
|
||||
"I cannot attack [{}].",
|
||||
newTar->GetCleanName()
|
||||
).c_str()
|
||||
);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
LogTestDebug("{}: Attempting {} on {}", __LINE__, c->GetSpellTypeNameByID(spellType), (newTar ? newTar->GetCleanName() : "NOBODY")); //deleteme
|
||||
|
||||
bot_iter->SetCommandedSpell(true);
|
||||
|
||||
if (bot_iter->AICastSpell(newTar, 100, spellType)) {
|
||||
if (!firstFound) {
|
||||
firstFound = bot_iter;
|
||||
}
|
||||
|
||||
isSuccess = true;
|
||||
++successCount;
|
||||
}
|
||||
|
||||
bot_iter->SetCommandedSpell(false);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!isSuccess) {
|
||||
c->Message(
|
||||
Chat::Yellow,
|
||||
fmt::format(
|
||||
"No bots are capable of casting [{}] on {}.",
|
||||
c->GetSpellTypeNameByID(spellType),
|
||||
tar ? tar->GetCleanName() : "your target"
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
else {
|
||||
c->Message( Chat::Yellow,
|
||||
fmt::format(
|
||||
"{} {} [{}]{}",
|
||||
((successCount == 1 && firstFound) ? firstFound->GetCleanName() : (fmt::format("{}", successCount).c_str())),
|
||||
((successCount == 1 && firstFound) ? "casted" : "of your bots casted"),
|
||||
c->GetSpellTypeNameByID(spellType),
|
||||
tar ? (fmt::format(" on {}.", tar->GetCleanName()).c_str()) : "."
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,7 @@ void bot_command_caster_range(Client* c, const Seperator* sep)
|
||||
}
|
||||
|
||||
if (helper_is_help_or_usage(sep->arg[1])) {
|
||||
c->Message(Chat::White, "usage: %s [current | value: 0 - 300] ([actionable: target | byname | ownergroup | ownerraid | targetgroup | namesgroup | healrotationtargets | byclass | byrace | spawned] ([actionable_name]))", sep->arg[0]);
|
||||
c->Message(Chat::White, "usage: %s [current | value: 0 - 300] ([actionable: target | byname | ownergroup | ownerraid | targetgroup | namesgroup | healrotationtargets | mmr | byclass | byrace | spawned] ([actionable_name]))", sep->arg[0]);
|
||||
c->Message(Chat::White, "note: Can only be used for Casters or Hybrids.");
|
||||
c->Message(Chat::White, "note: Use [current] to check the current setting.");
|
||||
c->Message(Chat::White, "note: Set the value to the minimum distance you want your bot to try to remain from its target.");
|
||||
@@ -15,6 +15,7 @@ void bot_command_caster_range(Client* c, const Seperator* sep)
|
||||
c->Message(Chat::White, "note: This is set to (90) units by default.");
|
||||
return;
|
||||
}
|
||||
|
||||
const int ab_mask = ActionableBots::ABM_Type1;
|
||||
|
||||
std::string arg1 = sep->arg[1];
|
||||
@@ -23,7 +24,7 @@ void bot_command_caster_range(Client* c, const Seperator* sep)
|
||||
uint32 crange = 0;
|
||||
|
||||
if (sep->IsNumber(1)) {
|
||||
ab_arg = 2;
|
||||
++ab_arg;
|
||||
crange = atoi(sep->arg[1]);
|
||||
if (crange < 0 || crange > 300) {
|
||||
c->Message(Chat::White, "You must enter a value within the range of 0 - 300.");
|
||||
@@ -31,7 +32,7 @@ void bot_command_caster_range(Client* c, const Seperator* sep)
|
||||
}
|
||||
}
|
||||
else if (!arg1.compare("current")) {
|
||||
ab_arg = 2;
|
||||
++ab_arg;
|
||||
current_check = true;
|
||||
}
|
||||
else {
|
||||
@@ -78,8 +79,6 @@ void bot_command_caster_range(Client* c, const Seperator* sep)
|
||||
else {
|
||||
my_bot->SetBotCasterRange(crange);
|
||||
++success_count;
|
||||
|
||||
database.botdb.SaveBotCasterRange(my_bot->GetBotID(), crange);
|
||||
}
|
||||
}
|
||||
if (!current_check) {
|
||||
|
||||
@@ -0,0 +1,113 @@
|
||||
#include "../bot_command.h"
|
||||
|
||||
void bot_command_class_race_list(Client* c, const Seperator* sep)
|
||||
{
|
||||
const std::string class_substrs[17] = {
|
||||
"",
|
||||
"WAR", "CLR", "PAL", "RNG",
|
||||
"SHD", "DRU", "MNK", "BRD",
|
||||
"ROG", "SHM", "NEC", "WIZ",
|
||||
"MAG", "ENC", "BST", "BER"
|
||||
};
|
||||
|
||||
const std::string race_substrs[17] = {
|
||||
"",
|
||||
"HUM", "BAR", "ERU", "ELF",
|
||||
"HIE", "DEF", "HEF", "DWF",
|
||||
"TRL", "OGR", "HFL", "GNM",
|
||||
"IKS", "VAH", "FRG", "DRK"
|
||||
};
|
||||
|
||||
const uint16 race_values[17] = {
|
||||
Race::Doug,
|
||||
Race::Human, Race::Barbarian, Race::Erudite, Race::WoodElf,
|
||||
Race::HighElf, Race::DarkElf, Race::HalfElf, Race::Dwarf,
|
||||
Race::Troll, Race::Ogre, Race::Halfling, Race::Gnome,
|
||||
Race::Iksar, Race::VahShir, Race::Froglok2, Race::Drakkin
|
||||
};
|
||||
|
||||
std::string window_text;
|
||||
std::string message_separator;
|
||||
int object_count = 0;
|
||||
const int object_max = 4;
|
||||
|
||||
window_text.append(
|
||||
fmt::format(
|
||||
"<c \"#EDDA74\">Classes{}<c \"#357EC7\">",
|
||||
DialogueWindow::Break()
|
||||
)
|
||||
);
|
||||
|
||||
window_text.append(
|
||||
fmt::format(
|
||||
"<c \"#D4A017\">--------------------------------------------------------------------<c \"#357EC7\">",
|
||||
DialogueWindow::Break()
|
||||
)
|
||||
);
|
||||
|
||||
window_text.append(DialogueWindow::Break());
|
||||
|
||||
message_separator = " ";
|
||||
object_count = 0;
|
||||
for (int i = 0; i <= 15; ++i) {
|
||||
window_text.append(message_separator);
|
||||
|
||||
if (object_count >= object_max) {
|
||||
window_text.append(DialogueWindow::Break());
|
||||
object_count = 0;
|
||||
}
|
||||
|
||||
window_text.append(
|
||||
fmt::format("{} ({})",
|
||||
class_substrs[i + 1],
|
||||
(i + 1)
|
||||
)
|
||||
);
|
||||
|
||||
++object_count;
|
||||
message_separator = ", ";
|
||||
}
|
||||
|
||||
window_text.append(DialogueWindow::Break(2));
|
||||
|
||||
window_text.append(
|
||||
fmt::format(
|
||||
"<c \"#EDDA74\">Races{}<c \"#357EC7\">",
|
||||
DialogueWindow::Break()
|
||||
)
|
||||
);
|
||||
|
||||
window_text.append(
|
||||
fmt::format(
|
||||
"<c \"#D4A017\">--------------------------------------------------------------------<c \"#357EC7\">",
|
||||
DialogueWindow::Break()
|
||||
)
|
||||
);
|
||||
|
||||
window_text.append(DialogueWindow::Break());
|
||||
|
||||
message_separator = " ";
|
||||
object_count = 0;
|
||||
for (int i = 0; i <= 15; ++i) {
|
||||
window_text.append(message_separator);
|
||||
|
||||
if (object_count >= object_max) {
|
||||
window_text.append(DialogueWindow::Break());
|
||||
object_count = 0;
|
||||
}
|
||||
|
||||
window_text.append(
|
||||
fmt::format("{} ({})",
|
||||
race_substrs[i + 1],
|
||||
race_values[i + 1]
|
||||
)
|
||||
);
|
||||
|
||||
++object_count;
|
||||
message_separator = ", ";
|
||||
}
|
||||
|
||||
c->SendPopupToClient("Bot Creation Options", window_text.c_str());
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -8,7 +8,7 @@ void bot_command_click_item(Client* c, const Seperator* sep)
|
||||
}
|
||||
|
||||
if (helper_is_help_or_usage(sep->arg[1])) {
|
||||
c->Message(Chat::White, "usage: <slot id> %s ([actionable: target | byname | ownergroup | ownerraid | targetgroup | namesgroup | byclass | byrace | spawned] ([actionable_name]))", sep->arg[0]);
|
||||
c->Message(Chat::White, "usage: %s <slot id> ([actionable: target | byname | ownergroup | ownerraid | targetgroup | namesgroup | healrotationtargets | mmr | byclass | byrace | spawned] ([actionable_name]))", sep->arg[0]);
|
||||
c->Message(Chat::White, "This will cause the selected bots to click the item in the given slot ID.");
|
||||
c->Message(Chat::White, "Use ^invlist to see their items along with slot IDs.");
|
||||
return;
|
||||
@@ -25,7 +25,7 @@ void bot_command_click_item(Client* c, const Seperator* sep)
|
||||
uint32 slot_id = 0;
|
||||
|
||||
if (sep->IsNumber(1)) {
|
||||
ab_arg = 2;
|
||||
++ab_arg;
|
||||
slot_id = atoi(sep->arg[1]);
|
||||
if (slot_id < EQ::invslot::EQUIPMENT_BEGIN || slot_id > EQ::invslot::EQUIPMENT_END) {
|
||||
c->Message(Chat::Yellow, "You must specify a valid inventory slot from 0 to 22. Use %s help for more information", sep->arg[0]);
|
||||
|
||||
@@ -0,0 +1,366 @@
|
||||
#include "../bot_command.h"
|
||||
|
||||
void bot_command_copy_settings(Client* c, const Seperator* sep)
|
||||
{
|
||||
if (helper_command_alias_fail(c, "bot_command_copy_settings", sep->arg[0], "copysettings")) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (helper_is_help_or_usage(sep->arg[1])) {
|
||||
std::vector<std::string> description =
|
||||
{
|
||||
"Copies settings from one bot to another bot"
|
||||
};
|
||||
|
||||
std::vector<std::string> notes =
|
||||
{
|
||||
"- You can put a spell type ID or shortname after any option except [all], [misc] and [spellsettings] to restore that specifc spell type only"
|
||||
};
|
||||
|
||||
std::vector<std::string> example_format =
|
||||
{
|
||||
fmt::format(
|
||||
"{} [from] [to] [option]"
|
||||
, sep->arg[0]
|
||||
)
|
||||
};
|
||||
std::vector<std::string> examples_one =
|
||||
{
|
||||
"To copy all settings from BotA to BotB:",
|
||||
fmt::format(
|
||||
"{} BotA BotB all",
|
||||
sep->arg[0]
|
||||
)
|
||||
};
|
||||
std::vector<std::string> examples_two =
|
||||
{
|
||||
"To copy only Nuke spelltypesettings from BotA to BotB:",
|
||||
fmt::format(
|
||||
"{} BotA BotB spelltypesettings {}",
|
||||
sep->arg[0],
|
||||
c->GetSpellTypeShortNameByID(BotSpellTypes::Nuke)
|
||||
),
|
||||
fmt::format(
|
||||
"{} BotA BotB spelltypesettings {}",
|
||||
sep->arg[0],
|
||||
c->GetSpellTypeShortNameByID(BotSpellTypes::Nuke)
|
||||
),
|
||||
};
|
||||
std::vector<std::string> examples_three = { };
|
||||
|
||||
std::vector<std::string> actionables =
|
||||
{
|
||||
"target, byname, ownergroup, ownerraid",
|
||||
"targetgroup, namesgroup, healrotationtargets",
|
||||
"mmr, byclass, byrace, spawned"
|
||||
};
|
||||
|
||||
std::vector<std::string> options =
|
||||
{
|
||||
"all, misc, spellsettings, spelltypesettings",
|
||||
"holds, delays, minthresholds, maxthresholds",
|
||||
"minmanapct, maxmanapct, minhppct, maxhppct",
|
||||
"idlepriority, engagedpriority, pursuepriority",
|
||||
"aggrochecks, targetcounts"
|
||||
};
|
||||
std::vector<std::string> options_one =
|
||||
{
|
||||
"[spellsettings] will copy ^spellsettings options",
|
||||
"[spelltypesettings] copies all spell type settings",
|
||||
"[all] copies all settings"
|
||||
};
|
||||
std::vector<std::string> options_two =
|
||||
{
|
||||
"[misc] copies all miscellaneous options such as:",
|
||||
"- ^showhelm, ^followd, ^stopmeleelevel",
|
||||
"- ^enforcespellsettings, ^bottoggleranged, ^petsettype",
|
||||
"- ^behindmob, ^casterrange, ^illusionblock",
|
||||
"- ^sitincombat, ^sithppercent and ^sitmanapercent",
|
||||
|
||||
};
|
||||
std::vector<std::string> options_three =
|
||||
{
|
||||
"The remaining options copy that specific type"
|
||||
};
|
||||
|
||||
std::string popup_text = c->SendCommandHelpWindow(
|
||||
c,
|
||||
description,
|
||||
notes,
|
||||
example_format,
|
||||
examples_one, examples_two, examples_three,
|
||||
actionables,
|
||||
options,
|
||||
options_one, options_two, options_three
|
||||
);
|
||||
|
||||
popup_text = DialogueWindow::Table(popup_text);
|
||||
|
||||
c->SendPopupToClient(sep->arg[0], popup_text.c_str());
|
||||
c->CastToBot()->SendSpellTypesWindow(c, sep->arg[0], "", "", true);
|
||||
c->Message(
|
||||
Chat::Yellow,
|
||||
fmt::format(
|
||||
"Use {} for information about race/class IDs.",
|
||||
Saylink::Silent("^classracelist")
|
||||
).c_str()
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
std::string arg1 = sep->arg[1];
|
||||
|
||||
if (!arg1.compare("listid") || !arg1.compare("listname")) {
|
||||
c->CastToBot()->SendSpellTypesWindow(c, sep->arg[0], sep->arg[1], sep->arg[2]);
|
||||
return;
|
||||
}
|
||||
|
||||
int ab_arg = 2;
|
||||
bool validOption = false;
|
||||
uint16 spellType = UINT16_MAX;
|
||||
std::vector<std::string> options =
|
||||
{
|
||||
"all",
|
||||
"misc"
|
||||
"spellsettings",
|
||||
"spelltypesettings",
|
||||
"holds",
|
||||
"delays",
|
||||
"minthresholds",
|
||||
"maxthresholds",
|
||||
"aggrochecks",
|
||||
"minmanapct",
|
||||
"maxmanapct",
|
||||
"minhppct",
|
||||
"maxhppct",
|
||||
"idlepriority",
|
||||
"engagedpriority",
|
||||
"pursuepriority",
|
||||
"targetcounts"
|
||||
};
|
||||
|
||||
for (int i = 0; i < options.size(); i++) {
|
||||
if (sep->arg[3] == options[i]) {
|
||||
if (options[i] != "all" && options[i] != "misc" && options[i] != "spellsettings") {
|
||||
|
||||
if (sep->IsNumber(4) || c->GetSpellTypeIDByShortName(sep->arg[4]) != UINT16_MAX) {
|
||||
if (sep->IsNumber(4)) {
|
||||
spellType = atoi(sep->arg[4]);
|
||||
}
|
||||
|
||||
if (c->GetSpellTypeIDByShortName(sep->arg[4]) != UINT16_MAX) {
|
||||
spellType = c->GetSpellTypeIDByShortName(sep->arg[4]);
|
||||
}
|
||||
|
||||
if (spellType < BotSpellTypes::START || spellType > BotSpellTypes::END) {
|
||||
c->Message(Chat::Yellow, "You must choose a valid spell type. Spell types range from %i to %i", BotSpellTypes::START, BotSpellTypes::END);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (
|
||||
(options[i] == "all" || options[i] == "misc" || options[i] == "spellsettings") &&
|
||||
((sep->IsNumber(2) || c->GetSpellTypeIDByShortName(sep->arg[4]) != UINT16_MAX))
|
||||
) {
|
||||
break;
|
||||
}
|
||||
|
||||
validOption = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!validOption) {
|
||||
c->Message(
|
||||
Chat::Yellow,
|
||||
fmt::format(
|
||||
"Incorrect argument, use {} for information regarding this command.",
|
||||
Saylink::Silent(
|
||||
fmt::format("{} help", sep->arg[0])
|
||||
)
|
||||
).c_str()
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
auto from = entity_list.GetBotByBotName(sep->arg[1]);
|
||||
|
||||
if (!from) {
|
||||
c->Message(Chat::Yellow, "Could not find %s.", sep->arg[1]);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!from->IsBot()) {
|
||||
c->Message(Chat::Yellow, "%s is not a bot.", from->GetCleanName());
|
||||
return;
|
||||
}
|
||||
|
||||
if (!from->GetOwner()) {
|
||||
c->Message(Chat::Yellow, "Could not find %s's owner.", from->GetCleanName());
|
||||
}
|
||||
|
||||
if (RuleB(Bots, CopySettingsOwnBotsOnly) && from->GetOwner() != c) {
|
||||
c->Message(Chat::Yellow, "You name a bot you own to use this command.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!RuleB(Bots, AllowCopySettingsAnon) && from->GetOwner() != c && from->GetOwner()->CastToClient()->GetAnon()) {
|
||||
c->Message(Chat::Yellow, "You name a bot you own to use this command.");
|
||||
return;
|
||||
}
|
||||
|
||||
auto to = ActionableBots::AsNamed_ByBot(c, sep->arg[2]);
|
||||
|
||||
if (!to) {
|
||||
c->Message(Chat::Yellow, "Could not find %s.", sep->arg[1]);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!to->IsBot()) {
|
||||
c->Message(Chat::Yellow, "%s is not a bot.", to->GetCleanName());
|
||||
return;
|
||||
}
|
||||
|
||||
if (!to->GetOwner()) {
|
||||
c->Message(Chat::Yellow, "Could not find %s's owner.", to->GetCleanName());
|
||||
}
|
||||
|
||||
if (to->GetOwner() != c) {
|
||||
c->Message(Chat::Yellow, "You must name a spawned bot that you own to use this command.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (to == from) {
|
||||
c->Message(Chat::Yellow, "You cannot copy to the same bot that you're copying from.");
|
||||
return;
|
||||
}
|
||||
|
||||
std::string output = "";
|
||||
|
||||
if (!strcasecmp(sep->arg[3], "misc")) {
|
||||
from->CopySettings(to, BotSettingCategories::BaseSetting);
|
||||
output = "Miscellaneous";
|
||||
}
|
||||
else if (!strcasecmp(sep->arg[3], "holds")) {
|
||||
from->CopySettings(to, BotSettingCategories::SpellHold, spellType);
|
||||
output = from->GetBotSpellCategoryName(BotSettingCategories::SpellHold);
|
||||
}
|
||||
else if (!strcasecmp(sep->arg[3], "delays")) {
|
||||
from->CopySettings(to, BotSettingCategories::SpellDelay, spellType);
|
||||
output = from->GetBotSpellCategoryName(BotSettingCategories::SpellDelay);
|
||||
}
|
||||
else if (!strcasecmp(sep->arg[3], "minthresholds")) {
|
||||
from->CopySettings(to, BotSettingCategories::SpellMinThreshold, spellType);
|
||||
output = from->GetBotSpellCategoryName(BotSettingCategories::SpellMinThreshold);
|
||||
}
|
||||
else if (!strcasecmp(sep->arg[3], "maxthresholds")) {
|
||||
from->CopySettings(to, BotSettingCategories::SpellMaxThreshold, spellType);
|
||||
output = from->GetBotSpellCategoryName(BotSettingCategories::SpellMaxThreshold);
|
||||
}
|
||||
else if (!strcasecmp(sep->arg[3], "aggrochecks")) {
|
||||
from->CopySettings(to, BotSettingCategories::SpellTypeAggroCheck, spellType);
|
||||
output = from->GetBotSpellCategoryName(BotSettingCategories::SpellTypeAggroCheck);
|
||||
}
|
||||
else if (!strcasecmp(sep->arg[3], "minmanapct")) {
|
||||
from->CopySettings(to, BotSettingCategories::SpellTypeMinManaPct, spellType);
|
||||
output = from->GetBotSpellCategoryName(BotSettingCategories::SpellTypeMinManaPct);
|
||||
}
|
||||
else if (!strcasecmp(sep->arg[3], "maxmanapct")) {
|
||||
from->CopySettings(to, BotSettingCategories::SpellTypeMaxManaPct, spellType);
|
||||
output = from->GetBotSpellCategoryName(BotSettingCategories::SpellTypeMaxManaPct);
|
||||
}
|
||||
else if (!strcasecmp(sep->arg[3], "minhppct")) {
|
||||
from->CopySettings(to, BotSettingCategories::SpellTypeMinHPPct, spellType);
|
||||
output = from->GetBotSpellCategoryName(BotSettingCategories::SpellTypeMinHPPct);
|
||||
}
|
||||
else if (!strcasecmp(sep->arg[3], "maxhppct")) {
|
||||
from->CopySettings(to, BotSettingCategories::SpellTypeMaxHPPct, spellType);
|
||||
output = from->GetBotSpellCategoryName(BotSettingCategories::SpellTypeMaxHPPct);
|
||||
}
|
||||
else if (!strcasecmp(sep->arg[3], "idlepriority")) {
|
||||
from->CopySettings(to, BotSettingCategories::SpellTypeIdlePriority, spellType);
|
||||
output = from->GetBotSpellCategoryName(BotSettingCategories::SpellTypeIdlePriority);
|
||||
}
|
||||
else if (!strcasecmp(sep->arg[3], "engagedpriority")) {
|
||||
from->CopySettings(to, BotSettingCategories::SpellTypeEngagedPriority, spellType);
|
||||
output = from->GetBotSpellCategoryName(BotSettingCategories::SpellTypeEngagedPriority);
|
||||
}
|
||||
else if (!strcasecmp(sep->arg[3], "pursuepriority")) {
|
||||
from->CopySettings(to, BotSettingCategories::SpellTypePursuePriority, spellType);
|
||||
output = from->GetBotSpellCategoryName(BotSettingCategories::SpellTypePursuePriority);
|
||||
}
|
||||
else if (!strcasecmp(sep->arg[3], "targetcounts")) {
|
||||
from->CopySettings(to, BotSettingCategories::SpellTypeAEOrGroupTargetCount, spellType);
|
||||
output = from->GetBotSpellCategoryName(BotSettingCategories::SpellTypeAEOrGroupTargetCount);
|
||||
}
|
||||
else if (!strcasecmp(sep->arg[3], "spellsettings")) {
|
||||
from->CopyBotSpellSettings(to);
|
||||
output = "^spellsettings";
|
||||
}
|
||||
else if (!strcasecmp(sep->arg[3], "spelltypesettings")) {
|
||||
from->CopySettings(to, BotSettingCategories::SpellHold, spellType);
|
||||
from->CopySettings(to, BotSettingCategories::SpellDelay, spellType);
|
||||
from->CopySettings(to, BotSettingCategories::SpellMinThreshold, spellType);
|
||||
from->CopySettings(to, BotSettingCategories::SpellMaxThreshold, spellType);
|
||||
from->CopySettings(to, BotSettingCategories::SpellTypeAggroCheck, spellType);
|
||||
from->CopySettings(to, BotSettingCategories::SpellTypeMinManaPct, spellType);
|
||||
from->CopySettings(to, BotSettingCategories::SpellTypeMaxManaPct, spellType);
|
||||
from->CopySettings(to, BotSettingCategories::SpellTypeMinHPPct, spellType);
|
||||
from->CopySettings(to, BotSettingCategories::SpellTypeMaxHPPct, spellType);
|
||||
from->CopySettings(to, BotSettingCategories::SpellTypeIdlePriority, spellType);
|
||||
from->CopySettings(to, BotSettingCategories::SpellTypeEngagedPriority, spellType);
|
||||
from->CopySettings(to, BotSettingCategories::SpellTypePursuePriority, spellType);
|
||||
from->CopySettings(to, BotSettingCategories::SpellTypeAEOrGroupTargetCount, spellType);
|
||||
output = "spell type";
|
||||
}
|
||||
else if (!strcasecmp(sep->arg[3], "all")) {
|
||||
from->CopySettings(to, BotSettingCategories::BaseSetting);
|
||||
from->CopySettings(to, BotSettingCategories::SpellHold, spellType);
|
||||
from->CopySettings(to, BotSettingCategories::SpellDelay, spellType);
|
||||
from->CopySettings(to, BotSettingCategories::SpellMinThreshold, spellType);
|
||||
from->CopySettings(to, BotSettingCategories::SpellMaxThreshold, spellType);
|
||||
from->CopySettings(to, BotSettingCategories::SpellTypeAggroCheck, spellType);
|
||||
from->CopySettings(to, BotSettingCategories::SpellTypeMinManaPct, spellType);
|
||||
from->CopySettings(to, BotSettingCategories::SpellTypeMaxManaPct, spellType);
|
||||
from->CopySettings(to, BotSettingCategories::SpellTypeMinHPPct, spellType);
|
||||
from->CopySettings(to, BotSettingCategories::SpellTypeMaxHPPct, spellType);
|
||||
from->CopySettings(to, BotSettingCategories::SpellTypeIdlePriority, spellType);
|
||||
from->CopySettings(to, BotSettingCategories::SpellTypeEngagedPriority, spellType);
|
||||
from->CopySettings(to, BotSettingCategories::SpellTypePursuePriority, spellType);
|
||||
from->CopySettings(to, BotSettingCategories::SpellTypeAEOrGroupTargetCount, spellType);
|
||||
from->CopyBotSpellSettings(to);
|
||||
}
|
||||
else {
|
||||
c->Message(
|
||||
Chat::Yellow,
|
||||
fmt::format(
|
||||
"Incorrect argument, use {} for information regarding this command.",
|
||||
Saylink::Silent(
|
||||
fmt::format("{} help", sep->arg[0])
|
||||
)
|
||||
).c_str()
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
c->Message(
|
||||
Chat::Green,
|
||||
fmt::format(
|
||||
"{}'s{}{} settings were copied to {}.",
|
||||
from->GetCleanName(),
|
||||
(
|
||||
spellType != UINT16_MAX ?
|
||||
fmt::format(" [{}] ",
|
||||
c->GetSpellTypeNameByID(spellType)
|
||||
)
|
||||
: " "
|
||||
),
|
||||
output,
|
||||
to->GetCleanName()
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,473 @@
|
||||
#include "../bot_command.h"
|
||||
|
||||
void bot_command_default_settings(Client* c, const Seperator* sep)
|
||||
{
|
||||
if (helper_command_alias_fail(c, "bot_command_default_settings", sep->arg[0], "defaultsettings")) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (helper_is_help_or_usage(sep->arg[1])) {
|
||||
std::vector<std::string> description =
|
||||
{
|
||||
"Restores a bot's setting(s) to defaults"
|
||||
};
|
||||
|
||||
std::vector<std::string> notes =
|
||||
{
|
||||
"- You can put a spell type ID or shortname after any option except [all], [misc] and [spellsettings] to restore that specifc spell type only"
|
||||
};
|
||||
|
||||
std::vector<std::string> example_format =
|
||||
{
|
||||
fmt::format(
|
||||
"{} [option] [actionable]"
|
||||
, sep->arg[0]
|
||||
)
|
||||
};
|
||||
std::vector<std::string> examples_one =
|
||||
{
|
||||
"To restore delays for Clerics:",
|
||||
fmt::format(
|
||||
"{} delays byclass 2",
|
||||
sep->arg[0]
|
||||
)
|
||||
};
|
||||
std::vector<std::string> examples_two =
|
||||
{
|
||||
"To restore only Snare delays for BotA:",
|
||||
fmt::format(
|
||||
"{} delays {} byname BotA",
|
||||
sep->arg[0],
|
||||
c->GetSpellTypeShortNameByID(BotSpellTypes::Snare)
|
||||
),
|
||||
fmt::format(
|
||||
"{} delays {} byname BotA",
|
||||
sep->arg[0],
|
||||
BotSpellTypes::Snare
|
||||
)
|
||||
};
|
||||
std::vector<std::string> examples_three = { };
|
||||
|
||||
std::vector<std::string> actionables =
|
||||
{
|
||||
"target, byname, ownergroup, ownerraid, targetgroup, namesgroup, healrotationtargets mmr, byclass, byrace, spawned"
|
||||
};
|
||||
|
||||
std::vector<std::string> options =
|
||||
{
|
||||
"all, misc, spellsettings, spelltypesettings, holds, delays, minthresholds, maxthresholds minmanapct, maxmanapct, minhppct, maxhppct, idlepriority, engagedpriority, pursuepriority, aggrocheck, targetcounts"
|
||||
};
|
||||
std::vector<std::string> options_one =
|
||||
{
|
||||
"[spellsettings] will restore ^spellsettings options",
|
||||
"[spelltypesettings] restores all spell type settings",
|
||||
"[all] restores all settings"
|
||||
};
|
||||
std::vector<std::string> options_two =
|
||||
{
|
||||
"[misc] restores all miscellaneous options such as:",
|
||||
"- ^showhelm, ^followd, ^stopmeleelevel",
|
||||
"- ^enforcespellsettings, ^bottoggleranged, ^petsettype",
|
||||
"- ^behindmob, ^casterrange, ^illusionblock",
|
||||
"- ^sitincombat, ^sithppercent and ^sitmanapercent",
|
||||
|
||||
};
|
||||
std::vector<std::string> options_three =
|
||||
{
|
||||
"The remaining options restore that specific type"
|
||||
};
|
||||
|
||||
std::string popup_text = c->SendCommandHelpWindow(
|
||||
c,
|
||||
description,
|
||||
notes,
|
||||
example_format,
|
||||
examples_one, examples_two, examples_three,
|
||||
actionables,
|
||||
options,
|
||||
options_one, options_two, options_three
|
||||
);
|
||||
|
||||
popup_text = DialogueWindow::Table(popup_text);
|
||||
|
||||
c->SendPopupToClient(sep->arg[0], popup_text.c_str());
|
||||
c->CastToBot()->SendSpellTypesWindow(c, sep->arg[0], "", "", true);
|
||||
c->Message(
|
||||
Chat::Yellow,
|
||||
fmt::format(
|
||||
"Use {} for information about race/class IDs.",
|
||||
Saylink::Silent("^classracelist")
|
||||
).c_str()
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
std::string arg1 = sep->arg[1];
|
||||
|
||||
if (!arg1.compare("listid") || !arg1.compare("listname")) {
|
||||
c->CastToBot()->SendSpellTypesWindow(c, sep->arg[0], sep->arg[1], sep->arg[2]);
|
||||
return;
|
||||
}
|
||||
|
||||
int ab_arg = 2;
|
||||
bool validOption = false;
|
||||
uint16 spellType = UINT16_MAX;
|
||||
std::vector<std::string> options =
|
||||
{
|
||||
"all",
|
||||
"misc"
|
||||
"spellsettings",
|
||||
"spelltypesettings",
|
||||
"holds",
|
||||
"delays",
|
||||
"minthresholds",
|
||||
"maxthresholds",
|
||||
"aggrocheck",
|
||||
"minmanapct",
|
||||
"maxmanapct",
|
||||
"minhppct",
|
||||
"maxhppct",
|
||||
"idlepriority",
|
||||
"engagedpriority",
|
||||
"pursuepriority",
|
||||
"targetcounts"
|
||||
};
|
||||
|
||||
for (int i = 0; i < options.size(); i++) {
|
||||
if (sep->arg[1] == options[i]) {
|
||||
if (options[i] != "all" && options[i] != "misc" && options[i] != "spellsettings") {
|
||||
|
||||
if (sep->IsNumber(2) || c->GetSpellTypeIDByShortName(sep->arg[2]) != UINT16_MAX) {
|
||||
if (sep->IsNumber(2)) {
|
||||
spellType = atoi(sep->arg[2]);
|
||||
}
|
||||
|
||||
if (c->GetSpellTypeIDByShortName(sep->arg[2]) != UINT16_MAX) {
|
||||
spellType = c->GetSpellTypeIDByShortName(sep->arg[2]);
|
||||
}
|
||||
|
||||
if (spellType < BotSpellTypes::START || spellType > BotSpellTypes::END) {
|
||||
c->Message(Chat::Yellow, "You must choose a valid spell type. Spell types range from %i to %i", BotSpellTypes::START, BotSpellTypes::END);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
++ab_arg;
|
||||
}
|
||||
}
|
||||
else if (
|
||||
(options[i] == "all" || options[i] == "misc" || options[i] == "spellsettings") &&
|
||||
((sep->IsNumber(2) || c->GetSpellTypeIDByShortName(sep->arg[2]) != UINT16_MAX))
|
||||
) {
|
||||
break;
|
||||
}
|
||||
|
||||
validOption = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!validOption) {
|
||||
c->Message(
|
||||
Chat::Yellow,
|
||||
fmt::format(
|
||||
"Incorrect argument, use {} for information regarding this command.",
|
||||
Saylink::Silent(
|
||||
fmt::format("{} help", sep->arg[0])
|
||||
)
|
||||
).c_str()
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const int ab_mask = ActionableBots::ABM_Type1;
|
||||
std::string class_race_arg = sep->arg[ab_arg];
|
||||
bool class_race_check = false;
|
||||
if (!class_race_arg.compare("byclass") || !class_race_arg.compare("byrace")) {
|
||||
class_race_check = true;
|
||||
}
|
||||
|
||||
std::list<Bot*> sbl;
|
||||
if (ActionableBots::PopulateSBL(c, sep->arg[ab_arg], sbl, ab_mask, !class_race_check ? sep->arg[ab_arg + 1] : nullptr, class_race_check ? atoi(sep->arg[ab_arg + 1]) : 0) == ActionableBots::ABT_None) {
|
||||
return;
|
||||
}
|
||||
|
||||
sbl.remove(nullptr);
|
||||
|
||||
Bot* first_found = nullptr;
|
||||
int success_count = 0;
|
||||
std::string output = "";
|
||||
for (auto my_bot : sbl) {
|
||||
if (!first_found) {
|
||||
first_found = my_bot;
|
||||
}
|
||||
|
||||
if (!strcasecmp(sep->arg[1], "misc")) {
|
||||
for (uint16 i = BotBaseSettings::START; i <= BotBaseSettings::END; ++i) {
|
||||
my_bot->SetBotBaseSetting(i, my_bot->GetDefaultBotBaseSetting(i));
|
||||
output = "miscellanous settings";
|
||||
}
|
||||
}
|
||||
else if (!strcasecmp(sep->arg[1], "holds")) {
|
||||
if (spellType != UINT16_MAX) {
|
||||
my_bot->SetSpellHold(spellType, my_bot->GetDefaultSpellHold(spellType));
|
||||
}
|
||||
else {
|
||||
for (uint16 i = BotSpellTypes::START; i <= BotSpellTypes::END; ++i) {
|
||||
my_bot->SetSpellHold(i, my_bot->GetDefaultSpellHold(i));
|
||||
}
|
||||
}
|
||||
|
||||
output = "hold settings";
|
||||
}
|
||||
else if (!strcasecmp(sep->arg[1], "delays")) {
|
||||
if (spellType != UINT16_MAX) {
|
||||
my_bot->SetSpellDelay(spellType, my_bot->GetDefaultSpellDelay(spellType));
|
||||
}
|
||||
else {
|
||||
for (uint16 i = BotSpellTypes::START; i <= BotSpellTypes::END; ++i) {
|
||||
my_bot->SetSpellDelay(i, my_bot->GetDefaultSpellDelay(i));
|
||||
}
|
||||
}
|
||||
|
||||
output = "delay settings";
|
||||
}
|
||||
else if (!strcasecmp(sep->arg[1], "minthresholds")) {
|
||||
if (spellType != UINT16_MAX) {
|
||||
my_bot->SetSpellMinThreshold(spellType, my_bot->GetDefaultSpellMinThreshold(spellType));
|
||||
}
|
||||
else {
|
||||
for (uint16 i = BotSpellTypes::START; i <= BotSpellTypes::END; ++i) {
|
||||
my_bot->SetSpellMinThreshold(i, my_bot->GetDefaultSpellMinThreshold(i));
|
||||
}
|
||||
}
|
||||
|
||||
output = "minimum threshold settings";
|
||||
}
|
||||
else if (!strcasecmp(sep->arg[1], "maxthresholds")) {
|
||||
if (spellType != UINT16_MAX) {
|
||||
my_bot->SetSpellMaxThreshold(spellType, my_bot->GetDefaultSpellMaxThreshold(spellType));
|
||||
}
|
||||
else {
|
||||
for (uint16 i = BotSpellTypes::START; i <= BotSpellTypes::END; ++i) {
|
||||
my_bot->SetSpellMaxThreshold(i, my_bot->GetDefaultSpellMaxThreshold(i));
|
||||
}
|
||||
}
|
||||
|
||||
output = "maximum threshold settings";
|
||||
}
|
||||
else if (!strcasecmp(sep->arg[1], "aggrochecks")) {
|
||||
if (spellType != UINT16_MAX) {
|
||||
my_bot->SetSpellTypeAggroCheck(spellType, my_bot->GetDefaultSpellTypeAggroCheck(spellType));
|
||||
}
|
||||
else {
|
||||
for (uint16 i = BotSpellTypes::START; i <= BotSpellTypes::END; ++i) {
|
||||
my_bot->SetSpellTypeAggroCheck(i, my_bot->GetDefaultSpellTypeAggroCheck(i));
|
||||
}
|
||||
}
|
||||
|
||||
output = "aggro check settings";
|
||||
}
|
||||
else if (!strcasecmp(sep->arg[1], "minmanapct")) {
|
||||
if (spellType != UINT16_MAX) {
|
||||
my_bot->SetSpellTypeMinManaLimit(spellType, my_bot->GetDefaultSpellTypeMinManaLimit(spellType));
|
||||
}
|
||||
else {
|
||||
for (uint16 i = BotSpellTypes::START; i <= BotSpellTypes::END; ++i) {
|
||||
my_bot->SetSpellTypeMinManaLimit(i, my_bot->GetDefaultSpellTypeMinManaLimit(i));
|
||||
}
|
||||
}
|
||||
|
||||
output = "min mana settings";
|
||||
}
|
||||
else if (!strcasecmp(sep->arg[1], "maxmanapct")) {
|
||||
if (spellType != UINT16_MAX) {
|
||||
my_bot->SetSpellTypeMaxManaLimit(spellType, my_bot->GetDefaultSpellTypeMaxManaLimit(spellType));
|
||||
}
|
||||
else {
|
||||
for (uint16 i = BotSpellTypes::START; i <= BotSpellTypes::END; ++i) {
|
||||
my_bot->SetSpellTypeMaxManaLimit(i, my_bot->GetDefaultSpellTypeMaxManaLimit(i));
|
||||
}
|
||||
}
|
||||
|
||||
output = "max mana settings";
|
||||
}
|
||||
else if (!strcasecmp(sep->arg[1], "minhppct")) {
|
||||
if (spellType != UINT16_MAX) {
|
||||
my_bot->SetSpellTypeMinHPLimit(spellType, my_bot->GetDefaultSpellTypeMinHPLimit(spellType));
|
||||
}
|
||||
else {
|
||||
for (uint16 i = BotSpellTypes::START; i <= BotSpellTypes::END; ++i) {
|
||||
my_bot->SetSpellTypeMinHPLimit(i, my_bot->GetDefaultSpellTypeMinHPLimit(i));
|
||||
}
|
||||
}
|
||||
|
||||
output = "min hp settings";
|
||||
}
|
||||
else if (!strcasecmp(sep->arg[1], "maxhppct")) {
|
||||
if (spellType != UINT16_MAX) {
|
||||
my_bot->SetSpellTypeMaxHPLimit(spellType, my_bot->GetDefaultSpellTypeMaxHPLimit(spellType));
|
||||
}
|
||||
else {
|
||||
for (uint16 i = BotSpellTypes::START; i <= BotSpellTypes::END; ++i) {
|
||||
my_bot->SetSpellTypeMaxHPLimit(i, my_bot->GetDefaultSpellTypeMaxHPLimit(i));
|
||||
}
|
||||
}
|
||||
|
||||
output = "max hp settings";
|
||||
}
|
||||
else if (!strcasecmp(sep->arg[1], "idlepriority")) {
|
||||
if (spellType != UINT16_MAX) {
|
||||
my_bot->SetSpellTypePriority(spellType, BotPriorityCategories::Idle, my_bot->GetDefaultSpellTypePriority(spellType, BotPriorityCategories::Idle, my_bot->GetClass()));
|
||||
}
|
||||
else {
|
||||
for (uint16 i = BotSpellTypes::START; i <= BotSpellTypes::END; ++i) {
|
||||
my_bot->SetSpellTypePriority(i, BotPriorityCategories::Idle, my_bot->GetDefaultSpellTypePriority(i, BotPriorityCategories::Idle, my_bot->GetClass()));
|
||||
}
|
||||
}
|
||||
|
||||
output = "idle priority settings";
|
||||
}
|
||||
else if (!strcasecmp(sep->arg[1], "engagedpriority")) {
|
||||
if (spellType != UINT16_MAX) {
|
||||
my_bot->SetSpellTypePriority(spellType, BotPriorityCategories::Engaged, my_bot->GetDefaultSpellTypePriority(spellType, BotPriorityCategories::Engaged, my_bot->GetClass()));
|
||||
}
|
||||
else {
|
||||
for (uint16 i = BotSpellTypes::START; i <= BotSpellTypes::END; ++i) {
|
||||
my_bot->SetSpellTypePriority(i, BotPriorityCategories::Engaged, my_bot->GetDefaultSpellTypePriority(i, BotPriorityCategories::Engaged, my_bot->GetClass()));
|
||||
}
|
||||
}
|
||||
|
||||
output = "engaged priority settings";
|
||||
}
|
||||
else if (!strcasecmp(sep->arg[1], "pursuepriority")) {
|
||||
if (spellType != UINT16_MAX) {
|
||||
my_bot->SetSpellTypePriority(spellType, BotPriorityCategories::Pursue, my_bot->GetDefaultSpellTypePriority(spellType, BotPriorityCategories::Pursue, my_bot->GetClass()));
|
||||
}
|
||||
else {
|
||||
for (uint16 i = BotSpellTypes::START; i <= BotSpellTypes::END; ++i) {
|
||||
my_bot->SetSpellTypePriority(i, BotPriorityCategories::Pursue, my_bot->GetDefaultSpellTypePriority(i, BotPriorityCategories::Pursue, my_bot->GetClass()));
|
||||
}
|
||||
}
|
||||
|
||||
output = "pursue priority settings";
|
||||
}
|
||||
else if (!strcasecmp(sep->arg[1], "targetcounts")) {
|
||||
if (spellType != UINT16_MAX) {
|
||||
my_bot->SetSpellDelay(spellType, my_bot->GetDefaultSpellDelay(spellType));
|
||||
}
|
||||
else {
|
||||
for (uint16 i = BotSpellTypes::START; i <= BotSpellTypes::END; ++i) {
|
||||
my_bot->SetSpellTypeAEOrGroupTargetCount(i, my_bot->GetDefaultSpellTypeAEOrGroupTargetCount(i));
|
||||
}
|
||||
}
|
||||
|
||||
output = "ae/group count settings";
|
||||
}
|
||||
else if (!strcasecmp(sep->arg[1], "spellsettings")) {
|
||||
my_bot->ResetBotSpellSettings();
|
||||
output = "^spellsettings";
|
||||
}
|
||||
else if (!strcasecmp(sep->arg[1], "spelltypesettings")) {
|
||||
if (spellType != UINT16_MAX) {
|
||||
my_bot->SetSpellHold(spellType, my_bot->GetDefaultSpellHold(spellType));
|
||||
my_bot->SetSpellDelay(spellType, my_bot->GetDefaultSpellDelay(spellType));
|
||||
my_bot->SetSpellMinThreshold(spellType, my_bot->GetDefaultSpellMinThreshold(spellType));
|
||||
my_bot->SetSpellMaxThreshold(spellType, my_bot->GetDefaultSpellMaxThreshold(spellType));
|
||||
my_bot->SetSpellTypeAggroCheck(spellType, my_bot->GetDefaultSpellTypeAggroCheck(spellType));
|
||||
my_bot->SetSpellTypeMinManaLimit(spellType, my_bot->GetDefaultSpellTypeMinManaLimit(spellType));
|
||||
my_bot->SetSpellTypeMaxManaLimit(spellType, my_bot->GetDefaultSpellTypeMaxManaLimit(spellType));
|
||||
my_bot->SetSpellTypeMinHPLimit(spellType, my_bot->GetDefaultSpellTypeMinHPLimit(spellType));
|
||||
my_bot->SetSpellTypeMaxHPLimit(spellType, my_bot->GetDefaultSpellTypeMaxHPLimit(spellType));
|
||||
my_bot->SetSpellTypePriority(spellType, BotPriorityCategories::Idle, my_bot->GetDefaultSpellTypePriority(spellType, BotPriorityCategories::Idle, my_bot->GetClass()));
|
||||
my_bot->SetSpellTypePriority(spellType, BotPriorityCategories::Engaged, my_bot->GetDefaultSpellTypePriority(spellType, BotPriorityCategories::Engaged, my_bot->GetClass()));
|
||||
my_bot->SetSpellTypePriority(spellType, BotPriorityCategories::Pursue, my_bot->GetDefaultSpellTypePriority(spellType, BotPriorityCategories::Pursue, my_bot->GetClass()));
|
||||
my_bot->SetSpellTypeAEOrGroupTargetCount(spellType, my_bot->GetDefaultSpellTypeAEOrGroupTargetCount(spellType));
|
||||
}
|
||||
else {
|
||||
for (uint16 i = BotSpellTypes::START; i <= BotSpellTypes::END; ++i) {
|
||||
my_bot->SetSpellHold(i, my_bot->GetDefaultSpellHold(i));
|
||||
my_bot->SetSpellDelay(i, my_bot->GetDefaultSpellDelay(i));
|
||||
my_bot->SetSpellMinThreshold(i, my_bot->GetDefaultSpellMinThreshold(i));
|
||||
my_bot->SetSpellMaxThreshold(i, my_bot->GetDefaultSpellMaxThreshold(i));
|
||||
my_bot->SetSpellTypeAggroCheck(i, my_bot->GetDefaultSpellTypeAggroCheck(i));
|
||||
my_bot->SetSpellTypeMinManaLimit(i, my_bot->GetDefaultSpellTypeMinManaLimit(i));
|
||||
my_bot->SetSpellTypeMaxManaLimit(i, my_bot->GetDefaultSpellTypeMaxManaLimit(i));
|
||||
my_bot->SetSpellTypeMinHPLimit(i, my_bot->GetDefaultSpellTypeMinHPLimit(i));
|
||||
my_bot->SetSpellTypeMaxHPLimit(i, my_bot->GetDefaultSpellTypeMaxHPLimit(i));
|
||||
my_bot->SetSpellTypePriority(i, BotPriorityCategories::Idle, my_bot->GetDefaultSpellTypePriority(i, BotPriorityCategories::Idle, my_bot->GetClass()));
|
||||
my_bot->SetSpellTypePriority(i, BotPriorityCategories::Engaged, my_bot->GetDefaultSpellTypePriority(i, BotPriorityCategories::Engaged, my_bot->GetClass()));
|
||||
my_bot->SetSpellTypePriority(i, BotPriorityCategories::Pursue, my_bot->GetDefaultSpellTypePriority(i, BotPriorityCategories::Pursue, my_bot->GetClass()));
|
||||
my_bot->SetSpellTypeAEOrGroupTargetCount(i, my_bot->GetDefaultSpellTypeAEOrGroupTargetCount(i));
|
||||
}
|
||||
}
|
||||
|
||||
output = "spell type settings";
|
||||
}
|
||||
else if (!strcasecmp(sep->arg[1], "all")) {
|
||||
for (uint16 i = BotBaseSettings::START; i <= BotBaseSettings::END; ++i) {
|
||||
my_bot->SetBotBaseSetting(i, my_bot->GetDefaultBotBaseSetting(i));
|
||||
}
|
||||
|
||||
for (uint16 i = BotSpellTypes::START; i <= BotSpellTypes::END; ++i) {
|
||||
my_bot->SetSpellHold(i, my_bot->GetDefaultSpellHold(i));
|
||||
my_bot->SetSpellDelay(i, my_bot->GetDefaultSpellDelay(i));
|
||||
my_bot->SetSpellMinThreshold(i, my_bot->GetDefaultSpellMinThreshold(i));
|
||||
my_bot->SetSpellMaxThreshold(i, my_bot->GetDefaultSpellMaxThreshold(i));
|
||||
my_bot->SetSpellTypeAggroCheck(i, my_bot->GetDefaultSpellTypeAggroCheck(i));
|
||||
my_bot->SetSpellTypeMinManaLimit(i, my_bot->GetDefaultSpellTypeMinManaLimit(i));
|
||||
my_bot->SetSpellTypeMaxManaLimit(i, my_bot->GetDefaultSpellTypeMaxManaLimit(i));
|
||||
my_bot->SetSpellTypeMinHPLimit(i, my_bot->GetDefaultSpellTypeMinHPLimit(i));
|
||||
my_bot->SetSpellTypeMaxHPLimit(i, my_bot->GetDefaultSpellTypeMaxHPLimit(i));
|
||||
my_bot->SetSpellTypePriority(i, BotPriorityCategories::Idle, my_bot->GetDefaultSpellTypePriority(i, BotPriorityCategories::Idle, my_bot->GetClass()));
|
||||
my_bot->SetSpellTypePriority(i, BotPriorityCategories::Engaged, my_bot->GetDefaultSpellTypePriority(i, BotPriorityCategories::Engaged, my_bot->GetClass()));
|
||||
my_bot->SetSpellTypePriority(i, BotPriorityCategories::Pursue, my_bot->GetDefaultSpellTypePriority(i, BotPriorityCategories::Pursue, my_bot->GetClass()));
|
||||
my_bot->SetSpellTypeAEOrGroupTargetCount(i, my_bot->GetDefaultSpellTypeAEOrGroupTargetCount(i));
|
||||
};
|
||||
|
||||
my_bot->ResetBotSpellSettings();
|
||||
|
||||
output = "settings";
|
||||
|
||||
}
|
||||
|
||||
++success_count;
|
||||
}
|
||||
|
||||
if (success_count == 1) {
|
||||
c->Message(
|
||||
Chat::Green,
|
||||
fmt::format(
|
||||
"{} says, '{}{} were restored.'",
|
||||
first_found->GetCleanName(),
|
||||
(
|
||||
spellType != UINT16_MAX ?
|
||||
fmt::format("My [{}] ",
|
||||
c->GetSpellTypeNameByID(spellType)
|
||||
)
|
||||
: "My "
|
||||
),
|
||||
output
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
else {
|
||||
c->Message(
|
||||
Chat::Green,
|
||||
fmt::format(
|
||||
"{} of your bot's{}{} were restored.",
|
||||
success_count,
|
||||
(
|
||||
spellType != UINT16_MAX ?
|
||||
fmt::format(" [{}] ",
|
||||
c->GetSpellTypeNameByID(spellType)
|
||||
)
|
||||
: " "
|
||||
),
|
||||
output
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -6,22 +6,27 @@ void bot_command_defensive(Client *c, const Seperator *sep)
|
||||
if (helper_spell_list_fail(c, local_list, BCEnum::SpT_Stance) || helper_command_alias_fail(c, "bot_command_defensive", sep->arg[0], "defensive"))
|
||||
return;
|
||||
if (helper_is_help_or_usage(sep->arg[1])) {
|
||||
c->Message(Chat::White, "usage: %s ([actionable: target | byname | ownergroup | ownerraid | targetgroup | namesgroup | healrotationtargets | byclass | byrace | spawned] ([actionable_name]))", sep->arg[0]);
|
||||
c->Message(Chat::White, "usage: %s ([actionable: target | byname | ownergroup | ownerraid | targetgroup | namesgroup | healrotationtargets | mmr | byclass | byrace | spawned] ([actionable_name]))", sep->arg[0]);
|
||||
helper_send_usage_required_bots(c, BCEnum::SpT_Stance);
|
||||
return;
|
||||
}
|
||||
const int ab_mask = ActionableBots::ABM_Type1;
|
||||
|
||||
std::string class_race_arg = sep->arg[1];
|
||||
std::string arg1 = sep->arg[1];
|
||||
int ab_arg = 1;
|
||||
|
||||
std::string class_race_arg = sep->arg[ab_arg];
|
||||
bool class_race_check = false;
|
||||
|
||||
if (!class_race_arg.compare("byclass") || !class_race_arg.compare("byrace")) {
|
||||
class_race_check = true;
|
||||
}
|
||||
|
||||
std::list<Bot*> sbl;
|
||||
if (ActionableBots::PopulateSBL(c, sep->arg[1], sbl, ab_mask, !class_race_check ? sep->arg[2] : nullptr, class_race_check ? atoi(sep->arg[2]) : 0) == ActionableBots::ABT_None) {
|
||||
if (ActionableBots::PopulateSBL(c, sep->arg[ab_arg], sbl, ab_mask, !class_race_check ? sep->arg[ab_arg + 1] : nullptr, class_race_check ? atoi(sep->arg[ab_arg + 1]) : 0) == ActionableBots::ABT_None) {
|
||||
return;
|
||||
}
|
||||
|
||||
sbl.remove(nullptr);
|
||||
|
||||
int success_count = 0;
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
#include "../bot_command.h"
|
||||
|
||||
void bot_command_follow(Client *c, const Seperator *sep)
|
||||
void bot_command_follow(Client* c, const Seperator* sep)
|
||||
{
|
||||
if (helper_command_alias_fail(c, "bot_command_follow", sep->arg[0], "follow"))
|
||||
return;
|
||||
if (helper_is_help_or_usage(sep->arg[1])) {
|
||||
c->Message(Chat::White, "usage: (<friendly_target>) %s ([option: reset]) [actionable: byname | ownergroup | ownerraid | namesgroup | healrotation | byclass | byrace | spawned]] ([actionable_name])", sep->arg[0]);
|
||||
c->Message(Chat::White, "usage: (<friendly_target>) %s ([option: reset]) [actionable: byname | ownergroup | ownerraid | namesgroup | mmr | byclass | byrace | spawned]] ([actionable_name])", sep->arg[0]);
|
||||
c->Message(Chat::White, "usage: %s chain", sep->arg[0]);
|
||||
return;
|
||||
}
|
||||
@@ -26,13 +26,22 @@ void bot_command_follow(Client *c, const Seperator *sep)
|
||||
}
|
||||
else if (!optional_arg.compare("reset")) {
|
||||
reset = true;
|
||||
ab_arg = 2;
|
||||
name_arg = 3;
|
||||
++ab_arg;
|
||||
++name_arg ;
|
||||
}
|
||||
else {
|
||||
target_mob = ActionableTarget::VerifyFriendly(c, BCEnum::TT_Single);
|
||||
//target_mob = ActionableTarget::VerifyFriendly(c, BCEnum::TT_Single);
|
||||
target_mob = c->GetTarget();
|
||||
if (!target_mob) {
|
||||
c->Message(Chat::White, "You must <target> a friendly mob to use this command");
|
||||
c->Message(Chat::White, "You must <target> a friendly player or bot within your group or raid to use this command");
|
||||
return;
|
||||
}
|
||||
else if (!target_mob->IsBot() && !target_mob->IsClient()) {
|
||||
c->Message(Chat::White, "You must <target> a friendly player or bot within your group or raid to use this command");
|
||||
return;
|
||||
}
|
||||
else if ((target_mob->GetGroup() && target_mob->GetGroup() != c->GetGroup()) || (target_mob->GetRaid() && target_mob->GetRaid() != c->GetRaid())) {
|
||||
c->Message(Chat::White, "You must <target> a friendly player or bot within your group or raid to use this command");
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -51,29 +60,54 @@ void bot_command_follow(Client *c, const Seperator *sep)
|
||||
sbl.remove(nullptr);
|
||||
for (auto bot_iter : sbl) {
|
||||
bot_iter->WipeHateList();
|
||||
auto my_group = bot_iter->GetGroup();
|
||||
if (my_group) {
|
||||
if (reset) {
|
||||
if (!my_group->GetLeader() || my_group->GetLeader() == bot_iter)
|
||||
bot_iter->SetFollowID(c->GetID());
|
||||
else
|
||||
bot_iter->SetFollowID(my_group->GetLeader()->GetID());
|
||||
|
||||
bot_iter->SetManualFollow(false);
|
||||
}
|
||||
else {
|
||||
if (bot_iter == target_mob)
|
||||
bot_iter->SetFollowID(c->GetID());
|
||||
else
|
||||
bot_iter->SetFollowID(target_mob->GetID());
|
||||
|
||||
bot_iter->SetManualFollow(true);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!bot_iter->GetGroup() && !bot_iter->GetRaid()) {
|
||||
bot_iter->SetFollowID(0);
|
||||
bot_iter->SetManualFollow(false);
|
||||
}
|
||||
else {
|
||||
if (reset) {
|
||||
bot_iter->SetFollowID(c->GetID());
|
||||
bot_iter->SetManualFollow(false);
|
||||
}
|
||||
else {
|
||||
if (target_mob->IsGrouped() || target_mob->IsRaidGrouped()) {
|
||||
bot_iter->SetFollowID(target_mob->GetID());
|
||||
bot_iter->SetManualFollow(true);
|
||||
}
|
||||
else if (bot_iter == target_mob) {
|
||||
bot_iter->SetFollowID(c->GetID());
|
||||
bot_iter->SetManualFollow(true);
|
||||
}
|
||||
else {
|
||||
bot_iter->SetFollowID(0);
|
||||
bot_iter->SetManualFollow(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
//auto my_group = bot_iter->GetGroup();
|
||||
//if (my_group) {
|
||||
// if (reset) {
|
||||
// if (!my_group->GetLeader() || my_group->GetLeader() == bot_iter)
|
||||
// bot_iter->SetFollowID(c->GetID());
|
||||
// else
|
||||
// bot_iter->SetFollowID(my_group->GetLeader()->GetID());
|
||||
//
|
||||
// bot_iter->SetManualFollow(false);
|
||||
// }
|
||||
// else {
|
||||
// if (bot_iter == target_mob)
|
||||
// bot_iter->SetFollowID(c->GetID());
|
||||
// else
|
||||
// bot_iter->SetFollowID(target_mob->GetID());
|
||||
//
|
||||
// bot_iter->SetManualFollow(true);
|
||||
// }
|
||||
//}
|
||||
//else {
|
||||
// bot_iter->SetFollowID(0);
|
||||
// bot_iter->SetManualFollow(false);
|
||||
//}
|
||||
if (!bot_iter->GetPet())
|
||||
continue;
|
||||
|
||||
@@ -81,31 +115,37 @@ void bot_command_follow(Client *c, const Seperator *sep)
|
||||
bot_iter->GetPet()->SetFollowID(bot_iter->GetID());
|
||||
}
|
||||
|
||||
Mob* follow_mob = nullptr;
|
||||
if (sbl.size() == 1) {
|
||||
Mob* follow_mob = entity_list.GetMob(sbl.front()->GetFollowID());
|
||||
Bot::BotGroupSay(
|
||||
sbl.front(),
|
||||
follow_mob = entity_list.GetMob(sbl.front()->GetFollowID());
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Following {}.",
|
||||
follow_mob ? follow_mob->GetCleanName() : "no one"
|
||||
follow_mob ? follow_mob->GetCleanName() : "you"
|
||||
).c_str()
|
||||
);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
if (reset) {
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"{} of your bots are following their default assignments.",
|
||||
"{} of your bots are following you.",
|
||||
sbl.size()
|
||||
).c_str()
|
||||
);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
if (!sbl.empty()) {
|
||||
follow_mob = entity_list.GetMob(sbl.front()->GetFollowID());
|
||||
}
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"{} of your bots are following {}.",
|
||||
sbl.size(),
|
||||
target_mob->GetCleanName()
|
||||
follow_mob ? follow_mob->GetCleanName() : "you"
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ void bot_command_guard(Client *c, const Seperator *sep)
|
||||
}
|
||||
if (helper_is_help_or_usage(sep->arg[1])) {
|
||||
|
||||
c->Message(Chat::White, "usage: %s ([option: clear]) [actionable: byname | ownergroup | ownerraid | namesgroup | healrotation | byclass | byrace | spawned]] ([actionable_name])", sep->arg[0]);
|
||||
c->Message(Chat::White, "usage: %s ([option: clear]) [actionable: byname | ownergroup | ownerraid | namesgroup | healrotation | mmr | byclass | byrace | default: spawned] ([actionable_name])", sep->arg[0]);
|
||||
return;
|
||||
}
|
||||
const int ab_mask = (ActionableBots::ABM_Target | ActionableBots::ABM_Type2);
|
||||
@@ -20,8 +20,8 @@ void bot_command_guard(Client *c, const Seperator *sep)
|
||||
if (!clear_arg.compare("clear")) {
|
||||
|
||||
clear = true;
|
||||
ab_arg = 2;
|
||||
name_arg = 3;
|
||||
++ab_arg;
|
||||
++name_arg;
|
||||
}
|
||||
|
||||
std::string class_race_arg = sep->arg[ab_arg];
|
||||
|
||||
@@ -7,7 +7,7 @@ void bot_command_hold(Client *c, const Seperator *sep)
|
||||
}
|
||||
if (helper_is_help_or_usage(sep->arg[1])) {
|
||||
|
||||
c->Message(Chat::White, "usage: %s ([option: clear]) [actionable: byname | ownergroup | ownerraid | namesgroup | healrotation | byclass | byrace | spawned]] ([actionable_name])", sep->arg[0]);
|
||||
c->Message(Chat::White, "usage: %s ([option: clear]) [actionable: byname | ownergroup | ownerraid | namesgroup | healrotation | mmr | byclass | byrace | default: spawned] ([actionable_name])", sep->arg[0]);
|
||||
return;
|
||||
}
|
||||
const int ab_mask = (ActionableBots::ABM_Target | ActionableBots::ABM_Type2);
|
||||
@@ -20,8 +20,8 @@ void bot_command_hold(Client *c, const Seperator *sep)
|
||||
if (!clear_arg.compare("clear")) {
|
||||
|
||||
clear = true;
|
||||
ab_arg = 2;
|
||||
name_arg = 3;
|
||||
++ab_arg;
|
||||
++name_arg;
|
||||
}
|
||||
|
||||
std::string class_race_arg = sep->arg[ab_arg];
|
||||
|
||||
@@ -0,0 +1,172 @@
|
||||
#include "../bot_command.h"
|
||||
|
||||
void bot_command_illusion_block(Client* c, const Seperator* sep)
|
||||
{
|
||||
if (helper_command_alias_fail(c, "bot_command_illusion_block", sep->arg[0], "illusionblock")) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (helper_is_help_or_usage(sep->arg[1])) {
|
||||
std::vector<std::string> description =
|
||||
{
|
||||
"Toggles whether or not bots will block the illusion effects of spells cast by players or bots."
|
||||
};
|
||||
|
||||
std::vector<std::string> notes = { };
|
||||
|
||||
std::vector<std::string> example_format =
|
||||
{
|
||||
fmt::format(
|
||||
"{} [value] [actionable]"
|
||||
, sep->arg[0]
|
||||
)
|
||||
};
|
||||
std::vector<std::string> examples_one =
|
||||
{
|
||||
"To set BotA to block illusions:",
|
||||
fmt::format(
|
||||
"{} 1 byname BotA",
|
||||
sep->arg[0]
|
||||
)
|
||||
};
|
||||
std::vector<std::string> examples_two = { };
|
||||
std::vector<std::string> examples_three =
|
||||
{
|
||||
"To check the illusion block status for all bots:",
|
||||
fmt::format(
|
||||
"{} current spawned",
|
||||
sep->arg[0]
|
||||
)
|
||||
};
|
||||
|
||||
std::vector<std::string> actionables =
|
||||
{
|
||||
"target, byname, ownergroup, ownerraid, targetgroup, namesgroup, healrotationtargets, mmr, byclass, byrace, spawned"
|
||||
};
|
||||
|
||||
std::vector<std::string> options = { };
|
||||
std::vector<std::string> options_one = { };
|
||||
std::vector<std::string> options_two = { };
|
||||
std::vector<std::string> options_three = { };
|
||||
|
||||
std::string popup_text = c->SendCommandHelpWindow(
|
||||
c,
|
||||
description,
|
||||
notes,
|
||||
example_format,
|
||||
examples_one, examples_two, examples_three,
|
||||
actionables,
|
||||
options,
|
||||
options_one, options_two, options_three
|
||||
);
|
||||
|
||||
popup_text = DialogueWindow::Table(popup_text);
|
||||
|
||||
c->SendPopupToClient(sep->arg[0], popup_text.c_str());
|
||||
c->Message(
|
||||
Chat::Yellow,
|
||||
fmt::format(
|
||||
"Use {} for information about race/class IDs.",
|
||||
Saylink::Silent("^classracelist")
|
||||
).c_str()
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
std::string arg1 = sep->arg[1];
|
||||
|
||||
if (!arg1.compare("listid") || !arg1.compare("listname")) {
|
||||
c->CastToBot()->SendSpellTypesWindow(c, sep->arg[0], sep->arg[1], sep->arg[2]);
|
||||
return;
|
||||
}
|
||||
|
||||
int ab_arg = 1;
|
||||
bool current_check = false;
|
||||
uint32 typeValue = 0;
|
||||
|
||||
if (sep->IsNumber(1)) {
|
||||
typeValue = atoi(sep->arg[1]);
|
||||
++ab_arg;
|
||||
if (typeValue < 0 || typeValue > 1) {
|
||||
c->Message(Chat::Yellow, "You must enter either 0 for disabled or 1 for enabled.");
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (!arg1.compare("current")) {
|
||||
++ab_arg;
|
||||
current_check = true;
|
||||
}
|
||||
else {
|
||||
c->Message(
|
||||
Chat::Yellow,
|
||||
fmt::format(
|
||||
"Incorrect argument, use {} for information regarding this command.",
|
||||
Saylink::Silent(
|
||||
fmt::format("{} help", sep->arg[0])
|
||||
)
|
||||
).c_str()
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const int ab_mask = ActionableBots::ABM_Type1;
|
||||
std::string class_race_arg = sep->arg[ab_arg];
|
||||
bool class_race_check = false;
|
||||
if (!class_race_arg.compare("byclass") || !class_race_arg.compare("byrace")) {
|
||||
class_race_check = true;
|
||||
}
|
||||
|
||||
std::list<Bot*> sbl;
|
||||
if (ActionableBots::PopulateSBL(c, sep->arg[ab_arg], sbl, ab_mask, !class_race_check ? sep->arg[ab_arg + 1] : nullptr, class_race_check ? atoi(sep->arg[ab_arg + 1]) : 0) == ActionableBots::ABT_None) {
|
||||
return;
|
||||
}
|
||||
|
||||
sbl.remove(nullptr);
|
||||
|
||||
Bot* first_found = nullptr;
|
||||
int success_count = 0;
|
||||
for (auto my_bot : sbl) {
|
||||
if (!first_found) {
|
||||
first_found = my_bot;
|
||||
}
|
||||
if (current_check) {
|
||||
c->Message(
|
||||
Chat::Green,
|
||||
fmt::format(
|
||||
"{} says, 'I {} block illusions.'",
|
||||
my_bot->GetCleanName(),
|
||||
my_bot->GetIllusionBlock() ? "will" : "will not"
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
else {
|
||||
my_bot->SetIllusionBlock(typeValue);
|
||||
++success_count;
|
||||
}
|
||||
}
|
||||
if (!current_check) {
|
||||
if (success_count == 1 && first_found) {
|
||||
c->Message(
|
||||
Chat::Green,
|
||||
fmt::format(
|
||||
"{} says, 'I {} block illusions.'",
|
||||
first_found->GetCleanName(),
|
||||
first_found->GetIllusionBlock() ? "will now" : "will no longer"
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
else {
|
||||
c->Message(
|
||||
Chat::Green,
|
||||
fmt::format(
|
||||
"{} of your bots {} block illusions.",
|
||||
success_count,
|
||||
typeValue ? "will now" : "will no longer"
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -217,9 +217,18 @@ void bot_command_inventory_remove(Client* c, const Seperator* sep)
|
||||
}
|
||||
|
||||
const auto* itm = inst->GetItem();
|
||||
EQ::SayLinkEngine linker;
|
||||
linker.SetLinkType(EQ::saylink::SayLinkItemInst);
|
||||
linker.SetItemInst(inst);
|
||||
|
||||
if (inst && itm && c->CheckLoreConflict(itm)) {
|
||||
c->MessageString(Chat::White, PICK_LORE);
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"You cannot pick up {} because it is a lore item you already possess.",
|
||||
linker.GenerateLink()
|
||||
).c_str()
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -233,7 +242,13 @@ void bot_command_inventory_remove(Client* c, const Seperator* sep)
|
||||
continue;
|
||||
}
|
||||
|
||||
c->MessageString(Chat::White, PICK_LORE);
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"You cannot pick up {} because it is a lore item you already possess.",
|
||||
linker.GenerateLink()
|
||||
).c_str()
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -247,7 +262,7 @@ void bot_command_inventory_remove(Client* c, const Seperator* sep)
|
||||
slot_id == EQ::invslot::slotRange ||
|
||||
slot_id == EQ::invslot::slotAmmo
|
||||
) {
|
||||
my_bot->SetBotArcherySetting(false, true);
|
||||
my_bot->SetBotRangedSetting(false);
|
||||
}
|
||||
|
||||
my_bot->RemoveBotItemBySlot(slot_id);
|
||||
|
||||
@@ -0,0 +1,172 @@
|
||||
#include "../bot_command.h"
|
||||
|
||||
void bot_command_max_melee_range(Client* c, const Seperator* sep)
|
||||
{
|
||||
if (helper_command_alias_fail(c, "bot_command_max_melee_range", sep->arg[0], "maxmeleerange")) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (helper_is_help_or_usage(sep->arg[1])) {
|
||||
std::vector<std::string> description =
|
||||
{
|
||||
"Toggles whether or not bots will stay at max melee range during combat."
|
||||
};
|
||||
|
||||
std::vector<std::string> notes = { };
|
||||
|
||||
std::vector<std::string> example_format =
|
||||
{
|
||||
fmt::format(
|
||||
"{} [value] [actionable]"
|
||||
, sep->arg[0]
|
||||
)
|
||||
};
|
||||
std::vector<std::string> examples_one =
|
||||
{
|
||||
"To set BotA to stay at max melee range:",
|
||||
fmt::format(
|
||||
"{} 1 byname BotA",
|
||||
sep->arg[0]
|
||||
)
|
||||
};
|
||||
std::vector<std::string> examples_two = { };
|
||||
std::vector<std::string> examples_three =
|
||||
{
|
||||
"To check the max melee range status for all bots:",
|
||||
fmt::format(
|
||||
"{} current spawned",
|
||||
sep->arg[0]
|
||||
)
|
||||
};
|
||||
|
||||
std::vector<std::string> actionables =
|
||||
{
|
||||
"target, byname, ownergroup, ownerraid, targetgroup, namesgroup, healrotationtargets, mmr, byclass, byrace, spawned"
|
||||
};
|
||||
|
||||
std::vector<std::string> options = { };
|
||||
std::vector<std::string> options_one = { };
|
||||
std::vector<std::string> options_two = { };
|
||||
std::vector<std::string> options_three = { };
|
||||
|
||||
std::string popup_text = c->SendCommandHelpWindow(
|
||||
c,
|
||||
description,
|
||||
notes,
|
||||
example_format,
|
||||
examples_one, examples_two, examples_three,
|
||||
actionables,
|
||||
options,
|
||||
options_one, options_two, options_three
|
||||
);
|
||||
|
||||
popup_text = DialogueWindow::Table(popup_text);
|
||||
|
||||
c->SendPopupToClient(sep->arg[0], popup_text.c_str());
|
||||
c->Message(
|
||||
Chat::Yellow,
|
||||
fmt::format(
|
||||
"Use {} for information about race/class IDs.",
|
||||
Saylink::Silent("^classracelist")
|
||||
).c_str()
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
std::string arg1 = sep->arg[1];
|
||||
|
||||
if (!arg1.compare("listid") || !arg1.compare("listname")) {
|
||||
c->CastToBot()->SendSpellTypesWindow(c, sep->arg[0], sep->arg[1], sep->arg[2]);
|
||||
return;
|
||||
}
|
||||
|
||||
int ab_arg = 1;
|
||||
bool current_check = false;
|
||||
uint32 typeValue = 0;
|
||||
|
||||
if (sep->IsNumber(1)) {
|
||||
typeValue = atoi(sep->arg[1]);
|
||||
++ab_arg;
|
||||
if (typeValue < 0 || typeValue > 1) {
|
||||
c->Message(Chat::Yellow, "You must enter either 0 for disabled or 1 for enabled.");
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (!arg1.compare("current")) {
|
||||
++ab_arg;
|
||||
current_check = true;
|
||||
}
|
||||
else {
|
||||
c->Message(
|
||||
Chat::Yellow,
|
||||
fmt::format(
|
||||
"Incorrect argument, use {} for information regarding this command.",
|
||||
Saylink::Silent(
|
||||
fmt::format("{} help", sep->arg[0])
|
||||
)
|
||||
).c_str()
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const int ab_mask = ActionableBots::ABM_Type1;
|
||||
std::string class_race_arg = sep->arg[ab_arg];
|
||||
bool class_race_check = false;
|
||||
if (!class_race_arg.compare("byclass") || !class_race_arg.compare("byrace")) {
|
||||
class_race_check = true;
|
||||
}
|
||||
|
||||
std::list<Bot*> sbl;
|
||||
if (ActionableBots::PopulateSBL(c, sep->arg[ab_arg], sbl, ab_mask, !class_race_check ? sep->arg[ab_arg + 1] : nullptr, class_race_check ? atoi(sep->arg[ab_arg + 1]) : 0) == ActionableBots::ABT_None) {
|
||||
return;
|
||||
}
|
||||
|
||||
sbl.remove(nullptr);
|
||||
|
||||
Bot* first_found = nullptr;
|
||||
int success_count = 0;
|
||||
for (auto my_bot : sbl) {
|
||||
if (!first_found) {
|
||||
first_found = my_bot;
|
||||
}
|
||||
if (current_check) {
|
||||
c->Message(
|
||||
Chat::Green,
|
||||
fmt::format(
|
||||
"{} says, 'I {} stay at max melee range.'",
|
||||
my_bot->GetCleanName(),
|
||||
my_bot->GetMaxMeleeRange() ? "will" : "will not"
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
else {
|
||||
my_bot->SetMaxMeleeRange(typeValue);
|
||||
++success_count;
|
||||
}
|
||||
}
|
||||
if (!current_check) {
|
||||
if (success_count == 1 && first_found) {
|
||||
c->Message(
|
||||
Chat::Green,
|
||||
fmt::format(
|
||||
"{} says, 'I {} stay at max melee range.'",
|
||||
first_found->GetCleanName(),
|
||||
first_found->GetMaxMeleeRange() ? "will now" : "will no longer"
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
else {
|
||||
c->Message(
|
||||
Chat::Green,
|
||||
fmt::format(
|
||||
"{} of your bots {} stay at max melee range.",
|
||||
success_count,
|
||||
typeValue ? "will now" : "will no longer"
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,42 +2,40 @@
|
||||
|
||||
void bot_command_mesmerize(Client *c, const Seperator *sep)
|
||||
{
|
||||
bcst_list* local_list = &bot_command_spells[BCEnum::SpT_Mesmerize];
|
||||
if (helper_spell_list_fail(c, local_list, BCEnum::SpT_Mesmerize) || helper_command_alias_fail(c, "bot_command_mesmerize", sep->arg[0], "mesmerize"))
|
||||
return;
|
||||
if (helper_is_help_or_usage(sep->arg[1])) {
|
||||
c->Message(Chat::White, "usage: <enemy_target> %s", sep->arg[0]);
|
||||
helper_send_usage_required_bots(c, BCEnum::SpT_Mesmerize);
|
||||
return;
|
||||
}
|
||||
|
||||
ActionableTarget::Types actionable_targets;
|
||||
Bot* my_bot = nullptr;
|
||||
bool isSuccess = false;
|
||||
std::list<Bot*> sbl;
|
||||
MyBots::PopulateSBL_BySpawnedBots(c, sbl);
|
||||
|
||||
for (auto list_iter : *local_list) {
|
||||
auto local_entry = list_iter;
|
||||
if (helper_spell_check_fail(local_entry))
|
||||
continue;
|
||||
for (auto bot_iter : sbl) {
|
||||
std::list<BotSpell_wPriority> botSpellList = bot_iter->GetPrioritizedBotSpellsBySpellType(bot_iter, BotSpellTypes::Mez, c->GetTarget(), IsAEBotSpellType(BotSpellTypes::Mez));
|
||||
|
||||
auto target_mob = actionable_targets.Select(c, local_entry->target_type, ENEMY);
|
||||
if (!target_mob)
|
||||
continue;
|
||||
for (const auto& s : botSpellList) {
|
||||
if (!IsValidSpell(s.SpellId)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (spells[local_entry->spell_id].max_value[EFFECTIDTOINDEX(1)] < target_mob->GetLevel())
|
||||
continue;
|
||||
if (!bot_iter->IsInGroupOrRaid()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
my_bot = ActionableBots::Select_ByMinLevelAndClass(c, local_entry->target_type, sbl, local_entry->spell_level, local_entry->caster_class, target_mob);
|
||||
if (!my_bot)
|
||||
continue;
|
||||
if (!bot_iter->CastChecks(s.SpellId, c->GetTarget(), BotSpellTypes::Mez, false, false)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
uint32 dont_root_before = 0;
|
||||
if (helper_cast_standard_spell(my_bot, target_mob, local_entry->spell_id, true, &dont_root_before))
|
||||
target_mob->SetDontRootMeBefore(dont_root_before);
|
||||
|
||||
break;
|
||||
if (bot_iter->CommandedDoSpellCast(s.SpellIndex, c->GetTarget(), s.ManaCost)) {
|
||||
bot_iter->BotGroupSay(bot_iter, "Casting %s [%s] on %s.", GetSpellName(s.SpellId), bot_iter->GetSpellTypeNameByID(BotSpellTypes::Mez), c->GetTarget()->GetCleanName());
|
||||
isSuccess = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
helper_no_available_bots(c, my_bot);
|
||||
if (!isSuccess) {
|
||||
helper_no_available_bots(c);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ void bot_command_pet_get_lost(Client *c, const Seperator *sep)
|
||||
if (helper_command_alias_fail(c, "bot_command_pet_get_lost", sep->arg[0], "petgetlost"))
|
||||
return;
|
||||
if (helper_is_help_or_usage(sep->arg[1])) {
|
||||
c->Message(Chat::White, "usage: %s ([actionable: target | byname | ownergroup | targetgroup | namesgroup | healrotation | spawned] ([actionable_name]))", sep->arg[0]);
|
||||
c->Message(Chat::White, "usage: %s ([actionable: target | byname | ownergroup | ownerraid | targetgroup | namesgroup | healrotationmembers | healrotationtargets | mmr | byclass | byrace | spawned] ([actionable_name]))", sep->arg[0]);
|
||||
return;
|
||||
}
|
||||
int ab_mask = ActionableBots::ABM_NoFilter;
|
||||
@@ -98,7 +98,8 @@ void bot_command_pet_set_type(Client *c, const Seperator *sep)
|
||||
if (helper_command_alias_fail(c, "bot_command_pet_set_type", sep->arg[0], "petsettype"))
|
||||
return;
|
||||
if (helper_is_help_or_usage(sep->arg[1])) {
|
||||
c->Message(Chat::White, "usage: %s [type: water | fire | air | earth | monster] ([actionable: target | byname] ([actionable_name]))", sep->arg[0]);
|
||||
c->Message(Chat::White, "usage: %s [type: auto | water | fire | air | earth | monster | epic] ([actionable: target | byname] ([actionable_name]))", sep->arg[0]);
|
||||
c->Message(Chat::White, "if set to 'auto', bots will choose their own pet type");
|
||||
c->Message(Chat::White, "requires one of the following bot classes:");
|
||||
c->Message(Chat::White, "Magician(1)");
|
||||
return;
|
||||
@@ -109,29 +110,41 @@ void bot_command_pet_set_type(Client *c, const Seperator *sep)
|
||||
|
||||
uint8 pet_type = 255;
|
||||
uint8 level_req = 255;
|
||||
if (!pet_arg.compare("water")) {
|
||||
if (!pet_arg.compare("auto")) {
|
||||
pet_type = 0;
|
||||
level_req = 1;
|
||||
}
|
||||
else if (!pet_arg.compare("fire")) {
|
||||
else if (!pet_arg.compare("water")) {
|
||||
pet_type = 1;
|
||||
level_req = 1;
|
||||
}
|
||||
else if (!pet_arg.compare("fire")) {
|
||||
pet_type = 2;
|
||||
level_req = 3;
|
||||
}
|
||||
else if (!pet_arg.compare("air")) {
|
||||
pet_type = 2;
|
||||
pet_type = 3;
|
||||
level_req = 4;
|
||||
}
|
||||
else if (!pet_arg.compare("earth")) {
|
||||
pet_type = 3;
|
||||
pet_type = 4;
|
||||
level_req = 5;
|
||||
}
|
||||
else if (!pet_arg.compare("monster")) {
|
||||
pet_type = 4;
|
||||
pet_type = 5;
|
||||
level_req = 30;
|
||||
}
|
||||
else if (!pet_arg.compare("epic")) {
|
||||
pet_type = 6;
|
||||
if (!RuleB(Bots, AllowMagicianEpicPet)) {
|
||||
c->Message(Chat::Yellow, "Epic pets are currently disabled for bots.");
|
||||
return;
|
||||
}
|
||||
level_req = RuleI(Bots,AllowMagicianEpicPetLevel);
|
||||
}
|
||||
|
||||
if (pet_type == 255) {
|
||||
c->Message(Chat::White, "You must specify a pet [type: water | fire | air | earth | monster]");
|
||||
c->Message(Chat::White, "You must specify a pet [type: auto | water | fire | air | earth | monster | epic]");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -157,7 +170,23 @@ void bot_command_pet_set_type(Client *c, const Seperator *sep)
|
||||
if (!bot_iter)
|
||||
continue;
|
||||
|
||||
bot_iter->SetPetChooser(true);
|
||||
if (RuleI(Bots, RequiredMagicianEpicPetItemID) > 0) {
|
||||
bool has_item = bot_iter->HasBotItem(RuleI(Bots, RequiredMagicianEpicPetItemID)) != INVALID_INDEX;
|
||||
|
||||
if (!has_item) {
|
||||
c->Message(
|
||||
Chat::Say,
|
||||
fmt::format(
|
||||
"{} says, 'I require {} to cast an epic pet which I do not currently possess.'",
|
||||
bot_iter->GetCleanName(),
|
||||
(database.GetItem(RuleI(Bots, RequiredMagicianEpicPetItemID)) ? database.CreateItemLink(RuleI(Bots, RequiredMagicianEpicPetItemID)) : "an item")
|
||||
).c_str()
|
||||
);
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
bot_iter->SetPetChooserID(pet_type);
|
||||
if (bot_iter->GetPet()) {
|
||||
auto pet_id = bot_iter->GetPetID();
|
||||
|
||||
@@ -7,15 +7,27 @@ void bot_command_pull(Client *c, const Seperator *sep)
|
||||
}
|
||||
if (helper_is_help_or_usage(sep->arg[1])) {
|
||||
|
||||
c->Message(Chat::White, "usage: <enemy_target> %s", sep->arg[0]);
|
||||
c->Message(Chat::White, "usage: <enemy_target> %s ([actionable: target | byname | ownergroup | ownerraid | targetgroup | namesgroup | healrotationtargets | mmr | byclass | byrace | spawned] ([actionable_name]))", sep->arg[0]);
|
||||
return;
|
||||
}
|
||||
int ab_mask = ActionableBots::ABM_OwnerGroup; // existing behavior - need to add c->IsGrouped() check and modify code if different behavior is desired
|
||||
|
||||
const int ab_mask = ActionableBots::ABM_Type1;
|
||||
|
||||
std::string arg1 = sep->arg[1];
|
||||
int ab_arg = 1;
|
||||
std::string class_race_arg = sep->arg[ab_arg];
|
||||
bool class_race_check = false;
|
||||
|
||||
if (!class_race_arg.compare("byclass") || !class_race_arg.compare("byrace")) {
|
||||
class_race_check = true;
|
||||
}
|
||||
|
||||
std::list<Bot*> sbl;
|
||||
if (ActionableBots::PopulateSBL(c, "ownergroup", sbl, ab_mask) == ActionableBots::ABT_None) {
|
||||
|
||||
if (ActionableBots::PopulateSBL(c, sep->arg[ab_arg], sbl, ab_mask, !class_race_check ? sep->arg[ab_arg + 1] : nullptr, class_race_check ? atoi(sep->arg[ab_arg + 1]) : 0) == ActionableBots::ABT_None) {
|
||||
return;
|
||||
}
|
||||
|
||||
sbl.remove(nullptr);
|
||||
|
||||
auto target_mob = ActionableTarget::VerifyEnemy(c, BCEnum::TT_Single);
|
||||
|
||||
@@ -5,7 +5,7 @@ void bot_command_release(Client *c, const Seperator *sep)
|
||||
if (helper_command_alias_fail(c, "bot_command_release", sep->arg[0], "release"))
|
||||
return;
|
||||
if (helper_is_help_or_usage(sep->arg[1])) {
|
||||
c->Message(Chat::White, "usage: %s ([actionable: <any>] ([actionable_name]))", sep->arg[0]);
|
||||
c->Message(Chat::White, "usage: %s ([actionable: target | byname | ownergroup | ownerraid | targetgroup | namesgroup | healrotationmembers | healrotationtargets | mmr | byclass | byrace | spawned] ([actionable_name]))", sep->arg[0]);
|
||||
return;
|
||||
}
|
||||
const int ab_mask = ActionableBots::ABM_NoFilter;
|
||||
|
||||
@@ -0,0 +1,172 @@
|
||||
#include "../bot_command.h"
|
||||
|
||||
void bot_command_sit_hp_percent(Client* c, const Seperator* sep)
|
||||
{
|
||||
if (helper_command_alias_fail(c, "bot_command_sit_hp_percent", sep->arg[0], "sithppercent")) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (helper_is_help_or_usage(sep->arg[1])) {
|
||||
std::vector<std::string> description =
|
||||
{
|
||||
"HP % threshold when bots will sit in combat if allowed."
|
||||
};
|
||||
|
||||
std::vector<std::string> notes = { };
|
||||
|
||||
std::vector<std::string> example_format =
|
||||
{
|
||||
fmt::format(
|
||||
"{} [value] [actionable]"
|
||||
, sep->arg[0]
|
||||
)
|
||||
};
|
||||
std::vector<std::string> examples_one =
|
||||
{
|
||||
"To set Clerics to sit at 45% HP:",
|
||||
fmt::format(
|
||||
"{} 45 byclass 2",
|
||||
sep->arg[0]
|
||||
)
|
||||
};
|
||||
std::vector<std::string> examples_two = { };
|
||||
std::vector<std::string> examples_three =
|
||||
{
|
||||
"To check the HP threshold for all bots:",
|
||||
fmt::format(
|
||||
"{} current spawned",
|
||||
sep->arg[0]
|
||||
)
|
||||
};
|
||||
|
||||
std::vector<std::string> actionables =
|
||||
{
|
||||
"target, byname, ownergroup, ownerraid, targetgroup, namesgroup, healrotationtargets, mmr, byclass, byrace, spawned"
|
||||
};
|
||||
|
||||
std::vector<std::string> options = { };
|
||||
std::vector<std::string> options_one = { };
|
||||
std::vector<std::string> options_two = { };
|
||||
std::vector<std::string> options_three = { };
|
||||
|
||||
std::string popup_text = c->SendCommandHelpWindow(
|
||||
c,
|
||||
description,
|
||||
notes,
|
||||
example_format,
|
||||
examples_one, examples_two, examples_three,
|
||||
actionables,
|
||||
options,
|
||||
options_one, options_two, options_three
|
||||
);
|
||||
|
||||
popup_text = DialogueWindow::Table(popup_text);
|
||||
|
||||
c->SendPopupToClient(sep->arg[0], popup_text.c_str());
|
||||
c->Message(
|
||||
Chat::Yellow,
|
||||
fmt::format(
|
||||
"Use {} for information about race/class IDs.",
|
||||
Saylink::Silent("^classracelist")
|
||||
).c_str()
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
std::string arg1 = sep->arg[1];
|
||||
|
||||
if (!arg1.compare("listid") || !arg1.compare("listname")) {
|
||||
c->CastToBot()->SendSpellTypesWindow(c, sep->arg[0], sep->arg[1], sep->arg[2]);
|
||||
return;
|
||||
}
|
||||
|
||||
int ab_arg = 1;
|
||||
bool current_check = false;
|
||||
uint32 typeValue = 0;
|
||||
|
||||
if (sep->IsNumber(1)) {
|
||||
typeValue = atoi(sep->arg[1]);
|
||||
++ab_arg;
|
||||
if (typeValue < 0 || typeValue > 100) {
|
||||
c->Message(Chat::Yellow, "You must enter a value between 0-100 (0%% to 100%% of health).");
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (!arg1.compare("current")) {
|
||||
++ab_arg;
|
||||
current_check = true;
|
||||
}
|
||||
else {
|
||||
c->Message(
|
||||
Chat::Yellow,
|
||||
fmt::format(
|
||||
"Incorrect argument, use {} for information regarding this command.",
|
||||
Saylink::Silent(
|
||||
fmt::format("{} help", sep->arg[0])
|
||||
)
|
||||
).c_str()
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const int ab_mask = ActionableBots::ABM_Type1;
|
||||
std::string class_race_arg = sep->arg[ab_arg];
|
||||
bool class_race_check = false;
|
||||
if (!class_race_arg.compare("byclass") || !class_race_arg.compare("byrace")) {
|
||||
class_race_check = true;
|
||||
}
|
||||
|
||||
std::list<Bot*> sbl;
|
||||
if (ActionableBots::PopulateSBL(c, sep->arg[ab_arg], sbl, ab_mask, !class_race_check ? sep->arg[ab_arg + 1] : nullptr, class_race_check ? atoi(sep->arg[ab_arg + 1]) : 0) == ActionableBots::ABT_None) {
|
||||
return;
|
||||
}
|
||||
|
||||
sbl.remove(nullptr);
|
||||
|
||||
Bot* first_found = nullptr;
|
||||
int success_count = 0;
|
||||
for (auto my_bot : sbl) {
|
||||
if (!first_found) {
|
||||
first_found = my_bot;
|
||||
}
|
||||
if (current_check) {
|
||||
c->Message(
|
||||
Chat::Green,
|
||||
fmt::format(
|
||||
"{} says, 'I sit in combat whem at or below [{}%%] HP.'",
|
||||
my_bot->GetCleanName(),
|
||||
my_bot->GetHPWhenToMed()
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
else {
|
||||
my_bot->SetHPWhenToMed(typeValue);
|
||||
++success_count;
|
||||
}
|
||||
}
|
||||
if (!current_check) {
|
||||
if (success_count == 1 && first_found) {
|
||||
c->Message(
|
||||
Chat::Green,
|
||||
fmt::format(
|
||||
"{} says, 'I will now sit in combat whem at or below [{}%%] HP.'",
|
||||
first_found->GetCleanName(),
|
||||
first_found->GetHPWhenToMed()
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
else {
|
||||
c->Message(
|
||||
Chat::Green,
|
||||
fmt::format(
|
||||
"{} of your bots will now sit in combat whem at or below [{}%%] HP.'",
|
||||
success_count,
|
||||
typeValue
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,172 @@
|
||||
#include "../bot_command.h"
|
||||
|
||||
void bot_command_sit_in_combat(Client* c, const Seperator* sep)
|
||||
{
|
||||
if (helper_command_alias_fail(c, "bot_command_sit_in_combat", sep->arg[0], "sitincombat")) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (helper_is_help_or_usage(sep->arg[1])) {
|
||||
std::vector<std::string> description =
|
||||
{
|
||||
"Toggles whether or not bots will sit in combat to heal or med."
|
||||
};
|
||||
|
||||
std::vector<std::string> notes = { };
|
||||
|
||||
std::vector<std::string> example_format =
|
||||
{
|
||||
fmt::format(
|
||||
"{} [value] [actionable]"
|
||||
, sep->arg[0]
|
||||
)
|
||||
};
|
||||
std::vector<std::string> examples_one =
|
||||
{
|
||||
"To set Clerics to sit in combat:",
|
||||
fmt::format(
|
||||
"{} 1 byclass 2",
|
||||
sep->arg[0]
|
||||
)
|
||||
};
|
||||
std::vector<std::string> examples_two = { };
|
||||
std::vector<std::string> examples_three =
|
||||
{
|
||||
"To check the sit in combat state for all bots:",
|
||||
fmt::format(
|
||||
"{} current spawned",
|
||||
sep->arg[0]
|
||||
)
|
||||
};
|
||||
|
||||
std::vector<std::string> actionables =
|
||||
{
|
||||
"target, byname, ownergroup, ownerraid, targetgroup, namesgroup, healrotationtargets, mmr, byclass, byrace, spawned"
|
||||
};
|
||||
|
||||
std::vector<std::string> options = { };
|
||||
std::vector<std::string> options_one = { };
|
||||
std::vector<std::string> options_two = { };
|
||||
std::vector<std::string> options_three = { };
|
||||
|
||||
std::string popup_text = c->SendCommandHelpWindow(
|
||||
c,
|
||||
description,
|
||||
notes,
|
||||
example_format,
|
||||
examples_one, examples_two, examples_three,
|
||||
actionables,
|
||||
options,
|
||||
options_one, options_two, options_three
|
||||
);
|
||||
|
||||
popup_text = DialogueWindow::Table(popup_text);
|
||||
|
||||
c->SendPopupToClient(sep->arg[0], popup_text.c_str());
|
||||
c->Message(
|
||||
Chat::Yellow,
|
||||
fmt::format(
|
||||
"Use {} for information about race/class IDs.",
|
||||
Saylink::Silent("^classracelist")
|
||||
).c_str()
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
std::string arg1 = sep->arg[1];
|
||||
|
||||
if (!arg1.compare("listid") || !arg1.compare("listname")) {
|
||||
c->CastToBot()->SendSpellTypesWindow(c, sep->arg[0], sep->arg[1], sep->arg[2]);
|
||||
return;
|
||||
}
|
||||
|
||||
int ab_arg = 1;
|
||||
bool current_check = false;
|
||||
uint32 typeValue = 0;
|
||||
|
||||
if (sep->IsNumber(1)) {
|
||||
typeValue = atoi(sep->arg[1]);
|
||||
++ab_arg;
|
||||
if (typeValue < 0 || typeValue > 1) {
|
||||
c->Message(Chat::Yellow, "You must enter either 0 for disabled or 1 for enabled.");
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (!arg1.compare("current")) {
|
||||
++ab_arg;
|
||||
current_check = true;
|
||||
}
|
||||
else {
|
||||
c->Message(
|
||||
Chat::Yellow,
|
||||
fmt::format(
|
||||
"Incorrect argument, use {} for information regarding this command.",
|
||||
Saylink::Silent(
|
||||
fmt::format("{} help", sep->arg[0])
|
||||
)
|
||||
).c_str()
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const int ab_mask = ActionableBots::ABM_Type1;
|
||||
std::string class_race_arg = sep->arg[ab_arg];
|
||||
bool class_race_check = false;
|
||||
if (!class_race_arg.compare("byclass") || !class_race_arg.compare("byrace")) {
|
||||
class_race_check = true;
|
||||
}
|
||||
|
||||
std::list<Bot*> sbl;
|
||||
if (ActionableBots::PopulateSBL(c, sep->arg[ab_arg], sbl, ab_mask, !class_race_check ? sep->arg[ab_arg + 1] : nullptr, class_race_check ? atoi(sep->arg[ab_arg + 1]) : 0) == ActionableBots::ABT_None) {
|
||||
return;
|
||||
}
|
||||
|
||||
sbl.remove(nullptr);
|
||||
|
||||
Bot* first_found = nullptr;
|
||||
int success_count = 0;
|
||||
for (auto my_bot : sbl) {
|
||||
if (!first_found) {
|
||||
first_found = my_bot;
|
||||
}
|
||||
if (current_check) {
|
||||
c->Message(
|
||||
Chat::Green,
|
||||
fmt::format(
|
||||
"{} says, 'I {} sit in combat.'",
|
||||
my_bot->GetCleanName(),
|
||||
my_bot->GetMedInCombat() ? "will" : "will not"
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
else {
|
||||
my_bot->SetMedInCombat(typeValue);
|
||||
++success_count;
|
||||
}
|
||||
}
|
||||
if (!current_check) {
|
||||
if (success_count == 1 && first_found) {
|
||||
c->Message(
|
||||
Chat::Green,
|
||||
fmt::format(
|
||||
"{} says, 'I {} sit in combat.'",
|
||||
first_found->GetCleanName(),
|
||||
first_found->GetMedInCombat() ? "will now" : "will no longer"
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
else {
|
||||
c->Message(
|
||||
Chat::Green,
|
||||
fmt::format(
|
||||
"{} of your bots {} sit in combat.",
|
||||
success_count,
|
||||
typeValue ? "will now" : "will no longer"
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,172 @@
|
||||
#include "../bot_command.h"
|
||||
|
||||
void bot_command_sit_mana_percent(Client* c, const Seperator* sep)
|
||||
{
|
||||
if (helper_command_alias_fail(c, "bot_command_sit_mana_percent", sep->arg[0], "sitmanapercent")) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (helper_is_help_or_usage(sep->arg[1])) {
|
||||
std::vector<std::string> description =
|
||||
{
|
||||
"Mana % threshold when bots will sit in combat if allowed."
|
||||
};
|
||||
|
||||
std::vector<std::string> notes = { };
|
||||
|
||||
std::vector<std::string> example_format =
|
||||
{
|
||||
fmt::format(
|
||||
"{} [value] [actionable]"
|
||||
, sep->arg[0]
|
||||
)
|
||||
};
|
||||
std::vector<std::string> examples_one =
|
||||
{
|
||||
"To set Clerics to sit at 45% mana:",
|
||||
fmt::format(
|
||||
"{} 45 byclass 2",
|
||||
sep->arg[0]
|
||||
)
|
||||
};
|
||||
std::vector<std::string> examples_two = { };
|
||||
std::vector<std::string> examples_three =
|
||||
{
|
||||
"To check the mana threshold for all bots:",
|
||||
fmt::format(
|
||||
"{} current spawned",
|
||||
sep->arg[0]
|
||||
)
|
||||
};
|
||||
|
||||
std::vector<std::string> actionables =
|
||||
{
|
||||
"target, byname, ownergroup, ownerraid, targetgroup, namesgroup, healrotationtargets, mmr, byclass, byrace, spawned"
|
||||
};
|
||||
|
||||
std::vector<std::string> options = { };
|
||||
std::vector<std::string> options_one = { };
|
||||
std::vector<std::string> options_two = { };
|
||||
std::vector<std::string> options_three = { };
|
||||
|
||||
std::string popup_text = c->SendCommandHelpWindow(
|
||||
c,
|
||||
description,
|
||||
notes,
|
||||
example_format,
|
||||
examples_one, examples_two, examples_three,
|
||||
actionables,
|
||||
options,
|
||||
options_one, options_two, options_three
|
||||
);
|
||||
|
||||
popup_text = DialogueWindow::Table(popup_text);
|
||||
|
||||
c->SendPopupToClient(sep->arg[0], popup_text.c_str());
|
||||
c->Message(
|
||||
Chat::Yellow,
|
||||
fmt::format(
|
||||
"Use {} for information about race/class IDs.",
|
||||
Saylink::Silent("^classracelist")
|
||||
).c_str()
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
std::string arg1 = sep->arg[1];
|
||||
|
||||
if (!arg1.compare("listid") || !arg1.compare("listname")) {
|
||||
c->CastToBot()->SendSpellTypesWindow(c, sep->arg[0], sep->arg[1], sep->arg[2]);
|
||||
return;
|
||||
}
|
||||
|
||||
int ab_arg = 1;
|
||||
bool current_check = false;
|
||||
uint32 typeValue = 0;
|
||||
|
||||
if (sep->IsNumber(1)) {
|
||||
typeValue = atoi(sep->arg[1]);
|
||||
++ab_arg;
|
||||
if (typeValue < 0 || typeValue > 100) {
|
||||
c->Message(Chat::Yellow, "You must enter a value between 0-100 (0%% to 100%% of health).");
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (!arg1.compare("current")) {
|
||||
++ab_arg;
|
||||
current_check = true;
|
||||
}
|
||||
else {
|
||||
c->Message(
|
||||
Chat::Yellow,
|
||||
fmt::format(
|
||||
"Incorrect argument, use {} for information regarding this command.",
|
||||
Saylink::Silent(
|
||||
fmt::format("{} help", sep->arg[0])
|
||||
)
|
||||
).c_str()
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const int ab_mask = ActionableBots::ABM_Type1;
|
||||
std::string class_race_arg = sep->arg[ab_arg];
|
||||
bool class_race_check = false;
|
||||
if (!class_race_arg.compare("byclass") || !class_race_arg.compare("byrace")) {
|
||||
class_race_check = true;
|
||||
}
|
||||
|
||||
std::list<Bot*> sbl;
|
||||
if (ActionableBots::PopulateSBL(c, sep->arg[ab_arg], sbl, ab_mask, !class_race_check ? sep->arg[ab_arg + 1] : nullptr, class_race_check ? atoi(sep->arg[ab_arg + 1]) : 0) == ActionableBots::ABT_None) {
|
||||
return;
|
||||
}
|
||||
|
||||
sbl.remove(nullptr);
|
||||
|
||||
Bot* first_found = nullptr;
|
||||
int success_count = 0;
|
||||
for (auto my_bot : sbl) {
|
||||
if (!first_found) {
|
||||
first_found = my_bot;
|
||||
}
|
||||
if (current_check) {
|
||||
c->Message(
|
||||
Chat::Green,
|
||||
fmt::format(
|
||||
"{} says, 'I sit in combat whem at or below [{}%%] mana.'",
|
||||
my_bot->GetCleanName(),
|
||||
my_bot->GetManaWhenToMed()
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
else {
|
||||
my_bot->SetManaWhenToMed(typeValue);
|
||||
++success_count;
|
||||
}
|
||||
}
|
||||
if (!current_check) {
|
||||
if (success_count == 1 && first_found) {
|
||||
c->Message(
|
||||
Chat::Green,
|
||||
fmt::format(
|
||||
"{} says, 'I will now sit in combat whem at or below [{}%%] mana.'",
|
||||
first_found->GetCleanName(),
|
||||
first_found->GetManaWhenToMed()
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
else {
|
||||
c->Message(
|
||||
Chat::Green,
|
||||
fmt::format(
|
||||
"{} of your bots will now sit in combat whem at or below [{}%%] mana.'",
|
||||
success_count,
|
||||
typeValue
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -503,7 +503,7 @@ void bot_spell_info_dialogue_window(Client* c, const Seperator *sep)
|
||||
auto results = database.QueryDatabase(
|
||||
fmt::format(
|
||||
"SELECT value FROM db_str WHERE id = {} and type = 6 LIMIT 1",
|
||||
spells[spell_id].effect_description_id
|
||||
spells[spell_id].description_id
|
||||
)
|
||||
);
|
||||
|
||||
@@ -557,7 +557,7 @@ void bot_command_enforce_spell_list(Client* c, const Seperator *sep)
|
||||
}
|
||||
|
||||
bool enforce_state = (sep->argnum > 0) ? Strings::ToBool(sep->arg[1]) : !my_bot->GetBotEnforceSpellSetting();
|
||||
my_bot->SetBotEnforceSpellSetting(enforce_state, true);
|
||||
my_bot->SetBotEnforceSpellSetting(enforce_state);
|
||||
|
||||
c->Message(
|
||||
Chat::White,
|
||||
|
||||
@@ -0,0 +1,236 @@
|
||||
#include "../bot_command.h"
|
||||
|
||||
void bot_command_spell_aggro_checks(Client* c, const Seperator* sep)
|
||||
{
|
||||
if (helper_command_alias_fail(c, "bot_command_spell_aggro_checks", sep->arg[0], "spellaggrochecks")) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (helper_is_help_or_usage(sep->arg[1])) {
|
||||
std::vector<std::string> description =
|
||||
{
|
||||
"Toggles whether or not bots will cast a spell type if they think it will get them aggro"
|
||||
};
|
||||
|
||||
std::vector<std::string> notes = { };
|
||||
|
||||
std::vector<std::string> example_format =
|
||||
{
|
||||
fmt::format(
|
||||
"{} [Type Shortname] [value] [actionable]"
|
||||
, sep->arg[0]
|
||||
),
|
||||
fmt::format(
|
||||
"{} [Type ID] [value] [actionable]"
|
||||
, sep->arg[0]
|
||||
)
|
||||
};
|
||||
std::vector<std::string> examples_one =
|
||||
{
|
||||
"To set all bots to check aggro on nukes:",
|
||||
fmt::format(
|
||||
"{} {} 1 spawned",
|
||||
sep->arg[0],
|
||||
c->GetSpellTypeShortNameByID(BotSpellTypes::Nuke)
|
||||
),
|
||||
fmt::format(
|
||||
"{} {} 1 spawned",
|
||||
sep->arg[0],
|
||||
BotSpellTypes::Nuke
|
||||
)
|
||||
};
|
||||
std::vector<std::string> examples_two =
|
||||
{
|
||||
"To set Shadowknights to ignore aggro checks on snares:",
|
||||
fmt::format(
|
||||
"{} {} 0 byclass 5",
|
||||
sep->arg[0],
|
||||
c->GetSpellTypeShortNameByID(BotSpellTypes::Snare)
|
||||
),
|
||||
fmt::format(
|
||||
"{} {} 0 byclass 5",
|
||||
sep->arg[0],
|
||||
BotSpellTypes::Snare
|
||||
)
|
||||
};
|
||||
std::vector<std::string> examples_three =
|
||||
{
|
||||
"To check the current DoT aggro check on all bots:",
|
||||
fmt::format(
|
||||
"{} {} current spawned",
|
||||
sep->arg[0],
|
||||
c->GetSpellTypeShortNameByID(BotSpellTypes::DOT)
|
||||
),
|
||||
fmt::format(
|
||||
"{} {} current spawned",
|
||||
sep->arg[0],
|
||||
BotSpellTypes::DOT
|
||||
)
|
||||
};
|
||||
|
||||
std::vector<std::string> actionables =
|
||||
{
|
||||
"target, byname, ownergroup, ownerraid, targetgroup, namesgroup, healrotationtargets mmr, byclass, byrace, spawned"
|
||||
};
|
||||
|
||||
std::vector<std::string> options = { };
|
||||
std::vector<std::string> options_one = { };
|
||||
std::vector<std::string> options_two = { };
|
||||
std::vector<std::string> options_three = { };
|
||||
|
||||
std::string popup_text = c->SendCommandHelpWindow(
|
||||
c,
|
||||
description,
|
||||
notes,
|
||||
example_format,
|
||||
examples_one, examples_two, examples_three,
|
||||
actionables,
|
||||
options,
|
||||
options_one, options_two, options_three
|
||||
);
|
||||
|
||||
popup_text = DialogueWindow::Table(popup_text);
|
||||
|
||||
c->SendPopupToClient(sep->arg[0], popup_text.c_str());
|
||||
c->CastToBot()->SendSpellTypesWindow(c, sep->arg[0], "", "", true);
|
||||
c->Message(
|
||||
Chat::Yellow,
|
||||
fmt::format(
|
||||
"Use {} for information about race/class IDs.",
|
||||
Saylink::Silent("^classracelist")
|
||||
).c_str()
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
std::string arg1 = sep->arg[1];
|
||||
|
||||
if (!arg1.compare("listid") || !arg1.compare("listname")) {
|
||||
c->CastToBot()->SendSpellTypesWindow(c, sep->arg[0], sep->arg[1], sep->arg[2]);
|
||||
return;
|
||||
}
|
||||
|
||||
std::string arg2 = sep->arg[2];
|
||||
int ab_arg = 2;
|
||||
bool current_check = false;
|
||||
uint16 spellType = 0;
|
||||
uint32 typeValue = 0;
|
||||
|
||||
// String/Int type checks
|
||||
if (sep->IsNumber(1)) {
|
||||
spellType = atoi(sep->arg[1]);
|
||||
|
||||
if (spellType < BotSpellTypes::START || spellType > BotSpellTypes::END) {
|
||||
c->Message(Chat::Yellow, "You must choose a valid spell type. Spell types range from %i to %i", BotSpellTypes::START, BotSpellTypes::END);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (c->GetSpellTypeIDByShortName(arg1) != UINT16_MAX) {
|
||||
spellType = c->GetSpellTypeIDByShortName(arg1);
|
||||
}
|
||||
else {
|
||||
c->Message(
|
||||
Chat::Yellow,
|
||||
fmt::format(
|
||||
"Incorrect argument, use {} for information regarding this command.",
|
||||
Saylink::Silent(
|
||||
fmt::format("{} help", sep->arg[0])
|
||||
)
|
||||
).c_str()
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (sep->IsNumber(2)) {
|
||||
typeValue = atoi(sep->arg[2]);
|
||||
++ab_arg;
|
||||
if (typeValue < 0 || typeValue > 1) {
|
||||
c->Message(Chat::Yellow, "You must enter either 0 for disabled or 1 for enabled.");
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (!arg2.compare("current")) {
|
||||
++ab_arg;
|
||||
current_check = true;
|
||||
}
|
||||
else {
|
||||
c->Message(
|
||||
Chat::Yellow,
|
||||
fmt::format(
|
||||
"Incorrect argument, use {} for information regarding this command.",
|
||||
Saylink::Silent(
|
||||
fmt::format("{} help", sep->arg[0])
|
||||
)
|
||||
).c_str()
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const int ab_mask = ActionableBots::ABM_Type1;
|
||||
std::string class_race_arg = sep->arg[ab_arg];
|
||||
bool class_race_check = false;
|
||||
if (!class_race_arg.compare("byclass") || !class_race_arg.compare("byrace")) {
|
||||
class_race_check = true;
|
||||
}
|
||||
|
||||
std::list<Bot*> sbl;
|
||||
if (ActionableBots::PopulateSBL(c, sep->arg[ab_arg], sbl, ab_mask, !class_race_check ? sep->arg[ab_arg + 1] : nullptr, class_race_check ? atoi(sep->arg[ab_arg + 1]) : 0) == ActionableBots::ABT_None) {
|
||||
return;
|
||||
}
|
||||
|
||||
sbl.remove(nullptr);
|
||||
|
||||
Bot* first_found = nullptr;
|
||||
int success_count = 0;
|
||||
for (auto my_bot : sbl) {
|
||||
if (!first_found) {
|
||||
first_found = my_bot;
|
||||
}
|
||||
if (current_check) {
|
||||
c->Message(
|
||||
Chat::Green,
|
||||
fmt::format(
|
||||
"{} says, 'My [{}] aggro check is currently [{}].'",
|
||||
my_bot->GetCleanName(),
|
||||
c->GetSpellTypeNameByID(spellType),
|
||||
my_bot->GetSpellTypeAggroCheck(spellType) ? "enabled" : "disabled"
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
else {
|
||||
my_bot->SetSpellTypeAggroCheck(spellType, typeValue);
|
||||
++success_count;
|
||||
}
|
||||
}
|
||||
if (!current_check) {
|
||||
if (success_count == 1 && first_found) {
|
||||
c->Message(
|
||||
Chat::Green,
|
||||
fmt::format(
|
||||
"{} says, 'My [{}] aggro check was [{}].'",
|
||||
first_found->GetCleanName(),
|
||||
c->GetSpellTypeNameByID(spellType),
|
||||
first_found->GetSpellTypeAggroCheck(spellType) ? "enabled" : "disabled"
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
else {
|
||||
c->Message(
|
||||
Chat::Green,
|
||||
fmt::format(
|
||||
"{} of your bots [{}] their [{}] aggro check.",
|
||||
success_count,
|
||||
c->GetSpellTypeNameByID(spellType),
|
||||
typeValue ? "enabled" : "disabled"
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,242 @@
|
||||
#include "../bot_command.h"
|
||||
|
||||
void bot_command_spell_delays(Client* c, const Seperator* sep)
|
||||
{
|
||||
if (helper_command_alias_fail(c, "bot_command_spell_delays", sep->arg[0], "spelldelays")) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (helper_is_help_or_usage(sep->arg[1])) {
|
||||
std::vector<std::string> description =
|
||||
{
|
||||
"Controls how long a bot will wait between casts of different spell types"
|
||||
};
|
||||
|
||||
std::vector<std::string> notes =
|
||||
{
|
||||
"- All pet types are based off the pet's owner's setting",
|
||||
"- Any remaining types use the owner's setting when a pet is the target",
|
||||
"- All Heals, Cures, Buffs (DS and resists included) are based off the target's setting, not the caster",
|
||||
"- e.g., BotA is healing BotB using BotB's settings",
|
||||
};
|
||||
|
||||
std::vector<std::string> example_format =
|
||||
{
|
||||
fmt::format(
|
||||
"{} [Type Shortname] [value] [actionable]"
|
||||
, sep->arg[0]
|
||||
),
|
||||
fmt::format(
|
||||
"{} [Type ID] [value] [actionable]"
|
||||
, sep->arg[0]
|
||||
)
|
||||
};
|
||||
std::vector<std::string> examples_one =
|
||||
{
|
||||
"To set all Necromancers to an 8s DoT delay:",
|
||||
fmt::format(
|
||||
"{} {} 8000 byclass 11",
|
||||
sep->arg[0],
|
||||
c->GetSpellTypeShortNameByID(BotSpellTypes::DOT)
|
||||
),
|
||||
fmt::format(
|
||||
"{} {} 8000 byclass 11",
|
||||
sep->arg[0],
|
||||
BotSpellTypes::DOT
|
||||
)
|
||||
};
|
||||
std::vector<std::string> examples_two =
|
||||
{
|
||||
"To set all Warriors to receive Fast Heals every 2.5s:",
|
||||
fmt::format(
|
||||
"{} {} 2500 byclass 1",
|
||||
sep->arg[0],
|
||||
c->GetSpellTypeShortNameByID(BotSpellTypes::FastHeals)
|
||||
),
|
||||
fmt::format(
|
||||
"{} {} 2500 byclass 1",
|
||||
sep->arg[0],
|
||||
BotSpellTypes::FastHeals
|
||||
)
|
||||
};
|
||||
std::vector<std::string> examples_three =
|
||||
{
|
||||
"To check the current Nuke delay on all bots:",
|
||||
fmt::format(
|
||||
"{} {} current spawned",
|
||||
sep->arg[0],
|
||||
c->GetSpellTypeShortNameByID(BotSpellTypes::Nuke)
|
||||
),
|
||||
fmt::format(
|
||||
"{} {} current spawned",
|
||||
sep->arg[0],
|
||||
BotSpellTypes::Nuke
|
||||
)
|
||||
};
|
||||
|
||||
std::vector<std::string> actionables =
|
||||
{
|
||||
"target, byname, ownergroup, ownerraid targetgroup, namesgroup, healrotationtargets mmr, byclass, byrace, spawned"
|
||||
};
|
||||
|
||||
std::vector<std::string> options = { };
|
||||
std::vector<std::string> options_one = { };
|
||||
std::vector<std::string> options_two = { };
|
||||
std::vector<std::string> options_three = { };
|
||||
|
||||
std::string popup_text = c->SendCommandHelpWindow(
|
||||
c,
|
||||
description,
|
||||
notes,
|
||||
example_format,
|
||||
examples_one, examples_two, examples_three,
|
||||
actionables,
|
||||
options,
|
||||
options_one, options_two, options_three
|
||||
);
|
||||
|
||||
popup_text = DialogueWindow::Table(popup_text);
|
||||
|
||||
c->SendPopupToClient(sep->arg[0], popup_text.c_str());
|
||||
c->CastToBot()->SendSpellTypesWindow(c, sep->arg[0], "", "", true);
|
||||
c->Message(
|
||||
Chat::Yellow,
|
||||
fmt::format(
|
||||
"Use {} for information about race/class IDs.",
|
||||
Saylink::Silent("^classracelist")
|
||||
).c_str()
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
std::string arg1 = sep->arg[1];
|
||||
|
||||
if (!arg1.compare("listid") || !arg1.compare("listname")) {
|
||||
c->CastToBot()->SendSpellTypesWindow(c, sep->arg[0], sep->arg[1], sep->arg[2]);
|
||||
return;
|
||||
}
|
||||
|
||||
std::string arg2 = sep->arg[2];
|
||||
int ab_arg = 2;
|
||||
bool current_check = false;
|
||||
uint16 spellType = 0;
|
||||
uint32 typeValue = 0;
|
||||
|
||||
// String/Int type checks
|
||||
if (sep->IsNumber(1)) {
|
||||
spellType = atoi(sep->arg[1]);
|
||||
|
||||
if (spellType < BotSpellTypes::START || spellType > BotSpellTypes::END) {
|
||||
c->Message(Chat::Yellow, "You must choose a valid spell type. Spell types range from %i to %i", BotSpellTypes::START, BotSpellTypes::END);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (c->GetSpellTypeIDByShortName(arg1) != UINT16_MAX) {
|
||||
spellType = c->GetSpellTypeIDByShortName(arg1);
|
||||
}
|
||||
else {
|
||||
c->Message(
|
||||
Chat::Yellow,
|
||||
fmt::format(
|
||||
"Incorrect argument, use {} for information regarding this command.",
|
||||
Saylink::Silent(
|
||||
fmt::format("{} help", sep->arg[0])
|
||||
)
|
||||
).c_str()
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (sep->IsNumber(2)) {
|
||||
typeValue = atoi(sep->arg[2]);
|
||||
++ab_arg;
|
||||
if (typeValue < 1 || typeValue > 60000) {
|
||||
c->Message(Chat::Yellow, "You must enter a value between 1-60000 (1ms to 60s).");
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (!arg2.compare("current")) {
|
||||
++ab_arg;
|
||||
current_check = true;
|
||||
}
|
||||
else {
|
||||
c->Message(
|
||||
Chat::Yellow,
|
||||
fmt::format(
|
||||
"Incorrect argument, use {} for information regarding this command.",
|
||||
Saylink::Silent(
|
||||
fmt::format("{} help", sep->arg[0])
|
||||
)
|
||||
).c_str()
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const int ab_mask = ActionableBots::ABM_Type1;
|
||||
std::string class_race_arg = sep->arg[ab_arg];
|
||||
bool class_race_check = false;
|
||||
if (!class_race_arg.compare("byclass") || !class_race_arg.compare("byrace")) {
|
||||
class_race_check = true;
|
||||
}
|
||||
|
||||
std::list<Bot*> sbl;
|
||||
if (ActionableBots::PopulateSBL(c, sep->arg[ab_arg], sbl, ab_mask, !class_race_check ? sep->arg[ab_arg + 1] : nullptr, class_race_check ? atoi(sep->arg[ab_arg + 1]) : 0) == ActionableBots::ABT_None) {
|
||||
return;
|
||||
}
|
||||
|
||||
sbl.remove(nullptr);
|
||||
|
||||
Bot* first_found = nullptr;
|
||||
int success_count = 0;
|
||||
for (auto my_bot : sbl) {
|
||||
if (!first_found) {
|
||||
first_found = my_bot;
|
||||
}
|
||||
if (current_check) {
|
||||
c->Message(
|
||||
Chat::Green,
|
||||
fmt::format(
|
||||
"{} says, 'My [{}] spell delay is currently [{}] seconds.'",
|
||||
my_bot->GetCleanName(),
|
||||
c->GetSpellTypeNameByID(spellType),
|
||||
my_bot->GetSpellDelay(spellType) / 1000.00
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
else {
|
||||
my_bot->SetSpellDelay(spellType, typeValue);
|
||||
++success_count;
|
||||
}
|
||||
}
|
||||
if (!current_check) {
|
||||
if (success_count == 1 && first_found) {
|
||||
c->Message(
|
||||
Chat::Green,
|
||||
fmt::format(
|
||||
"{} says, 'My [{}] spell delay was set to [{}] seconds.'",
|
||||
first_found->GetCleanName(),
|
||||
c->GetSpellTypeNameByID(spellType),
|
||||
first_found->GetSpellDelay(spellType) / 1000.00
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
else {
|
||||
c->Message(
|
||||
Chat::Green,
|
||||
fmt::format(
|
||||
"{} of your bots set their [{}] spell delay to [{}] seconds.",
|
||||
success_count,
|
||||
c->GetSpellTypeNameByID(spellType),
|
||||
typeValue / 1000.00
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,240 @@
|
||||
#include "../bot_command.h"
|
||||
|
||||
void bot_command_spell_engaged_priority(Client* c, const Seperator* sep)
|
||||
{
|
||||
if (helper_command_alias_fail(c, "bot_command_spell_engaged_priority", sep->arg[0], "spellengagedpriority")) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (helper_is_help_or_usage(sep->arg[1])) {
|
||||
std::vector<std::string> description =
|
||||
{
|
||||
"Sets the order of spell casts when engaged in combat by spell type"
|
||||
};
|
||||
|
||||
std::vector<std::string> notes =
|
||||
{
|
||||
"-Setting a spell type to 0 will prevent that type from being cast.",
|
||||
"-If 2 or more are set to the same priority they will sort by spell type ID."
|
||||
};
|
||||
|
||||
std::vector<std::string> example_format =
|
||||
{
|
||||
fmt::format(
|
||||
"{} [Type Shortname] [value] [actionable]"
|
||||
, sep->arg[0]
|
||||
),
|
||||
fmt::format(
|
||||
"{} [Type ID] [value] [actionable]"
|
||||
, sep->arg[0]
|
||||
)
|
||||
};
|
||||
std::vector<std::string> examples_one =
|
||||
{
|
||||
"To set all Shaman to cast slows first:",
|
||||
fmt::format(
|
||||
"{} {} 1 byclass 10",
|
||||
sep->arg[0],
|
||||
c->GetSpellTypeShortNameByID(BotSpellTypes::Slow)
|
||||
),
|
||||
fmt::format(
|
||||
"{} {} 1 byclass 10",
|
||||
sep->arg[0],
|
||||
BotSpellTypes::Slow
|
||||
)
|
||||
};
|
||||
std::vector<std::string> examples_two =
|
||||
{
|
||||
"To set all bots to not cast snares:",
|
||||
fmt::format(
|
||||
"{} {} 0 spawned",
|
||||
sep->arg[0],
|
||||
c->GetSpellTypeShortNameByID(BotSpellTypes::Snare)
|
||||
),
|
||||
fmt::format(
|
||||
"{} {} 0 spawned",
|
||||
sep->arg[0],
|
||||
BotSpellTypes::Snare
|
||||
)
|
||||
};
|
||||
std::vector<std::string> examples_three =
|
||||
{
|
||||
"To check the current engaged priority of dispels on all bots:",
|
||||
fmt::format(
|
||||
"{} {} current spawned",
|
||||
sep->arg[0],
|
||||
c->GetSpellTypeShortNameByID(BotSpellTypes::Dispel)
|
||||
),
|
||||
fmt::format(
|
||||
"{} {} current spawned",
|
||||
sep->arg[0],
|
||||
BotSpellTypes::Dispel
|
||||
)
|
||||
};
|
||||
|
||||
std::vector<std::string> actionables =
|
||||
{
|
||||
"target, byname, ownergroup, ownerraid, targetgroup, namesgroup, healrotationtargets, mmr, byclass, byrace, spawned"
|
||||
};
|
||||
|
||||
std::vector<std::string> options = { };
|
||||
std::vector<std::string> options_one = { };
|
||||
std::vector<std::string> options_two = { };
|
||||
std::vector<std::string> options_three = { };
|
||||
|
||||
std::string popup_text = c->SendCommandHelpWindow(
|
||||
c,
|
||||
description,
|
||||
notes,
|
||||
example_format,
|
||||
examples_one, examples_two, examples_three,
|
||||
actionables,
|
||||
options,
|
||||
options_one, options_two, options_three
|
||||
);
|
||||
|
||||
popup_text = DialogueWindow::Table(popup_text);
|
||||
|
||||
c->SendPopupToClient(sep->arg[0], popup_text.c_str());
|
||||
c->CastToBot()->SendSpellTypesWindow(c, sep->arg[0], "", "", true);
|
||||
c->Message(
|
||||
Chat::Yellow,
|
||||
fmt::format(
|
||||
"Use {} for information about race/class IDs.",
|
||||
Saylink::Silent("^classracelist")
|
||||
).c_str()
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
std::string arg1 = sep->arg[1];
|
||||
|
||||
if (!arg1.compare("listid") || !arg1.compare("listname")) {
|
||||
c->CastToBot()->SendSpellTypesWindow(c, sep->arg[0], sep->arg[1], sep->arg[2]);
|
||||
return;
|
||||
}
|
||||
|
||||
std::string arg2 = sep->arg[2];
|
||||
int ab_arg = 2;
|
||||
bool current_check = false;
|
||||
uint16 spellType = 0;
|
||||
uint32 typeValue = 0;
|
||||
|
||||
// String/Int type checks
|
||||
if (sep->IsNumber(1)) {
|
||||
spellType = atoi(sep->arg[1]);
|
||||
|
||||
if (spellType < BotSpellTypes::START || spellType > BotSpellTypes::END) {
|
||||
c->Message(Chat::Yellow, "You must choose a valid spell type. Spell types range from %i to %i", BotSpellTypes::START, BotSpellTypes::END);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (c->GetSpellTypeIDByShortName(arg1) != UINT16_MAX) {
|
||||
spellType = c->GetSpellTypeIDByShortName(arg1);
|
||||
}
|
||||
else {
|
||||
c->Message(
|
||||
Chat::Yellow,
|
||||
fmt::format(
|
||||
"Incorrect argument, use {} for information regarding this command.",
|
||||
Saylink::Silent(
|
||||
fmt::format("{} help", sep->arg[0])
|
||||
)
|
||||
).c_str()
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (sep->IsNumber(2)) {
|
||||
typeValue = atoi(sep->arg[2]);
|
||||
++ab_arg;
|
||||
if (typeValue < 0 || typeValue > 100) {
|
||||
c->Message(Chat::Yellow, "You must enter a value between 0-100.");
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (!arg2.compare("current")) {
|
||||
++ab_arg;
|
||||
current_check = true;
|
||||
}
|
||||
else {
|
||||
c->Message(
|
||||
Chat::Yellow,
|
||||
fmt::format(
|
||||
"Incorrect argument, use {} for information regarding this command.",
|
||||
Saylink::Silent(
|
||||
fmt::format("{} help", sep->arg[0])
|
||||
)
|
||||
).c_str()
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const int ab_mask = ActionableBots::ABM_Type1;
|
||||
std::string class_race_arg = sep->arg[ab_arg];
|
||||
bool class_race_check = false;
|
||||
if (!class_race_arg.compare("byclass") || !class_race_arg.compare("byrace")) {
|
||||
class_race_check = true;
|
||||
}
|
||||
|
||||
std::list<Bot*> sbl;
|
||||
if (ActionableBots::PopulateSBL(c, sep->arg[ab_arg], sbl, ab_mask, !class_race_check ? sep->arg[ab_arg + 1] : nullptr, class_race_check ? atoi(sep->arg[ab_arg + 1]) : 0) == ActionableBots::ABT_None) {
|
||||
return;
|
||||
}
|
||||
|
||||
sbl.remove(nullptr);
|
||||
|
||||
Bot* first_found = nullptr;
|
||||
int success_count = 0;
|
||||
for (auto my_bot : sbl) {
|
||||
if (!first_found) {
|
||||
first_found = my_bot;
|
||||
}
|
||||
if (current_check) {
|
||||
c->Message(
|
||||
Chat::Green,
|
||||
fmt::format(
|
||||
"{} says, 'My [{}] engaged cast priority is currently [{}].'",
|
||||
my_bot->GetCleanName(),
|
||||
c->GetSpellTypeNameByID(spellType),
|
||||
my_bot->GetSpellTypePriority(spellType, BotPriorityCategories::Engaged)
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
else {
|
||||
my_bot->SetSpellTypePriority(spellType, BotPriorityCategories::Engaged, typeValue);
|
||||
++success_count;
|
||||
}
|
||||
}
|
||||
if (!current_check) {
|
||||
if (success_count == 1 && first_found) {
|
||||
c->Message(
|
||||
Chat::Green,
|
||||
fmt::format(
|
||||
"{} says, 'My [{}] engaged cast priority was set to [{}].'",
|
||||
first_found->GetCleanName(),
|
||||
c->GetSpellTypeNameByID(spellType),
|
||||
first_found->GetSpellTypePriority(spellType, BotPriorityCategories::Engaged)
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
else {
|
||||
c->Message(
|
||||
Chat::Green,
|
||||
fmt::format(
|
||||
"{} of your bots set their [{}] engaged cast priority to [{}].",
|
||||
success_count,
|
||||
c->GetSpellTypeNameByID(spellType),
|
||||
typeValue
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,229 @@
|
||||
#include "../bot_command.h"
|
||||
|
||||
void bot_command_spell_holds(Client* c, const Seperator* sep)
|
||||
{
|
||||
if (helper_command_alias_fail(c, "bot_command_spell_holds", sep->arg[0], "spellholds")) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (helper_is_help_or_usage(sep->arg[1])) {
|
||||
std::vector<std::string> description =
|
||||
{
|
||||
"Toggles whether or not bots can cast or receive certain spell types"
|
||||
};
|
||||
|
||||
std::vector<std::string> notes =
|
||||
{
|
||||
"- All pet types are based off the pet's owner's setting",
|
||||
"- Any remaining types use the owner's setting when a pet is the target",
|
||||
"- All Heals, Cures, Buffs (DS and resists included) are based off the target's setting, not the caster",
|
||||
"- e.g., BotA is healing BotB using BotB's settings",
|
||||
};
|
||||
|
||||
std::vector<std::string> example_format =
|
||||
{
|
||||
fmt::format(
|
||||
"{} [Type Shortname] [value] [actionable]"
|
||||
, sep->arg[0]
|
||||
),
|
||||
fmt::format(
|
||||
"{} [Type ID] [value] [actionable]"
|
||||
, sep->arg[0]
|
||||
)
|
||||
};
|
||||
std::vector<std::string> examples_one =
|
||||
{
|
||||
"To set all bots to hold DoTs:",
|
||||
fmt::format(
|
||||
"{} {} 1 spawned",
|
||||
sep->arg[0],
|
||||
c->GetSpellTypeShortNameByID(BotSpellTypes::DOT)
|
||||
),
|
||||
fmt::format(
|
||||
"{} {} 1 spawned",
|
||||
sep->arg[0],
|
||||
BotSpellTypes::DOT
|
||||
)
|
||||
};
|
||||
std::vector<std::string> examples_two =
|
||||
{
|
||||
"To check the current DoT settings on all bots:",
|
||||
fmt::format(
|
||||
"{} {} current spawned",
|
||||
sep->arg[0],
|
||||
c->GetSpellTypeShortNameByID(BotSpellTypes::DOT)
|
||||
),
|
||||
fmt::format(
|
||||
"{} {} current spawned",
|
||||
sep->arg[0],
|
||||
BotSpellTypes::DOT
|
||||
)
|
||||
};
|
||||
std::vector<std::string> examples_three = { };
|
||||
|
||||
std::vector<std::string> actionables =
|
||||
{
|
||||
"target, byname, ownergroup, ownerraid, targetgroup, namesgroup, healrotationtargets, mmr, byclass, byrace, spawned"
|
||||
};
|
||||
|
||||
std::vector<std::string> options = { };
|
||||
std::vector<std::string> options_one = { };
|
||||
std::vector<std::string> options_two = { };
|
||||
std::vector<std::string> options_three = { };
|
||||
|
||||
std::string popup_text = c->SendCommandHelpWindow(
|
||||
c,
|
||||
description,
|
||||
notes,
|
||||
example_format,
|
||||
examples_one, examples_two, examples_three,
|
||||
actionables,
|
||||
options,
|
||||
options_one, options_two, options_three
|
||||
);
|
||||
|
||||
popup_text = DialogueWindow::Table(popup_text);
|
||||
|
||||
c->SendPopupToClient(sep->arg[0], popup_text.c_str());
|
||||
c->CastToBot()->SendSpellTypesWindow(c, sep->arg[0], "", "", true);
|
||||
c->Message(
|
||||
Chat::Yellow,
|
||||
fmt::format(
|
||||
"Use {} for information about race/class IDs.",
|
||||
Saylink::Silent("^classracelist")
|
||||
).c_str()
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
std::string arg1 = sep->arg[1];
|
||||
|
||||
if (!arg1.compare("listid") || !arg1.compare("listname")) {
|
||||
c->CastToBot()->SendSpellTypesWindow(c, sep->arg[0], sep->arg[1], sep->arg[2]);
|
||||
return;
|
||||
}
|
||||
|
||||
std::string arg2 = sep->arg[2];
|
||||
int ab_arg = 2;
|
||||
bool current_check = false;
|
||||
uint16 spellType = 0;
|
||||
uint32 typeValue = 0;
|
||||
|
||||
// String/Int type checks
|
||||
if (sep->IsNumber(1)) {
|
||||
spellType = atoi(sep->arg[1]);
|
||||
|
||||
if (spellType < BotSpellTypes::START || spellType > BotSpellTypes::END) {
|
||||
c->Message(Chat::Yellow, "You must choose a valid spell type. Spell types range from %i to %i", BotSpellTypes::START, BotSpellTypes::END);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (c->GetSpellTypeIDByShortName(arg1) != UINT16_MAX) {
|
||||
spellType = c->GetSpellTypeIDByShortName(arg1);
|
||||
}
|
||||
else {
|
||||
c->Message(
|
||||
Chat::Yellow,
|
||||
fmt::format(
|
||||
"Incorrect argument, use {} for information regarding this command.",
|
||||
Saylink::Silent(
|
||||
fmt::format("{} help", sep->arg[0])
|
||||
)
|
||||
).c_str()
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (sep->IsNumber(2)) {
|
||||
typeValue = atoi(sep->arg[2]);
|
||||
++ab_arg;
|
||||
if (typeValue < 0 || typeValue > 1) {
|
||||
c->Message(Chat::Yellow, "You must enter either 0 for disabled or 1 for enabled.");
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (!arg2.compare("current")) {
|
||||
++ab_arg;
|
||||
current_check = true;
|
||||
}
|
||||
else {
|
||||
c->Message(
|
||||
Chat::Yellow,
|
||||
fmt::format(
|
||||
"Incorrect argument, use {} for information regarding this command.",
|
||||
Saylink::Silent(
|
||||
fmt::format("{} help", sep->arg[0])
|
||||
)
|
||||
).c_str()
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const int ab_mask = ActionableBots::ABM_Type1;
|
||||
std::string class_race_arg = sep->arg[ab_arg];
|
||||
bool class_race_check = false;
|
||||
if (!class_race_arg.compare("byclass") || !class_race_arg.compare("byrace")) {
|
||||
class_race_check = true;
|
||||
}
|
||||
|
||||
std::list<Bot*> sbl;
|
||||
if (ActionableBots::PopulateSBL(c, sep->arg[ab_arg], sbl, ab_mask, !class_race_check ? sep->arg[ab_arg + 1] : nullptr, class_race_check ? atoi(sep->arg[ab_arg + 1]) : 0) == ActionableBots::ABT_None) {
|
||||
return;
|
||||
}
|
||||
|
||||
sbl.remove(nullptr);
|
||||
|
||||
Bot* first_found = nullptr;
|
||||
int success_count = 0;
|
||||
for (auto my_bot : sbl) {
|
||||
if (!first_found) {
|
||||
first_found = my_bot;
|
||||
}
|
||||
if (current_check) {
|
||||
c->Message(
|
||||
Chat::Green,
|
||||
fmt::format(
|
||||
"{} says, 'My [{}] spell hold is currently [{}].'",
|
||||
my_bot->GetCleanName(),
|
||||
c->GetSpellTypeNameByID(spellType),
|
||||
my_bot->GetSpellHold(spellType) ? "enabled" : "disabled"
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
else {
|
||||
my_bot->SetSpellHold(spellType, typeValue);
|
||||
++success_count;
|
||||
}
|
||||
}
|
||||
if (!current_check) {
|
||||
if (success_count == 1 && first_found) {
|
||||
c->Message(
|
||||
Chat::Green,
|
||||
fmt::format(
|
||||
"{} says, 'My [{}] spell hold was [{}].'",
|
||||
first_found->GetCleanName(),
|
||||
c->GetSpellTypeNameByID(spellType),
|
||||
first_found->GetSpellHold(spellType) ? "enabled" : "disabled"
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
else {
|
||||
c->Message(
|
||||
Chat::Green,
|
||||
fmt::format(
|
||||
"{} of your bots [{}] their [{}] spell hold.",
|
||||
success_count,
|
||||
typeValue ? "enabled" : "disabled",
|
||||
c->GetSpellTypeNameByID(spellType)
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,240 @@
|
||||
#include "../bot_command.h"
|
||||
|
||||
void bot_command_spell_idle_priority(Client* c, const Seperator* sep)
|
||||
{
|
||||
if (helper_command_alias_fail(c, "bot_command_spell_idle_priority", sep->arg[0], "spellidlepriority")) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (helper_is_help_or_usage(sep->arg[1])) {
|
||||
std::vector<std::string> description =
|
||||
{
|
||||
"Sets the order of spell casts when not in combat by spell type"
|
||||
};
|
||||
|
||||
std::vector<std::string> notes =
|
||||
{
|
||||
"-Setting a spell type to 0 will prevent that type from being cast.",
|
||||
"-If 2 or more are set to the same priority they will sort by spell type ID."
|
||||
};
|
||||
|
||||
std::vector<std::string> example_format =
|
||||
{
|
||||
fmt::format(
|
||||
"{} [Type Shortname] [value] [actionable]"
|
||||
, sep->arg[0]
|
||||
),
|
||||
fmt::format(
|
||||
"{} [Type ID] [value] [actionable]"
|
||||
, sep->arg[0]
|
||||
)
|
||||
};
|
||||
std::vector<std::string> examples_one =
|
||||
{
|
||||
"To set all Clerics to cast fast heals third:",
|
||||
fmt::format(
|
||||
"{} {} 3 byclass 2",
|
||||
sep->arg[0],
|
||||
c->GetSpellTypeShortNameByID(BotSpellTypes::FastHeals)
|
||||
),
|
||||
fmt::format(
|
||||
"{} {} 3 byclass 2",
|
||||
sep->arg[0],
|
||||
BotSpellTypes::FastHeals
|
||||
)
|
||||
};
|
||||
std::vector<std::string> examples_two =
|
||||
{
|
||||
"To set all bots to not cast cures:",
|
||||
fmt::format(
|
||||
"{} {} 0 spawned",
|
||||
sep->arg[0],
|
||||
c->GetSpellTypeShortNameByID(BotSpellTypes::Cure)
|
||||
),
|
||||
fmt::format(
|
||||
"{} {} 0 spawned",
|
||||
sep->arg[0],
|
||||
BotSpellTypes::Cure
|
||||
)
|
||||
};
|
||||
std::vector<std::string> examples_three =
|
||||
{
|
||||
"To check the current idle priority of buffs on all bots:",
|
||||
fmt::format(
|
||||
"{} {} current spawned",
|
||||
sep->arg[0],
|
||||
c->GetSpellTypeShortNameByID(BotSpellTypes::Buff)
|
||||
),
|
||||
fmt::format(
|
||||
"{} {} current spawned",
|
||||
sep->arg[0],
|
||||
BotSpellTypes::Buff
|
||||
)
|
||||
};
|
||||
|
||||
std::vector<std::string> actionables =
|
||||
{
|
||||
"target, byname, ownergroup, ownerraid, targetgroup, namesgroup, healrotationtargets, mmr, byclass, byrace, spawned"
|
||||
};
|
||||
|
||||
std::vector<std::string> options = { };
|
||||
std::vector<std::string> options_one = { };
|
||||
std::vector<std::string> options_two = { };
|
||||
std::vector<std::string> options_three = { };
|
||||
|
||||
std::string popup_text = c->SendCommandHelpWindow(
|
||||
c,
|
||||
description,
|
||||
notes,
|
||||
example_format,
|
||||
examples_one, examples_two, examples_three,
|
||||
actionables,
|
||||
options,
|
||||
options_one, options_two, options_three
|
||||
);
|
||||
|
||||
popup_text = DialogueWindow::Table(popup_text);
|
||||
|
||||
c->SendPopupToClient(sep->arg[0], popup_text.c_str());
|
||||
c->CastToBot()->SendSpellTypesWindow(c, sep->arg[0], "", "", true);
|
||||
c->Message(
|
||||
Chat::Yellow,
|
||||
fmt::format(
|
||||
"Use {} for information about race/class IDs.",
|
||||
Saylink::Silent("^classracelist")
|
||||
).c_str()
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
std::string arg1 = sep->arg[1];
|
||||
|
||||
if (!arg1.compare("listid") || !arg1.compare("listname")) {
|
||||
c->CastToBot()->SendSpellTypesWindow(c, sep->arg[0], sep->arg[1], sep->arg[2]);
|
||||
return;
|
||||
}
|
||||
|
||||
std::string arg2 = sep->arg[2];
|
||||
int ab_arg = 2;
|
||||
bool current_check = false;
|
||||
uint16 spellType = 0;
|
||||
uint32 typeValue = 0;
|
||||
|
||||
// String/Int type checks
|
||||
if (sep->IsNumber(1)) {
|
||||
spellType = atoi(sep->arg[1]);
|
||||
|
||||
if (spellType < BotSpellTypes::START || spellType > BotSpellTypes::END) {
|
||||
c->Message(Chat::Yellow, "You must choose a valid spell type. Spell types range from %i to %i", BotSpellTypes::START, BotSpellTypes::END);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (c->GetSpellTypeIDByShortName(arg1) != UINT16_MAX) {
|
||||
spellType = c->GetSpellTypeIDByShortName(arg1);
|
||||
}
|
||||
else {
|
||||
c->Message(
|
||||
Chat::Yellow,
|
||||
fmt::format(
|
||||
"Incorrect argument, use {} for information regarding this command.",
|
||||
Saylink::Silent(
|
||||
fmt::format("{} help", sep->arg[0])
|
||||
)
|
||||
).c_str()
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (sep->IsNumber(2)) {
|
||||
typeValue = atoi(sep->arg[2]);
|
||||
++ab_arg;
|
||||
if (typeValue < 0 || typeValue > 100) {
|
||||
c->Message(Chat::Yellow, "You must enter a value between 0-100.");
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (!arg2.compare("current")) {
|
||||
++ab_arg;
|
||||
current_check = true;
|
||||
}
|
||||
else {
|
||||
c->Message(
|
||||
Chat::Yellow,
|
||||
fmt::format(
|
||||
"Incorrect argument, use {} for information regarding this command.",
|
||||
Saylink::Silent(
|
||||
fmt::format("{} help", sep->arg[0])
|
||||
)
|
||||
).c_str()
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const int ab_mask = ActionableBots::ABM_Type1;
|
||||
std::string class_race_arg = sep->arg[ab_arg];
|
||||
bool class_race_check = false;
|
||||
if (!class_race_arg.compare("byclass") || !class_race_arg.compare("byrace")) {
|
||||
class_race_check = true;
|
||||
}
|
||||
|
||||
std::list<Bot*> sbl;
|
||||
if (ActionableBots::PopulateSBL(c, sep->arg[ab_arg], sbl, ab_mask, !class_race_check ? sep->arg[ab_arg + 1] : nullptr, class_race_check ? atoi(sep->arg[ab_arg + 1]) : 0) == ActionableBots::ABT_None) {
|
||||
return;
|
||||
}
|
||||
|
||||
sbl.remove(nullptr);
|
||||
|
||||
Bot* first_found = nullptr;
|
||||
int success_count = 0;
|
||||
for (auto my_bot : sbl) {
|
||||
if (!first_found) {
|
||||
first_found = my_bot;
|
||||
}
|
||||
if (current_check) {
|
||||
c->Message(
|
||||
Chat::Green,
|
||||
fmt::format(
|
||||
"{} says, 'My [{}] idle cast priority is currently [{}].'",
|
||||
my_bot->GetCleanName(),
|
||||
c->GetSpellTypeNameByID(spellType),
|
||||
my_bot->GetSpellTypePriority(spellType, BotPriorityCategories::Idle)
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
else {
|
||||
my_bot->SetSpellTypePriority(spellType, BotPriorityCategories::Idle, typeValue);
|
||||
++success_count;
|
||||
}
|
||||
}
|
||||
if (!current_check) {
|
||||
if (success_count == 1 && first_found) {
|
||||
c->Message(
|
||||
Chat::Green,
|
||||
fmt::format(
|
||||
"{} says, 'My [{}] idle cast priority was set to [{}].'",
|
||||
first_found->GetCleanName(),
|
||||
c->GetSpellTypeNameByID(spellType),
|
||||
first_found->GetSpellTypePriority(spellType, BotPriorityCategories::Idle)
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
else {
|
||||
c->Message(
|
||||
Chat::Green,
|
||||
fmt::format(
|
||||
"{} of your bots set their [{}] idle cast priority to [{}].",
|
||||
success_count,
|
||||
c->GetSpellTypeNameByID(spellType),
|
||||
typeValue
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,236 @@
|
||||
#include "../bot_command.h"
|
||||
|
||||
void bot_command_spell_max_hp_pct(Client* c, const Seperator* sep)
|
||||
{
|
||||
if (helper_command_alias_fail(c, "bot_command_spell_max_hp_pct", sep->arg[0], "spellmaxhppct")) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (helper_is_help_or_usage(sep->arg[1])) {
|
||||
std::vector<std::string> description =
|
||||
{
|
||||
"Controls at what health percentage a bot will start casting different spell types"
|
||||
};
|
||||
|
||||
std::vector<std::string> notes = { };
|
||||
|
||||
std::vector<std::string> example_format =
|
||||
{
|
||||
fmt::format(
|
||||
"{} [Type Shortname] [value] [actionable]"
|
||||
, sep->arg[0]
|
||||
),
|
||||
fmt::format(
|
||||
"{} [Type ID] [value] [actionable]"
|
||||
, sep->arg[0]
|
||||
)
|
||||
};
|
||||
std::vector<std::string> examples_one =
|
||||
{
|
||||
"To set all bots to start snaring when their health is at or below 100% HP:",
|
||||
fmt::format(
|
||||
"{} {} 100 spawned",
|
||||
sep->arg[0],
|
||||
c->GetSpellTypeShortNameByID(BotSpellTypes::Snare)
|
||||
),
|
||||
fmt::format(
|
||||
"{} {} 10 spawned",
|
||||
sep->arg[0],
|
||||
BotSpellTypes::Snare
|
||||
)
|
||||
};
|
||||
std::vector<std::string> examples_two =
|
||||
{
|
||||
"To set BotA to start casting fast heals at 30% HP:",
|
||||
fmt::format(
|
||||
"{} {} 30 byname BotA",
|
||||
sep->arg[0],
|
||||
c->GetSpellTypeShortNameByID(BotSpellTypes::FastHeals)
|
||||
),
|
||||
fmt::format(
|
||||
"{} {} 30 byname BotA",
|
||||
sep->arg[0],
|
||||
BotSpellTypes::FastHeals
|
||||
)
|
||||
};
|
||||
std::vector<std::string> examples_three =
|
||||
{
|
||||
"To check the current Stun max HP percent on all bots:",
|
||||
fmt::format(
|
||||
"{} {} current spawned",
|
||||
sep->arg[0],
|
||||
c->GetSpellTypeShortNameByID(BotSpellTypes::Stun)
|
||||
),
|
||||
fmt::format(
|
||||
"{} {} current spawned",
|
||||
sep->arg[0],
|
||||
BotSpellTypes::Stun
|
||||
)
|
||||
};
|
||||
|
||||
std::vector<std::string> actionables =
|
||||
{
|
||||
"target, byname, ownergroup, ownerraid, targetgroup, namesgroup, healrotationtargets, mmr, byclass, byrace, spawned"
|
||||
};
|
||||
|
||||
std::vector<std::string> options = { };
|
||||
std::vector<std::string> options_one = { };
|
||||
std::vector<std::string> options_two = { };
|
||||
std::vector<std::string> options_three = { };
|
||||
|
||||
std::string popup_text = c->SendCommandHelpWindow(
|
||||
c,
|
||||
description,
|
||||
notes,
|
||||
example_format,
|
||||
examples_one, examples_two, examples_three,
|
||||
actionables,
|
||||
options,
|
||||
options_one, options_two, options_three
|
||||
);
|
||||
|
||||
popup_text = DialogueWindow::Table(popup_text);
|
||||
|
||||
c->SendPopupToClient(sep->arg[0], popup_text.c_str());
|
||||
c->CastToBot()->SendSpellTypesWindow(c, sep->arg[0], "", "", true);
|
||||
c->Message(
|
||||
Chat::Yellow,
|
||||
fmt::format(
|
||||
"Use {} for information about race/class IDs.",
|
||||
Saylink::Silent("^classracelist")
|
||||
).c_str()
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
std::string arg1 = sep->arg[1];
|
||||
|
||||
if (!arg1.compare("listid") || !arg1.compare("listname")) {
|
||||
c->CastToBot()->SendSpellTypesWindow(c, sep->arg[0], sep->arg[1], sep->arg[2]);
|
||||
return;
|
||||
}
|
||||
|
||||
std::string arg2 = sep->arg[2];
|
||||
int ab_arg = 2;
|
||||
bool current_check = false;
|
||||
uint16 spellType = 0;
|
||||
uint32 typeValue = 0;
|
||||
|
||||
// String/Int type checks
|
||||
if (sep->IsNumber(1)) {
|
||||
spellType = atoi(sep->arg[1]);
|
||||
|
||||
if (spellType < BotSpellTypes::START || spellType > BotSpellTypes::END) {
|
||||
c->Message(Chat::Yellow, "You must choose a valid spell type. Spell types range from %i to %i", BotSpellTypes::START, BotSpellTypes::END);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (c->GetSpellTypeIDByShortName(arg1) != UINT16_MAX) {
|
||||
spellType = c->GetSpellTypeIDByShortName(arg1);
|
||||
}
|
||||
else {
|
||||
c->Message(
|
||||
Chat::Yellow,
|
||||
fmt::format(
|
||||
"Incorrect argument, use {} for information regarding this command.",
|
||||
Saylink::Silent(
|
||||
fmt::format("{} help", sep->arg[0])
|
||||
)
|
||||
).c_str()
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (sep->IsNumber(2)) {
|
||||
typeValue = atoi(sep->arg[2]);
|
||||
++ab_arg;
|
||||
if (typeValue < 0 || typeValue > 100) {
|
||||
c->Message(Chat::Yellow, "You must enter a value between 0-100 (0%% to 100%% of health).");
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (!arg2.compare("current")) {
|
||||
++ab_arg;
|
||||
current_check = true;
|
||||
}
|
||||
else {
|
||||
c->Message(
|
||||
Chat::Yellow,
|
||||
fmt::format(
|
||||
"Incorrect argument, use {} for information regarding this command.",
|
||||
Saylink::Silent(
|
||||
fmt::format("{} help", sep->arg[0])
|
||||
)
|
||||
).c_str()
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const int ab_mask = ActionableBots::ABM_Type1;
|
||||
std::string class_race_arg = sep->arg[ab_arg];
|
||||
bool class_race_check = false;
|
||||
if (!class_race_arg.compare("byclass") || !class_race_arg.compare("byrace")) {
|
||||
class_race_check = true;
|
||||
}
|
||||
|
||||
std::list<Bot*> sbl;
|
||||
if (ActionableBots::PopulateSBL(c, sep->arg[ab_arg], sbl, ab_mask, !class_race_check ? sep->arg[ab_arg + 1] : nullptr, class_race_check ? atoi(sep->arg[ab_arg + 1]) : 0) == ActionableBots::ABT_None) {
|
||||
return;
|
||||
}
|
||||
|
||||
sbl.remove(nullptr);
|
||||
|
||||
Bot* first_found = nullptr;
|
||||
int success_count = 0;
|
||||
for (auto my_bot : sbl) {
|
||||
if (!first_found) {
|
||||
first_found = my_bot;
|
||||
}
|
||||
if (current_check) {
|
||||
c->Message(
|
||||
Chat::Green,
|
||||
fmt::format(
|
||||
"{} says, 'My [{}] maximum HP is currently [{}%%].'",
|
||||
my_bot->GetCleanName(),
|
||||
c->GetSpellTypeNameByID(spellType),
|
||||
my_bot->GetSpellTypeMaxHPLimit(spellType)
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
else {
|
||||
my_bot->SetSpellTypeMaxHPLimit(spellType, typeValue);
|
||||
++success_count;
|
||||
}
|
||||
}
|
||||
if (!current_check) {
|
||||
if (success_count == 1 && first_found) {
|
||||
c->Message(
|
||||
Chat::Green,
|
||||
fmt::format(
|
||||
"{} says, 'My [{}] maximum HP was set to [{}%%].'",
|
||||
first_found->GetCleanName(),
|
||||
c->GetSpellTypeNameByID(spellType),
|
||||
first_found->GetSpellTypeMaxHPLimit(spellType)
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
else {
|
||||
c->Message(
|
||||
Chat::Green,
|
||||
fmt::format(
|
||||
"{} of your bots set their [{}] maximum HP to [{}%%].",
|
||||
success_count,
|
||||
c->GetSpellTypeNameByID(spellType),
|
||||
typeValue
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,236 @@
|
||||
#include "../bot_command.h"
|
||||
|
||||
void bot_command_spell_max_mana_pct(Client* c, const Seperator* sep)
|
||||
{
|
||||
if (helper_command_alias_fail(c, "bot_command_spell_max_mana_pct", sep->arg[0], "spellmaxmanapct")) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (helper_is_help_or_usage(sep->arg[1])) {
|
||||
std::vector<std::string> description =
|
||||
{
|
||||
"Controls at what mana percentage a bot will stop casting different spell types"
|
||||
};
|
||||
|
||||
std::vector<std::string> notes = { };
|
||||
|
||||
std::vector<std::string> example_format =
|
||||
{
|
||||
fmt::format(
|
||||
"{} [Type Shortname] [value] [actionable]"
|
||||
, sep->arg[0]
|
||||
),
|
||||
fmt::format(
|
||||
"{} [Type ID] [value] [actionable]"
|
||||
, sep->arg[0]
|
||||
)
|
||||
};
|
||||
std::vector<std::string> examples_one =
|
||||
{
|
||||
"To set all bots to start snaring when their mana is at or below 100% HP:",
|
||||
fmt::format(
|
||||
"{} {} 10 spawned",
|
||||
sep->arg[0],
|
||||
c->GetSpellTypeShortNameByID(BotSpellTypes::Snare)
|
||||
),
|
||||
fmt::format(
|
||||
"{} {} 10 spawned",
|
||||
sep->arg[0],
|
||||
BotSpellTypes::Snare
|
||||
)
|
||||
};
|
||||
std::vector<std::string> examples_two =
|
||||
{
|
||||
"To set BotA to start casting fast heals at 30% mana:",
|
||||
fmt::format(
|
||||
"{} {} 30 byname BotA",
|
||||
sep->arg[0],
|
||||
c->GetSpellTypeShortNameByID(BotSpellTypes::FastHeals)
|
||||
),
|
||||
fmt::format(
|
||||
"{} {} 30 byname BotA",
|
||||
sep->arg[0],
|
||||
BotSpellTypes::FastHeals
|
||||
)
|
||||
};
|
||||
std::vector<std::string> examples_three =
|
||||
{
|
||||
"To check the current Stun max mana percent on all bots:",
|
||||
fmt::format(
|
||||
"{} {} current spawned",
|
||||
sep->arg[0],
|
||||
c->GetSpellTypeShortNameByID(BotSpellTypes::Stun)
|
||||
),
|
||||
fmt::format(
|
||||
"{} {} current spawned",
|
||||
sep->arg[0],
|
||||
BotSpellTypes::Stun
|
||||
)
|
||||
};
|
||||
|
||||
std::vector<std::string> actionables =
|
||||
{
|
||||
"target, byname, ownergroup, ownerraid, targetgroup, namesgroup, healrotationtargets, mmr, byclass, byrace, spawned"
|
||||
};
|
||||
|
||||
std::vector<std::string> options = { };
|
||||
std::vector<std::string> options_one = { };
|
||||
std::vector<std::string> options_two = { };
|
||||
std::vector<std::string> options_three = { };
|
||||
|
||||
std::string popup_text = c->SendCommandHelpWindow(
|
||||
c,
|
||||
description,
|
||||
notes,
|
||||
example_format,
|
||||
examples_one, examples_two, examples_three,
|
||||
actionables,
|
||||
options,
|
||||
options_one, options_two, options_three
|
||||
);
|
||||
|
||||
popup_text = DialogueWindow::Table(popup_text);
|
||||
|
||||
c->SendPopupToClient(sep->arg[0], popup_text.c_str());
|
||||
c->CastToBot()->SendSpellTypesWindow(c, sep->arg[0], "", "", true);
|
||||
c->Message(
|
||||
Chat::Yellow,
|
||||
fmt::format(
|
||||
"Use {} for information about race/class IDs.",
|
||||
Saylink::Silent("^classracelist")
|
||||
).c_str()
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
std::string arg1 = sep->arg[1];
|
||||
|
||||
if (!arg1.compare("listid") || !arg1.compare("listname")) {
|
||||
c->CastToBot()->SendSpellTypesWindow(c, sep->arg[0], sep->arg[1], sep->arg[2]);
|
||||
return;
|
||||
}
|
||||
|
||||
std::string arg2 = sep->arg[2];
|
||||
int ab_arg = 2;
|
||||
bool current_check = false;
|
||||
uint16 spellType = 0;
|
||||
uint32 typeValue = 0;
|
||||
|
||||
// String/Int type checks
|
||||
if (sep->IsNumber(1)) {
|
||||
spellType = atoi(sep->arg[1]);
|
||||
|
||||
if (spellType < BotSpellTypes::START || spellType > BotSpellTypes::END) {
|
||||
c->Message(Chat::Yellow, "You must choose a valid spell type. Spell types range from %i to %i", BotSpellTypes::START, BotSpellTypes::END);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (c->GetSpellTypeIDByShortName(arg1) != UINT16_MAX) {
|
||||
spellType = c->GetSpellTypeIDByShortName(arg1);
|
||||
}
|
||||
else {
|
||||
c->Message(
|
||||
Chat::Yellow,
|
||||
fmt::format(
|
||||
"Incorrect argument, use {} for information regarding this command.",
|
||||
Saylink::Silent(
|
||||
fmt::format("{} help", sep->arg[0])
|
||||
)
|
||||
).c_str()
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (sep->IsNumber(2)) {
|
||||
typeValue = atoi(sep->arg[2]);
|
||||
++ab_arg;
|
||||
if (typeValue < 0 || typeValue > 100) {
|
||||
c->Message(Chat::Yellow, "You must enter a value between 0-100 (0%% to 100%% of mana).");
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (!arg2.compare("current")) {
|
||||
++ab_arg;
|
||||
current_check = true;
|
||||
}
|
||||
else {
|
||||
c->Message(
|
||||
Chat::Yellow,
|
||||
fmt::format(
|
||||
"Incorrect argument, use {} for information regarding this command.",
|
||||
Saylink::Silent(
|
||||
fmt::format("{} help", sep->arg[0])
|
||||
)
|
||||
).c_str()
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const int ab_mask = ActionableBots::ABM_Type1;
|
||||
std::string class_race_arg = sep->arg[ab_arg];
|
||||
bool class_race_check = false;
|
||||
if (!class_race_arg.compare("byclass") || !class_race_arg.compare("byrace")) {
|
||||
class_race_check = true;
|
||||
}
|
||||
|
||||
std::list<Bot*> sbl;
|
||||
if (ActionableBots::PopulateSBL(c, sep->arg[ab_arg], sbl, ab_mask, !class_race_check ? sep->arg[ab_arg + 1] : nullptr, class_race_check ? atoi(sep->arg[ab_arg + 1]) : 0) == ActionableBots::ABT_None) {
|
||||
return;
|
||||
}
|
||||
|
||||
sbl.remove(nullptr);
|
||||
|
||||
Bot* first_found = nullptr;
|
||||
int success_count = 0;
|
||||
for (auto my_bot : sbl) {
|
||||
if (!first_found) {
|
||||
first_found = my_bot;
|
||||
}
|
||||
if (current_check) {
|
||||
c->Message(
|
||||
Chat::Green,
|
||||
fmt::format(
|
||||
"{} says, 'My [{}] maximum mana is currently [{}%%].'",
|
||||
my_bot->GetCleanName(),
|
||||
c->GetSpellTypeNameByID(spellType),
|
||||
my_bot->GetSpellTypeMaxManaLimit(spellType)
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
else {
|
||||
my_bot->SetSpellTypeMaxManaLimit(spellType, typeValue);
|
||||
++success_count;
|
||||
}
|
||||
}
|
||||
if (!current_check) {
|
||||
if (success_count == 1 && first_found) {
|
||||
c->Message(
|
||||
Chat::Green,
|
||||
fmt::format(
|
||||
"{} says, 'My [{}] maximum mana was set to [{}%%].'",
|
||||
first_found->GetCleanName(),
|
||||
c->GetSpellTypeNameByID(spellType),
|
||||
first_found->GetSpellTypeMaxManaLimit(spellType)
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
else {
|
||||
c->Message(
|
||||
Chat::Green,
|
||||
fmt::format(
|
||||
"{} of your bots set their [{}] maximum mana to [{}%%].",
|
||||
success_count,
|
||||
c->GetSpellTypeNameByID(spellType),
|
||||
typeValue
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,243 @@
|
||||
#include "../bot_command.h"
|
||||
|
||||
void bot_command_spell_max_thresholds(Client* c, const Seperator* sep)
|
||||
{
|
||||
if (helper_command_alias_fail(c, "bot_command_spell_max_thresholds", sep->arg[0], "spellmaxthresholds")) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (helper_is_help_or_usage(sep->arg[1])) {
|
||||
std::vector<std::string> description =
|
||||
{
|
||||
"Controls at what target HP % the bot will start casting different spell types"
|
||||
};
|
||||
|
||||
std::vector<std::string> notes =
|
||||
{
|
||||
"- All pet types are based off the pet's owner's setting",
|
||||
"- Any remaining types use the owner's setting when a pet is the target",
|
||||
"- All Heals, Cures, Buffs (DS and resists included)",
|
||||
"are based off the target's setting, not the caster",
|
||||
"- e.g., BotA is healing BotB using BotB's settings",
|
||||
};
|
||||
|
||||
std::vector<std::string> example_format =
|
||||
{
|
||||
fmt::format(
|
||||
"{} [Type Shortname] [value] [actionable]"
|
||||
, sep->arg[0]
|
||||
),
|
||||
fmt::format(
|
||||
"{} [Type ID] [value] [actionable]"
|
||||
, sep->arg[0]
|
||||
)
|
||||
};
|
||||
std::vector<std::string> examples_one =
|
||||
{
|
||||
"To set all bots to start snaring at 99%:",
|
||||
fmt::format(
|
||||
"{} {} 99 spawned",
|
||||
sep->arg[0],
|
||||
c->GetSpellTypeShortNameByID(BotSpellTypes::Snare)
|
||||
),
|
||||
fmt::format(
|
||||
"{} {} 99 spawned",
|
||||
sep->arg[0],
|
||||
BotSpellTypes::Snare
|
||||
)
|
||||
};
|
||||
std::vector<std::string> examples_two =
|
||||
{
|
||||
"To set bot Enchbot to start casting Debuffs at 99%:",
|
||||
fmt::format(
|
||||
"{} {} 99 byname Enchbot",
|
||||
sep->arg[0],
|
||||
c->GetSpellTypeShortNameByID(BotSpellTypes::Debuff)
|
||||
),
|
||||
fmt::format(
|
||||
"{} {} 99 byname Enchbot",
|
||||
sep->arg[0],
|
||||
BotSpellTypes::Debuff
|
||||
)
|
||||
};
|
||||
std::vector<std::string> examples_three =
|
||||
{
|
||||
"To check the current Nuke max threshold on all bots:",
|
||||
fmt::format(
|
||||
"{} {} current spawned",
|
||||
sep->arg[0],
|
||||
c->GetSpellTypeShortNameByID(BotSpellTypes::Nuke)
|
||||
),
|
||||
fmt::format(
|
||||
"{} {} current spawned",
|
||||
sep->arg[0],
|
||||
BotSpellTypes::Nuke
|
||||
)
|
||||
};
|
||||
|
||||
std::vector<std::string> actionables =
|
||||
{
|
||||
"target, byname, ownergroup, ownerraid, targetgroup, namesgroup, healrotationtargets, mmr, byclass, byrace, spawned"
|
||||
};
|
||||
|
||||
std::vector<std::string> options = { };
|
||||
std::vector<std::string> options_one = { };
|
||||
std::vector<std::string> options_two = { };
|
||||
std::vector<std::string> options_three = { };
|
||||
|
||||
std::string popup_text = c->SendCommandHelpWindow(
|
||||
c,
|
||||
description,
|
||||
notes,
|
||||
example_format,
|
||||
examples_one, examples_two, examples_three,
|
||||
actionables,
|
||||
options,
|
||||
options_one, options_two, options_three
|
||||
);
|
||||
|
||||
popup_text = DialogueWindow::Table(popup_text);
|
||||
|
||||
c->SendPopupToClient(sep->arg[0], popup_text.c_str());
|
||||
c->CastToBot()->SendSpellTypesWindow(c, sep->arg[0], "", "", true);
|
||||
c->Message(
|
||||
Chat::Yellow,
|
||||
fmt::format(
|
||||
"Use {} for information about race/class IDs.",
|
||||
Saylink::Silent("^classracelist")
|
||||
).c_str()
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
std::string arg1 = sep->arg[1];
|
||||
|
||||
if (!arg1.compare("listid") || !arg1.compare("listname")) {
|
||||
c->CastToBot()->SendSpellTypesWindow(c, sep->arg[0], sep->arg[1], sep->arg[2]);
|
||||
return;
|
||||
}
|
||||
|
||||
std::string arg2 = sep->arg[2];
|
||||
int ab_arg = 2;
|
||||
bool current_check = false;
|
||||
uint16 spellType = 0;
|
||||
uint32 typeValue = 0;
|
||||
|
||||
// String/Int type checks
|
||||
if (sep->IsNumber(1)) {
|
||||
spellType = atoi(sep->arg[1]);
|
||||
|
||||
if (spellType < BotSpellTypes::START || spellType > BotSpellTypes::END) {
|
||||
c->Message(Chat::Yellow, "You must choose a valid spell type. Spell types range from %i to %i", BotSpellTypes::START, BotSpellTypes::END);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (c->GetSpellTypeIDByShortName(arg1) != UINT16_MAX) {
|
||||
spellType = c->GetSpellTypeIDByShortName(arg1);
|
||||
}
|
||||
else {
|
||||
c->Message(
|
||||
Chat::Yellow,
|
||||
fmt::format(
|
||||
"Incorrect argument, use {} for information regarding this command.",
|
||||
Saylink::Silent(
|
||||
fmt::format("{} help", sep->arg[0])
|
||||
)
|
||||
).c_str()
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (sep->IsNumber(2)) {
|
||||
typeValue = atoi(sep->arg[2]);
|
||||
++ab_arg;
|
||||
if (typeValue < 0 || typeValue > 100) {
|
||||
c->Message(Chat::Yellow, "You must enter a value between 0-100 (0%% to 100%% of health).");
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (!arg2.compare("current")) {
|
||||
++ab_arg;
|
||||
current_check = true;
|
||||
}
|
||||
else {
|
||||
c->Message(
|
||||
Chat::Yellow,
|
||||
fmt::format(
|
||||
"Incorrect argument, use {} for information regarding this command.",
|
||||
Saylink::Silent(
|
||||
fmt::format("{} help", sep->arg[0])
|
||||
)
|
||||
).c_str()
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const int ab_mask = ActionableBots::ABM_Type1;
|
||||
std::string class_race_arg = sep->arg[ab_arg];
|
||||
bool class_race_check = false;
|
||||
if (!class_race_arg.compare("byclass") || !class_race_arg.compare("byrace")) {
|
||||
class_race_check = true;
|
||||
}
|
||||
|
||||
std::list<Bot*> sbl;
|
||||
if (ActionableBots::PopulateSBL(c, sep->arg[ab_arg], sbl, ab_mask, !class_race_check ? sep->arg[ab_arg + 1] : nullptr, class_race_check ? atoi(sep->arg[ab_arg + 1]) : 0) == ActionableBots::ABT_None) {
|
||||
return;
|
||||
}
|
||||
|
||||
sbl.remove(nullptr);
|
||||
|
||||
Bot* first_found = nullptr;
|
||||
int success_count = 0;
|
||||
for (auto my_bot : sbl) {
|
||||
if (!first_found) {
|
||||
first_found = my_bot;
|
||||
}
|
||||
if (current_check) {
|
||||
c->Message(
|
||||
Chat::Green,
|
||||
fmt::format(
|
||||
"{} says, 'My [{}] maximum threshold is currently [{}%%].'",
|
||||
my_bot->GetCleanName(),
|
||||
c->GetSpellTypeNameByID(spellType),
|
||||
my_bot->GetSpellMaxThreshold(spellType)
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
else {
|
||||
my_bot->SetSpellMaxThreshold(spellType, typeValue);
|
||||
++success_count;
|
||||
}
|
||||
}
|
||||
if (!current_check) {
|
||||
if (success_count == 1 && first_found) {
|
||||
c->Message(
|
||||
Chat::Green,
|
||||
fmt::format(
|
||||
"{} says, 'My [{}] maximum threshold was set to [{}%%].'",
|
||||
first_found->GetCleanName(),
|
||||
c->GetSpellTypeNameByID(spellType),
|
||||
first_found->GetSpellMaxThreshold(spellType)
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
else {
|
||||
c->Message(
|
||||
Chat::Green,
|
||||
fmt::format(
|
||||
"{} of your bots set their [{}] maximum threshold to [{}%%].",
|
||||
success_count,
|
||||
c->GetSpellTypeNameByID(spellType),
|
||||
typeValue
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,236 @@
|
||||
#include "../bot_command.h"
|
||||
|
||||
void bot_command_spell_min_hp_pct(Client* c, const Seperator* sep)
|
||||
{
|
||||
if (helper_command_alias_fail(c, "bot_command_spell_min_hp_pct", sep->arg[0], "spellminhppct")) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (helper_is_help_or_usage(sep->arg[1])) {
|
||||
std::vector<std::string> description =
|
||||
{
|
||||
"Controls at what health percentage a bot will stop casting different spell types"
|
||||
};
|
||||
|
||||
std::vector<std::string> notes = { };
|
||||
|
||||
std::vector<std::string> example_format =
|
||||
{
|
||||
fmt::format(
|
||||
"{} [Type Shortname] [value] [actionable]"
|
||||
, sep->arg[0]
|
||||
),
|
||||
fmt::format(
|
||||
"{} [Type ID] [value] [actionable]"
|
||||
, sep->arg[0]
|
||||
)
|
||||
};
|
||||
std::vector<std::string> examples_one =
|
||||
{
|
||||
"To set all bots to stop snaring when their health is below 10% HP:",
|
||||
fmt::format(
|
||||
"{} {} 10 spawned",
|
||||
sep->arg[0],
|
||||
c->GetSpellTypeShortNameByID(BotSpellTypes::Snare)
|
||||
),
|
||||
fmt::format(
|
||||
"{} {} 10 spawned",
|
||||
sep->arg[0],
|
||||
BotSpellTypes::Snare
|
||||
)
|
||||
};
|
||||
std::vector<std::string> examples_two =
|
||||
{
|
||||
"To set BotA to stop casting fast heals at 30% HP:",
|
||||
fmt::format(
|
||||
"{} {} 30 byname BotA",
|
||||
sep->arg[0],
|
||||
c->GetSpellTypeShortNameByID(BotSpellTypes::FastHeals)
|
||||
),
|
||||
fmt::format(
|
||||
"{} {} 30 byname BotA",
|
||||
sep->arg[0],
|
||||
BotSpellTypes::FastHeals
|
||||
)
|
||||
};
|
||||
std::vector<std::string> examples_three =
|
||||
{
|
||||
"To check the current Stun min HP percent on all bots:",
|
||||
fmt::format(
|
||||
"{} {} current spawned",
|
||||
sep->arg[0],
|
||||
c->GetSpellTypeShortNameByID(BotSpellTypes::Stun)
|
||||
),
|
||||
fmt::format(
|
||||
"{} {} current spawned",
|
||||
sep->arg[0],
|
||||
BotSpellTypes::Stun
|
||||
)
|
||||
};
|
||||
|
||||
std::vector<std::string> actionables =
|
||||
{
|
||||
"target, byname, ownergroup, ownerraid, targetgroup, namesgroup, healrotationtargets, mmr, byclass, byrace, spawned"
|
||||
};
|
||||
|
||||
std::vector<std::string> options = { };
|
||||
std::vector<std::string> options_one = { };
|
||||
std::vector<std::string> options_two = { };
|
||||
std::vector<std::string> options_three = { };
|
||||
|
||||
std::string popup_text = c->SendCommandHelpWindow(
|
||||
c,
|
||||
description,
|
||||
notes,
|
||||
example_format,
|
||||
examples_one, examples_two, examples_three,
|
||||
actionables,
|
||||
options,
|
||||
options_one, options_two, options_three
|
||||
);
|
||||
|
||||
popup_text = DialogueWindow::Table(popup_text);
|
||||
|
||||
c->SendPopupToClient(sep->arg[0], popup_text.c_str());
|
||||
c->CastToBot()->SendSpellTypesWindow(c, sep->arg[0], "", "", true);
|
||||
c->Message(
|
||||
Chat::Yellow,
|
||||
fmt::format(
|
||||
"Use {} for information about race/class IDs.",
|
||||
Saylink::Silent("^classracelist")
|
||||
).c_str()
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
std::string arg1 = sep->arg[1];
|
||||
|
||||
if (!arg1.compare("listid") || !arg1.compare("listname")) {
|
||||
c->CastToBot()->SendSpellTypesWindow(c, sep->arg[0], sep->arg[1], sep->arg[2]);
|
||||
return;
|
||||
}
|
||||
|
||||
std::string arg2 = sep->arg[2];
|
||||
int ab_arg = 2;
|
||||
bool current_check = false;
|
||||
uint16 spellType = 0;
|
||||
uint32 typeValue = 0;
|
||||
|
||||
// String/Int type checks
|
||||
if (sep->IsNumber(1)) {
|
||||
spellType = atoi(sep->arg[1]);
|
||||
|
||||
if (spellType < BotSpellTypes::START || spellType > BotSpellTypes::END) {
|
||||
c->Message(Chat::Yellow, "You must choose a valid spell type. Spell types range from %i to %i", BotSpellTypes::START, BotSpellTypes::END);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (c->GetSpellTypeIDByShortName(arg1) != UINT16_MAX) {
|
||||
spellType = c->GetSpellTypeIDByShortName(arg1);
|
||||
}
|
||||
else {
|
||||
c->Message(
|
||||
Chat::Yellow,
|
||||
fmt::format(
|
||||
"Incorrect argument, use {} for information regarding this command.",
|
||||
Saylink::Silent(
|
||||
fmt::format("{} help", sep->arg[0])
|
||||
)
|
||||
).c_str()
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (sep->IsNumber(2)) {
|
||||
typeValue = atoi(sep->arg[2]);
|
||||
++ab_arg;
|
||||
if (typeValue < 0 || typeValue > 100) {
|
||||
c->Message(Chat::Yellow, "You must enter a value between 0-100 (0%% to 100%% of mana).");
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (!arg2.compare("current")) {
|
||||
++ab_arg;
|
||||
current_check = true;
|
||||
}
|
||||
else {
|
||||
c->Message(
|
||||
Chat::Yellow,
|
||||
fmt::format(
|
||||
"Incorrect argument, use {} for information regarding this command.",
|
||||
Saylink::Silent(
|
||||
fmt::format("{} help", sep->arg[0])
|
||||
)
|
||||
).c_str()
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const int ab_mask = ActionableBots::ABM_Type1;
|
||||
std::string class_race_arg = sep->arg[ab_arg];
|
||||
bool class_race_check = false;
|
||||
if (!class_race_arg.compare("byclass") || !class_race_arg.compare("byrace")) {
|
||||
class_race_check = true;
|
||||
}
|
||||
|
||||
std::list<Bot*> sbl;
|
||||
if (ActionableBots::PopulateSBL(c, sep->arg[ab_arg], sbl, ab_mask, !class_race_check ? sep->arg[ab_arg + 1] : nullptr, class_race_check ? atoi(sep->arg[ab_arg + 1]) : 0) == ActionableBots::ABT_None) {
|
||||
return;
|
||||
}
|
||||
|
||||
sbl.remove(nullptr);
|
||||
|
||||
Bot* first_found = nullptr;
|
||||
int success_count = 0;
|
||||
for (auto my_bot : sbl) {
|
||||
if (!first_found) {
|
||||
first_found = my_bot;
|
||||
}
|
||||
if (current_check) {
|
||||
c->Message(
|
||||
Chat::Green,
|
||||
fmt::format(
|
||||
"{} says, 'My [{}] minimum HP is currently [{}%%].'",
|
||||
my_bot->GetCleanName(),
|
||||
c->GetSpellTypeNameByID(spellType),
|
||||
my_bot->GetSpellTypeMinHPLimit(spellType)
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
else {
|
||||
my_bot->SetSpellTypeMinHPLimit(spellType, typeValue);
|
||||
++success_count;
|
||||
}
|
||||
}
|
||||
if (!current_check) {
|
||||
if (success_count == 1 && first_found) {
|
||||
c->Message(
|
||||
Chat::Green,
|
||||
fmt::format(
|
||||
"{} says, 'My [{}] minimum HP was set to [{}%%].'",
|
||||
first_found->GetCleanName(),
|
||||
c->GetSpellTypeNameByID(spellType),
|
||||
first_found->GetSpellTypeMinHPLimit(spellType)
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
else {
|
||||
c->Message(
|
||||
Chat::Green,
|
||||
fmt::format(
|
||||
"{} of your bots set their [{}] minimum HP to [{}%%].",
|
||||
success_count,
|
||||
c->GetSpellTypeNameByID(spellType),
|
||||
typeValue
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,236 @@
|
||||
#include "../bot_command.h"
|
||||
|
||||
void bot_command_spell_min_mana_pct(Client* c, const Seperator* sep)
|
||||
{
|
||||
if (helper_command_alias_fail(c, "bot_command_spell_min_mana_pct", sep->arg[0], "spellminmanapct")) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (helper_is_help_or_usage(sep->arg[1])) {
|
||||
std::vector<std::string> description =
|
||||
{
|
||||
"Controls at what mana percentage a bot will stop casting different spell types"
|
||||
};
|
||||
|
||||
std::vector<std::string> notes = { };
|
||||
|
||||
std::vector<std::string> example_format =
|
||||
{
|
||||
fmt::format(
|
||||
"{} [Type Shortname] [value] [actionable]"
|
||||
, sep->arg[0]
|
||||
),
|
||||
fmt::format(
|
||||
"{} [Type ID] [value] [actionable]"
|
||||
, sep->arg[0]
|
||||
)
|
||||
};
|
||||
std::vector<std::string> examples_one =
|
||||
{
|
||||
"To set all bots to stop snaring when their mana is below 10% HP:",
|
||||
fmt::format(
|
||||
"{} {} 10 spawned",
|
||||
sep->arg[0],
|
||||
c->GetSpellTypeShortNameByID(BotSpellTypes::Snare)
|
||||
),
|
||||
fmt::format(
|
||||
"{} {} 10 spawned",
|
||||
sep->arg[0],
|
||||
BotSpellTypes::Snare
|
||||
)
|
||||
};
|
||||
std::vector<std::string> examples_two =
|
||||
{
|
||||
"To set BotA to stop casting fast heals at 30% mana:",
|
||||
fmt::format(
|
||||
"{} {} 30 byname BotA",
|
||||
sep->arg[0],
|
||||
c->GetSpellTypeShortNameByID(BotSpellTypes::FastHeals)
|
||||
),
|
||||
fmt::format(
|
||||
"{} {} 30 byname BotA",
|
||||
sep->arg[0],
|
||||
BotSpellTypes::FastHeals
|
||||
)
|
||||
};
|
||||
std::vector<std::string> examples_three =
|
||||
{
|
||||
"To check the current Stun min mana percent on all bots:",
|
||||
fmt::format(
|
||||
"{} {} current spawned",
|
||||
sep->arg[0],
|
||||
c->GetSpellTypeShortNameByID(BotSpellTypes::Stun)
|
||||
),
|
||||
fmt::format(
|
||||
"{} {} current spawned",
|
||||
sep->arg[0],
|
||||
BotSpellTypes::Stun
|
||||
)
|
||||
};
|
||||
|
||||
std::vector<std::string> actionables =
|
||||
{
|
||||
"target, byname, ownergroup, ownerraid, targetgroup, namesgroup, healrotationtargets, mmr, byclass, byrace, spawned"
|
||||
};
|
||||
|
||||
std::vector<std::string> options = { };
|
||||
std::vector<std::string> options_one = { };
|
||||
std::vector<std::string> options_two = { };
|
||||
std::vector<std::string> options_three = { };
|
||||
|
||||
std::string popup_text = c->SendCommandHelpWindow(
|
||||
c,
|
||||
description,
|
||||
notes,
|
||||
example_format,
|
||||
examples_one, examples_two, examples_three,
|
||||
actionables,
|
||||
options,
|
||||
options_one, options_two, options_three
|
||||
);
|
||||
|
||||
popup_text = DialogueWindow::Table(popup_text);
|
||||
|
||||
c->SendPopupToClient(sep->arg[0], popup_text.c_str());
|
||||
c->CastToBot()->SendSpellTypesWindow(c, sep->arg[0], "", "", true);
|
||||
c->Message(
|
||||
Chat::Yellow,
|
||||
fmt::format(
|
||||
"Use {} for information about race/class IDs.",
|
||||
Saylink::Silent("^classracelist")
|
||||
).c_str()
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
std::string arg1 = sep->arg[1];
|
||||
|
||||
if (!arg1.compare("listid") || !arg1.compare("listname")) {
|
||||
c->CastToBot()->SendSpellTypesWindow(c, sep->arg[0], sep->arg[1], sep->arg[2]);
|
||||
return;
|
||||
}
|
||||
|
||||
std::string arg2 = sep->arg[2];
|
||||
int ab_arg = 2;
|
||||
bool current_check = false;
|
||||
uint16 spellType = 0;
|
||||
uint32 typeValue = 0;
|
||||
|
||||
// String/Int type checks
|
||||
if (sep->IsNumber(1)) {
|
||||
spellType = atoi(sep->arg[1]);
|
||||
|
||||
if (spellType < BotSpellTypes::START || spellType > BotSpellTypes::END) {
|
||||
c->Message(Chat::Yellow, "You must choose a valid spell type. Spell types range from %i to %i", BotSpellTypes::START, BotSpellTypes::END);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (c->GetSpellTypeIDByShortName(arg1) != UINT16_MAX) {
|
||||
spellType = c->GetSpellTypeIDByShortName(arg1);
|
||||
}
|
||||
else {
|
||||
c->Message(
|
||||
Chat::Yellow,
|
||||
fmt::format(
|
||||
"Incorrect argument, use {} for information regarding this command.",
|
||||
Saylink::Silent(
|
||||
fmt::format("{} help", sep->arg[0])
|
||||
)
|
||||
).c_str()
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (sep->IsNumber(2)) {
|
||||
typeValue = atoi(sep->arg[2]);
|
||||
++ab_arg;
|
||||
if (typeValue < 0 || typeValue > 100) {
|
||||
c->Message(Chat::Yellow, "You must enter a value between 0-100 (0%% to 100%% of mana).");
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (!arg2.compare("current")) {
|
||||
++ab_arg;
|
||||
current_check = true;
|
||||
}
|
||||
else {
|
||||
c->Message(
|
||||
Chat::Yellow,
|
||||
fmt::format(
|
||||
"Incorrect argument, use {} for information regarding this command.",
|
||||
Saylink::Silent(
|
||||
fmt::format("{} help", sep->arg[0])
|
||||
)
|
||||
).c_str()
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const int ab_mask = ActionableBots::ABM_Type1;
|
||||
std::string class_race_arg = sep->arg[ab_arg];
|
||||
bool class_race_check = false;
|
||||
if (!class_race_arg.compare("byclass") || !class_race_arg.compare("byrace")) {
|
||||
class_race_check = true;
|
||||
}
|
||||
|
||||
std::list<Bot*> sbl;
|
||||
if (ActionableBots::PopulateSBL(c, sep->arg[ab_arg], sbl, ab_mask, !class_race_check ? sep->arg[ab_arg + 1] : nullptr, class_race_check ? atoi(sep->arg[ab_arg + 1]) : 0) == ActionableBots::ABT_None) {
|
||||
return;
|
||||
}
|
||||
|
||||
sbl.remove(nullptr);
|
||||
|
||||
Bot* first_found = nullptr;
|
||||
int success_count = 0;
|
||||
for (auto my_bot : sbl) {
|
||||
if (!first_found) {
|
||||
first_found = my_bot;
|
||||
}
|
||||
if (current_check) {
|
||||
c->Message(
|
||||
Chat::Green,
|
||||
fmt::format(
|
||||
"{} says, 'My [{}] minimum mana is currently [{}%%].'",
|
||||
my_bot->GetCleanName(),
|
||||
c->GetSpellTypeNameByID(spellType),
|
||||
my_bot->GetSpellTypeMinManaLimit(spellType)
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
else {
|
||||
my_bot->SetSpellTypeMinManaLimit(spellType, typeValue);
|
||||
++success_count;
|
||||
}
|
||||
}
|
||||
if (!current_check) {
|
||||
if (success_count == 1 && first_found) {
|
||||
c->Message(
|
||||
Chat::Green,
|
||||
fmt::format(
|
||||
"{} says, 'My [{}] minimum mana was set to [{}%%].'",
|
||||
first_found->GetCleanName(),
|
||||
c->GetSpellTypeNameByID(spellType),
|
||||
first_found->GetSpellTypeMinManaLimit(spellType)
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
else {
|
||||
c->Message(
|
||||
Chat::Green,
|
||||
fmt::format(
|
||||
"{} of your bots set their [{}] minimum mana to [{}%%].",
|
||||
success_count,
|
||||
c->GetSpellTypeNameByID(spellType),
|
||||
typeValue
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,244 @@
|
||||
#include "../bot_command.h"
|
||||
|
||||
void bot_command_spell_min_thresholds(Client* c, const Seperator* sep)
|
||||
{
|
||||
if (helper_command_alias_fail(c, "bot_command_spell_min_thresholds", sep->arg[0], "spellminthresholds")) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (helper_is_help_or_usage(sep->arg[1])) {
|
||||
std::vector<std::string> description =
|
||||
{
|
||||
"Controls at what target HP % the bot will stop casting different spell types"
|
||||
};
|
||||
|
||||
std::vector<std::string> notes =
|
||||
{
|
||||
"- All pet types are based off the pet's owner's setting",
|
||||
"- Any remaining types use the owner's setting when a pet is the target",
|
||||
"- All Heals, Cures, Buffs (DS and resists included) are based off the target's setting, not the caster",
|
||||
"- e.g., BotA is healing BotB using BotB's settings",
|
||||
};
|
||||
|
||||
std::vector<std::string> example_format =
|
||||
{
|
||||
fmt::format(
|
||||
"{} [Type Shortname] [value] [actionable]"
|
||||
, sep->arg[0]
|
||||
),
|
||||
fmt::format(
|
||||
"{} [Type ID] [value] [actionable]"
|
||||
, sep->arg[0]
|
||||
)
|
||||
};
|
||||
std::vector<std::string> examples_one =
|
||||
{
|
||||
"To set all bots to stop debuffing at 10%:",
|
||||
fmt::format(
|
||||
"{} {} 10 spawned",
|
||||
sep->arg[0],
|
||||
c->GetSpellTypeShortNameByID(BotSpellTypes::Debuff)
|
||||
),
|
||||
fmt::format(
|
||||
"{} {} 10 spawned",
|
||||
sep->arg[0],
|
||||
BotSpellTypes::Debuff
|
||||
)
|
||||
};
|
||||
std::vector<std::string> examples_two =
|
||||
{
|
||||
"To set all Druids to stop casting DoTs at 15%:",
|
||||
fmt::format(
|
||||
"{} {} 15 byclass 6",
|
||||
sep->arg[0],
|
||||
c->GetSpellTypeShortNameByID(BotSpellTypes::DOT)
|
||||
),
|
||||
fmt::format(
|
||||
"{} {} 15 byclass 6",
|
||||
sep->arg[0],
|
||||
BotSpellTypes::DOT
|
||||
)
|
||||
};
|
||||
std::vector<std::string> examples_three =
|
||||
{
|
||||
"To check the current Fast Heal min threshold on all bots:",
|
||||
fmt::format(
|
||||
"{} {} current spawned",
|
||||
sep->arg[0],
|
||||
c->GetSpellTypeShortNameByID(BotSpellTypes::FastHeals)
|
||||
),
|
||||
fmt::format(
|
||||
"{} {} current spawned",
|
||||
sep->arg[0],
|
||||
BotSpellTypes::FastHeals
|
||||
)
|
||||
};
|
||||
|
||||
std::vector<std::string> actionables =
|
||||
{
|
||||
"target, byname, ownergroup, ownerraid",
|
||||
"targetgroup, namesgroup, healrotationtargets",
|
||||
"mmr, byclass, byrace, spawned"
|
||||
};
|
||||
|
||||
std::vector<std::string> options = { };
|
||||
std::vector<std::string> options_one = { };
|
||||
std::vector<std::string> options_two = { };
|
||||
std::vector<std::string> options_three = { };
|
||||
|
||||
std::string popup_text = c->SendCommandHelpWindow(
|
||||
c,
|
||||
description,
|
||||
notes,
|
||||
example_format,
|
||||
examples_one, examples_two, examples_three,
|
||||
actionables,
|
||||
options,
|
||||
options_one, options_two, options_three
|
||||
);
|
||||
|
||||
popup_text = DialogueWindow::Table(popup_text);
|
||||
|
||||
c->SendPopupToClient(sep->arg[0], popup_text.c_str());
|
||||
c->CastToBot()->SendSpellTypesWindow(c, sep->arg[0], "", "", true);
|
||||
c->Message(
|
||||
Chat::Yellow,
|
||||
fmt::format(
|
||||
"Use {} for information about race/class IDs.",
|
||||
Saylink::Silent("^classracelist")
|
||||
).c_str()
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
std::string arg1 = sep->arg[1];
|
||||
|
||||
if (!arg1.compare("listid") || !arg1.compare("listname")) {
|
||||
c->CastToBot()->SendSpellTypesWindow(c, sep->arg[0], sep->arg[1], sep->arg[2]);
|
||||
return;
|
||||
}
|
||||
|
||||
std::string arg2 = sep->arg[2];
|
||||
int ab_arg = 2;
|
||||
bool current_check = false;
|
||||
uint16 spellType = 0;
|
||||
uint32 typeValue = 0;
|
||||
|
||||
// String/Int type checks
|
||||
if (sep->IsNumber(1)) {
|
||||
spellType = atoi(sep->arg[1]);
|
||||
|
||||
if (spellType < BotSpellTypes::START || spellType > BotSpellTypes::END) {
|
||||
c->Message(Chat::Yellow, "You must choose a valid spell type. Spell types range from %i to %i", BotSpellTypes::START, BotSpellTypes::END);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (c->GetSpellTypeIDByShortName(arg1) != UINT16_MAX) {
|
||||
spellType = c->GetSpellTypeIDByShortName(arg1);
|
||||
}
|
||||
else {
|
||||
c->Message(
|
||||
Chat::Yellow,
|
||||
fmt::format(
|
||||
"Incorrect argument, use {} for information regarding this command.",
|
||||
Saylink::Silent(
|
||||
fmt::format("{} help", sep->arg[0])
|
||||
)
|
||||
).c_str()
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (sep->IsNumber(2)) {
|
||||
typeValue = atoi(sep->arg[2]);
|
||||
++ab_arg;
|
||||
if (typeValue < 0 || typeValue > 100) {
|
||||
c->Message(Chat::Yellow, "You must enter a value between 0-100 (0%% to 100%% of health).");
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (!arg2.compare("current")) {
|
||||
++ab_arg;
|
||||
current_check = true;
|
||||
}
|
||||
else {
|
||||
c->Message(
|
||||
Chat::Yellow,
|
||||
fmt::format(
|
||||
"Incorrect argument, use {} for information regarding this command.",
|
||||
Saylink::Silent(
|
||||
fmt::format("{} help", sep->arg[0])
|
||||
)
|
||||
).c_str()
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const int ab_mask = ActionableBots::ABM_Type1;
|
||||
std::string class_race_arg = sep->arg[ab_arg];
|
||||
bool class_race_check = false;
|
||||
if (!class_race_arg.compare("byclass") || !class_race_arg.compare("byrace")) {
|
||||
class_race_check = true;
|
||||
}
|
||||
|
||||
std::list<Bot*> sbl;
|
||||
if (ActionableBots::PopulateSBL(c, sep->arg[ab_arg], sbl, ab_mask, !class_race_check ? sep->arg[ab_arg + 1] : nullptr, class_race_check ? atoi(sep->arg[ab_arg + 1]) : 0) == ActionableBots::ABT_None) {
|
||||
return;
|
||||
}
|
||||
|
||||
sbl.remove(nullptr);
|
||||
|
||||
Bot* first_found = nullptr;
|
||||
int success_count = 0;
|
||||
for (auto my_bot : sbl) {
|
||||
if (!first_found) {
|
||||
first_found = my_bot;
|
||||
}
|
||||
if (current_check) {
|
||||
c->Message(
|
||||
Chat::Green,
|
||||
fmt::format(
|
||||
"{} says, 'My [{}] minimum threshold is currently [{}%%].'",
|
||||
my_bot->GetCleanName(),
|
||||
c->GetSpellTypeNameByID(spellType),
|
||||
my_bot->GetSpellMinThreshold(spellType)
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
else {
|
||||
my_bot->SetSpellMinThreshold(spellType, typeValue);
|
||||
++success_count;
|
||||
}
|
||||
}
|
||||
if (!current_check) {
|
||||
if (success_count == 1 && first_found) {
|
||||
c->Message(
|
||||
Chat::Green,
|
||||
fmt::format(
|
||||
"{} says, 'My [{}] minimum threshold was set to [{}%%].'",
|
||||
first_found->GetCleanName(),
|
||||
c->GetSpellTypeNameByID(spellType),
|
||||
first_found->GetSpellMinThreshold(spellType)
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
else {
|
||||
c->Message(
|
||||
Chat::Green,
|
||||
fmt::format(
|
||||
"{} of your bots set their [{}] minimum threshold to [{}%%].",
|
||||
success_count,
|
||||
c->GetSpellTypeNameByID(spellType),
|
||||
typeValue
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,240 @@
|
||||
#include "../bot_command.h"
|
||||
|
||||
void bot_command_spell_pursue_priority(Client* c, const Seperator* sep)
|
||||
{
|
||||
if (helper_command_alias_fail(c, "bot_command_spell_pursue_priority", sep->arg[0], "spellpursuepriority")) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (helper_is_help_or_usage(sep->arg[1])) {
|
||||
std::vector<std::string> description =
|
||||
{
|
||||
"Sets the order of spell casts when the mob is fleeing in combat by spell type"
|
||||
};
|
||||
|
||||
std::vector<std::string> notes =
|
||||
{
|
||||
"- Setting a spell type to 0 will prevent that type from being cast.",
|
||||
"- If 2 or more are set to the same priority they will sort by spell type ID."
|
||||
};
|
||||
|
||||
std::vector<std::string> example_format =
|
||||
{
|
||||
fmt::format(
|
||||
"{} [Type Shortname] [value] [actionable]"
|
||||
, sep->arg[0]
|
||||
),
|
||||
fmt::format(
|
||||
"{} [Type ID] [value] [actionable]"
|
||||
, sep->arg[0]
|
||||
)
|
||||
};
|
||||
std::vector<std::string> examples_one =
|
||||
{
|
||||
"To set all bots to cast nukes first:",
|
||||
fmt::format(
|
||||
"{} {} 1 spawned",
|
||||
sep->arg[0],
|
||||
c->GetSpellTypeShortNameByID(BotSpellTypes::Nuke)
|
||||
),
|
||||
fmt::format(
|
||||
"{} {} 1 spawned",
|
||||
sep->arg[0],
|
||||
BotSpellTypes::FastHeals
|
||||
)
|
||||
};
|
||||
std::vector<std::string> examples_two =
|
||||
{
|
||||
"To set all Shaman to not cast cures:",
|
||||
fmt::format(
|
||||
"{} {} 0 byclass 10",
|
||||
sep->arg[0],
|
||||
c->GetSpellTypeShortNameByID(BotSpellTypes::Cure)
|
||||
),
|
||||
fmt::format(
|
||||
"{} {} 0 byclass 10",
|
||||
sep->arg[0],
|
||||
BotSpellTypes::Cure
|
||||
)
|
||||
};
|
||||
std::vector<std::string> examples_three =
|
||||
{
|
||||
"To check the current pursue priority of buffs on all bots:",
|
||||
fmt::format(
|
||||
"{} {} current spawned",
|
||||
sep->arg[0],
|
||||
c->GetSpellTypeShortNameByID(BotSpellTypes::Buff)
|
||||
),
|
||||
fmt::format(
|
||||
"{} {} current spawned",
|
||||
sep->arg[0],
|
||||
BotSpellTypes::Buff
|
||||
)
|
||||
};
|
||||
|
||||
std::vector<std::string> actionables =
|
||||
{
|
||||
"target, byname, ownergroup, ownerraid, targetgroup, namesgroup, healrotationtargets, mmr, byclass, byrace, spawned"
|
||||
};
|
||||
|
||||
std::vector<std::string> options = { };
|
||||
std::vector<std::string> options_one = { };
|
||||
std::vector<std::string> options_two = { };
|
||||
std::vector<std::string> options_three = { };
|
||||
|
||||
std::string popup_text = c->SendCommandHelpWindow(
|
||||
c,
|
||||
description,
|
||||
notes,
|
||||
example_format,
|
||||
examples_one, examples_two, examples_three,
|
||||
actionables,
|
||||
options,
|
||||
options_one, options_two, options_three
|
||||
);
|
||||
|
||||
popup_text = DialogueWindow::Table(popup_text);
|
||||
|
||||
c->SendPopupToClient(sep->arg[0], popup_text.c_str());
|
||||
c->CastToBot()->SendSpellTypesWindow(c, sep->arg[0], "", "", true);
|
||||
c->Message(
|
||||
Chat::Yellow,
|
||||
fmt::format(
|
||||
"Use {} for information about race/class IDs.",
|
||||
Saylink::Silent("^classracelist")
|
||||
).c_str()
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
std::string arg1 = sep->arg[1];
|
||||
|
||||
if (!arg1.compare("listid") || !arg1.compare("listname")) {
|
||||
c->CastToBot()->SendSpellTypesWindow(c, sep->arg[0], sep->arg[1], sep->arg[2]);
|
||||
return;
|
||||
}
|
||||
|
||||
std::string arg2 = sep->arg[2];
|
||||
int ab_arg = 2;
|
||||
bool current_check = false;
|
||||
uint16 spellType = 0;
|
||||
uint32 typeValue = 0;
|
||||
|
||||
// String/Int type checks
|
||||
if (sep->IsNumber(1)) {
|
||||
spellType = atoi(sep->arg[1]);
|
||||
|
||||
if (spellType < BotSpellTypes::START || spellType > BotSpellTypes::END) {
|
||||
c->Message(Chat::Yellow, "You must choose a valid spell type. Spell types range from %i to %i", BotSpellTypes::START, BotSpellTypes::END);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (c->GetSpellTypeIDByShortName(arg1) != UINT16_MAX) {
|
||||
spellType = c->GetSpellTypeIDByShortName(arg1);
|
||||
}
|
||||
else {
|
||||
c->Message(
|
||||
Chat::Yellow,
|
||||
fmt::format(
|
||||
"Incorrect argument, use {} for information regarding this command.",
|
||||
Saylink::Silent(
|
||||
fmt::format("{} help", sep->arg[0])
|
||||
)
|
||||
).c_str()
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (sep->IsNumber(2)) {
|
||||
typeValue = atoi(sep->arg[2]);
|
||||
++ab_arg;
|
||||
if (typeValue < 0 || typeValue > 100) {
|
||||
c->Message(Chat::Yellow, "You must enter a value between 0-100.");
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (!arg2.compare("current")) {
|
||||
++ab_arg;
|
||||
current_check = true;
|
||||
}
|
||||
else {
|
||||
c->Message(
|
||||
Chat::Yellow,
|
||||
fmt::format(
|
||||
"Incorrect argument, use {} for information regarding this command.",
|
||||
Saylink::Silent(
|
||||
fmt::format("{} help", sep->arg[0])
|
||||
)
|
||||
).c_str()
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const int ab_mask = ActionableBots::ABM_Type1;
|
||||
std::string class_race_arg = sep->arg[ab_arg];
|
||||
bool class_race_check = false;
|
||||
if (!class_race_arg.compare("byclass") || !class_race_arg.compare("byrace")) {
|
||||
class_race_check = true;
|
||||
}
|
||||
|
||||
std::list<Bot*> sbl;
|
||||
if (ActionableBots::PopulateSBL(c, sep->arg[ab_arg], sbl, ab_mask, !class_race_check ? sep->arg[ab_arg + 1] : nullptr, class_race_check ? atoi(sep->arg[ab_arg + 1]) : 0) == ActionableBots::ABT_None) {
|
||||
return;
|
||||
}
|
||||
|
||||
sbl.remove(nullptr);
|
||||
|
||||
Bot* first_found = nullptr;
|
||||
int success_count = 0;
|
||||
for (auto my_bot : sbl) {
|
||||
if (!first_found) {
|
||||
first_found = my_bot;
|
||||
}
|
||||
if (current_check) {
|
||||
c->Message(
|
||||
Chat::Green,
|
||||
fmt::format(
|
||||
"{} says, 'My [{}] pursue cast priority is currently [{}].'",
|
||||
my_bot->GetCleanName(),
|
||||
c->GetSpellTypeNameByID(spellType),
|
||||
my_bot->GetSpellTypePriority(spellType, BotPriorityCategories::Pursue)
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
else {
|
||||
my_bot->SetSpellTypePriority(spellType, BotPriorityCategories::Pursue, typeValue);
|
||||
++success_count;
|
||||
}
|
||||
}
|
||||
if (!current_check) {
|
||||
if (success_count == 1 && first_found) {
|
||||
c->Message(
|
||||
Chat::Green,
|
||||
fmt::format(
|
||||
"{} says, 'My [{}] pursue cast priority was set to [{}].'",
|
||||
first_found->GetCleanName(),
|
||||
c->GetSpellTypeNameByID(spellType),
|
||||
first_found->GetSpellTypePriority(spellType, BotPriorityCategories::Pursue)
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
else {
|
||||
c->Message(
|
||||
Chat::Green,
|
||||
fmt::format(
|
||||
"{} of your bots set their [{}] pursue cast priority to [{}].",
|
||||
success_count,
|
||||
c->GetSpellTypeNameByID(spellType),
|
||||
typeValue
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,236 @@
|
||||
#include "../bot_command.h"
|
||||
|
||||
void bot_command_spell_target_count(Client* c, const Seperator* sep)
|
||||
{
|
||||
if (helper_command_alias_fail(c, "bot_command_spell_target_count", sep->arg[0], "spelltargetcount")) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (helper_is_help_or_usage(sep->arg[1])) {
|
||||
std::vector<std::string> description =
|
||||
{
|
||||
"Decides how many eligible targets are required for an AE or group spell to cast by spell type"
|
||||
};
|
||||
|
||||
std::vector<std::string> notes = { };
|
||||
|
||||
std::vector<std::string> example_format =
|
||||
{
|
||||
fmt::format(
|
||||
"{} [Type Shortname] [value] [actionable]"
|
||||
, sep->arg[0]
|
||||
),
|
||||
fmt::format(
|
||||
"{} [Type ID] [value] [actionable]"
|
||||
, sep->arg[0]
|
||||
)
|
||||
};
|
||||
std::vector<std::string> examples_one =
|
||||
{
|
||||
"To set all bots to AEMez with 5 or more targets:",
|
||||
fmt::format(
|
||||
"{} {} 5 spawned",
|
||||
sep->arg[0],
|
||||
c->GetSpellTypeShortNameByID(BotSpellTypes::AEMez)
|
||||
),
|
||||
fmt::format(
|
||||
"{} {} 5 spawned",
|
||||
sep->arg[0],
|
||||
BotSpellTypes::AEMez
|
||||
)
|
||||
};
|
||||
std::vector<std::string> examples_two =
|
||||
{
|
||||
"To set Wizards to require 5 targets for AENukes:",
|
||||
fmt::format(
|
||||
"{} {} 3 byname BotA",
|
||||
sep->arg[0],
|
||||
c->GetSpellTypeShortNameByID(BotSpellTypes::AENukes)
|
||||
),
|
||||
fmt::format(
|
||||
"{} {} 3 byname BotA",
|
||||
sep->arg[0],
|
||||
BotSpellTypes::AENukes
|
||||
)
|
||||
};
|
||||
std::vector<std::string> examples_three =
|
||||
{
|
||||
"To check the current AESlow count on all bots:",
|
||||
fmt::format(
|
||||
"{} {} current spawned",
|
||||
sep->arg[0],
|
||||
c->GetSpellTypeShortNameByID(BotSpellTypes::AESlow)
|
||||
),
|
||||
fmt::format(
|
||||
"{} {} current spawned",
|
||||
sep->arg[0],
|
||||
BotSpellTypes::AESlow
|
||||
)
|
||||
};
|
||||
|
||||
std::vector<std::string> actionables =
|
||||
{
|
||||
"target, byname, ownergroup, ownerraid, targetgroup, namesgroup, healrotationtargets, mmr, byclass, byrace, spawned"
|
||||
};
|
||||
|
||||
std::vector<std::string> options = { };
|
||||
std::vector<std::string> options_one = { };
|
||||
std::vector<std::string> options_two = { };
|
||||
std::vector<std::string> options_three = { };
|
||||
|
||||
std::string popup_text = c->SendCommandHelpWindow(
|
||||
c,
|
||||
description,
|
||||
notes,
|
||||
example_format,
|
||||
examples_one, examples_two, examples_three,
|
||||
actionables,
|
||||
options,
|
||||
options_one, options_two, options_three
|
||||
);
|
||||
|
||||
popup_text = DialogueWindow::Table(popup_text);
|
||||
|
||||
c->SendPopupToClient(sep->arg[0], popup_text.c_str());
|
||||
c->CastToBot()->SendSpellTypesWindow(c, sep->arg[0], "", "", true);
|
||||
c->Message(
|
||||
Chat::Yellow,
|
||||
fmt::format(
|
||||
"Use {} for information about race/class IDs.",
|
||||
Saylink::Silent("^classracelist")
|
||||
).c_str()
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
std::string arg1 = sep->arg[1];
|
||||
|
||||
if (!arg1.compare("listid") || !arg1.compare("listname")) {
|
||||
c->CastToBot()->SendSpellTypesWindow(c, sep->arg[0], sep->arg[1], sep->arg[2]);
|
||||
return;
|
||||
}
|
||||
|
||||
std::string arg2 = sep->arg[2];
|
||||
int ab_arg = 2;
|
||||
bool current_check = false;
|
||||
uint16 spellType = 0;
|
||||
uint32 typeValue = 0;
|
||||
|
||||
// String/Int type checks
|
||||
if (sep->IsNumber(1)) {
|
||||
spellType = atoi(sep->arg[1]);
|
||||
|
||||
if (spellType < BotSpellTypes::START || spellType > BotSpellTypes::END) {
|
||||
c->Message(Chat::Yellow, "You must choose a valid spell type. Spell types range from %i to %i", BotSpellTypes::START, BotSpellTypes::END);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (c->GetSpellTypeIDByShortName(arg1) != UINT16_MAX) {
|
||||
spellType = c->GetSpellTypeIDByShortName(arg1);
|
||||
}
|
||||
else {
|
||||
c->Message(
|
||||
Chat::Yellow,
|
||||
fmt::format(
|
||||
"Incorrect argument, use {} for information regarding this command.",
|
||||
Saylink::Silent(
|
||||
fmt::format("{} help", sep->arg[0])
|
||||
)
|
||||
).c_str()
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (sep->IsNumber(2)) {
|
||||
typeValue = atoi(sep->arg[2]);
|
||||
++ab_arg;
|
||||
if (typeValue < 1 || typeValue > 100) {
|
||||
c->Message(Chat::Yellow, "You must enter a value between 1-100.");
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (!arg2.compare("current")) {
|
||||
++ab_arg;
|
||||
current_check = true;
|
||||
}
|
||||
else {
|
||||
c->Message(
|
||||
Chat::Yellow,
|
||||
fmt::format(
|
||||
"Incorrect argument, use {} for information regarding this command.",
|
||||
Saylink::Silent(
|
||||
fmt::format("{} help", sep->arg[0])
|
||||
)
|
||||
).c_str()
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const int ab_mask = ActionableBots::ABM_Type1;
|
||||
std::string class_race_arg = sep->arg[ab_arg];
|
||||
bool class_race_check = false;
|
||||
if (!class_race_arg.compare("byclass") || !class_race_arg.compare("byrace")) {
|
||||
class_race_check = true;
|
||||
}
|
||||
|
||||
std::list<Bot*> sbl;
|
||||
if (ActionableBots::PopulateSBL(c, sep->arg[ab_arg], sbl, ab_mask, !class_race_check ? sep->arg[ab_arg + 1] : nullptr, class_race_check ? atoi(sep->arg[ab_arg + 1]) : 0) == ActionableBots::ABT_None) {
|
||||
return;
|
||||
}
|
||||
|
||||
sbl.remove(nullptr);
|
||||
|
||||
Bot* first_found = nullptr;
|
||||
int success_count = 0;
|
||||
for (auto my_bot : sbl) {
|
||||
if (!first_found) {
|
||||
first_found = my_bot;
|
||||
}
|
||||
if (current_check) {
|
||||
c->Message(
|
||||
Chat::Green,
|
||||
fmt::format(
|
||||
"{} says, 'My [{}] target count is currently [{}].'",
|
||||
my_bot->GetCleanName(),
|
||||
c->GetSpellTypeNameByID(spellType),
|
||||
my_bot->GetSpellTypeAEOrGroupTargetCount(spellType)
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
else {
|
||||
my_bot->SetSpellTypeAEOrGroupTargetCount(spellType, typeValue);
|
||||
++success_count;
|
||||
}
|
||||
}
|
||||
if (!current_check) {
|
||||
if (success_count == 1 && first_found) {
|
||||
c->Message(
|
||||
Chat::Green,
|
||||
fmt::format(
|
||||
"{} says, 'My [{}] target count was set to [{}].'",
|
||||
first_found->GetCleanName(),
|
||||
c->GetSpellTypeNameByID(spellType),
|
||||
first_found->GetSpellTypeAEOrGroupTargetCount(spellType)
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
else {
|
||||
c->Message(
|
||||
Chat::Green,
|
||||
fmt::format(
|
||||
"{} of your bots set their [{}] target count to [{}].",
|
||||
success_count,
|
||||
c->GetSpellTypeNameByID(spellType),
|
||||
typeValue
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,7 @@ void bot_command_suspend(Client *c, const Seperator *sep)
|
||||
return;
|
||||
}
|
||||
if (helper_is_help_or_usage(sep->arg[1])) {
|
||||
c->Message(Chat::White, "usage: %s ([actionable: <any>] ([actionable_name]))", sep->arg[0]);
|
||||
c->Message(Chat::White, "usage: %s ([actionable: target | byname | ownergroup | ownerraid | targetgroup | namesgroup | healrotationmembers | healrotationtargets | mmr | byclass | byrace | spawned] ([actionable_name]))", sep->arg[0]);
|
||||
return;
|
||||
}
|
||||
const int ab_mask = ActionableBots::ABM_NoFilter;
|
||||
|
||||
@@ -2,12 +2,15 @@
|
||||
|
||||
void bot_command_taunt(Client *c, const Seperator *sep)
|
||||
{
|
||||
if (helper_command_alias_fail(c, "bot_command_taunt", sep->arg[0], "taunt"))
|
||||
return;
|
||||
if (helper_is_help_or_usage(sep->arg[1])) {
|
||||
c->Message(Chat::White, "usage: %s ([option: on | off]) ([actionable: target | byname | ownergroup | ownerraid | targetgroup | namesgroup | healrotationtargets | byclass | byrace | spawned] ([actionable_name]))", sep->arg[0]);
|
||||
if (helper_command_alias_fail(c, "bot_command_taunt", sep->arg[0], "taunt")) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (helper_is_help_or_usage(sep->arg[1])) {
|
||||
c->Message(Chat::White, "usage: %s ([option: on | off]) ([actionable: target | byname | ownergroup | ownerraid | targetgroup | namesgroup | healrotationtargets | mmr | byclass | byrace | spawned] ([actionable_name]))", sep->arg[0]);
|
||||
return;
|
||||
}
|
||||
|
||||
const int ab_mask = ActionableBots::ABM_Type1;
|
||||
|
||||
std::string arg1 = sep->arg[1];
|
||||
@@ -15,26 +18,30 @@ void bot_command_taunt(Client *c, const Seperator *sep)
|
||||
bool taunt_state = false;
|
||||
bool toggle_taunt = true;
|
||||
int ab_arg = 1;
|
||||
|
||||
if (!arg1.compare("on")) {
|
||||
taunt_state = true;
|
||||
toggle_taunt = false;
|
||||
ab_arg = 2;
|
||||
++ab_arg;
|
||||
}
|
||||
else if (!arg1.compare("off")) {
|
||||
toggle_taunt = false;
|
||||
ab_arg = 2;
|
||||
++ab_arg;
|
||||
}
|
||||
|
||||
std::string class_race_arg = sep->arg[ab_arg];
|
||||
bool class_race_check = false;
|
||||
|
||||
if (!class_race_arg.compare("byclass") || !class_race_arg.compare("byrace")) {
|
||||
class_race_check = true;
|
||||
}
|
||||
|
||||
std::list<Bot*> sbl;
|
||||
|
||||
if (ActionableBots::PopulateSBL(c, sep->arg[ab_arg], sbl, ab_mask, !class_race_check ? sep->arg[(ab_arg + 1)] : nullptr, class_race_check ? atoi(sep->arg[(ab_arg + 1)]) : 0) == ActionableBots::ABT_None) {
|
||||
return;
|
||||
}
|
||||
|
||||
sbl.remove(nullptr);
|
||||
|
||||
int taunting_count = 0;
|
||||
|
||||
@@ -2,10 +2,12 @@
|
||||
|
||||
void bot_command_timer(Client* c, const Seperator* sep)
|
||||
{
|
||||
if (helper_command_alias_fail(c, "bot_command_timer", sep->arg[0], "timer"))
|
||||
if (helper_command_alias_fail(c, "bot_command_timer", sep->arg[0], "timer")) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (helper_is_help_or_usage(sep->arg[1])) {
|
||||
c->Message(Chat::White, "usage: %s [clear | has | set] [disc | item | spell] [timer ID | item ID | spell ID | all] [optional ms for set] [actionable].", sep->arg[0]);
|
||||
c->Message(Chat::White, "usage: %s [clear | has | set] [disc | item | spell] [timer ID | item ID | spell ID | all] [optional ms for set] ([actionable: target | byname | ownergroup | ownerraid | targetgroup | namesgroup | healrotationtargets | mmr | byclass | byrace | spawned] ([actionable_name])).", sep->arg[0]);
|
||||
c->Message(Chat::White, "When setting, you can leave the value blank to use the default for the item or specify a value in ms to set the timer to.");
|
||||
c->Message(Chat::White, "Returns or sets the provided timer(s) for the selected bot(s) or clears the selected timer(s) for the selected bot(s).");
|
||||
return;
|
||||
@@ -88,14 +90,17 @@ void bot_command_timer(Client* c, const Seperator* sep)
|
||||
|
||||
std::string class_race_arg = sep->arg[ab_arg];
|
||||
bool class_race_check = false;
|
||||
|
||||
if (!class_race_arg.compare("byclass") || !class_race_arg.compare("byrace")) {
|
||||
class_race_check = true;
|
||||
}
|
||||
|
||||
std::list<Bot*> sbl;
|
||||
|
||||
if (ActionableBots::PopulateSBL(c, sep->arg[ab_arg], sbl, ab_mask, !class_race_check ? sep->arg[ab_arg + 1] : nullptr, class_race_check ? atoi(sep->arg[ab_arg + 1]) : 0) == ActionableBots::ABT_None) {
|
||||
return;
|
||||
}
|
||||
|
||||
sbl.remove(nullptr);
|
||||
|
||||
for (auto my_bot : sbl) {
|
||||
|
||||
Reference in New Issue
Block a user