correct and tweak all combat positioning and combat range

This commit is contained in:
nytmyr
2024-11-10 23:35:28 -06:00
parent 8989c6f21b
commit 464c69190d
4 changed files with 94 additions and 65 deletions
+4 -4
View File
@@ -836,15 +836,15 @@ RULE_INT(Bots, StackSizeMin, 20, "20 Default. -1 to disable and use default max
RULE_INT(Bots, HasOrMayGetAggroThreshold, 90, "90 Default. Percent threshold of total hate where bots will stop casting spells that generate hate if they are set to try to not pull aggro via spells.") RULE_INT(Bots, HasOrMayGetAggroThreshold, 90, "90 Default. Percent threshold of total hate where bots will stop casting spells that generate hate if they are set to try to not pull aggro via spells.")
RULE_BOOL(Bots, UseFlatNormalMeleeRange, false, "False Default. If true, bots melee distance will be a flat distance set by Bots:NormalMeleeRangeDistance.") RULE_BOOL(Bots, UseFlatNormalMeleeRange, false, "False Default. If true, bots melee distance will be a flat distance set by Bots:NormalMeleeRangeDistance.")
RULE_REAL(Bots, NormalMeleeRangeDistance, 0.75, "If UseFlatNormalMeleeRange is enabled, multiplier of the max melee range at which a bot will stand in melee combat. 0.75 Recommended, max melee for all abilities to land.") RULE_REAL(Bots, NormalMeleeRangeDistance, 0.75, "If UseFlatNormalMeleeRange is enabled, multiplier of the max melee range at which a bot will stand in melee combat. 0.75 Recommended, max melee for all abilities to land.")
RULE_REAL(Bots, PercentMinMeleeDistance, 0.60, "Multiplier of the max melee range - Minimum distance from target a bot will stand while in melee combat before trying to adjust. 0.60 Recommended.") RULE_REAL(Bots, PercentMinMeleeDistance, 0.75, "Multiplier of the their melee range - Minimum distance from target a bot will stand while in melee combat before trying to adjust. 0.60 Recommended.")
RULE_REAL(Bots, MaxDistanceForMelee, 20, "Maximum distance bots will stand for melee. Default 20 to allow all special attacks to land.") RULE_REAL(Bots, MaxDistanceForMelee, 20, "Maximum distance bots will stand for melee. Default 20 to allow all special attacks to land.")
RULE_REAL(Bots, TauntNormalMeleeRangeDistance, 0.50, "Multiplier of the max melee range at which a taunting bot will stand in melee combat. 0.50 Recommended, closer than others .") RULE_REAL(Bots, TauntNormalMeleeRangeDistance, 0.50, "Multiplier of the max melee range at which a taunting bot will stand in melee combat. 0.50 Recommended, closer than others .")
RULE_REAL(Bots, PercentTauntMinMeleeDistance, 0.25, "Multiplier of max melee range - Minimum distance from target a taunting bot will stand while in melee combat before trying to adjust. 0.25 Recommended.") RULE_REAL(Bots, PercentTauntMinMeleeDistance, 0.40, "Multiplier of their melee range - Minimum distance from target a taunting bot will stand while in melee combat before trying to adjust. 0.25 Recommended.")
RULE_REAL(Bots, PercentMaxMeleeRangeDistance, 0.95, "Multiplier of the max melee range at which a bot will stand in melee combat. 0.95 Recommended, max melee while disabling special attacks/taunt.") RULE_REAL(Bots, PercentMaxMeleeRangeDistance, 0.95, "Multiplier of the max melee range at which a bot will stand in melee combat. 0.95 Recommended, max melee while disabling special attacks/taunt.")
RULE_REAL(Bots, PercentMinMaxMeleeRangeDistance, 0.75, "Multiplier of the closest max melee range at which a bot will stand in melee combat before trying to adjust. 0.75 Recommended, max melee while disabling special attacks/taunt.") RULE_REAL(Bots, PercentMinMaxMeleeRangeDistance, 0.75, "Multiplier of the closest max melee range at which a bot will stand in melee combat before trying to adjust. 0.75 Recommended, max melee while disabling special attacks/taunt.")
RULE_BOOL(Bots, TauntingBotsFollowTopHate, true, "True Default. If true, bots that are taunting will attempt to stick with whoever currently is top hate.") RULE_BOOL(Bots, TauntingBotsFollowTopHate, true, "True Default. If true, bots that are taunting will attempt to stick with whoever currently is top hate.")
RULE_REAL(Bots, DistanceTauntingBotsStickMainHate, 25.00, "If TauntingBotsFollowTopHate is enabled, this is the distance bots will try to stick to whoever currently is Top Hate.") RULE_INT(Bots, DistanceTauntingBotsStickMainHate, 10, "If TauntingBotsFollowTopHate is enabled, this is the distance bots will try to stick to whoever currently is Top Hate.")
RULE_BOOL(Bots, DisableSpecialAbilitiesAtMaxMelee, false, "False Default. If true, when bots are at max melee distance, special abilities including taunt will be disabled.") RULE_BOOL(Bots, DisableSpecialAbilitiesAtMaxMelee, true, "True Default. If true, when bots are at max melee distance, special abilities including taunt will be disabled.")
RULE_INT(Bots, MinJitterTimer, 500, "Minimum ms between bot movement jitter checks.") RULE_INT(Bots, MinJitterTimer, 500, "Minimum ms between bot movement jitter checks.")
RULE_INT(Bots, MaxJitterTimer, 2500, "Maximum ms between bot movement jitter checks. Set to 0 to disable timer checks.") RULE_INT(Bots, MaxJitterTimer, 2500, "Maximum ms between bot movement jitter checks. Set to 0 to disable timer checks.")
RULE_BOOL(Bots, PreventBotCampOnFD, true, "True Default. If true, players will not be able to camp bots while feign death.") RULE_BOOL(Bots, PreventBotCampOnFD, true, "True Default. If true, players will not be able to camp bots while feign death.")
+87 -59
View File
@@ -2163,7 +2163,8 @@ void Bot::AI_Process()
// COMBAT RANGE CALCS // COMBAT RANGE CALCS
bool atCombatRange = false; bool atCombatRange = false;
bool behindMob = false; bool behindMob = BehindMob(tar, GetX(), GetY());
bool frontMob = InFrontMob(tar, GetX(), GetY());
uint8 stopMeleeLevel = GetStopMeleeLevel(); uint8 stopMeleeLevel = GetStopMeleeLevel();
const EQ::ItemInstance* p_item; const EQ::ItemInstance* p_item;
const EQ::ItemInstance* s_item; const EQ::ItemInstance* s_item;
@@ -2230,7 +2231,7 @@ void Bot::AI_Process()
} }
if (!jitterCooldown && AI_movement_timer->Check() && (!spellend_timer.Enabled() || GetClass() == Class::Bard)) { if (!jitterCooldown && AI_movement_timer->Check() && (!spellend_timer.Enabled() || GetClass() == Class::Bard)) {
DoCombatPositioning(tar, Goal, stopMeleeLevel, tar_distance, melee_distance_min, melee_distance, melee_distance_max, behindMob); DoCombatPositioning(tar, Goal, stopMeleeLevel, tar_distance, melee_distance_min, melee_distance, melee_distance_max, behindMob, frontMob);
return; return;
} }
else { else {
@@ -2363,10 +2364,10 @@ bool Bot::TryNonCombatMovementChecks(Client* bot_owner, const Mob* follow_mob, g
else { else {
Goal = follow_mob->GetPosition(); Goal = follow_mob->GetPosition();
} }
float destination_distance = DistanceSquared(GetPosition(), Goal); float destination_distance = DistanceSquared(GetPosition(), Goal);
if ((!bot_owner->GetBotPulling() || PULLING_BOT) && (destination_distance > GetFollowDistance())) { if ((!bot_owner->GetBotPulling() || PULLING_BOT) && (destination_distance > GetFollowDistance())) {
if (!IsRooted()) { if (!IsRooted()) {
if (rest_timer.Enabled()) { if (rest_timer.Enabled()) {
rest_timer.Disable(); rest_timer.Disable();
@@ -2380,7 +2381,6 @@ bool Bot::TryNonCombatMovementChecks(Client* bot_owner, const Mob* follow_mob, g
else { else {
if (IsMoving()) { if (IsMoving()) {
StopMoving(); StopMoving();
return true; return true;
} }
@@ -2733,7 +2733,7 @@ bool Bot::TryEvade(Mob* tar) {
return false; return false;
} }
void Bot::CheckCombatRange(Mob* tar, float tar_distance, bool& atCombatRange, bool& behindMob, const EQ::ItemInstance*& p_item, const EQ::ItemInstance*& s_item, float& melee_distance_min, float& melee_distance, float& melee_distance_max, uint8 stopMeleeLevel) { void Bot::CheckCombatRange(Mob* tar, float tar_distance, bool& atCombatRange, bool behindMob, const EQ::ItemInstance*& p_item, const EQ::ItemInstance*& s_item, float& melee_distance_min, float& melee_distance, float& melee_distance_max, uint8 stopMeleeLevel) {
atCombatRange= false; atCombatRange= false;
p_item = GetBotItem(EQ::invslot::slotPrimary); p_item = GetBotItem(EQ::invslot::slotPrimary);
@@ -2742,32 +2742,46 @@ void Bot::CheckCombatRange(Mob* tar, float tar_distance, bool& atCombatRange, bo
bool backstab_weapon = false; bool backstab_weapon = false;
if (GetBehindMob()) { if (GetBehindMob()) {
behindMob = BehindMob(tar, GetX(), GetY()); // Can be separated for other future use
if (GetClass() == Class::Rogue) { if (GetClass() == Class::Rogue) {
backstab_weapon = p_item && p_item->GetItemBackstabDamage(); backstab_weapon = p_item && p_item->GetItemBackstabDamage();
} }
} }
// Calculate melee distances // Calculate melee distances
CalcMeleeDistances(tar, p_item, s_item, behindMob, backstab_weapon, melee_distance_min, melee_distance, melee_distance_max, stopMeleeLevel); CalcMeleeDistances(tar, p_item, s_item, backstab_weapon, behindMob, melee_distance_min, melee_distance, melee_distance_max, stopMeleeLevel);
//LogTestDebugDetail("{} is {} {}. They are currently {} away {} to be between [{} - {}] away. MMR is {}." if (!GetCombatRoundForAlerts()) {
// , GetCleanName() SetCombatRoundForAlerts();
// , (tar_distance < melee_distance_min ? "too close to" : (tar_distance <= melee_distance ? "within range of" : "too far away from")) LogTestDebugDetail("{} says, 'I'm {} {}. I am currently {} away {} to be between [{} - {}] away. MMR is {}.'"
// , tar->GetCleanName() , GetCleanName()
// , tar_distance , (tar_distance < melee_distance_min ? "too close to" : (tar_distance <= melee_distance ? "within range of" : "too far away from"))
// , (tar_distance <= melee_distance ? "but only needed" : "but need to be") , tar->GetCleanName()
// , melee_distance_min , tar_distance
// , melee_distance , (tar_distance <= melee_distance ? "but only needed" : "but need to be")
// , melee_distance_max , melee_distance_min
//); //deleteme , melee_distance
, melee_distance_max
); //deleteme
LogTestDebugDetail("{} says, 'My stance is {} #{}, I am {} taunting. I am set to {} {}, {} at MMR, distanceranged {}, sml {} [{}]'"
, GetCleanName()
, Stance::GetName(GetBotStance())
, GetBotStance()
, (IsTaunting() ? "currently" : "not")
, (BehindMob() ? "stay behind" : "not stay behind")
, tar->GetCleanName()
, (GetMaxMeleeRange() ? "I stay" : "I do not stay")
, GetBotDistanceRanged()
, GetStopMeleeLevel()
, ((GetLevel() <= GetStopMeleeLevel()) ? "disabled" : "enabled")
); //deleteme
}
if (tar_distance <= melee_distance) { if (tar_distance <= melee_distance) {
atCombatRange = true; atCombatRange = true;
} }
} }
void Bot::CalcMeleeDistances(const Mob* tar, const EQ::ItemInstance* const& p_item, const EQ::ItemInstance* const& s_item, bool behindMob, bool backstab_weapon, float& melee_distance_min, float& melee_distance, float& melee_distance_max, uint8 stopMeleeLevel) { void Bot::CalcMeleeDistances(const Mob* tar, const EQ::ItemInstance* const& p_item, const EQ::ItemInstance* const& s_item, bool backstab_weapon, bool behindMob, float& melee_distance_min, float& melee_distance, float& melee_distance_max, uint8 stopMeleeLevel) {
float size_mod = GetSize(); float size_mod = GetSize();
float other_size_mod = tar->GetSize(); float other_size_mod = tar->GetSize();
@@ -2880,27 +2894,26 @@ void Bot::CalcMeleeDistances(const Mob* tar, const EQ::ItemInstance* const& p_it
melee_distance = RuleR(Bots, MaxDistanceForMelee); melee_distance = RuleR(Bots, MaxDistanceForMelee);
} }
melee_distance_min = melee_distance_max * RuleR(Bots, PercentMinMeleeDistance); melee_distance_min = melee_distance * RuleR(Bots, PercentMinMeleeDistance);
if (taunting) { if (IsTaunting()) {
melee_distance_min = melee_distance_max * RuleR(Bots, PercentTauntMinMeleeDistance); melee_distance_min = melee_distance * RuleR(Bots, PercentTauntMinMeleeDistance);
melee_distance = melee_distance_max * RuleR(Bots, TauntNormalMeleeRangeDistance); melee_distance = melee_distance * RuleR(Bots, TauntNormalMeleeRangeDistance);
} }
bool isStopMeleeLevel = GetLevel() >= stopMeleeLevel; bool isStopMeleeLevel = GetLevel() >= stopMeleeLevel;
if (!taunting && !IsBotRanged() && !isStopMeleeLevel && GetMaxMeleeRange()) { if (!IsTaunting() && !IsBotRanged() && !isStopMeleeLevel && GetMaxMeleeRange()) {
melee_distance = melee_distance_max * RuleR(Bots, PercentMaxMeleeRangeDistance);
melee_distance_min = melee_distance_max * RuleR(Bots, PercentMinMaxMeleeRangeDistance); melee_distance_min = melee_distance_max * RuleR(Bots, PercentMinMaxMeleeRangeDistance);
melee_distance = melee_distance_max * RuleR(Bots, PercentMaxMeleeRangeDistance);
} }
if (isStopMeleeLevel && !IsBotRanged()) { if (isStopMeleeLevel && !IsBotRanged()) {
float desiredRange = GetBotDistanceRanged(); float desiredRange = GetBotDistanceRanged();
melee_distance_min = std::min(melee_distance, (desiredRange / 2)); melee_distance_min = std::max(melee_distance, (desiredRange / 2));
melee_distance = std::max((melee_distance + 1), desiredRange); melee_distance = std::max((melee_distance + 1), desiredRange);
} }
/* Archer Checks*/
if (IsBotRanged()) { if (IsBotRanged()) {
float minDistance = RuleI(Combat, MinRangedAttackDist); float minDistance = RuleI(Combat, MinRangedAttackDist);
float maxDistance = GetBotRangedValue(); float maxDistance = GetBotRangedValue();
@@ -3003,7 +3016,6 @@ Mob* Bot::GetBotTarget(Client* bot_owner)
} }
bool Bot::ReturningFlagChecks(Client* bot_owner, float fm_distance) {// Need to make it back to group before clearing return flag bool Bot::ReturningFlagChecks(Client* bot_owner, float fm_distance) {// Need to make it back to group before clearing return flag
if (fm_distance <= GetFollowDistance()) { if (fm_distance <= GetFollowDistance()) {
// Once we're back, clear blocking flags so everyone else can join in // Once we're back, clear blocking flags so everyone else can join in
@@ -3022,13 +3034,12 @@ bool Bot::ReturningFlagChecks(Client* bot_owner, float fm_distance) {// Need to
WipeHateList(); WipeHateList();
return false; return false;
} }
return true; return true;
} }
bool Bot::PullingFlagChecks(Client* bot_owner) { bool Bot::PullingFlagChecks(Client* bot_owner) {
if (!GetTarget()) { if (!GetTarget()) {
WipeHateList(); WipeHateList();
SetTarget(nullptr); SetTarget(nullptr);
SetPullingFlag(false); SetPullingFlag(false);
@@ -3042,7 +3053,6 @@ bool Bot::PullingFlagChecks(Client* bot_owner) {
return false; return false;
} }
else if (GetTarget()->GetHateList().size()) { else if (GetTarget()->GetHateList().size()) {
WipeHateList(); WipeHateList();
SetTarget(nullptr); SetTarget(nullptr);
SetPullingFlag(false); SetPullingFlag(false);
@@ -3064,7 +3074,6 @@ bool Bot::PullingFlagChecks(Client* bot_owner) {
} }
void Bot::HealRotationChecks() { void Bot::HealRotationChecks() {
if (IsMyHealRotationSet()) { if (IsMyHealRotationSet()) {
if (AIHealRotation(HealRotationTarget(), UseHealRotationFastHeals())) { if (AIHealRotation(HealRotationTarget(), UseHealRotationFastHeals())) {
m_member_of_heal_rotation->SetMemberIsCasting(this); m_member_of_heal_rotation->SetMemberIsCasting(this);
@@ -3079,7 +3088,6 @@ void Bot::HealRotationChecks() {
} }
bool Bot::IsAIProcessValid(const Client* bot_owner, const Group* bot_group, const Raid* raid) { bool Bot::IsAIProcessValid(const Client* bot_owner, const Group* bot_group, const Raid* raid) {
if (!bot_owner || (!bot_group && !raid) || !IsAIControlled()) { if (!bot_owner || (!bot_group && !raid) || !IsAIControlled()) {
return false; return false;
} }
@@ -3089,11 +3097,11 @@ bool Bot::IsAIProcessValid(const Client* bot_owner, const Group* bot_group, cons
SetBotOwner(nullptr); SetBotOwner(nullptr);
return false; return false;
} }
return true; return true;
} }
bool Bot::CheckIfCasting(float fm_distance) { bool Bot::CheckIfCasting(float fm_distance) {
if (IsCasting()) { if (IsCasting()) {
if (IsHealRotationMember() && if (IsHealRotationMember() &&
m_member_of_heal_rotation->CastingOverride() && m_member_of_heal_rotation->CastingOverride() &&
@@ -3105,12 +3113,10 @@ bool Bot::CheckIfCasting(float fm_distance) {
InterruptSpell(); InterruptSpell();
} }
else if (AmICastingForHealRotation() && m_member_of_heal_rotation->CastingMember() == this) { else if (AmICastingForHealRotation() && m_member_of_heal_rotation->CastingMember() == this) {
AdvanceHealRotation(false); AdvanceHealRotation(false);
return true; return true;
} }
else if (GetClass() != Class::Bard) { else if (GetClass() != Class::Bard) {
if (IsEngaged()) { if (IsEngaged()) {
return true; return true;
} }
@@ -3128,13 +3134,12 @@ bool Bot::CheckIfCasting(float fm_distance) {
else if (IsHealRotationMember()) { else if (IsHealRotationMember()) {
m_member_of_heal_rotation->SetMemberIsCasting(this, false); m_member_of_heal_rotation->SetMemberIsCasting(this, false);
} }
return false; return false;
} }
bool Bot::CheckIfIncapacitated() { bool Bot::CheckIfIncapacitated() {
if (GetPauseAI() || IsStunned() || IsMezzed() || (GetAppearance() == eaDead)) { if (GetPauseAI() || IsStunned() || IsMezzed() || (GetAppearance() == eaDead)) {
if (IsCasting()) { if (IsCasting()) {
InterruptSpell(); InterruptSpell();
} }
@@ -3143,6 +3148,7 @@ bool Bot::CheckIfIncapacitated() {
AdvanceHealRotation(false); AdvanceHealRotation(false);
m_member_of_heal_rotation->SetMemberIsCasting(this, false); m_member_of_heal_rotation->SetMemberIsCasting(this, false);
} }
return true; return true;
} }
@@ -3188,29 +3194,29 @@ void Bot::SetBerserkState() {// Berserk updates should occur if primary AI crite
Mob* Bot::SetFollowMob(Client* leash_owner) { Mob* Bot::SetFollowMob(Client* leash_owner) {
Mob* follow_mob = entity_list.GetMob(GetFollowID()); Mob* follow_mob = entity_list.GetMob(GetFollowID());
if (!follow_mob) {
if (!follow_mob) {
follow_mob = leash_owner; follow_mob = leash_owner;
SetFollowID(leash_owner->GetID()); SetFollowID(leash_owner->GetID());
} }
return follow_mob; return follow_mob;
} }
Client* Bot::SetLeashOwner(Client* bot_owner, Group* bot_group, Raid* raid, uint32 r_group) const { Client* Bot::SetLeashOwner(Client* bot_owner, Group* bot_group, Raid* raid, uint32 r_group) const {
Client* leash_owner = nullptr; Client* leash_owner = nullptr;
if (raid && r_group < MAX_RAID_GROUPS && raid->GetGroupLeader(r_group)) { if (raid && r_group < MAX_RAID_GROUPS && raid->GetGroupLeader(r_group)) {
leash_owner = leash_owner =
raid->GetGroupLeader(r_group) && raid->GetGroupLeader(r_group) &&
raid->GetGroupLeader(r_group)->IsClient() ? raid->GetGroupLeader(r_group)->IsClient() ?
raid->GetGroupLeader(r_group)->CastToClient() : bot_owner; raid->GetGroupLeader(r_group)->CastToClient() : bot_owner;
} else if (bot_group) { } else if (bot_group) {
leash_owner = (bot_group->GetLeader() && bot_group->GetLeader()->IsClient() ? bot_group->GetLeader()->CastToClient() : bot_owner); leash_owner = (bot_group->GetLeader() && bot_group->GetLeader()->IsClient() ? bot_group->GetLeader()->CastToClient() : bot_owner);
} else { } else {
leash_owner = bot_owner; leash_owner = bot_owner;
} }
return leash_owner; return leash_owner;
} }
@@ -3235,6 +3241,7 @@ void Bot::SetOwnerTarget(Client* bot_owner) {
AddToHateList(attack_target, 1); AddToHateList(attack_target, 1);
SetTarget(attack_target); SetTarget(attack_target);
SetAttackingFlag(); SetAttackingFlag();
if (GetPet() && (GetClass() != Class::Enchanter || GetPet()->GetPetType() != petAnimation || GetAA(aaAnimationEmpathy) >= 2)) { if (GetPet() && (GetClass() != Class::Enchanter || GetPet()->GetPetType() != petAnimation || GetAA(aaAnimationEmpathy) >= 2)) {
GetPet()->WipeHateList(); GetPet()->WipeHateList();
GetPet()->AddToHateList(attack_target, 1); GetPet()->AddToHateList(attack_target, 1);
@@ -3275,8 +3282,8 @@ void Bot::BotPullerProcess(Client* bot_owner, Raid* raid) {
SetTarget(pull_target); SetTarget(pull_target);
SetPullingFlag(); SetPullingFlag();
bot_owner->SetBotPulling(); bot_owner->SetBotPulling();
if (HasPet() && (GetClass() != Class::Enchanter || GetPet()->GetPetType() != petAnimation || GetAA(aaAnimationEmpathy) >= 1)) {
if (HasPet() && (GetClass() != Class::Enchanter || GetPet()->GetPetType() != petAnimation || GetAA(aaAnimationEmpathy) >= 1)) {
GetPet()->WipeHateList(); GetPet()->WipeHateList();
GetPet()->SetTarget(nullptr); GetPet()->SetTarget(nullptr);
m_previous_pet_order = GetPet()->GetPetOrder(); m_previous_pet_order = GetPet()->GetPetOrder();
@@ -5132,7 +5139,7 @@ void Bot::DoClassAttacks(Mob *target, bool IsRiposte) {
} }
} }
if (taunting && target->IsNPC() && taunt_time) { if (IsTaunting() && target->IsNPC() && taunt_time) {
if (GetTarget() && GetTarget()->GetHateTop() && GetTarget()->GetHateTop() != this) { if (GetTarget() && GetTarget()->GetHateTop() && GetTarget()->GetHateTop() != this) {
BotGroupSay( BotGroupSay(
this, this,
@@ -6758,6 +6765,7 @@ void Bot::Zone() {
bool Bot::IsAtRange(Mob *target) { bool Bot::IsAtRange(Mob *target) {
bool result = false; bool result = false;
if (target) { if (target) {
float range = (GetBotRangedValue() + 5.0); float range = (GetBotRangedValue() + 5.0);
range *= range; range *= range;
@@ -7501,6 +7509,7 @@ void EntityList::ScanCloseClientMobs(std::unordered_map<uint16, Mob*>& close_mob
} }
float distance = DistanceSquared(scanning_mob->GetPosition(), mob->GetPosition()); float distance = DistanceSquared(scanning_mob->GetPosition(), mob->GetPosition());
if (distance <= scan_range) { if (distance <= scan_range) {
close_mobs.insert(std::pair<uint16, Mob*>(mob->GetID(), mob)); close_mobs.insert(std::pair<uint16, Mob*>(mob->GetID(), mob));
} }
@@ -9480,7 +9489,7 @@ bool Bot::CastChecks(uint16 spellid, Mob* tar, uint16 spellType, bool doPrecheck
return false; return false;
} }
if (!IsCommandedSpell() && !taunting && GetSpellTypeAggroCheck(spellType) && HasOrMayGetAggro(IsSitting(), spellid) && !tar->IsFleeing()) { if (!IsCommandedSpell() && !IsTaunting() && GetSpellTypeAggroCheck(spellType) && HasOrMayGetAggro(IsSitting(), spellid) && !tar->IsFleeing()) {
LogBotPreChecksDetail("{} says, 'Cancelling cast of {} on {} due to HasOrMayGetAggro.'", GetCleanName(), GetSpellName(spellid), tar->GetCleanName()); //deleteme LogBotPreChecksDetail("{} says, 'Cancelling cast of {} on {} due to HasOrMayGetAggro.'", GetCleanName(), GetSpellName(spellid), tar->GetCleanName()); //deleteme
return false; return false;
} }
@@ -10831,7 +10840,7 @@ bool Bot::AttemptAICastSpell(uint16 spellType) {
Mob* tar = GetTarget(); Mob* tar = GetTarget();
if (!taunting && GetSpellTypeAggroCheck(spellType) && HasOrMayGetAggro(IsSitting())) { if (!IsTaunting() && GetSpellTypeAggroCheck(spellType) && HasOrMayGetAggro(IsSitting())) {
LogBotPreChecksDetail("{} says, 'Cancelling cast of [{}] due to GetSpellTypeAggroCheck and HasOrMayGetAggro.'", GetCleanName(), GetSpellTypeNameByID(spellType)); //deleteme LogBotPreChecksDetail("{} says, 'Cancelling cast of [{}] due to GetSpellTypeAggroCheck and HasOrMayGetAggro.'", GetCleanName(), GetSpellTypeNameByID(spellType)); //deleteme
return result; return result;
} }
@@ -11058,63 +11067,81 @@ void Bot::SetCombatJitter() {
} }
} }
void Bot::DoCombatPositioning(Mob* tar, glm::vec3 Goal, bool stopMeleeLevel, float tar_distance, float melee_distance_min, float melee_distance, float melee_distance_max, bool behindMob) { void Bot::DoCombatPositioning(
Mob* tar,
glm::vec3 Goal,
bool stopMeleeLevel,
float tar_distance,
float melee_distance_min,
float melee_distance,
float melee_distance_max,
bool behindMob,
bool frontMob
) {
//LogTestDebug("{} says, 'DoCombatPositioning. {} #{}", GetCleanName(), __FILE__, __LINE__); //deleteme
if (HasTargetReflection()) { if (HasTargetReflection()) {
if (!taunting && !tar->IsFeared() && !tar->IsStunned()) { if (!IsTaunting() && !tar->IsFeared() && !tar->IsStunned()) {
if (TryEvade(tar)) { if (TryEvade(tar)) {
return; return;
} }
} }
else if (tar->IsRooted() && !IsTaunting()) { // Move non-taunters out of range - Above already checks if bot is targeted, otherwise they would stay
if (tar->IsRooted() && !taunting) { // Move non-taunters out of range - Above already checks if bot is targeted, otherwise they would stay
if (tar_distance <= melee_distance_max) { if (tar_distance <= melee_distance_max) {
if (PlotBotPositionAroundTarget(tar, Goal.x, Goal.y, Goal.z, (melee_distance_max + 1), (melee_distance_max * 2), false, taunting)) { if (PlotBotPositionAroundTarget(tar, Goal.x, Goal.y, Goal.z, (melee_distance_max + 1), (melee_distance_max * 2), false, IsTaunting())) {
RunToGoalWithJitter(Goal); RunToGoalWithJitter(Goal);
return; return;
} }
} }
} }
else if (IsTaunting() && ((tar_distance < melee_distance_min) || !frontMob)) { // Back up any bots that are too close
if (taunting && tar_distance < melee_distance_min) { // Back up any bots that are too close if (PlotBotPositionAroundTarget(tar, Goal.x, Goal.y, Goal.z, melee_distance_min, melee_distance, false, IsTaunting())) {
if (PlotBotPositionAroundTarget(tar, Goal.x, Goal.y, Goal.z, melee_distance_min, melee_distance, false, taunting)) {
RunToGoalWithJitter(Goal); RunToGoalWithJitter(Goal);
return; return;
} }
} }
} }
else { else {
if (!tar->IsFeared()) { if (!tar->IsFeared()) {
if (taunting) { // Taunting adjustments if (IsTaunting()) { // Taunting adjustments
Mob* mobTar = tar->GetTarget(); Mob* mobTar = tar->GetTarget();
if (!mobTar || mobTar == nullptr) { if (!mobTar || mobTar == nullptr) {
DoFaceCheckNoJitter(tar); DoFaceCheckNoJitter(tar);
return; return;
} }
if (RuleB(Bots, TauntingBotsFollowTopHate)) { // If enabled, taunting bots will stick to top hate if (RuleB(Bots, TauntingBotsFollowTopHate)) { // If enabled, taunting bots will stick to top hate
if ((DistanceSquared(m_Position, mobTar->GetPosition()) > pow(RuleR(Bots, DistanceTauntingBotsStickMainHate), 2))) { if (Distance(m_Position, mobTar->GetPosition()) > RuleI(Bots, DistanceTauntingBotsStickMainHate)) {
Goal = mobTar->GetPosition(); Goal = mobTar->GetPosition();
RunToGoalWithJitter(Goal); RunToGoalWithJitter(Goal);
return; return;
} }
} }
else { // Otherwise, stick to any other bots that are taunting else { // Otherwise, stick to any other bots that are taunting
if (mobTar->IsBot() && mobTar->CastToBot()->taunting && (DistanceSquared(m_Position, mobTar->GetPosition()) > pow(RuleR(Bots, DistanceTauntingBotsStickMainHate), 2))) { if (mobTar->IsBot() && mobTar->CastToBot()->IsTaunting() && (Distance(m_Position, mobTar->GetPosition()) > RuleI(Bots, DistanceTauntingBotsStickMainHate))) {
Goal = mobTar->GetPosition(); Goal = mobTar->GetPosition();
RunToGoalWithJitter(Goal); RunToGoalWithJitter(Goal);
return; return;
} }
} }
} }
else if (tar_distance < melee_distance_min || (GetBehindMob() && !behindMob) || !HasRequiredLoSForPositioning(tar)) { // Regular adjustment else if (tar_distance < melee_distance_min || (GetBehindMob() && !behindMob) || (IsTaunting() && !frontMob)|| !HasRequiredLoSForPositioning(tar)) { // Regular adjustment
if (PlotBotPositionAroundTarget(tar, Goal.x, Goal.y, Goal.z, melee_distance_min, melee_distance, GetBehindMob(), taunting)) { if (PlotBotPositionAroundTarget(tar, Goal.x, Goal.y, Goal.z, melee_distance_min, melee_distance, GetBehindMob(), IsTaunting())) {
RunToGoalWithJitter(Goal); RunToGoalWithJitter(Goal);
return; return;
} }
} }
else if (tar->IsEnraged() && !taunting && !stopMeleeLevel && !behindMob) { // Move non-taunting melee bots behind target during enrage else if (tar->IsEnraged() && !IsTaunting() && !stopMeleeLevel && !behindMob) { // Move non-taunting melee bots behind target during enrage
if (PlotBotPositionAroundTarget(tar, Goal.x, Goal.y, Goal.z, melee_distance_min, melee_distance, true)) { if (PlotBotPositionAroundTarget(tar, Goal.x, Goal.y, Goal.z, melee_distance_min, melee_distance, true)) {
RunToGoalWithJitter(Goal); RunToGoalWithJitter(Goal);
return; return;
} }
} }
@@ -11122,6 +11149,7 @@ void Bot::DoCombatPositioning(Mob* tar, glm::vec3 Goal, bool stopMeleeLevel, flo
} }
DoFaceCheckNoJitter(tar); DoFaceCheckNoJitter(tar);
return; return;
} }
+2 -2
View File
@@ -943,7 +943,7 @@ public:
Mob* tar, Mob* tar,
float tar_distance, float tar_distance,
bool& atCombatRange, bool& atCombatRange,
bool& behindMob, bool behindMob,
const EQ::ItemInstance*& p_item, const EQ::ItemInstance*& p_item,
const EQ::ItemInstance*& s_item, const EQ::ItemInstance*& s_item,
float& melee_distance_min, float& melee_distance_min,
@@ -957,7 +957,7 @@ public:
void SetCombatOutOfRangeJitterFlag(bool flag = true) { m_combat_out_of_range_jitter_flag = flag; } void SetCombatOutOfRangeJitterFlag(bool flag = true) { m_combat_out_of_range_jitter_flag = flag; }
void SetCombatJitter(); void SetCombatJitter();
void SetCombatOutOfRangeJitter(); void SetCombatOutOfRangeJitter();
void DoCombatPositioning(Mob* tar, glm::vec3 Goal, bool stopMeleeLevel, float tar_distance, float melee_distance_min, float melee_distance, float melee_distance_max, bool behindMob); void DoCombatPositioning(Mob* tar, glm::vec3 Goal, bool stopMeleeLevel, float tar_distance, float melee_distance_min, float melee_distance, float melee_distance_max, bool behindMob, bool frontMob);
void DoFaceCheckWithJitter(Mob* tar); void DoFaceCheckWithJitter(Mob* tar);
void DoFaceCheckNoJitter(Mob* tar); void DoFaceCheckNoJitter(Mob* tar);
void RunToGoalWithJitter(glm::vec3 Goal); void RunToGoalWithJitter(glm::vec3 Goal);
+1
View File
@@ -1695,6 +1695,7 @@ void bot_command_toggle_ranged(Client *c, const Seperator *sep)
else { else {
bot_iter->SetBotRangedSetting(ranged_state); bot_iter->SetBotRangedSetting(ranged_state);
} }
bot_iter->ChangeBotRangedWeapons(bot_iter->IsBotRanged()); bot_iter->ChangeBotRangedWeapons(bot_iter->IsBotRanged());
} }
} }