mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-13 18:51:29 +00:00
Fixed a few bot issues...
This commit is contained in:
parent
d8c6c62809
commit
94c17f941c
@ -1,5 +1,11 @@
|
|||||||
EQEMu Changelog (Started on Sept 24, 2003 15:50)
|
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 ==
|
== 07/10/2018 ==
|
||||||
Akkadius: Adjusted DataBuckets to use other acceptable time formats
|
Akkadius: Adjusted DataBuckets to use other acceptable time formats
|
||||||
Example: quest::set_data('key', 'value', '1d');
|
Example: quest::set_data('key', 'value', '1d');
|
||||||
|
|||||||
17
zone/bot.cpp
17
zone/bot.cpp
@ -2261,11 +2261,16 @@ void Bot::AI_Process() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (find_target) {
|
if (find_target) {
|
||||||
if (IsRooted())
|
if (IsRooted()) {
|
||||||
SetTarget(hate_list.GetClosestEntOnHateList(this));
|
SetTarget(hate_list.GetClosestEntOnHateList(this));
|
||||||
else
|
}
|
||||||
|
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));
|
SetTarget(hate_list.GetEntWithMostHateOnList(this));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TEST_TARGET();
|
TEST_TARGET();
|
||||||
|
|
||||||
@ -2471,6 +2476,8 @@ void Bot::AI_Process() {
|
|||||||
ChangeBotArcherWeapons(IsBotArcher());
|
ChangeBotArcherWeapons(IsBotArcher());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// all of this needs review...
|
||||||
|
|
||||||
if (IsBotArcher() && atArcheryRange)
|
if (IsBotArcher() && atArcheryRange)
|
||||||
atCombatRange = true;
|
atCombatRange = true;
|
||||||
else if (caster_distance_max && tar_distance <= caster_distance_max)
|
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
|
// 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
|
// 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
|
// 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)
|
if (GetTarget()->GetHPRatio() <= 99.0f)
|
||||||
BotRangedAttack(tar);
|
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..
|
// we can't fight if we don't have a target, are stun/mezzed or dead..
|
||||||
// Stop attacking if the target is enraged
|
// Stop attacking if the target is enraged
|
||||||
TEST_TARGET();
|
TEST_TARGET();
|
||||||
|
|||||||
@ -534,6 +534,9 @@ public:
|
|||||||
bool IsBotCaster() { return IsCasterClass(GetClass()); }
|
bool IsBotCaster() { return IsCasterClass(GetClass()); }
|
||||||
bool IsBotINTCaster() { return IsINTCasterClass(GetClass()); }
|
bool IsBotINTCaster() { return IsINTCasterClass(GetClass()); }
|
||||||
bool IsBotWISCaster() { return IsWISCasterClass(GetClass()); }
|
bool IsBotWISCaster() { return IsWISCasterClass(GetClass()); }
|
||||||
|
bool IsBotSpellFighter() { return IsSpellFighterClass(GetClass()); }
|
||||||
|
bool IsBotFighter() { return IsFighterClass(GetClass()); }
|
||||||
|
bool IsBotNonSpellFighter() { return IsNonSpellFighterClass(GetClass()); }
|
||||||
bool CanHeal();
|
bool CanHeal();
|
||||||
int GetRawACNoShield(int &shield_ac);
|
int GetRawACNoShield(int &shield_ac);
|
||||||
|
|
||||||
|
|||||||
@ -538,6 +538,69 @@ Mob *HateList::GetRandomEntOnHateList()
|
|||||||
return (*iterator)->entity_on_hatelist;
|
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)
|
int32 HateList::GetEntHateAmount(Mob *in_entity, bool damage)
|
||||||
{
|
{
|
||||||
struct_HateList *entity;
|
struct_HateList *entity;
|
||||||
|
|||||||
@ -46,6 +46,8 @@ public:
|
|||||||
Mob *GetEntWithMostHateOnList(Mob *center, Mob *skip = nullptr);
|
Mob *GetEntWithMostHateOnList(Mob *center, Mob *skip = nullptr);
|
||||||
Mob *GetRandomEntOnHateList();
|
Mob *GetRandomEntOnHateList();
|
||||||
Mob *GetEntWithMostHateOnList();
|
Mob *GetEntWithMostHateOnList();
|
||||||
|
Mob *GetEscapingEntOnHateList(); // returns first eligble entity
|
||||||
|
Mob *GetEscapingEntOnHateList(Mob *center, float range = 0.0f, bool first = false);
|
||||||
|
|
||||||
bool IsEntOnHateList(Mob *mob);
|
bool IsEntOnHateList(Mob *mob);
|
||||||
bool IsHateListEmpty();
|
bool IsHateListEmpty();
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user