Project SkyFire Core
SkyFire 5.4.8 server core API documentation
Loading...
Searching...
No Matches
PetTransportController.cpp
Go to the documentation of this file.
1/*
2* This file is part of Project SkyFire https://www.projectskyfire.org.
3* See LICENSE.md file for Copyright information
4*/
5
7#include "Map.h"
8#include "MoveSplineInit.h"
9#include "Pet.h"
10#include "PetTransportSupport.h"
11#include "Player.h"
12#include "Transport.h"
13
14namespace
15{
16 float const MaxPassengerOffset = 250.0f;
17 uint32 const TransportExitGraceDuration = 3 * IN_MILLISECONDS;
18
19 bool ShouldMirrorHunterPetOnTransport(Player const* owner, Pet const* pet)
20 {
21 if (!owner || !pet)
22 return false;
23
25 pet->isControlled(), pet->IsAlive(), pet->GetOwnerGUID() == owner->GetGUID());
26 }
27
28 bool NeedsPassengerOffsetRefresh(Pet const* pet)
29 {
31 pet->GetTransOffsetX(), pet->GetTransOffsetY(), pet->GetTransOffsetZ(), MaxPassengerOffset);
32 }
33
34 Skyfire::PetTransport::PassengerOffset CalculatePetTransportOffset(Player* owner, Pet* pet, Transport* transport)
35 {
36 if (owner->GetTransport() == transport)
38 owner->GetTransOffsetX(), owner->GetTransOffsetY(), owner->GetTransOffsetZ(), owner->GetTransOffsetO(),
40
42 owner->GetPositionX(), owner->GetPositionY(), owner->GetPositionZ(), owner->GetOrientation(),
44
45 transport->CalculatePassengerOffset(offset.X, offset.Y, offset.Z, &offset.O);
46 return offset;
47 }
48
49 void RelocatePetToTransportOffset(Pet* pet, Transport* transport, Skyfire::PetTransport::PassengerOffset const& offset)
50 {
51 pet->m_movementInfo.transport.pos.Relocate(offset.X, offset.Y, offset.Z, offset.O);
52
53 float x = offset.X;
54 float y = offset.Y;
55 float z = offset.Z;
56 float o = offset.O;
57 transport->CalculatePassengerPosition(x, y, z, &o);
58
59 if (pet->IsInWorld())
60 pet->GetMap()->CreatureRelocation(pet, x, y, z, o, false);
61 else
62 pet->Relocate(x, y, z, o);
63
64 pet->SetHomePosition(x, y, z, o);
66 }
67
68 void SendTransportEnterSpline(Pet* pet, Skyfire::PetTransport::PassengerOffset const& offset)
69 {
71 init.DisableTransportPathTransformations();
72 init.MoveTo(offset.X, offset.Y, offset.Z, false, true);
73 init.SetFacing(offset.O);
74 init.SetTransportEnter();
75 init.Launch();
76 }
77
78 void ResumeFollowerMotion(Player* owner, Pet* pet, Transport* transport, bool forceRestart)
79 {
81 pet->GetTransport() == transport, pet->IsInWorld()))
82 return;
83
85 owner->GetTransport() == transport, pet->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED));
86 if (clearMountedStun)
88
89 bool wasFollowing = false;
90 if (CharmInfo* charmInfo = pet->GetCharmInfo())
91 {
92 wasFollowing = charmInfo->IsFollowing();
93 charmInfo->SetIsAtStay(false);
94 charmInfo->SetIsReturning(false);
95 charmInfo->SetIsFollowing(true);
96 }
97
98 if (forceRestart || clearMountedStun || !wasFollowing)
99 {
100 pet->GetMotionMaster()->Clear();
102 }
103 }
104}
105
106namespace Skyfire
107{
109{
111 {
112 if (!owner || !pet || !transport)
113 return false;
114
115 if (!ShouldAttachHunterPetToOwnerTransport(owner->GetTransport() == transport,
116 pet->getPetType() == PetType::HUNTER_PET, pet->isControlled(), pet->IsAlive(),
117 pet->GetOwnerGUID() == owner->GetGUID(), pet->GetMap() == owner->GetMap()))
118 return false;
119
120 bool const alreadyOnTransport = pet->GetTransport() == transport;
121 bool const offsetRefreshed = ShouldRefreshPetTransportOffset(alreadyOnTransport,
122 alreadyOnTransport && NeedsPassengerOffsetRefresh(pet));
123 if (!offsetRefreshed)
124 {
125 ResumeFollowerMotion(owner, pet, transport, false);
126 return false;
127 }
128
129 PassengerOffset const offset = CalculatePetTransportOffset(owner, pet, transport);
130 if (!IsPassengerOffsetWithinLimit(offset.X, offset.Y, offset.Z, MaxPassengerOffset))
131 return false;
132
133 if (Transport* oldTransport = pet->GetTransport())
134 if (oldTransport != transport)
135 oldTransport->RemovePassenger(pet);
136
137 RelocatePetToTransportOffset(pet, transport, offset);
138
139 if (!alreadyOnTransport)
140 transport->AddPassenger(pet);
141
143
144 bool const petOnOwnerTransport = pet->GetTransport() == transport;
145 if (ShouldSendTransportEnterSpline(pet->IsInWorld(), petOnOwnerTransport, offsetRefreshed))
146 SendTransportEnterSpline(pet, offset);
147
148 ResumeFollowerMotion(owner, pet, transport, true);
149 return petOnOwnerTransport;
150 }
151
152 bool BoardOwnerHunterPet(Player* owner, Transport* transport)
153 {
154 if (!owner || !transport)
155 return false;
156
157 Pet* pet = owner->GetPet();
158 if (!ShouldMirrorHunterPetOnTransport(owner, pet) || !pet->IsInWorld())
159 return false;
160
161 return AttachHunterPetToOwnerTransport(owner, pet, transport);
162 }
163
164 void RemoveOwnerHunterPet(Player* owner, Transport* transport)
165 {
166 if (!owner || !transport)
167 return;
168
169 Pet* pet = owner->GetPet();
170 if (!ShouldMirrorHunterPetOnTransport(owner, pet) || pet->GetTransport() != transport)
171 return;
172
173 float x, y, z, o;
174 if (ShouldPlacePetNearOwnerOnTransportExit(owner->GetTransport() == transport))
175 {
176 owner->GetClosePoint(x, y, z, pet->GetObjectSize(), PET_FOLLOW_DIST, pet->GetFollowAngle());
177 o = owner->GetOrientation();
178 }
179 else
180 {
181 pet->m_movementInfo.transport.pos.GetPosition(x, y, z, o);
182 transport->CalculatePassengerPosition(x, y, z, &o);
183 }
184
185 transport->RemovePassenger(pet);
186 pet->StartTransportExitGrace(TransportExitGraceDuration);
187 pet->GetMap()->CreatureRelocation(pet, x, y, z, o);
188 pet->SetHomePosition(x, y, z, o);
190 }
191}
192}
@ IN_MILLISECONDS
Definition Common.h:125
std::uint32_t uint32
Definition Define.h:77
#define PET_FOLLOW_DIST
Definition PetDefines.h:57
@ HUNTER_PET
Definition PetDefines.h:12
@ UNIT_FLAG_STUNNED
Definition Unit.h:643
@ UNIT_FIELD_FLAGS
void SetHomePosition(float x, float y, float z, float o)
Definition Creature.h:626
void SetTransportHomePosition(float x, float y, float z, float o)
Definition Creature.h:631
void CreatureRelocation(Creature *creature, float x, float y, float z, float ang, bool respawnRelocationOnFail=true)
Definition Map.cpp:909
float GetFollowAngle() const OVERRIDE
void MoveFollow(Unit *target, float dist, float angle, MovementSlot slot=MOTION_SLOT_ACTIVE)
void Clear(bool reset=true)
uint64 GetGUID() const
Definition Object.h:119
bool IsInWorld() const
Definition Object.h:114
void RemoveFlag(uint16 index, uint32 oldFlag)
Definition Object.cpp:1280
bool HasFlag(uint16 index, uint32 flag) const
Definition Object.cpp:1309
Definition Pet.h:28
void ClearTransportExitGrace()
Definition Pet.h:58
void StartTransportExitGrace(uint32 duration)
Definition Pet.cpp:86
PetType getPetType() const
Definition Pet.h:38
bool isControlled() const
Definition Pet.cpp:2135
Pet * GetPet() const
Definition Player.cpp:15640
void CalculatePassengerPosition(float &x, float &y, float &z, float *o) const
This method transforms supplied transport offsets into global coordinates.
Definition Transport.h:39
void CalculatePassengerOffset(float &x, float &y, float &z, float *o) const
This method transforms supplied global coordinates into local offsets.
Definition Transport.h:45
void RemovePassenger(WorldObject *passenger)
void AddPassenger(WorldObject *passenger)
MotionMaster * GetMotionMaster()
Definition Unit.h:2605
bool IsAlive() const
Definition Unit.h:2032
CharmInfo * GetCharmInfo()
Definition Unit.h:2148
bool IsMounted() const
Definition Unit.h:1742
uint64 GetOwnerGUID() const
Definition Unit.h:2050
Map * GetMap() const
Definition Object.h:740
float GetTransOffsetX() const
Definition Object.h:798
float GetTransOffsetY() const
Definition Object.h:799
float GetTransOffsetZ() const
Definition Object.h:800
Transport * GetTransport() const
Definition Object.h:797
void GetClosePoint(float &x, float &y, float &z, float size, float distance2d=0, float angle=0) const
Definition Object.cpp:3070
float GetTransOffsetO() const
Definition Object.h:801
MovementInfo m_movementInfo
Definition Object.h:807
float GetObjectSize() const
Definition Object.cpp:3100
bool ShouldResumePetFollowOnTransport(bool ownerHasTransport, bool petOnOwnerTransport, bool petInWorld)
bool BoardOwnerHunterPet(Player *owner, Transport *transport)
bool AttachHunterPetToOwnerTransport(Player *owner, Pet *pet, Transport *transport)
bool ShouldRefreshPetTransportOffset(bool petAlreadyOnOwnerTransport, bool petPassengerOffsetInvalid)
bool ShouldPlacePetNearOwnerOnTransportExit(bool ownerStillOnTransport)
PassengerOffset CalculateFollowerPosition(float ownerX, float ownerY, float ownerZ, float ownerO, float ownerObjectSize, float petObjectSize, float followDistance, float followAngle)
bool ShouldSendTransportEnterSpline(bool petInWorld, bool petOnOwnerTransport, bool offsetRefreshed)
bool ShouldMirrorOwnerPet(bool isHunterPet, bool isControlled, bool isAlive, bool ownerMatches)
void RemoveOwnerHunterPet(Player *owner, Transport *transport)
bool IsPassengerOffsetWithinLimit(float x, float y, float z, float limit)
bool ShouldAttachHunterPetToOwnerTransport(bool ownerHasTransport, bool petIsHunterPet, bool petIsControlled, bool petIsAlive, bool ownerMatches, bool sameMap)
bool ShouldClearMountedPetStunForTransport(bool ownerMounted, bool ownerHasTransport, bool petStunned)
struct MovementInfo::TransportInfo transport
float GetPositionZ() const
Definition Object.h:330
float GetOrientation() const
Definition Object.h:331
float GetPositionX() const
Definition Object.h:328
void GetPosition(float &x, float &y) const
Definition Object.h:333
float GetPositionY() const
Definition Object.h:329
void Relocate(float x, float y)
Definition Object.h:302