Rewrite ^pull logic and handling. **MORE**

Add ^setassistee command to set who your bots will assist. Bots will always assist you first before anyone else.

If the rule Bots, AllowCrossGroupRaidAssist is enabled bots will assist the group or raid main assists.

Rewrites logic in handling of pull and returning to ensure bots make it back to their location.
This commit is contained in:
nytmyr
2024-12-05 07:21:34 -06:00
parent d6df4aae3f
commit 3d4474861c
6 changed files with 199 additions and 25 deletions
+133 -25
View File
@@ -2039,6 +2039,7 @@ void Bot::AI_Process()
auto raid = entity_list.GetRaidByBotName(GetName());
uint32 r_group = RAID_GROUPLESS;
if (raid) {
raid->VerifyRaid();
r_group = raid->GetGroup(GetName());
@@ -2135,7 +2136,6 @@ void Bot::AI_Process()
// RETURNING FLAG
if (GetReturningFlag()) {
LogTestDebugDetail("#{}: {} has ReturningFlag", __LINE__, GetCleanName()); //deleteme
ReturningFlagChecks(bot_owner, leash_owner, fm_distance);
return;
@@ -2208,6 +2208,7 @@ void Bot::AI_Process()
if (!DoLosChecks(this, tar)) {
return;
}
if (atCombatRange) {
if (RuleB(Bots, AllowRangedPulling) && IsBotRanged() && ranged_timer.Check(false)) {
StopMoving(CalculateHeadingToTarget(tar->GetX(), tar->GetY()));
@@ -2244,8 +2245,8 @@ void Bot::AI_Process()
}
TryPursueTarget(leash_distance, Goal);
return;
//TODO bot rewrite - need pulling checks below to prevent assist
}
// ENGAGED AT COMBAT RANGE
@@ -2457,42 +2458,150 @@ bool Bot::TryAutoDefend(Client* bot_owner, float leash_distance) {
if (
m_auto_defend_timer.Check() &&
bot_owner->GetAggroCount() &&
NOT_HOLDING &&
NOT_PASSIVE
) {
auto xhaters = bot_owner->GetXTargetAutoMgr();
XTargetAutoHaters* tempHaters;
std::vector<XTargetAutoHaters*> assisteeHaters;
std::vector<Client*> assisteeMembers;
bool found = false;
if (xhaters && !xhaters->empty()) {
for (auto hater_iter : xhaters->get_list()) {
if (!hater_iter.spawn_id) {
continue;
}
if (bot_owner->GetAggroCount()) {
tempHaters = bot_owner->GetXTargetAutoMgr();
if (bot_owner->GetBotPulling() && bot_owner->GetTarget() && hater_iter.spawn_id == bot_owner->GetTarget()->GetID()) {
continue;
}
if (tempHaters && !tempHaters->empty()) {
assisteeHaters.emplace_back(tempHaters);
assisteeMembers.emplace_back(bot_owner);
}
}
auto hater = entity_list.GetMob(hater_iter.spawn_id);
if (hater && hater->CastToNPC()->IsOnHatelist(bot_owner) && !hater->IsMezzed() && DistanceSquared(hater->GetPosition(), bot_owner->GetPosition()) <= leash_distance) {
// This is roughly equivilent to npc attacking a client pet owner
AddToHateList(hater, 1);
SetTarget(hater);
SetAttackingFlag();
if (
(!bot_owner->GetAssistee() || !entity_list.GetClientByCharID(bot_owner->GetAssistee())) &&
RuleB(Bots, AllowCrossGroupRaidAssist)
) {
XTargetAutoHaters* temp_xhaters = bot_owner->GetXTargetAutoMgr();
bool assisteeFound = false;
if (HasPet() && (GetClass() != Class::Enchanter || GetPet()->GetPetType() != petAnimation || GetAA(aaAnimationEmpathy) >= 2)) {
GetPet()->AddToHateList(hater, 1);
GetPet()->SetTarget(hater);
if (IsRaidGrouped()) {
Raid* r = entity_list.GetRaidByBotName(GetName());
if (r) {
for (const auto& m : r->members) {
if (
m.member &&
m.member->IsClient() &&
m.member->GetAggroCount() &&
r->IsAssister(m.member_name)
) {
temp_xhaters = m.member->GetXTargetAutoMgr();
if (!temp_xhaters || temp_xhaters->empty()) {
continue;
}
assisteeHaters.emplace_back(temp_xhaters);
assisteeMembers.emplace_back(m.member);
}
}
}
}
else if (HasGroup()) {
Group* g = GetGroup();
if (g) {
for (auto& m : g->members) {
if (
m &&
m->IsClient() &&
m->CastToClient()->GetAggroCount() &&
g->AmIMainAssist(m->GetName())
) {
temp_xhaters = m->CastToClient()->GetXTargetAutoMgr();
m_auto_defend_timer.Disable();
if (!temp_xhaters || temp_xhaters->empty()) {
continue;
}
return true;
assisteeHaters.emplace_back(temp_xhaters);
assisteeMembers.emplace_back(m->CastToClient());
}
}
}
}
else {
return false;
}
}
else {
if (bot_owner->GetAssistee()) {
Client* c = entity_list.GetClientByCharID(bot_owner->GetAssistee());
if (bot_owner->IsInGroupOrRaid(c) && c->GetAggroCount()) {
tempHaters = bot_owner->GetXTargetAutoMgr();
if (tempHaters && !tempHaters->empty()) {
assisteeHaters.emplace_back(tempHaters);
assisteeMembers.emplace_back(c);
}
}
}
}
if (!assisteeHaters.empty()) {
for (XTargetAutoHaters* xHaters : assisteeHaters) {
if (!xHaters->empty()) {
for (auto hater_iter : xHaters->get_list()) {
if (!hater_iter.spawn_id) {
continue;
}
Mob* hater = nullptr;
for (Client* xMember : assisteeMembers) {
if (
xMember &&
xMember->GetBotPulling() &&
xMember->GetTarget() &&
(hater_iter.spawn_id == xMember->GetTarget()->GetID())
) {
continue;
}
hater = entity_list.GetMob(hater_iter.spawn_id);
if (
hater &&
!hater->IsMezzed() &&
(DistanceSquared(hater->GetPosition(), bot_owner->GetPosition()) <= leash_distance) &&
hater->CastToNPC()->IsOnHatelist(xMember)
) {
break;
}
hater = nullptr;
}
if (hater) {
AddToHateList(hater, 1);
SetTarget(hater);
SetAttackingFlag();
if (HasPet() && (GetClass() != Class::Enchanter || GetPet()->GetPetType() != petAnimation || GetAA(aaAnimationEmpathy) >= 2)) {
GetPet()->AddToHateList(hater, 1);
GetPet()->SetTarget(hater);
}
m_auto_defend_timer.Disable();
return true;
}
}
}
}
}
return false;
}
}
return false;
}
@@ -3052,6 +3161,7 @@ bool Bot::ReturningFlagChecks(Client* bot_owner, Mob* leash_owner, float fm_dist
Goal = follow_mob->GetPosition();
}
RunTo(Goal.x, Goal.y, Goal.z);
}
@@ -11283,8 +11393,6 @@ void Bot::DoCombatPositioning(
bool behindMob,
bool frontMob
) {
//LogTestDebug("{} says, 'DoCombatPositioning. {} #{}", GetCleanName(), __FILE__, __LINE__); //deleteme
if (HasTargetReflection()) {
if (!IsTaunting() && !tar->IsFeared() && !tar->IsStunned()) {
if (TryEvade(tar)) {