Implement ^spellannouncecasts to toggle announcing casts of spell types

This commit is contained in:
nytmyr
2025-01-31 14:31:48 -06:00
parent bf8a576003
commit bd97453852
12 changed files with 461 additions and 116 deletions
@@ -274,6 +274,7 @@ UPDATE `bot_command_settings` SET `aliases`= 'resistlimits' WHERE `bot_command`=
UPDATE `bot_command_settings` SET `aliases`= 'targetcount' WHERE `bot_command`='spelltargetcount';
UPDATE `bot_command_settings` SET `aliases`= 'disc' WHERE `bot_command`='discipline';
UPDATE `bot_command_settings` SET `aliases`= CASE WHEN LENGTH(`aliases`) > 0 THEN CONCAT(`aliases`, '|vc') ELSE 'vc' END WHERE `bot_command`='viewcombos' AND `aliases` NOT LIKE '%vc%';
UPDATE `bot_command_settings` SET `aliases`= 'announcecasts' WHERE `bot_command`='spellannouncecasts';
)"
},
ManifestEntry{
+59 -4
View File
@@ -7915,6 +7915,7 @@ void Bot::RaidGroupSay(Mob* speaker, const char* msg, ...) {
if (speaker->IsRaidGrouped()) {
Raid* r = speaker->CastToBot()->GetStoredRaid();
if (r) {
for (const auto& m : r->members) {
if (m.member && !m.is_bot) {
@@ -7932,6 +7933,7 @@ void Bot::RaidGroupSay(Mob* speaker, const char* msg, ...) {
}
else if (speaker->HasGroup()) {
Group* g = speaker->GetGroup();
if (g) {
for (auto& m : g->members) {
if (m && !m->IsBot()) {
@@ -7948,7 +7950,6 @@ void Bot::RaidGroupSay(Mob* speaker, const char* msg, ...) {
}
}
else {
//speaker->Say("%s", buf);
speaker->GetOwner()->FilteredMessageString(
speaker,
Chat::PetResponse,
@@ -10324,6 +10325,9 @@ void Bot::SetBotSetting(uint8 setting_type, uint16 bot_setting, int setting_valu
case BotSettingCategories::SpellTypeAEOrGroupTargetCount:
SetSpellTypeAEOrGroupTargetCount(bot_setting, setting_value);
break;
case BotSettingCategories::SpellTypeAnnounceCast:
SetSpellTypeAnnounceCast(bot_setting, setting_value);
break;
}
}
@@ -10515,6 +10519,7 @@ void Bot::LoadDefaultBotSettings() {
bot_stance
);
t.ae_or_group_target_count = GetDefaultSpellTypeAEOrGroupTargetCount(i, bot_stance);
t.announce_cast = GetDefaultSpellTypeAnnounceCast(i, bot_stance);
t.recast_timer.Start();
m_bot_spell_settings.push_back(t);
@@ -10522,7 +10527,8 @@ void Bot::LoadDefaultBotSettings() {
LogBotSettingsDetail("{} says, 'Setting defaults for {} ({}) [#{}] - [{} [#{}] stance]'", GetCleanName(), t.name, t.short_name, t.spell_type, Stance::GetName(bot_stance), bot_stance);
LogBotSettingsDetail("{} says, 'Hold = [{}] | Delay = [{}ms] | MinThreshold = [{}\%] | MaxThreshold = [{}\%]'", GetCleanName(), GetDefaultSpellHold(i, bot_stance), GetDefaultSpellDelay(i, bot_stance), GetDefaultSpellMinThreshold(i, bot_stance), GetDefaultSpellMaxThreshold(i, bot_stance));
LogBotSettingsDetail("{} says, 'AggroCheck = [{}] | MinManaPCT = [{}\%] | MaxManaPCT = [{}\%] | MinHPPCT = [{}\% | MaxHPPCT = [{}\%]'", GetCleanName(), GetDefaultSpellTypeAggroCheck(i, bot_stance), GetDefaultSpellTypeMinManaLimit(i, bot_stance), GetDefaultSpellTypeMaxManaLimit(i, bot_stance), GetDefaultSpellTypeMinHPLimit(i, bot_stance), GetDefaultSpellTypeMaxHPLimit(i, bot_stance));
LogBotSettingsDetail("{} says, 'IdlePriority = [{}] | EngagedPriority = [{}] | PursuePriority = [{}] | ae_or_group_target_count = [{}]'", GetCleanName(), GetDefaultSpellTypeIdlePriority(i, GetClass(), bot_stance), GetDefaultSpellTypeEngagedPriority(i, GetClass(), bot_stance), GetDefaultSpellTypePursuePriority(i, GetClass(), bot_stance), GetDefaultSpellTypeAEOrGroupTargetCount(i, bot_stance));
LogBotSettingsDetail("{} says, 'IdlePriority = [{}] | EngagedPriority = [{}] | PursuePriority = [{}]'", GetCleanName(), GetDefaultSpellTypeIdlePriority(i, GetClass(), bot_stance), GetDefaultSpellTypeEngagedPriority(i, GetClass(), bot_stance), GetDefaultSpellTypePursuePriority(i, GetClass(), bot_stance));
LogBotSettingsDetail("{} says, 'TargetCount = [{}] | AnnounceCast = [{}]'", GetCleanName(), GetDefaultSpellTypeAEOrGroupTargetCount(i, bot_stance), GetDefaultSpellTypeAnnounceCast(i, bot_stance));
}
}
@@ -10638,6 +10644,8 @@ int Bot::GetDefaultSetting(uint16 setting_category, uint16 setting_type, uint8 s
return GetDefaultSpellTypePriority(setting_type, BotPriorityCategories::Pursue, GetClass(), stance);
case BotSettingCategories::SpellTypeAEOrGroupTargetCount:
return GetDefaultSpellTypeAEOrGroupTargetCount(setting_type, stance);
case BotSettingCategories::SpellTypeAnnounceCast:
return GetDefaultSpellTypeAnnounceCast(setting_type, stance);
default:
break;
}
@@ -10675,6 +10683,8 @@ int Bot::GetSetting(uint16 setting_category, uint16 setting_type) {
return GetSpellTypePriority(setting_type, BotPriorityCategories::Pursue);
case BotSettingCategories::SpellTypeAEOrGroupTargetCount:
return GetSpellTypeAEOrGroupTargetCount(setting_type);
case BotSettingCategories::SpellTypeAnnounceCast:
return GetSpellTypeAnnounceCast(setting_type);
default:
break;
}
@@ -11123,6 +11133,29 @@ uint16 Bot::GetDefaultSpellTypeAEOrGroupTargetCount(uint16 spell_type, uint8 sta
return 1;
}
uint16 Bot::GetDefaultSpellTypeAnnounceCast(uint16 spell_type, uint8 stance) {
switch (GetClass()) {
case Class::Bard:
switch (spell_type) {
case BotSpellTypes::Mez:
case BotSpellTypes::AEMez:
case BotSpellTypes::Cure:
case BotSpellTypes::GroupCures:
case BotSpellTypes::PetCures:
case BotSpellTypes::Charm:
return 1;
default:
return 0;
}
return 1;
default:
return 1;
}
return 1;
}
bool Bot::GetUltimateSpellHold(uint16 spell_type, Mob* tar) {
if (!tar) {
return GetSpellHold(spell_type);
@@ -12112,6 +12145,17 @@ void Bot::CopySettings(Bot* to, uint8 setting_type, uint16 spell_type) {
}
}
break;
case BotSettingCategories::SpellTypeResistLimit:
if (spell_type != UINT16_MAX) {
to->SetSpellTypeResistLimit(spell_type, GetSpellTypeResistLimit(spell_type));
}
else {
for (uint16 i = BotSpellTypes::START; i <= BotSpellTypes::END; ++i) {
to->SetSpellTypeResistLimit(i, GetSpellTypeResistLimit(i));
}
}
break;
case BotSettingCategories::SpellTypeMinManaPct:
if (spell_type != UINT16_MAX) {
@@ -12200,6 +12244,17 @@ void Bot::CopySettings(Bot* to, uint8 setting_type, uint16 spell_type) {
}
}
break;
case BotSettingCategories::SpellTypeAnnounceCast:
if (spell_type != UINT16_MAX) {
to->SetSpellTypeAnnounceCast(spell_type, GetSpellTypeAnnounceCast(spell_type));
}
else {
for (uint16 i = BotSpellTypes::START; i <= BotSpellTypes::END; ++i) {
to->SetSpellTypeAnnounceCast(i, GetSpellTypeAnnounceCast(i));
}
}
break;
}
}
@@ -12723,11 +12778,11 @@ uint16 Bot::GetSpellTypeIDByShortName(std::string spell_type_string) {
}
bool Bot::IsValidBotSpellCategory(uint8 setting_type) {
return EQ::ValueWithin(setting_type, BotSettingCategories::START, BotSettingCategories::END_FULL);
return EQ::ValueWithin(setting_type, BotSettingCategories::START, BotSettingCategories::END);
}
std::string Bot::GetBotSpellCategoryName(uint8 setting_type) {
return Bot::IsValidBotBaseSetting(setting_type) ? botSpellCategory_names[setting_type] : "UNKNOWN CATEGORY";
return Bot::IsValidBotSpellCategory(setting_type) ? botSpellCategory_names[setting_type] : "UNKNOWN CATEGORY";
}
uint16 Bot::GetBotSpellCategoryIDByShortName(std::string setting_string) {
+7 -3
View File
@@ -109,7 +109,7 @@ namespace BotSettingCategories { // Update GetBotSpellCategoryName as needed
constexpr uint8 SpellTypeEngagedPriority = 12;
constexpr uint8 SpellTypePursuePriority = 13;
constexpr uint8 SpellTypeAEOrGroupTargetCount = 14;
constexpr uint8 SpellTypeRecastDelay = 15;
constexpr uint8 SpellTypeAnnounceCast = 15;
constexpr uint16 START = BotSettingCategories::BaseSetting;
constexpr uint16 START_NO_BASE = BotSettingCategories::SpellHold;
@@ -117,6 +117,7 @@ namespace BotSettingCategories { // Update GetBotSpellCategoryName as needed
constexpr uint16 END_CLIENT = BotSettingCategories::SpellMaxThreshold;
constexpr uint16 END = BotSettingCategories::SpellTypeAEOrGroupTargetCount;
constexpr uint16 END_FULL = BotSettingCategories::SpellTypeRecastDelay;
constexpr uint16 END = BotSettingCategories::SpellTypeAnnounceCast;
};
static std::map<uint8, std::string> botSpellCategory_names = {
@@ -135,7 +136,7 @@ static std::map<uint8, std::string> botSpellCategory_names = {
{ BotSettingCategories::SpellTypeEngagedPriority, "SpellEngagedPriority" },
{ BotSettingCategories::SpellTypePursuePriority, "SpellPursuePriority" },
{ BotSettingCategories::SpellTypeAEOrGroupTargetCount, "SpellTargetCounts" },
{ BotSettingCategories::SpellTypeRecastDelay, "SpellRecastDelay" }
{ BotSettingCategories::SpellTypeAnnounceCast, "SpellAnnounceCasts" }
};
namespace BotPriorityCategories { // Update GetBotSpellCategoryName as needed
@@ -582,6 +583,7 @@ public:
uint8 GetDefaultSpellTypeMaxManaLimit(uint16 spell_type, uint8 stance = Stance::Balanced);
uint8 GetDefaultSpellTypeMinHPLimit(uint16 spell_type, uint8 stance = Stance::Balanced);
uint8 GetDefaultSpellTypeMaxHPLimit(uint16 spell_type, uint8 stance = Stance::Balanced);
uint16 GetDefaultSpellTypeAnnounceCast(uint16 spell_type, uint8 stance = Stance::Balanced);
uint16 GetDefaultSpellTypeAEOrGroupTargetCount(uint16 spell_type, uint8 stance = Stance::Balanced);
static bool IsValidBotBaseSetting(uint16 setting_type);
@@ -627,6 +629,8 @@ public:
inline void SetSpellTypeMaxHPLimit(uint16 spell_type, uint8 value) { m_bot_spell_settings[spell_type].max_hp_pct = value; }
inline uint16 GetSpellTypeAEOrGroupTargetCount(uint16 spell_type) const { return m_bot_spell_settings[spell_type].ae_or_group_target_count; }
inline void SetSpellTypeAEOrGroupTargetCount(uint16 spell_type, uint16 value) { m_bot_spell_settings[spell_type].ae_or_group_target_count = value; }
inline uint16 GetSpellTypeAnnounceCast(uint16 spell_type) const { return m_bot_spell_settings[spell_type].announce_cast; }
inline void SetSpellTypeAnnounceCast(uint16 spell_type, uint16 value) { m_bot_spell_settings[spell_type].announce_cast = value; }
inline uint16 GetSpellDelay(uint16 spell_type) const { return m_bot_spell_settings[spell_type].delay; }
inline void SetSpellDelay(uint16 spell_type, uint16 delay_value) { m_bot_spell_settings[spell_type].delay = delay_value; }
inline uint8 GetSpellMinThreshold(uint16 spell_type) const { return m_bot_spell_settings[spell_type].min_threshold; }
@@ -671,7 +675,7 @@ public:
inline uint16 GetCastedSpellType() const { return _castedSpellType; }
void SetCastedSpellType(uint16 spell_type);
bool IsValidSpellTypeSubType(uint16 spell_type, uint16 sub_type, uint16 spell_id);
bool IsValidBotSpellCategory(uint8 setting_type);
static bool IsValidBotSpellCategory(uint8 setting_type);
static std::string GetBotSpellCategoryName(uint8 setting_type);
static uint16 GetBotSpellCategoryIDByShortName(std::string setting_string);
void AssignBotSpellsToTypes(std::vector<BotSpells>& AIBot_spells, std::unordered_map<uint16, std::vector<BotSpells_wIndex>>& AIBot_spells_by_type);
+2
View File
@@ -180,6 +180,7 @@ int bot_command_init(void)
bot_command_add("sitincombat", "Toggles whether or a not a bot will attempt to med or sit to heal in combat", AccountStatus::Player, bot_command_sit_in_combat) ||
bot_command_add("sitmanapercent", "Mana threshold for a bot to start sitting in combat if allowed", AccountStatus::Player, bot_command_sit_mana_percent) ||
bot_command_add("spellaggrochecks", "Toggles whether or not bots will cast a spell type if they think it will get them aggro", AccountStatus::Player, bot_command_spell_aggro_checks) ||
bot_command_add("spellannouncecasts", "Turn on or off cast announcements by spell type", AccountStatus::Player, bot_command_spell_announce_cast) ||
bot_command_add("spellengagedpriority", "Controls the order of casts by spell type when engaged in combat", AccountStatus::Player, bot_command_spell_engaged_priority) ||
bot_command_add("spelldelays", "Controls the delay between casts for a specific spell type", AccountStatus::Player, bot_command_spell_delays) ||
bot_command_add("spellholds", "Controls whether a bot holds the specified spell type or not", AccountStatus::Player, bot_command_spell_holds) ||
@@ -959,6 +960,7 @@ void SendSpellTypeWindow(Client* c, const Seperator* sep) {
#include "bot_commands/sit_mana_percent.cpp"
#include "bot_commands/spell.cpp"
#include "bot_commands/spell_aggro_checks.cpp"
#include "bot_commands/spell_announce_cast.cpp"
#include "bot_commands/spell_delays.cpp"
#include "bot_commands/spell_engaged_priority.cpp"
#include "bot_commands/spell_holds.cpp"
+1
View File
@@ -1084,6 +1084,7 @@ void bot_command_sit_hp_percent(Client* c, const Seperator* sep);
void bot_command_sit_in_combat(Client* c, const Seperator* sep);
void bot_command_sit_mana_percent(Client* c, const Seperator* sep);
void bot_command_spell_aggro_checks(Client* c, const Seperator* sep);
void bot_command_spell_announce_cast(Client* c, const Seperator* sep);
void bot_command_spell_delays(Client* c, const Seperator* sep);
void bot_command_spell_engaged_priority(Client* c, const Seperator* sep);
void bot_command_spell_holds(Client* c, const Seperator* sep);
+3 -1
View File
@@ -19,7 +19,8 @@ void bot_command_bot_settings(Client* c, const Seperator* sep)
"sithppercent",
"sitincombat",
"sitmanapercent",
"spellaggrocheck",
"spellaggrochecks",
"spellannouncecasts",
"spelldelays",
"spellengagedpriority",
"spellholds",
@@ -31,6 +32,7 @@ void bot_command_bot_settings(Client* c, const Seperator* sep)
"spellminmanapct",
"spellminthresholds",
"spellpursuepriority",
"spellresistlimits",
"spelltargetcount",
"spelllist",
"stance",
+13 -4
View File
@@ -52,7 +52,7 @@ void bot_command_copy_settings(Client* c, const Seperator* sep)
),
};
p.actionables = { "target, byname, ownergroup, ownerraid, targetgroup, namesgroup, healrotationtargets, mmr, byclass, byrace, spawned" };
p.options = { "all, misc, spellsettings, spelltypesettings, spellholds, spelldelays, spellminthresholds, spellmaxthresholds, spellminmanapct, spellmaxmanapct, spellminhppct, spellmaxhppct, spellidlepriority, spellengagedpriority, spellpursuepriority, spellaggrochecks, spelltargetcounts, spellresistlimits, blockedbuffs, blockedpetbuffs" };
p.options = { "all, misc, spellsettings, spelltypesettings, spellholds, spelldelays, spellminthresholds, spellmaxthresholds, spellminmanapct, spellmaxmanapct, spellminhppct, spellmaxhppct, spellidlepriority, spellengagedpriority, spellpursuepriority, spellaggrochecks, spelltargetcounts, spellresistlimits, spellannouncecasts, blockedbuffs, blockedpetbuffs" };
p.options_one =
{
"[spellsettings] will copy ^spellsettings options",
@@ -111,6 +111,7 @@ void bot_command_copy_settings(Client* c, const Seperator* sep)
"spellaggrochecks",
"spelltargetcounts",
"spellresistlimits",
"spellannouncecasts",
"blockedbuffs",
"blockedpetbuffs"
};
@@ -255,14 +256,16 @@ void bot_command_copy_settings(Client* c, const Seperator* sep)
from->CopySettings(to, BotSettingCategories::SpellMinThreshold, spell_type);
from->CopySettings(to, BotSettingCategories::SpellMaxThreshold, spell_type);
from->CopySettings(to, BotSettingCategories::SpellTypeAggroCheck, spell_type);
from->CopySettings(to, BotSettingCategories::SpellTypeResistLimit, spell_type);
from->CopySettings(to, BotSettingCategories::SpellTypeMinManaPct, spell_type);
from->CopySettings(to, BotSettingCategories::SpellTypeMaxManaPct, spell_type);
from->CopySettings(to, BotSettingCategories::SpellTypeMinHPPct, spell_type);
from->CopySettings(to, BotSettingCategories::SpellTypeMaxHPPct, spell_type);
from->CopySettings(to, BotSettingCategories::SpellTypeIdlePriority, spell_type);
from->CopySettings(to, BotSettingCategories::SpellTypeEngagedPriority, spell_type);
from->CopySettings(to, BotSettingCategories::SpellTypePursuePriority, spell_type);
from->CopySettings(to, BotSettingCategories::SpellTypePursuePriority, spell_type);
from->CopySettings(to, BotSettingCategories::SpellTypeAEOrGroupTargetCount, spell_type);
from->CopySettings(to, BotSettingCategories::SpellTypeAnnounceCast, spell_type);
}
else {
for (uint16 i = BotSpellTypes::START; i <= BotSpellTypes::END; ++i) {
@@ -271,14 +274,16 @@ void bot_command_copy_settings(Client* c, const Seperator* sep)
from->CopySettings(to, BotSettingCategories::SpellMinThreshold, i);
from->CopySettings(to, BotSettingCategories::SpellMaxThreshold, i);
from->CopySettings(to, BotSettingCategories::SpellTypeAggroCheck, i);
from->CopySettings(to, BotSettingCategories::SpellTypeResistLimit, i);
from->CopySettings(to, BotSettingCategories::SpellTypeMinManaPct, i);
from->CopySettings(to, BotSettingCategories::SpellTypeMaxManaPct, i);
from->CopySettings(to, BotSettingCategories::SpellTypeMinHPPct, i);
from->CopySettings(to, BotSettingCategories::SpellTypeMaxHPPct, i);
from->CopySettings(to, BotSettingCategories::SpellTypeIdlePriority, i);
from->CopySettings(to, BotSettingCategories::SpellTypeEngagedPriority, i);
from->CopySettings(to, BotSettingCategories::SpellTypePursuePriority, i);
from->CopySettings(to, BotSettingCategories::SpellTypePursuePriority, i);
from->CopySettings(to, BotSettingCategories::SpellTypeAEOrGroupTargetCount, i);
from->CopySettings(to, BotSettingCategories::SpellTypeAnnounceCast, i);
}
}
@@ -299,14 +304,16 @@ void bot_command_copy_settings(Client* c, const Seperator* sep)
from->CopySettings(to, BotSettingCategories::SpellMinThreshold, spell_type);
from->CopySettings(to, BotSettingCategories::SpellMaxThreshold, spell_type);
from->CopySettings(to, BotSettingCategories::SpellTypeAggroCheck, spell_type);
from->CopySettings(to, BotSettingCategories::SpellTypeResistLimit, spell_type);
from->CopySettings(to, BotSettingCategories::SpellTypeMinManaPct, spell_type);
from->CopySettings(to, BotSettingCategories::SpellTypeMaxManaPct, spell_type);
from->CopySettings(to, BotSettingCategories::SpellTypeMinHPPct, spell_type);
from->CopySettings(to, BotSettingCategories::SpellTypeMaxHPPct, spell_type);
from->CopySettings(to, BotSettingCategories::SpellTypeIdlePriority, spell_type);
from->CopySettings(to, BotSettingCategories::SpellTypeEngagedPriority, spell_type);
from->CopySettings(to, BotSettingCategories::SpellTypePursuePriority, spell_type);
from->CopySettings(to, BotSettingCategories::SpellTypePursuePriority, spell_type);
from->CopySettings(to, BotSettingCategories::SpellTypeAEOrGroupTargetCount, spell_type);
from->CopySettings(to, BotSettingCategories::SpellTypeAnnounceCast, spell_type);
}
else {
for (uint16 i = BotSpellTypes::START; i <= BotSpellTypes::END; ++i) {
@@ -315,6 +322,7 @@ void bot_command_copy_settings(Client* c, const Seperator* sep)
from->CopySettings(to, BotSettingCategories::SpellMinThreshold, i);
from->CopySettings(to, BotSettingCategories::SpellMaxThreshold, i);
from->CopySettings(to, BotSettingCategories::SpellTypeAggroCheck, i);
from->CopySettings(to, BotSettingCategories::SpellTypeResistLimit, i);
from->CopySettings(to, BotSettingCategories::SpellTypeMinManaPct, i);
from->CopySettings(to, BotSettingCategories::SpellTypeMaxManaPct, i);
from->CopySettings(to, BotSettingCategories::SpellTypeMinHPPct, i);
@@ -323,6 +331,7 @@ void bot_command_copy_settings(Client* c, const Seperator* sep)
from->CopySettings(to, BotSettingCategories::SpellTypeEngagedPriority, i);
from->CopySettings(to, BotSettingCategories::SpellTypePursuePriority, i);
from->CopySettings(to, BotSettingCategories::SpellTypeAEOrGroupTargetCount, i);
from->CopySettings(to, BotSettingCategories::SpellTypeAnnounceCast, i);
}
}
+33 -2
View File
@@ -38,7 +38,7 @@ void bot_command_default_settings(Client* c, const Seperator* sep)
)
};
p.actionables = { "target, byname, ownergroup, ownerraid, targetgroup, namesgroup, healrotationtargets, mmr, byclass, byrace, spawned" };
p.options = { "all, misc, spellsettings, spelltypesettings, spellholds, spelldelays, spellminthresholds, spellmaxthresholds, spellminmanapct, spellmaxmanapct, spellminhppct, spellmaxhppct, spellidlepriority, spellengagedpriority, spellpursuepriority, spellaggrocheck, spelltargetcounts, spellresistlimits" };
p.options = { "all, misc, spellsettings, spelltypesettings, spellholds, spelldelays, spellminthresholds, spellmaxthresholds, spellminmanapct, spellmaxmanapct, spellminhppct, spellmaxhppct, spellidlepriority, spellengagedpriority, spellpursuepriority, spellaggrocheck, spelltargetcounts, spellresistlimits, spellannouncecasts" };
p.options_one =
{
"[spellsettings] will restore ^spellsettings options",
@@ -100,7 +100,8 @@ void bot_command_default_settings(Client* c, const Seperator* sep)
"spellpursuepriority",
"spellaggrochecks",
"spelltargetcounts",
"spellresistlimits"
"spellresistlimits",
"spellannouncecasts"
};
if (sep->IsNumber(spell_type_arg_int)) {
@@ -223,6 +224,7 @@ void bot_command_default_settings(Client* c, const Seperator* sep)
my_bot->SetSpellMinThreshold(spell_type, my_bot->GetDefaultSpellMinThreshold(spell_type, bot_stance));
my_bot->SetSpellMaxThreshold(spell_type, my_bot->GetDefaultSpellMaxThreshold(spell_type, bot_stance));
my_bot->SetSpellTypeAggroCheck(spell_type, my_bot->GetDefaultSpellTypeAggroCheck(spell_type, bot_stance));
my_bot->SetSpellTypeResistLimit(spell_type, my_bot->GetDefaultSpellTypeResistLimit(spell_type, bot_stance));
my_bot->SetSpellTypeMinManaLimit(spell_type, my_bot->GetDefaultSpellTypeMinManaLimit(spell_type, bot_stance));
my_bot->SetSpellTypeMaxManaLimit(spell_type, my_bot->GetDefaultSpellTypeMaxManaLimit(spell_type, bot_stance));
my_bot->SetSpellTypeMinHPLimit(spell_type, my_bot->GetDefaultSpellTypeMinHPLimit(spell_type, bot_stance));
@@ -231,6 +233,7 @@ void bot_command_default_settings(Client* c, const Seperator* sep)
my_bot->SetSpellTypePriority(spell_type, BotPriorityCategories::Engaged, my_bot->GetDefaultSpellTypePriority(spell_type, BotPriorityCategories::Engaged, my_bot->GetClass(), bot_stance));
my_bot->SetSpellTypePriority(spell_type, BotPriorityCategories::Pursue, my_bot->GetDefaultSpellTypePriority(spell_type, BotPriorityCategories::Pursue, my_bot->GetClass(), bot_stance));
my_bot->SetSpellTypeAEOrGroupTargetCount(spell_type, my_bot->GetDefaultSpellTypeAEOrGroupTargetCount(spell_type, bot_stance));
my_bot->SetSpellTypeAnnounceCast(spell_type, my_bot->GetDefaultSpellTypeAnnounceCast(spell_type, bot_stance));
}
else {
for (uint16 i = BotSpellTypes::START; i <= BotSpellTypes::END; ++i) {
@@ -239,6 +242,7 @@ void bot_command_default_settings(Client* c, const Seperator* sep)
my_bot->SetSpellMinThreshold(i, my_bot->GetDefaultSpellMinThreshold(i, bot_stance));
my_bot->SetSpellMaxThreshold(i, my_bot->GetDefaultSpellMaxThreshold(i, bot_stance));
my_bot->SetSpellTypeAggroCheck(i, my_bot->GetDefaultSpellTypeAggroCheck(i, bot_stance));
my_bot->SetSpellTypeResistLimit(i, my_bot->GetDefaultSpellTypeResistLimit(i, bot_stance));
my_bot->SetSpellTypeMinManaLimit(i, my_bot->GetDefaultSpellTypeMinManaLimit(i, bot_stance));
my_bot->SetSpellTypeMaxManaLimit(i, my_bot->GetDefaultSpellTypeMaxManaLimit(i, bot_stance));
my_bot->SetSpellTypeMinHPLimit(i, my_bot->GetDefaultSpellTypeMinHPLimit(i, bot_stance));
@@ -247,6 +251,7 @@ void bot_command_default_settings(Client* c, const Seperator* sep)
my_bot->SetSpellTypePriority(i, BotPriorityCategories::Engaged, my_bot->GetDefaultSpellTypePriority(i, BotPriorityCategories::Engaged, my_bot->GetClass(), bot_stance));
my_bot->SetSpellTypePriority(i, BotPriorityCategories::Pursue, my_bot->GetDefaultSpellTypePriority(i, BotPriorityCategories::Pursue, my_bot->GetClass(), bot_stance));
my_bot->SetSpellTypeAEOrGroupTargetCount(i, my_bot->GetDefaultSpellTypeAEOrGroupTargetCount(i, bot_stance));
my_bot->SetSpellTypeAnnounceCast(i, my_bot->GetDefaultSpellTypeAnnounceCast(i, bot_stance));
}
}
@@ -263,6 +268,7 @@ void bot_command_default_settings(Client* c, const Seperator* sep)
my_bot->SetSpellMinThreshold(i, my_bot->GetDefaultSpellMinThreshold(i, bot_stance));
my_bot->SetSpellMaxThreshold(i, my_bot->GetDefaultSpellMaxThreshold(i, bot_stance));
my_bot->SetSpellTypeAggroCheck(i, my_bot->GetDefaultSpellTypeAggroCheck(i, bot_stance));
my_bot->SetSpellTypeResistLimit(i, my_bot->GetDefaultSpellTypeResistLimit(i, bot_stance));
my_bot->SetSpellTypeMinManaLimit(i, my_bot->GetDefaultSpellTypeMinManaLimit(i, bot_stance));
my_bot->SetSpellTypeMaxManaLimit(i, my_bot->GetDefaultSpellTypeMaxManaLimit(i, bot_stance));
my_bot->SetSpellTypeMinHPLimit(i, my_bot->GetDefaultSpellTypeMinHPLimit(i, bot_stance));
@@ -271,6 +277,7 @@ void bot_command_default_settings(Client* c, const Seperator* sep)
my_bot->SetSpellTypePriority(i, BotPriorityCategories::Engaged, my_bot->GetDefaultSpellTypePriority(i, BotPriorityCategories::Engaged, my_bot->GetClass(), bot_stance));
my_bot->SetSpellTypePriority(i, BotPriorityCategories::Pursue, my_bot->GetDefaultSpellTypePriority(i, BotPriorityCategories::Pursue, my_bot->GetClass(), bot_stance));
my_bot->SetSpellTypeAEOrGroupTargetCount(i, my_bot->GetDefaultSpellTypeAEOrGroupTargetCount(i, bot_stance));
my_bot->SetSpellTypeAnnounceCast(i, my_bot->GetDefaultSpellTypeAnnounceCast(i, bot_stance));
};
my_bot->ResetBotSpellSettings();
@@ -339,6 +346,18 @@ void bot_command_default_settings(Client* c, const Seperator* sep)
output = "aggro check settings";
}
else if (!strcasecmp(sep->arg[1], "resist limit")) {
if (spell_type != UINT16_MAX) {
my_bot->SetSpellTypeAEOrGroupTargetCount(spell_type, my_bot->GetDefaultSpellTypeAEOrGroupTargetCount(spell_type, bot_stance));
}
else {
for (uint16 i = BotSpellTypes::START; i <= BotSpellTypes::END; ++i) {
my_bot->SetSpellTypeAEOrGroupTargetCount(i, my_bot->GetDefaultSpellTypeAEOrGroupTargetCount(i, bot_stance));
}
}
output = "resist limit settings";
}
else if (!strcasecmp(sep->arg[1], "minmanapct")) {
if (spell_type != UINT16_MAX) {
my_bot->SetSpellTypeMinManaLimit(spell_type, my_bot->GetDefaultSpellTypeMinManaLimit(spell_type, bot_stance));
@@ -435,6 +454,18 @@ void bot_command_default_settings(Client* c, const Seperator* sep)
output = "target count settings";
}
else if (!strcasecmp(sep->arg[1], "announcecast")) {
if (spell_type != UINT16_MAX) {
my_bot->SetSpellTypeAEOrGroupTargetCount(spell_type, my_bot->GetDefaultSpellTypeAEOrGroupTargetCount(spell_type, bot_stance));
}
else {
for (uint16 i = BotSpellTypes::START; i <= BotSpellTypes::END; ++i) {
my_bot->SetSpellTypeAEOrGroupTargetCount(i, my_bot->GetDefaultSpellTypeAEOrGroupTargetCount(i, bot_stance));
}
}
output = "announce cast settings";
}
my_bot->Save();
++success_count;
+9 -11
View File
@@ -233,17 +233,15 @@ void bot_command_depart(Client* c, const Seperator* sep)
bot_iter->SetCastedSpellType(BotSpellTypes::Teleport);
}
if (bot_iter->GetClass() != Class::Bard || RuleB(Bots, BardsAnnounceCasts)) {
Bot::RaidGroupSay(
bot_iter,
fmt::format(
"Casting {} [{}] on {}.",
GetSpellName(itr->SpellId),
bot_iter->GetSpellTypeNameByID(BotSpellTypes::Teleport),
(tar == bot_iter ? "myself" : tar->GetCleanName())
).c_str()
);
}
Bot::RaidGroupSay(
bot_iter,
fmt::format(
"Casting {} [{}] on {}.",
GetSpellName(itr->SpellId),
bot_iter->GetSpellTypeNameByID(BotSpellTypes::Teleport),
(tar == bot_iter ? "myself" : tar->GetCleanName())
).c_str()
);
is_success = true;
}
+214
View File
@@ -0,0 +1,214 @@
#include "../bot_command.h"
void bot_command_spell_announce_cast(Client* c, const Seperator* sep) {
if (helper_command_alias_fail(c, "bot_command_spell_announce_cast", sep->arg[0], "spellannouncecasts")) {
c->Message(Chat::White, "note: Allows you to enable or disable cast announcements for bots by spell type.");
return;
}
if (helper_is_help_or_usage(sep->arg[1])) {
BotCommandHelpParams p;
p.description = { "Allows you to enable or disable cast announcements for bots by spell type." };
p.example_format =
{
fmt::format("{} [Type Shortname] [value] [actionable]", sep->arg[0]),
fmt::format("{} [Type ID] [value] [actionable]", sep->arg[0])
};
p.examples_one =
{
"To set all bots to stop announcing dispels:",
fmt::format(
"{} {} 0 spawned",
sep->arg[0],
Bot::GetSpellTypeShortNameByID(BotSpellTypes::Dispel)
),
fmt::format(
"{} {} 0 spawned",
sep->arg[0],
BotSpellTypes::Dispel
)
};
p.examples_two =
{
"To set Wizards to not announce nukes:",
fmt::format(
"{} {} 0 byclass {}",
sep->arg[0],
Bot::GetSpellTypeShortNameByID(BotSpellTypes::Nuke),
Class::Wizard
),
fmt::format(
"{} {} 0 byclass {}",
sep->arg[0],
BotSpellTypes::Nuke,
Class::Wizard
)
};
p.examples_three =
{
"To check the current announcement setting for debuffs:",
fmt::format(
"{} {} current spawned",
sep->arg[0],
Bot::GetSpellTypeShortNameByID(BotSpellTypes::Debuff)
),
fmt::format(
"{} {} current spawned",
sep->arg[0],
BotSpellTypes::Debuff
)
};
p.actionables = { "target, byname, ownergroup, ownerraid, targetgroup, namesgroup, healrotationtargets, mmr, byclass, byrace, spawned" };
std::string popup_text = c->SendBotCommandHelpWindow(p);
popup_text = DialogueWindow::Table(popup_text);
c->SendPopupToClient(sep->arg[0], popup_text.c_str());
c->SendSpellTypePrompts();
if (RuleB(Bots, SendClassRaceOnHelp)) {
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];
std::string arg2 = sep->arg[2];
int ab_arg = 2;
bool current_check = false;
uint16 spell_type = 0;
uint32 type_value = 0;
// String/Int type checks
if (sep->IsNumber(1)) {
spell_type = atoi(sep->arg[1]);
if (!EQ::ValueWithin(spell_type, BotSpellTypes::START, 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 (Bot::GetSpellTypeIDByShortName(arg1) != UINT16_MAX) {
spell_type = Bot::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)) {
type_value = atoi(sep->arg[2]);
++ab_arg;
if (type_value != 0 && type_value != 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::vector<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.erase(std::remove(sbl.begin(), sbl.end(), nullptr), sbl.end());
Bot* first_found = nullptr;
int success_count = 0;
for (auto my_bot : sbl) {
if (my_bot->BotPassiveCheck()) {
continue;
}
if (!first_found) {
first_found = my_bot;
}
if (current_check) {
c->Message(
Chat::Green,
fmt::format(
"{} says, 'I currently {} announce [{}] casts.'",
my_bot->GetCleanName(),
(my_bot->GetSpellTypeAnnounceCast(spell_type) ? "do" : "do not"),
Bot::GetSpellTypeNameByID(spell_type)
).c_str()
);
}
else {
my_bot->SetSpellTypeAnnounceCast(spell_type, type_value);
++success_count;
}
}
if (!current_check) {
if (success_count == 1 && first_found) {
c->Message(
Chat::Green,
fmt::format(
"{} says, 'I will {} announce [{}] casts.'",
first_found->GetCleanName(),
(first_found->GetSpellTypeAnnounceCast(spell_type) ? "now" : "no longer"),
Bot::GetSpellTypeNameByID(spell_type)
).c_str()
);
}
else {
c->Message(
Chat::Green,
fmt::format(
"{} of your bots will {} announce [{}] casts.",
success_count,
(type_value ? "now" : "no longer"),
Bot::GetSpellTypeNameByID(spell_type)
).c_str()
);
}
}
}
+1
View File
@@ -129,6 +129,7 @@ struct BotSpellSettings {
uint16 engaged_priority; // engaged priority of the spell type
uint16 pursue_priority; // pursue priority of the spell type
uint16 ae_or_group_target_count; // require target count to cast an AE or Group spell type
uint16 announce_cast; // announce when casting a certain spell type
Timer recast_timer; // recast timer based off delay
};
+118 -91
View File
@@ -257,18 +257,20 @@ bool Bot::AICastSpell(Mob* tar, uint8 chance, uint16 spell_type, uint16 sub_targ
SetCastedSpellType(spell_type);
}
if (bot_class != Class::Bard || RuleB(Bots, BardsAnnounceCasts)) {
RaidGroupSay(
this,
fmt::format(
"Casting {} [{}] on {}.",
GetSpellName(s.SpellId),
GetSpellTypeNameByID(spell_type),
(tar == this ? "myself" : tar->GetCleanName())
).c_str()
);
if (!GetSpellTypeAnnounceCast(spell_type)) {
return true;
}
RaidGroupSay(
this,
fmt::format(
"Casting {} [{}] on {}.",
GetSpellName(s.SpellId),
GetSpellTypeNameByID(spell_type),
(tar == this ? "myself" : tar->GetCleanName())
).c_str()
);
return true;
}
}
@@ -306,6 +308,10 @@ bool Bot::BotCastMez(Mob* tar, uint8 bot_class, BotSpell& bot_spell, uint16 spel
SetCastedSpellType(spell_type);
}
if (!GetSpellTypeAnnounceCast(spell_type)) {
return true;
}
RaidGroupSay(
this,
fmt::format(
@@ -340,41 +346,47 @@ bool Bot::BotCastCure(Mob* tar, uint8 bot_class, BotSpell& bot_spell, uint16 spe
}
if (AIDoSpellCast(bot_spell.SpellIndex, tar, bot_spell.ManaCost)) {
if (bot_class != Class::Bard || RuleB(Bots, BardsAnnounceCasts)) {
if (IsGroupSpell(bot_spell.SpellId)) {
RaidGroupSay(
this,
fmt::format(
"Curing the group with {}.",
GetSpellName(bot_spell.SpellId)
).c_str()
);
if (IsGroupSpell(bot_spell.SpellId)) {
if (!IsCommandedSpell()) {
const std::vector<Mob*> v = GatherSpellTargets(false, tar);
if (!IsCommandedSpell()) {
for (Mob* m : v) {
SetBotSpellRecastTimer(spell_type, m, true);
}
for (Mob* m : v) {
SetBotSpellRecastTimer(spell_type, m, true);
}
}
else {
RaidGroupSay(
this,
fmt::format(
"Curing {} with {}.",
(tar == this ? "myself" : tar->GetCleanName()),
GetSpellName(bot_spell.SpellId)
).c_str()
);
if (!IsCommandedSpell()) {
SetBotSpellRecastTimer(spell_type, tar, true);
}
if (!GetSpellTypeAnnounceCast(spell_type)) {
return true;
}
RaidGroupSay(
this,
fmt::format(
"Curing the group with {}.",
GetSpellName(bot_spell.SpellId)
).c_str()
);
}
else {
if (!IsCommandedSpell()) {
SetBotSpellRecastTimer(spell_type, tar, true);
}
if (!GetSpellTypeAnnounceCast(spell_type)) {
return true;
}
RaidGroupSay(
this,
fmt::format(
"Curing {} with {}.",
(tar == this ? "myself" : tar->GetCleanName()),
GetSpellName(bot_spell.SpellId)
).c_str()
);
}
return true;
}
return false;
@@ -417,6 +429,11 @@ bool Bot::BotCastPet(Mob* tar, uint8 bot_class, BotSpell& bot_spell, uint16 spel
if (AIDoSpellCast(bot_spell.SpellIndex, tar, bot_spell.ManaCost)) {
SetCastedSpellType(spell_type);
if (!GetSpellTypeAnnounceCast(spell_type)) {
return true;
}
RaidGroupSay(
this,
fmt::format(
@@ -473,18 +490,20 @@ bool Bot::BotCastNuke(Mob* tar, uint8 bot_class, BotSpell& bot_spell, uint16 spe
if (AIDoSpellCast(s.SpellIndex, tar, s.ManaCost)) {
SetCastedSpellType(spell_type);
if (bot_class != Class::Bard || RuleB(Bots, BardsAnnounceCasts)) {
RaidGroupSay(
this,
fmt::format(
"Casting {} [{}] on {}.",
GetSpellName(s.SpellId),
GetSpellTypeNameByID(spell_type),
tar->GetCleanName()
).c_str()
);
if (!GetSpellTypeAnnounceCast(spell_type)) {
return true;
}
RaidGroupSay(
this,
fmt::format(
"Casting {} [{}] on {}.",
GetSpellName(s.SpellId),
GetSpellTypeNameByID(spell_type),
tar->GetCleanName()
).c_str()
);
return true;
}
}
@@ -493,18 +512,20 @@ bool Bot::BotCastNuke(Mob* tar, uint8 bot_class, BotSpell& bot_spell, uint16 spe
if (AIDoSpellCast(bot_spell.SpellIndex, tar, bot_spell.ManaCost)) {
SetCastedSpellType(spell_type);
if (bot_class != Class::Bard || RuleB(Bots, BardsAnnounceCasts)) {
RaidGroupSay(
this,
fmt::format(
"Casting {} [{}] on {}.",
GetSpellName(bot_spell.SpellId),
GetSpellTypeNameByID(spell_type),
tar->GetCleanName()
).c_str()
);
if (!GetSpellTypeAnnounceCast(spell_type)) {
return true;
}
RaidGroupSay(
this,
fmt::format(
"Casting {} [{}] on {}.",
GetSpellName(bot_spell.SpellId),
GetSpellTypeNameByID(spell_type),
tar->GetCleanName()
).c_str()
);
return true;
}
}
@@ -520,45 +541,51 @@ bool Bot::BotCastHeal(Mob* tar, uint8 bot_class, BotSpell& bot_spell, uint16 spe
}
if (AIDoSpellCast(bot_spell.SpellIndex, tar, bot_spell.ManaCost)) {
if (bot_class != Class::Bard || RuleB(Bots, BardsAnnounceCasts)) {
if (IsGroupSpell(bot_spell.SpellId)) {
RaidGroupSay(
this,
fmt::format(
"Healing the group with {} [{}].",
GetSpellName(bot_spell.SpellId),
GetSpellTypeNameByID(spell_type)
).c_str()
);
if (bot_class != Class::Bard) {
if (IsGroupSpell(bot_spell.SpellId)) {
if (bot_class != Class::Bard) {
if (!IsCommandedSpell()) {
const std::vector<Mob*> v = GatherSpellTargets(false, tar);
if (!IsCommandedSpell()) {
for (Mob* m : v) {
SetBotSpellRecastTimer(spell_type, m, true);
}
}
}
}
else {
RaidGroupSay(
this,
fmt::format(
"Healing {} with {} [{}].",
(tar == this ? "myself" : tar->GetCleanName()),
GetSpellName(bot_spell.SpellId),
GetSpellTypeNameByID(spell_type)
).c_str()
);
if (bot_class != Class::Bard) {
if (!IsCommandedSpell()) {
SetBotSpellRecastTimer(spell_type, tar, true);
for (Mob* m : v) {
SetBotSpellRecastTimer(spell_type, m, true);
}
}
}
if (!GetSpellTypeAnnounceCast(spell_type)) {
return true;
}
RaidGroupSay(
this,
fmt::format(
"Healing the group with {} [{}].",
GetSpellName(bot_spell.SpellId),
GetSpellTypeNameByID(spell_type)
).c_str()
);
}
else {
if (bot_class != Class::Bard) {
if (!IsCommandedSpell()) {
SetBotSpellRecastTimer(spell_type, tar, true);
}
}
if (!GetSpellTypeAnnounceCast(spell_type)) {
return true;
}
RaidGroupSay(
this,
fmt::format(
"Healing {} with {} [{}].",
(tar == this ? "myself" : tar->GetCleanName()),
GetSpellName(bot_spell.SpellId),
GetSpellTypeNameByID(spell_type)
).c_str()
);
}
return true;