Fixed a few bot issues...

This commit is contained in:
Uleat 2018-10-06 23:23:29 -04:00
parent d8c6c62809
commit 94c17f941c
5 changed files with 89 additions and 4 deletions

View File

@ -1,5 +1,11 @@
EQEMu Changelog (Started on Sept 24, 2003 15:50)
-------------------------------------------------------
== 10/06/2018 ==
Uleat: Fixed a few bot issues..
- Fix for bot 'stop melee level' not honoring setting level over rule level
- Fix for missing bot combat spell casting when within melee range
- Fix (in-work) for bots 'forgetting' current target when it flees
== 07/10/2018 ==
Akkadius: Adjusted DataBuckets to use other acceptable time formats
Example: quest::set_data('key', 'value', '1d');

View File

@ -2261,10 +2261,15 @@ void Bot::AI_Process() {
}
if (find_target) {
if (IsRooted())
if (IsRooted()) {
SetTarget(hate_list.GetClosestEntOnHateList(this));
else
SetTarget(hate_list.GetEntWithMostHateOnList(this));
}
else {
// This will keep bots on target for now..but, future updates will allow for rooting/stunning
SetTarget(hate_list.GetEscapingEntOnHateList(leash_owner, BOT_LEASH_DISTANCE));
if (!GetTarget())
SetTarget(hate_list.GetEntWithMostHateOnList(this));
}
}
TEST_TARGET();
@ -2471,6 +2476,8 @@ void Bot::AI_Process() {
ChangeBotArcherWeapons(IsBotArcher());
}
// all of this needs review...
if (IsBotArcher() && atArcheryRange)
atCombatRange = true;
else if (caster_distance_max && tar_distance <= caster_distance_max)
@ -2567,6 +2574,10 @@ void Bot::AI_Process() {
}
}
if (!IsBotNonSpellFighter() && AI_EngagedCastCheck()) {
return;
}
// Up to this point, GetTarget() has been safe to dereference since the initial
// TEST_TARGET() call. Due to the chance of the target dying and our pointer
// being nullified, we need to test it before dereferencing to avoid crashes
@ -2576,7 +2587,7 @@ void Bot::AI_Process() {
if (GetTarget()->GetHPRatio() <= 99.0f)
BotRangedAttack(tar);
}
else if (!IsBotArcher() && (!(IsBotCaster() && GetLevel() >= RuleI(Bots, CasterStopMeleeLevel)))) {
else if (!IsBotArcher() && (IsBotNonSpellFighter() || GetLevel() < GetStopMeleeLevel())) {
// we can't fight if we don't have a target, are stun/mezzed or dead..
// Stop attacking if the target is enraged
TEST_TARGET();

View File

@ -534,6 +534,9 @@ public:
bool IsBotCaster() { return IsCasterClass(GetClass()); }
bool IsBotINTCaster() { return IsINTCasterClass(GetClass()); }
bool IsBotWISCaster() { return IsWISCasterClass(GetClass()); }
bool IsBotSpellFighter() { return IsSpellFighterClass(GetClass()); }
bool IsBotFighter() { return IsFighterClass(GetClass()); }
bool IsBotNonSpellFighter() { return IsNonSpellFighterClass(GetClass()); }
bool CanHeal();
int GetRawACNoShield(int &shield_ac);

View File

@ -538,6 +538,69 @@ Mob *HateList::GetRandomEntOnHateList()
return (*iterator)->entity_on_hatelist;
}
Mob *HateList::GetEscapingEntOnHateList() {
// function is still in design stage
for (auto iter : list) {
if (!iter->entity_on_hatelist)
continue;
if (!iter->entity_on_hatelist->IsFeared())
continue;
if (iter->entity_on_hatelist->IsRooted())
continue;
if (iter->entity_on_hatelist->IsMezzed())
continue;
if (iter->entity_on_hatelist->IsStunned())
continue;
return iter->entity_on_hatelist;
}
return nullptr;
}
Mob *HateList::GetEscapingEntOnHateList(Mob *center, float range, bool first) {
// function is still in design stage
if (!center)
return nullptr;
Mob *escaping_mob = nullptr;
float mob_distance = 0.0f;
for (auto iter : list) {
if (!iter->entity_on_hatelist)
continue;
if (!iter->entity_on_hatelist->IsFeared())
continue;
if (iter->entity_on_hatelist->IsRooted())
continue;
if (iter->entity_on_hatelist->IsMezzed())
continue;
if (iter->entity_on_hatelist->IsStunned())
continue;
float distance_test = DistanceSquared(center->GetPosition(), iter->entity_on_hatelist->GetPosition());
if (range > 0.0f && distance_test > range)
continue;
if (first)
return iter->entity_on_hatelist;
if (distance_test > mob_distance) {
escaping_mob = iter->entity_on_hatelist;
mob_distance = distance_test;
}
}
return escaping_mob;
}
int32 HateList::GetEntHateAmount(Mob *in_entity, bool damage)
{
struct_HateList *entity;

View File

@ -46,6 +46,8 @@ public:
Mob *GetEntWithMostHateOnList(Mob *center, Mob *skip = nullptr);
Mob *GetRandomEntOnHateList();
Mob *GetEntWithMostHateOnList();
Mob *GetEscapingEntOnHateList(); // returns first eligble entity
Mob *GetEscapingEntOnHateList(Mob *center, float range = 0.0f, bool first = false);
bool IsEntOnHateList(Mob *mob);
bool IsHateListEmpty();