implement commanded cast types

This commit is contained in:
nytmyr
2024-11-26 13:17:36 -06:00
parent 3d67009de5
commit ee9651b4f1
27 changed files with 1394 additions and 993 deletions
-42
View File
@@ -1,42 +0,0 @@
#include "../bot_command.h"
void bot_command_bind_affinity(Client *c, const Seperator *sep)
{
bcst_list* local_list = &bot_command_spells[BCEnum::SpT_BindAffinity];
if (helper_spell_list_fail(c, local_list, BCEnum::SpT_BindAffinity) || helper_command_alias_fail(c, "bot_command_bind_affinity", sep->arg[0], "bindaffinity"))
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;
}
ActionableTarget::Types actionable_targets;
Bot* my_bot = nullptr;
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;
auto target_mob = actionable_targets.Select(c, local_entry->target_type, FRIENDLY);
if (!target_mob)
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;
// Cast effect message is not being generated
if (helper_cast_standard_spell(my_bot, target_mob, local_entry->spell_id))
c->Message(Chat::White, "Successfully bound %s to this location", target_mob->GetCleanName());
else
c->Message(Chat::White, "Failed to bind %s to this location", target_mob->GetCleanName());
break;
}
helper_no_available_bots(c, my_bot);
}
+193 -37
View File
@@ -99,8 +99,8 @@ void bot_command_cast(Client* c, const Seperator* sep)
c->Message(
Chat::Yellow,
fmt::format(
"Use {} for information about race/class IDs.",
Saylink::Silent("^classracelist")
"Use help after any command type for more subtypes to use, for example: {}.",
Saylink::Silent("^cast invisibility help")
).c_str()
);
@@ -118,9 +118,58 @@ void bot_command_cast(Client* c, const Seperator* sep)
}
std::string arg1 = sep->arg[1];
std::string arg2 = sep->arg[2];
if (!arg1.compare("listid") || !arg1.compare("listname")) {
c->CastToBot()->SendSpellTypesWindow(c, sep->arg[0], sep->arg[1], sep->arg[2]);
//Commanded type help prompts
if (!arg2.compare("help")) {
c->Message(Chat::Yellow, "You can also use [single], [group], [ae]. Ex: ^cast movementspeed group.", sep->arg[0]);
}
if (!arg1.compare("invisibility") && !arg2.compare("help")) {
c->Message(
Chat::Yellow,
fmt::format(
"Available options for {} are: {}, {}, {}, {}.",
sep->arg[0],
Saylink::Silent("^cast invisibility see", "see"),
Saylink::Silent("^cast invisibility invis", "invis"),
Saylink::Silent("^cast invisibility undead", "undead"),
Saylink::Silent("^cast invisibility animals", "animals")
).c_str()
);
return;
}
if (!arg1.compare("size") && !arg2.compare("help")) {
c->Message(
Chat::Yellow,
fmt::format(
"Available options for {} are: {}, {}.",
sep->arg[0],
Saylink::Silent("^cast size grow", "grow"),
Saylink::Silent("^cast size shrink", "shrink")
).c_str()
);
return;
}
if (!arg1.compare("movementspeed") && !arg2.compare("help")) {
c->Message(
Chat::Yellow,
fmt::format(
"Available options for {} are: {}, {}.",
sep->arg[0],
Saylink::Silent("^cast movementspeed selo"), "selo"
).c_str()
);
return;
}
if (!arg2.compare("help")) {
c->Message(Chat::Yellow, "There are no additional options for {}.", sep->arg[0]);
return;
}
@@ -131,8 +180,16 @@ void bot_command_cast(Client* c, const Seperator* sep)
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);
if (spellType < BotSpellTypes::START || (spellType > BotSpellTypes::END && spellType < BotSpellTypes::COMMANDED_START) || spellType > BotSpellTypes::COMMANDED_END) {
c->Message(
Chat::Yellow,
fmt::format(
"You must choose a valid spell type. Use {} for information regarding this command.",
Saylink::Silent(
fmt::format("{} help", sep->arg[0])
)
).c_str()
);
return;
}
@@ -156,6 +213,88 @@ void bot_command_cast(Client* c, const Seperator* sep)
}
}
switch (spellType) { //Allowed command checks
case BotSpellTypes::Charm:
if (!RuleB(Bots, AllowCommandedCharm)) {
c->Message(Chat::Yellow, "This commanded type is currently disabled.");
return;
}
break;
case BotSpellTypes::AEMez:
case BotSpellTypes::Mez:
if (!RuleB(Bots, AllowCommandedMez)) {
c->Message(Chat::Yellow, "This commanded type is currently disabled.");
return;
}
break;
case BotSpellTypes::Resurrect:
if (!RuleB(Bots, AllowCommandedResurrect)) {
c->Message(Chat::Yellow, "This commanded type is currently disabled.");
return;
}
break;
case BotSpellTypes::SummonCorpse:
if (!RuleB(Bots, AllowCommandedSummonCorpse)) {
c->Message(Chat::Yellow, "This commanded type is currently disabled.");
return;
}
break;
default:
break;
}
std::string argString = sep->arg[ab_arg];
uint16 subType = UINT16_MAX;
uint16 subTargetType = UINT16_MAX;
if (!argString.compare("shrink")) {
subType = CommandedSubTypes::Shrink;
++ab_arg;
}
else if (!argString.compare("grow")) {
subType = CommandedSubTypes::Grow;
++ab_arg;
}
else if (!argString.compare("see")) {
subType = CommandedSubTypes::SeeInvis;
++ab_arg;
}
else if (!argString.compare("invis")) {
subType = CommandedSubTypes::Invis;
++ab_arg;
}
else if (!argString.compare("undead")) {
subType = CommandedSubTypes::InvisUndead;
++ab_arg;
}
else if (!argString.compare("animals")) {
subType = CommandedSubTypes::InvisAnimals;
++ab_arg;
}
else if (!argString.compare("selo")) {
subType = CommandedSubTypes::Selo;
++ab_arg;
}
argString = sep->arg[ab_arg];
if (!argString.compare("single")) {
subTargetType = CommandedSubTypes::SingleTarget;
++ab_arg;
}
else if (!argString.compare("group")) {
subTargetType = CommandedSubTypes::GroupTarget;
++ab_arg;
}
else if (!argString.compare("ae")) {
subTargetType = CommandedSubTypes::AETarget;
++ab_arg;
}
if (
spellType == BotSpellTypes::PetBuffs ||
spellType == BotSpellTypes::PetCompleteHeals ||
@@ -169,47 +308,63 @@ void bot_command_cast(Client* c, const Seperator* sep)
}
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) {
LogTestDebug("{}: 'Attempting {} [{}] on {}'", __LINE__, c->GetSpellTypeNameByID(spellType), (subType != UINT16_MAX ? c->GetSubTypeNameByID(subType) : "Standard"), (tar ? tar->GetCleanName() : "NOBODY")); //deleteme
if (!tar) {
if (spellType != BotSpellTypes::Escape && spellType != BotSpellTypes::Pet) {
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;
switch (spellType) { //Target Checks
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());
c->Message(Chat::Yellow, "[%s] is not a player's corpse.", tar->GetCleanName());
return;
}
break;
case BotSpellTypes::Identify:
case BotSpellTypes::SendHome:
case BotSpellTypes::BindAffinity:
case BotSpellTypes::SummonCorpse:
if (!tar->IsClient() || !c->IsInGroupOrRaid(tar)) {
c->Message(Chat::Yellow, "[%s] is an invalid target. Only players in your group or raid are eligible targets.", tar->GetCleanName());
return;
}
break;
default:
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())) ||
((tar->IsOfClientBot() && !c->IsInGroupOrRaid(tar)) || (tar->GetOwner() && tar->GetOwner()->IsOfClientBot() && !c->IsInGroupOrRaid(tar->GetOwner())))
) {
c->Message(Chat::Yellow, "[%s] is an invalid target. Only players in your group or raid are eligible targets.", tar->GetCleanName());
return;
}
}
break;
}
const int ab_mask = ActionableBots::ABM_Type1;
std::string actionableArg = sep->arg[ab_arg];
if (actionableArg.empty()) {
actionableArg = "spawned";
}
std::string class_race_arg = sep->arg[ab_arg];
bool class_race_check = false;
@@ -219,7 +374,7 @@ void bot_command_cast(Client* c, const Seperator* sep)
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) {
if (ActionableBots::PopulateSBL(c, actionableArg, 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;
}
@@ -240,7 +395,8 @@ void bot_command_cast(Client* c, const Seperator* sep)
/*
TODO bot rewrite -
FIX: Snares, Group Cures, OOC Song, Precombat, HateRedux, Fear/AE Fear
FIX: Depart, SummonCorpse, Lull,
Group Cures, Precombat, 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???
@@ -250,7 +406,7 @@ void bot_command_cast(Client* c, const Seperator* sep)
}
Mob* newTar = tar;
LogTestDebug("{}: Attempting {} on {}", __LINE__, c->GetSpellTypeNameByID(spellType), (newTar ? newTar->GetCleanName() : "NOBODY")); //deleteme
LogTestDebug("{}: {} says, 'Attempting {} [{}] on {}'", __LINE__, bot_iter->GetCleanName(), c->GetSpellTypeNameByID(spellType), (subType != UINT16_MAX ? c->GetSubTypeNameByID(subType) : "Standard"), (newTar ? newTar->GetCleanName() : "NOBODY")); //deleteme
if (!SpellTypeRequiresTarget(spellType, bot_iter->GetClass())) {
newTar = bot_iter;
}
@@ -279,11 +435,11 @@ void bot_command_cast(Client* c, const Seperator* sep)
continue;
}
LogTestDebug("{}: Attempting {} on {}", __LINE__, c->GetSpellTypeNameByID(spellType), (newTar ? newTar->GetCleanName() : "NOBODY")); //deleteme
LogTestDebug("{}: {} says, 'Attempting {} [{}] on {}'", __LINE__, bot_iter->GetCleanName(), c->GetSpellTypeNameByID(spellType), (subType != UINT16_MAX ? c->GetSubTypeNameByID(subType) : "Standard"), (newTar ? newTar->GetCleanName() : "NOBODY")); //deleteme
bot_iter->SetCommandedSpell(true);
if (bot_iter->AICastSpell(newTar, 100, spellType)) {
if (bot_iter->AICastSpell(newTar, 100, spellType, subTargetType, subType)) {
if (!firstFound) {
firstFound = bot_iter;
}
-54
View File
@@ -1,54 +0,0 @@
#include "../bot_command.h"
void bot_command_charm(Client *c, const Seperator *sep)
{
auto local_list = &bot_command_spells[BCEnum::SpT_Charm];
if (helper_spell_list_fail(c, local_list, BCEnum::SpT_Charm) || helper_command_alias_fail(c, "bot_command_charm", sep->arg[0], "charm"))
return;
if (helper_is_help_or_usage(sep->arg[1])) {
c->Message(Chat::White, "usage: <enemy_target> %s ([option: dire])", sep->arg[0]);
helper_send_usage_required_bots(c, BCEnum::SpT_Charm);
return;
}
bool dire = false;
std::string dire_arg = sep->arg[1];
if (!dire_arg.compare("dire"))
dire = true;
ActionableTarget::Types actionable_targets;
Bot* my_bot = nullptr;
std::list<Bot*> sbl;
MyBots::PopulateSBL_BySpawnedBots(c, sbl);
for (auto list_iter : *local_list) {
auto local_entry = list_iter->SafeCastToCharm();
if (helper_spell_check_fail(local_entry))
continue;
if (local_entry->dire != dire)
continue;
auto target_mob = actionable_targets.Select(c, local_entry->target_type, ENEMY);
if (!target_mob)
continue;
if (target_mob->IsCharmed()) {
c->Message(Chat::White, "Your <target> is already charmed");
return;
}
if (spells[local_entry->spell_id].max_value[EFFECTIDTOINDEX(1)] < target_mob->GetLevel())
continue;
my_bot = ActionableBots::Select_ByMinLevelAndClass(c, local_entry->target_type, sbl, local_entry->spell_level, local_entry->caster_class, target_mob, true);
if (!my_bot)
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;
}
helper_no_available_bots(c, my_bot);
}
-71
View File
@@ -1,71 +0,0 @@
#include "../bot_command.h"
void bot_command_cure(Client *c, const Seperator *sep)
{
bcst_list* local_list = &bot_command_spells[BCEnum::SpT_Cure];
if (helper_spell_list_fail(c, local_list, BCEnum::SpT_Cure) || helper_command_alias_fail(c, "bot_command_cure", sep->arg[0], "cure"))
return;
if (helper_is_help_or_usage(sep->arg[1])) {
c->Message(Chat::White, "usage: (<friendly_target>) %s [ailment: blindness | disease | poison | curse | corruption]", sep->arg[0]);
helper_send_usage_required_bots(c, BCEnum::SpT_Cure);
return;
}
std::string ailment_arg = sep->arg[1];
auto ailment_type = BCEnum::AT_None;
if (!ailment_arg.compare("blindness"))
ailment_type = BCEnum::AT_Blindness;
else if (!ailment_arg.compare("disease"))
ailment_type = BCEnum::AT_Disease;
else if (!ailment_arg.compare("poison"))
ailment_type = BCEnum::AT_Poison;
else if (!ailment_arg.compare("curse"))
ailment_type = BCEnum::AT_Curse;
else if (!ailment_arg.compare("corruption"))
ailment_type = BCEnum::AT_Corruption;
if (ailment_type == BCEnum::AT_None) {
c->Message(Chat::White, "You must specify a cure [ailment] to use this command");
return;
}
local_list->sort([ailment_type](STBaseEntry* l, STBaseEntry* r) {
auto _l = l->SafeCastToCure(), _r = r->SafeCastToCure();
if (_l->cure_value[AILMENTIDTOINDEX(ailment_type)] < _r->cure_value[AILMENTIDTOINDEX(ailment_type)])
return true;
if (_l->cure_value[AILMENTIDTOINDEX(ailment_type)] == _r->cure_value[AILMENTIDTOINDEX(ailment_type)] && spells[_l->spell_id].mana < spells[_r->spell_id].mana)
return true;
if (_l->cure_value[AILMENTIDTOINDEX(ailment_type)] == _r->cure_value[AILMENTIDTOINDEX(ailment_type)] && spells[_l->spell_id].mana == spells[_r->spell_id].mana && _l->cure_total < _r->cure_total)
return true;
return false;
});
ActionableTarget::Types actionable_targets;
Bot* my_bot = nullptr;
std::list<Bot*> sbl;
MyBots::PopulateSBL_BySpawnedBots(c, sbl);
bool cast_success = false;
for (auto list_iter : *local_list) {
auto local_entry = list_iter->SafeCastToCure();
if (helper_spell_check_fail(local_entry))
continue;
if (!local_entry->cure_value[AILMENTIDTOINDEX(ailment_type)])
continue;
auto target_mob = actionable_targets.Select(c, local_entry->target_type, FRIENDLY);
if (!target_mob)
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;
cast_success = helper_cast_standard_spell(my_bot, target_mob, local_entry->spell_id);
break;
}
helper_no_available_bots(c, my_bot);
}
-44
View File
@@ -1,44 +0,0 @@
#include "../bot_command.h"
void bot_command_escape(Client *c, const Seperator *sep)
{
bcst_list* local_list = &bot_command_spells[BCEnum::SpT_Escape];
if (helper_spell_list_fail(c, local_list, BCEnum::SpT_Escape) || helper_command_alias_fail(c, "bot_command_escape", sep->arg[0], "escape"))
return;
if (helper_is_help_or_usage(sep->arg[1])) {
c->Message(Chat::White, "usage: (<friendly_target>) %s ([option: lesser])", sep->arg[0]);
helper_send_usage_required_bots(c, BCEnum::SpT_Escape);
return;
}
bool use_lesser = false;
if (!strcasecmp(sep->arg[1], "lesser"))
use_lesser = true;
ActionableTarget::Types actionable_targets;
Bot* my_bot = nullptr;
std::list<Bot*> sbl;
MyBots::PopulateSBL_BySpawnedBots(c, sbl);
bool cast_success = false;
for (auto list_iter : *local_list) {
auto local_entry = list_iter->SafeCastToEscape();
if (helper_spell_check_fail(local_entry))
continue;
if (local_entry->lesser != use_lesser)
continue;
auto target_mob = actionable_targets.Select(c, local_entry->target_type, FRIENDLY);
if (!target_mob)
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;
cast_success = helper_cast_standard_spell(my_bot, target_mob, local_entry->spell_id);
break;
}
helper_no_available_bots(c, my_bot);
}
-38
View File
@@ -1,38 +0,0 @@
#include "../bot_command.h"
void bot_command_identify(Client *c, const Seperator *sep)
{
bcst_list* local_list = &bot_command_spells[BCEnum::SpT_Identify];
if (helper_spell_list_fail(c, local_list, BCEnum::SpT_Identify) || helper_command_alias_fail(c, "bot_command_identify", sep->arg[0], "identify"))
return;
if (helper_is_help_or_usage(sep->arg[1])) {
c->Message(Chat::White, "usage: (<friendly_target>) %s", sep->arg[0]);
helper_send_usage_required_bots(c, BCEnum::SpT_Identify);
return;
}
ActionableTarget::Types actionable_targets;
Bot* my_bot = nullptr;
std::list<Bot*> sbl;
MyBots::PopulateSBL_BySpawnedBots(c, sbl);
bool cast_success = false;
for (auto list_iter : *local_list) {
auto local_entry = list_iter;
if (helper_spell_check_fail(local_entry))
continue;
auto target_mob = actionable_targets.Select(c, local_entry->target_type, FRIENDLY);
if (!target_mob)
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;
cast_success = helper_cast_standard_spell(my_bot, target_mob, local_entry->spell_id);
break;
}
helper_no_available_bots(c, my_bot);
}
-57
View File
@@ -1,57 +0,0 @@
#include "../bot_command.h"
void bot_command_invisibility(Client *c, const Seperator *sep)
{
bcst_list* local_list = &bot_command_spells[BCEnum::SpT_Invisibility];
if (helper_spell_list_fail(c, local_list, BCEnum::SpT_Invisibility) || helper_command_alias_fail(c, "bot_command_invisibility", sep->arg[0], "invisibility"))
return;
if (helper_is_help_or_usage(sep->arg[1])) {
c->Message(Chat::White, "usage: (<friendly_target>) %s [invisibility: living | undead | animal | see]", sep->arg[0]);
helper_send_usage_required_bots(c, BCEnum::SpT_Invisibility);
return;
}
std::string invisibility = sep->arg[1];
BCEnum::IType invisibility_type = BCEnum::IT_None;
if (!invisibility.compare("living"))
invisibility_type = BCEnum::IT_Living;
else if (!invisibility.compare("undead"))
invisibility_type = BCEnum::IT_Undead;
else if (!invisibility.compare("animal"))
invisibility_type = BCEnum::IT_Animal;
else if (!invisibility.compare("see"))
invisibility_type = BCEnum::IT_See;
if (invisibility_type == BCEnum::IT_None) {
c->Message(Chat::White, "You must specify an [invisibility]");
return;
}
ActionableTarget::Types actionable_targets;
Bot* my_bot = nullptr;
std::list<Bot*> sbl;
MyBots::PopulateSBL_BySpawnedBots(c, sbl);
bool cast_success = false;
for (auto list_iter : *local_list) {
auto local_entry = list_iter->SafeCastToInvisibility();
if (helper_spell_check_fail(local_entry))
continue;
if (local_entry->invis_type != invisibility_type)
continue;
auto target_mob = actionable_targets.Select(c, local_entry->target_type, FRIENDLY);
if (!target_mob)
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;
cast_success = helper_cast_standard_spell(my_bot, target_mob, local_entry->spell_id);
break;
}
helper_no_available_bots(c, my_bot);
}
-38
View File
@@ -1,38 +0,0 @@
#include "../bot_command.h"
void bot_command_levitation(Client *c, const Seperator *sep)
{
bcst_list* local_list = &bot_command_spells[BCEnum::SpT_Levitation];
if (helper_spell_list_fail(c, local_list, BCEnum::SpT_Levitation) || helper_command_alias_fail(c, "bot_command_levitation", sep->arg[0], "levitation"))
return;
if (helper_is_help_or_usage(sep->arg[1])) {
c->Message(Chat::White, "usage: (<friendly_target>) %s", sep->arg[0]);
helper_send_usage_required_bots(c, BCEnum::SpT_Levitation);
return;
}
ActionableTarget::Types actionable_targets;
Bot* my_bot = nullptr;
std::list<Bot*> sbl;
MyBots::PopulateSBL_BySpawnedBots(c, sbl);
bool cast_success = false;
for (auto list_iter : *local_list) {
auto local_entry = list_iter;
if (helper_spell_check_fail(local_entry))
continue;
auto target_mob = actionable_targets.Select(c, local_entry->target_type, FRIENDLY);
if (!target_mob)
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;
cast_success = helper_cast_standard_spell(my_bot, target_mob, local_entry->spell_id);
break;
}
helper_no_available_bots(c, my_bot);
}
-41
View File
@@ -1,41 +0,0 @@
#include "../bot_command.h"
void bot_command_mesmerize(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]);
helper_send_usage_required_bots(c, BCEnum::SpT_Mesmerize);
return;
}
bool isSuccess = false;
std::list<Bot*> sbl;
MyBots::PopulateSBL_BySpawnedBots(c, sbl);
for (auto bot_iter : sbl) {
std::list<BotSpell_wPriority> botSpellList = bot_iter->GetPrioritizedBotSpellsBySpellType(bot_iter, BotSpellTypes::Mez, c->GetTarget(), IsAEBotSpellType(BotSpellTypes::Mez));
for (const auto& s : botSpellList) {
if (!IsValidSpell(s.SpellId)) {
continue;
}
if (!bot_iter->IsInGroupOrRaid(c)) {
continue;
}
if (!bot_iter->CastChecks(s.SpellId, c->GetTarget(), BotSpellTypes::Mez, false, false)) {
continue;
}
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;
}
}
}
if (!isSuccess) {
helper_no_available_bots(c);
}
}
-50
View File
@@ -1,50 +0,0 @@
#include "../bot_command.h"
void bot_command_movement_speed(Client *c, const Seperator *sep)
{
bcst_list* local_list = &bot_command_spells[BCEnum::SpT_MovementSpeed];
if (helper_spell_list_fail(c, local_list, BCEnum::SpT_MovementSpeed) || helper_command_alias_fail(c, "bot_command_movement_speed", sep->arg[0], "movementspeed"))
return;
if (helper_is_help_or_usage(sep->arg[1])) {
c->Message(Chat::White, "usage: (<friendly_target>) %s ([group | sow])", sep->arg[0]);
helper_send_usage_required_bots(c, BCEnum::SpT_MovementSpeed);
return;
}
bool group = false;
bool sow = false;
std::string arg1 = sep->arg[1];
if (!arg1.compare("group"))
group = true;
else if (!arg1.compare("sow"))
sow = true;
ActionableTarget::Types actionable_targets;
Bot* my_bot = nullptr;
std::list<Bot*> sbl;
MyBots::PopulateSBL_BySpawnedBots(c, sbl);
bool cast_success = false;
for (auto list_iter : *local_list) {
auto local_entry = list_iter->SafeCastToMovementSpeed();
if (helper_spell_check_fail(local_entry))
continue;
if (!sow && (local_entry->group != group))
continue;
if (sow && (local_entry->spell_id != 278)) // '278' = single-target "Spirit of Wolf"
continue;
auto target_mob = actionable_targets.Select(c, local_entry->target_type, FRIENDLY);
if (!target_mob)
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;
cast_success = helper_cast_standard_spell(my_bot, target_mob, local_entry->spell_id);
break;
}
helper_no_available_bots(c, my_bot);
}
-73
View File
@@ -1,73 +0,0 @@
#include "../bot_command.h"
void bot_command_resistance(Client *c, const Seperator *sep)
{
bcst_list* local_list = &bot_command_spells[BCEnum::SpT_Resistance];
if (helper_spell_list_fail(c, local_list, BCEnum::SpT_Resistance) || helper_command_alias_fail(c, "bot_command_resistance", sep->arg[0], "resistance"))
return;
if (helper_is_help_or_usage(sep->arg[1])) {
c->Message(Chat::White, "usage: (<friendly_target>) %s [resistance: fire | cold | poison | disease | magic | corruption]", sep->arg[0]);
helper_send_usage_required_bots(c, BCEnum::SpT_Resistance);
return;
}
std::string resistance_arg = sep->arg[1];
auto resistance_type = BCEnum::RT_None;
if (!resistance_arg.compare("fire"))
resistance_type = BCEnum::RT_Fire;
else if (!resistance_arg.compare("cold"))
resistance_type = BCEnum::RT_Cold;
else if (!resistance_arg.compare("poison"))
resistance_type = BCEnum::RT_Poison;
else if (!resistance_arg.compare("disease"))
resistance_type = BCEnum::RT_Disease;
else if (!resistance_arg.compare("magic"))
resistance_type = BCEnum::RT_Magic;
else if (!resistance_arg.compare("corruption"))
resistance_type = BCEnum::RT_Corruption;
if (resistance_type == BCEnum::RT_None) {
c->Message(Chat::White, "You must specify a [resistance]");
return;
}
local_list->sort([resistance_type](STBaseEntry* l, STBaseEntry* r) {
auto _l = l->SafeCastToResistance(), _r = r->SafeCastToResistance();
if (_l->resist_value[RESISTANCEIDTOINDEX(resistance_type)] > _r->resist_value[RESISTANCEIDTOINDEX(resistance_type)])
return true;
if (_l->resist_value[RESISTANCEIDTOINDEX(resistance_type)] == _r->resist_value[RESISTANCEIDTOINDEX(resistance_type)] && spells[_l->spell_id].mana < spells[_r->spell_id].mana)
return true;
if (_l->resist_value[RESISTANCEIDTOINDEX(resistance_type)] == _r->resist_value[RESISTANCEIDTOINDEX(resistance_type)] && spells[_l->spell_id].mana == spells[_r->spell_id].mana && _l->resist_total > _r->resist_total)
return true;
return false;
});
ActionableTarget::Types actionable_targets;
Bot* my_bot = nullptr;
std::list<Bot*> sbl;
MyBots::PopulateSBL_BySpawnedBots(c, sbl);
bool cast_success = false;
for (auto list_iter : *local_list) {
auto local_entry = list_iter->SafeCastToResistance();
if (helper_spell_check_fail(local_entry))
continue;
if (!local_entry->resist_value[RESISTANCEIDTOINDEX(resistance_type)])
continue;
auto target_mob = actionable_targets.Select(c, local_entry->target_type, FRIENDLY);
if (!target_mob)
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;
cast_success = helper_cast_standard_spell(my_bot, target_mob, local_entry->spell_id);
break;
}
helper_no_available_bots(c, my_bot);
}
-57
View File
@@ -1,57 +0,0 @@
#include "../bot_command.h"
void bot_command_resurrect(Client *c, const Seperator *sep)
{
// Obscure bot spell code prohibits the aoe portion from working correctly...
bcst_list* local_list = &bot_command_spells[BCEnum::SpT_Resurrect];
if (helper_spell_list_fail(c, local_list, BCEnum::SpT_Resurrect) || helper_command_alias_fail(c, "bot_command_resurrect", sep->arg[0], "resurrect"))
return;
if (helper_is_help_or_usage(sep->arg[1])) {
//c->Message(Chat::White, "usage: <corpse_target> %s ([option: aoe])", sep->arg[0]);
c->Message(Chat::White, "usage: <corpse_target> %s", sep->arg[0]);
helper_send_usage_required_bots(c, BCEnum::SpT_Resurrect);
return;
}
bool aoe = false;
//std::string aoe_arg = sep->arg[1];
//if (!aoe_arg.compare("aoe"))
// aoe = true;
ActionableTarget::Types actionable_targets;
Bot* my_bot = nullptr;
std::list<Bot*> sbl;
MyBots::PopulateSBL_BySpawnedBots(c, sbl);
for (auto list_iter : *local_list) {
auto local_entry = list_iter->SafeCastToResurrect();
if (helper_spell_check_fail(local_entry))
continue;
//if (local_entry->aoe != aoe)
// continue;
if (local_entry->aoe)
continue;
auto target_mob = actionable_targets.Select(c, local_entry->target_type, FRIENDLY);
//if (!target_mob && !local_entry->aoe)
// continue;
if (!target_mob)
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 (local_entry->aoe)
// target_mob = my_bot;
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;
}
helper_no_available_bots(c, my_bot);
}
-38
View File
@@ -1,38 +0,0 @@
#include "../bot_command.h"
void bot_command_rune(Client *c, const Seperator *sep)
{
bcst_list* local_list = &bot_command_spells[BCEnum::SpT_Rune];
if (helper_spell_list_fail(c, local_list, BCEnum::SpT_Rune) || helper_command_alias_fail(c, "bot_command_rune", sep->arg[0], "rune"))
return;
if (helper_is_help_or_usage(sep->arg[1])) {
c->Message(Chat::White, "usage: (<friendly_target>) %s", sep->arg[0]);
helper_send_usage_required_bots(c, BCEnum::SpT_Rune);
return;
}
ActionableTarget::Types actionable_targets;
Bot* my_bot = nullptr;
std::list<Bot*> sbl;
MyBots::PopulateSBL_BySpawnedBots(c, sbl);
bool cast_success = false;
for (auto list_iter : *local_list) {
auto local_entry = list_iter;
if (helper_spell_check_fail(local_entry))
continue;
auto target_mob = actionable_targets.Select(c, local_entry->target_type, FRIENDLY);
if (!target_mob)
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;
cast_success = helper_cast_standard_spell(my_bot, target_mob, local_entry->spell_id);
break;
}
helper_no_available_bots(c, my_bot);
}
-47
View File
@@ -1,47 +0,0 @@
#include "../bot_command.h"
void bot_command_send_home(Client *c, const Seperator *sep)
{
// Obscure bot spell code prohibits the aoe portion from working correctly...
bcst_list* local_list = &bot_command_spells[BCEnum::SpT_SendHome];
if (helper_spell_list_fail(c, local_list, BCEnum::SpT_SendHome) || helper_command_alias_fail(c, "bot_command_send_home", sep->arg[0], "sendhome"))
return;
if (helper_is_help_or_usage(sep->arg[1])) {
c->Message(Chat::White, "usage: (<friendly_target>) %s ([option: group])", sep->arg[0]);
helper_send_usage_required_bots(c, BCEnum::SpT_SendHome);
return;
}
bool group = false;
std::string group_arg = sep->arg[1];
if (!group_arg.compare("group"))
group = true;
ActionableTarget::Types actionable_targets;
Bot* my_bot = nullptr;
std::list<Bot*> sbl;
MyBots::PopulateSBL_BySpawnedBots(c, sbl);
bool cast_success = false;
for (auto list_iter : *local_list) {
auto local_entry = list_iter->SafeCastToSendHome();
if (helper_spell_check_fail(local_entry))
continue;
if (local_entry->group != group)
continue;
auto target_mob = actionable_targets.Select(c, local_entry->target_type, FRIENDLY);
if (!target_mob)
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;
cast_success = helper_cast_standard_spell(my_bot, target_mob, local_entry->spell_id);
break;
}
helper_no_available_bots(c, my_bot);
}
-50
View File
@@ -1,50 +0,0 @@
#include "../bot_command.h"
void bot_command_size(Client *c, const Seperator *sep)
{
bcst_list* local_list = &bot_command_spells[BCEnum::SpT_Size];
if (helper_spell_list_fail(c, local_list, BCEnum::SpT_Size) || helper_command_alias_fail(c, "bot_command_size", sep->arg[0], "size"))
return;
if (helper_is_help_or_usage(sep->arg[1])) {
c->Message(Chat::White, "usage: (<friendly_target>) %s [grow | shrink]", sep->arg[0]);
helper_send_usage_required_bots(c, BCEnum::SpT_Size);
return;
}
std::string size_arg = sep->arg[1];
auto size_type = BCEnum::SzT_Reduce;
if (!size_arg.compare("grow")) {
size_type = BCEnum::SzT_Enlarge;
}
else if (size_arg.compare("shrink")) {
c->Message(Chat::White, "This command requires a [grow | shrink] argument");
return;
}
ActionableTarget::Types actionable_targets;
Bot* my_bot = nullptr;
std::list<Bot*> sbl;
MyBots::PopulateSBL_BySpawnedBots(c, sbl);
bool cast_success = false;
for (auto list_iter : *local_list) {
auto local_entry = list_iter->SafeCastToSize();
if (helper_spell_check_fail(local_entry))
continue;
if (local_entry->size_type != size_type)
continue;
auto target_mob = actionable_targets.Select(c, local_entry->target_type, FRIENDLY);
if (!target_mob)
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;
cast_success = helper_cast_standard_spell(my_bot, target_mob, local_entry->spell_id);
break;
}
helper_no_available_bots(c, my_bot);
}
-38
View File
@@ -1,38 +0,0 @@
#include "../bot_command.h"
void bot_command_water_breathing(Client *c, const Seperator *sep)
{
bcst_list* local_list = &bot_command_spells[BCEnum::SpT_WaterBreathing];
if (helper_spell_list_fail(c, local_list, BCEnum::SpT_WaterBreathing) || helper_command_alias_fail(c, "bot_command_water_breathing", sep->arg[0], "waterbreathing"))
return;
if (helper_is_help_or_usage(sep->arg[1])) {
c->Message(Chat::White, "usage: (<friendly_target>) %s", sep->arg[0]);
helper_send_usage_required_bots(c, BCEnum::SpT_WaterBreathing);
return;
}
ActionableTarget::Types actionable_targets;
Bot* my_bot = nullptr;
std::list<Bot*> sbl;
MyBots::PopulateSBL_BySpawnedBots(c, sbl);
bool cast_success = false;
for (auto list_iter : *local_list) {
auto local_entry = list_iter;
if (helper_spell_check_fail(local_entry))
continue;
auto target_mob = actionable_targets.Select(c, local_entry->target_type, FRIENDLY);
if (!target_mob)
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;
cast_success = helper_cast_standard_spell(my_bot, target_mob, local_entry->spell_id);
break;
}
helper_no_available_bots(c, my_bot);
}