correct and tweak all combat positioning and combat range

This commit is contained in:
nytmyr
2024-11-10 23:35:28 -06:00
parent 161d6b3b66
commit f3c0ddd4be
4 changed files with 94 additions and 65 deletions
+4 -4
View File
@@ -842,15 +842,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_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, 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, 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, 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_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_BOOL(Bots, DisableSpecialAbilitiesAtMaxMelee, false, "False Default. If true, when bots are at max melee distance, special abilities including taunt will be disabled.")
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, 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, 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.")
+87 -59
View File
@@ -2165,7 +2165,8 @@ void Bot::AI_Process()
// COMBAT RANGE CALCS
bool atCombatRange = false;
bool behindMob = false;
bool behindMob = BehindMob(tar, GetX(), GetY());
bool frontMob = InFrontMob(tar, GetX(), GetY());
uint8 stopMeleeLevel = GetStopMeleeLevel();
const EQ::ItemInstance* p_item;
const EQ::ItemInstance* s_item;
@@ -2232,7 +2233,7 @@ void Bot::AI_Process()
}
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;
}
else {
@@ -2365,10 +2366,10 @@ bool Bot::TryNonCombatMovementChecks(Client* bot_owner, const Mob* follow_mob, g
else {
Goal = follow_mob->GetPosition();
}
float destination_distance = DistanceSquared(GetPosition(), Goal);
if ((!bot_owner->GetBotPulling() || PULLING_BOT) && (destination_distance > GetFollowDistance())) {
if (!IsRooted()) {
if (rest_timer.Enabled()) {
rest_timer.Disable();
@@ -2382,7 +2383,6 @@ bool Bot::TryNonCombatMovementChecks(Client* bot_owner, const Mob* follow_mob, g
else {
if (IsMoving()) {
StopMoving();
return true;
}
@@ -2735,7 +2735,7 @@ bool Bot::TryEvade(Mob* tar) {
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;
p_item = GetBotItem(EQ::invslot::slotPrimary);
@@ -2744,32 +2744,46 @@ void Bot::CheckCombatRange(Mob* tar, float tar_distance, bool& atCombatRange, bo
bool backstab_weapon = false;
if (GetBehindMob()) {
behindMob = BehindMob(tar, GetX(), GetY()); // Can be separated for other future use
if (GetClass() == Class::Rogue) {
backstab_weapon = p_item && p_item->GetItemBackstabDamage();
}
}
// 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 {}."
// , GetCleanName()
// , (tar_distance < melee_distance_min ? "too close to" : (tar_distance <= melee_distance ? "within range of" : "too far away from"))
// , tar->GetCleanName()
// , tar_distance
// , (tar_distance <= melee_distance ? "but only needed" : "but need to be")
// , melee_distance_min
// , melee_distance
// , melee_distance_max
//); //deleteme
if (!GetCombatRoundForAlerts()) {
SetCombatRoundForAlerts();
LogTestDebugDetail("{} says, 'I'm {} {}. I am currently {} away {} to be between [{} - {}] away. MMR is {}.'"
, GetCleanName()
, (tar_distance < melee_distance_min ? "too close to" : (tar_distance <= melee_distance ? "within range of" : "too far away from"))
, tar->GetCleanName()
, tar_distance
, (tar_distance <= melee_distance ? "but only needed" : "but need to be")
, melee_distance_min
, 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) {
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 other_size_mod = tar->GetSize();
@@ -2882,27 +2896,26 @@ void Bot::CalcMeleeDistances(const Mob* tar, const EQ::ItemInstance* const& p_it
melee_distance = RuleR(Bots, MaxDistanceForMelee);
}
melee_distance_min = melee_distance_max * RuleR(Bots, PercentMinMeleeDistance);
melee_distance_min = melee_distance * RuleR(Bots, PercentMinMeleeDistance);
if (taunting) {
melee_distance_min = melee_distance_max * RuleR(Bots, PercentTauntMinMeleeDistance);
melee_distance = melee_distance_max * RuleR(Bots, TauntNormalMeleeRangeDistance);
if (IsTaunting()) {
melee_distance_min = melee_distance * RuleR(Bots, PercentTauntMinMeleeDistance);
melee_distance = melee_distance * RuleR(Bots, TauntNormalMeleeRangeDistance);
}
bool isStopMeleeLevel = GetLevel() >= stopMeleeLevel;
if (!taunting && !IsBotRanged() && !isStopMeleeLevel && GetMaxMeleeRange()) {
melee_distance = melee_distance_max * RuleR(Bots, PercentMaxMeleeRangeDistance);
if (!IsTaunting() && !IsBotRanged() && !isStopMeleeLevel && GetMaxMeleeRange()) {
melee_distance_min = melee_distance_max * RuleR(Bots, PercentMinMaxMeleeRangeDistance);
melee_distance = melee_distance_max * RuleR(Bots, PercentMaxMeleeRangeDistance);
}
if (isStopMeleeLevel && !IsBotRanged()) {
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);
}
/* Archer Checks*/
if (IsBotRanged()) {
float minDistance = RuleI(Combat, MinRangedAttackDist);
float maxDistance = GetBotRangedValue();
@@ -3005,7 +3018,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
if (fm_distance <= GetFollowDistance()) {
// Once we're back, clear blocking flags so everyone else can join in
@@ -3024,13 +3036,12 @@ bool Bot::ReturningFlagChecks(Client* bot_owner, float fm_distance) {// Need to
WipeHateList();
return false;
}
return true;
}
bool Bot::PullingFlagChecks(Client* bot_owner) {
if (!GetTarget()) {
WipeHateList();
SetTarget(nullptr);
SetPullingFlag(false);
@@ -3044,7 +3055,6 @@ bool Bot::PullingFlagChecks(Client* bot_owner) {
return false;
}
else if (GetTarget()->GetHateList().size()) {
WipeHateList();
SetTarget(nullptr);
SetPullingFlag(false);
@@ -3066,7 +3076,6 @@ bool Bot::PullingFlagChecks(Client* bot_owner) {
}
void Bot::HealRotationChecks() {
if (IsMyHealRotationSet()) {
if (AIHealRotation(HealRotationTarget(), UseHealRotationFastHeals())) {
m_member_of_heal_rotation->SetMemberIsCasting(this);
@@ -3081,7 +3090,6 @@ void Bot::HealRotationChecks() {
}
bool Bot::IsAIProcessValid(const Client* bot_owner, const Group* bot_group, const Raid* raid) {
if (!bot_owner || (!bot_group && !raid) || !IsAIControlled()) {
return false;
}
@@ -3091,11 +3099,11 @@ bool Bot::IsAIProcessValid(const Client* bot_owner, const Group* bot_group, cons
SetBotOwner(nullptr);
return false;
}
return true;
}
bool Bot::CheckIfCasting(float fm_distance) {
if (IsCasting()) {
if (IsHealRotationMember() &&
m_member_of_heal_rotation->CastingOverride() &&
@@ -3107,12 +3115,10 @@ bool Bot::CheckIfCasting(float fm_distance) {
InterruptSpell();
}
else if (AmICastingForHealRotation() && m_member_of_heal_rotation->CastingMember() == this) {
AdvanceHealRotation(false);
return true;
}
else if (GetClass() != Class::Bard) {
if (IsEngaged()) {
return true;
}
@@ -3130,13 +3136,12 @@ bool Bot::CheckIfCasting(float fm_distance) {
else if (IsHealRotationMember()) {
m_member_of_heal_rotation->SetMemberIsCasting(this, false);
}
return false;
}
bool Bot::CheckIfIncapacitated() {
if (GetPauseAI() || IsStunned() || IsMezzed() || (GetAppearance() == eaDead)) {
if (IsCasting()) {
InterruptSpell();
}
@@ -3145,6 +3150,7 @@ bool Bot::CheckIfIncapacitated() {
AdvanceHealRotation(false);
m_member_of_heal_rotation->SetMemberIsCasting(this, false);
}
return true;
}
@@ -3190,29 +3196,29 @@ void Bot::SetBerserkState() {// Berserk updates should occur if primary AI crite
Mob* Bot::SetFollowMob(Client* leash_owner) {
Mob* follow_mob = entity_list.GetMob(GetFollowID());
if (!follow_mob) {
if (!follow_mob) {
follow_mob = leash_owner;
SetFollowID(leash_owner->GetID());
}
return follow_mob;
}
Client* Bot::SetLeashOwner(Client* bot_owner, Group* bot_group, Raid* raid, uint32 r_group) const {
Client* leash_owner = nullptr;
if (raid && r_group < MAX_RAID_GROUPS && raid->GetGroupLeader(r_group)) {
leash_owner =
raid->GetGroupLeader(r_group) &&
raid->GetGroupLeader(r_group)->IsClient() ?
raid->GetGroupLeader(r_group)->CastToClient() : bot_owner;
} else if (bot_group) {
leash_owner = (bot_group->GetLeader() && bot_group->GetLeader()->IsClient() ? bot_group->GetLeader()->CastToClient() : bot_owner);
} else {
leash_owner = bot_owner;
}
return leash_owner;
}
@@ -3237,6 +3243,7 @@ void Bot::SetOwnerTarget(Client* bot_owner) {
AddToHateList(attack_target, 1);
SetTarget(attack_target);
SetAttackingFlag();
if (GetPet() && (GetClass() != Class::Enchanter || GetPet()->GetPetType() != petAnimation || GetAA(aaAnimationEmpathy) >= 2)) {
GetPet()->WipeHateList();
GetPet()->AddToHateList(attack_target, 1);
@@ -3277,8 +3284,8 @@ void Bot::BotPullerProcess(Client* bot_owner, Raid* raid) {
SetTarget(pull_target);
SetPullingFlag();
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()->SetTarget(nullptr);
m_previous_pet_order = GetPet()->GetPetOrder();
@@ -5121,7 +5128,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) {
BotGroupSay(
this,
@@ -6747,6 +6754,7 @@ void Bot::Zone() {
bool Bot::IsAtRange(Mob *target) {
bool result = false;
if (target) {
float range = (GetBotRangedValue() + 5.0);
range *= range;
@@ -7490,6 +7498,7 @@ void EntityList::ScanCloseClientMobs(std::unordered_map<uint16, Mob*>& close_mob
}
float distance = DistanceSquared(scanning_mob->GetPosition(), mob->GetPosition());
if (distance <= scan_range) {
close_mobs.insert(std::pair<uint16, Mob*>(mob->GetID(), mob));
}
@@ -9469,7 +9478,7 @@ bool Bot::CastChecks(uint16 spellid, Mob* tar, uint16 spellType, bool doPrecheck
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
return false;
}
@@ -10820,7 +10829,7 @@ bool Bot::AttemptAICastSpell(uint16 spellType) {
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
return result;
}
@@ -11047,63 +11056,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 (!taunting && !tar->IsFeared() && !tar->IsStunned()) {
if (!IsTaunting() && !tar->IsFeared() && !tar->IsStunned()) {
if (TryEvade(tar)) {
return;
}
}
if (tar->IsRooted() && !taunting) { // Move non-taunters out of range - Above already checks if bot is targeted, otherwise they would stay
else if (tar->IsRooted() && !IsTaunting()) { // Move non-taunters out of range - Above already checks if bot is targeted, otherwise they would stay
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);
return;
}
}
}
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, taunting)) {
else if (IsTaunting() && ((tar_distance < melee_distance_min) || !frontMob)) { // Back up any bots that are too close
if (PlotBotPositionAroundTarget(tar, Goal.x, Goal.y, Goal.z, melee_distance_min, melee_distance, false, IsTaunting())) {
RunToGoalWithJitter(Goal);
return;
}
}
}
else {
if (!tar->IsFeared()) {
if (taunting) { // Taunting adjustments
if (IsTaunting()) { // Taunting adjustments
Mob* mobTar = tar->GetTarget();
if (!mobTar || mobTar == nullptr) {
DoFaceCheckNoJitter(tar);
return;
}
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();
RunToGoalWithJitter(Goal);
return;
}
}
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();
RunToGoalWithJitter(Goal);
return;
}
}
}
else if (tar_distance < melee_distance_min || (GetBehindMob() && !behindMob) || !HasRequiredLoSForPositioning(tar)) { // Regular adjustment
if (PlotBotPositionAroundTarget(tar, Goal.x, Goal.y, Goal.z, melee_distance_min, melee_distance, GetBehindMob(), taunting)) {
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(), IsTaunting())) {
RunToGoalWithJitter(Goal);
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)) {
RunToGoalWithJitter(Goal);
return;
}
}
@@ -11111,6 +11138,7 @@ void Bot::DoCombatPositioning(Mob* tar, glm::vec3 Goal, bool stopMeleeLevel, flo
}
DoFaceCheckNoJitter(tar);
return;
}
+2 -2
View File
@@ -943,7 +943,7 @@ public:
Mob* tar,
float tar_distance,
bool& atCombatRange,
bool& behindMob,
bool behindMob,
const EQ::ItemInstance*& p_item,
const EQ::ItemInstance*& s_item,
float& melee_distance_min,
@@ -957,7 +957,7 @@ public:
void SetCombatOutOfRangeJitterFlag(bool flag = true) { m_combat_out_of_range_jitter_flag = flag; }
void SetCombatJitter();
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 DoFaceCheckNoJitter(Mob* tar);
void RunToGoalWithJitter(glm::vec3 Goal);
+1
View File
@@ -1695,6 +1695,7 @@ void bot_command_toggle_ranged(Client *c, const Seperator *sep)
else {
bot_iter->SetBotRangedSetting(ranged_state);
}
bot_iter->ChangeBotRangedWeapons(bot_iter->IsBotRanged());
}
}