diff --git a/common/database/database_update_manifest_bots.cpp b/common/database/database_update_manifest_bots.cpp index 44083475b..639d173b0 100644 --- a/common/database/database_update_manifest_bots.cpp +++ b/common/database/database_update_manifest_bots.cpp @@ -174,6 +174,7 @@ CREATE TABLE `bot_settings` ( `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, `char_id` INT UNSIGNED NOT NULL, `bot_id` INT UNSIGNED NOT NULL, + `stance` INT UNSIGNED NOT NULL, `setting_id` INT UNSIGNED NOT NULL, `setting_type` INT UNSIGNED NOT NULL, `value` INT UNSIGNED NOT NULL, @@ -183,16 +184,16 @@ CREATE TABLE `bot_settings` ( ) COLLATE='utf8mb4_general_ci'; -INSERT INTO bot_settings SELECT NULL, 0, bd.`bot_id`, 0, 0, bd.`expansion_bitmask`, 'BaseSetting', 'ExpansionBitmask' FROM bot_data bd +INSERT INTO bot_settings SELECT NULL, 0, bd.`bot_id`, (SELECT bs.`stance_id` FROM bot_stances bs WHERE bs.`bot_id` = bd.`bot_id`) AS stance_id, 0, 0, bd.`expansion_bitmask`, 'BaseSetting', 'ExpansionBitmask' FROM bot_data bd JOIN rule_values rv WHERE rv.rule_name LIKE 'Bots:BotExpansionSettings' AND bd.expansion_bitmask != rv.rule_value; -INSERT INTO bot_settings SELECT NULL, 0, `bot_id`, 1, 0, `show_helm`, 'BaseSetting', 'ShowHelm' FROM bot_data WHERE `show_helm` != 1; -INSERT INTO bot_settings SELECT NULL, 0, `bot_id`, 2, 0, sqrt(`follow_distance`), 'BaseSetting', 'FollowDistance' FROM bot_data WHERE `follow_distance` != 184; +INSERT INTO bot_settings SELECT NULL, 0, `bot_id`, (SELECT bs.`stance_id` FROM bot_stances bs WHERE bs.`bot_id` = bd.`bot_id`) AS stance_id, 1, 0, `show_helm`, 'BaseSetting', 'ShowHelm' FROM bot_data WHERE `show_helm` != 1; +INSERT INTO bot_settings SELECT NULL, 0, `bot_id`, (SELECT bs.`stance_id` FROM bot_stances bs WHERE bs.`bot_id` = bd.`bot_id`) AS stance_id, 2, 0, sqrt(`follow_distance`), 'BaseSetting', 'FollowDistance' FROM bot_data WHERE `follow_distance` != 184; INSERT INTO bot_settings -SELECT NULL, 0, `bot_id`, 3, 0, `stop_melee_level`, 'BaseSetting', 'StopMeleeLevel' +SELECT NULL, 0, `bot_id`, (SELECT bs.`stance_id` FROM bot_stances bs WHERE bs.`bot_id` = bd.`bot_id`) AS stance_id, 3, 0, `stop_melee_level`, 'BaseSetting', 'StopMeleeLevel' FROM ( SELECT `bot_id`, (CASE @@ -204,11 +205,11 @@ FROM ( ) AS `subquery` WHERE `sml` != `stop_melee_level`; -INSERT INTO bot_settings SELECT NULL, 0, `bot_id`, 4, 0, `enforce_spell_settings`, 'BaseSetting', 'EnforceSpellSettings' FROM bot_data WHERE `enforce_spell_settings` != 0; -INSERT INTO bot_settings SELECT NULL, 0, `bot_id`, 5, 0, `archery_setting`, 'BaseSetting', 'RangedSetting' FROM bot_data WHERE `archery_setting` != 0; +INSERT INTO bot_settings SELECT NULL, 0, `bot_id`, (SELECT bs.`stance_id` FROM bot_stances bs WHERE bs.`bot_id` = bd.`bot_id`) AS stance_id, 4, 0, `enforce_spell_settings`, 'BaseSetting', 'EnforceSpellSettings' FROM bot_data WHERE `enforce_spell_settings` != 0; +INSERT INTO bot_settings SELECT NULL, 0, `bot_id`, (SELECT bs.`stance_id` FROM bot_stances bs WHERE bs.`bot_id` = bd.`bot_id`) AS stance_id, 5, 0, `archery_setting`, 'BaseSetting', 'RangedSetting' FROM bot_data WHERE `archery_setting` != 0; INSERT INTO bot_settings -SELECT NULL, 0, `bot_id`, 8, 0, `caster_range`, 'BaseSetting', 'CasterRange' +SELECT NULL, 0, `bot_id`, (SELECT bs.`stance_id` FROM bot_stances bs WHERE bs.`bot_id` = bd.`bot_id`) AS stance_id, 8, 0, `caster_range`, 'BaseSetting', 'CasterRange' FROM ( SELECT `bot_id`, (CASE diff --git a/common/repositories/base/base_bot_settings_repository.h b/common/repositories/base/base_bot_settings_repository.h index 2018177dc..92d4aba15 100644 --- a/common/repositories/base/base_bot_settings_repository.h +++ b/common/repositories/base/base_bot_settings_repository.h @@ -22,6 +22,7 @@ public: uint32_t id; uint32_t char_id; uint32_t bot_id; + uint8_t stance; uint16_t setting_id; uint8_t setting_type; int32_t value; @@ -40,6 +41,7 @@ public: "id", "char_id", "bot_id", + "stance", "setting_id", "setting_type", "value", @@ -54,6 +56,7 @@ public: "id", "char_id", "bot_id", + "stance", "setting_id", "setting_type", "value", @@ -102,6 +105,7 @@ public: e.id = 0; e.char_id = 0; e.bot_id = 0; + e.stance = 0; e.setting_id = 0; e.setting_type = 0; e.value = 0; @@ -146,11 +150,12 @@ public: e.id = row[0] ? static_cast(strtoul(row[0], nullptr, 10)) : 0; e.char_id = row[1] ? static_cast(strtoul(row[1], nullptr, 10)) : 0; e.bot_id = row[2] ? static_cast(strtoul(row[2], nullptr, 10)) : 0; - e.setting_id = row[3] ? static_cast(strtoul(row[3], nullptr, 10)) : 0; - e.setting_type = row[4] ? static_cast(strtoul(row[4], nullptr, 10)) : 0; - e.value = row[5] ? static_cast(strtoul(row[5], nullptr, 10)) : 0; - e.category_name = row[6] ? row[6] : ""; - e.setting_name = row[7] ? row[7] : ""; + e.stance = row[3] ? static_cast(strtoul(row[3], nullptr, 10)) : 0; + e.setting_id = row[4] ? static_cast(strtoul(row[4], nullptr, 10)) : 0; + e.setting_type = row[5] ? static_cast(strtoul(row[5], nullptr, 10)) : 0; + e.value = row[6] ? static_cast(strtoul(row[6], nullptr, 10)) : 0; + e.category_name = row[7] ? row[7] : ""; + e.setting_name = row[8] ? row[8] : ""; return e; } @@ -187,11 +192,12 @@ public: v.push_back(columns[0] + " = " + std::to_string(e.id)); v.push_back(columns[1] + " = " + std::to_string(e.char_id)); v.push_back(columns[2] + " = " + std::to_string(e.bot_id)); - v.push_back(columns[3] + " = " + std::to_string(e.setting_id)); - v.push_back(columns[4] + " = " + std::to_string(e.setting_type)); - v.push_back(columns[5] + " = " + std::to_string(e.value)); - v.push_back(columns[6] + " = '" + Strings::Escape(e.category_name) + "'"); - v.push_back(columns[7] + " = '" + Strings::Escape(e.setting_name) + "'"); + v.push_back(columns[3] + " = " + std::to_string(e.stance)); + v.push_back(columns[4] + " = " + std::to_string(e.setting_id)); + v.push_back(columns[5] + " = " + std::to_string(e.setting_type)); + v.push_back(columns[6] + " = " + std::to_string(e.value)); + v.push_back(columns[7] + " = '" + Strings::Escape(e.category_name) + "'"); + v.push_back(columns[8] + " = '" + Strings::Escape(e.setting_name) + "'"); auto results = db.QueryDatabase( fmt::format( @@ -216,6 +222,7 @@ public: v.push_back(std::to_string(e.id)); v.push_back(std::to_string(e.char_id)); v.push_back(std::to_string(e.bot_id)); + v.push_back(std::to_string(e.stance)); v.push_back(std::to_string(e.setting_id)); v.push_back(std::to_string(e.setting_type)); v.push_back(std::to_string(e.value)); @@ -253,6 +260,7 @@ public: v.push_back(std::to_string(e.id)); v.push_back(std::to_string(e.char_id)); v.push_back(std::to_string(e.bot_id)); + v.push_back(std::to_string(e.stance)); v.push_back(std::to_string(e.setting_id)); v.push_back(std::to_string(e.setting_type)); v.push_back(std::to_string(e.value)); @@ -294,11 +302,12 @@ public: e.id = row[0] ? static_cast(strtoul(row[0], nullptr, 10)) : 0; e.char_id = row[1] ? static_cast(strtoul(row[1], nullptr, 10)) : 0; e.bot_id = row[2] ? static_cast(strtoul(row[2], nullptr, 10)) : 0; - e.setting_id = row[3] ? static_cast(strtoul(row[3], nullptr, 10)) : 0; - e.setting_type = row[4] ? static_cast(strtoul(row[4], nullptr, 10)) : 0; - e.value = row[5] ? static_cast(strtoul(row[5], nullptr, 10)) : 0; - e.category_name = row[6] ? row[6] : ""; - e.setting_name = row[7] ? row[7] : ""; + e.stance = row[3] ? static_cast(strtoul(row[3], nullptr, 10)) : 0; + e.setting_id = row[4] ? static_cast(strtoul(row[4], nullptr, 10)) : 0; + e.setting_type = row[5] ? static_cast(strtoul(row[5], nullptr, 10)) : 0; + e.value = row[6] ? static_cast(strtoul(row[6], nullptr, 10)) : 0; + e.category_name = row[7] ? row[7] : ""; + e.setting_name = row[8] ? row[8] : ""; all_entries.push_back(e); } @@ -326,11 +335,12 @@ public: e.id = row[0] ? static_cast(strtoul(row[0], nullptr, 10)) : 0; e.char_id = row[1] ? static_cast(strtoul(row[1], nullptr, 10)) : 0; e.bot_id = row[2] ? static_cast(strtoul(row[2], nullptr, 10)) : 0; - e.setting_id = row[3] ? static_cast(strtoul(row[3], nullptr, 10)) : 0; - e.setting_type = row[4] ? static_cast(strtoul(row[4], nullptr, 10)) : 0; - e.value = row[5] ? static_cast(strtoul(row[5], nullptr, 10)) : 0; - e.category_name = row[6] ? row[6] : ""; - e.setting_name = row[7] ? row[7] : ""; + e.stance = row[3] ? static_cast(strtoul(row[3], nullptr, 10)) : 0; + e.setting_id = row[4] ? static_cast(strtoul(row[4], nullptr, 10)) : 0; + e.setting_type = row[5] ? static_cast(strtoul(row[5], nullptr, 10)) : 0; + e.value = row[6] ? static_cast(strtoul(row[6], nullptr, 10)) : 0; + e.category_name = row[7] ? row[7] : ""; + e.setting_name = row[8] ? row[8] : ""; all_entries.push_back(e); } @@ -408,6 +418,7 @@ public: v.push_back(std::to_string(e.id)); v.push_back(std::to_string(e.char_id)); v.push_back(std::to_string(e.bot_id)); + v.push_back(std::to_string(e.stance)); v.push_back(std::to_string(e.setting_id)); v.push_back(std::to_string(e.setting_type)); v.push_back(std::to_string(e.value)); @@ -438,6 +449,7 @@ public: v.push_back(std::to_string(e.id)); v.push_back(std::to_string(e.char_id)); v.push_back(std::to_string(e.bot_id)); + v.push_back(std::to_string(e.stance)); v.push_back(std::to_string(e.setting_id)); v.push_back(std::to_string(e.setting_type)); v.push_back(std::to_string(e.value)); diff --git a/zone/bot.cpp b/zone/bot.cpp index 956692b03..6bf9e5e25 100644 --- a/zone/bot.cpp +++ b/zone/bot.cpp @@ -9985,14 +9985,14 @@ int Bot::GetBotBaseSetting(uint16 botSetting) { return true; } -int Bot::GetDefaultBotBaseSetting(uint16 botSetting) { +int Bot::GetDefaultBotBaseSetting(uint16 botSetting, uint8 stance) { switch (botSetting) { case BotBaseSettings::ExpansionBitmask: return RuleI(Bots, BotExpansionSettings); case BotBaseSettings::ShowHelm: return true; case BotBaseSettings::FollowDistance: - return (RuleI(Bots, DefaultFollowDistance) * RuleI(Bots, DefaultFollowDistance)); + return RuleI(Bots, DefaultFollowDistance); case BotBaseSettings::StopMeleeLevel: if (IsCasterClass(GetClass())) { return RuleI(Bots, CasterStopMeleeLevel); @@ -10003,7 +10003,7 @@ int Bot::GetDefaultBotBaseSetting(uint16 botSetting) { case BotBaseSettings::PetSetTypeSetting: return 0; case BotBaseSettings::BehindMob: - if (GetClass() == Class::Rogue) { + if (GetClass() == Class::Rogue || (IsPureMeleeClass() && GetClass() != Class::Warrior)) { return true; } else { @@ -10043,10 +10043,14 @@ int Bot::GetDefaultBotBaseSetting(uint16 botSetting) { void Bot::LoadDefaultBotSettings() { + _spellSettings.clear(); + + uint8 botStance = GetBotStance(); + for (uint16 i = BotBaseSettings::START; i <= BotBaseSettings::END; ++i) { - SetBotBaseSetting(i, GetDefaultSetting(BotSettingCategories::BaseSetting, i)); - LogBotSettingsDetail("{} says, 'Setting default {} [{}] to [{}]'", GetCleanName(), GetBotSettingCategoryName(i), i, GetDefaultBotBaseSetting(i)); //deleteme - } + SetBotBaseSetting(i, GetDefaultSetting(BotSettingCategories::BaseSetting, i, botStance)); + LogBotSettingsDetail("{} says, 'Setting default {} [{}] to [{}]'", GetCleanName(), GetBotSettingCategoryName(i), i, GetDefaultBotBaseSetting(i, botStance)); //deleteme + } for (uint16 i = BotSpellTypes::START; i <= BotSpellTypes::END; ++i) { BotSpellSettings_Struct t; @@ -10054,28 +10058,28 @@ void Bot::LoadDefaultBotSettings() { t.spellType = i; t.shortName = GetSpellTypeShortNameByID(i); t.name = GetSpellTypeNameByID(i); - t.hold = GetDefaultSpellHold(i); - t.delay = GetDefaultSpellDelay(i); - t.minThreshold = GetDefaultSpellMinThreshold(i); - t.maxThreshold = GetDefaultSpellMaxThreshold(i); - t.resistLimit = GetDefaultSpellTypeResistLimit(i); - t.aggroCheck = GetDefaultSpellTypeAggroCheck(i); - t.minManaPct = GetDefaultSpellTypeMinManaLimit(i); - t.maxManaPct = GetDefaultSpellTypeMaxManaLimit(i); - t.minHPPct = GetDefaultSpellTypeMinHPLimit(i); - t.maxHPPct = GetDefaultSpellTypeMaxHPLimit(i); - t.idlePriority = GetDefaultSpellTypePriority(i, BotPriorityCategories::Idle, GetClass()); - t.engagedPriority = GetDefaultSpellTypePriority(i, BotPriorityCategories::Engaged, GetClass()); - t.pursuePriority = GetDefaultSpellTypePriority(i, BotPriorityCategories::Pursue, GetClass()); - t.AEOrGroupTargetCount = GetDefaultSpellTypeAEOrGroupTargetCount(i); + t.hold = GetDefaultSpellHold(i, botStance); + t.delay = GetDefaultSpellDelay(i, botStance); + t.minThreshold = GetDefaultSpellMinThreshold(i, botStance); + t.maxThreshold = GetDefaultSpellMaxThreshold(i, botStance); + t.resistLimit = GetDefaultSpellTypeResistLimit(i, botStance); + t.aggroCheck = GetDefaultSpellTypeAggroCheck(i, botStance); + t.minManaPct = GetDefaultSpellTypeMinManaLimit(i, botStance); + t.maxManaPct = GetDefaultSpellTypeMaxManaLimit(i, botStance); + t.minHPPct = GetDefaultSpellTypeMinHPLimit(i, botStance); + t.maxHPPct = GetDefaultSpellTypeMaxHPLimit(i, botStance); + t.idlePriority = GetDefaultSpellTypePriority(i, BotPriorityCategories::Idle, GetClass(), botStance); + t.engagedPriority = GetDefaultSpellTypePriority(i, BotPriorityCategories::Engaged, GetClass(), botStance); + t.pursuePriority = GetDefaultSpellTypePriority(i, BotPriorityCategories::Pursue, GetClass(), botStance); + t.AEOrGroupTargetCount = GetDefaultSpellTypeAEOrGroupTargetCount(i, botStance); t.recastTimer.Start(); _spellSettings.push_back(t); - LogBotSettingsDetail("{} says, 'Setting defaults for {} ({}) [#{}]'", GetCleanName(), t.name, t.shortName, t.spellType); //deleteme - LogBotSettingsDetail("{} says, 'Hold = [{}] | Delay = [{}ms] | MinThreshold = [{}\%] | MaxThreshold = [{}\%]'", GetCleanName(), GetDefaultSpellHold(i), GetDefaultSpellDelay(i), GetDefaultSpellMinThreshold(i), GetDefaultSpellMaxThreshold(i)); //deleteme - LogBotSettingsDetail("{} says, 'AggroCheck = [{}] | MinManaPCT = [{}\%] | MaxManaPCT = [{}\%] | MinHPPCT = [{}\% | MaxHPPCT = [{}\%]'", GetCleanName(), GetDefaultSpellTypeAggroCheck(i), GetDefaultSpellTypeMinManaLimit(i), GetDefaultSpellTypeMaxManaLimit(i), GetDefaultSpellTypeMinHPLimit(i), GetDefaultSpellTypeMaxHPLimit(i)); //deleteme - LogBotSettingsDetail("{} says, 'IdlePriority = [{}] | EngagedPriority = [{}] | PursuePriority = [{}] | AEOrGroupTargetCount = [{}] | recastTimer = [{}]'", GetCleanName(), GetDefaultSpellTypeIdlePriority(i, GetClass()), GetDefaultSpellTypeEngagedPriority(i, GetClass()), GetDefaultSpellTypePursuePriority(i, GetClass()), GetDefaultSpellTypeAEOrGroupTargetCount(i), t.recastTimer.GetRemainingTime()); //deleteme + LogBotSettingsDetail("{} says, 'Setting defaults for {} ({}) [#{}] - [{} [#{}] stance]'", GetCleanName(), t.name, t.shortName, t.spellType, Stance::GetName(botStance), botStance); //deleteme + LogBotSettingsDetail("{} says, 'Hold = [{}] | Delay = [{}ms] | MinThreshold = [{}\%] | MaxThreshold = [{}\%]'", GetCleanName(), GetDefaultSpellHold(i, botStance), GetDefaultSpellDelay(i, botStance), GetDefaultSpellMinThreshold(i, botStance), GetDefaultSpellMaxThreshold(i, botStance)); //deleteme + LogBotSettingsDetail("{} says, 'AggroCheck = [{}] | MinManaPCT = [{}\%] | MaxManaPCT = [{}\%] | MinHPPCT = [{}\% | MaxHPPCT = [{}\%]'", GetCleanName(), GetDefaultSpellTypeAggroCheck(i, botStance), GetDefaultSpellTypeMinManaLimit(i, botStance), GetDefaultSpellTypeMaxManaLimit(i, botStance), GetDefaultSpellTypeMinHPLimit(i, botStance), GetDefaultSpellTypeMaxHPLimit(i, botStance)); //deleteme + LogBotSettingsDetail("{} says, 'IdlePriority = [{}] | EngagedPriority = [{}] | PursuePriority = [{}] | AEOrGroupTargetCount = [{}]'", GetCleanName(), GetDefaultSpellTypeIdlePriority(i, GetClass(), botStance), GetDefaultSpellTypeEngagedPriority(i, GetClass(), botStance), GetDefaultSpellTypePursuePriority(i, GetClass(), botStance), GetDefaultSpellTypeAEOrGroupTargetCount(i, botStance)); //deleteme } } @@ -10149,36 +10153,36 @@ uint16 Bot::GetSpellTypePriority(uint16 spellType, uint8 priorityType) { } } -int Bot::GetDefaultSetting(uint16 settingCategory, uint16 settingType) { +int Bot::GetDefaultSetting(uint16 settingCategory, uint16 settingType, uint8 stance) { switch (settingCategory) { case BotSettingCategories::BaseSetting: - return GetDefaultBotBaseSetting(settingType); + return GetDefaultBotBaseSetting(settingType, stance); case BotSettingCategories::SpellHold: - return GetDefaultSpellHold(settingType); + return GetDefaultSpellHold(settingType, stance); case BotSettingCategories::SpellDelay: - return GetDefaultSpellDelay(settingType); + return GetDefaultSpellDelay(settingType, stance); case BotSettingCategories::SpellMinThreshold: - return GetDefaultSpellMinThreshold(settingType); + return GetDefaultSpellMinThreshold(settingType, stance); case BotSettingCategories::SpellMaxThreshold: - return GetDefaultSpellMinThreshold(settingType); + return GetDefaultSpellMaxThreshold(settingType, stance); case BotSettingCategories::SpellTypeAggroCheck: - return GetDefaultSpellTypeAggroCheck(settingType); + return GetDefaultSpellTypeAggroCheck(settingType, stance); case BotSettingCategories::SpellTypeMinManaPct: - return GetDefaultSpellTypeMinManaLimit(settingType); + return GetDefaultSpellTypeMinManaLimit(settingType, stance); case BotSettingCategories::SpellTypeMaxManaPct: - return GetDefaultSpellTypeMaxManaLimit(settingType); + return GetDefaultSpellTypeMaxManaLimit(settingType, stance); case BotSettingCategories::SpellTypeMinHPPct: - return GetDefaultSpellTypeMinHPLimit(settingType); + return GetDefaultSpellTypeMinHPLimit(settingType, stance); case BotSettingCategories::SpellTypeMaxHPPct: - return GetDefaultSpellTypeMaxHPLimit(settingType); + return GetDefaultSpellTypeMaxHPLimit(settingType, stance); case BotSettingCategories::SpellTypeIdlePriority: - return GetDefaultSpellTypePriority(settingType, BotPriorityCategories::Idle, GetClass()); + return GetDefaultSpellTypePriority(settingType, BotPriorityCategories::Idle, GetClass(), stance); case BotSettingCategories::SpellTypeEngagedPriority: - return GetDefaultSpellTypePriority(settingType, BotPriorityCategories::Engaged, GetClass()); + return GetDefaultSpellTypePriority(settingType, BotPriorityCategories::Engaged, GetClass(), stance); case BotSettingCategories::SpellTypePursuePriority: - return GetDefaultSpellTypePriority(settingType, BotPriorityCategories::Pursue, GetClass()); + return GetDefaultSpellTypePriority(settingType, BotPriorityCategories::Pursue, GetClass(), stance); case BotSettingCategories::SpellTypeAEOrGroupTargetCount: - return GetDefaultSpellTypeAEOrGroupTargetCount(settingType); + return GetDefaultSpellTypeAEOrGroupTargetCount(settingType, stance); default: break; } @@ -10195,7 +10199,7 @@ int Bot::GetSetting(uint16 settingCategory, uint16 settingType) { case BotSettingCategories::SpellMinThreshold: return GetSpellMinThreshold(settingType); case BotSettingCategories::SpellMaxThreshold: - return GetSpellMinThreshold(settingType); + return GetSpellMaxThreshold(settingType); case BotSettingCategories::SpellTypeAggroCheck: return GetSpellTypeAggroCheck(settingType); case BotSettingCategories::SpellTypeMinManaPct: @@ -10219,20 +10223,20 @@ int Bot::GetSetting(uint16 settingCategory, uint16 settingType) { } } -uint16 Bot::GetDefaultSpellTypePriority(uint16 spellType, uint8 priorityType, uint8 botClass) { +uint16 Bot::GetDefaultSpellTypePriority(uint16 spellType, uint8 priorityType, uint8 botClass, uint8 stance) { switch (priorityType) { case BotPriorityCategories::Idle: - return GetDefaultSpellTypeIdlePriority(spellType, botClass); + return GetDefaultSpellTypeIdlePriority(spellType, botClass, stance); case BotPriorityCategories::Engaged: - return GetDefaultSpellTypeEngagedPriority(spellType, botClass); + return GetDefaultSpellTypeEngagedPriority(spellType, botClass, stance); case BotPriorityCategories::Pursue: - return GetDefaultSpellTypePursuePriority(spellType, botClass); + return GetDefaultSpellTypePursuePriority(spellType, botClass, stance); default: return 0; } } -uint16 Bot::GetDefaultSpellTypeIdlePriority(uint16 spellType, uint8 botClass) { +uint16 Bot::GetDefaultSpellTypeIdlePriority(uint16 spellType, uint8 botClass, uint8 stance) { if (!BOT_SPELL_TYPES_BENEFICIAL(spellType, botClass)) { return 0; } @@ -10341,7 +10345,7 @@ uint16 Bot::GetDefaultSpellTypeIdlePriority(uint16 spellType, uint8 botClass) { return priority; } -uint16 Bot::GetDefaultSpellTypeEngagedPriority(uint16 spellType, uint8 botClass) { +uint16 Bot::GetDefaultSpellTypeEngagedPriority(uint16 spellType, uint8 botClass, uint8 stance) { switch (spellType) { case BotSpellTypes::Escape: return 1; @@ -10429,14 +10433,12 @@ uint16 Bot::GetDefaultSpellTypeEngagedPriority(uint16 spellType, uint8 botClass) return 42; case BotSpellTypes::InCombatBuffSong: return 43; - case BotSpellTypes::Pet: - return 44; default: return 0; } } -uint16 Bot::GetDefaultSpellTypePursuePriority(uint16 spellType, uint8 botClass) { +uint16 Bot::GetDefaultSpellTypePursuePriority(uint16 spellType, uint8 botClass, uint8 stance) { switch (spellType) { case BotSpellTypes::Escape: return 1; @@ -10487,7 +10489,7 @@ uint16 Bot::GetDefaultSpellTypePursuePriority(uint16 spellType, uint8 botClass) } } -uint16 Bot::GetDefaultSpellTypeResistLimit(uint16 spellType) { +uint16 Bot::GetDefaultSpellTypeResistLimit(uint16 spellType, uint8 stance) { if (!BOT_SPELL_TYPES_BENEFICIAL(spellType, GetClass())) { return RuleI(Bots, SpellResistLimit); @@ -10497,35 +10499,46 @@ uint16 Bot::GetDefaultSpellTypeResistLimit(uint16 spellType) { } } -bool Bot::GetDefaultSpellTypeAggroCheck(uint16 spellType) { +bool Bot::GetDefaultSpellTypeAggroCheck(uint16 spellType, uint8 stance) { + switch (stance) { + case Stance::AEBurn: + case Stance::Burn: + return false; + default: + break; + } + switch (spellType) { + case BotSpellTypes::Nuke: + case BotSpellTypes::Root: + case BotSpellTypes::Snare: + case BotSpellTypes::DOT: + case BotSpellTypes::Slow: + case BotSpellTypes::Debuff: + case BotSpellTypes::Fear: + case BotSpellTypes::Stun: case BotSpellTypes::AENukes: case BotSpellTypes::AERains: - case BotSpellTypes::PBAENuke: - case BotSpellTypes::Nuke: - case BotSpellTypes::AESlow: - case BotSpellTypes::Slow: - case BotSpellTypes::AESnare: - case BotSpellTypes::Snare: - case BotSpellTypes::AEDispel: - case BotSpellTypes::Dispel: - case BotSpellTypes::AEDebuff: - case BotSpellTypes::Debuff: - case BotSpellTypes::AEDoT: - case BotSpellTypes::DOT: case BotSpellTypes::AEStun: - case BotSpellTypes::Stun: + case BotSpellTypes::AEDebuff: + case BotSpellTypes::AESlow: + case BotSpellTypes::AESnare: + case BotSpellTypes::AEFear: + case BotSpellTypes::AEDispel: + case BotSpellTypes::AERoot: + case BotSpellTypes::AEDoT: + case BotSpellTypes::PBAENuke: return true; default: return false; } } -uint8 Bot::GetDefaultSpellTypeMinManaLimit(uint16 spellType) { +uint8 Bot::GetDefaultSpellTypeMinManaLimit(uint16 spellType, uint8 stance) { return 0; } -uint8 Bot::GetDefaultSpellTypeMaxManaLimit(uint16 spellType) { +uint8 Bot::GetDefaultSpellTypeMaxManaLimit(uint16 spellType, uint8 stance) { switch (spellType) { case BotSpellTypes::InCombatBuff: if (GetClass() == Class::Shaman) { @@ -10540,7 +10553,7 @@ uint8 Bot::GetDefaultSpellTypeMaxManaLimit(uint16 spellType) { return 100; } -uint8 Bot::GetDefaultSpellTypeMinHPLimit(uint16 spellType) { +uint8 Bot::GetDefaultSpellTypeMinHPLimit(uint16 spellType, uint8 stance) { switch (spellType) { case BotSpellTypes::InCombatBuff: if (GetClass() == Class::Shaman) { @@ -10555,11 +10568,11 @@ uint8 Bot::GetDefaultSpellTypeMinHPLimit(uint16 spellType) { return 0; } -uint8 Bot::GetDefaultSpellTypeMaxHPLimit(uint16 spellType) { +uint8 Bot::GetDefaultSpellTypeMaxHPLimit(uint16 spellType, uint8 stance) { return 100; } -uint16 Bot::GetDefaultSpellTypeAEOrGroupTargetCount(uint16 spellType) { +uint16 Bot::GetDefaultSpellTypeAEOrGroupTargetCount(uint16 spellType, uint8 stance) { if (IsAEBotSpellType(spellType)) { return RuleI(Bots, MinTargetsForAESpell); } diff --git a/zone/bot.h b/zone/bot.h index 4e40f3939..553148ee5 100644 --- a/zone/bot.h +++ b/zone/bot.h @@ -458,7 +458,7 @@ public: void CopyBotSpellSettings(Bot* to); void ResetBotSpellSettings(); int GetBotBaseSetting(uint16 botSetting); - int GetDefaultBotBaseSetting(uint16 botSetting); + int GetDefaultBotBaseSetting(uint16 botSetting, uint8 stance = Stance::Balanced); void SetBotBaseSetting(uint16 botSetting, int settingValue); void LoadDefaultBotSettings(); void SetBotSpellRecastTimer(uint16 spellType, Mob* spelltar, bool preCast = false); @@ -467,18 +467,18 @@ public: std::string GetBotSpellCategoryName(uint8 setting_type); std::string GetBotSettingCategoryName(uint8 setting_type); - int GetDefaultSetting(uint16 settingCategory, uint16 settingType); - uint16 GetDefaultSpellTypePriority(uint16 spellType, uint8 priorityType, uint8 botClass); - uint16 GetDefaultSpellTypeIdlePriority(uint16 spellType, uint8 botClass); - uint16 GetDefaultSpellTypeEngagedPriority(uint16 spellType, uint8 botClass); - uint16 GetDefaultSpellTypePursuePriority(uint16 spellType, uint8 botClass); - uint16 GetDefaultSpellTypeResistLimit(uint16 spellType); - bool GetDefaultSpellTypeAggroCheck(uint16 spellType); - uint8 GetDefaultSpellTypeMinManaLimit(uint16 spellType); - uint8 GetDefaultSpellTypeMaxManaLimit(uint16 spellType); - uint8 GetDefaultSpellTypeMinHPLimit(uint16 spellType); - uint8 GetDefaultSpellTypeMaxHPLimit(uint16 spellType); - uint16 GetDefaultSpellTypeAEOrGroupTargetCount(uint16 spellType); + int GetDefaultSetting(uint16 settingCategory, uint16 settingType, uint8 stance = Stance::Balanced); + uint16 GetDefaultSpellTypePriority(uint16 spellType, uint8 priorityType, uint8 botClass, uint8 stance = Stance::Balanced); + uint16 GetDefaultSpellTypeIdlePriority(uint16 spellType, uint8 botClass, uint8 stance = Stance::Balanced); + uint16 GetDefaultSpellTypeEngagedPriority(uint16 spellType, uint8 botClass, uint8 stance = Stance::Balanced); + uint16 GetDefaultSpellTypePursuePriority(uint16 spellType, uint8 botClass, uint8 stance = Stance::Balanced); + uint16 GetDefaultSpellTypeResistLimit(uint16 spellType, uint8 stance = Stance::Balanced); + bool GetDefaultSpellTypeAggroCheck(uint16 spellType, uint8 stance = Stance::Balanced); + uint8 GetDefaultSpellTypeMinManaLimit(uint16 spellType, uint8 stance = Stance::Balanced); + uint8 GetDefaultSpellTypeMaxManaLimit(uint16 spellType, uint8 stance = Stance::Balanced); + uint8 GetDefaultSpellTypeMinHPLimit(uint16 spellType, uint8 stance = Stance::Balanced); + uint8 GetDefaultSpellTypeMaxHPLimit(uint16 spellType, uint8 stance = Stance::Balanced); + uint16 GetDefaultSpellTypeAEOrGroupTargetCount(uint16 spellType, uint8 stance = Stance::Balanced); int GetSetting(uint16 settingCategory, uint16 settingType); uint16 GetSpellTypePriority(uint16 spellType, uint8 priorityType); diff --git a/zone/bot_commands/bot.cpp b/zone/bot_commands/bot.cpp index e360d49ed..d867b4e67 100644 --- a/zone/bot_commands/bot.cpp +++ b/zone/bot_commands/bot.cpp @@ -1180,43 +1180,188 @@ void bot_command_stance(Client *c, const Seperator *sep) } if (helper_is_help_or_usage(sep->arg[1])) { - c->Message(Chat::White, "usage: %s [current | value: 1-9] ([actionable: target | byname | ownergroup | ownerraid | targetgroup | namesgroup | healrotationtargets | mmr | byclass | byrace | spawned] ([actionable_name]))", sep->arg[0]); - c->Message( - Chat::White, + std::vector description = + { + "Change a bot's stance to control the way it behaves." + }; + + std::vector notes = + { + "- Changing a stance will reset all settings to match that stance type.", + "- Any changes made will only save to that stance for future use.", fmt::format( - "Value: {} ({}), {} ({}), {} ({})", - Stance::Passive, + "- {} (#{}) will tell Non-Warrior classes to taunt automatically.", + Stance::GetName(Stance::Aggressive), + Stance::Aggressive + ), + "
", + "Available stances:", + fmt::format( + "{} (#{}), {} (#{}), {} (#{}), {} (#{}), {} (#{}), {} (#{}), {} (#{})", Stance::GetName(Stance::Passive), - Stance::Balanced, + Stance::Passive, Stance::GetName(Stance::Balanced), + Stance::Balanced, + Stance::GetName(Stance::Efficient), + Stance::Efficient, + Stance::GetName(Stance::Aggressive), Stance::Aggressive, - Stance::GetName(Stance::Aggressive) - ).c_str() + Stance::GetName(Stance::Assist), + Stance::Assist, + Stance::GetName(Stance::Burn), + Stance::Burn, + Stance::GetName(Stance::AEBurn), + Stance::AEBurn + ), + "
", + fmt::format( + "- {} (#{}) [Default] - Overall balance and casts most spell types by default.", + Stance::GetName(Stance::Balanced), + Stance::Balanced + ), + fmt::format( + "- {} (#{}) - Idle. Does not cast or engage in combat.", + Stance::GetName(Stance::Passive), + Stance::Passive + ), + fmt::format( + "- {} (#{}) - More mana and aggro efficient (SKs will still cast hate line). Longer delays between detrimental spells, thresholds adjusted to cast less often.", + Stance::GetName(Stance::Efficient), + Stance::Efficient + ), + fmt::format( + "- {} (#{}) - Much more aggressive in their cast times and thresholds. More DPS, debuffs and slow but a higher risk of snagging aggro.", + Stance::GetName(Stance::Aggressive), + Stance::Aggressive + ), + fmt::format( + "- {} (#{}) - Support role. Most offensive spell types are disabled. Focused on heals, cures, CC, debuffs and slows.", + Stance::GetName(Stance::Assist), + Stance::Assist + ), + fmt::format( + "- {} (#{}) - Murder. Doesn't care about aggro, just wants to kill. DPS Machine.", + Stance::GetName(Stance::Burn), + Stance::Burn + ), + fmt::format( + "- {} (#{}) - Murder EVERYTHING. Doesn't care about aggro, casts AEs. Everything must die ASAP.", + Stance::GetName(Stance::AEBurn), + Stance::AEBurn + ) + }; + + std::vector example_format = + { + fmt::format( + "{} [current | value: {}-{}]", + sep->arg[0], + Stance::Passive, + Stance::AEBurn + ) + }; + std::vector examples_one = + { + "To set all bots to BurnAE:", + fmt::format( + "{} {} spawned {}", + sep->arg[0], + Stance::Aggressive, + Class::ShadowKnight + ) + }; + std::vector examples_two = + { + "To set all Shadowknights to Aggressive:", + fmt::format( + "{} {} byclass {}", + sep->arg[0], + Stance::Aggressive, + Class::ShadowKnight + ) + }; + std::vector examples_three = + { + "To check the current stances of all bots:", + fmt::format( + "{} current spawned", + sep->arg[0] + ) + }; + + std::vector actionables = + { + "target, byname, ownergroup, ownerraid, targetgroup, namesgroup, healrotationtargets, mmr, byclass, byrace, spawned" + }; + + std::vector options = { }; + std::vector options_one = { }; + std::vector options_two = { }; + std::vector options_three = { }; + + std::string popup_text = c->SendCommandHelpWindow( + c, + description, + notes, + example_format, + examples_one, examples_two, examples_three, + actionables, + options, + options_one, options_two, options_three ); + + popup_text = DialogueWindow::Table(popup_text); + + c->SendPopupToClient(sep->arg[0], popup_text.c_str()); + return; } const int ab_mask = ActionableBots::ABM_Type1; - std::string arg1 = sep->arg[1]; + bool currentCheck = false; int ab_arg = 1; - bool current_check = false; uint32 value = 0; + std::string arg1 = sep->arg[1]; + if (sep->IsNumber(1)) { ++ab_arg; value = atoi(sep->arg[1]); - if (value < 0 || value > 300) { - c->Message(Chat::White, "You must enter a value within the range of 0 - 300."); + if ( + value < Stance::Passive || + value > Stance::AEBurn || + value == Stance::Reactive || + value == Stance::Assist + ) { + c->Message( + Chat::Yellow, + fmt::format( + "You must choose a valid stance ID, use {} for information regarding this command.", + Saylink::Silent( + fmt::format("{} help", sep->arg[0]) + ) + ).c_str() + ); + return; } } else if (!arg1.compare("current")) { ++ab_arg; - current_check = true; + currentCheck = true; } else { - c->Message(Chat::White, "Incorrect argument, use %s help for a list of options.", sep->arg[0]); + 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; } @@ -1232,26 +1377,56 @@ void bot_command_stance(Client *c, const Seperator *sep) return; } - if (!current_check && (value == Stance::Unknown || (value != Stance::Passive && value != Stance::Balanced && value != Stance::Aggressive))) { - c->Message(Chat::White, "A [current] argument or valid numeric [value] is required to use this command"); + Bot* first_found = nullptr; + int success_count = 0; + for (auto bot_iter : sbl) { + if (!first_found) { + first_found = bot_iter; + } + + if (currentCheck) { + c->Message( + Chat::Green, + fmt::format( + "{} says, 'My current stance is {} ({}).'", + bot_iter->GetCleanName(), + Stance::GetName(bot_iter->GetBotStance()), + bot_iter->GetBotStance() + ).c_str() + ); + + continue; + } + + bot_iter->Save(); + bot_iter->SetBotStance(value); + bot_iter->LoadDefaultBotSettings(); + database.botdb.LoadBotSettings(bot_iter); + bot_iter->Save(); + ++success_count; + } + + if (currentCheck) { return; } - for (auto bot_iter : sbl) { - if (!bot_iter) - continue; - - if (!current_check) { - bot_iter->SetBotStance(value); - bot_iter->Save(); - } - - Bot::BotGroupSay( - bot_iter, + if (success_count == 1 && first_found) { + c->Message( + Chat::Green, fmt::format( - "My current stance is {} ({}).", - Stance::GetName(bot_iter->GetBotStance()), - bot_iter->GetBotStance() + "{} says, 'I am now set to the stance [{}].'", + first_found->GetCleanName(), + Stance::GetName(value) + ).c_str() + ); + } + else { + c->Message( + Chat::Green, + fmt::format( + "{} of your bots are now set to the stance [{}].", + success_count, + Stance::GetName(value) ).c_str() ); } @@ -1278,7 +1453,7 @@ void bot_command_stop_melee_level(Client* c, const Seperator* sep) uint8 sml = RuleI(Bots, CasterStopMeleeLevel); bool sync_sml = false; bool reset_sml = false; - bool current_check = false; + bool currentCheck = false; if (sep->IsNumber(1)) { ab_arg = 2; @@ -1294,14 +1469,23 @@ void bot_command_stop_melee_level(Client* c, const Seperator* sep) } else if (!arg1.compare("current")) { ab_arg = 2; - current_check = true; + currentCheck = true; } else if (!strcasecmp(sep->arg[1], "reset")) { ab_arg = 2; reset_sml = true; } else { - c->Message(Chat::White, "Incorrect argument, use %s help for a list of options.", sep->arg[0]); + 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; } @@ -1347,7 +1531,7 @@ void bot_command_stop_melee_level(Client* c, const Seperator* sep) sml = my_bot->GetDefaultBotBaseSetting(BotBaseSettings::StopMeleeLevel); } - if (current_check) { + if (currentCheck) { c->Message( Chat::White, fmt::format( @@ -1364,7 +1548,7 @@ void bot_command_stop_melee_level(Client* c, const Seperator* sep) } } - if (!current_check) { + if (!currentCheck) { if (success_count == 1 && first_found) { c->Message( Chat::White, diff --git a/zone/bot_commands/default_settings.cpp b/zone/bot_commands/default_settings.cpp index 1f7c854ca..87bb31b0f 100644 --- a/zone/bot_commands/default_settings.cpp +++ b/zone/bot_commands/default_settings.cpp @@ -199,24 +199,28 @@ void bot_command_default_settings(Client* c, const Seperator* sep) Bot* first_found = nullptr; int success_count = 0; std::string output = ""; - for (auto my_bot : sbl) { + uint8 botStance = 2; + + for (auto myBot : sbl) { if (!first_found) { - first_found = my_bot; + first_found = myBot; } + botStance = myBot->GetBotStance(); + if (!strcasecmp(sep->arg[1], "misc")) { for (uint16 i = BotBaseSettings::START; i <= BotBaseSettings::END; ++i) { - my_bot->SetBotBaseSetting(i, my_bot->GetDefaultBotBaseSetting(i)); + myBot->SetBotBaseSetting(i, myBot->GetDefaultBotBaseSetting(i, botStance)); output = "miscellanous settings"; } } else if (!strcasecmp(sep->arg[1], "holds")) { if (spellType != UINT16_MAX) { - my_bot->SetSpellHold(spellType, my_bot->GetDefaultSpellHold(spellType)); + myBot->SetSpellHold(spellType, myBot->GetDefaultSpellHold(spellType, botStance)); } else { for (uint16 i = BotSpellTypes::START; i <= BotSpellTypes::END; ++i) { - my_bot->SetSpellHold(i, my_bot->GetDefaultSpellHold(i)); + myBot->SetSpellHold(i, myBot->GetDefaultSpellHold(i, botStance)); } } @@ -224,11 +228,11 @@ void bot_command_default_settings(Client* c, const Seperator* sep) } else if (!strcasecmp(sep->arg[1], "delays")) { if (spellType != UINT16_MAX) { - my_bot->SetSpellDelay(spellType, my_bot->GetDefaultSpellDelay(spellType)); + myBot->SetSpellDelay(spellType, myBot->GetDefaultSpellDelay(spellType, botStance)); } else { for (uint16 i = BotSpellTypes::START; i <= BotSpellTypes::END; ++i) { - my_bot->SetSpellDelay(i, my_bot->GetDefaultSpellDelay(i)); + myBot->SetSpellDelay(i, myBot->GetDefaultSpellDelay(i, botStance)); } } @@ -236,11 +240,11 @@ void bot_command_default_settings(Client* c, const Seperator* sep) } else if (!strcasecmp(sep->arg[1], "minthresholds")) { if (spellType != UINT16_MAX) { - my_bot->SetSpellMinThreshold(spellType, my_bot->GetDefaultSpellMinThreshold(spellType)); + myBot->SetSpellMinThreshold(spellType, myBot->GetDefaultSpellMinThreshold(spellType, botStance)); } else { for (uint16 i = BotSpellTypes::START; i <= BotSpellTypes::END; ++i) { - my_bot->SetSpellMinThreshold(i, my_bot->GetDefaultSpellMinThreshold(i)); + myBot->SetSpellMinThreshold(i, myBot->GetDefaultSpellMinThreshold(i, botStance)); } } @@ -248,11 +252,11 @@ void bot_command_default_settings(Client* c, const Seperator* sep) } else if (!strcasecmp(sep->arg[1], "maxthresholds")) { if (spellType != UINT16_MAX) { - my_bot->SetSpellMaxThreshold(spellType, my_bot->GetDefaultSpellMaxThreshold(spellType)); + myBot->SetSpellMaxThreshold(spellType, myBot->GetDefaultSpellMaxThreshold(spellType, botStance)); } else { for (uint16 i = BotSpellTypes::START; i <= BotSpellTypes::END; ++i) { - my_bot->SetSpellMaxThreshold(i, my_bot->GetDefaultSpellMaxThreshold(i)); + myBot->SetSpellMaxThreshold(i, myBot->GetDefaultSpellMaxThreshold(i, botStance)); } } @@ -260,11 +264,11 @@ void bot_command_default_settings(Client* c, const Seperator* sep) } else if (!strcasecmp(sep->arg[1], "aggrochecks")) { if (spellType != UINT16_MAX) { - my_bot->SetSpellTypeAggroCheck(spellType, my_bot->GetDefaultSpellTypeAggroCheck(spellType)); + myBot->SetSpellTypeAggroCheck(spellType, myBot->GetDefaultSpellTypeAggroCheck(spellType, botStance)); } else { for (uint16 i = BotSpellTypes::START; i <= BotSpellTypes::END; ++i) { - my_bot->SetSpellTypeAggroCheck(i, my_bot->GetDefaultSpellTypeAggroCheck(i)); + myBot->SetSpellTypeAggroCheck(i, myBot->GetDefaultSpellTypeAggroCheck(i, botStance)); } } @@ -272,11 +276,11 @@ void bot_command_default_settings(Client* c, const Seperator* sep) } else if (!strcasecmp(sep->arg[1], "minmanapct")) { if (spellType != UINT16_MAX) { - my_bot->SetSpellTypeMinManaLimit(spellType, my_bot->GetDefaultSpellTypeMinManaLimit(spellType)); + myBot->SetSpellTypeMinManaLimit(spellType, myBot->GetDefaultSpellTypeMinManaLimit(spellType, botStance)); } else { for (uint16 i = BotSpellTypes::START; i <= BotSpellTypes::END; ++i) { - my_bot->SetSpellTypeMinManaLimit(i, my_bot->GetDefaultSpellTypeMinManaLimit(i)); + myBot->SetSpellTypeMinManaLimit(i, myBot->GetDefaultSpellTypeMinManaLimit(i, botStance)); } } @@ -284,11 +288,11 @@ void bot_command_default_settings(Client* c, const Seperator* sep) } else if (!strcasecmp(sep->arg[1], "maxmanapct")) { if (spellType != UINT16_MAX) { - my_bot->SetSpellTypeMaxManaLimit(spellType, my_bot->GetDefaultSpellTypeMaxManaLimit(spellType)); + myBot->SetSpellTypeMaxManaLimit(spellType, myBot->GetDefaultSpellTypeMaxManaLimit(spellType, botStance)); } else { for (uint16 i = BotSpellTypes::START; i <= BotSpellTypes::END; ++i) { - my_bot->SetSpellTypeMaxManaLimit(i, my_bot->GetDefaultSpellTypeMaxManaLimit(i)); + myBot->SetSpellTypeMaxManaLimit(i, myBot->GetDefaultSpellTypeMaxManaLimit(i, botStance)); } } @@ -296,11 +300,11 @@ void bot_command_default_settings(Client* c, const Seperator* sep) } else if (!strcasecmp(sep->arg[1], "minhppct")) { if (spellType != UINT16_MAX) { - my_bot->SetSpellTypeMinHPLimit(spellType, my_bot->GetDefaultSpellTypeMinHPLimit(spellType)); + myBot->SetSpellTypeMinHPLimit(spellType, myBot->GetDefaultSpellTypeMinHPLimit(spellType, botStance)); } else { for (uint16 i = BotSpellTypes::START; i <= BotSpellTypes::END; ++i) { - my_bot->SetSpellTypeMinHPLimit(i, my_bot->GetDefaultSpellTypeMinHPLimit(i)); + myBot->SetSpellTypeMinHPLimit(i, myBot->GetDefaultSpellTypeMinHPLimit(i, botStance)); } } @@ -308,11 +312,11 @@ void bot_command_default_settings(Client* c, const Seperator* sep) } else if (!strcasecmp(sep->arg[1], "maxhppct")) { if (spellType != UINT16_MAX) { - my_bot->SetSpellTypeMaxHPLimit(spellType, my_bot->GetDefaultSpellTypeMaxHPLimit(spellType)); + myBot->SetSpellTypeMaxHPLimit(spellType, myBot->GetDefaultSpellTypeMaxHPLimit(spellType, botStance)); } else { for (uint16 i = BotSpellTypes::START; i <= BotSpellTypes::END; ++i) { - my_bot->SetSpellTypeMaxHPLimit(i, my_bot->GetDefaultSpellTypeMaxHPLimit(i)); + myBot->SetSpellTypeMaxHPLimit(i, myBot->GetDefaultSpellTypeMaxHPLimit(i, botStance)); } } @@ -320,11 +324,11 @@ void bot_command_default_settings(Client* c, const Seperator* sep) } else if (!strcasecmp(sep->arg[1], "idlepriority")) { if (spellType != UINT16_MAX) { - my_bot->SetSpellTypePriority(spellType, BotPriorityCategories::Idle, my_bot->GetDefaultSpellTypePriority(spellType, BotPriorityCategories::Idle, my_bot->GetClass())); + myBot->SetSpellTypePriority(spellType, BotPriorityCategories::Idle, myBot->GetDefaultSpellTypePriority(spellType, BotPriorityCategories::Idle, myBot->GetClass(), botStance)); } else { for (uint16 i = BotSpellTypes::START; i <= BotSpellTypes::END; ++i) { - my_bot->SetSpellTypePriority(i, BotPriorityCategories::Idle, my_bot->GetDefaultSpellTypePriority(i, BotPriorityCategories::Idle, my_bot->GetClass())); + myBot->SetSpellTypePriority(i, BotPriorityCategories::Idle, myBot->GetDefaultSpellTypePriority(i, BotPriorityCategories::Idle, myBot->GetClass(), botStance)); } } @@ -332,11 +336,11 @@ void bot_command_default_settings(Client* c, const Seperator* sep) } else if (!strcasecmp(sep->arg[1], "engagedpriority")) { if (spellType != UINT16_MAX) { - my_bot->SetSpellTypePriority(spellType, BotPriorityCategories::Engaged, my_bot->GetDefaultSpellTypePriority(spellType, BotPriorityCategories::Engaged, my_bot->GetClass())); + myBot->SetSpellTypePriority(spellType, BotPriorityCategories::Engaged, myBot->GetDefaultSpellTypePriority(spellType, BotPriorityCategories::Engaged, myBot->GetClass(), botStance)); } else { for (uint16 i = BotSpellTypes::START; i <= BotSpellTypes::END; ++i) { - my_bot->SetSpellTypePriority(i, BotPriorityCategories::Engaged, my_bot->GetDefaultSpellTypePriority(i, BotPriorityCategories::Engaged, my_bot->GetClass())); + myBot->SetSpellTypePriority(i, BotPriorityCategories::Engaged, myBot->GetDefaultSpellTypePriority(i, BotPriorityCategories::Engaged, myBot->GetClass(), botStance)); } } @@ -344,11 +348,11 @@ void bot_command_default_settings(Client* c, const Seperator* sep) } else if (!strcasecmp(sep->arg[1], "pursuepriority")) { if (spellType != UINT16_MAX) { - my_bot->SetSpellTypePriority(spellType, BotPriorityCategories::Pursue, my_bot->GetDefaultSpellTypePriority(spellType, BotPriorityCategories::Pursue, my_bot->GetClass())); + myBot->SetSpellTypePriority(spellType, BotPriorityCategories::Pursue, myBot->GetDefaultSpellTypePriority(spellType, BotPriorityCategories::Pursue, myBot->GetClass(), botStance)); } else { for (uint16 i = BotSpellTypes::START; i <= BotSpellTypes::END; ++i) { - my_bot->SetSpellTypePriority(i, BotPriorityCategories::Pursue, my_bot->GetDefaultSpellTypePriority(i, BotPriorityCategories::Pursue, my_bot->GetClass())); + myBot->SetSpellTypePriority(i, BotPriorityCategories::Pursue, myBot->GetDefaultSpellTypePriority(i, BotPriorityCategories::Pursue, myBot->GetClass(), botStance)); } } @@ -356,51 +360,51 @@ void bot_command_default_settings(Client* c, const Seperator* sep) } else if (!strcasecmp(sep->arg[1], "targetcounts")) { if (spellType != UINT16_MAX) { - my_bot->SetSpellDelay(spellType, my_bot->GetDefaultSpellDelay(spellType)); + myBot->SetSpellDelay(spellType, myBot->GetDefaultSpellDelay(spellType, botStance)); } else { for (uint16 i = BotSpellTypes::START; i <= BotSpellTypes::END; ++i) { - my_bot->SetSpellTypeAEOrGroupTargetCount(i, my_bot->GetDefaultSpellTypeAEOrGroupTargetCount(i)); + myBot->SetSpellTypeAEOrGroupTargetCount(i, myBot->GetDefaultSpellTypeAEOrGroupTargetCount(i, botStance)); } } output = "ae/group count settings"; } else if (!strcasecmp(sep->arg[1], "spellsettings")) { - my_bot->ResetBotSpellSettings(); + myBot->ResetBotSpellSettings(); output = "^spellsettings"; } else if (!strcasecmp(sep->arg[1], "spelltypesettings")) { if (spellType != UINT16_MAX) { - my_bot->SetSpellHold(spellType, my_bot->GetDefaultSpellHold(spellType)); - my_bot->SetSpellDelay(spellType, my_bot->GetDefaultSpellDelay(spellType)); - my_bot->SetSpellMinThreshold(spellType, my_bot->GetDefaultSpellMinThreshold(spellType)); - my_bot->SetSpellMaxThreshold(spellType, my_bot->GetDefaultSpellMaxThreshold(spellType)); - my_bot->SetSpellTypeAggroCheck(spellType, my_bot->GetDefaultSpellTypeAggroCheck(spellType)); - my_bot->SetSpellTypeMinManaLimit(spellType, my_bot->GetDefaultSpellTypeMinManaLimit(spellType)); - my_bot->SetSpellTypeMaxManaLimit(spellType, my_bot->GetDefaultSpellTypeMaxManaLimit(spellType)); - my_bot->SetSpellTypeMinHPLimit(spellType, my_bot->GetDefaultSpellTypeMinHPLimit(spellType)); - my_bot->SetSpellTypeMaxHPLimit(spellType, my_bot->GetDefaultSpellTypeMaxHPLimit(spellType)); - my_bot->SetSpellTypePriority(spellType, BotPriorityCategories::Idle, my_bot->GetDefaultSpellTypePriority(spellType, BotPriorityCategories::Idle, my_bot->GetClass())); - my_bot->SetSpellTypePriority(spellType, BotPriorityCategories::Engaged, my_bot->GetDefaultSpellTypePriority(spellType, BotPriorityCategories::Engaged, my_bot->GetClass())); - my_bot->SetSpellTypePriority(spellType, BotPriorityCategories::Pursue, my_bot->GetDefaultSpellTypePriority(spellType, BotPriorityCategories::Pursue, my_bot->GetClass())); - my_bot->SetSpellTypeAEOrGroupTargetCount(spellType, my_bot->GetDefaultSpellTypeAEOrGroupTargetCount(spellType)); + myBot->SetSpellHold(spellType, myBot->GetDefaultSpellHold(spellType, botStance)); + myBot->SetSpellDelay(spellType, myBot->GetDefaultSpellDelay(spellType, botStance)); + myBot->SetSpellMinThreshold(spellType, myBot->GetDefaultSpellMinThreshold(spellType, botStance)); + myBot->SetSpellMaxThreshold(spellType, myBot->GetDefaultSpellMaxThreshold(spellType, botStance)); + myBot->SetSpellTypeAggroCheck(spellType, myBot->GetDefaultSpellTypeAggroCheck(spellType, botStance)); + myBot->SetSpellTypeMinManaLimit(spellType, myBot->GetDefaultSpellTypeMinManaLimit(spellType, botStance)); + myBot->SetSpellTypeMaxManaLimit(spellType, myBot->GetDefaultSpellTypeMaxManaLimit(spellType, botStance)); + myBot->SetSpellTypeMinHPLimit(spellType, myBot->GetDefaultSpellTypeMinHPLimit(spellType, botStance)); + myBot->SetSpellTypeMaxHPLimit(spellType, myBot->GetDefaultSpellTypeMaxHPLimit(spellType, botStance)); + myBot->SetSpellTypePriority(spellType, BotPriorityCategories::Idle, myBot->GetDefaultSpellTypePriority(spellType, BotPriorityCategories::Idle, myBot->GetClass(), botStance)); + myBot->SetSpellTypePriority(spellType, BotPriorityCategories::Engaged, myBot->GetDefaultSpellTypePriority(spellType, BotPriorityCategories::Engaged, myBot->GetClass(), botStance)); + myBot->SetSpellTypePriority(spellType, BotPriorityCategories::Pursue, myBot->GetDefaultSpellTypePriority(spellType, BotPriorityCategories::Pursue, myBot->GetClass(), botStance)); + myBot->SetSpellTypeAEOrGroupTargetCount(spellType, myBot->GetDefaultSpellTypeAEOrGroupTargetCount(spellType, botStance)); } else { for (uint16 i = BotSpellTypes::START; i <= BotSpellTypes::END; ++i) { - my_bot->SetSpellHold(i, my_bot->GetDefaultSpellHold(i)); - my_bot->SetSpellDelay(i, my_bot->GetDefaultSpellDelay(i)); - my_bot->SetSpellMinThreshold(i, my_bot->GetDefaultSpellMinThreshold(i)); - my_bot->SetSpellMaxThreshold(i, my_bot->GetDefaultSpellMaxThreshold(i)); - my_bot->SetSpellTypeAggroCheck(i, my_bot->GetDefaultSpellTypeAggroCheck(i)); - my_bot->SetSpellTypeMinManaLimit(i, my_bot->GetDefaultSpellTypeMinManaLimit(i)); - my_bot->SetSpellTypeMaxManaLimit(i, my_bot->GetDefaultSpellTypeMaxManaLimit(i)); - my_bot->SetSpellTypeMinHPLimit(i, my_bot->GetDefaultSpellTypeMinHPLimit(i)); - my_bot->SetSpellTypeMaxHPLimit(i, my_bot->GetDefaultSpellTypeMaxHPLimit(i)); - my_bot->SetSpellTypePriority(i, BotPriorityCategories::Idle, my_bot->GetDefaultSpellTypePriority(i, BotPriorityCategories::Idle, my_bot->GetClass())); - my_bot->SetSpellTypePriority(i, BotPriorityCategories::Engaged, my_bot->GetDefaultSpellTypePriority(i, BotPriorityCategories::Engaged, my_bot->GetClass())); - my_bot->SetSpellTypePriority(i, BotPriorityCategories::Pursue, my_bot->GetDefaultSpellTypePriority(i, BotPriorityCategories::Pursue, my_bot->GetClass())); - my_bot->SetSpellTypeAEOrGroupTargetCount(i, my_bot->GetDefaultSpellTypeAEOrGroupTargetCount(i)); + myBot->SetSpellHold(i, myBot->GetDefaultSpellHold(i, botStance)); + myBot->SetSpellDelay(i, myBot->GetDefaultSpellDelay(i, botStance)); + myBot->SetSpellMinThreshold(i, myBot->GetDefaultSpellMinThreshold(i, botStance)); + myBot->SetSpellMaxThreshold(i, myBot->GetDefaultSpellMaxThreshold(i, botStance)); + myBot->SetSpellTypeAggroCheck(i, myBot->GetDefaultSpellTypeAggroCheck(i, botStance)); + myBot->SetSpellTypeMinManaLimit(i, myBot->GetDefaultSpellTypeMinManaLimit(i, botStance)); + myBot->SetSpellTypeMaxManaLimit(i, myBot->GetDefaultSpellTypeMaxManaLimit(i, botStance)); + myBot->SetSpellTypeMinHPLimit(i, myBot->GetDefaultSpellTypeMinHPLimit(i, botStance)); + myBot->SetSpellTypeMaxHPLimit(i, myBot->GetDefaultSpellTypeMaxHPLimit(i, botStance)); + myBot->SetSpellTypePriority(i, BotPriorityCategories::Idle, myBot->GetDefaultSpellTypePriority(i, BotPriorityCategories::Idle, myBot->GetClass(), botStance)); + myBot->SetSpellTypePriority(i, BotPriorityCategories::Engaged, myBot->GetDefaultSpellTypePriority(i, BotPriorityCategories::Engaged, myBot->GetClass(), botStance)); + myBot->SetSpellTypePriority(i, BotPriorityCategories::Pursue, myBot->GetDefaultSpellTypePriority(i, BotPriorityCategories::Pursue, myBot->GetClass(), botStance)); + myBot->SetSpellTypeAEOrGroupTargetCount(i, myBot->GetDefaultSpellTypeAEOrGroupTargetCount(i, botStance)); } } @@ -408,26 +412,26 @@ void bot_command_default_settings(Client* c, const Seperator* sep) } else if (!strcasecmp(sep->arg[1], "all")) { for (uint16 i = BotBaseSettings::START; i <= BotBaseSettings::END; ++i) { - my_bot->SetBotBaseSetting(i, my_bot->GetDefaultBotBaseSetting(i)); + myBot->SetBotBaseSetting(i, myBot->GetDefaultBotBaseSetting(i, botStance)); } for (uint16 i = BotSpellTypes::START; i <= BotSpellTypes::END; ++i) { - my_bot->SetSpellHold(i, my_bot->GetDefaultSpellHold(i)); - my_bot->SetSpellDelay(i, my_bot->GetDefaultSpellDelay(i)); - my_bot->SetSpellMinThreshold(i, my_bot->GetDefaultSpellMinThreshold(i)); - my_bot->SetSpellMaxThreshold(i, my_bot->GetDefaultSpellMaxThreshold(i)); - my_bot->SetSpellTypeAggroCheck(i, my_bot->GetDefaultSpellTypeAggroCheck(i)); - my_bot->SetSpellTypeMinManaLimit(i, my_bot->GetDefaultSpellTypeMinManaLimit(i)); - my_bot->SetSpellTypeMaxManaLimit(i, my_bot->GetDefaultSpellTypeMaxManaLimit(i)); - my_bot->SetSpellTypeMinHPLimit(i, my_bot->GetDefaultSpellTypeMinHPLimit(i)); - my_bot->SetSpellTypeMaxHPLimit(i, my_bot->GetDefaultSpellTypeMaxHPLimit(i)); - my_bot->SetSpellTypePriority(i, BotPriorityCategories::Idle, my_bot->GetDefaultSpellTypePriority(i, BotPriorityCategories::Idle, my_bot->GetClass())); - my_bot->SetSpellTypePriority(i, BotPriorityCategories::Engaged, my_bot->GetDefaultSpellTypePriority(i, BotPriorityCategories::Engaged, my_bot->GetClass())); - my_bot->SetSpellTypePriority(i, BotPriorityCategories::Pursue, my_bot->GetDefaultSpellTypePriority(i, BotPriorityCategories::Pursue, my_bot->GetClass())); - my_bot->SetSpellTypeAEOrGroupTargetCount(i, my_bot->GetDefaultSpellTypeAEOrGroupTargetCount(i)); + myBot->SetSpellHold(i, myBot->GetDefaultSpellHold(i, botStance)); + myBot->SetSpellDelay(i, myBot->GetDefaultSpellDelay(i, botStance)); + myBot->SetSpellMinThreshold(i, myBot->GetDefaultSpellMinThreshold(i, botStance)); + myBot->SetSpellMaxThreshold(i, myBot->GetDefaultSpellMaxThreshold(i, botStance)); + myBot->SetSpellTypeAggroCheck(i, myBot->GetDefaultSpellTypeAggroCheck(i, botStance)); + myBot->SetSpellTypeMinManaLimit(i, myBot->GetDefaultSpellTypeMinManaLimit(i, botStance)); + myBot->SetSpellTypeMaxManaLimit(i, myBot->GetDefaultSpellTypeMaxManaLimit(i, botStance)); + myBot->SetSpellTypeMinHPLimit(i, myBot->GetDefaultSpellTypeMinHPLimit(i, botStance)); + myBot->SetSpellTypeMaxHPLimit(i, myBot->GetDefaultSpellTypeMaxHPLimit(i, botStance)); + myBot->SetSpellTypePriority(i, BotPriorityCategories::Idle, myBot->GetDefaultSpellTypePriority(i, BotPriorityCategories::Idle, myBot->GetClass(), botStance)); + myBot->SetSpellTypePriority(i, BotPriorityCategories::Engaged, myBot->GetDefaultSpellTypePriority(i, BotPriorityCategories::Engaged, myBot->GetClass(), botStance)); + myBot->SetSpellTypePriority(i, BotPriorityCategories::Pursue, myBot->GetDefaultSpellTypePriority(i, BotPriorityCategories::Pursue, myBot->GetClass(), botStance)); + myBot->SetSpellTypeAEOrGroupTargetCount(i, myBot->GetDefaultSpellTypeAEOrGroupTargetCount(i, botStance)); }; - my_bot->ResetBotSpellSettings(); + myBot->ResetBotSpellSettings(); output = "settings"; diff --git a/zone/bot_database.cpp b/zone/bot_database.cpp index 20715d0d7..e60a17961 100644 --- a/zone/bot_database.cpp +++ b/zone/bot_database.cpp @@ -2211,14 +2211,15 @@ bool BotDatabase::LoadBotSettings(Mob* m) } uint32 mobID = (m->IsClient() ? m->CastToClient()->CharacterID() : m->CastToBot()->GetBotID()); + uint8 stanceID = (m->IsBot() ? m->CastToBot()->GetBotStance() : 0); std::string query = ""; if (m->IsClient()) { - query = fmt::format("`char_id` = {}", mobID); + query = fmt::format("`char_id` = {} AND `stance` = {}", mobID, stanceID); } else { - query = fmt::format("`bot_id` = {}", mobID); + query = fmt::format("`bot_id` = {} AND `stance` = {}", mobID, stanceID); } const auto& l = BotSettingsRepository::GetWhere(database, query); @@ -2228,12 +2229,24 @@ bool BotDatabase::LoadBotSettings(Mob* m) } for (const auto& e : l) { - LogBotSettings("[{}] says, 'Loading {} [{}] - setting to [{}]." - , m->GetCleanName() - , (e.setting_type == BotSettingCategories::BaseSetting ? m->CastToBot()->GetBotSettingCategoryName(e.setting_id) : m->CastToBot()->GetBotSpellCategoryName(e.setting_id)) - , e.setting_id - , e.value - ); //deleteme + if (e.setting_type == BotSettingCategories::BaseSetting) { + LogBotSettings("[{}] says, 'Loading {} [{}] - setting to [{}]." + , m->GetCleanName() + , m->CastToBot()->GetBotSettingCategoryName(e.setting_type) + , e.setting_type + , e.value + ); //deleteme + } + else { + LogBotSettings("[{}] says, 'Loading {} [{}], {} [{}] - setting to [{}]." + , m->GetCleanName() + , m->CastToBot()->GetBotSpellCategoryName(e.setting_type) + , e.setting_type + , m->GetSpellTypeNameByID(e.setting_id) + , e.setting_id + , e.value + ); //deleteme + } m->SetBotSetting(e.setting_type, e.setting_id, e.value); } @@ -2251,16 +2264,17 @@ bool BotDatabase::SaveBotSettings(Mob* m) return false; } - uint32 botID = (m->IsClient() ? 0 : m->CastToBot()->GetBotID()); + uint32 botID = (m->IsBot() ? m->CastToBot()->GetBotID() : 0); uint32 charID = (m->IsClient() ? m->CastToClient()->CharacterID() : 0); + uint8 stanceID = (m->IsBot() ? m->CastToBot()->GetBotStance() : 0); std::string query = ""; if (m->IsClient()) { - query = fmt::format("`char_id` = {}", charID); + query = fmt::format("`char_id` = {} AND `stance` = {}", charID, stanceID); } else { - query = fmt::format("`bot_id` = {}", botID); + query = fmt::format("`bot_id` = {} AND `stance` = {}", botID, stanceID); } BotSettingsRepository::DeleteWhere(database, query); @@ -2268,16 +2282,19 @@ bool BotDatabase::SaveBotSettings(Mob* m) std::vector v; if (m->IsBot()) { + uint8 botStance = m->CastToBot()->GetBotStance(); + for (uint16 i = BotBaseSettings::START; i <= BotBaseSettings::END; ++i) { - if (m->CastToBot()->GetBotBaseSetting(i) != m->CastToBot()->GetDefaultBotBaseSetting(i)) { + if (m->CastToBot()->GetBotBaseSetting(i) != m->CastToBot()->GetDefaultBotBaseSetting(i, botStance)) { auto e = BotSettingsRepository::BotSettings{ - .char_id = charID, - .bot_id = botID, - .setting_id = static_cast(i), - .setting_type = static_cast(BotSettingCategories::BaseSetting), - .value = static_cast(m->CastToBot()->GetBotBaseSetting(i)), - .category_name = m->CastToBot()->GetBotSpellCategoryName(BotSettingCategories::BaseSetting), - .setting_name = m->CastToBot()->GetBotSettingCategoryName(i) + .char_id = charID, + .bot_id = botID, + .stance = stanceID, + .setting_id = static_cast(i), + .setting_type = static_cast(BotSettingCategories::BaseSetting), + .value = static_cast(m->CastToBot()->GetBotBaseSetting(i)), + .category_name = m->CastToBot()->GetBotSpellCategoryName(BotSettingCategories::BaseSetting), + .setting_name = m->CastToBot()->GetBotSettingCategoryName(i) }; v.emplace_back(e); @@ -2288,10 +2305,11 @@ bool BotDatabase::SaveBotSettings(Mob* m) for (uint16 i = BotSettingCategories::START_NO_BASE; i <= BotSettingCategories::END; ++i) { for (uint16 x = BotSpellTypes::START; x <= BotSpellTypes::END; ++x) { - if (m->CastToBot()->GetSetting(i, x) != m->CastToBot()->GetDefaultSetting(i, x)) { + if (m->CastToBot()->GetSetting(i, x) != m->CastToBot()->GetDefaultSetting(i, x, botStance)) { auto e = BotSettingsRepository::BotSettings{ .char_id = charID, .bot_id = botID, + .stance = stanceID, .setting_id = static_cast(x), .setting_type = static_cast(i), .value = m->CastToBot()->GetSetting(i, x), @@ -2301,7 +2319,7 @@ bool BotDatabase::SaveBotSettings(Mob* m) v.emplace_back(e); - LogBotSettings("{} says, 'Saving {} {} [{}] - set to [{}] default [{}].'", m->GetCleanName(), m->CastToBot()->GetBotSpellCategoryName(i), m->GetSpellTypeNameByID(x), x, e.value, m->CastToBot()->GetDefaultSetting(i, x)); //deleteme + LogBotSettings("{} says, 'Saving {} {} [{}] - set to [{}] default [{}].'", m->GetCleanName(), m->CastToBot()->GetBotSpellCategoryName(i), m->GetSpellTypeNameByID(x), x, e.value, m->CastToBot()->GetDefaultSetting(i, x, botStance)); //deleteme } } } @@ -2312,6 +2330,7 @@ bool BotDatabase::SaveBotSettings(Mob* m) auto e = BotSettingsRepository::BotSettings{ .char_id = charID, .bot_id = botID, + .stance = stanceID, .setting_id = static_cast(BotBaseSettings::IllusionBlock), .setting_type = static_cast(BotSettingCategories::BaseSetting), .value = m->GetIllusionBlock(), @@ -2331,6 +2350,7 @@ bool BotDatabase::SaveBotSettings(Mob* m) auto e = BotSettingsRepository::BotSettings{ .char_id = charID, .bot_id = botID, + .stance = stanceID, .setting_id = static_cast(x), .setting_type = static_cast(i), .value = m->CastToClient()->GetBotSetting(i, x), diff --git a/zone/client.cpp b/zone/client.cpp index fe36a6056..dd22e2a23 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -13080,6 +13080,8 @@ void Client::ClientToNpcAggroProcess() } void Client::LoadDefaultBotSettings() { + _spellSettings.clear(); + // Only illusion block supported currently SetBotSetting(BotSettingCategories::BaseSetting, BotBaseSettings::IllusionBlock, GetDefaultBotSettings(BotSettingCategories::BaseSetting, BotBaseSettings::IllusionBlock)); LogBotSettingsDetail("{} says, 'Setting default {} [{}] to [{}]'", GetCleanName(), CastToBot()->GetBotSettingCategoryName(BotBaseSettings::IllusionBlock), BotBaseSettings::IllusionBlock, GetDefaultBotSettings(BotSettingCategories::BaseSetting, BotBaseSettings::IllusionBlock)); //deleteme @@ -13132,21 +13134,21 @@ int Client::GetBotSetting(uint8 settingType, uint16 botSetting) { void Client::SetBotSetting(uint8 settingType, uint16 botSetting, uint32 settingValue) { switch (settingType) { - case BotSettingCategories::BaseSetting: - SetBaseSetting(botSetting, settingValue); - break; - case BotSettingCategories::SpellHold: - SetSpellHold(botSetting, settingValue); - break; - case BotSettingCategories::SpellDelay: - SetSpellDelay(botSetting, settingValue); - break; - case BotSettingCategories::SpellMinThreshold: - SetSpellMinThreshold(botSetting, settingValue); - break; - case BotSettingCategories::SpellMaxThreshold: - SetSpellMaxThreshold(botSetting, settingValue); - break; + case BotSettingCategories::BaseSetting: + SetBaseSetting(botSetting, settingValue); + break; + case BotSettingCategories::SpellHold: + SetSpellHold(botSetting, settingValue); + break; + case BotSettingCategories::SpellDelay: + SetSpellDelay(botSetting, settingValue); + break; + case BotSettingCategories::SpellMinThreshold: + SetSpellMinThreshold(botSetting, settingValue); + break; + case BotSettingCategories::SpellMaxThreshold: + SetSpellMaxThreshold(botSetting, settingValue); + break; } } diff --git a/zone/mob.cpp b/zone/mob.cpp index 926ea3382..e75ce0068 100644 --- a/zone/mob.cpp +++ b/zone/mob.cpp @@ -9046,18 +9046,30 @@ std::string Mob::GetSpellTypeShortNameByID(uint16 spellType) { return spellTypeName; } -bool Mob::GetDefaultSpellHold(uint16 spellType) { +bool Mob::GetDefaultSpellHold(uint16 spellType, uint8 stance) { switch (spellType) { + case BotSpellTypes::Nuke: + case BotSpellTypes::DOT: + case BotSpellTypes::Stun: + switch (stance) { + case Stance::Assist: + return true; + default: + return false; + } case BotSpellTypes::AENukes: case BotSpellTypes::AERains: - case BotSpellTypes::AEMez: case BotSpellTypes::AEStun: - case BotSpellTypes::AEDebuff: - case BotSpellTypes::AESlow: - case BotSpellTypes::AESnare: case BotSpellTypes::AEDoT: case BotSpellTypes::AELifetap: case BotSpellTypes::PBAENuke: + switch (stance) { + case Stance::AEBurn: + return false; + default: + return true; + } + case BotSpellTypes::AESnare: case BotSpellTypes::AERoot: case BotSpellTypes::Root: case BotSpellTypes::AEDispel: @@ -9065,28 +9077,46 @@ bool Mob::GetDefaultSpellHold(uint16 spellType) { case BotSpellTypes::AEFear: case BotSpellTypes::Fear: return true; - case BotSpellTypes::Snare: - if (GetClass() == Class::Wizard) { - return true; + case BotSpellTypes::AEMez: + case BotSpellTypes::AEDebuff: + case BotSpellTypes::AESlow: + case BotSpellTypes::HateRedux: + switch (stance) { + case Stance::AEBurn: + case Stance::Burn: + return true; + default: + return false; } - else { - return false; + case BotSpellTypes::Snare: + switch (stance) { + case Stance::AEBurn: + case Stance::Burn: + case Stance::Assist: + return true; + default: + if (GetClass() == Class::Wizard) { + return true; + } + else { + return false; + } } case BotSpellTypes::InCombatBuffSong: case BotSpellTypes::OutOfCombatBuffSong: case BotSpellTypes::PreCombatBuffSong: if (GetClass() == Class::Bard) { - return true; + return false; } else { - return false; + return true; } default: return false; } } -uint16 Mob::GetDefaultSpellDelay(uint16 spellType) { +uint16 Mob::GetDefaultSpellDelay(uint16 spellType, uint8 stance) { switch (spellType) { case BotSpellTypes::VeryFastHeals: case BotSpellTypes::PetVeryFastHeals: @@ -9094,12 +9124,31 @@ uint16 Mob::GetDefaultSpellDelay(uint16 spellType) { case BotSpellTypes::FastHeals: case BotSpellTypes::PetFastHeals: return 2500; - case BotSpellTypes::AEDoT: - case BotSpellTypes::DOT: case BotSpellTypes::GroupHeals: case BotSpellTypes::RegularHeal: case BotSpellTypes::PetRegularHeals: return 4000; + case BotSpellTypes::CompleteHeal: + case BotSpellTypes::GroupCompleteHeals: + case BotSpellTypes::PetCompleteHeals: + return 8000; + case BotSpellTypes::GroupHoTHeals: + case BotSpellTypes::HoTHeals: + case BotSpellTypes::PetHoTHeals: + return 22000; + case BotSpellTypes::AEDoT: + case BotSpellTypes::DOT: + switch (stance) { + case Stance::AEBurn: + case Stance::Burn: + return 1; + case Stance::Aggressive: + return 2000; + case Stance::Efficient: + return 8000; + default: + return 4000; + } case BotSpellTypes::AENukes: case BotSpellTypes::AERains: case BotSpellTypes::PBAENuke: @@ -9112,43 +9161,68 @@ uint16 Mob::GetDefaultSpellDelay(uint16 spellType) { case BotSpellTypes::Slow: case BotSpellTypes::AEStun: case BotSpellTypes::Stun: - return 6000; + switch (stance) { + case Stance::AEBurn: + case Stance::Burn: + return 1; + case Stance::Aggressive: + return 3000; + case Stance::Efficient: + return 10000; + default: + return 6000; + } case BotSpellTypes::AERoot: case BotSpellTypes::Root: - case BotSpellTypes::CompleteHeal: - case BotSpellTypes::GroupCompleteHeals: - case BotSpellTypes::PetCompleteHeals: - return 8000; + return 8000; case BotSpellTypes::Fear: case BotSpellTypes::AEFear: return 15000; - case BotSpellTypes::GroupHoTHeals: - case BotSpellTypes::HoTHeals: - case BotSpellTypes::PetHoTHeals: - return 22000; default: return 1; } } -uint8 Mob::GetDefaultSpellMinThreshold(uint16 spellType) { +uint8 Mob::GetDefaultSpellMinThreshold(uint16 spellType, uint8 stance) { switch (spellType) { - case BotSpellTypes::AENukes: - case BotSpellTypes::AERains: - case BotSpellTypes::PBAENuke: - case BotSpellTypes::Nuke: case BotSpellTypes::AEDebuff: case BotSpellTypes::Debuff: case BotSpellTypes::AEDispel: case BotSpellTypes::Dispel: case BotSpellTypes::AESlow: case BotSpellTypes::Slow: - return 20; + switch (stance) { + case Stance::AEBurn: + case Stance::Burn: + case Stance::Aggressive: + return 0; + default: + return 20; + } + case BotSpellTypes::AENukes: + case BotSpellTypes::AERains: + case BotSpellTypes::PBAENuke: + case BotSpellTypes::Nuke: + switch (stance) { + case Stance::AEBurn: + case Stance::Burn: + case Stance::Aggressive: + return 0; + default: + return 5; + } case BotSpellTypes::AEDoT: case BotSpellTypes::DOT: - return 35; - case BotSpellTypes::Charm: - return 50; + switch (stance) { + case Stance::AEBurn: + case Stance::Burn: + case Stance::Aggressive: + return 0; + case Stance::Efficient: + return 40; + default: + return 25; + } case BotSpellTypes::Mez: case BotSpellTypes::AEMez: return 85; @@ -9157,25 +9231,60 @@ uint8 Mob::GetDefaultSpellMinThreshold(uint16 spellType) { } } -uint8 Mob::GetDefaultSpellMaxThreshold(uint16 spellType) { +uint8 Mob::GetDefaultSpellMaxThreshold(uint16 spellType, uint8 stance) { switch (spellType) { case BotSpellTypes::Escape: case BotSpellTypes::VeryFastHeals: case BotSpellTypes::PetVeryFastHeals: - return 25; + switch (stance) { + case Stance::AEBurn: + case Stance::Burn: + case Stance::Aggressive: + return 40; + case Stance::Efficient: + default: + return 25; + } case BotSpellTypes::AELifetap: case BotSpellTypes::Lifetap: case BotSpellTypes::FastHeals: case BotSpellTypes::PetFastHeals: - return 40; + switch (stance) { + case Stance::AEBurn: + case Stance::Burn: + case Stance::Aggressive: + return 55; + case Stance::Efficient: + return 35; + default: + return 40; + } case BotSpellTypes::GroupHeals: case BotSpellTypes::RegularHeal: case BotSpellTypes::PetRegularHeals: - return 60; + switch (stance) { + case Stance::AEBurn: + case Stance::Burn: + case Stance::Aggressive: + return 70; + case Stance::Efficient: + return 50; + default: + return 60; + } case BotSpellTypes::CompleteHeal: case BotSpellTypes::GroupCompleteHeals: case BotSpellTypes::PetCompleteHeals: - return 80; + switch (stance) { + case Stance::AEBurn: + case Stance::Burn: + case Stance::Aggressive: + return 90; + case Stance::Efficient: + return 65; + default: + return 80; + } case BotSpellTypes::AENukes: case BotSpellTypes::AERains: case BotSpellTypes::PBAENuke: @@ -9195,7 +9304,17 @@ uint8 Mob::GetDefaultSpellMaxThreshold(uint16 spellType) { case BotSpellTypes::AEDebuff: case BotSpellTypes::Debuff: case BotSpellTypes::Stun: - return 99; + switch (stance) { + case Stance::AEBurn: + case Stance::Burn: + return 100; + case Stance::Aggressive: + return 100; + case Stance::Efficient: + return 90; + default: + return 99; + } case BotSpellTypes::Buff: case BotSpellTypes::Charm: case BotSpellTypes::Cure: @@ -9220,7 +9339,16 @@ uint8 Mob::GetDefaultSpellMaxThreshold(uint16 spellType) { return 60; } else { - return 90; + switch (stance) { + case Stance::AEBurn: + case Stance::Burn: + case Stance::Aggressive: + return 95; + case Stance::Efficient: + return 80; + default: + return 90; + } } default: return 100; diff --git a/zone/mob.h b/zone/mob.h index f2e8e9abd..8e0a4728c 100644 --- a/zone/mob.h +++ b/zone/mob.h @@ -437,10 +437,10 @@ public: std::string GetSpellTypeNameByID(uint16 spellType); std::string GetSpellTypeShortNameByID(uint16 spellType); - bool GetDefaultSpellHold(uint16 spellType); - uint16 GetDefaultSpellDelay(uint16 spellType); - uint8 GetDefaultSpellMinThreshold(uint16 spellType); - uint8 GetDefaultSpellMaxThreshold(uint16 spellType); + bool GetDefaultSpellHold(uint16 spellType, uint8 stance = Stance::Balanced); + uint16 GetDefaultSpellDelay(uint16 spellType, uint8 stance = Stance::Balanced); + uint8 GetDefaultSpellMinThreshold(uint16 spellType, uint8 stance = Stance::Balanced); + uint8 GetDefaultSpellMaxThreshold(uint16 spellType, uint8 stance = Stance::Balanced); inline bool GetSpellHold(uint16 spellType) const { return _spellSettings[spellType].hold; } void SetSpellHold(uint16 spellType, bool holdStatus);