mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-12 22:01:30 +00:00
[Bots] Add Caster Range Command, and IsValidSpellRange Checks (#2942)
* [Bots] Add Caster Range Command, and IsValidSpellRange Checks * remove/add exceptions where makes sense like buffs * fixes * fixes
This commit is contained in:
parent
0d72295cc9
commit
afaa8f4100
@ -69,6 +69,7 @@ public:
|
||||
int32_t expansion_bitmask;
|
||||
uint8_t enforce_spell_settings;
|
||||
uint8_t archery_setting;
|
||||
uint32_t caster_range;
|
||||
};
|
||||
|
||||
static std::string PrimaryKey()
|
||||
@ -129,6 +130,7 @@ public:
|
||||
"expansion_bitmask",
|
||||
"enforce_spell_settings",
|
||||
"archery_setting",
|
||||
"caster_range",
|
||||
};
|
||||
}
|
||||
|
||||
@ -185,6 +187,7 @@ public:
|
||||
"expansion_bitmask",
|
||||
"enforce_spell_settings",
|
||||
"archery_setting",
|
||||
"caster_range",
|
||||
};
|
||||
}
|
||||
|
||||
@ -275,6 +278,7 @@ public:
|
||||
e.expansion_bitmask = -1;
|
||||
e.enforce_spell_settings = 0;
|
||||
e.archery_setting = 0;
|
||||
e.caster_range = 0;
|
||||
|
||||
return e;
|
||||
}
|
||||
@ -361,6 +365,7 @@ public:
|
||||
e.expansion_bitmask = static_cast<int32_t>(atoi(row[47]));
|
||||
e.enforce_spell_settings = static_cast<uint8_t>(strtoul(row[48], nullptr, 10));
|
||||
e.archery_setting = static_cast<uint8_t>(strtoul(row[49], nullptr, 10));
|
||||
e.caster_range = static_cast<uint32_t>(strtoul(row[50], nullptr, 10));
|
||||
|
||||
return e;
|
||||
}
|
||||
@ -443,6 +448,7 @@ public:
|
||||
v.push_back(columns[47] + " = " + std::to_string(e.expansion_bitmask));
|
||||
v.push_back(columns[48] + " = " + std::to_string(e.enforce_spell_settings));
|
||||
v.push_back(columns[49] + " = " + std::to_string(e.archery_setting));
|
||||
v.push_back(columns[50] + " = " + std::to_string(e.caster_range));
|
||||
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
@ -514,6 +520,7 @@ public:
|
||||
v.push_back(std::to_string(e.expansion_bitmask));
|
||||
v.push_back(std::to_string(e.enforce_spell_settings));
|
||||
v.push_back(std::to_string(e.archery_setting));
|
||||
v.push_back(std::to_string(e.caster_range));
|
||||
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
@ -593,6 +600,7 @@ public:
|
||||
v.push_back(std::to_string(e.expansion_bitmask));
|
||||
v.push_back(std::to_string(e.enforce_spell_settings));
|
||||
v.push_back(std::to_string(e.archery_setting));
|
||||
v.push_back(std::to_string(e.caster_range));
|
||||
|
||||
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
||||
}
|
||||
@ -676,6 +684,7 @@ public:
|
||||
e.expansion_bitmask = static_cast<int32_t>(atoi(row[47]));
|
||||
e.enforce_spell_settings = static_cast<uint8_t>(strtoul(row[48], nullptr, 10));
|
||||
e.archery_setting = static_cast<uint8_t>(strtoul(row[49], nullptr, 10));
|
||||
e.caster_range = static_cast<uint32_t>(strtoul(row[50], nullptr, 10));
|
||||
|
||||
all_entries.push_back(e);
|
||||
}
|
||||
@ -750,6 +759,7 @@ public:
|
||||
e.expansion_bitmask = static_cast<int32_t>(atoi(row[47]));
|
||||
e.enforce_spell_settings = static_cast<uint8_t>(strtoul(row[48], nullptr, 10));
|
||||
e.archery_setting = static_cast<uint8_t>(strtoul(row[49], nullptr, 10));
|
||||
e.caster_range = static_cast<uint32_t>(strtoul(row[50], nullptr, 10));
|
||||
|
||||
all_entries.push_back(e);
|
||||
}
|
||||
|
||||
@ -43,7 +43,7 @@
|
||||
*/
|
||||
|
||||
#define CURRENT_BINARY_DATABASE_VERSION 9220
|
||||
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 9037
|
||||
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 9038
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@ -36,6 +36,7 @@
|
||||
9035|2022_12_04_bot_archery.sql|SHOW COLUMNS FROM `bot_data` LIKE 'archery_setting'|empty|
|
||||
9036|2023_01_19_drop_bot_views.sql|SHOW TABLES LIKE 'vw_groups'|not_empty|
|
||||
9037|2023_01_22_add_name_index.sql||show index from bot_data WHERE key_name = 'name`|empty|
|
||||
9038|2023_02_16_add_caster_range.sql|SHOW COLUMNS FROM `bot_data` LIKE 'caster_range'|empty|
|
||||
|
||||
# Upgrade conditions:
|
||||
# This won't be needed after this system is implemented, but it is used database that are not
|
||||
|
||||
@ -0,0 +1,2 @@
|
||||
ALTER TABLE `bot_data`
|
||||
ADD COLUMN `caster_range` INT(11) UNSIGNED NOT NULL DEFAULT '300' AFTER `archery_setting`;
|
||||
44
zone/bot.cpp
44
zone/bot.cpp
@ -71,6 +71,7 @@ Bot::Bot(NPCType *npcTypeData, Client* botOwner) : NPC(npcTypeData, nullptr, glm
|
||||
m_enforce_spell_settings = 0;
|
||||
m_bot_archery_setting = 0;
|
||||
m_expansion_bitmask = -1;
|
||||
m_bot_caster_range = 0;
|
||||
SetBotID(0);
|
||||
SetBotSpellID(0);
|
||||
SetSpawnStatus(false);
|
||||
@ -3115,26 +3116,7 @@ void Bot::AI_Process()
|
||||
}
|
||||
}
|
||||
float melee_distance_min = melee_distance / 2.0f;
|
||||
|
||||
// Calculate caster distances
|
||||
float caster_distance_max = 0.0f;
|
||||
float caster_distance_min = 0.0f;
|
||||
float caster_distance = 0.0f;
|
||||
{
|
||||
if (GetLevel() >= GetStopMeleeLevel() && GetClass() >= WARRIOR && GetClass() <= BERSERKER) {
|
||||
caster_distance_max = MAX_CASTER_DISTANCE[(GetClass() - 1)];
|
||||
}
|
||||
|
||||
if (caster_distance_max) {
|
||||
|
||||
caster_distance_min = melee_distance_max;
|
||||
if (caster_distance_max <= caster_distance_min) {
|
||||
caster_distance_max = caster_distance_min * 1.25f;
|
||||
}
|
||||
|
||||
caster_distance = ((caster_distance_max + caster_distance_min) / 2);
|
||||
}
|
||||
}
|
||||
float caster_distance_max = GetBotCasterMaxRange(melee_distance_max);
|
||||
|
||||
bool atArcheryRange = IsArcheryRange(tar);
|
||||
|
||||
@ -3157,11 +3139,11 @@ void Bot::AI_Process()
|
||||
ChangeBotArcherWeapons(IsBotArcher());
|
||||
}
|
||||
}
|
||||
|
||||
bool stop_melee_level = GetLevel() >= GetStopMeleeLevel();
|
||||
if (IsBotArcher() && atArcheryRange) {
|
||||
atCombatRange = true;
|
||||
}
|
||||
else if (caster_distance_max && tar_distance <= caster_distance_max) {
|
||||
else if (caster_distance_max && tar_distance <= caster_distance_max && stop_melee_level) {
|
||||
atCombatRange = true;
|
||||
}
|
||||
else if (tar_distance <= melee_distance) {
|
||||
@ -9825,4 +9807,22 @@ void Bot::SendSpellAnim(uint16 target_id, uint16 spell_id)
|
||||
entity_list.QueueCloseClients(this, &app, false, RuleI(Range, SpellParticles));
|
||||
}
|
||||
|
||||
float Bot::GetBotCasterMaxRange(float melee_distance_max) {// Calculate caster distances
|
||||
float caster_distance_max = 0.0f;
|
||||
float caster_distance_min = 0.0f;
|
||||
float caster_distance = 0.0f;
|
||||
|
||||
caster_distance_max = GetBotCasterRange() * GetBotCasterRange();
|
||||
if (!GetBotCasterRange() && GetLevel() >= GetStopMeleeLevel() && GetClass() >= WARRIOR && GetClass() <= BERSERKER) {
|
||||
caster_distance_max = MAX_CASTER_DISTANCE[GetClass() - 1];
|
||||
}
|
||||
if (caster_distance_max) {
|
||||
caster_distance_min = melee_distance_max;
|
||||
if (caster_distance_max <= caster_distance_min) {
|
||||
caster_distance_max = caster_distance_min * 1.25f;
|
||||
}
|
||||
}
|
||||
return caster_distance_max;
|
||||
}
|
||||
|
||||
uint8 Bot::spell_casting_chances[SPELL_TYPE_COUNT][PLAYER_CLASS_COUNT][EQ::constants::STANCE_TYPE_COUNT][cntHSND] = { 0 };
|
||||
|
||||
@ -348,6 +348,8 @@ public:
|
||||
void SetStopMeleeLevel(uint8 level);
|
||||
void SetGuardMode();
|
||||
void SetHoldMode();
|
||||
uint32 GetBotCasterRange() { return m_bot_caster_range; }
|
||||
bool IsValidSpellRange(uint16 spell_id, Mob const* tar);
|
||||
|
||||
// Bot AI Methods
|
||||
void AI_Bot_Init();
|
||||
@ -490,7 +492,7 @@ public:
|
||||
EQ::constants::StanceType GetBotStance() { return _botStance; }
|
||||
uint8 GetChanceToCastBySpellType(uint32 spellType);
|
||||
bool GetBotEnforceSpellSetting() { return m_enforce_spell_settings; }
|
||||
|
||||
float GetBotCasterMaxRange(float melee_distance_max);
|
||||
bool IsGroupHealer() { return m_CastingRoles.GroupHealer; }
|
||||
bool IsGroupSlower() { return m_CastingRoles.GroupSlower; }
|
||||
bool IsGroupNuker() { return m_CastingRoles.GroupNuker; }
|
||||
@ -623,6 +625,7 @@ public:
|
||||
else
|
||||
_botStance = EQ::constants::stancePassive;
|
||||
}
|
||||
void SetBotCasterRange(uint32 bot_caster_range) { m_bot_caster_range = bot_caster_range; }
|
||||
void SetSpellRecastTimer(int timer_index, int32 recast_delay);
|
||||
void SetDisciplineRecastTimer(int timer_index, int32 recast_delay);
|
||||
void SetAltOutOfCombatBehavior(bool behavior_flag) { _altoutofcombatbehavior = behavior_flag;}
|
||||
@ -820,7 +823,7 @@ private:
|
||||
bool m_pulling_flag;
|
||||
bool m_returning_flag;
|
||||
eStandingPetOrder m_previous_pet_order;
|
||||
|
||||
uint32 m_bot_caster_range;
|
||||
BotCastingRoles m_CastingRoles;
|
||||
std::map<std::string,std::string> bot_data_buckets;
|
||||
std::map<std::string,std::string> bot_owner_data_buckets;
|
||||
|
||||
@ -1366,6 +1366,7 @@ int bot_command_init(void)
|
||||
bot_command_add("bottitle", "Sets a bots title", AccountStatus::Player, bot_subcommand_bot_title) ||
|
||||
bot_command_add("botupdate", "Updates a bot to reflect any level changes that you have experienced", AccountStatus::Player, bot_subcommand_bot_update) ||
|
||||
bot_command_add("botwoad", "Changes the Barbarian woad of a bot", AccountStatus::Player, bot_subcommand_bot_woad) ||
|
||||
bot_command_add("casterrange", "Controls the range casters will try to stay away from a mob (if too far, they will skip spells that are out-of-range)", AccountStatus::Player, bot_command_caster_range) ||
|
||||
bot_command_add("charm", "Attempts to have a bot charm your target", AccountStatus::Player, bot_command_charm) ||
|
||||
bot_command_add("circle", "Orders a Druid bot to open a magical doorway to a specified destination", AccountStatus::Player, bot_subcommand_circle) ||
|
||||
bot_command_add("cure", "Orders a bot to remove any ailments", AccountStatus::Player, bot_command_cure) ||
|
||||
@ -10848,3 +10849,53 @@ void bot_command_enforce_spell_list(Client* c, const Seperator *sep)
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
|
||||
void bot_command_caster_range(Client* c, const Seperator* sep)
|
||||
{
|
||||
if (helper_command_alias_fail(c, "bot_command_caster_range", sep->arg[0], "casterrange")) {
|
||||
return;
|
||||
}
|
||||
if (helper_is_help_or_usage(sep->arg[1])) {
|
||||
c->Message(Chat::White, "usage: <target_bot> %s [current | value: 0 - 300].", 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.");
|
||||
c->Message(Chat::White, "note: If they are too far for a spell, it will be skipped.");
|
||||
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 to use this command.");
|
||||
return;
|
||||
}
|
||||
|
||||
uint32 crange = 0;
|
||||
if (sep->IsNumber(1)) {
|
||||
crange = atoi(sep->arg[1]);
|
||||
if (crange >= 0 && crange <= 300) {
|
||||
my_bot->SetBotCasterRange(crange);
|
||||
if (!database.botdb.SaveBotCasterRange(c->CharacterID(), my_bot->GetBotID(), crange)) {
|
||||
c->Message(Chat::White, "%s for '%s'", BotDatabase::fail::SaveBotCasterRange(), my_bot->GetCleanName());
|
||||
return;
|
||||
}
|
||||
else {
|
||||
c->Message(Chat::White, "Successfully set Caster Range for %s to %u.", my_bot->GetCleanName(), crange);
|
||||
}
|
||||
}
|
||||
else {
|
||||
c->Message(Chat::White, "You must enter a value within the range of 0 - 300.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (!strcasecmp(sep->arg[1], "current")) {
|
||||
c->Message(Chat::White, "My current range is %u.", my_bot->GetBotCasterRange());
|
||||
}
|
||||
else {
|
||||
c->Message(Chat::White, "Incorrect argument, use help for a list of options.");
|
||||
}
|
||||
}
|
||||
@ -553,6 +553,7 @@ void bot_command_attack(Client *c, const Seperator *sep);
|
||||
void bot_command_bind_affinity(Client *c, const Seperator *sep);
|
||||
void bot_command_bot(Client *c, const Seperator *sep);
|
||||
void bot_command_botgroup(Client *c, const Seperator *sep);
|
||||
void bot_command_caster_range(Client* c, const Seperator* sep);
|
||||
void bot_command_charm(Client *c, const Seperator *sep);
|
||||
void bot_command_cure(Client *c, const Seperator *sep);
|
||||
void bot_command_defensive(Client *c, const Seperator *sep);
|
||||
|
||||
@ -485,6 +485,8 @@ bool BotDatabase::LoadBot(const uint32 bot_id, Bot*& loaded_bot)
|
||||
loaded_bot->SetBotEnforceSpellSetting((l.enforce_spell_settings ? true : false));
|
||||
|
||||
loaded_bot->SetBotArcherySetting((l.archery_setting ? true : false));
|
||||
|
||||
loaded_bot->SetBotCasterRange(l.caster_range);
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -545,6 +547,7 @@ bool BotDatabase::SaveNewBot(Bot* bot_inst, uint32& bot_id)
|
||||
e.expansion_bitmask = bot_inst->GetExpansionBitmask();
|
||||
e.enforce_spell_settings = bot_inst->GetBotEnforceSpellSetting();
|
||||
e.archery_setting = bot_inst->IsBotArcher() ? 1 : 0;
|
||||
e.caster_range = bot_inst->GetBotCasterRange();
|
||||
|
||||
auto b = BotDataRepository::InsertOne(database, e);
|
||||
if (!b.bot_id) {
|
||||
@ -3151,6 +3154,30 @@ std::string BotDatabase::GetBotNameByID(const uint32 bot_id)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool BotDatabase::SaveBotCasterRange(const uint32 owner_id, const uint32 bot_id, const uint32 bot_caster_range_value)
|
||||
{
|
||||
if (!owner_id || !bot_id) {
|
||||
return false;
|
||||
}
|
||||
|
||||
query = fmt::format(
|
||||
"UPDATE `bot_data`"
|
||||
" SET `caster_range` = '{}'"
|
||||
" WHERE `owner_id` = '{}'"
|
||||
" AND `bot_id` = '{}'",
|
||||
bot_caster_range_value,
|
||||
owner_id,
|
||||
bot_id
|
||||
);
|
||||
auto results = database.QueryDatabase(query);
|
||||
|
||||
if (!results.Success()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* fail::Bot functions */
|
||||
const char* BotDatabase::fail::LoadBotsList() { return "Failed to bots list"; }
|
||||
const char* BotDatabase::fail::LoadOwnerID() { return "Failed to load owner ID"; }
|
||||
@ -3205,6 +3232,7 @@ const char* BotDatabase::fail::ToggleAllHelmAppearances() { return "Failed to sa
|
||||
const char* BotDatabase::fail::SaveFollowDistance() { return "Failed to save follow distance"; }
|
||||
const char* BotDatabase::fail::SaveAllFollowDistances() { return "Failed to save all follow distances"; }
|
||||
const char* BotDatabase::fail::SaveStopMeleeLevel() { return "Failed to save stop melee level"; }
|
||||
const char* BotDatabase::fail::SaveBotCasterRange() { return "Failed to save caster range"; }
|
||||
|
||||
/* fail::Bot heal rotation functions */
|
||||
const char* BotDatabase::fail::LoadHealRotationIDByBotID() { return "Failed to load heal rotation ID by bot ID"; }
|
||||
|
||||
@ -146,6 +146,8 @@ public:
|
||||
bool SaveOwnerOption(const uint32 owner_id, size_t type, const bool flag);
|
||||
bool SaveOwnerOption(const uint32 owner_id, const std::pair<size_t, size_t> type, const std::pair<bool, bool> flag);
|
||||
|
||||
bool SaveBotCasterRange(const uint32 owner_id, const uint32 bot_id, const uint32 bot_caster_range_value);
|
||||
|
||||
/* Bot bot-group functions */
|
||||
bool QueryBotGroupExistence(const std::string& botgroup_name);
|
||||
|
||||
@ -250,6 +252,7 @@ public:
|
||||
static const char* SaveFollowDistance();
|
||||
static const char* SaveAllFollowDistances();
|
||||
static const char* SaveStopMeleeLevel();
|
||||
static const char* SaveBotCasterRange();
|
||||
|
||||
/* fail::Bot bot-group functions */
|
||||
static const char* QueryBotGroupExistence();
|
||||
|
||||
@ -98,8 +98,10 @@ bool Bot::AICastSpell(Mob* tar, uint8 iChance, uint32 iSpellTypes) {
|
||||
if (!(!addMob->IsImmuneToSpell(botSpell.SpellId, this) && addMob->CanBuffStack(botSpell.SpellId, botLevel, true) >= 0)) {
|
||||
break;
|
||||
}
|
||||
castedSpell = AIDoSpellCast(botSpell.SpellIndex, addMob, botSpell.ManaCost);
|
||||
|
||||
if (IsValidSpellRange(botSpell.SpellId, addMob)) {
|
||||
castedSpell = AIDoSpellCast(botSpell.SpellIndex, addMob, botSpell.ManaCost);
|
||||
}
|
||||
if (castedSpell) {
|
||||
BotGroupSay(
|
||||
this,
|
||||
@ -260,7 +262,9 @@ bool Bot::AICastSpell(Mob* tar, uint8 iChance, uint32 iSpellTypes) {
|
||||
|
||||
uint32 TempDontHealMeBeforeTime = tar->DontHealMeBefore();
|
||||
|
||||
castedSpell = AIDoSpellCast(botSpell.SpellIndex, tar, botSpell.ManaCost, &TempDontHealMeBeforeTime);
|
||||
if (IsValidSpellRange(botSpell.SpellId, tar) || botClass == BARD) {
|
||||
castedSpell = AIDoSpellCast(botSpell.SpellIndex, tar, botSpell.ManaCost, &TempDontHealMeBeforeTime);
|
||||
}
|
||||
|
||||
if (castedSpell) {
|
||||
/*if (TempDontHealMeBeforeTime != tar->DontHealMeBefore())
|
||||
@ -340,7 +344,9 @@ bool Bot::AICastSpell(Mob* tar, uint8 iChance, uint32 iSpellTypes) {
|
||||
}
|
||||
uint32 TempDontRootMeBefore = tar->DontRootMeBefore();
|
||||
|
||||
castedSpell = AIDoSpellCast(botSpell.SpellIndex, tar, botSpell.ManaCost, &TempDontRootMeBefore);
|
||||
if (IsValidSpellRange(botSpell.SpellId, tar)) {
|
||||
castedSpell = AIDoSpellCast(botSpell.SpellIndex, tar, botSpell.ManaCost, &TempDontRootMeBefore);
|
||||
}
|
||||
|
||||
if (TempDontRootMeBefore != tar->DontRootMeBefore()) {
|
||||
tar->SetDontRootMeBefore(TempDontRootMeBefore);
|
||||
@ -488,7 +494,10 @@ bool Bot::AICastSpell(Mob* tar, uint8 iChance, uint32 iSpellTypes) {
|
||||
if (IsInvulnerabilitySpell(botSpell.SpellId)) {
|
||||
tar = this; //target self for invul type spells
|
||||
}
|
||||
castedSpell = AIDoSpellCast(botSpell.SpellIndex, tar, botSpell.ManaCost);
|
||||
|
||||
if (IsValidSpellRange(botSpell.SpellId, tar) || botClass == BARD) {
|
||||
castedSpell = AIDoSpellCast(botSpell.SpellIndex, tar, botSpell.ManaCost);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -573,7 +582,9 @@ bool Bot::AICastSpell(Mob* tar, uint8 iChance, uint32 iSpellTypes) {
|
||||
}
|
||||
}
|
||||
|
||||
castedSpell = AIDoSpellCast(botSpell.SpellIndex, tar, botSpell.ManaCost);
|
||||
if (IsValidSpellRange(botSpell.SpellId, tar)) {
|
||||
castedSpell = AIDoSpellCast(botSpell.SpellIndex, tar, botSpell.ManaCost);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -594,7 +605,9 @@ bool Bot::AICastSpell(Mob* tar, uint8 iChance, uint32 iSpellTypes) {
|
||||
// TODO: Check target to see if there is anything to dispel
|
||||
|
||||
if (tar->CountDispellableBuffs() > 0) {
|
||||
castedSpell = AIDoSpellCast(botSpell.SpellIndex, tar, botSpell.ManaCost);
|
||||
if (IsValidSpellRange(botSpell.SpellId, tar)) {
|
||||
castedSpell = AIDoSpellCast(botSpell.SpellIndex, tar, botSpell.ManaCost);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -768,7 +781,6 @@ bool Bot::AICastSpell(Mob* tar, uint8 iChance, uint32 iSpellTypes) {
|
||||
if (CheckSpellRecastTimers(this, itr->SpellIndex)) {
|
||||
uint32 TempDontBuffMeBefore = tar->DontBuffMeBefore();
|
||||
castedSpell = AIDoSpellCast(selectedBotSpell.SpellIndex, tar, selectedBotSpell.ManaCost, &TempDontBuffMeBefore);
|
||||
|
||||
if (TempDontBuffMeBefore != tar->DontBuffMeBefore())
|
||||
tar->SetDontBuffMeBefore(TempDontBuffMeBefore);
|
||||
}
|
||||
@ -797,7 +809,9 @@ bool Bot::AICastSpell(Mob* tar, uint8 iChance, uint32 iSpellTypes) {
|
||||
if (!(!tar->IsImmuneToSpell(botSpell.SpellId, this) && (tar->CanBuffStack(botSpell.SpellId, botLevel, true) >= 0)))
|
||||
break;
|
||||
|
||||
castedSpell = AIDoSpellCast(botSpell.SpellIndex, tar, botSpell.ManaCost);
|
||||
if (IsValidSpellRange(botSpell.SpellId, tar)) {
|
||||
castedSpell = AIDoSpellCast(botSpell.SpellIndex, tar, botSpell.ManaCost);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -820,7 +834,9 @@ bool Bot::AICastSpell(Mob* tar, uint8 iChance, uint32 iSpellTypes) {
|
||||
|
||||
uint32 TempDontSnareMeBefore = tar->DontSnareMeBefore();
|
||||
|
||||
if (IsValidSpellRange(botSpell.SpellId, tar)) {
|
||||
castedSpell = AIDoSpellCast(botSpell.SpellIndex, tar, botSpell.ManaCost, &TempDontSnareMeBefore);
|
||||
}
|
||||
|
||||
if (TempDontSnareMeBefore != tar->DontSnareMeBefore())
|
||||
tar->SetDontSnareMeBefore(TempDontSnareMeBefore);
|
||||
@ -856,7 +872,7 @@ bool Bot::AICastSpell(Mob* tar, uint8 iChance, uint32 iSpellTypes) {
|
||||
|
||||
uint32 TempDontDotMeBefore = tar->DontDotMeBefore();
|
||||
|
||||
castedSpell = AIDoSpellCast(selectedBotSpell.SpellIndex, tar, selectedBotSpell.ManaCost, &TempDontDotMeBefore);
|
||||
castedSpell = AIDoSpellCast(selectedBotSpell.SpellIndex, tar, selectedBotSpell.ManaCost, &TempDontDotMeBefore);
|
||||
|
||||
if (TempDontDotMeBefore != tar->DontDotMeBefore())
|
||||
tar->SetDontDotMeBefore(TempDontDotMeBefore);
|
||||
@ -888,7 +904,9 @@ bool Bot::AICastSpell(Mob* tar, uint8 iChance, uint32 iSpellTypes) {
|
||||
|
||||
uint32 TempDontDotMeBefore = tar->DontDotMeBefore();
|
||||
|
||||
castedSpell = AIDoSpellCast(selectedBotSpell.SpellIndex, tar, selectedBotSpell.ManaCost, &TempDontDotMeBefore);
|
||||
if (IsValidSpellRange(botSpell.SpellId, tar)) {
|
||||
castedSpell = AIDoSpellCast(selectedBotSpell.SpellIndex, tar, selectedBotSpell.ManaCost, &TempDontDotMeBefore);
|
||||
}
|
||||
|
||||
if (TempDontDotMeBefore != tar->DontDotMeBefore())
|
||||
tar->SetDontDotMeBefore(TempDontDotMeBefore);
|
||||
@ -929,7 +947,9 @@ bool Bot::AICastSpell(Mob* tar, uint8 iChance, uint32 iSpellTypes) {
|
||||
if (tar->CanBuffStack(iter.SpellId, botLevel, true) < 0)
|
||||
continue;
|
||||
|
||||
castedSpell = AIDoSpellCast(iter.SpellIndex, tar, iter.ManaCost);
|
||||
if (IsValidSpellRange(botSpell.SpellId, tar)) {
|
||||
castedSpell = AIDoSpellCast(iter.SpellIndex, tar, iter.ManaCost);
|
||||
}
|
||||
if (castedSpell)
|
||||
break;
|
||||
}
|
||||
@ -956,7 +976,9 @@ bool Bot::AICastSpell(Mob* tar, uint8 iChance, uint32 iSpellTypes) {
|
||||
if (!(!tar->IsImmuneToSpell(botSpell.SpellId, this) && tar->CanBuffStack(botSpell.SpellId, botLevel, true) >= 0))
|
||||
break;
|
||||
|
||||
castedSpell = AIDoSpellCast(botSpell.SpellIndex, tar, botSpell.ManaCost);
|
||||
if (IsValidSpellRange(botSpell.SpellId, tar)) {
|
||||
castedSpell = AIDoSpellCast(botSpell.SpellIndex, tar, botSpell.ManaCost);
|
||||
}
|
||||
|
||||
if (castedSpell && GetClass() != BARD) {
|
||||
BotGroupSay(
|
||||
@ -992,7 +1014,9 @@ bool Bot::AICastSpell(Mob* tar, uint8 iChance, uint32 iSpellTypes) {
|
||||
if (!(!tar->IsImmuneToSpell(botSpell.SpellId, this) && (tar->CanBuffStack(botSpell.SpellId, botLevel, true) >= 0)))
|
||||
break;
|
||||
|
||||
castedSpell = AIDoSpellCast(botSpell.SpellIndex, tar, botSpell.ManaCost);
|
||||
if (IsValidSpellRange(botSpell.SpellId, tar)) {
|
||||
castedSpell = AIDoSpellCast(botSpell.SpellIndex, tar, botSpell.ManaCost);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -1006,7 +1030,7 @@ bool Bot::AICastSpell(Mob* tar, uint8 iChance, uint32 iSpellTypes) {
|
||||
|
||||
uint32 TempDontCureMeBeforeTime = tar->DontCureMeBefore();
|
||||
|
||||
castedSpell = AIDoSpellCast(botSpell.SpellIndex, tar, botSpell.ManaCost, &TempDontCureMeBeforeTime);
|
||||
castedSpell = AIDoSpellCast(botSpell.SpellIndex, tar, botSpell.ManaCost, &TempDontCureMeBeforeTime);
|
||||
|
||||
if (castedSpell) {
|
||||
if (botClass != BARD) {
|
||||
@ -1054,7 +1078,9 @@ bool Bot::AICastSpell(Mob* tar, uint8 iChance, uint32 iSpellTypes) {
|
||||
if (tar->CanBuffStack(iter.SpellId, botLevel, true) < 0)
|
||||
continue;
|
||||
|
||||
castedSpell = AIDoSpellCast(iter.SpellIndex, tar, iter.ManaCost);
|
||||
if (IsValidSpellRange(botSpell.SpellId, tar)) {
|
||||
castedSpell = AIDoSpellCast(iter.SpellIndex, tar, iter.ManaCost);
|
||||
}
|
||||
if (castedSpell) {
|
||||
BotGroupSay(
|
||||
this,
|
||||
@ -1096,7 +1122,7 @@ bool Bot::AICastSpell(Mob* tar, uint8 iChance, uint32 iSpellTypes) {
|
||||
if (tar->CanBuffStack(iter.SpellId, botLevel, true) < 0)
|
||||
continue;
|
||||
|
||||
castedSpell = AIDoSpellCast(iter.SpellIndex, tar, iter.ManaCost);
|
||||
castedSpell = AIDoSpellCast(iter.SpellIndex, tar, iter.ManaCost);
|
||||
if (castedSpell)
|
||||
break;
|
||||
}
|
||||
@ -1128,7 +1154,7 @@ bool Bot::AICastSpell(Mob* tar, uint8 iChance, uint32 iSpellTypes) {
|
||||
if (tar->CanBuffStack(iter.SpellId, botLevel, true) < 0)
|
||||
continue;
|
||||
|
||||
castedSpell = AIDoSpellCast(iter.SpellIndex, tar, iter.ManaCost);
|
||||
castedSpell = AIDoSpellCast(iter.SpellIndex, tar, iter.ManaCost);
|
||||
if (castedSpell)
|
||||
break;
|
||||
}
|
||||
@ -1764,8 +1790,9 @@ bool Bot::AIHealRotation(Mob* tar, bool useFastHeals) {
|
||||
return false;
|
||||
|
||||
uint32 TempDontHealMeBeforeTime = tar->DontHealMeBefore();
|
||||
|
||||
castedSpell = AIDoSpellCast(botSpell.SpellIndex, tar, botSpell.ManaCost, &TempDontHealMeBeforeTime);
|
||||
if (IsValidSpellRange(botSpell.SpellId, tar)) {
|
||||
castedSpell = AIDoSpellCast(botSpell.SpellIndex, tar, botSpell.ManaCost, &TempDontHealMeBeforeTime);
|
||||
}
|
||||
|
||||
if (castedSpell) {
|
||||
BotGroupSay(
|
||||
@ -3456,3 +3483,17 @@ bool Bot::HasBotSpellEntry(uint16 spellid) {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Bot::IsValidSpellRange(uint16 spell_id, Mob const* tar) {
|
||||
if (!IsValidSpell(spell_id)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (tar) {
|
||||
int spellrange = (GetActSpellRange(spell_id, spells[spell_id].range) * GetActSpellRange(spell_id, spells[spell_id].range));
|
||||
if (spellrange >= DistanceSquared(m_Position, tar->GetPosition())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user