TrinityCore
PlayerTaxi.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 "PlayerTaxi.h"
19#include "DB2Stores.h"
20#include "ObjectMgr.h"
21#include "Player.h"
22#include "StringConvert.h"
23#include "TaxiPackets.h"
24#include <sstream>
25
27{
28 // class specific initial known nodes
30 switch (chrClass)
31 {
33 {
34 for (std::size_t i = 0; i < m_taximask.size(); ++i)
35 m_taximask[i] |= sOldContinentsNodesMask[i] & factionMask[i];
36 break;
37 }
38 }
39
40 // race specific initial known nodes: capital and taxi hub masks
41 switch (race)
42 {
43 case RACE_HUMAN:
44 case RACE_DWARF:
45 case RACE_NIGHTELF:
46 case RACE_GNOME:
47 case RACE_DRAENEI:
48 case RACE_WORGEN:
50 SetTaximaskNode(2); // Stormwind, Elwynn
51 SetTaximaskNode(6); // Ironforge, Dun Morogh
52 SetTaximaskNode(26); // Lor'danel, Darkshore
53 SetTaximaskNode(27); // Rut'theran Village, Teldrassil
54 SetTaximaskNode(49); // Moonglade (Alliance)
55 SetTaximaskNode(94); // The Exodar
56 SetTaximaskNode(456); // Dolanaar, Teldrassil
57 SetTaximaskNode(457); // Darnassus, Teldrassil
58 SetTaximaskNode(582); // Goldshire, Elwynn
59 SetTaximaskNode(589); // Eastvale Logging Camp, Elwynn
60 SetTaximaskNode(619); // Kharanos, Dun Morogh
61 SetTaximaskNode(620); // Gol'Bolar Quarry, Dun Morogh
62 SetTaximaskNode(624); // Azure Watch, Azuremyst Isle
63 break;
64 case RACE_ORC:
66 case RACE_TAUREN:
67 case RACE_TROLL:
68 case RACE_BLOODELF:
69 case RACE_GOBLIN:
71 SetTaximaskNode(11); // Undercity, Tirisfal
72 SetTaximaskNode(22); // Thunder Bluff, Mulgore
73 SetTaximaskNode(23); // Orgrimmar, Durotar
74 SetTaximaskNode(69); // Moonglade (Horde)
75 SetTaximaskNode(82); // Silvermoon City
76 SetTaximaskNode(384); // The Bulwark, Tirisfal
77 SetTaximaskNode(402); // Bloodhoof Village, Mulgore
78 SetTaximaskNode(460); // Brill, Tirisfal Glades
79 SetTaximaskNode(536); // Sen'jin Village, Durotar
80 SetTaximaskNode(537); // Razor Hill, Durotar
81 SetTaximaskNode(625); // Fairbreeze Village, Eversong Woods
82 SetTaximaskNode(631); // Falconwing Square, Eversong Woods
83 break;
84 }
85
86 // new continent starting masks (It will be accessible only at new map)
87 switch (Player::TeamForRace(race))
88 {
89 case ALLIANCE: SetTaximaskNode(100); break;
90 case HORDE: SetTaximaskNode(99); break;
91 default:
92 break;
93 }
94
95 // level dependent taxi hubs
96 if (level >= 68)
97 SetTaximaskNode(213); //Shattered Sun Staging Area
98}
99
100bool PlayerTaxi::LoadTaxiMask(std::string const& data)
101{
102 bool warn = false;
103 std::vector<std::string_view> tokens = Trinity::Tokenize(data, ' ', false);
104 for (size_t index = 0; (index < m_taximask.size()) && (index < tokens.size()); ++index)
105 {
106 if (Optional<uint32> mask = Trinity::StringTo<uint32>(tokens[index]))
107 {
108 // load and set bits only for existing taxi nodes
109 m_taximask[index] = sTaxiNodesMask[index] & *mask;
110 if (m_taximask[index] != *mask)
111 warn = true;
112 }
113 else
114 {
115 m_taximask[index] = 0;
116 warn = true;
117 }
118 }
119 return !warn;
120}
121
123{
124 if (all)
125 {
126 data.CanLandNodes = sTaxiNodesMask; // all existed nodes
128 }
129 else
130 {
131 data.CanLandNodes = m_taximask; // known nodes
132 data.CanUseNodes = m_taximask;
133 }
134}
135
136bool PlayerTaxi::LoadTaxiDestinationsFromString(const std::string& values, uint32 team)
137{
139
140 std::vector<std::string_view> tokens = Trinity::Tokenize(values, ' ', false);
141 auto itr = tokens.begin();
142 if (itr != tokens.end())
143 {
144 if (Optional<uint32> faction = Trinity::StringTo<uint32>(*itr))
145 m_flightMasterFactionId = *faction;
146 else
147 return false;
148 }
149 else
150 return false;
151
152 while ((++itr) != tokens.end())
153 {
154 if (Optional<uint32> node = Trinity::StringTo<uint32>(*itr))
155 AddTaxiDestination(*node);
156 else
157 return false;
158 }
159
160 if (m_TaxiDestinations.empty())
161 return true;
162
163 // Check integrity
164 if (m_TaxiDestinations.size() < 2)
165 return false;
166
167 for (size_t i = 1; i < m_TaxiDestinations.size(); ++i)
168 {
169 uint32 cost;
170 uint32 path;
171 sObjectMgr->GetTaxiPath(m_TaxiDestinations[i - 1], m_TaxiDestinations[i], path, cost);
172 if (!path)
173 return false;
174 }
175
176 // can't load taxi path without mount set (quest taxi path?)
177 if (!sObjectMgr->GetTaxiMountDisplayId(GetTaxiSource(), team, true))
178 return false;
179
180 return true;
181}
182
184{
185 if (m_TaxiDestinations.empty())
186 return "";
187
188 ASSERT(m_TaxiDestinations.size() >= 2);
189
190 std::ostringstream ss;
191 ss << m_flightMasterFactionId << ' ';
192
193 for (size_t i = 0; i < m_TaxiDestinations.size(); ++i)
194 ss << m_TaxiDestinations[i] << ' ';
195
196 return ss.str();
197}
198
200{
201 if (m_TaxiDestinations.size() < 2)
202 return 0;
203
204 uint32 path;
205 uint32 cost;
206
207 sObjectMgr->GetTaxiPath(m_TaxiDestinations[0], m_TaxiDestinations[1], path, cost);
208
209 return path;
210}
211
212std::ostringstream& operator<<(std::ostringstream& ss, PlayerTaxi const& taxi)
213{
214 for (std::size_t i = 0; i < taxi.m_taximask.size(); ++i)
215 ss << uint32(taxi.m_taximask[i]) << ' ';
216 return ss;
217}
218
220{
221 if (m_TaxiDestinations.size() <= 2)
222 return false;
223
224 // start from first destination - m_TaxiDestinations[0] is the current starting node
225 for (std::deque<uint32>::iterator it = ++m_TaxiDestinations.begin(); it != m_TaxiDestinations.end(); ++it)
226 {
227 if (IsTaximaskNodeKnown(*it))
228 {
229 if (++it == m_TaxiDestinations.end())
230 return false; // if we are left with only 1 known node on the path don't change the spline, its our final destination anyway
231
232 m_TaxiDestinations.erase(it, m_TaxiDestinations.end());
233 return true;
234 }
235 }
236
237 return false;
238}
239
241{
243}
TaxiMask sAllianceTaxiNodesMask
Definition: DB2Stores.cpp:382
TaxiMask sTaxiNodesMask
Definition: DB2Stores.cpp:379
TaxiMask sOldContinentsNodesMask
Definition: DB2Stores.cpp:380
DB2Storage< FactionTemplateEntry > sFactionTemplateStore("FactionTemplate.db2", &FactionTemplateLoadInfo::Instance)
TaxiMask sHordeTaxiNodesMask
Definition: DB2Stores.cpp:381
uint8_t uint8
Definition: Define.h:144
uint32_t uint32
Definition: Define.h:142
#define ASSERT
Definition: Errors.h:68
#define sObjectMgr
Definition: ObjectMgr.h:1946
std::optional< T > Optional
Optional helper class to wrap optional values within.
Definition: Optional.h:25
std::ostringstream & operator<<(std::ostringstream &ss, PlayerTaxi const &taxi)
Definition: PlayerTaxi.cpp:212
@ RACE_TROLL
Definition: RaceMask.h:35
@ RACE_UNDEAD_PLAYER
Definition: RaceMask.h:32
@ RACE_ORC
Definition: RaceMask.h:29
@ RACE_DRAENEI
Definition: RaceMask.h:38
@ RACE_NIGHTELF
Definition: RaceMask.h:31
@ RACE_BLOODELF
Definition: RaceMask.h:37
@ RACE_DWARF
Definition: RaceMask.h:30
@ RACE_GNOME
Definition: RaceMask.h:34
@ RACE_GOBLIN
Definition: RaceMask.h:36
@ RACE_HUMAN
Definition: RaceMask.h:28
@ RACE_WORGEN
Definition: RaceMask.h:49
@ RACE_PANDAREN_ALLIANCE
Definition: RaceMask.h:52
@ RACE_PANDAREN_HORDE
Definition: RaceMask.h:53
@ RACE_TAUREN
Definition: RaceMask.h:33
@ CLASS_DEATH_KNIGHT
@ ALLIANCE
@ HORDE
std::string SaveTaxiDestinationsToString()
Definition: PlayerTaxi.cpp:183
void AddTaxiDestination(uint32 dest)
Definition: PlayerTaxi.h:71
bool SetTaximaskNode(uint32 nodeidx)
Definition: PlayerTaxi.h:51
std::deque< uint32 > m_TaxiDestinations
Definition: PlayerTaxi.h:89
uint32 GetTaxiSource() const
Definition: PlayerTaxi.h:72
FactionTemplateEntry const * GetFlightMasterFactionTemplate() const
Definition: PlayerTaxi.cpp:240
void AppendTaximaskTo(WorldPackets::Taxi::ShowTaxiNodes &data, bool all)
Definition: PlayerTaxi.cpp:122
bool RequestEarlyLanding()
Definition: PlayerTaxi.cpp:219
uint32 m_flightMasterFactionId
Definition: PlayerTaxi.h:90
bool LoadTaxiDestinationsFromString(std::string const &values, uint32 team)
Definition: PlayerTaxi.cpp:136
bool IsTaximaskNodeKnown(uint32 nodeidx) const
Definition: PlayerTaxi.h:45
bool LoadTaxiMask(std::string const &data)
Definition: PlayerTaxi.cpp:100
void ClearTaxiDestinations()
Definition: PlayerTaxi.h:70
TaxiMask m_taximask
Definition: PlayerTaxi.h:88
uint32 GetCurrentTaxiPath() const
Definition: PlayerTaxi.cpp:199
void InitTaxiNodesForLevel(uint32 race, uint32 chrClass, uint8 level)
Definition: PlayerTaxi.cpp:26
static Team TeamForRace(uint8 race)
Definition: Player.cpp:6454
size_t size() const
Definition: DBCEnums.h:2035
TC_COMMON_API std::vector< std::string_view > Tokenize(std::string_view str, char sep, bool keepEmpty)
Definition: Util.cpp:56