On Hold: Pets On Transports

Edit 2012-12-25: Reviving an old topic because I really, really want to solve this issue

Edit 2012-12-30: Progress updates will be posted further down in this thread

Edit 2013-02-11: On hold indefinitely. Moving on.

So I’ve been playing with the issue of pets not staying with their master on transports and I’m wondering exactly what is missing from the Pet class?

At first I thought we could just add the pet as an NPCPassenger when we add the player. Then I realized the pet doesn’t even see the transport at all. When the pet runs off the end of the dock it falls immediately into the ocean. Similarly, when you summon your pet on the transport it never appears on the deck next to you, it is summoned into the water below.

Is there a missing inheritance that would allow the pet to even see the boat so it won’t run off the end of the dock? I played around with it for a few hours the other night but the only thing I accomplished was creative ways to crash a server.

My wife loves her pets but they do crazy things. Whenever I play with her I tell her to get rid of the pet because she either can’t control it or it does something insane that gets me stuck in combat or killed. If you can make pets less stupid I might not have to keep putting her pets down. /emoticons/default_smile.png

Well pets in general are getting closer to retail. The main problem with them now is the terrain / evade bug. I think you might be experiencing a person who just needs more practice with pet control.

As for my OP, I can’t figure out why the pets don’t at least treat the transport like any other object and walk on it, they just fall off the end of the dock like the boat isn’t even there.

Maybe it’s another map / vmap issue. I seem to remember they used to stand on the boats but they’d fall off when it moved.

Take a look at Transport::AddNPCPassenger. You are correct that pets used to stand on the boats until they started to move. Now that we have dynamic vmaps, and transports are dynamic GOs, you are probably right about some code needing to be fixed there as well. It used to be a single issue of the pet needing to be bound to the transport GO so it moved with it. When Silinoron added the code for NPCs on transports, he did most of the work to make pets on transports a possibility.

– Brian

It appears that GO_SET_ACTIVE isn’t happening for pets. With the new dynamic GO LoS system, the GO must be active for the NPC to “see” it, and that isn’t the case with pets and transports.

I’m still digging through code, but this should be easily fixable, if we can find WHERE to fix it.

– Brian

Yeah, I had already tried AddNPCPassenger but it caused the server to crash when I dismissed / called the pet. I think somewhere I missed removing the pet as a passenger.

GO_SET_ACTIVE doesn’t exist…did you mean GO_STATE_ACTIVE or GO_STATE_READY?

GO_STATE_ACTIVE is used when the transport starts moving so that’s probably not it…

This is a dumb question, but do pets fall through other GOs? Have you tried to revert to the rev before dynamic LoS was added – to see if we are both on crack and pets never did “see” transports.

– Brian

Well, pets can stand on chairs and tables without falling through - although I don’t know if those are the same type of GO that a boat is.

I’m trying to find that Dynamic LOS commit now do you remember the date?

https://github.com/TrinityCore/TrinityCore/commit/93d199f04382fe3c7f6f08f59fd2ad058568679a . I have tested pets on ICC’s GB before DLOS and they were falling.

Still messing around with this but no luck so far.

I think part of the problem is pets don’t get / send movement opcodes like players do. There is an opcode that causes the core to add the player to the transport when the player steps off the dock but it doesn’t fire for pets.

It’s odd though that pets just fall off into the water. When it comes to other GOs such as chairs and mailboxes, they will climb over them but boats just don’t seem to exist in their world.

Trying a few things, will provide updates here. Just open the spoiler to reveal a list

of updates (also collapsed in spoiler tags).

Color code: red = not working, green = working, blue = untested

Update #12 - 2013-01-26

Still working on this. Finished the “quest levels in dialogs” patch. Updated my local repo and am working on building mmaps. Will revisit this after I get mmaps working to see if they make any difference.

Update #11 - 2013-01-19

Still working on this. Got sidetracked working on other things, among them a patch to show quest levels in dialogs… (coming soon).

Update #10 - 2013-01-11

Haven’t had a chance to even touch this lately. Haven’t forgot about it though.

Update #9 - 2013-01-04

Still working on the issues from #8 (though not in the past couple days).

Update #8 - 2012-12-31

[ul]
[li]Follow owner onto transport[/li]
[li]Follow owner off transport[/li]

Pet stuck at walk speed until reach target after exiting transport

If transport moves in this time, it “sweeps” the pet away too

[/ul]

[li]Move around on transport with owner[/li][li]Pet stays on transport when transport moves[/li][li]Pet stays on transport at transport departure[/li][li]Pet not placed on transport after loading screen for destination zone[/li][li]“Call Pet” - pet properly placed on transport[/li][ul]
Only if transport is not in motion

[/ul]

[li]“Revive Pet” - pet properly placed on transport[/li][ul]
Only if transport is not in motion

[/ul]

[li]Combat[/li]

Update #7 - 2012-12-30

It looks like setting the pet’s movementInfo to Transport->CalculatePassengerOffset() will do the trick.

I took a bunch of location readings in Transport->AddPetPassenger() and the result of CalculatePassengerOffset()

was very close to the values contained in the player’s movementInfo struct.

Will test and post results after some sleep.

Update #6 - 2012-12-30

Got a PM that the new transport code won’t be ready for a while…

It seems that there are several calls to IsWithinDistInMap() that cause the pet to despawn

because the coordinates are way off when either the pet or owner are on a transport.

For example:

Pet is on the dock - GetPositionX() = 6453.3452

Owner is on boat - GetPositionX() = -4.231

… naturally this causes the pet to not be within visibility of owner and it despawns

Update #5 - 2012-12-27

Same issues as Update #3. Also, will slow down on working on this until the new

transport code is released.

Update #4 - 2012-12-26

No new updates. Taking a break, expect to resume later today or tomorrow.

Update #3 - 2012-12-26

Minor tweaks, break a few things /emoticons/default_smile.png

[ul]
[li]Follow owner onto transport[/li]
[li]Follow owner off transport[/li]
Pet stuck at walk speed for about 30 seconds after exiting transport

[/ul]

[li]Move around on transport with owner[/li][li]Pet stays on transport when transport moves[/li][ul]

Pet stays on transport at transport departure

[li]Pet not placed on transport after loading screen for destination zone[/li](it sort of flies through the air until it catches up)

[/ul]

[li]“Call Pet” - pet properly placed on transport[/li][li]“Revive Pet” - pet properly placed on transport[/li][li]Combat[/li]

Update #2 - 2012-12-25

Minor tweaks, fix a few problems

[ul]
[li]Follow owner onto transport[/li]
[li]Follow owner off transport[/li][li]Move around on transport with owner[/li][li]Pet stays on transport when transport moves[/li][li]“Call Pet” - pet properly placed on transport[/li][li]“Revive Pet” - pet properly placed on transport[/li]
It was just playing dead, I swear /emoticons/default_wink.png

[/ul]

[li]Combat[/li]

Update #1 - 2012-12-25

Initial code testing

[ul]
[li]Follow owner onto transport[/li]
[li]Follow owner off transport[/li][li]Move around on transport with owner[/li][li]Pet stays on transport when transport moves[/li][li]“Call Pet” - pet properly placed on transport[/li]
[li]“Revive Pet” - pet properly placed on transport[/li]
[li]Combat[/li][/ul]

I took advantage of the holiday break to build a new core and start playing the client again after a long break. I’ll have to get my wife to play and check out all the pet improvements you’ve done during my absence. She loves her pets and I often would tell her no pets because they frequently behaved so badly they got one or both of us killed. With the evade fixes and pet fixes they should be more team friendly now. Thanks for the tenacity in squashing so many pet bugs. /emoticons/default_smile.png

+MrSmite No, don’t work on this yet, you’d end up hacking even more the current hack-a-hell transport system, wait for Shauren to commit his transport system changes, then work on it.

+Subv

I actually don’t use the transport code at all other than a “AddPetPassenger()” function I wrote. I use the movementhandler’s _reachTarget() method to check if the target is on a transport. If it is then logically the pet is too. I then just add the pet to the transport (it actually just sets a few flags) and adjust the Z axis properly.

I definitely won’t push a PR until Shauren is done though.

+Zaranthos

I do hope you and your wife find her pets much more enjoyable. I remember on retail how Hunters got a bad name when it was really a bugged pet.

As a Hunter I feel a broken pet system is pretty much the same as a Mage with a broken spell system.

PS: You might want to grab this PR which is still pending. It fixes pets lagging behind and despawning.

MrSmite, and… what about elevators? the pets remain on ground in those cases too (for example… in thunder bluff, thousand needles or shattrath)

+durotar

Elevators are still considered transports so they should function the same. I will certainly be testing that though.

The hardest part about the whole thing isn’t the transport code (adding / removing, I’ve got that working) it’s figuring out when to add / remove. Pets don’t send CMSG_MOVE_CHNG_TRANSPORT like players do which tells the worldhandler to add / remove the player.

This might be kind of dumb but, when the server receives the transport packets from the player doesn’t that also imply that the pet should also be on the transport? So, can’t we just check if the player has a pet and then add the pet to the transport if it exists?

I also noticed that pets occasionally have problems saving auras and receive errors such as these:

SQL(p): INSERT INTO pet_aura (guid, caster_guid, spell, effect_mask, recalculate_mask, stackcount, amount0, amount1, amount2, base_amount0, base_amount1, base_amount2, maxduration, remaintime, remaincharges) VALUES (‘30921’, ‘17379391294765825854’, ‘34655’, ‘2’, ‘2’, ‘1’, ‘0’, ‘15’, ‘0’, ‘0’, ‘14’, ‘0’, ‘8000’, ‘7600’, ‘0’)
[ERROR]: [1062] Duplicate entry ‘30921-34655-2’ for key ‘PRIMARY’

+Nex

No, it isn’t that simple. The pet doesn’t reach the transport the same time as the player:

[ul][li]Pet follows approx. 5 yards behind player by default[/li][li]Pet might be on “stay” somewhere[/li][li]Pet might have just finished fighting something[/li][/ul]
so adding the pet to the transport while it’s still off the transport causes other problems:

[ul][li]If the transport moves, the pet will float along the same arc / path[/li][li]Player::Update() causes the pet to despawn due to failure of IsWithinDistInMap()[/li][/ul]

Trust me, I’ve done extensive research, coding and trials. Pets for all intents and purposes are

considered mobs by the server and therefore don’t trigger packets / messages the same way.

I had initially thought of this “hack”:

[ul][li]Create an invisible NPC on the transport at the edge facing the bow[/li][li]When the pet passes within LOS do one of the following[/li]If pet already has MOVEMENTFLAG_ONTRANSPORT
LOS trigger means the pet left the transport, remove it
[/ul]
[li]If the pet doesn’t have MOVEMENTFLAG_ONTRANSPORT[/li][ul]LOS trigger means pet entered the transport, add it
[/ul]

but since it’s a “hack” it would be hard to get it pushed. Besides, I’d rather come up with something

more elegant. I don’t like hacks unless there’s absolutely no other way.

Well, here’s what I’ve got so far… keep in mind I’ve only been testing boats. Maybe +Shauren can fix it up?

Sorry it’s not a real DIFF /emoticons/default_sad.png

Solved:

[ul]
[li]Pet follows owner on / off transport without falling through[/li][li]Pet moves around on transport without falling through[/li][li]Pet stays on transport when it moves[/li][/ul]
Bugs:

[ul]
[li]Pet randomly despawns when leaving the transport[/li][li]Pet does not appear with player at map change[/li][li]Others I probably haven’t found yet[/li][/ul]

Transport.h

// Pet handling
bool AddPetPassenger(Creature* passenger);
bool RemovePetPassenger(Creature* passenger);
CreatureSet const& GetPetPassengers() const { return _petPassengerSet; }

Private:

    CreatureSet _petPassengerSet; [B]Transport.cpp[/B]

bool Transport::AddPetPassenger(Creature* passenger)
{
// Add pets to transport
if (!passenger->isPet())
return false;

// Already on this transport?
if (passenger->GetTransGUID() == this->GetGUID())
    return true;

passenger->SetTransport(this);
passenger->AddUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT);
passenger->m_movementInfo.guid = passenger->GetGUID();
passenger->m_movementInfo.t_guid = GetGUID();
_petPassengerSet.insert(passenger);

sScriptMgr->OnAddCreaturePassenger(this, passenger);
return true;

}
bool Transport::RemovePetPassenger(Creature* passenger)
{
if (_petPassengerSet.erase(passenger))
sLog->outInfo(LOG_FILTER_TRANSPORTS, “Pet %s removed from transport %s.”, passenger->GetName().c_str(), GetName().c_str());

passenger->SetTransport(NULL);
passenger->RemoveUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT);
passenger->m_movementInfo.t_guid = 0;

return true;

}
void Transport::TeleportTransport(uint32 newMapid, float x, float y, float z)
{
// STUFF (existing code)

// Pets - FIX ME !!! pets don't spawn at owner and float in the air
for (CreatureSet::iterator itr = _petPassengerSet.begin(); itr != _petPassengerSet.end(); ++itr)
    (*itr)->FarTeleportTo(newMap, x, y, z, (*itr)->GetOrientation());

} TargetedMovementGenerator.cpp

[CODE]bool TargetedMovementGeneratorMedium<T,D>::DoUpdate(T &owner, uint32 time_diff)
{
if (dist >= allowed_dist * allowed_dist)
_setTargetLocation(owner);
}

// Handle transport enter / leave for pets
if (owner.isPet())
{
    bool target_transport = i_target->m_movementInfo.flags & MOVEMENTFLAG_ONTRANSPORT;
    bool my_transport = owner.m_movementInfo.flags & MOVEMENTFLAG_ONTRANSPORT;

    if (target_transport && !my_transport)
    {
        Transport* trans = i_target->GetTransport();

        // Target is on a transport, we need to add ourselves when we enter
        // Approximate size of transport is 25 (from dock to water)
        if (owner.IsWithinDist(trans, 25))
            trans->AddPetPassenger((Creature*)&owner);
    }
    else if (!target_transport && my_transport)
    {
        Transport* trans = owner.GetTransport();

        // Target is off transport, we need to remove ourselves when we leave
        // Approximate size of transport is 25 (from dock to water)
        if (!owner.IsWithinDist(trans, 25))
            trans->RemovePetPassenger((Creature*)&owner);
}

}
void TargetedMovementGeneratorMedium<T,D>::_setTargetLocation(T &owner)
{
// Fix Z coordinate and handle transport stuff
if (i_target->GetTransGUID())
{
// GetClosePoint() returns wrong Z position when on transports
z = i_target->GetPositionZ();
}

D::_addUnitStateMove(owner);

}
[/CODE]

Ok, so I got a PM that Shauren isn’t planning on pushing his repo any time soon so I’ll keep working on it. If I solve the problem and even if it ends up as a custom patch and not an actual PR it will help in the interim.