mirror of
https://github.com/EQEmu/Server.git
synced 2026-05-19 13:28:25 +00:00
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:
@@ -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
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user