Project SkyFire Core
SkyFire 5.4.8 server core API documentation
Loading...
Searching...
No Matches
TaxiHandler.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
6#include "Common.h"
7#include "DatabaseEnv.h"
8#include "Log.h"
10#include "ObjectMgr.h"
11#include "Opcodes.h"
12#include "Path.h"
13#include "Player.h"
14#include "UpdateMask.h"
16#include "WorldPacket.h"
17#include "WorldSession.h"
18
20{
21 SF_LOG_DEBUG("network", "WORLD: Received CMSG_TAXI_NODE_STATUS_QUERY");
22
23 ObjectGuid guid;
24
25 recvData.ReadGuidMask(guid, 0, 1, 6, 4, 5, 2, 3, 7);
26 recvData.ReadGuidBytes(guid, 4, 1, 5, 0, 2, 7, 6, 3);
27
28 SendTaxiStatus(guid);
29}
30
32{
33 // cheating checks
34 Creature* unit = GetPlayer()->GetMap()->GetCreature(guid);
35 if (!unit)
36 {
37 SF_LOG_DEBUG("network", "WorldSession::SendTaxiStatus - Unit (GUID: %u) not found.", uint32(GUID_LOPART(guid)));
38 return;
39 }
40
41 uint32 curloc = sObjectMgr->GetNearestTaxiNode(unit->GetPositionX(), unit->GetPositionY(), unit->GetPositionZ(), unit->GetMapId(), GetPlayer()->GetTeam());
42
43 // not found nearest
44 if (curloc == 0)
45 return;
46
47 SF_LOG_DEBUG("network", "WORLD: current location %u ", curloc);
48
49 ObjectGuid Guid = guid;
51
52 data.WriteBit(Guid[6]);
53 data.WriteBit(Guid[2]);
54 data.WriteBit(Guid[7]);
55 data.WriteBit(Guid[5]);
56 data.WriteBit(Guid[4]);
57 data.WriteBit(Guid[1]);
58 data.WriteBits(GetPlayer()->m_taxi.IsTaximaskNodeKnown(curloc) ? 1 : 3, 2);
59 data.WriteBit(Guid[3]);
60 data.WriteBit(Guid[0]);
61 data.FlushBits();
62
63 data.WriteByteSeq(Guid[0]);
64 data.WriteByteSeq(Guid[5]);
65 data.WriteByteSeq(Guid[2]);
66 data.WriteByteSeq(Guid[1]);
67 data.WriteByteSeq(Guid[4]);
68 data.WriteByteSeq(Guid[6]);
69 data.WriteByteSeq(Guid[7]);
70 data.WriteByteSeq(Guid[3]);
71
72 SendPacket(&data);
73
74 SF_LOG_DEBUG("network", "WORLD: Sent SMSG_TAXI_NODE_STATUS");
75}
76
78{
79 SF_LOG_DEBUG("network", "WORLD: Received CMSG_TAXI_QUERY_AVAILABLE_NODES");
80
81 ObjectGuid guid;
82
83 recvData.ReadGuidMask(guid, 7, 1, 0, 4, 2, 5, 6, 3);
84 recvData.ReadGuidBytes(guid, 0, 3, 7, 5, 2, 6, 4, 1);
85
86 // cheating checks
88 if (!unit)
89 {
90 SF_LOG_DEBUG("network", "WORLD: HandleTaxiQueryAvailableNodes - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(guid)));
91 return;
92 }
93
94 // remove fake death
95 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
97
98 // unknown taxi node case
99 if (SendLearnNewTaxiNode(unit))
100 return;
101
102 // known taxi node case
103 SendTaxiMenu(unit);
104}
105
107{
108 // find current node
109 uint32 curloc = sObjectMgr->GetNearestTaxiNode(unit->GetPositionX(), unit->GetPositionY(), unit->GetPositionZ(), unit->GetMapId(), GetPlayer()->GetTeam());
110 if (!curloc)
111 return;
112
113 bool lastTaxiCheaterState = GetPlayer()->isTaxiCheater();
114 if (unit->GetEntry() == 29480)
115 GetPlayer()->SetTaxiCheater(true); // Grimwing in Ebon Hold, special case. NOTE: Not perfect, Zul'Aman should not be included according to WoWhead, and I think taxicheat includes it.
116
117 SF_LOG_DEBUG("network", "WORLD: CMSG_TAXI_NODE_STATUS_QUERY %u ", curloc);
118 ObjectGuid Guid = unit->GetGUID();
119
120 WorldPacket data(SMSG_SHOW_TAXI_NODES, (4 + 8 + 4 + 8 * 4));
121 data.WriteBit(1); //unk
122 data.WriteGuidMask(Guid, 3, 0, 4, 2, 1, 7, 6, 5);
123 data.WriteBits(TaxiMaskSize, 24);
124 data.FlushBits();
125
126 data.WriteGuidBytes(Guid, 0, 3);
127 data << uint32(curloc);
128 data.WriteGuidBytes(Guid, 5, 2, 6, 1, 7, 4);
129
130 GetPlayer()->m_taxi.AppendTaximaskTo(data, GetPlayer()->isTaxiCheater());
131 SendPacket(&data);
132
133 SF_LOG_DEBUG("network", "WORLD: Sent SMSG_SHOW_TAXI_NODES");
134
135 GetPlayer()->SetTaxiCheater(lastTaxiCheaterState);
136}
137
138void WorldSession::SendDoFlight(uint32 mountDisplayId, uint32 path, uint32 pathNode)
139{
140 // remove fake death
141 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
143
144 while (GetPlayer()->GetMotionMaster()->GetCurrentMovementGeneratorType() == FLIGHT_MOTION_TYPE)
146
147 if (mountDisplayId)
148 GetPlayer()->Mount(mountDisplayId);
149
150 GetPlayer()->GetMotionMaster()->MoveTaxiFlight(path, pathNode);
151}
152
154{
155 // find current node
156 uint32 curloc = sObjectMgr->GetNearestTaxiNode(unit->GetPositionX(), unit->GetPositionY(), unit->GetPositionZ(), unit->GetMapId(), GetPlayer()->GetTeam());
157
158 if (curloc == 0)
159 return true;
160 // `true` send to avoid WorldSession::SendTaxiMenu call with one more curlock seartch with same false result.
161
162 if (GetPlayer()->m_taxi.SetTaximaskNode(curloc))
163 {
165 SendPacket(&msg);
166
168 update.WriteBit(1);
169 ObjectGuid guid = unit->GetGUID();
170
171 update.WriteGuidMask(guid, 1, 7, 6, 5, 4, 0, 2, 3);
172 update.WriteGuidBytes(guid, 4, 2, 3, 6, 7, 0, 1, 5);
173
174 SendPacket(&update);
175
176 return true;
177 }
178 else
179 return false;
180}
181
183{
184 if (GetPlayer()->m_taxi.SetTaximaskNode(nodeid))
185 {
187 SendPacket(&msg);
188 }
189}
190
192{
193 SF_LOG_DEBUG("network", "WORLD: Received CMSG_ACTIVATE_TAXI_EXPRESS");
194
195 ObjectGuid guid;
196 uint32 node_count;
197
198 recvData.ReadGuidMask(guid, 6, 7);
199 node_count = recvData.ReadBits(22);
200 recvData.ReadGuidMask(guid, 2, 0, 4, 3, 1, 5);
201 recvData.ReadGuidBytes(guid, 2, 7, 1);
202
203 std::vector<uint32> nodes;
204
205 for (uint32 i = 0; i < node_count; ++i)
206 {
207 uint32 node;
208 recvData >> node;
209 nodes.push_back(node);
210 }
211
212 recvData.ReadGuidBytes(guid, 0, 5, 3, 6, 4);
213
215 if (!npc)
216 {
217 SF_LOG_DEBUG("network", "WORLD: HandleActivateTaxiExpressOpcode - Unit (GUID: %u) not found or you can't interact with it.", uint32(GUID_LOPART(guid)));
218 return;
219 }
220
221 SF_LOG_DEBUG("network", "WORLD: Received CMSG_ACTIVATE_TAXI_EXPRESS from %d to %d", nodes.front(), nodes.back());
222
224}
225
227{
228 SF_LOG_DEBUG("network", "WORLD: Received CMSG_MOVE_SPLINE_DONE");
229
230 uint32 SplineID;
231 recvData >> SplineID;
232 MovementInfo movementInfo; // used only for proper packet read
233 _player->ReadMovementInfo(recvData, &movementInfo);
234
235 // in taxi flight packet received in 2 case:
236 // 1) end taxi path in far (multi-node) flight
237 // 2) switch from one map to other in case multim-map taxi path
238 // we need process only (1)
239
241 if (!curDest)
242 return;
243
244 TaxiNodesEntry const* curDestNode = sTaxiNodesStore.LookupEntry(curDest);
245
246 // far teleport case
247 if (curDestNode && curDestNode->map_id != GetPlayer()->GetMapId())
248 {
249 if (GetPlayer()->GetMotionMaster()->GetCurrentMovementGeneratorType() == FLIGHT_MOTION_TYPE)
250 {
251 // short preparations to continue flight
252 FlightPathMovementGenerator* flight = (FlightPathMovementGenerator*)(GetPlayer()->GetMotionMaster()->top());
253
255 TaxiPathNodeEntry const& node = flight->GetPath()[flight->GetCurrentNode()];
256 flight->SkipCurrentNode();
257
258 GetPlayer()->TeleportTo(curDestNode->map_id, node.x, node.y, node.z, GetPlayer()->GetOrientation());
259 }
260 return;
261 }
262
263 uint32 destinationnode = GetPlayer()->m_taxi.NextTaxiDestination();
264 if (destinationnode > 0) // if more destinations to go
265 {
266 // current source node for next destination
267 uint32 sourcenode = GetPlayer()->m_taxi.GetTaxiSource();
268
269 // Add to taximask middle hubs in taxicheat mode (to prevent having player with disabled taxicheat and not having back flight path)
270 if (GetPlayer()->isTaxiCheater())
271 {
272 if (GetPlayer()->m_taxi.SetTaximaskNode(sourcenode))
273 {
275 _player->GetSession()->SendPacket(&data);
276 }
277 }
278
279 SF_LOG_DEBUG("network", "WORLD: Taxi has to go from %u to %u", sourcenode, destinationnode);
280
281 uint32 mountDisplayId = sObjectMgr->GetTaxiMountDisplayId(sourcenode, GetPlayer()->GetTeam());
282
283 uint32 path, cost;
284 sObjectMgr->GetTaxiPath(sourcenode, destinationnode, path, cost);
285
286 if (path && mountDisplayId)
287 SendDoFlight(mountDisplayId, path, 1); // skip start fly node
288 else
289 GetPlayer()->m_taxi.ClearTaxiDestinations(); // clear problematic path and next
290 return;
291 }
292 else
293 GetPlayer()->m_taxi.ClearTaxiDestinations(); // not destinations, clear source node
294
296 GetPlayer()->SetFallInformation(0, GetPlayer()->GetPositionZ());
297 if (GetPlayer()->pvpInfo.IsHostile)
298 GetPlayer()->CastSpell(GetPlayer(), 2479, true);
299}
300
302{
303 SF_LOG_DEBUG("network", "WORLD: Received CMSG_ACTIVATE_TAXI");
304
305 ObjectGuid guid;
306 std::vector<uint32> nodes;
307 nodes.resize(2);
308
309 recvData >> nodes[1] >> nodes[0];
310 recvData.ReadGuidMask(guid, 4, 0, 1, 2, 5, 6, 7, 3);
311 recvData.ReadGuidBytes(guid, 1, 0, 6, 5, 2, 4, 3, 7);
312
313 SF_LOG_DEBUG("network", "WORLD: Received CMSG_ACTIVATE_TAXI from %d to %d", nodes[0], nodes[1]);
315 if (!npc)
316 {
317 SF_LOG_DEBUG("network", "WORLD: HandleActivateTaxiOpcode - Unit (GUID: %u) not found or you can't interact with it.", uint32(GUID_LOPART(guid)));
318 return;
319 }
320
322}
323
325{
327 data.WriteBits(reply, 4);
328 data.FlushBits();
329 SendPacket(&data);
330}
DBCStorage< TaxiNodesEntry > sTaxiNodesStore(TaxiNodesEntryfmt)
#define TaxiMaskSize
std::uint32_t uint32
Definition Define.h:77
std::uint64_t uint64
Definition Define.h:76
#define SF_LOG_DEBUG(filterType__,...)
Definition Log.h:134
@ FLIGHT_MOTION_TYPE
uint32 GUID_LOPART(uint64 x)
#define sObjectMgr
Definition ObjectMgr.h:1617
ActivateTaxiReply
5.4.8 18414
@ SPELL_AURA_FEIGN_DEATH
@ UNIT_NPC_FLAG_FLIGHTMASTER
Definition Unit.h:700
@ UNIT_STATE_DIED
Definition Unit.h:512
void WriteGuidBytes(const ObjectGuid &guid, Offsets... offsets)
Definition ByteBuffer.h:264
bool WriteBit(uint32 bit)
Definition ByteBuffer.h:164
void WriteGuidMask(const ObjectGuid &guid, Offsets... offsets)
Definition ByteBuffer.h:248
uint32 ReadBits(size_t bits)
Definition ByteBuffer.h:198
void ReadGuidBytes(ObjectGuid &guid, Offsets... offsets)
Definition ByteBuffer.h:256
void ReadGuidMask(ObjectGuid &guid, Offsets... offsets)
Definition ByteBuffer.h:240
void WriteBits(T value, size_t bits)
Definition ByteBuffer.h:192
void WriteByteSeq(uint8 b)
Definition ByteBuffer.h:227
void FlushBits()
Definition ByteBuffer.h:154
TaxiPathNodeList const & GetPath()
Creature * GetCreature(uint64 guid)
Definition Map.cpp:3179
void MoveTaxiFlight(uint32 path, uint32 pathnode)
void MovementExpired(bool reset=true)
uint64 GetGUID() const
Definition Object.h:119
uint32 GetEntry() const
Definition Object.h:125
void SetFallInformation(uint32 time, float z)
Definition Player.cpp:20943
Creature * GetNPCIfCanInteractWith(uint64 guid, uint32 npcflagmask)
Definition Player.cpp:2836
bool TeleportTo(uint32 mapid, float x, float y, float z, float orientation, uint32 options=0)
Definition Player.cpp:2090
bool ActivateTaxiPathTo(std::vector< uint32 > const &nodes, Creature *npc=NULL, uint32 spellid=0)
Definition Player.cpp:16547
PlayerTaxi m_taxi
Definition Player.h:1351
void SetTaxiCheater(bool on)
Definition Player.h:1386
void CleanupAfterTaxiFlight()
Definition Player.cpp:16748
bool isTaxiCheater() const
Definition Player.h:1382
uint32 GetTaxiSource() const
Definition PlayerTaxi.h:56
uint32 NextTaxiDestination()
Definition PlayerTaxi.h:65
uint32 GetTaxiDestination() const
Definition PlayerTaxi.h:60
void AppendTaximaskTo(ByteBuffer &data, bool all)
void ClearTaxiDestinations()
Definition PlayerTaxi.h:48
void CastSpell(SpellCastTargets const &targets, SpellInfo const *spellInfo, CustomSpellValues const *value, TriggerCastFlags triggerFlags=TRIGGERED_NONE, Item *castItem=NULL, AuraEffect const *triggeredByAura=NULL, uint64 originalCaster=0)
MotionMaster * GetMotionMaster()
Definition Unit.h:2605
void Mount(uint32 mount, uint32 vehicleId=0, uint32 creatureEntry=0)
Definition Unit.cpp:3635
void RemoveAurasByType(AuraType auraType, uint64 casterGUID=0, Aura *except=NULL, bool negative=true, bool positive=true)
uint32 GetMapId() const
Definition Object.h:546
Map * GetMap() const
Definition Object.h:740
void HandleMoveSplineDoneOpcode(WorldPacket &recvPacket)
void HandleActivateTaxiOpcode(WorldPacket &recvPacket)
bool SendLearnNewTaxiNode(Creature *unit)
void SendTaxiMenu(Creature *unit)
Player * GetPlayer() const
void HandleTaxiNodeStatusQueryOpcode(WorldPacket &recvPacket)
void SendActivateTaxiReply(ActivateTaxiReply reply)
void SendPacket(WorldPacket const *packet, bool forced=false)
Send a packet to the client.
void HandleTaxiQueryAvailableNodes(WorldPacket &recvPacket)
Player * _player
void SendDiscoverNewTaxiNode(uint32 nodeid)
void HandleActivateTaxiExpressOpcode(WorldPacket &recvPacket)
void SendTaxiStatus(uint64 guid)
void SendDoFlight(uint32 mountDisplayId, uint32 path, uint32 pathNode=0)
@ SMSG_SHOW_TAXI_NODES
Definition Opcodes.h:968
@ SMSG_ACTIVATE_TAXI_REPLY
Definition Opcodes.h:508
@ SMSG_NEW_TAXI_PATH
Definition Opcodes.h:833
@ SMSG_TAXI_NODE_STATUS
Definition Opcodes.h:1024
float GetPositionZ() const
Definition Object.h:330
float GetPositionX() const
Definition Object.h:328
float GetPositionY() const
Definition Object.h:329
uint32 map_id
float y
float x
float z