TrinityCore
Loading...
Searching...
No Matches
TaxiHandler.cpp
Go to the documentation of this file.
1/*
2 * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#include "WorldSession.h"
19#include "Common.h"
20#include "Creature.h"
21#include "DatabaseEnv.h"
22#include "DBCStores.h"
24#include "Log.h"
25#include "MotionMaster.h"
26#include "ObjectAccessor.h"
27#include "ObjectMgr.h"
28#include "Opcodes.h"
29#include "Player.h"
30#include "WorldPacket.h"
31
33{
34 TC_LOG_DEBUG("network", "WORLD: Received CMSG_TAXINODE_STATUS_QUERY");
35
36 ObjectGuid guid;
37
38 recvData >> guid;
39 SendTaxiStatus(guid);
40}
41
43{
44 Player* const player = GetPlayer();
45 Creature* unit = ObjectAccessor::GetCreature(*player, guid);
46 if (!unit || unit->IsHostileTo(player) || !unit->HasNpcFlag(UNIT_NPC_FLAG_FLIGHTMASTER))
47 {
48 TC_LOG_DEBUG("network", "WorldSession::SendTaxiStatus - {} not found or you can't interact with him.", guid.ToString());
49 return;
50 }
51
52 // find taxi node
53 uint32 nearest = sObjectMgr->GetNearestTaxiNode(unit->GetPositionX(), unit->GetPositionY(), unit->GetPositionZ(), unit->GetMapId(), player->GetTeam());
54 if (!nearest)
55 return;
56
58 data << guid;
59 data << uint8(player->m_taxi.IsTaximaskNodeKnown(nearest) ? 1 : 0);
60 SendPacket(&data);
61}
62
64{
65 TC_LOG_DEBUG("network", "WORLD: Received CMSG_TAXIQUERYAVAILABLENODES");
66
67 ObjectGuid guid;
68 recvData >> guid;
69
70 // cheating checks
72 if (!unit)
73 {
74 TC_LOG_DEBUG("network", "WORLD: HandleTaxiQueryAvailableNodes - {} not found or you can't interact with him.", guid.ToString());
75 return;
76 }
77
78 // remove fake death
79 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
81
82 // unknown taxi node case
83 if (SendLearnNewTaxiNode(unit))
84 return;
85
86 // known taxi node case
87 SendTaxiMenu(unit);
88}
89
91{
92 // find current node
93 uint32 curloc = sObjectMgr->GetNearestTaxiNode(unit->GetPositionX(), unit->GetPositionY(), unit->GetPositionZ(), unit->GetMapId(), GetPlayer()->GetTeam());
94 if (!curloc)
95 return;
96
97 bool lastTaxiCheaterState = GetPlayer()->isTaxiCheater();
98 if (unit->GetEntry() == 29480)
99 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.
100
101 TC_LOG_DEBUG("network", "WORLD: CMSG_TAXINODE_STATUS_QUERY {} ", curloc);
102
103 WorldPacket data(SMSG_SHOWTAXINODES, (4 + 8 + 4 + 8 * 4));
104 data << uint32(1);
105 data << unit->GetGUID();
106 data << uint32(curloc);
107 GetPlayer()->m_taxi.AppendTaximaskTo(data, GetPlayer()->isTaxiCheater());
108 SendPacket(&data);
109
110 TC_LOG_DEBUG("network", "WORLD: Sent SMSG_SHOWTAXINODES");
111
112 GetPlayer()->SetTaxiCheater(lastTaxiCheaterState);
113}
114
115void WorldSession::SendDoFlight(uint32 mountDisplayId, uint32 path, uint32 pathNode)
116{
117 // remove fake death
118 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
120
121 if (mountDisplayId)
122 GetPlayer()->Mount(mountDisplayId);
123
124 GetPlayer()->GetMotionMaster()->MoveTaxiFlight(path, pathNode);
125}
126
128{
129 // find current node
130 uint32 curloc = sObjectMgr->GetNearestTaxiNode(unit->GetPositionX(), unit->GetPositionY(), unit->GetPositionZ(), unit->GetMapId(), GetPlayer()->GetTeam());
131
132 if (curloc == 0)
133 return true; // `true` send to avoid WorldSession::SendTaxiMenu call with one more curlock seartch with same false result.
134
135 if (GetPlayer()->m_taxi.SetTaximaskNode(curloc))
136 {
138 SendPacket(&msg);
139
141 update << unit->GetGUID();
142 update << uint8(1);
143 SendPacket(&update);
144
145 return true;
146 }
147 else
148 return false;
149}
150
152{
153 if (GetPlayer()->m_taxi.SetTaximaskNode(nodeid))
154 {
156 SendPacket(&msg);
157 }
158}
159
161{
162 TC_LOG_DEBUG("network", "WORLD: Received CMSG_ACTIVATETAXIEXPRESS");
163
164 ObjectGuid guid;
165 uint32 node_count;
166
167 recvData >> guid >> node_count;
168
170 if (!npc)
171 {
172 TC_LOG_DEBUG("network", "WORLD: HandleActivateTaxiExpressOpcode - {} not found or you can't interact with it.", guid.ToString());
174 return;
175 }
176 std::vector<uint32> nodes;
177
178 for (uint32 i = 0; i < node_count; ++i)
179 {
180 uint32 node;
181 recvData >> node;
182
183 if (!GetPlayer()->m_taxi.IsTaximaskNodeKnown(node) && !GetPlayer()->isTaxiCheater())
184 {
186 recvData.rfinish();
187 return;
188 }
189
190 nodes.push_back(node);
191 }
192
193 if (nodes.empty())
194 return;
195
196 TC_LOG_DEBUG("network", "WORLD: Received CMSG_ACTIVATETAXIEXPRESS from {} to {}", nodes.front(), nodes.back());
197
198 GetPlayer()->ActivateTaxiPathTo(nodes, npc);
199}
200
202{
203 TC_LOG_DEBUG("network", "WORLD: Received CMSG_MOVE_SPLINE_DONE");
204
205 ObjectGuid guid;
206 recvData >> guid.ReadAsPacked();
207
208 if (!ValidateAndGetUnitBeingMoved(guid, false))
209 {
210 recvData.rfinish(); // prevent warnings spam
211 return;
212 }
213
214 MovementInfo movementInfo; // used only for proper packet read
215 movementInfo.guid = guid;
216 ReadMovementInfo(recvData, &movementInfo);
217
218 recvData.read_skip<uint32>(); // spline id
219
220 // in taxi flight packet received in 2 case:
221 // 1) end taxi path in far (multi-node) flight
222 // 2) switch from one map to other in case multim-map taxi path
223 // we need process only (1)
224
226 if (curDest)
227 {
228 TaxiNodesEntry const* curDestNode = sTaxiNodesStore.LookupEntry(curDest);
229
230 // far teleport case
231 if (curDestNode && curDestNode->ContinentID != GetPlayer()->GetMapId() && GetPlayer()->GetMotionMaster()->GetCurrentMovementGeneratorType() == FLIGHT_MOTION_TYPE)
232 {
233 if (FlightPathMovementGenerator* flight = dynamic_cast<FlightPathMovementGenerator*>(GetPlayer()->GetMotionMaster()->GetCurrentMovementGenerator()))
234 {
235 // short preparations to continue flight
236 flight->SetCurrentNodeAfterTeleport();
237 TaxiPathNodeEntry const* node = flight->GetPath()[flight->GetCurrentNode()];
238 flight->SkipCurrentNode();
239
240 GetPlayer()->TeleportTo(curDestNode->ContinentID, node->Loc.X, node->Loc.Y, node->Loc.Z, GetPlayer()->GetOrientation());
241 }
242 }
243
244 return;
245 }
246
247 // at this point only 1 node is expected (final destination)
248 if (GetPlayer()->m_taxi.GetPath().size() != 1)
249 return;
250
252 GetPlayer()->SetFallInformation(0, GetPlayer()->GetPositionZ());
253 if (GetPlayer()->pvpInfo.IsHostile)
254 GetPlayer()->CastSpell(GetPlayer(), 2479, true);
255}
256
258{
259 TC_LOG_DEBUG("network", "WORLD: Received CMSG_ACTIVATETAXI");
260
261 ObjectGuid guid;
262 std::vector<uint32> nodes;
263 nodes.resize(2);
264
265 recvData >> guid >> nodes[0] >> nodes[1];
266 TC_LOG_DEBUG("network", "WORLD: Received CMSG_ACTIVATETAXI from {} to {}", nodes[0], nodes[1]);
268 if (!npc)
269 {
270 TC_LOG_DEBUG("network", "WORLD: HandleActivateTaxiOpcode - {} not found or you can't interact with it.", guid.ToString());
272 return;
273 }
274
275 if (!GetPlayer()->isTaxiCheater())
276 {
277 if (!GetPlayer()->m_taxi.IsTaximaskNodeKnown(nodes[0]) || !GetPlayer()->m_taxi.IsTaximaskNodeKnown(nodes[1]))
278 {
280 return;
281 }
282 }
283
284 GetPlayer()->ActivateTaxiPathTo(nodes, npc);
285}
286
288{
290 data << uint32(reply);
291 SendPacket(&data);
292}
DBCStorage< TaxiNodesEntry > sTaxiNodesStore(TaxiNodesEntryfmt)
uint8_t uint8
Definition Define.h:135
uint32_t uint32
Definition Define.h:133
#define TC_LOG_DEBUG(filterType__,...)
Definition Log.h:156
@ FLIGHT_MOTION_TYPE
#define sObjectMgr
Definition ObjectMgr.h:1721
ActivateTaxiReply
@ ERR_TAXINOTVISITED
@ ERR_TAXITOOFARAWAY
@ SPELL_AURA_FEIGN_DEATH
@ UNIT_NPC_FLAG_FLIGHTMASTER
@ UNIT_STATE_DIED
Definition Unit.h:220
void read_skip()
Definition ByteBuffer.h:330
void rfinish()
Definition ByteBuffer.h:316
void MoveTaxiFlight(uint32 path, uint32 pathnode)
std::string ToString() const
PackedGuidReader ReadAsPacked()
Definition ObjectGuid.h:146
uint32 GetEntry() const
Definition Object.h:81
static ObjectGuid GetGUID(Object const *o)
Definition Object.h:78
bool IsTaximaskNodeKnown(uint32 nodeidx) const
Definition PlayerTaxi.h:39
uint32 GetTaxiDestination() const
Definition PlayerTaxi.h:66
void AppendTaximaskTo(ByteBuffer &data, bool all)
uint32 GetTeam() const
Definition Player.h:1832
void SetFallInformation(uint32 time, float z)
Definition Player.cpp:24853
Creature * GetNPCIfCanInteractWith(ObjectGuid const &guid, NPCFlags npcFlags) const
Definition Player.cpp:2094
bool ActivateTaxiPathTo(std::vector< uint32 > const &nodes, Creature *npc=nullptr, uint32 spellid=0)
Definition Player.cpp:21008
bool TeleportTo(uint32 mapid, float x, float y, float z, float orientation, uint32 options=0)
Definition Player.cpp:1524
PlayerTaxi m_taxi
Definition Player.h:985
void SetTaxiCheater(bool on)
Definition Player.h:1005
void CleanupAfterTaxiFlight()
Definition Player.cpp:21211
bool isTaxiCheater() const
Definition Player.h:1004
void RemoveAurasByType(AuraType auraType, std::function< bool(AuraApplication const *)> const &check, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition Unit.cpp:3765
MotionMaster * GetMotionMaster()
Definition Unit.h:1667
void Mount(uint32 mount, uint32 vehicleId=0, uint32 creatureEntry=0)
Definition Unit.cpp:8184
bool HasNpcFlag(NPCFlags flags) const
Definition Unit.h:1096
uint32 GetMapId() const
Definition Position.h:193
SpellCastResult CastSpell(CastSpellTargetArg const &targets, uint32 spellId, CastSpellExtraArgs const &args={ })
Definition Object.cpp:2832
bool IsHostileTo(WorldObject const *target) const
Definition Object.cpp:2796
void HandleMoveSplineDoneOpcode(WorldPacket &recvPacket)
void HandleActivateTaxiOpcode(WorldPacket &recvPacket)
Unit * ValidateAndGetUnitBeingMoved(ObjectGuid guid, bool forStatusAck) const
void SendPacket(WorldPacket const *packet)
Send a packet to the client.
bool SendLearnNewTaxiNode(Creature *unit)
void SendTaxiMenu(Creature *unit)
void SendTaxiStatus(ObjectGuid guid)
Player * GetPlayer() const
void HandleTaxiNodeStatusQueryOpcode(WorldPacket &recvPacket)
void SendActivateTaxiReply(ActivateTaxiReply reply)
void HandleTaxiQueryAvailableNodes(WorldPacket &recvPacket)
void ReadMovementInfo(WorldPacket &data, MovementInfo *mi)
void SendDiscoverNewTaxiNode(uint32 nodeid)
void HandleActivateTaxiExpressOpcode(WorldPacket &recvPacket)
void SendDoFlight(uint32 mountDisplayId, uint32 path, uint32 pathNode=0)
@ SMSG_TAXINODE_STATUS
Definition Opcodes.h:456
@ SMSG_SHOWTAXINODES
Definition Opcodes.h:454
@ SMSG_ACTIVATETAXIREPLY
Definition Opcodes.h:459
@ SMSG_NEW_TAXI_PATH
Definition Opcodes.h:460
TC_GAME_API Creature * GetCreature(WorldObject const &u, ObjectGuid const &guid)
ObjectGuid guid
float GetPositionZ() const
Definition Position.h:81
float GetPositionX() const
Definition Position.h:79
float GetPositionY() const
Definition Position.h:80
DBCPosition3D Loc