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 "ConditionMgr.h"
21#include "Containers.h"
22#include "Creature.h"
23#include "DatabaseEnv.h"
24#include "DB2Stores.h"
26#include "GossipDef.h"
27#include "Log.h"
28#include "MotionMaster.h"
29#include "ObjectAccessor.h"
30#include "ObjectMgr.h"
31#include "Player.h"
32#include "TaxiPackets.h"
33#include "TaxiPathGraph.h"
34
40
45
47{
48 Player* const player = GetPlayer();
49 Creature* unit = ObjectAccessor::GetCreature(*player, guid);
50 if (!unit || unit->IsHostileTo(player) || !unit->HasNpcFlag(UNIT_NPC_FLAG_FLIGHTMASTER))
51 {
52 TC_LOG_DEBUG("network", "WorldSession::SendTaxiStatus - {} not found or you can't interact with him.", guid.ToString());
53 return;
54 }
55
56 // find taxi node
57 uint32 nearest = sObjectMgr->GetNearestTaxiNode(unit->GetPositionX(), unit->GetPositionY(), unit->GetPositionZ(), unit->GetMapId(), player->GetTeam());
58
60 data.Unit = guid;
61
62 if (!nearest)
64 else if (unit->GetReactionTo(GetPlayer()) >= REP_NEUTRAL)
66 else
68
69 SendPacket(data.Write());
70}
71
73{
74 // cheating checks
76 if (!unit)
77 {
78 TC_LOG_DEBUG("network", "WORLD: HandleTaxiQueryAvailableNodes - {} not found or you can't interact with him.", taxiQueryAvailableNodes.Unit.ToString());
79 return;
80 }
81 // remove fake death
82 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
84
85 // unknown taxi node case
86 if (SendLearnNewTaxiNode(unit))
87 return;
88
89 // known taxi node case
90 SendTaxiMenu(unit);
91}
92
94{
95 // find current node
96 uint32 curloc = sObjectMgr->GetNearestTaxiNode(unit->GetPositionX(), unit->GetPositionY(), unit->GetPositionZ(), unit->GetMapId(), GetPlayer()->GetTeam());
97 if (!curloc)
98 return;
99
100 GetPlayer()->PlayerTalkClass->GetInteractionData().StartInteraction(unit->GetGUID(), PlayerInteractionType::TaxiNode);
101
102 bool lastTaxiCheaterState = GetPlayer()->isTaxiCheater();
103 if (unit->GetEntry() == 29480)
104 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.
105
106 TC_LOG_DEBUG("network", "WORLD: CMSG_TAXINODE_STATUS_QUERY {} ", curloc);
107
109 data.WindowInfo.emplace();
110 data.WindowInfo->UnitGUID = unit->GetGUID();
111 data.WindowInfo->CurrentNode = curloc;
112
113 GetPlayer()->m_taxi.AppendTaximaskTo(data, lastTaxiCheaterState);
114
115 TaxiMask reachableNodes;
116 TaxiPathGraph::GetReachableNodesMask(sTaxiNodesStore.LookupEntry(curloc), &reachableNodes);
117
118 for (std::size_t i = 0; i < reachableNodes.size(); ++i)
119 {
120 data.CanLandNodes[i] &= reachableNodes[i];
121 data.CanUseNodes[i] &= reachableNodes[i];
122 }
123
124 SendPacket(data.Write());
125
126 GetPlayer()->SetTaxiCheater(lastTaxiCheaterState);
127}
128
130{
131 // find current node
132 uint32 curloc = sObjectMgr->GetNearestTaxiNode(unit->GetPositionX(), unit->GetPositionY(), unit->GetPositionZ(), unit->GetMapId(), GetPlayer()->GetTeam());
133
134 if (curloc == 0)
135 return true; // `true` send to avoid WorldSession::SendTaxiMenu call with one more curlock seartch with same false result.
136
137 if (GetPlayer()->m_taxi.SetTaximaskNode(curloc))
138 {
140
142 data.Unit = unit->GetGUID();
144 SendPacket(data.Write());
145
147 return true;
148 }
149 else
150 return false;
151}
152
154{
155 if (GetPlayer()->m_taxi.SetTaximaskNode(nodeid))
157}
158
160{
162 if (!unit)
163 {
164 TC_LOG_DEBUG("network", "WORLD: HandleActivateTaxiOpcode - {} not found or you can't interact with it.", activateTaxi.Vendor.ToString());
166 return;
167 }
168
169 uint32 curloc = sObjectMgr->GetNearestTaxiNode(unit->GetPositionX(), unit->GetPositionY(), unit->GetPositionZ(), unit->GetMapId(), GetPlayer()->GetTeam());
170 if (!curloc)
171 return;
172
173 TaxiNodesEntry const* from = sTaxiNodesStore.LookupEntry(curloc);
174 TaxiNodesEntry const* to = sTaxiNodesStore.LookupEntry(activateTaxi.Node);
175 if (!to)
176 return;
177
178 if (!GetPlayer()->isTaxiCheater())
179 {
180 if (!GetPlayer()->m_taxi.IsTaximaskNodeKnown(curloc) || !GetPlayer()->m_taxi.IsTaximaskNodeKnown(activateTaxi.Node))
181 {
183 return;
184 }
185 }
186
187 uint32 preferredMountDisplay = 0;
188 if (MountEntry const* mount = sMountStore.LookupEntry(activateTaxi.FlyingMountID))
189 {
190 if (GetPlayer()->HasSpell(mount->SourceSpellID))
191 {
192 if (DB2Manager::MountXDisplayContainer const* mountDisplays = sDB2Manager.GetMountDisplays(mount->ID))
193 {
195 std::copy_if(mountDisplays->begin(), mountDisplays->end(), std::back_inserter(usableDisplays), [this](MountXDisplayEntry const* mountDisplay)
196 {
197 return ConditionMgr::IsPlayerMeetingCondition(GetPlayer(), mountDisplay->PlayerConditionID);
198 });
199
200 if (!usableDisplays.empty())
201 preferredMountDisplay = Trinity::Containers::SelectRandomContainerElement(usableDisplays)->CreatureDisplayInfoID;
202 }
203 }
204 }
205
206 std::vector<uint32> nodes;
208 GetPlayer()->ActivateTaxiPathTo(nodes, unit, 0, preferredMountDisplay);
209}
210
217
219{
220 if (FlightPathMovementGenerator* flight = dynamic_cast<FlightPathMovementGenerator*>(GetPlayer()->GetMotionMaster()->GetCurrentMovementGenerator()))
221 {
222 if (GetPlayer()->m_taxi.RequestEarlyLanding())
223 {
224 flight->LoadPath(GetPlayer(), flight->GetPath()[flight->GetCurrentNode()]->NodeIndex);
225 flight->Reset(GetPlayer());
226 }
227 }
228}
DB2Storage< TaxiNodesEntry > sTaxiNodesStore("TaxiNodes.db2", &TaxiNodesLoadInfo::Instance)
DB2Storage< MountEntry > sMountStore("Mount.db2", &MountLoadInfo::Instance)
#define sDB2Manager
Definition DB2Stores.h:569
uint32_t uint32
Definition Define.h:154
#define TC_LOG_DEBUG(filterType__, message__,...)
Definition Log.h:181
#define sObjectMgr
Definition ObjectMgr.h:1885
@ REP_NEUTRAL
@ TAXISTATUS_LEARNED
@ TAXISTATUS_UNLEARNED
@ TAXISTATUS_NONE
@ TAXISTATUS_NOT_ELIGIBLE
ActivateTaxiReply
@ ERR_TAXINOTVISITED
@ ERR_TAXITOOFARAWAY
@ SPELL_AURA_FEIGN_DEATH
@ UNIT_NPC_FLAG_FLIGHTMASTER
@ UNIT_NPC_FLAG_2_NONE
@ UNIT_STATE_DIED
Definition Unit.h:261
ObjectGuid const & GetGUID() const
Definition BaseEntity.h:163
std::vector< MountXDisplayEntry const * > MountXDisplayContainer
Definition DB2Stores.h:442
std::string ToString() const
uint32 GetEntry() const
Definition Object.h:89
void AppendTaximaskTo(WorldPackets::Taxi::ShowTaxiNodes &data, bool all)
bool IsTaximaskNodeKnown(uint32 nodeidx) const
Definition PlayerTaxi.h:50
Creature * GetNPCIfCanInteractWith(ObjectGuid const &guid, NPCFlags npcFlags, NPCFlags2 npcFlags2) const
Definition Player.cpp:1903
void UpdateCriteria(CriteriaType type, uint64 miscValue1=0, uint64 miscValue2=0, uint64 miscValue3=0, WorldObject *ref=nullptr)
Definition Player.cpp:27588
PlayerTaxi m_taxi
Definition Player.h:1293
bool ActivateTaxiPathTo(std::vector< uint32 > const &nodes, Creature *npc=nullptr, uint32 spellid=0, uint32 preferredMountDisplay=0, Optional< float > speed={}, Scripting::v2::ActionResultSetter< MovementStopReason > const &scriptResult={})
Definition Player.cpp:23160
void SetTaxiCheater(bool on)
Definition Player.h:1316
std::unique_ptr< PlayerMenu > PlayerTalkClass
Definition Player.h:2570
bool isTaxiCheater() const
Definition Player.h:1315
Team GetTeam() const
Definition Player.h:2423
size_t size() const
Definition DBCEnums.h:2513
void RemoveAurasByType(AuraType auraType, std::function< bool(AuraApplication const *)> const &check, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition Unit.cpp:3955
bool HasNpcFlag(NPCFlags flags) const
Definition Unit.h:996
constexpr uint32 GetMapId() const
Definition Position.h:216
bool IsHostileTo(WorldObject const *target) const
Definition Object.cpp:2181
ReputationRank GetReactionTo(WorldObject const *target) const
Definition Object.cpp:2028
WorldPacket const * Write() override
Optional< ShowTaxiNodesWindowInfo > WindowInfo
Definition TaxiPackets.h:64
WorldPacket const * Write() override
WorldPacket const * Write() override
void HandleActivateTaxiOpcode(WorldPackets::Taxi::ActivateTaxi &activateTaxi)
void HandleTaxiQueryAvailableNodesOpcode(WorldPackets::Taxi::TaxiQueryAvailableNodes &taxiQueryAvailableNodes)
void HandleTaxiRequestEarlyLanding(WorldPackets::Taxi::TaxiRequestEarlyLanding &taxiRequestEarlyLanding)
bool SendLearnNewTaxiNode(Creature *unit)
void SendTaxiMenu(Creature *unit)
void HandleTaxiNodeStatusQueryOpcode(WorldPackets::Taxi::TaxiNodeStatusQuery &taxiNodeStatusQuery)
void SendTaxiStatus(ObjectGuid guid)
void HandleEnableTaxiNodeOpcode(WorldPackets::Taxi::EnableTaxiNode &enableTaxiNode)
Player * GetPlayer() const
void SendActivateTaxiReply(ActivateTaxiReply reply)
void SendPacket(WorldPacket const *packet, bool forced=false)
Send a packet to the client.
void SendDiscoverNewTaxiNode(uint32 nodeid)
TC_GAME_API Creature * GetCreature(WorldObject const &u, ObjectGuid const &guid)
void GetReachableNodesMask(TaxiNodesEntry const *from, TaxiMask *mask)
std::size_t GetCompleteNodeRoute(TaxiNodesEntry const *from, TaxiNodesEntry const *to, Player const *player, std::vector< uint32 > &shortestPath)
auto SelectRandomContainerElement(C const &container) -> std::add_const_t< decltype(*std::ranges::begin(container))> &
Definition Containers.h:110
constexpr float GetPositionX() const
Definition Position.h:87
constexpr float GetPositionY() const
Definition Position.h:88
constexpr float GetPositionZ() const
Definition Position.h:89