EQEmulator Forums

EQEmulator Forums (https://www.eqemulator.org/forums/index.php)
-   Development::Bug Reports (https://www.eqemulator.org/forums/forumdisplay.php?f=591)
-   -   Extended Target/Bot Pet Hate Issue (https://www.eqemulator.org/forums/showthread.php?t=36747)

Uleat 04-10-2013 07:14 PM

Extended Target/Bot Pet Hate Issue
 
I am running across an issue where one of my bot's pet agros all of my other bots and their pets.

The offending bot pet and its owner, as well as my toon, are the only mobs that do not show up in the extended target window.


I think this problem has been around for a long time, but I just re-noticed it when I started playing with a RoF client. Obviously, my old
SoF client doesn't have the XT window.


There seems to be two different trigger instances for this:

1) Pet attacks its owning bot

2) Pet attacks the corpse of the previously killed mob


One of the above will only fill the XT window, so older clients will not know when this is occurring.

The other one fills up the XT window and then causes the pet to spam the invalid target message..with it likely stuck in combat.


Both seem to occur within 5 seconds of starting a fight or ending one. I don't recall seeing these trigger at any other point.

I do remember seeing the pet spam last year with my SoF client..possibly when I started playing in April/May.


I have verified the hate lists of the affected mobs in-game after many of these occurrences, and they are empty.

If anyone wants to see the Entity list dump, here is the code that I used (I dropped it in over my command_zopp code):
Code:

void command_zopp(Client *c, const Seperator *sep)
{
        if(!c) { return; }
       
        c->Message(13, "Dumping Zone Entity list... (Client, Bot, Pet)");
        LogFile->write(EQEMuLog::Debug, "Dumping Zone Entity list... (Client, Bot, Pet)");
        LogFile->write(EQEMuLog::Debug, "----------------------------------------------");

        list<Mob*> zm_list;
        entity_list.GetMobList(zm_list);

        list<Mob*>::iterator m_itr;

        for(m_itr = zm_list.begin(); m_itr != zm_list.end(); m_itr++)
        {
                Mob* m_inst = *m_itr;
                if(!m_inst || (!m_inst->IsBot() && !m_inst->IsPet() && !m_inst->IsClient())) { continue; }

                LogFile->write(EQEMuLog::Debug, "Entity Name: %s (ID: %i)",
                        m_inst->GetName(),
                        m_inst->GetID());

                if(m_inst->IsBot())
                {
                        LogFile->write(EQEMuLog::Debug, "Bot Owner Name: %s, ID: %i (BotOwnerCharacterID: %i)",
                                m_inst->CastToBot()->GetBotOwner()->GetName(),
                                m_inst->CastToBot()->GetBotOwner()->GetID(),
                                m_inst->CastToBot()->GetBotOwnerCharacterID());
                }
               
                if(m_inst->IsPet())
                {
                        LogFile->write(EQEMuLog::Debug, "Owner Name: %s, ID: %i (OwnerID: %i)",
                                m_inst->GetOwner()->GetName(),
                                m_inst->GetOwner()->GetID(),
                                m_inst->GetOwnerID());
                }

                if(m_inst->IsGrouped())
                {
                        LogFile->write(EQEMuLog::Debug, "Group Leader Name: %s (GroupID: %i)",
                                m_inst->GetGroup()->GetLeaderName(),
                                m_inst->GetGroup()->GetID());
                }

                list<tHateEntry*> he_list;
                m_inst->GetHateList(he_list);

                list<tHateEntry*>::iterator h_itr;
                for(h_itr = he_list.begin(); h_itr != he_list.end(); h_itr++)
                {
                        tHateEntry* h_inst = *h_itr;
                        if(!h_inst) { continue; }

                        LogFile->write(EQEMuLog::Debug, "Hate Entity Name: %s (ID: %i)",
                                h_inst->ent->GetName(),
                                h_inst->ent->GetID());
                }

                LogFile->write(EQEMuLog::Debug, "----------------------------------------------");
        }

        LogFile->write(EQEMuLog::Debug, "Zone Entity Dump complete...");
        c->Message(13, "Dump complete...");
}


I am trying to trace the cause of this, but if anyone else has any input, it's welcome!

Uleat 04-11-2013 08:57 PM

Follow-up: the double processing of bot pets per scan cycle...


Mob::AI_Process() checks for target->IsCorpse(), so it's not likely that this is causing the corpse trigger event..only the
bot pet owner trigger event.

Bot::PetAIProcess() -> '!botPet->IsAttackAllowed(GetTarget())' -> This checks the bot's, not the pet's, target..unsure what
response will be given. This, combined with the first melee attack also being set to the bot's target, can lead to definite
confusion as to what is a valid target and what the target actually is. It's highly likely that both owner and mob corpse
trigger events are caused here.


Testing with the Bot::PetAIProcess() call disabled 'seemed' to allow a normal operation, but the bug still triggered.

Testing with Mob::AI_Process() disabled simply denied the pets any attacks at all due to the entry return issued if the
attack timer returns true. (Bot::PetAIProcess() only processes when the attack timer is not ready, so the !IsEngaged()
portion is never really processed.)


Regardless, bot pet's are being processed twice per scan cycle. Obviously, this shouldn't be occurring... I'm guessing they
receive a 2-10% dps increase over what the actual value should be as a result.

I have also observed the pets dancing around during combat due to conflicting movement calls between the AI processes.


Below is a 'seed' patch for this issue as it disables the Bot::PetAIProcess() call and adds a specific check for bot pets
that forbids a pet from ever attacking its bot owner. This may or may not be appropriate, so do not apply this patch
directly to any operational server code..it is not meant to be a working fix.

I played with this patch for 4 hours and 5 levels with 3 of the 5 bots being pet owners. The hate/XT bug never triggered,
though thorough testing on a bot server will need to be done before that can reliably confirmed.
(I'd like to hear from people who have experienced this bug..bot pet stuck in combat after fight is over counts too.)

Also, unwanted effects due to the no-owner attack check need to be tested for in pertinent scenarios.


Someone familiar with mob entity classes should review the Bot::PetAIProcess() code to see if there are specific conditions
that should be added to the Mob::AI_Process() code. (I'm not picking on you Bad_Captain :) I know there are others.)

Since I seem to be the only one currently observing this problem, and the bug doesn't cause any playability issues, I
consider this bug low-priority and can be added to any long-term updates.

(Again, leave it to me to find the most obscure of bugs...)


Code:

zone/MobAI.cpp | 7 +++++++
 zone/bot.cpp  | 4 ++--
 2 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/zone/MobAI.cpp b/zone/MobAI.cpp
index a2030aa..292e913 100644
--- a/zone/MobAI.cpp
+++ b/zone/MobAI.cpp
@@ -1083,6 +1083,13 @@ void Mob::AI_Process() {
                        RemoveFromHateList(this);
                        return;
                }
+
+                if (IsPet() && GetOwner()->IsBot() && target == GetOwner())
+                {
+                        // this blocks all pet attacks against owner..bot pet test (copied above check)
+                        RemoveFromHateList(this);
+                        return;
+                }
     
                if(DivineAura())
                        return;
diff --git a/zone/bot.cpp b/zone/bot.cpp
index 51b649b..3ae5a3b 100644
--- a/zone/bot.cpp
+++ b/zone/bot.cpp
@@ -3123,8 +3123,8 @@ bool Bot::Process()
        AI_Process();
 
        // Bot Pet AI
-        if(HasPet())
-                PetAIProcess();
+        //if(HasPet()) // letting Mob::AI_Process() handle bot pet AI
+        //        PetAIProcess();
 
        return true;
 }


Uleat 04-16-2013 04:26 PM

Anyone more adept at troubleshooting than I am will have seen this coming...

This issue does not match my debugging path.


The bot pet hate issue is actually a bot hate issue caused by certain types of spells. (You pegged that one D!)

In the case of 'lifetap-esque' spells, Bot::Damage is passed the caster as 'from.'

Where (this == from), there's nothing to avoid wiping the hatelist from 'this' and adding of its group members to the list.


Code:

zone/bot.cpp | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/zone/bot.cpp b/zone/bot.cpp
index 51b649b..2013ad4 100644
--- a/zone/bot.cpp
+++ b/zone/bot.cpp
@@ -6364,6 +6364,8 @@ void Bot::Damage(Mob *from, int32 damage, uint16 spell_id, SkillType attack_skil
 
        SendHPUpdate();
 
+        if(this == from) { return; }
+       
        // Aggro the bot's group members
        if(IsGrouped())
        {


The double-processing of bot pets issue is still relevant, but not to bot hate..from what I can tell.

Uleat 04-18-2013 08:17 PM

I had a 23-strong mob of bots trying this last night and didn't get the results I had hoped for. I'll probably have to go back
to single-group bots to get a better sample..they made level 40 in 8 hours..naked...


Necromancer SpellIDs: 641, 642

These were triggered while it was in a botgroup, but previously they triggered in my group.

There is a 300-series (358?) spell that should be in there somewhere as well, but it didn't trigger last night.

The Shaman spell series didn't trigger either, but it may be a higher level or owner-group issue.


[probably unrelated..]
Sometimes, when I use #bot botgroup attack, the first botgroup doesn't always sic on the target. Botgroups 2 & 3, along
with my group's bots, don't have any issues..but BG 1 is first on the macro.

This doesn't appear to arise when I engage with a melee attack.

Uleat 04-19-2013 07:22 PM

These hits are based on unmodified code..only Bot::Damage() has the 'if(this == from) { Logfile->...; }' snippet.

Testbotnecromancera: SpellID: 641, Levels {6...13, 16}, Avoidable: false, iBuffTic: true
Testbotnecromancera: SpellID: 642, Levels {24..27, 29}, Avoidable: false, iBuffTic: true

Testbotshamana: SpellID: 754, Levels {45...48, 50...53}, Avoidable: false, iBuffTic: false
Testbotshamana: SpellID: 1572, Levels {54...57}, Avoidable: false, iBuffTic: false

Testbotshamanb: SpellID: 754, Levels {44...53}, Avoidable: false, iBuffTic: false
Testbotshamanb: SpellID: 1572, Levels {54...57}, Avoidable: false, iBuffTic: false


Been getting quite a few of these too:
'A null Mob object was passed to NPC::Attack() for evaluation!'
'A null Mob object was passed to Mob::TryWeaponProc for evaluation!'


SpellID: 359 - 'Vampiric Embrace' (spell that didn't show up with this testing, but did with other methods)
SpellID: 641 - 'Dark Pact'
SPellID: 642 - 'Allure of Death'
SpellID: 754 - 'Cannibalize II'
SpellID: 1572 - 'Cannibalize III'


[Main Group]
Testchar(Warrior)
Testbotshadowknighta
Testbotroguea
Testbotenchantera
Testbotbarda
Testbotclerica

[Bot Group 1]
Testbotbeastlorda
Testbotberserkera
Testbotmonka
Testbotbardb
Testbotshamana
Testbotdruida

[Bot Group 2]
Testbotmagiciana
Testbotnecromancera
Testbotpaladina
Testbotwizarda
Testbotenchanterb
Testbotclericb

[Bot Group 3]
Testbotrangera
Testbotwarriora
Testbotshadowknightb
Testbotbardc
Testbotclericc
Testbotshamanb

Uleat 04-20-2013 05:43 PM

I 'think' that I found the two places that were causing issues...

I'm still testing out this patch, but it appears to be working. I made it through level 10 with no bug triggers.

It still needs to be looked over..and it only affects bot code.


Code:

zone/bot.cpp | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/zone/bot.cpp b/zone/bot.cpp
index 51b649b..963cd2a 100644
--- a/zone/bot.cpp
+++ b/zone/bot.cpp
@@ -3122,7 +3122,7 @@ bool Bot::Process()
        // Bot AI
        AI_Process();
 
-        // Bot Pet AI
+        // Bot Pet AI // Remove when/if all bot pet features are transfered to NPC::AI_Process()
        if(HasPet())
                PetAIProcess();
 
@@ -3594,7 +3594,8 @@ void Bot::AI_Process() {
                                if(g) {
                                        for(int counter = 0; counter < g->GroupCount(); counter++) {
                                                if(g->members[counter]) {
-                                                        if(g->members[counter]->IsEngaged() && g->members[counter]->GetTarget()) {
+                                                        if(g->members[counter]->IsEngaged() && g->members[counter]->GetTarget() &&
+                                                                g->members[counter]->GetTarget() != this && this->IsAttackAllowed(g->members[counter]->GetTarget())) {
                                                                AddToHateList(g->members[counter]->GetTarget(), 1);
 
                                                                if(HasPet())
@@ -6364,8 +6365,10 @@ void Bot::Damage(Mob *from, int32 damage, uint16 spell_id, SkillType attack_skil
 
        SendHPUpdate();
 
+        if(this == from) { return; } // IsAttackAllowed() check below returns true for 'this = this'
+
        // Aggro the bot's group members
-        if(IsGrouped())
+        if(IsGrouped() && IsAttackAllowed(from))
        {
                Group *g = GetGroup();
                if(g)


I got the invalid target message from bot pets when the enchanter had a target mezzed, but this did not trigger the
Extended Target bug.

Another instance, about mid-fight in a level 12 melee, the message popped up once, but no trigger of the bug.


(The above testing was done with a fresh character and bots. I did go back with my bot mob and try to get this to
trigger in the mid-30's range - Shaman Cannibalize - and no hits there after ~150 fights.)

bad_captain 04-25-2013 12:48 AM

Try my committed code and let me know if you have any more issues.

I tried with a necro casting Ancient: Seduction of Chaos (4978) and a Shaman casting Ancient: Chaotic Pain (4979). I did not get any can't attack messages from pets and nothing showing up in the extended target window that shouldn't have, while using RoF.

There are probably other instances where this can happen, and I will continue to try to find them, but hopefully that helps.

Uleat 04-25-2013 09:49 PM

Will do, thanks for taking a look!

Kingly_Krab 01-08-2014 02:30 PM

Sorry for resurrecting such an old thread, but some of this code was never added, as the issue is still around.

I don't seem to be able to find this bit of code anywhere in the mentioned files.

May I get some confirmation as to if this is the cause of the issue, and if adding these lines would fix it?
Code:

@@ -3594,7 +3594,8 @@
void Bot::AI_Process()
{
        if(g)
        {
                for(int counter = 0; counter < g->GroupCount(); counter++)
                {
                        if(g->members[counter])
                        {
-                                if(g->members[counter]->IsEngaged() && g->members[counter]->GetTarget()) {
+                                if(g->members[counter]->IsEngaged() && g->members[counter]->GetTarget() &&
+                                        g->members[counter]->GetTarget() != this && this->IsAttackAllowed(g->members[counter]->GetTarget())) {

Code:

if(g)
{
        for(int counter = 0; counter < g->GroupCount(); counter++)
        {
                if(g->members[counter])
                {
                        Mob* tar = g->members[counter]->GetTarget();
                        if(tar && tar->IsNPC() && tar->GetHateAmount(g->members[counter]) && IsAttackAllowed(g->members[counter]->GetTarget()))
                        {
                                AddToHateList(tar, 1);
                                if(HasPet())
                                        GetPet()->AddToHateList(tar, 1);
                                break;
                        }
                }
        }
}

IsGrouped(), IsAttackAllowed() wasn't added.
Code:

@@ -6364,8 +6365,10 @@
void Bot::Damage(Mob *from, int32 damage, uint16 spell_id, SkillType attack_skill, bool avoidable, int8 buffslot, bool iBuffTic)
{
+        if(this == from) { return; } // IsAttackAllowed() check below returns true for 'this = this'
+
        // Aggro the bot's group members
-        if(IsGrouped())
+        if(IsGrouped() && IsAttackAllowed(from))

Code:

if(IsGrouped())
{
        Group *g = GetGroup();
        if(g)
        {
                for(int i=0; i<MAX_GROUP_MEMBERS; i++)
                {
                        if(g->members[i] && g->members[i]->IsBot() && from && !g->members[i]->CheckAggro(from) && g->members[i]->IsAttackAllowed(from))
                        {
                                g->members[i]->AddToHateList(from, 1);
                        }
                }
        }
}


Uleat 01-08-2014 11:35 PM

There was another thread within a day or two that mentioned similar behavior..but, I think it may have been due to their
having custom spells.

The bot spells are hand-selected and placed into categories based on their id's.

Changing the db spell data could cause bots to cast detrimental spells during the healing cycle, etc...


As far as this thread...

Bad_captain worked this issue to my satisfaction..though, I don't have an issue re-opening this if a valid bug can be found
in the current 'pbw' eqemu code and peq data.

Otherwise, we should consider this closed :)


All times are GMT -4. The time now is 08:43 AM.

Powered by vBulletin®, Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.