Implement more commanded types properly, move shadownight hate to hateline type...

Add incapacitated checks to casting logic and checks.
Add candocombat zone check, summon other's corpse for bot, in/out combat spell checks, mute checks, level restriction
This commit is contained in:
nytmyr
2024-11-27 13:51:37 -06:00
parent b200bdd04e
commit 10effce2a6
10 changed files with 588 additions and 248 deletions
@@ -513,7 +513,7 @@ UPDATE bot_spells_entries SET `type` = 4 WHERE `spell_id` = 10436;
.match = "",
.sql = R"(
INSERT INTO `bot_spells_entries` (`npc_spells_id`, `spell_id`, `type`, `minlevel`, `maxlevel`)
VALUES
VALUES
(3006, 9957, 100, 20, 254),
(3006, 9956, 100, 20, 254),
(3006, 552, 100, 25, 254),
@@ -764,31 +764,6 @@ VALUES
(3006, 34863, 101, 96, 254),
(3006, 34864, 101, 96, 254),
(3006, 34862, 101, 96, 254),
(3007, 4614, 101, 35, 49),
(3007, 4683, 101, 50, 56),
(3007, 4684, 101, 57, 63),
(3007, 4698, 101, 64, 64),
(3007, 5019, 101, 65, 254),
(3007, 5020, 101, 65, 254),
(3007, 6175, 101, 69, 70),
(3007, 10949, 101, 71, 75),
(3007, 10947, 101, 71, 75),
(3007, 10948, 101, 71, 75),
(3007, 14800, 101, 76, 80),
(3007, 14801, 101, 76, 80),
(3007, 14799, 101, 76, 80),
(3007, 18905, 101, 81, 85),
(3007, 18906, 101, 81, 85),
(3007, 18904, 101, 81, 85),
(3007, 25912, 101, 86, 90),
(3007, 25913, 101, 86, 90),
(3007, 25911, 101, 86, 90),
(3007, 29006, 101, 91, 95),
(3007, 29007, 101, 91, 95),
(3007, 29008, 101, 91, 95),
(3007, 35047, 101, 96, 254),
(3007, 35048, 101, 96, 254),
(3007, 35049, 101, 96, 254),
(3008, 728, 101, 8, 60),
(3008, 3361, 101, 61, 254),
(3008, 5370, 101, 66, 70),
@@ -1090,6 +1065,104 @@ VALUES
(3011, 25555, 112, 86, 90),
(3011, 28632, 112, 91, 95),
(3011, 34662, 112, 96, 254);
)"
},
ManifestEntry{
.version = 9051,
.description = "2024_11_26_remove_sk_icb.sql",
.check = "SELECT * FROM `bot_spells_entries` where `type` = 55",
.condition = "empty",
.match = "",
.sql = R"(
DELETE
FROM bot_spells_entries
WHERE `npc_spells_id` = 3005
AND `type` = 10;
INSERT INTO `bot_spells_entries` (`npc_spells_id`, `spell_id`, `type`, `minlevel`, `maxlevel`)
VALUES
(3003, 10175, 55, 72, 76),
(3003, 10173, 55, 72, 76),
(3003, 10174, 55, 72, 76),
(3003, 14956, 55, 77, 81),
(3003, 14954, 55, 77, 81),
(3003, 14955, 55, 77, 81),
(3003, 19070, 55, 82, 86),
(3003, 19068, 55, 82, 86),
(3003, 19069, 55, 82, 86),
(3003, 25298, 55, 87, 91),
(3003, 25299, 55, 87, 91),
(3003, 25297, 55, 87, 91),
(3003, 28348, 55, 92, 96),
(3003, 28349, 55, 92, 96),
(3003, 28347, 55, 92, 96),
(3003, 34351, 55, 97, 254),
(3003, 34352, 55, 97, 254),
(3003, 34350, 55, 97, 254),
(3003, 40078, 55, 98, 254),
(3003, 40079, 55, 98, 254),
(3003, 40080, 55, 98, 254),
(3005, 1221, 55, 33, 41),
(3005, 1222, 55, 42, 52),
(3005, 1223, 55, 53, 58),
(3005, 1224, 55, 59, 62),
(3005, 3405, 55, 63, 66),
(3005, 5329, 55, 67, 70),
(3005, 5336, 55, 69, 73),
(3005, 10258, 55, 71, 71),
(3005, 10259, 55, 71, 71),
(3005, 10257, 55, 71, 71),
(3005, 10261, 55, 72, 76),
(3005, 10262, 55, 72, 76),
(3005, 10260, 55, 72, 76),
(3005, 10291, 55, 74, 78),
(3005, 10292, 55, 74, 78),
(3005, 10293, 55, 74, 78),
(3005, 15160, 55, 76, 76),
(3005, 15161, 55, 76, 76),
(3005, 15162, 55, 76, 76),
(3005, 15165, 55, 77, 81),
(3005, 15163, 55, 77, 81),
(3005, 15164, 55, 77, 81),
(3005, 15186, 55, 79, 83),
(3005, 15184, 55, 79, 83),
(3005, 15185, 55, 79, 83),
(3005, 19315, 55, 81, 81),
(3005, 19313, 55, 81, 81),
(3005, 19314, 55, 81, 81),
(3005, 19317, 55, 82, 86),
(3005, 19318, 55, 82, 86),
(3005, 19316, 55, 82, 86),
(3005, 19338, 55, 84, 88),
(3005, 19339, 55, 84, 88),
(3005, 19337, 55, 84, 88),
(3005, 25581, 55, 86, 86),
(3005, 25582, 55, 86, 86),
(3005, 25580, 55, 86, 86),
(3005, 25586, 55, 87, 91),
(3005, 25587, 55, 87, 91),
(3005, 25588, 55, 87, 91),
(3005, 25641, 55, 89, 93),
(3005, 25642, 55, 89, 93),
(3005, 25643, 55, 89, 93),
(3005, 28659, 55, 91, 91),
(3005, 28657, 55, 91, 91),
(3005, 28658, 55, 91, 91),
(3005, 28665, 55, 92, 96),
(3005, 28663, 55, 92, 96),
(3005, 28664, 55, 92, 96),
(3005, 28735, 55, 94, 98),
(3005, 28733, 55, 94, 98),
(3005, 28734, 55, 94, 98),
(3005, 34688, 55, 96, 96),
(3005, 34689, 55, 96, 96),
(3005, 34687, 55, 96, 96),
(3005, 34694, 55, 97, 254),
(3005, 34695, 55, 97, 254),
(3005, 34693, 55, 97, 254),
(3005, 34752, 55, 99, 254),
(3005, 34753, 55, 99, 254),
(3005, 34751, 55, 99, 254);
)"
}
// -- template; copy/paste this when you need to create a new entry
+1
View File
@@ -800,6 +800,7 @@ RULE_INT(Bots, PercentChanceToCastSnare, 75, "The chance for a bot to attempt to
RULE_INT(Bots, PercentChanceToCastDOT, 75, "The chance for a bot to attempt to cast the given spell type in combat. Default 75%.")
RULE_INT(Bots, PercentChanceToCastDispel, 75, "The chance for a bot to attempt to cast the given spell type in combat. Default 75%.")
RULE_INT(Bots, PercentChanceToCastInCombatBuff, 75, "The chance for a bot to attempt to cast the given spell type in combat. Default 75%.")
RULE_INT(Bots, PercentChanceToCastHateLine, 75, "The chance for a bot to attempt to cast the given spell type in combat. Default 75%.")
RULE_INT(Bots, PercentChanceToCastMez, 75, "The chance for a bot to attempt to cast the given spell type in combat. Default 75%.")
RULE_INT(Bots, PercentChanceToCastSlow, 75, "The chance for a bot to attempt to cast the given spell type in combat. Default 75%.")
RULE_INT(Bots, PercentChanceToCastDebuff, 75, "The chance for a bot to attempt to cast the given spell type in combat. Default 75%.")
+42 -25
View File
@@ -2843,13 +2843,8 @@ bool BOT_SPELL_TYPES_DETRIMENTAL(uint16 spellType, uint8 cls) {
case BotSpellTypes::AELifetap:
case BotSpellTypes::PBAENuke:
case BotSpellTypes::Lull:
case BotSpellTypes::HateLine:
return true;
case BotSpellTypes::InCombatBuff:
if (cls == Class::ShadowKnight) {
return true;
}
return false;
default:
return false;
}
@@ -2898,12 +2893,6 @@ bool BOT_SPELL_TYPES_BENEFICIAL(uint16 spellType, uint8 cls) {
case BotSpellTypes::MovementSpeed:
case BotSpellTypes::SendHome:
case BotSpellTypes::SummonCorpse:
return true;
case BotSpellTypes::InCombatBuff:
if (cls == Class::ShadowKnight) {
return false;
}
return true;
default:
return false;
@@ -3134,12 +3123,7 @@ bool SpellTypeRequiresLoS(uint16 spellType, uint16 cls) {
case BotSpellTypes::PetFastHeals:
case BotSpellTypes::PetVeryFastHeals:
case BotSpellTypes::PetHoTHeals:
return false;
case BotSpellTypes::InCombatBuff:
if (cls && cls == Class::ShadowKnight) {
return true;
}
return false;
default:
return true;
@@ -3150,13 +3134,44 @@ bool SpellTypeRequiresLoS(uint16 spellType, uint16 cls) {
bool SpellTypeRequiresTarget(uint16 spellType, uint16 cls) {
switch (spellType) {
case BotSpellTypes::Escape:
if (cls == Class::ShadowKnight) {
return false;
}
return true;
case BotSpellTypes::Pet:
case BotSpellTypes::Succor:
return false;
default:
return true;
}
return true;
}
bool SpellTypeRequiresCastChecks(uint16 spellType) {
switch (spellType) {
case BotSpellTypes::AEDebuff:
case BotSpellTypes::AEDispel:
case BotSpellTypes::AEDoT:
case BotSpellTypes::AEFear:
case BotSpellTypes::AELifetap:
case BotSpellTypes::AEMez:
case BotSpellTypes::AENukes:
case BotSpellTypes::AERains:
case BotSpellTypes::AERoot:
case BotSpellTypes::AESlow:
case BotSpellTypes::AESnare:
case BotSpellTypes::AEStun:
case BotSpellTypes::PBAENuke:
case BotSpellTypes::Mez:
case BotSpellTypes::SummonCorpse:
return false;
default:
return true;
}
return true;
}
bool SpellTypeRequiresAEChecks(uint16 spellType) {
switch (spellType) {
case BotSpellTypes::AEMez:
return false;
default:
return true;
@@ -3263,6 +3278,10 @@ bool IsDamageShieldOnlySpell(uint16 spell_id) {
bool IsCommandedSpellType(uint16 spellType) {
switch (spellType) {
case BotSpellTypes::Charm:
case BotSpellTypes::AEFear:
case BotSpellTypes::Fear:
case BotSpellTypes::Resurrect:
case BotSpellTypes::Lull:
case BotSpellTypes::Teleport:
case BotSpellTypes::Succor:
@@ -3276,8 +3295,6 @@ bool IsCommandedSpellType(uint16 spellType) {
case BotSpellTypes::MovementSpeed:
case BotSpellTypes::SendHome:
case BotSpellTypes::SummonCorpse:
//case BotSpellTypes::Charm:
//case BotSpellTypes::Resurrect:
//case BotSpellTypes::Cure:
//case BotSpellTypes::GroupCures:
//case BotSpellTypes::DamageShields:
+4 -1
View File
@@ -708,6 +708,7 @@ namespace BotSpellTypes
constexpr uint16 ResistBuffs = 52;
constexpr uint16 PetDamageShields = 53;
constexpr uint16 PetResistBuffs = 54;
constexpr uint16 HateLine = 55;
// Command Spell Types
constexpr uint16 Teleport = 100; // this is handled by ^depart so uses other logic
@@ -725,7 +726,7 @@ namespace BotSpellTypes
constexpr uint16 SummonCorpse = 112;
constexpr uint16 START = BotSpellTypes::Nuke; // Do not remove or change this
constexpr uint16 END = BotSpellTypes::PetResistBuffs; // Do not remove this, increment as needed
constexpr uint16 END = BotSpellTypes::HateLine; // Do not remove this, increment as needed
constexpr uint16 COMMANDED_START = BotSpellTypes::Lull; // Do not remove or change this
constexpr uint16 COMMANDED_END = BotSpellTypes::SummonCorpse; // Do not remove this, increment as needed
}
@@ -747,6 +748,8 @@ bool IsClientBotSpellType(uint16 spellType);
bool IsHealBotSpellType(uint16 spellType);
bool SpellTypeRequiresLoS(uint16 spellType, uint16 cls = 0);
bool SpellTypeRequiresTarget(uint16 spellType, uint16 cls = 0);
bool SpellTypeRequiresCastChecks(uint16 spellType);
bool SpellTypeRequiresAEChecks(uint16 spellType);
bool IsCommandedSpellType(uint16 spellType);
// These should not be used to determine spell category..
+1 -1
View File
@@ -43,7 +43,7 @@
*/
#define CURRENT_BINARY_DATABASE_VERSION 9284
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 9050 //TODO update as needed
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 9051 //TODO update as needed
#endif
+177 -111
View File
@@ -5675,9 +5675,7 @@ bool Bot::CastSpell(
casting_spell_id ||
delaytimer ||
spellend_timer.Enabled() ||
IsStunned() ||
IsFeared() ||
IsMezzed() ||
((IsStunned() || IsMezzed() || DivineAura()) && !IsCastNotStandingSpell(spell_id)) ||
(IsSilenced() && !IsDiscipline(spell_id)) ||
(IsAmnesiad() && IsDiscipline(spell_id))
) {
@@ -9414,7 +9412,12 @@ bool Bot::CastChecks(uint16 spell_id, Mob* tar, uint16 spellType, bool doPrechec
if (doPrechecks) {
if (spells[spell_id].target_type == ST_Self && tar != this) {
tar = this;
if (IsEffectInSpell(spell_id, SE_SummonCorpse) && RuleB(Bots, AllowCommandedSummonCorpse)) {
//tar = this;
}
else {
tar = this;
}
}
if (!PrecastChecks(tar, spellType)) {
@@ -9430,11 +9433,30 @@ bool Bot::CastChecks(uint16 spell_id, Mob* tar, uint16 spellType, bool doPrechec
return false;
}
if (spells[spell_id].target_type == ST_Self && tar != this) {
if (IsFeared() || IsSilenced() || IsAmnesiad()) {
LogBotPreChecksDetail("{} says, 'Cancelling cast of {} on {} due to Incapacitated.'", GetCleanName(), GetSpellName(spell_id), tar->GetCleanName()); //deleteme
return false;
}
if ((IsStunned() || IsMezzed() || DivineAura()) && !IsCastNotStandingSpell(spell_id)) {
LogBotPreChecksDetail("{} says, 'Cancelling cast of {} on {} due to !IsCastNotStandingSpell.'", GetCleanName(), GetSpellName(spell_id), tar->GetCleanName()); //deleteme
return false;
}
if (
spells[spell_id].target_type == ST_Self
&& tar != this &&
(spellType != BotSpellTypes::SummonCorpse || RuleB(Bots, AllowCommandedSummonCorpse))
) {
LogBotPreChecksDetail("{} says, 'Cancelling cast of {} on {} due to ST_Self.'", GetCleanName(), GetSpellName(spell_id), tar->GetCleanName()); //deleteme
return false;
}
if (IsDetrimentalSpell(spell_id) && !zone->CanDoCombat()) {
LogBotPreChecksDetail("{} says, 'Cancelling cast of {} on {} due to !CanDoCombat.'", GetCleanName(), GetSpellName(spell_id), tar->GetCleanName()); //deleteme
return false;
}
if (!CheckSpellRecastTimer(spell_id)) {
LogBotPreChecksDetail("{} says, 'Cancelling cast of {} due to !CheckSpellRecastTimer.'", GetCleanName(), GetSpellName(spell_id)); //deleteme
return false;
@@ -9450,6 +9472,42 @@ bool Bot::CastChecks(uint16 spell_id, Mob* tar, uint16 spellType, bool doPrechec
return false;
}
if (this == tar && IsSacrificeSpell(spell_id)) {
LogBotPreChecks("{} says, 'Cancelling cast of {} due to IsSacrificeSpell.'", GetCleanName(), GetSpellName(spell_id)); //deleteme
return false;
}
if (spells[spell_id].caster_requirement_id && !PassCastRestriction(spells[spell_id].caster_requirement_id)) {
LogBotPreChecks("{} says, 'Cancelling cast of {} due to !PassCastRestriction.'", GetCleanName(), GetSpellName(spell_id)); //deleteme
return false;
}
if (!spells[spell_id].can_cast_in_combat && spells[spell_id].can_cast_out_of_combat) {
if (IsBeneficialSpell(spell_id)) {
if (IsEngaged()) {
LogBotPreChecks("{} says, 'Cancelling cast of {} due to !can_cast_in_combat.'", GetCleanName(), GetSpellName(spell_id)); //deleteme
return false;
}
}
}
else if (spells[spell_id].can_cast_in_combat && !spells[spell_id].can_cast_out_of_combat) {
if (IsBeneficialSpell(spell_id)) {
if (!IsEngaged()) {
LogBotPreChecks("{} says, 'Cancelling cast of {} due to !can_cast_out_of_combat.'", GetCleanName(), GetSpellName(spell_id)); //deleteme
return false;
}
}
}
if (!IsDiscipline(spell_id)) {
int chance = GetFocusEffect(focusFcMute, spell_id);
if (chance && zone->random.Roll(chance)) {
LogBotPreChecks("{} says, 'Cancelling cast of {} due to focusFcMute.'", GetCleanName(), GetSpellName(spell_id)); //deleteme
return(false);
}
}
if (!zone->CanLevitate() && IsEffectInSpell(spell_id, SE_Levitate)) {
LogBotPreChecks("{} says, 'Cancelling cast of {} due to !CanLevitate.'", GetCleanName(), GetSpellName(spell_id)); //deleteme
return false;
@@ -9534,6 +9592,7 @@ bool Bot::CanCastSpellType(uint16 spellType, uint16 spell_id, Mob* tar) {
case BotSpellTypes::Buff:
case BotSpellTypes::PetBuffs:
case BotSpellTypes::PreCombatBuff:
case BotSpellTypes::InCombatBuff:
case BotSpellTypes::DamageShields:
case BotSpellTypes::PetDamageShields:
case BotSpellTypes::ResistBuffs:
@@ -9567,6 +9626,11 @@ bool Bot::CanCastSpellType(uint16 spellType, uint16 spell_id, Mob* tar) {
return false;
}
if (!tar->CheckSpellLevelRestriction(this, spell_id)) {
LogBotPreChecks("{} says, 'Cancelling cast of {} on {} due to CheckSpellLevelRestriction.'", GetCleanName(), GetSpellName(spell_id), tar->GetCleanName()); //deleteme
return false;
}
if ((spellType != BotSpellTypes::Teleport && spellType != BotSpellTypes::Succor) && (IsEffectInSpell(spell_id, SE_Teleport) || IsEffectInSpell(spell_id, SE_Succor))) {
LogBotPreChecks("{} says, 'Cancelling cast of {} on {} due to Teleport.'", GetCleanName(), GetSpellName(spell_id), tar->GetCleanName()); //deleteme
return false;
@@ -9679,6 +9743,13 @@ bool Bot::CanCastSpellType(uint16 spellType, uint16 spell_id, Mob* tar) {
}
}
break;
case BotSpellTypes::Lull:
if (IsHarmonySpell(spell_id) && !HarmonySpellLevelCheck(spell_id, tar)) {
LogBotPreChecksDetail("{} says, 'Cancelling cast of {} on {} due to HarmonySpellLevelCheck.'", GetCleanName(), GetSpellName(spell_id), tar->GetCleanName()); //deleteme
return false;
}
break;
default:
break;
@@ -10505,50 +10576,48 @@ uint16 Bot::GetDefaultSpellTypeEngagedPriority(uint16 spellType, uint8 botClass,
return 20;
case BotSpellTypes::Mez:
return 21;
case BotSpellTypes::AEDispel:
case BotSpellTypes::HateLine:
return 22;
case BotSpellTypes::Dispel:
case BotSpellTypes::AEDispel:
return 23;
case BotSpellTypes::AEDebuff:
case BotSpellTypes::Dispel:
return 24;
case BotSpellTypes::Debuff:
case BotSpellTypes::AEDebuff:
return 25;
case BotSpellTypes::AESnare:
case BotSpellTypes::Debuff:
return 26;
case BotSpellTypes::Snare:
case BotSpellTypes::AESnare:
return 27;
case BotSpellTypes::AEFear:
case BotSpellTypes::Snare:
return 28;
case BotSpellTypes::Fear:
return 29;
case BotSpellTypes::AESlow:
return 30;
return 29;
case BotSpellTypes::Slow:
return 31;
return 30;
case BotSpellTypes::AERoot:
return 32;
return 31;
case BotSpellTypes::Root:
return 33;
return 32;
case BotSpellTypes::AEDoT:
return 34;
return 33;
case BotSpellTypes::DOT:
return 35;
return 34;
case BotSpellTypes::AEStun:
return 36;
return 35;
case BotSpellTypes::PBAENuke:
return 37;
return 36;
case BotSpellTypes::AENukes:
return 38;
return 37;
case BotSpellTypes::AERains:
return 39;
return 38;
case BotSpellTypes::Stun:
return 40;
return 39;
case BotSpellTypes::Nuke:
return 41;
return 40;
case BotSpellTypes::InCombatBuff:
return 42;
return 41;
case BotSpellTypes::InCombatBuffSong:
return 43;
return 42;
default:
return 0;
}
@@ -10915,8 +10984,6 @@ uint16 Bot::GetSpellListSpellType(uint16 spellType) {
case BotSpellTypes::PetDamageShields:
case BotSpellTypes::ResistBuffs:
case BotSpellTypes::PetResistBuffs:
case BotSpellTypes::Teleport:
case BotSpellTypes::Succor:
case BotSpellTypes::BindAffinity:
case BotSpellTypes::Identify:
case BotSpellTypes::Levitate:
@@ -10925,8 +10992,6 @@ uint16 Bot::GetSpellListSpellType(uint16 spellType) {
case BotSpellTypes::Size:
case BotSpellTypes::Invisibility:
case BotSpellTypes::MovementSpeed:
case BotSpellTypes::SendHome:
case BotSpellTypes::SummonCorpse:
return BotSpellTypes::Buff;
case BotSpellTypes::AEMez:
case BotSpellTypes::Mez:
@@ -10961,6 +11026,7 @@ uint16 Bot::GetSpellListSpellType(uint16 spellType) {
case BotSpellTypes::Charm:
case BotSpellTypes::Escape:
case BotSpellTypes::HateRedux:
case BotSpellTypes::HateLine:
case BotSpellTypes::InCombatBuff:
case BotSpellTypes::InCombatBuffSong:
case BotSpellTypes::OutOfCombatBuffSong:
@@ -11032,84 +11098,84 @@ bool Bot::IsValidSpellTypeBySpellID(uint16 spellType, uint16 spell_id) {
}
return false;
case BotSpellTypes::Lull:
if (!IsHarmonySpell(spell_id)) {
return true;
}
return false;
case BotSpellTypes::Teleport:
if (IsBeneficialSpell(spell_id) && (IsEffectInSpell(spell_id, SE_Teleport) || IsEffectInSpell(spell_id, SE_Translocate))) {
return true;
}
return false;
case BotSpellTypes::Succor:
if (IsBeneficialSpell(spell_id) && IsEffectInSpell(spell_id, SE_Succor)) {
return true;
}
return false;
case BotSpellTypes::BindAffinity:
if (IsEffectInSpell(spell_id, SE_BindAffinity)) {
return true;
}
return false;
case BotSpellTypes::Identify:
if (IsEffectInSpell(spell_id, SE_Identify)) {
return true;
}
return false;
case BotSpellTypes::Levitate:
if (IsBeneficialSpell(spell_id) && (IsEffectInSpell(spell_id, SE_Levitate))) {
return true;
}
return false;
case BotSpellTypes::Rune:
if (IsEffectInSpell(spell_id, SE_AbsorbMagicAtt) || IsEffectInSpell(spell_id, SE_Rune)) {
return true;
}
return false;
case BotSpellTypes::WaterBreathing:
if (IsEffectInSpell(spell_id, SE_WaterBreathing)) {
return true;
}
return false;
case BotSpellTypes::Size:
if (IsBeneficialSpell(spell_id) && (IsEffectInSpell(spell_id, SE_ModelSize) || IsEffectInSpell(spell_id, SE_ChangeHeight))) {
return true;
}
return false;
case BotSpellTypes::Invisibility:
if (IsEffectInSpell(spell_id, SE_SeeInvis) || IsInvisibleSpell(spell_id)) {
return true;
}
return false;
case BotSpellTypes::MovementSpeed:
if (IsBeneficialSpell(spell_id) && IsEffectInSpell(spell_id, SE_MovementSpeed)) {
return true;
}
return false;
case BotSpellTypes::SendHome:
if (IsBeneficialSpell(spell_id) && IsEffectInSpell(spell_id, SE_GateToHomeCity)) {
return true;
}
return false;
case BotSpellTypes::SummonCorpse:
if (IsEffectInSpell(spell_id, SE_SummonCorpse)) {
return true;
}
return false;
//case BotSpellTypes::Lull:
// if (IsHarmonySpell(spell_id)) {
// return true;
// }
//
// return false;
//case BotSpellTypes::Teleport:
// if (IsBeneficialSpell(spell_id) && (IsEffectInSpell(spell_id, SE_Teleport) || IsEffectInSpell(spell_id, SE_Translocate))) {
// return true;
// }
//
// return false;
//case BotSpellTypes::Succor:
// if (IsBeneficialSpell(spell_id) && IsEffectInSpell(spell_id, SE_Succor)) {
// return true;
// }
//
// return false;
//case BotSpellTypes::BindAffinity:
// if (IsEffectInSpell(spell_id, SE_BindAffinity)) {
// return true;
// }
//
// return false;
//case BotSpellTypes::Identify:
// if (IsEffectInSpell(spell_id, SE_Identify)) {
// return true;
// }
//
// return false;
//case BotSpellTypes::Levitate:
// if (IsBeneficialSpell(spell_id) && (IsEffectInSpell(spell_id, SE_Levitate))) {
// return true;
// }
//
// return false;
//case BotSpellTypes::Rune:
// if (IsEffectInSpell(spell_id, SE_AbsorbMagicAtt) || IsEffectInSpell(spell_id, SE_Rune)) {
// return true;
// }
//
// return false;
//case BotSpellTypes::WaterBreathing:
// if (IsEffectInSpell(spell_id, SE_WaterBreathing)) {
// return true;
// }
//
// return false;
//case BotSpellTypes::Size:
// if (IsBeneficialSpell(spell_id) && (IsEffectInSpell(spell_id, SE_ModelSize) || IsEffectInSpell(spell_id, SE_ChangeHeight))) {
// return true;
// }
//
// return false;
//case BotSpellTypes::Invisibility:
// if (IsEffectInSpell(spell_id, SE_SeeInvis) || IsInvisibleSpell(spell_id)) {
// return true;
// }
//
// return false;
//case BotSpellTypes::MovementSpeed:
// if (IsBeneficialSpell(spell_id) && IsEffectInSpell(spell_id, SE_MovementSpeed)) {
// return true;
// }
//
// return false;
//case BotSpellTypes::SendHome:
// if (IsBeneficialSpell(spell_id) && IsEffectInSpell(spell_id, SE_GateToHomeCity)) {
// return true;
// }
//
// return false;
//case BotSpellTypes::SummonCorpse:
// if (IsEffectInSpell(spell_id, SE_SummonCorpse)) {
// return true;
// }
//
// return false;
default:
return true;
}
@@ -11342,7 +11408,7 @@ bool Bot::HasValidAETarget(Bot* botCaster, uint16 spell_id, uint16 spellType, Mo
break;
}
if (!m->IsNPC() || !m->CastToNPC()->IsOnHatelist(botCaster->GetOwner())) {
if (!m->IsNPC() || (!IsCommandedSpell() && !m->CastToNPC()->IsOnHatelist(botCaster->GetOwner()))) {
continue;
}
+17 -9
View File
@@ -308,7 +308,7 @@ void bot_command_cast(Client* c, const Seperator* sep)
}
Mob* tar = c->GetTarget();
LogTestDebug("{}: 'Attempting {} [{}] on {}'", __LINE__, c->GetSpellTypeNameByID(spellType), (subType != UINT16_MAX ? c->GetSubTypeNameByID(subType) : "Standard"), (tar ? tar->GetCleanName() : "NOBODY")); //deleteme
//LogTestDebug("{}: 'Attempting {} [{}-{}] on {}'", __LINE__, c->GetSpellTypeNameByID(spellType), (subType != UINT16_MAX ? c->GetSubTypeNameByID(subType) : "Standard"), (subTargetType != UINT16_MAX ? c->GetSubTypeNameByID(subTargetType) : "Standard"), (tar ? tar->GetCleanName() : "NOBODY")); //deleteme
if (!tar) {
if (spellType != BotSpellTypes::Escape && spellType != BotSpellTypes::Pet) {
@@ -338,7 +338,17 @@ void bot_command_cast(Client* c, const Seperator* sep)
break;
default:
if (BOT_SPELL_TYPES_DETRIMENTAL(spellType) && !c->IsAttackAllowed(tar)) {
if (
(BOT_SPELL_TYPES_DETRIMENTAL(spellType) && !c->IsAttackAllowed(tar)) ||
(
spellType == BotSpellTypes::Charm &&
(
tar->IsClient() ||
tar->IsCorpse() ||
tar->GetOwner()
)
)
) {
c->Message(Chat::Yellow, "You cannot attack [%s].", tar->GetCleanName());
return;
@@ -395,18 +405,16 @@ void bot_command_cast(Client* c, const Seperator* sep)
/*
TODO bot rewrite -
FIX: Depart, SummonCorpse, Lull,
Group Cures, Precombat, Fear/AE Fear
ICB (SK) casting hate on friendly but not hostile?
FIX: Depart
Group Cures, Precombat
NEED TO CHECK: precombat, AE Dispel, AE Lifetap
DO I NEED A PBAE CHECK???
*/
if (bot_iter->GetBotStance() == Stance::Passive || bot_iter->GetHoldFlag() || bot_iter->GetAppearance() == eaDead || bot_iter->IsFeared() || bot_iter->IsStunned() || bot_iter->IsMezzed() || bot_iter->DivineAura() || bot_iter->GetHP() < 0) {
if (bot_iter->GetBotStance() == Stance::Passive || bot_iter->GetHoldFlag() || bot_iter->GetAppearance() == eaDead || bot_iter->IsFeared() || bot_iter->IsSilenced() || bot_iter->IsAmnesiad() || bot_iter->GetHP() < 0) {
continue;
}
Mob* newTar = tar;
LogTestDebug("{}: {} says, 'Attempting {} [{}] on {}'", __LINE__, bot_iter->GetCleanName(), c->GetSpellTypeNameByID(spellType), (subType != UINT16_MAX ? c->GetSubTypeNameByID(subType) : "Standard"), (newTar ? newTar->GetCleanName() : "NOBODY")); //deleteme
//LogTestDebug("{}: {} says, 'Attempting {} [{}-{}] on {}'", __LINE__, bot_iter->GetCleanName(), c->GetSpellTypeNameByID(spellType), (subType != UINT16_MAX ? c->GetSubTypeNameByID(subType) : "Standard"), (subTargetType != UINT16_MAX ? c->GetSubTypeNameByID(subTargetType) : "Standard"), (newTar ? newTar->GetCleanName() : "NOBODY")); //deleteme
if (!SpellTypeRequiresTarget(spellType, bot_iter->GetClass())) {
newTar = bot_iter;
}
@@ -435,7 +443,7 @@ void bot_command_cast(Client* c, const Seperator* sep)
continue;
}
LogTestDebug("{}: {} says, 'Attempting {} [{}] on {}'", __LINE__, bot_iter->GetCleanName(), c->GetSpellTypeNameByID(spellType), (subType != UINT16_MAX ? c->GetSubTypeNameByID(subType) : "Standard"), (newTar ? newTar->GetCleanName() : "NOBODY")); //deleteme
LogTestDebug("{}: {} says, 'Attempting {} [{}-{}] on {}'", __LINE__, bot_iter->GetCleanName(), c->GetSpellTypeNameByID(spellType), (subType != UINT16_MAX ? c->GetSubTypeNameByID(subType) : "Standard"), (subTargetType != UINT16_MAX ? c->GetSubTypeNameByID(subTargetType) : "Standard"), (newTar ? newTar->GetCleanName() : "NOBODY")); //deleteme
bot_iter->SetCommandedSpell(true);
+174 -67
View File
@@ -116,11 +116,13 @@ bool Bot::AICastSpell(Mob* tar, uint8 iChance, uint16 spellType, uint16 subTarge
break;
case BotSpellTypes::InCombatBuff:
if (GetClass() == Class::ShadowKnight && (tar->IsOfClientBot() || (tar->IsPet() && tar->GetOwner() && tar->GetOwner()->IsOfClientBot()))) {
if (!IsCommandedSpell() && GetClass() != Class::Shaman && spellType == BotSpellTypes::InCombatBuff && IsCasterClass(GetClass()) && GetLevel() >= GetStopMeleeLevel()) {
return false;
}
if (!IsCommandedSpell() && GetClass() != Class::Shaman && spellType == BotSpellTypes::InCombatBuff && IsCasterClass(GetClass()) && GetLevel() >= GetStopMeleeLevel()) {
break;
case BotSpellTypes::HateLine:
if (!tar->IsNPC()) {
return false;
}
@@ -198,7 +200,6 @@ bool Bot::AICastSpell(Mob* tar, uint8 iChance, uint16 spellType, uint16 subTarge
return BotCastPet(tar, botClass, botSpell, spellType);
case BotSpellTypes::Resurrect:
case BotSpellTypes::SummonCorpse:
if (!tar->IsCorpse() || !tar->CastToCorpse()->IsPlayerCorpse()) {
return false;
}
@@ -267,6 +268,7 @@ bool Bot::AICastSpell(Mob* tar, uint8 iChance, uint16 spellType, uint16 subTarge
return true;
}
else { LogTestDebug("{} says, '{} [#{}] - [{}] FAILED AIDoSpellCast on {}.'", GetCleanName(), spells[s.SpellId].name, s.SpellId, GetSpellTypeNameByID(spellType), tar->GetCleanName()); } //deleteme
}
return false;
@@ -631,7 +633,7 @@ bool Bot::AIDoSpellCast(int32 i, Mob* tar, int32 mana_cost, uint32* oDontDoAgain
}
bool Bot::AI_PursueCastCheck() {
if (GetAppearance() == eaDead || IsFeared() || IsStunned() || IsMezzed() || DivineAura() || GetHP() < 0) {
if (GetAppearance() == eaDead || IsFeared() || IsSilenced() || IsAmnesiad() || GetHP() < 0) {
return false;
}
@@ -656,11 +658,11 @@ bool Bot::AI_PursueCastCheck() {
continue;
}
if (RuleB(Bots, AllowAIMez) && (currentCast.spellType == BotSpellTypes::AEMez || currentCast.spellType == BotSpellTypes::Mez)) {
if (!RuleB(Bots, AllowAIMez) && (currentCast.spellType == BotSpellTypes::AEMez || currentCast.spellType == BotSpellTypes::Mez)) {
continue;
}
if (IsCommandedSpellType(currentCast.spellType) || currentCast.spellType == BotSpellTypes::Resurrect || currentCast.spellType == BotSpellTypes::Charm) { // Unsupported by AI currently.
if (IsCommandedSpellType(currentCast.spellType)) { // Unsupported by AI currently.
continue;
}
@@ -680,7 +682,7 @@ bool Bot::AI_PursueCastCheck() {
}
bool Bot::AI_IdleCastCheck() {
if (GetAppearance() == eaDead || IsFeared() || IsStunned() || IsMezzed() || DivineAura() || GetHP() < 0) {
if (GetAppearance() == eaDead || IsFeared() || IsSilenced() || IsAmnesiad() || GetHP() < 0) {
return false;
}
@@ -719,11 +721,11 @@ bool Bot::AI_IdleCastCheck() {
continue;
}
if (RuleB(Bots, AllowAIMez) && (currentCast.spellType == BotSpellTypes::AEMez || currentCast.spellType == BotSpellTypes::Mez)) {
if (!RuleB(Bots, AllowAIMez) && (currentCast.spellType == BotSpellTypes::AEMez || currentCast.spellType == BotSpellTypes::Mez)) {
continue;
}
if (IsCommandedSpellType(currentCast.spellType) || currentCast.spellType == BotSpellTypes::Resurrect || currentCast.spellType == BotSpellTypes::Charm) { // Unsupported by AI currently.
if (IsCommandedSpellType(currentCast.spellType)) { // Unsupported by AI currently.
continue;
}
@@ -743,7 +745,7 @@ bool Bot::AI_IdleCastCheck() {
}
bool Bot::AI_EngagedCastCheck() {
if (GetAppearance() == eaDead || IsFeared() || IsStunned() || IsMezzed() || DivineAura() || GetHP() < 0) {
if (GetAppearance() == eaDead || IsFeared() || IsSilenced() || IsAmnesiad() || GetHP() < 0) {
return false;
}
@@ -769,11 +771,11 @@ bool Bot::AI_EngagedCastCheck() {
continue;
}
if (RuleB(Bots, AllowAIMez) && (currentCast.spellType == BotSpellTypes::AEMez || currentCast.spellType == BotSpellTypes::Mez)) {
if (!RuleB(Bots, AllowAIMez) && (currentCast.spellType == BotSpellTypes::AEMez || currentCast.spellType == BotSpellTypes::Mez)) {
continue;
}
if (IsCommandedSpellType(currentCast.spellType) || currentCast.spellType == BotSpellTypes::Resurrect || currentCast.spellType == BotSpellTypes::Charm) { // Unsupported by AI currently.
if (IsCommandedSpellType(currentCast.spellType)) { // Unsupported by AI currently.
continue;
}
@@ -1045,28 +1047,19 @@ std::list<BotSpell_wPriority> Bot::GetPrioritizedBotSpellsBySpellType(Bot* botCa
}
if (
(
!botCaster->IsCommandedSpell() ||
(
botCaster->IsCommandedSpell() &&
(spellType != BotSpellTypes::Mez && spellType != BotSpellTypes::AEMez)
)
)
&&
(
!IsPBAESpell(botSpellList[i].spellid) &&
!botCaster->CastChecks(botSpellList[i].spellid, tar, spellType, false, IsAEBotSpellType(spellType))
)
(!botCaster->IsCommandedSpell() || (botCaster->IsCommandedSpell() && SpellTypeRequiresCastChecks(spellType))) &&
(!IsPBAESpell(botSpellList[i].spellid) && !botCaster->CastChecks(botSpellList[i].spellid, tar, spellType, false, IsAEBotSpellType(spellType)))
) {
continue;
}
if (
botCaster->IsCommandedSpell() ||
botCaster->IsCommandedSpell() ||
!AE ||
(spellType == BotSpellTypes::GroupCures) ||
(spellType == BotSpellTypes::AEMez) ||
(AE && botCaster->HasValidAETarget(botCaster, botSpellList[i].spellid, spellType, tar))
(
SpellTypeRequiresAEChecks(spellType) &&
botCaster->HasValidAETarget(botCaster, botSpellList[i].spellid, spellType, tar)
)
) {
BotSpell_wPriority botSpell;
botSpell.SpellId = botSpellList[i].spellid;
@@ -2099,18 +2092,6 @@ uint8 Bot::GetChanceToCastBySpellType(uint16 spellType)
case BotSpellTypes::PetResistBuffs:
case BotSpellTypes::DamageShields:
case BotSpellTypes::PetDamageShields:
case BotSpellTypes::Teleport:
case BotSpellTypes::Succor:
case BotSpellTypes::BindAffinity:
case BotSpellTypes::Identify:
case BotSpellTypes::Levitate:
case BotSpellTypes::Rune:
case BotSpellTypes::WaterBreathing:
case BotSpellTypes::Size:
case BotSpellTypes::Invisibility:
case BotSpellTypes::MovementSpeed:
case BotSpellTypes::SendHome:
case BotSpellTypes::SummonCorpse:
return RuleI(Bots, PercentChanceToCastBuff);
case BotSpellTypes::Escape:
return RuleI(Bots, PercentChanceToCastEscape);
@@ -2124,6 +2105,8 @@ uint8 Bot::GetChanceToCastBySpellType(uint16 spellType)
return RuleI(Bots, PercentChanceToCastDispel);
case BotSpellTypes::InCombatBuff:
return RuleI(Bots, PercentChanceToCastInCombatBuff);
case BotSpellTypes::HateLine:
return RuleI(Bots, PercentChanceToCastHateLine);
case BotSpellTypes::Mez:
return RuleI(Bots, PercentChanceToCastMez);
case BotSpellTypes::Slow:
@@ -2842,65 +2825,71 @@ void Bot::CheckBotSpells() {
switch (s.type) {
case BotSpellTypes::Nuke: //DONE
case BotSpellTypes::Nuke:
if (IsAnyNukeOrStunSpell(spell_id) && !IsEffectInSpell(spell_id, SE_Root) && !IsDebuffSpell(spell_id)) {
valid = true;
break;
}
break;
case BotSpellTypes::RegularHeal: //DONE
//if (IsAnyHealSpell(spell_id) && !IsEscapeSpell(spell_id) && (IsRegularPetHealSpell(spell_id) || !IsCureSpell(spell_id))) {
case BotSpellTypes::RegularHeal:
if (IsAnyHealSpell(spell_id) && !IsEscapeSpell(spell_id)) {
valid = true;
break;
}
break;
case BotSpellTypes::Root: //DONE
case BotSpellTypes::Root:
if (IsEffectInSpell(spell_id, SE_Root)) {
valid = true;
break;
}
break;
case BotSpellTypes::Buff: //DONE
case BotSpellTypes::Buff:
if (IsAnyBuffSpell(spell_id)) {
valid = true;
break;
}
break;
case BotSpellTypes::Pet: //DONE
case BotSpellTypes::Pet:
if (IsSummonPetSpell(spell_id) || IsEffectInSpell(spell_id, SE_TemporaryPets)) {
valid = true;
break;
}
break;
case BotSpellTypes::Lifetap: //DONE
case BotSpellTypes::Lifetap:
if (IsLifetapSpell(spell_id)) {
valid = true;
break;
}
break;
case BotSpellTypes::Snare: //DONE
case BotSpellTypes::Snare:
if (IsEffectInSpell(spell_id, SE_MovementSpeed) && IsDetrimentalSpell(spell_id)) {
valid = true;
break;
}
break;
case BotSpellTypes::DOT: //DONE
case BotSpellTypes::DOT:
if (IsStackableDOT(spell_id) || IsDamageOverTimeSpell(spell_id)) {
valid = true;
break;
}
break;
case BotSpellTypes::Dispel: //DONE
case BotSpellTypes::Dispel:
if (IsDispelSpell(spell_id)) {
valid = true;
break;
}
break;
case BotSpellTypes::InCombatBuff: //DONE
case BotSpellTypes::InCombatBuff:
if (
IsSelfConversionSpell(spell_id) ||
IsAnyBuffSpell(spell_id) ||
IsAnyBuffSpell(spell_id)
) {
valid = true;
break;
}
break;
case BotSpellTypes::HateLine:
if (
(IsEffectInSpell(spell_id, SE_Hate) && spells[spell_id].base_value[GetSpellEffectIndex(spell_id, SE_Hate)] > 0) ||
(IsEffectInSpell(spell_id, SE_InstantHate) && spells[spell_id].base_value[GetSpellEffectIndex(spell_id, SE_InstantHate)] > 0)
) {
@@ -2908,37 +2897,37 @@ void Bot::CheckBotSpells() {
break;
}
break;
case BotSpellTypes::Mez: //DONE
case BotSpellTypes::Mez:
if (IsMesmerizeSpell(spell_id)) {
valid = true;
break;
}
break;
case BotSpellTypes::Charm: //DONE
case BotSpellTypes::Charm:
if (IsCharmSpell(spell_id)) {
valid = true;
break;
}
break;
case BotSpellTypes::Slow: //DONE
case BotSpellTypes::Slow:
if (IsSlowSpell(spell_id)) {
valid = true;
break;
}
break;
case BotSpellTypes::Debuff: //DONE
case BotSpellTypes::Debuff:
if (IsDebuffSpell(spell_id) && !IsEscapeSpell(spell_id) && !IsHateReduxSpell(spell_id)) {
valid = true;
break;
}
break;
case BotSpellTypes::Cure: //DONE
case BotSpellTypes::Cure:
if (IsCureSpell(spell_id)) {
valid = true;
break;
}
break;
case BotSpellTypes::PreCombatBuff: //DONE
case BotSpellTypes::PreCombatBuff:
if (
IsBuffSpell(spell_id) &&
IsBeneficialSpell(spell_id) &&
@@ -2950,9 +2939,9 @@ void Bot::CheckBotSpells() {
break;
}
break;
case BotSpellTypes::InCombatBuffSong: //DONE
case BotSpellTypes::OutOfCombatBuffSong: //DONE
case BotSpellTypes::PreCombatBuffSong: //DONE
case BotSpellTypes::InCombatBuffSong:
case BotSpellTypes::OutOfCombatBuffSong:
case BotSpellTypes::PreCombatBuffSong:
if (
IsBuffSpell(spell_id) &&
IsBeneficialSpell(spell_id) &&
@@ -2964,7 +2953,7 @@ void Bot::CheckBotSpells() {
break;
}
break;
case BotSpellTypes::Fear: //DONE
case BotSpellTypes::Fear:
if (IsFearSpell(spell_id)) {
valid = true;
break;
@@ -2988,7 +2977,84 @@ void Bot::CheckBotSpells() {
break;
}
break;
//TODO bot rewrite - add commanded types
case BotSpellTypes::Lull:
if (IsHarmonySpell(spell_id)) {
valid = true;
break;
}
break;
case BotSpellTypes::Teleport:
if (IsBeneficialSpell(spell_id) && (IsEffectInSpell(spell_id, SE_Teleport) || IsEffectInSpell(spell_id, SE_Translocate))) {
valid = true;
break;
}
break;
case BotSpellTypes::Succor:
if (IsBeneficialSpell(spell_id) && IsEffectInSpell(spell_id, SE_Succor)) {
valid = true;
break;
}
break;
case BotSpellTypes::BindAffinity:
if (IsEffectInSpell(spell_id, SE_BindAffinity)) {
valid = true;
break;
}
break;
case BotSpellTypes::Identify:
if (IsEffectInSpell(spell_id, SE_Identify)) {
valid = true;
break;
}
break;
case BotSpellTypes::Levitate:
if (IsBeneficialSpell(spell_id) && (IsEffectInSpell(spell_id, SE_Levitate))) {
valid = true;
break;
}
break;
case BotSpellTypes::Rune:
if (IsBeneficialSpell(spell_id) && IsEffectInSpell(spell_id, SE_AbsorbMagicAtt) || IsEffectInSpell(spell_id, SE_Rune)) {
valid = true;
break;
}
break;
case BotSpellTypes::WaterBreathing:
if (IsBeneficialSpell(spell_id) && IsEffectInSpell(spell_id, SE_WaterBreathing)) {
valid = true;
break;
}
break;
case BotSpellTypes::Size:
if (IsBeneficialSpell(spell_id) && (IsEffectInSpell(spell_id, SE_ModelSize) || IsEffectInSpell(spell_id, SE_ChangeHeight))) {
valid = true;
break;
}
break;
case BotSpellTypes::Invisibility:
if (IsBeneficialSpell(spell_id) && IsEffectInSpell(spell_id, SE_SeeInvis) || IsInvisibleSpell(spell_id)) {
valid = true;
break;
}
break;
case BotSpellTypes::MovementSpeed:
if (IsBeneficialSpell(spell_id) && IsEffectInSpell(spell_id, SE_MovementSpeed)) {
valid = true;
break;
}
break;
case BotSpellTypes::SendHome:
if (IsBeneficialSpell(spell_id) && IsEffectInSpell(spell_id, SE_GateToHomeCity)) {
valid = true;
break;
}
break;
case BotSpellTypes::SummonCorpse:
if (IsEffectInSpell(spell_id, SE_SummonCorpse)) {
valid = true;
break;
}
break;
default:
break;
@@ -2997,7 +3063,6 @@ void Bot::CheckBotSpells() {
if (IsAnyNukeOrStunSpell(spell_id) && !IsEffectInSpell(spell_id, SE_Root) && !IsDebuffSpell(spell_id)) {
correctType = BotSpellTypes::Nuke;
}
//else if (IsAnyHealSpell(spell_id) && !IsEscapeSpell(spell_id) && (IsRegularPetHealSpell(spell_id) || !IsCureSpell(spell_id))) {
else if (IsAnyHealSpell(spell_id) && !IsEscapeSpell(spell_id)) {
correctType = BotSpellTypes::RegularHeal;
}
@@ -3024,11 +3089,15 @@ void Bot::CheckBotSpells() {
}
else if (
IsSelfConversionSpell(spell_id) ||
IsAnyBuffSpell(spell_id) ||
IsAnyBuffSpell(spell_id)
) {
correctType = BotSpellTypes::InCombatBuff;
}
else if (
(IsEffectInSpell(spell_id, SE_Hate) && spells[spell_id].base_value[GetSpellEffectIndex(spell_id, SE_Hate)] > 0) ||
(IsEffectInSpell(spell_id, SE_InstantHate) && spells[spell_id].base_value[GetSpellEffectIndex(spell_id, SE_InstantHate)] > 0)
) {
correctType = BotSpellTypes::InCombatBuff;
correctType = BotSpellTypes::HateLine;
}
else if (IsMesmerizeSpell(spell_id)) {
correctType = BotSpellTypes::Mez;
@@ -3084,7 +3153,45 @@ void Bot::CheckBotSpells() {
else if (IsEffectInSpell(spell_id, SE_Revive)) {
correctType = BotSpellTypes::Resurrect;
}
//TODO bot rewrite - add commanded types
else if (IsHarmonySpell(spell_id)) {
correctType = BotSpellTypes::Lull;
}
else if (IsBeneficialSpell(spell_id) && (IsEffectInSpell(spell_id, SE_Teleport) || IsEffectInSpell(spell_id, SE_Translocate))) {
correctType = BotSpellTypes::Teleport;
}
else if (IsBeneficialSpell(spell_id) && IsEffectInSpell(spell_id, SE_Succor)) {
correctType = BotSpellTypes::Succor;
}
else if (IsEffectInSpell(spell_id, SE_BindAffinity)) {
correctType = BotSpellTypes::BindAffinity;
}
else if (IsEffectInSpell(spell_id, SE_Identify)) {
correctType = BotSpellTypes::Identify;
}
else if (IsBeneficialSpell(spell_id) && (IsEffectInSpell(spell_id, SE_Levitate))) {
correctType = BotSpellTypes::Levitate;
}
else if (IsBeneficialSpell(spell_id) && IsEffectInSpell(spell_id, SE_AbsorbMagicAtt) || IsEffectInSpell(spell_id, SE_Rune)) {
correctType = BotSpellTypes::Rune;
}
else if (IsBeneficialSpell(spell_id) && IsEffectInSpell(spell_id, SE_WaterBreathing)) {
correctType = BotSpellTypes::WaterBreathing;
}
else if (IsBeneficialSpell(spell_id) && (IsEffectInSpell(spell_id, SE_ModelSize) || IsEffectInSpell(spell_id, SE_ChangeHeight))) {
correctType = BotSpellTypes::Size;
}
else if (IsBeneficialSpell(spell_id) && IsEffectInSpell(spell_id, SE_SeeInvis) || IsInvisibleSpell(spell_id)) {
correctType = BotSpellTypes::Invisibility;
}
else if (IsBeneficialSpell(spell_id) && IsEffectInSpell(spell_id, SE_MovementSpeed)) {
correctType = BotSpellTypes::MovementSpeed;
}
else if (IsBeneficialSpell(spell_id) && IsEffectInSpell(spell_id, SE_GateToHomeCity)) {
correctType = BotSpellTypes::SendHome;
}
else if (IsEffectInSpell(spell_id, SE_SummonCorpse)) {
correctType = BotSpellTypes::SummonCorpse;
}
if (!valid || (correctType == UINT16_MAX) || (s.type != correctType)) {
LogBotSpellTypeChecks("{} [#{}] is incorrect. It is currently set as {} [#{}] and should be {} [#{}]"
+60 -6
View File
@@ -8898,6 +8898,9 @@ std::string Mob::GetSpellTypeNameByID(uint16 spellType) {
case BotSpellTypes::PetResistBuffs:
spellTypeName = "Pet Resist Buff";
break;
case BotSpellTypes::HateLine:
spellTypeName = "Hate Line";
break;
case BotSpellTypes::Lull:
spellTypeName = "Lull";
break;
@@ -9113,6 +9116,9 @@ std::string Mob::GetSpellTypeShortNameByID(uint16 spellType) {
case BotSpellTypes::PetResistBuffs:
spellTypeName = "petresistbuffs";
break;
case BotSpellTypes::HateLine:
spellTypeName = "hateline";
break;
case BotSpellTypes::Lull:
spellTypeName = "lull";
break;
@@ -9231,8 +9237,11 @@ bool Mob::GetDefaultSpellHold(uint16 spellType, uint8 stance) {
case BotSpellTypes::AEFear:
case BotSpellTypes::Fear:
return true;
case BotSpellTypes::Mez:
case BotSpellTypes::AEMez:
case BotSpellTypes::Debuff:
case BotSpellTypes::AEDebuff:
case BotSpellTypes::Slow:
case BotSpellTypes::AESlow:
case BotSpellTypes::HateRedux:
switch (stance) {
@@ -9249,12 +9258,7 @@ bool Mob::GetDefaultSpellHold(uint16 spellType, uint8 stance) {
case Stance::Assist:
return true;
default:
if (GetClass() == Class::Wizard) {
return true;
}
else {
return false;
}
return false;
}
case BotSpellTypes::InCombatBuffSong:
case BotSpellTypes::OutOfCombatBuffSong:
@@ -9265,6 +9269,55 @@ bool Mob::GetDefaultSpellHold(uint16 spellType, uint8 stance) {
else {
return true;
}
case BotSpellTypes::HateLine:
if (GetClass() == Class::ShadowKnight || GetClass() == Class::Paladin) {
switch (stance) {
case Stance::Aggressive:
return false;
default:
return true;
}
}
else {
return true;
}
case BotSpellTypes::Cure:
case BotSpellTypes::GroupCures:
switch (stance) {
case Stance::Aggressive:
case Stance::AEBurn:
case Stance::Burn:
return true;
default:
return false;
}
case BotSpellTypes::GroupCompleteHeals:
case BotSpellTypes::GroupHeals:
case BotSpellTypes::GroupHoTHeals:
case BotSpellTypes::HoTHeals:
case BotSpellTypes::CompleteHeal:
case BotSpellTypes::PetCompleteHeals:
case BotSpellTypes::PetFastHeals:
case BotSpellTypes::PetHoTHeals:
case BotSpellTypes::PetRegularHeals:
case BotSpellTypes::PetVeryFastHeals:
case BotSpellTypes::RegularHeal:
switch (stance) {
case Stance::Aggressive:
case Stance::AEBurn:
case Stance::Burn:
return true;
default:
return false;
}
case BotSpellTypes::FastHeals:
case BotSpellTypes::VeryFastHeals:
case BotSpellTypes::Pet:
case BotSpellTypes::Escape:
case BotSpellTypes::Lifetap:
case BotSpellTypes::Buff:
case BotSpellTypes::InCombatBuff:
case BotSpellTypes::PreCombatBuff:
default:
return false;
}
@@ -9487,6 +9540,7 @@ uint8 Mob::GetDefaultSpellMaxThreshold(uint16 spellType, uint8 stance) {
case BotSpellTypes::PetResistBuffs:
case BotSpellTypes::ResistBuffs:
case BotSpellTypes::Resurrect:
case BotSpellTypes::HateLine:
return 100;
case BotSpellTypes::GroupHoTHeals:
case BotSpellTypes::HoTHeals:
+13 -2
View File
@@ -803,7 +803,12 @@ bool Mob::DoCastingChecksOnTarget(bool check_on_casting, int32 spell_id, Mob *sp
if (IsGroupSpell(spell_id)) {
return true;
} else if (spells[spell_id].target_type == ST_Self) {
spell_target = this;
if (IsBot() && (IsEffectInSpell(spell_id, SE_SummonCorpse) && RuleB(Bots, AllowCommandedSummonCorpse))) {
//spell_target = this;
}
else {
spell_target = this;
}
}
} else {
if (IsGroupSpell(spell_id) && spell_target != this) {
@@ -1951,7 +1956,13 @@ bool Mob::DetermineSpellTargets(uint16 spell_id, Mob *&spell_target, Mob *&ae_ce
// single target spells
case ST_Self:
{
spell_target = this;
if (IsBot() && (IsEffectInSpell(spell_id, SE_SummonCorpse) && RuleB(Bots, AllowCommandedSummonCorpse))) {
//spell_target = this;
}
else {
spell_target = this;
}
CastAction = SingleTarget;
break;
}