mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-12 17:51:28 +00:00
[Bots] Crash fixes related to GetNumberNeedingHealedInGroup (#4684)
- Add pre-death checks and early returns - Cleanup pointers for GetUltimateSpellType checks - Rename IsBotSpellTypeOtherBeneficial to BotSpellTypeUsesTargetSettings - Rename GetUltimateSpellTypeDelayCheck to GetUltimateSpellTypeRecastCheck -Add entity validation to GetNumberNeedingHealedInGroup
This commit is contained in:
parent
da24bf467a
commit
18685748f6
@ -900,7 +900,7 @@ const uint32 SPELL_TYPES_INNATE = (SpellType_Nuke | SpellType_Lifetap | SpellTyp
|
|||||||
// Bot related functions
|
// Bot related functions
|
||||||
bool IsBotSpellTypeDetrimental (uint16 spell_type);
|
bool IsBotSpellTypeDetrimental (uint16 spell_type);
|
||||||
bool IsBotSpellTypeBeneficial (uint16 spell_type);
|
bool IsBotSpellTypeBeneficial (uint16 spell_type);
|
||||||
bool IsBotSpellTypeOtherBeneficial(uint16 spell_type);
|
bool BotSpellTypeUsesTargetSettings(uint16 spell_type);
|
||||||
bool IsBotSpellTypeInnate (uint16 spell_type);
|
bool IsBotSpellTypeInnate (uint16 spell_type);
|
||||||
bool IsAEBotSpellType(uint16 spell_type);
|
bool IsAEBotSpellType(uint16 spell_type);
|
||||||
bool IsGroupBotSpellType(uint16 spell_type);
|
bool IsGroupBotSpellType(uint16 spell_type);
|
||||||
|
|||||||
@ -90,7 +90,7 @@ bool IsBotSpellTypeBeneficial(uint16 spell_type) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsBotSpellTypeOtherBeneficial(uint16 spell_type) {
|
bool BotSpellTypeUsesTargetSettings(uint16 spell_type) {
|
||||||
switch (spell_type) {
|
switch (spell_type) {
|
||||||
case BotSpellTypes::RegularHeal:
|
case BotSpellTypes::RegularHeal:
|
||||||
case BotSpellTypes::CompleteHeal:
|
case BotSpellTypes::CompleteHeal:
|
||||||
|
|||||||
134
zone/bot.cpp
134
zone/bot.cpp
@ -3265,7 +3265,11 @@ Mob* Bot::GetBotTarget(Client* bot_owner)
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool Bot::TargetValidation(Mob* other) {
|
bool Bot::TargetValidation(Mob* other) {
|
||||||
if (!other || GetAppearance() == eaDead) {
|
if (GetAppearance() == eaDead || GetHP() < 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!other || other->GetAppearance() == eaDead || other->GetHP() < 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -7684,15 +7688,21 @@ void EntityList::ShowSpawnWindow(Client* client, int Distance, bool NamedOnly) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint8 Bot::GetNumberNeedingHealedInGroup(Mob* tar, uint16 spell_type, uint16 spell_id, float range) {
|
uint8 Bot::GetNumberNeedingHealedInGroup(Mob* tar, uint16 spell_type, uint16 spell_id, float range) {
|
||||||
if (!tar) {
|
if (!TargetValidation(tar)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8 count = 0;
|
uint8 count = 0;
|
||||||
auto target_list = tar->IsClient() ? GatherSpellTargets(false, tar) : tar->CastToBot()->GetSpellTargetList();
|
std::vector<Mob*> target_list = tar->IsClient() ? GatherSpellTargets(false, tar) : tar->CastToBot()->GetSpellTargetList();
|
||||||
|
|
||||||
for (Mob* m : target_list) {
|
for (auto* m : target_list) {
|
||||||
if (m && tar->CalculateDistance(m) < range && CastChecks(spell_id, m, spell_type, true, IsGroupBotSpellType(spell_type))) {
|
if (
|
||||||
|
m &&
|
||||||
|
entity_list.IsMobInZone(m) &&
|
||||||
|
TargetValidation(m) &&
|
||||||
|
tar->CalculateDistance(m) < range &&
|
||||||
|
CastChecks(spell_id, m, spell_type, true, IsGroupBotSpellType(spell_type))
|
||||||
|
) {
|
||||||
++count;
|
++count;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -9403,7 +9413,7 @@ void Bot::DoItemClick(const EQ::ItemData *item, uint16 slot_id)
|
|||||||
uint8 Bot::spell_casting_chances[SPELL_TYPE_COUNT][Class::PLAYER_CLASS_COUNT][Stance::AEBurn][cntHSND] = { 0 };
|
uint8 Bot::spell_casting_chances[SPELL_TYPE_COUNT][Class::PLAYER_CLASS_COUNT][Stance::AEBurn][cntHSND] = { 0 };
|
||||||
|
|
||||||
bool Bot::PrecastChecks(Mob* tar, uint16 spell_type) {
|
bool Bot::PrecastChecks(Mob* tar, uint16 spell_type) {
|
||||||
if (!tar) {
|
if (!TargetValidation(tar)) {
|
||||||
LogBotSpellChecksDetail("{} says, 'Cancelling cast due to PrecastChecks !tar.'", GetCleanName());
|
LogBotSpellChecksDetail("{} says, 'Cancelling cast due to PrecastChecks !tar.'", GetCleanName());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -9425,24 +9435,18 @@ bool Bot::PrecastChecks(Mob* tar, uint16 spell_type) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (!EQ::ValueWithin(GetManaRatio(), GetSpellTypeMinManaLimit(spell_type), GetSpellTypeMaxManaLimit(spell_type))) {
|
||||||
GetManaRatio() < GetSpellTypeMinManaLimit(spell_type) ||
|
|
||||||
GetManaRatio() > GetSpellTypeMaxManaLimit(spell_type)
|
|
||||||
) {
|
|
||||||
LogBotSpellChecksDetail("{} says, 'Cancelling cast of [{}] on [{}] due to GetSpellTypeMinManaLimit or GetSpellTypeMaxManaLimit.'", GetCleanName(), GetSpellTypeNameByID(spell_type), tar->GetCleanName());
|
LogBotSpellChecksDetail("{} says, 'Cancelling cast of [{}] on [{}] due to GetSpellTypeMinManaLimit or GetSpellTypeMaxManaLimit.'", GetCleanName(), GetSpellTypeNameByID(spell_type), tar->GetCleanName());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (!EQ::ValueWithin(GetHPRatio(), GetSpellTypeMinHPLimit(spell_type), GetSpellTypeMaxHPLimit(spell_type))) {
|
||||||
GetHPRatio() < GetSpellTypeMinHPLimit(spell_type) ||
|
|
||||||
GetHPRatio() > GetSpellTypeMaxHPLimit(spell_type)
|
|
||||||
) {
|
|
||||||
LogBotSpellChecksDetail("{} says, 'Cancelling cast of [{}] on [{}] due to GetSpellTypeMinHPLimit or GetSpellTypeMaxHPLimit.'", GetCleanName(), GetSpellTypeNameByID(spell_type), tar->GetCleanName());
|
LogBotSpellChecksDetail("{} says, 'Cancelling cast of [{}] on [{}] due to GetSpellTypeMinHPLimit or GetSpellTypeMaxHPLimit.'", GetCleanName(), GetSpellTypeNameByID(spell_type), tar->GetCleanName());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!GetUltimateSpellTypeDelayCheck(spell_type, tar)) {
|
if (!GetUltimateSpellTypeRecastCheck(spell_type, tar)) {
|
||||||
LogBotSpellChecksDetail("{} says, 'Cancelling cast of [{}] on [{}] due to GetUltimateSpellTypeDelayCheck.'", GetCleanName(), GetSpellTypeNameByID(spell_type), tar->GetCleanName());
|
LogBotSpellChecksDetail("{} says, 'Cancelling cast of [{}] on [{}] due to GetUltimateSpellTypeRecastCheck.'", GetCleanName(), GetSpellTypeNameByID(spell_type), tar->GetCleanName());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -9451,10 +9455,7 @@ bool Bot::PrecastChecks(Mob* tar, uint16 spell_type) {
|
|||||||
case BotSpellTypes::AEMez:
|
case BotSpellTypes::AEMez:
|
||||||
return true;
|
return true;
|
||||||
default:
|
default:
|
||||||
if (
|
if (!EQ::ValueWithin(GetHPRatioForSpellType(spell_type, tar), GetUltimateSpellTypeMinThreshold(spell_type, tar), GetUltimateSpellTypeMaxThreshold(spell_type, tar))) {
|
||||||
GetHPRatioForSpellType(spell_type, tar) < GetUltimateSpellTypeMinThreshold(spell_type, tar) ||
|
|
||||||
GetHPRatioForSpellType(spell_type, tar) > GetUltimateSpellTypeMaxThreshold(spell_type, tar)
|
|
||||||
) {
|
|
||||||
LogBotSpellChecksDetail("{} says, 'Cancelling cast of [{}] on [{}] due to GetUltimateSpellTypeMinThreshold or GetUltimateSpellTypeMaxThreshold.'", GetCleanName(), GetSpellTypeNameByID(spell_type), tar->GetCleanName());
|
LogBotSpellChecksDetail("{} says, 'Cancelling cast of [{}] on [{}] due to GetUltimateSpellTypeMinThreshold or GetUltimateSpellTypeMaxThreshold.'", GetCleanName(), GetSpellTypeNameByID(spell_type), tar->GetCleanName());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -9465,7 +9466,7 @@ bool Bot::PrecastChecks(Mob* tar, uint16 spell_type) {
|
|||||||
|
|
||||||
bool Bot::CastChecks(uint16 spell_id, Mob* tar, uint16 spell_type, bool prechecks, bool ae_check) {
|
bool Bot::CastChecks(uint16 spell_id, Mob* tar, uint16 spell_type, bool prechecks, bool ae_check) {
|
||||||
if (prechecks) {
|
if (prechecks) {
|
||||||
if (!tar) {
|
if (!tar || tar->GetAppearance() == eaDead || tar->GetHP() < 0) {
|
||||||
LogBotSpellChecksDetail("{} says, 'Cancelling cast due to CastChecks !tar.'", GetCleanName());
|
LogBotSpellChecksDetail("{} says, 'Cancelling cast due to CastChecks !tar.'", GetCleanName());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -9616,7 +9617,7 @@ bool Bot::CastChecks(uint16 spell_id, Mob* tar, uint16 spell_type, bool precheck
|
|||||||
|
|
||||||
if (
|
if (
|
||||||
BotSpellTypeRequiresTarget(spell_type) &&
|
BotSpellTypeRequiresTarget(spell_type) &&
|
||||||
!tar
|
!TargetValidation(tar)
|
||||||
) {
|
) {
|
||||||
LogBotSpellChecksDetail("{} says, 'Cancelling cast due to CastChecks !tar.'", GetCleanName());
|
LogBotSpellChecksDetail("{} says, 'Cancelling cast due to CastChecks !tar.'", GetCleanName());
|
||||||
return false;
|
return false;
|
||||||
@ -10520,7 +10521,7 @@ void Bot::SetBotSpellRecastTimer(uint16 spell_type, Mob* tar, bool precast) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!precast && IsBotSpellTypeOtherBeneficial(spell_type)) {
|
if (!precast && BotSpellTypeUsesTargetSettings(spell_type)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -10545,7 +10546,7 @@ void Bot::SetBotSpellRecastTimer(uint16 spell_type, Mob* tar, bool precast) {
|
|||||||
owner->CastToBot()->SetSpellTypeRecastTimer(spell_type, (GetUltimateSpellTypeDelay(spell_type, tar) + added_delay));
|
owner->CastToBot()->SetSpellTypeRecastTimer(spell_type, (GetUltimateSpellTypeDelay(spell_type, tar) + added_delay));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (IsBotSpellTypeOtherBeneficial(spell_type)) {
|
else if (BotSpellTypeUsesTargetSettings(spell_type)) {
|
||||||
if (tar->IsClient()) {
|
if (tar->IsClient()) {
|
||||||
tar->CastToClient()->SetSpellTypeRecastTimer(spell_type, (GetUltimateSpellTypeDelay(spell_type, tar) + added_delay));
|
tar->CastToClient()->SetSpellTypeRecastTimer(spell_type, (GetUltimateSpellTypeDelay(spell_type, tar) + added_delay));
|
||||||
}
|
}
|
||||||
@ -10559,6 +10560,12 @@ void Bot::SetBotSpellRecastTimer(uint16 spell_type, Mob* tar, bool precast) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
BotSpell Bot::GetSpellByHealType(uint16 spell_type, Mob* tar) {
|
BotSpell Bot::GetSpellByHealType(uint16 spell_type, Mob* tar) {
|
||||||
|
if (!TargetValidation(tar)) {
|
||||||
|
BotSpell result;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
switch (spell_type) {
|
switch (spell_type) {
|
||||||
case BotSpellTypes::VeryFastHeals:
|
case BotSpellTypes::VeryFastHeals:
|
||||||
case BotSpellTypes::PetVeryFastHeals:
|
case BotSpellTypes::PetVeryFastHeals:
|
||||||
@ -11142,7 +11149,7 @@ uint16 Bot::GetDefaultSpellTypeAnnounceCast(uint16 spell_type, uint8 stance) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool Bot::GetUltimateSpellTypeHold(uint16 spell_type, Mob* tar) {
|
bool Bot::GetUltimateSpellTypeHold(uint16 spell_type, Mob* tar) {
|
||||||
if (!tar) {
|
if (!TargetValidation(tar)) {
|
||||||
return GetSpellTypeHold(spell_type);
|
return GetSpellTypeHold(spell_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -13001,7 +13008,7 @@ uint8 Bot::GetDefaultSpellTypeMaxThreshold(uint16 spell_type, uint8 stance) {
|
|||||||
}
|
}
|
||||||
case BotSpellTypes::GroupHeals:
|
case BotSpellTypes::GroupHeals:
|
||||||
case BotSpellTypes::RegularHeal:
|
case BotSpellTypes::RegularHeal:
|
||||||
if (bot_class == Class::Necromancer || (bot_class == Class::Shaman && !GetSpellTypeHold(BotSpellTypes::InCombatBuff))) {
|
if (bot_class == Class::Necromancer || bot_class == Class::Shaman) {
|
||||||
return 60;
|
return 60;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -13130,81 +13137,88 @@ uint8 Bot::GetDefaultSpellTypeMaxThreshold(uint16 spell_type, uint8 stance) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint16 Bot::GetUltimateSpellTypeDelay(uint16 spell_type, Mob* tar) {
|
uint16 Bot::GetUltimateSpellTypeDelay(uint16 spell_type, Mob* tar) {
|
||||||
if (!tar) {
|
if (!TargetValidation(tar)) {
|
||||||
return GetSpellTypeDelay(spell_type);
|
return GetSpellTypeDelay(spell_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tar->IsPet() && tar->GetOwner() && tar->GetOwner()->IsOfClientBot()) {
|
Mob* owner = tar->IsPet() ? tar->GetOwner() : nullptr;
|
||||||
Mob* owner = tar->GetOwner();
|
|
||||||
|
|
||||||
return owner->IsClient() ? owner->CastToClient()->GetSpellTypeDelay(GetPetBotSpellType(spell_type)) : owner->CastToBot()->GetSpellTypeDelay(
|
if (owner && owner->IsOfClientBot()) {
|
||||||
GetPetBotSpellType(spell_type));
|
return owner->IsClient()
|
||||||
|
? owner->CastToClient()->GetSpellTypeDelay(GetPetBotSpellType(spell_type))
|
||||||
|
: owner->CastToBot()->GetSpellTypeDelay(GetPetBotSpellType(spell_type));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsBotSpellTypeOtherBeneficial(spell_type) && tar->IsOfClientBot()) {
|
if (BotSpellTypeUsesTargetSettings(spell_type) && tar->IsOfClientBot()) {
|
||||||
return tar->IsClient() ? tar->CastToClient()->GetSpellTypeDelay(spell_type) : tar->CastToBot()->GetSpellTypeDelay(
|
return tar->IsClient()
|
||||||
spell_type
|
? tar->CastToClient()->GetSpellTypeDelay(spell_type)
|
||||||
);
|
: tar->CastToBot()->GetSpellTypeDelay(spell_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
return GetSpellTypeDelay(spell_type);
|
return GetSpellTypeDelay(spell_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Bot::GetUltimateSpellTypeDelayCheck(uint16 spell_type, Mob* tar) {
|
bool Bot::GetUltimateSpellTypeRecastCheck(uint16 spell_type, Mob* tar) {
|
||||||
if (!tar) {
|
if (!TargetValidation(tar)) {
|
||||||
return SpellTypeRecastCheck(spell_type);
|
return SpellTypeRecastCheck(spell_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tar->IsPet() && tar->GetOwner() && tar->GetOwner()->IsOfClientBot()) {
|
Mob* owner = tar->IsPet() ? tar->GetOwner() : nullptr;
|
||||||
Mob* owner = tar->GetOwner();
|
|
||||||
|
|
||||||
return owner->IsClient() ? owner->CastToClient()->SpellTypeRecastCheck(GetPetBotSpellType(spell_type)) : owner->CastToBot()->SpellTypeRecastCheck(GetPetBotSpellType(spell_type));
|
if (owner && owner->IsOfClientBot()) {
|
||||||
|
return owner->IsClient()
|
||||||
|
? owner->CastToClient()->SpellTypeRecastCheck(GetPetBotSpellType(spell_type))
|
||||||
|
: owner->CastToBot()->SpellTypeRecastCheck(GetPetBotSpellType(spell_type));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsBotSpellTypeOtherBeneficial(spell_type) && tar->IsOfClientBot()) {
|
if (BotSpellTypeUsesTargetSettings(spell_type) && tar->IsOfClientBot()) {
|
||||||
return tar->IsClient() ? tar->CastToClient()->SpellTypeRecastCheck(spell_type) : tar->CastToBot()->SpellTypeRecastCheck(spell_type);
|
return tar->IsClient()
|
||||||
|
? tar->CastToClient()->SpellTypeRecastCheck(spell_type)
|
||||||
|
: tar->CastToBot()->SpellTypeRecastCheck(spell_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
return SpellTypeRecastCheck(spell_type);
|
return SpellTypeRecastCheck(spell_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8 Bot::GetUltimateSpellTypeMinThreshold(uint16 spell_type, Mob* tar) {
|
uint8 Bot::GetUltimateSpellTypeMinThreshold(uint16 spell_type, Mob* tar) {
|
||||||
if (!tar) {
|
if (!TargetValidation(tar)) {
|
||||||
return GetSpellTypeMinThreshold(spell_type);
|
return GetSpellTypeMinThreshold(spell_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tar->IsPet() && tar->GetOwner() && tar->GetOwner()->IsOfClientBot()) {
|
Mob* owner = tar->IsPet() ? tar->GetOwner() : nullptr;
|
||||||
Mob* owner = tar->GetOwner();
|
|
||||||
|
|
||||||
return owner->IsClient() ? owner->CastToClient()->GetSpellTypeMinThreshold(GetPetBotSpellType(spell_type)) : owner->CastToBot()->GetSpellTypeMinThreshold(
|
if (owner && owner->IsOfClientBot()) {
|
||||||
GetPetBotSpellType(spell_type));
|
return owner->IsClient()
|
||||||
|
? owner->CastToClient()->GetSpellTypeMinThreshold(GetPetBotSpellType(spell_type))
|
||||||
|
: owner->CastToBot()->GetSpellTypeMinThreshold(GetPetBotSpellType(spell_type));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsBotSpellTypeOtherBeneficial(spell_type) && tar->IsOfClientBot()) {
|
if (BotSpellTypeUsesTargetSettings(spell_type) && tar->IsOfClientBot()) {
|
||||||
return tar->IsClient() ? tar->CastToClient()->GetSpellTypeMinThreshold(spell_type) : tar->CastToBot()->GetSpellTypeMinThreshold(
|
return tar->IsClient()
|
||||||
spell_type
|
? tar->CastToClient()->GetSpellTypeMinThreshold(spell_type)
|
||||||
);
|
: tar->CastToBot()->GetSpellTypeMinThreshold(spell_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
return GetSpellTypeMinThreshold(spell_type);
|
return GetSpellTypeMinThreshold(spell_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8 Bot::GetUltimateSpellTypeMaxThreshold(uint16 spell_type, Mob* tar) {
|
uint8 Bot::GetUltimateSpellTypeMaxThreshold(uint16 spell_type, Mob* tar) {
|
||||||
if (!tar) {
|
if (!TargetValidation(tar)) {
|
||||||
return GetSpellTypeMaxThreshold(spell_type);
|
return GetSpellTypeMaxThreshold(spell_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tar->IsPet() && tar->GetOwner() && tar->GetOwner()->IsOfClientBot()) {
|
Mob* owner = tar->IsPet() ? tar->GetOwner() : nullptr;
|
||||||
Mob* owner = tar->GetOwner();
|
|
||||||
|
|
||||||
return owner->IsClient() ? owner->CastToClient()->GetSpellTypeMaxThreshold(GetPetBotSpellType(spell_type)) : owner->CastToBot()->GetSpellTypeMaxThreshold(
|
if (owner && owner->IsOfClientBot()) {
|
||||||
GetPetBotSpellType(spell_type));
|
return owner->IsClient()
|
||||||
|
? owner->CastToClient()->GetSpellTypeMaxThreshold(GetPetBotSpellType(spell_type))
|
||||||
|
: owner->CastToBot()->GetSpellTypeMaxThreshold(GetPetBotSpellType(spell_type));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsBotSpellTypeOtherBeneficial(spell_type) && tar->IsOfClientBot()) {
|
if (BotSpellTypeUsesTargetSettings(spell_type) && tar->IsOfClientBot()) {
|
||||||
return tar->IsClient() ? tar->CastToClient()->GetSpellTypeMaxThreshold(spell_type) : tar->CastToBot()->GetSpellTypeMaxThreshold(
|
return tar->IsClient()
|
||||||
spell_type
|
? tar->CastToClient()->GetSpellTypeMaxThreshold(spell_type)
|
||||||
);
|
: tar->CastToBot()->GetSpellTypeMaxThreshold(spell_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
return GetSpellTypeMaxThreshold(spell_type);
|
return GetSpellTypeMaxThreshold(spell_type);
|
||||||
|
|||||||
@ -643,7 +643,7 @@ public:
|
|||||||
uint8 GetDefaultSpellTypeMinThreshold(uint16 spell_type, uint8 stance = Stance::Balanced);
|
uint8 GetDefaultSpellTypeMinThreshold(uint16 spell_type, uint8 stance = Stance::Balanced);
|
||||||
uint8 GetDefaultSpellTypeMaxThreshold(uint16 spell_type, uint8 stance = Stance::Balanced);
|
uint8 GetDefaultSpellTypeMaxThreshold(uint16 spell_type, uint8 stance = Stance::Balanced);
|
||||||
uint16 GetUltimateSpellTypeDelay(uint16 spell_type, Mob* tar);
|
uint16 GetUltimateSpellTypeDelay(uint16 spell_type, Mob* tar);
|
||||||
bool GetUltimateSpellTypeDelayCheck(uint16 spell_type, Mob* tar);
|
bool GetUltimateSpellTypeRecastCheck(uint16 spell_type, Mob* tar);
|
||||||
uint8 GetUltimateSpellTypeMinThreshold(uint16 spell_type, Mob* tar);
|
uint8 GetUltimateSpellTypeMinThreshold(uint16 spell_type, Mob* tar);
|
||||||
uint8 GetUltimateSpellTypeMaxThreshold(uint16 spell_type, Mob* tar);
|
uint8 GetUltimateSpellTypeMaxThreshold(uint16 spell_type, Mob* tar);
|
||||||
void SetIllusionBlock(bool value) { _illusionBlock = value; }
|
void SetIllusionBlock(bool value) { _illusionBlock = value; }
|
||||||
|
|||||||
@ -220,7 +220,7 @@ void bot_command_depart(Client* c, const Seperator* sep)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (bot_iter->CastSpell(itr->SpellId, tar->GetID(), EQ::spells::CastingSlot::Gem2, -1, -1)) {
|
if (bot_iter->CastSpell(itr->SpellId, tar->GetID(), EQ::spells::CastingSlot::Gem2, -1, -1)) {
|
||||||
if (IsBotSpellTypeOtherBeneficial(BotSpellTypes::Teleport)) {
|
if (BotSpellTypeUsesTargetSettings(BotSpellTypes::Teleport)) {
|
||||||
bot_iter->SetCastedSpellType(UINT16_MAX);
|
bot_iter->SetCastedSpellType(UINT16_MAX);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|||||||
@ -242,7 +242,7 @@ bool Bot::AICastSpell(Mob* tar, uint8 chance, uint16 spell_type, uint16 sub_targ
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (AIDoSpellCast(s.SpellIndex, tar, s.ManaCost)) {
|
if (AIDoSpellCast(s.SpellIndex, tar, s.ManaCost)) {
|
||||||
if (IsBotSpellTypeOtherBeneficial(spell_type)) {
|
if (BotSpellTypeUsesTargetSettings(spell_type)) {
|
||||||
SetCastedSpellType(UINT16_MAX);
|
SetCastedSpellType(UINT16_MAX);
|
||||||
|
|
||||||
if (!IsCommandedSpell()) {
|
if (!IsCommandedSpell()) {
|
||||||
@ -288,7 +288,7 @@ bool Bot::BotCastMez(Mob* tar, uint8 bot_class, BotSpell& bot_spell, uint16 spel
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (AIDoSpellCast(s.SpellIndex, tar, s.ManaCost)) {
|
if (AIDoSpellCast(s.SpellIndex, tar, s.ManaCost)) {
|
||||||
if (IsBotSpellTypeOtherBeneficial(spell_type)) {
|
if (BotSpellTypeUsesTargetSettings(spell_type)) {
|
||||||
SetCastedSpellType(UINT16_MAX);
|
SetCastedSpellType(UINT16_MAX);
|
||||||
|
|
||||||
if (!IsCommandedSpell()) {
|
if (!IsCommandedSpell()) {
|
||||||
@ -493,6 +493,10 @@ bool Bot::BotCastNuke(Mob* tar, uint8 bot_class, BotSpell& bot_spell, uint16 spe
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool Bot::BotCastHeal(Mob* tar, uint8 bot_class, BotSpell& bot_spell, uint16 spell_type) {
|
bool Bot::BotCastHeal(Mob* tar, uint8 bot_class, BotSpell& bot_spell, uint16 spell_type) {
|
||||||
|
if (!TargetValidation(tar)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bot_spell = GetSpellByHealType(spell_type, tar);
|
bot_spell = GetSpellByHealType(spell_type, tar);
|
||||||
|
|
||||||
if (!IsValidSpell(bot_spell.SpellId)) {
|
if (!IsValidSpell(bot_spell.SpellId)) {
|
||||||
@ -1287,20 +1291,23 @@ BotSpell Bot::GetBestBotSpellForGroupHeal(Bot* caster, Mob* tar, uint16 spell_ty
|
|||||||
result.SpellIndex = 0;
|
result.SpellIndex = 0;
|
||||||
result.ManaCost = 0;
|
result.ManaCost = 0;
|
||||||
|
|
||||||
if (caster) {
|
if (!caster->TargetValidation(tar)) {
|
||||||
std::list<BotSpell> bot_spell_list = GetBotSpellsForSpellEffect(caster, spell_type, SE_CurrentHP);
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::list<BotSpell> bot_spell_list = GetBotSpellsForSpellEffect(caster, spell_type, SE_CurrentHP);
|
||||||
int target_count = 0;
|
int target_count = 0;
|
||||||
|
int required_count = caster->GetSpellTypeAEOrGroupTargetCount(spell_type);
|
||||||
|
|
||||||
for (std::list<BotSpell>::iterator bot_spell_list_itr = bot_spell_list.begin(); bot_spell_list_itr != bot_spell_list.end(); ++bot_spell_list_itr) {
|
for (std::list<BotSpell>::iterator bot_spell_list_itr = bot_spell_list.begin(); bot_spell_list_itr != bot_spell_list.end(); ++bot_spell_list_itr) {
|
||||||
// Assuming all the spells have been loaded into this list by level and in descending order
|
// Assuming all the spells have been loaded into this list by level and in descending order
|
||||||
if (IsRegularGroupHealSpell(bot_spell_list_itr->SpellId)) {
|
if (IsRegularGroupHealSpell(bot_spell_list_itr->SpellId)) {
|
||||||
uint16 spell_id = bot_spell_list_itr->SpellId;
|
uint16 spell_id = bot_spell_list_itr->SpellId;
|
||||||
|
|
||||||
if (!caster->IsCommandedSpell() && caster->IsValidSpellRange(spell_id, tar)) {
|
if (caster->TargetValidation(tar) && !caster->IsCommandedSpell() && caster->IsValidSpellRange(spell_id, tar)) {
|
||||||
target_count = caster->GetNumberNeedingHealedInGroup(tar, spell_type, spell_id, caster->GetAOERange(spell_id));
|
target_count = caster->GetNumberNeedingHealedInGroup(tar, spell_type, spell_id, caster->GetAOERange(spell_id));
|
||||||
|
|
||||||
if (target_count < caster->GetSpellTypeAEOrGroupTargetCount(spell_type)) {
|
if (target_count < required_count) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1312,7 +1319,6 @@ BotSpell Bot::GetBestBotSpellForGroupHeal(Bot* caster, Mob* tar, uint16 spell_ty
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -1324,20 +1330,23 @@ BotSpell Bot::GetBestBotSpellForGroupHealOverTime(Bot* caster, Mob* tar, uint16
|
|||||||
result.SpellIndex = 0;
|
result.SpellIndex = 0;
|
||||||
result.ManaCost = 0;
|
result.ManaCost = 0;
|
||||||
|
|
||||||
if (caster) {
|
if (!caster->TargetValidation(tar)) {
|
||||||
std::list<BotSpell> bot_spell_list = GetBotSpellsForSpellEffect(caster, spell_type, SE_HealOverTime);
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::list<BotSpell> bot_spell_list = GetBotSpellsForSpellEffect(caster, spell_type, SE_HealOverTime);
|
||||||
int target_count = 0;
|
int target_count = 0;
|
||||||
|
int required_count = caster->GetSpellTypeAEOrGroupTargetCount(spell_type);
|
||||||
|
|
||||||
for (std::list<BotSpell>::iterator bot_spell_list_itr = bot_spell_list.begin(); bot_spell_list_itr != bot_spell_list.end(); ++bot_spell_list_itr) {
|
for (std::list<BotSpell>::iterator bot_spell_list_itr = bot_spell_list.begin(); bot_spell_list_itr != bot_spell_list.end(); ++bot_spell_list_itr) {
|
||||||
// Assuming all the spells have been loaded into this list by level and in descending order
|
// Assuming all the spells have been loaded into this list by level and in descending order
|
||||||
if (IsGroupHealOverTimeSpell(bot_spell_list_itr->SpellId)) {
|
if (IsGroupHealOverTimeSpell(bot_spell_list_itr->SpellId)) {
|
||||||
uint16 spell_id = bot_spell_list_itr->SpellId;
|
uint16 spell_id = bot_spell_list_itr->SpellId;
|
||||||
|
|
||||||
if (!caster->IsCommandedSpell() && caster->IsValidSpellRange(spell_id, tar)) {
|
if (caster->TargetValidation(tar) && !caster->IsCommandedSpell() && caster->IsValidSpellRange(spell_id, tar)) {
|
||||||
target_count = caster->GetNumberNeedingHealedInGroup(tar, spell_type, spell_id, caster->GetAOERange(spell_id));
|
target_count = caster->GetNumberNeedingHealedInGroup(tar, spell_type, spell_id, caster->GetAOERange(spell_id));
|
||||||
|
|
||||||
if (target_count < caster->GetSpellTypeAEOrGroupTargetCount(spell_type)) {
|
if (target_count < required_count) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1349,7 +1358,6 @@ BotSpell Bot::GetBestBotSpellForGroupHealOverTime(Bot* caster, Mob* tar, uint16
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -1361,20 +1369,23 @@ BotSpell Bot::GetBestBotSpellForGroupCompleteHeal(Bot* caster, Mob* tar, uint16
|
|||||||
result.SpellIndex = 0;
|
result.SpellIndex = 0;
|
||||||
result.ManaCost = 0;
|
result.ManaCost = 0;
|
||||||
|
|
||||||
if (caster) {
|
if (!caster->TargetValidation(tar)) {
|
||||||
std::list<BotSpell> bot_spell_list = GetBotSpellsForSpellEffect(caster, spell_type, SE_CompleteHeal);
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::list<BotSpell> bot_spell_list = GetBotSpellsForSpellEffect(caster, spell_type, SE_CompleteHeal);
|
||||||
int target_count = 0;
|
int target_count = 0;
|
||||||
|
int required_count = caster->GetSpellTypeAEOrGroupTargetCount(spell_type);
|
||||||
|
|
||||||
for (std::list<BotSpell>::iterator bot_spell_list_itr = bot_spell_list.begin(); bot_spell_list_itr != bot_spell_list.end(); ++bot_spell_list_itr) {
|
for (std::list<BotSpell>::iterator bot_spell_list_itr = bot_spell_list.begin(); bot_spell_list_itr != bot_spell_list.end(); ++bot_spell_list_itr) {
|
||||||
// Assuming all the spells have been loaded into this list by level and in descending order
|
// Assuming all the spells have been loaded into this list by level and in descending order
|
||||||
if (IsGroupCompleteHealSpell(bot_spell_list_itr->SpellId)) {
|
if (IsGroupCompleteHealSpell(bot_spell_list_itr->SpellId)) {
|
||||||
uint16 spell_id = bot_spell_list_itr->SpellId;
|
uint16 spell_id = bot_spell_list_itr->SpellId;
|
||||||
|
|
||||||
if (!caster->IsCommandedSpell() && caster->IsValidSpellRange(spell_id, tar)) {
|
if (caster->TargetValidation(tar) && !caster->IsCommandedSpell() && caster->IsValidSpellRange(spell_id, tar)) {
|
||||||
target_count = caster->GetNumberNeedingHealedInGroup(tar, spell_type, spell_id, caster->GetAOERange(spell_id));
|
target_count = caster->GetNumberNeedingHealedInGroup(tar, spell_type, spell_id, caster->GetAOERange(spell_id));
|
||||||
|
|
||||||
if (target_count < caster->GetSpellTypeAEOrGroupTargetCount(spell_type)) {
|
if (target_count < required_count) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1386,7 +1397,6 @@ BotSpell Bot::GetBestBotSpellForGroupCompleteHeal(Bot* caster, Mob* tar, uint16
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user