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