mirror of
https://github.com/EQEmu/Server.git
synced 2026-06-26 15:37:16 +00:00
Add rules (Bots, AICastSpellTypeDelay, Bots, AICastSpellTypeHeldDelay) to prevent spamming of failed spell type AI casts
This commit is contained in:
@@ -898,6 +898,8 @@ RULE_STRING(Bots, ZonesWithSpawnLimits, "", "Comma-delimited list of zones where
|
|||||||
RULE_STRING(Bots, ZoneSpawnLimits, "", "Comma-delimited list of spawn limits for zones.")
|
RULE_STRING(Bots, ZoneSpawnLimits, "", "Comma-delimited list of spawn limits for zones.")
|
||||||
RULE_STRING(Bots, ZonesWithForcedSpawnLimits, "", "Comma-delimited list of zones where bot spawn limits are forced. This will take priority over any other type of spawn limits.")
|
RULE_STRING(Bots, ZonesWithForcedSpawnLimits, "", "Comma-delimited list of zones where bot spawn limits are forced. This will take priority over any other type of spawn limits.")
|
||||||
RULE_STRING(Bots, ZoneForcedSpawnLimits, "", "Comma-delimited list of forced spawn limits for zones.")
|
RULE_STRING(Bots, ZoneForcedSpawnLimits, "", "Comma-delimited list of forced spawn limits for zones.")
|
||||||
|
RULE_INT(Bots, AICastSpellTypeDelay, 100, "Delay in milliseconds between AI cast attempts for each spell type. Default 100ms")
|
||||||
|
RULE_INT(Bots, AICastSpellTypeHeldDelay, 2500, "Delay in milliseconds between AI cast attempts for each spell type that is held or disabled. Default 2500ms (2.5s)")
|
||||||
RULE_CATEGORY_END()
|
RULE_CATEGORY_END()
|
||||||
|
|
||||||
RULE_CATEGORY(Chat)
|
RULE_CATEGORY(Chat)
|
||||||
|
|||||||
@@ -9434,6 +9434,9 @@ bool Bot::PrecastChecks(Mob* tar, uint16 spell_type) {
|
|||||||
LogBotSpellChecksDetail("{} says, 'Running [{}] PreChecks on [{}].'", GetCleanName(), GetSpellTypeNameByID(spell_type), tar->GetCleanName());
|
LogBotSpellChecksDetail("{} says, 'Running [{}] PreChecks on [{}].'", GetCleanName(), GetSpellTypeNameByID(spell_type), tar->GetCleanName());
|
||||||
|
|
||||||
if (GetUltimateSpellHold(spell_type, tar)) {
|
if (GetUltimateSpellHold(spell_type, tar)) {
|
||||||
|
if (!IsCommandedSpell()) {
|
||||||
|
SetSpellTypeAITimer(spell_type, RuleI(Bots, AICastSpellTypeHeldDelay));
|
||||||
|
}
|
||||||
LogBotSpellChecksDetail("{} says, 'Cancelling cast of [{}] on [{}] due to GetUltimateSpellHold.'", GetCleanName(), GetSpellTypeNameByID(spell_type), tar->GetCleanName());
|
LogBotSpellChecksDetail("{} says, 'Cancelling cast of [{}] on [{}] due to GetUltimateSpellHold.'", GetCleanName(), GetSpellTypeNameByID(spell_type), tar->GetCleanName());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -10521,6 +10524,7 @@ void Bot::LoadDefaultBotSettings() {
|
|||||||
t.ae_or_group_target_count = GetDefaultSpellTypeAEOrGroupTargetCount(i, bot_stance);
|
t.ae_or_group_target_count = GetDefaultSpellTypeAEOrGroupTargetCount(i, bot_stance);
|
||||||
t.announce_cast = GetDefaultSpellTypeAnnounceCast(i, bot_stance);
|
t.announce_cast = GetDefaultSpellTypeAnnounceCast(i, bot_stance);
|
||||||
t.recast_timer.Start();
|
t.recast_timer.Start();
|
||||||
|
t.ai_delay.Start();
|
||||||
|
|
||||||
m_bot_spell_settings.push_back(t);
|
m_bot_spell_settings.push_back(t);
|
||||||
|
|
||||||
|
|||||||
@@ -637,6 +637,8 @@ public:
|
|||||||
inline void SetSpellMaxThreshold(uint16 spell_type, uint8 threshold_value) { m_bot_spell_settings[spell_type].max_threshold = threshold_value; }
|
inline void SetSpellMaxThreshold(uint16 spell_type, uint8 threshold_value) { m_bot_spell_settings[spell_type].max_threshold = threshold_value; }
|
||||||
inline bool SpellTypeRecastCheck(uint16 spellType) { return !m_bot_spell_settings[spellType].recast_timer.GetRemainingTime(); }
|
inline bool SpellTypeRecastCheck(uint16 spellType) { return !m_bot_spell_settings[spellType].recast_timer.GetRemainingTime(); }
|
||||||
void SetSpellTypeRecastTimer(uint16 spell_type, uint32 recast_time) { m_bot_spell_settings[spell_type].recast_timer.Start(recast_time); }
|
void SetSpellTypeRecastTimer(uint16 spell_type, uint32 recast_time) { m_bot_spell_settings[spell_type].recast_timer.Start(recast_time); }
|
||||||
|
inline bool SpellTypeAIDelayCheck(uint16 spellType) { return !m_bot_spell_settings[spellType].ai_delay.GetRemainingTime(); }
|
||||||
|
void SetSpellTypeAITimer(uint16 spell_type, uint32 recast_time) { m_bot_spell_settings[spell_type].ai_delay.Start(recast_time); }
|
||||||
uint16 GetDefaultSpellDelay(uint16 spell_type, uint8 stance = Stance::Balanced);
|
uint16 GetDefaultSpellDelay(uint16 spell_type, uint8 stance = Stance::Balanced);
|
||||||
uint8 GetDefaultSpellMinThreshold(uint16 spell_type, uint8 stance = Stance::Balanced);
|
uint8 GetDefaultSpellMinThreshold(uint16 spell_type, uint8 stance = Stance::Balanced);
|
||||||
uint8 GetDefaultSpellMaxThreshold(uint16 spell_type, uint8 stance = Stance::Balanced);
|
uint8 GetDefaultSpellMaxThreshold(uint16 spell_type, uint8 stance = Stance::Balanced);
|
||||||
|
|||||||
@@ -131,6 +131,7 @@ struct BotSpellSettings {
|
|||||||
uint16 ae_or_group_target_count; // require target count to cast an AE or Group 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
|
uint16 announce_cast; // announce when casting a certain spell type
|
||||||
Timer recast_timer; // recast timer based off delay
|
Timer recast_timer; // recast timer based off delay
|
||||||
|
Timer ai_delay; // spell timer based off delay
|
||||||
};
|
};
|
||||||
|
|
||||||
struct BotSpellTypeOrder {
|
struct BotSpellTypeOrder {
|
||||||
|
|||||||
@@ -663,6 +663,7 @@ bool Bot::AI_PursueCastCheck() {
|
|||||||
|
|
||||||
for (auto& current_cast : cast_order) {
|
for (auto& current_cast : cast_order) {
|
||||||
if (current_cast.priority == 0) {
|
if (current_cast.priority == 0) {
|
||||||
|
SetSpellTypeAITimer(current_cast.spellType, RuleI(Bots, AICastSpellTypeHeldDelay));
|
||||||
LogBotSpellChecksDetail("{} says, '[{}] is priority 0, skipping.'", GetCleanName(), GetSpellTypeNameByID(current_cast.spellType));
|
LogBotSpellChecksDetail("{} says, '[{}] is priority 0, skipping.'", GetCleanName(), GetSpellTypeNameByID(current_cast.spellType));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -679,12 +680,18 @@ bool Bot::AI_PursueCastCheck() {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!SpellTypeAIDelayCheck(current_cast.spellType)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
result = AttemptAICastSpell(current_cast.spellType, nullptr);
|
result = AttemptAICastSpell(current_cast.spellType, nullptr);
|
||||||
|
|
||||||
if (!result && IsBotSpellTypeBeneficial(current_cast.spellType)) {
|
if (!result && IsBotSpellTypeBeneficial(current_cast.spellType)) {
|
||||||
result = AttemptCloseBeneficialSpells(current_cast.spellType);
|
result = AttemptCloseBeneficialSpells(current_cast.spellType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SetSpellTypeAITimer(current_cast.spellType, RuleI(Bots, AICastSpellTypeDelay));
|
||||||
|
|
||||||
if (result) {
|
if (result) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -731,6 +738,7 @@ bool Bot::AI_IdleCastCheck() {
|
|||||||
|
|
||||||
for (auto& current_cast : cast_order) {
|
for (auto& current_cast : cast_order) {
|
||||||
if (current_cast.priority == 0) {
|
if (current_cast.priority == 0) {
|
||||||
|
SetSpellTypeAITimer(current_cast.spellType, RuleI(Bots, AICastSpellTypeHeldDelay));
|
||||||
LogBotSpellChecksDetail("{} says, '[{}] is priority 0, skipping.'", GetCleanName(), GetSpellTypeNameByID(current_cast.spellType));
|
LogBotSpellChecksDetail("{} says, '[{}] is priority 0, skipping.'", GetCleanName(), GetSpellTypeNameByID(current_cast.spellType));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -755,6 +763,10 @@ bool Bot::AI_IdleCastCheck() {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!SpellTypeAIDelayCheck(current_cast.spellType)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
result = AttemptAICastSpell(current_cast.spellType, nullptr);
|
result = AttemptAICastSpell(current_cast.spellType, nullptr);
|
||||||
|
|
||||||
if (result) {
|
if (result) {
|
||||||
@@ -763,6 +775,8 @@ bool Bot::AI_IdleCastCheck() {
|
|||||||
|
|
||||||
result = AttemptCloseBeneficialSpells(current_cast.spellType);
|
result = AttemptCloseBeneficialSpells(current_cast.spellType);
|
||||||
|
|
||||||
|
SetSpellTypeAITimer(current_cast.spellType, RuleI(Bots, AICastSpellTypeDelay));
|
||||||
|
|
||||||
if (result) {
|
if (result) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -799,6 +813,7 @@ bool Bot::AI_EngagedCastCheck() {
|
|||||||
|
|
||||||
for (auto& current_cast : cast_order) {
|
for (auto& current_cast : cast_order) {
|
||||||
if (current_cast.priority == 0) {
|
if (current_cast.priority == 0) {
|
||||||
|
SetSpellTypeAITimer(current_cast.spellType, RuleI(Bots, AICastSpellTypeHeldDelay));
|
||||||
LogBotSpellChecksDetail("{} says, '[{}] is priority 0, skipping.'", GetCleanName(), GetSpellTypeNameByID(current_cast.spellType));
|
LogBotSpellChecksDetail("{} says, '[{}] is priority 0, skipping.'", GetCleanName(), GetSpellTypeNameByID(current_cast.spellType));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -815,8 +830,14 @@ bool Bot::AI_EngagedCastCheck() {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!SpellTypeAIDelayCheck(current_cast.spellType)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
result = AttemptAICastSpell(current_cast.spellType, nullptr);
|
result = AttemptAICastSpell(current_cast.spellType, nullptr);
|
||||||
|
|
||||||
|
SetSpellTypeAITimer(current_cast.spellType, RuleI(Bots, AICastSpellTypeDelay));
|
||||||
|
|
||||||
if (!result && IsBotSpellTypeBeneficial(current_cast.spellType)) {
|
if (!result && IsBotSpellTypeBeneficial(current_cast.spellType)) {
|
||||||
result = AttemptCloseBeneficialSpells(current_cast.spellType);
|
result = AttemptCloseBeneficialSpells(current_cast.spellType);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user