Project SkyFire Core
SkyFire 5.4.8 server core API documentation
Loading...
Searching...
No Matches
TransportMgr.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 "InstanceScript.h"
8#include "MapManager.h"
9#include "MoveSpline.h"
10#include "ObjectMgr.h"
11#include "ScriptMgr.h"
12#include "Transport.h"
13#include "TransportMgr.h"
14
16{
17 // Collect shared pointers into a set to avoid deleting the same memory more than once
18 std::set<TransportSpline*> splines;
19 for (size_t i = 0; i < keyFrames.size(); ++i)
20 splines.insert(keyFrames[i].Spline);
21
22 for (std::set<TransportSpline*>::iterator itr = splines.begin(); itr != splines.end(); ++itr)
23 delete* itr;
24}
25
27
29
31{
32 _transportTemplates.clear();
33}
34
39
41{
42 uint32 oldMSTime = getMSTime();
43
44 QueryResult result = WorldDatabase.Query("SELECT entry FROM gameobject_template WHERE type = 15 ORDER BY entry ASC");
45
46 if (!result)
47 {
48 SF_LOG_INFO("server.loading", ">> Loaded 0 transport templates. DB table `gameobject_template` has no transports!");
49 return;
50 }
51
52 uint32 count = 0;
53
54 do
55 {
56 Field* fields = result->Fetch();
57 uint32 entry = fields[0].GetUInt32();
58 GameObjectTemplate const* goInfo = sObjectMgr->GetGameObjectTemplate(entry);
59 if (goInfo->moTransport.taxiPathId >= sTaxiPathNodesByPath.size())
60 {
61 SF_LOG_ERROR("sql.sql", "Transport %u (name: %s) has an invalid path specified in `gameobject_template`.`data0` (%u) field, skipped.", entry, goInfo->name.c_str(), goInfo->moTransport.taxiPathId);
62 continue;
63 }
64
65 // paths are generated per template, saves us from generating it again in case of instanced transports
66 TransportTemplate& transport = _transportTemplates[entry];
67 transport.entry = entry;
68 GeneratePath(goInfo, &transport);
69
70 // transports in instance are only on one map
71 if (transport.inInstance)
72 _instanceTransports[*transport.mapsUsed.begin()].insert(entry);
73
74 ++count;
75 } while (result->NextRow());
76
77 SF_LOG_INFO("server.loading", ">> Loaded %u transport templates in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
78}
79
81{
82 uint32 pathId = goInfo->moTransport.taxiPathId;
83 TaxiPathNodeList const& path = sTaxiPathNodesByPath[pathId];
84 std::vector<KeyFrame>& keyFrames = transport->keyFrames;
85 Movement::PointsArray splinePath;
86 bool mapChange = false;
87 bool cyclic = true;
88 for (size_t i = 0; i < path.size(); ++i)
89 {
90 if (!mapChange)
91 {
92 TaxiPathNodeEntry const& node_i = path[i];
93 if (i != path.size() - 1 && (node_i.actionFlag == 1 || node_i.mapid != path[i + 1].mapid))
94 {
95 cyclic = false;
96 keyFrames.back().Teleport = true;
97 mapChange = true;
98 }
99 else
100 {
101 KeyFrame k(node_i);
102 keyFrames.push_back(k);
103 splinePath.push_back(G3D::Vector3(node_i.x, node_i.y, node_i.z));
104 transport->mapsUsed.insert(k.Node->mapid);
105 }
106 }
107 else
108 mapChange = false;
109 }
110
111 // Not sure if data8 means the transport can be stopped or that its path in dbc does not contain extra spline points
112 if (!goInfo->moTransport.canBeStopped && splinePath.size() >= 2)
113 {
114 // Remove special catmull-rom spline points
115 splinePath.erase(splinePath.begin());
116 keyFrames.erase(keyFrames.begin());
117 splinePath.pop_back();
118 keyFrames.pop_back();
119 // Cyclic spline has one more extra point
120 if (cyclic && !splinePath.empty())
121 {
122 splinePath.pop_back();
123 keyFrames.pop_back();
124 }
125 }
126
127 ASSERT(!keyFrames.empty());
128
129 if (transport->mapsUsed.size() > 1)
130 {
131 for (std::set<uint32>::const_iterator itr = transport->mapsUsed.begin(); itr != transport->mapsUsed.end(); ++itr)
132 ASSERT(!sMapStore.LookupEntry(*itr)->Instanceable());
133
134 transport->inInstance = false;
135 }
136 else
137 transport->inInstance = sMapStore.LookupEntry(*transport->mapsUsed.begin())->Instanceable();
138
139 // last to first is always "teleport", even for closed paths
140 keyFrames.back().Teleport = true;
141
142 const float speed = float(goInfo->moTransport.moveSpeed);
143 const float accel = float(goInfo->moTransport.accelRate);
144 const float accel_dist = 0.5f * speed * speed / accel;
145
146 transport->accelTime = speed / accel;
147 transport->accelDist = accel_dist;
148
149 int32 firstStop = -1;
150 int32 lastStop = -1;
151
152 // first cell is arrived at by teleportation :S
153 keyFrames[0].DistFromPrev = 0;
154 keyFrames[0].Index = 1;
155 if (keyFrames[0].IsStopFrame())
156 {
157 firstStop = 0;
158 lastStop = 0;
159 }
160
161 // find the rest of the distances between key points
162 // Every path segment has its own spline
163 if (cyclic)
164 {
165 TransportSpline* spline = new TransportSpline();
166 spline->init_cyclic_spline(&splinePath[0], splinePath.size(), Movement::SplineBase::ModeCatmullrom, 0);
167 spline->initLengths();
168 keyFrames[0].DistFromPrev = spline->length(spline->last() - 2, spline->last() - 1);
169 keyFrames[0].Spline = spline;
170 for (size_t i = 0; i < keyFrames.size(); ++i)
171 {
172 keyFrames[i].Index = i + 1;
173 keyFrames[i].DistFromPrev = spline->length(i, i + 1);
174 if (i > 0)
175 keyFrames[i - 1].NextDistFromPrev = keyFrames[i].DistFromPrev;
176 keyFrames[i].Spline = spline;
177 if (keyFrames[i].IsStopFrame())
178 {
179 // remember first stop frame
180 if (firstStop == -1)
181 firstStop = i;
182 lastStop = i;
183 }
184 }
185 }
186 else
187 {
188 size_t start = 0;
189 for (size_t i = 1; i < keyFrames.size(); ++i)
190 {
191 if (keyFrames[i - 1].Teleport || i + 1 == keyFrames.size())
192 {
193 size_t extra = !keyFrames[i - 1].Teleport ? 1 : 0;
194 TransportSpline* spline = new TransportSpline();
195 spline->init_spline(&splinePath[start], i - start + extra, Movement::SplineBase::ModeCatmullrom);
196 spline->initLengths();
197 for (size_t j = start; j < i + extra; ++j)
198 {
199 keyFrames[j].Index = j - start + 1;
200 keyFrames[j].DistFromPrev = spline->length(j - start, j + 1 - start);
201 if (j > 0)
202 keyFrames[j - 1].NextDistFromPrev = keyFrames[j].DistFromPrev;
203 keyFrames[j].Spline = spline;
204 }
205
206 if (keyFrames[i - 1].Teleport)
207 {
208 keyFrames[i].Index = i - start + 1;
209 keyFrames[i].DistFromPrev = 0.0f;
210 keyFrames[i - 1].NextDistFromPrev = 0.0f;
211 keyFrames[i].Spline = spline;
212 }
213
214 start = i;
215 }
216
217 if (keyFrames[i].IsStopFrame())
218 {
219 // remember first stop frame
220 if (firstStop == -1)
221 firstStop = i;
222 lastStop = i;
223 }
224 }
225 }
226
227 keyFrames.back().NextDistFromPrev = keyFrames.front().DistFromPrev;
228
229 if (firstStop == -1 || lastStop == -1)
230 firstStop = lastStop = 0;
231
232 // at stopping keyframes, we define distSinceStop == 0,
233 // and distUntilStop is to the next stopping keyframe.
234 // this is required to properly handle cases of two stopping frames in a row (yes they do exist)
235 float tmpDist = 0.0f;
236 for (size_t i = 0; i < keyFrames.size(); ++i)
237 {
238 int32 j = (i + lastStop) % keyFrames.size();
239 if (keyFrames[j].IsStopFrame() || j == lastStop)
240 tmpDist = 0.0f;
241 else
242 tmpDist += keyFrames[j].DistFromPrev;
243 keyFrames[j].DistSinceStop = tmpDist;
244 }
245
246 tmpDist = 0.0f;
247 for (int32 i = int32(keyFrames.size()) - 1; i >= 0; i--)
248 {
249 int32 j = (i + firstStop) % keyFrames.size();
250 tmpDist += keyFrames[(j + 1) % keyFrames.size()].DistFromPrev;
251 keyFrames[j].DistUntilStop = tmpDist;
252 if (keyFrames[j].IsStopFrame() || j == firstStop)
253 tmpDist = 0.0f;
254 }
255
256 for (size_t i = 0; i < keyFrames.size(); ++i)
257 {
258 float total_dist = keyFrames[i].DistSinceStop + keyFrames[i].DistUntilStop;
259 if (total_dist < 2 * accel_dist) // won't reach full speed
260 {
261 if (keyFrames[i].DistSinceStop < keyFrames[i].DistUntilStop) // is still accelerating
262 {
263 // calculate accel+brake time for this short segment
264 float segment_time = 2.0f * sqrt((keyFrames[i].DistUntilStop + keyFrames[i].DistSinceStop) / accel);
265 // substract acceleration time
266 keyFrames[i].TimeTo = segment_time - sqrt(2 * keyFrames[i].DistSinceStop / accel);
267 }
268 else // slowing down
269 keyFrames[i].TimeTo = sqrt(2 * keyFrames[i].DistUntilStop / accel);
270 }
271 else if (keyFrames[i].DistSinceStop < accel_dist) // still accelerating (but will reach full speed)
272 {
273 // calculate accel + cruise + brake time for this long segment
274 float segment_time = (keyFrames[i].DistUntilStop + keyFrames[i].DistSinceStop) / speed + (speed / accel);
275 // substract acceleration time
276 keyFrames[i].TimeTo = segment_time - sqrt(2 * keyFrames[i].DistSinceStop / accel);
277 }
278 else if (keyFrames[i].DistUntilStop < accel_dist) // already slowing down (but reached full speed)
279 keyFrames[i].TimeTo = sqrt(2 * keyFrames[i].DistUntilStop / accel);
280 else // at full speed
281 keyFrames[i].TimeTo = (keyFrames[i].DistUntilStop / speed) + (0.5f * speed / accel);
282 }
283
284 // calculate tFrom times from tTo times
285 float segmentTime = 0.0f;
286 for (size_t i = 0; i < keyFrames.size(); ++i)
287 {
288 int32 j = (i + lastStop) % keyFrames.size();
289 if (keyFrames[j].IsStopFrame() || j == lastStop)
290 segmentTime = keyFrames[j].TimeTo;
291 keyFrames[j].TimeFrom = segmentTime - keyFrames[j].TimeTo;
292 }
293
294 // calculate path times
295 keyFrames[0].ArriveTime = 0;
296 float curPathTime = 0.0f;
297 if (keyFrames[0].IsStopFrame())
298 {
299 curPathTime = float(keyFrames[0].Node->delay);
300 keyFrames[0].DepartureTime = uint32(curPathTime * float(IN_MILLISECONDS));
301 }
302
303 for (size_t i = 1; i < keyFrames.size(); ++i)
304 {
305 curPathTime += keyFrames[i - 1].TimeTo;
306 if (keyFrames[i].IsStopFrame())
307 {
308 keyFrames[i].ArriveTime = uint32(curPathTime * float(IN_MILLISECONDS));
309 keyFrames[i - 1].NextArriveTime = keyFrames[i].ArriveTime;
310 curPathTime += float(keyFrames[i].Node->delay);
311 keyFrames[i].DepartureTime = uint32(curPathTime * float(IN_MILLISECONDS));
312 }
313 else
314 {
315 curPathTime -= keyFrames[i].TimeTo;
316 keyFrames[i].ArriveTime = uint32(curPathTime * float(IN_MILLISECONDS));
317 keyFrames[i - 1].NextArriveTime = keyFrames[i].ArriveTime;
318 keyFrames[i].DepartureTime = keyFrames[i].ArriveTime;
319 }
320 }
321
322 keyFrames.back().NextArriveTime = keyFrames.back().DepartureTime;
323
324 transport->pathTime = keyFrames.back().DepartureTime;
325}
326
328{
329 TransportAnimation& animNode = _transportAnimations[transportEntry];
330 if (animNode.TotalTime < timeSeg)
331 animNode.TotalTime = timeSeg;
332
333 animNode.Path[timeSeg] = node;
334}
335
337{
338 GameObjectData const* data = sObjectMgr->GetGOData(guid);
339 if (!data)
340 {
341 SF_LOG_ERROR("entities.transport", "Local transport with guid %u will not be loaded, `gameobject` data is missing", guid);
342 return NULL;
343 }
344
345 uint32 const entry = GetLocalTransportEntry(data->id);
346 LegacyTransport::LegacyTransportSpawnDiagnostic diagnostic = { guid, data->id, entry, map->GetId(), map->GetSpawnMode(), data->posX, data->posY, data->posZ, data->orientation, 0, 0 };
347 if (!LegacyTransport::IsAllowedOnMap(data->id, map->GetId(), map->GetSpawnMode()))
348 return NULL;
349
350 if (TransportAnimation const* animationInfo = GetTransportAnimInfo(entry))
351 {
352 diagnostic.AnimTime = animationInfo->TotalTime;
353 diagnostic.AnimNodes = uint32(animationInfo->Path.size());
355 }
356 else
358
359 Transport* transport = new Transport();
360 if (!transport->CreateLocal(guid, entry, map, data->posX, data->posY, data->posZ, data->orientation,
361 data->rotation0, data->rotation1, data->rotation2, data->rotation3, data->animprogress))
362 {
364 delete transport;
365 return NULL;
366 }
367
368 ASSERT(transport->GetMap()->AddToMap<Transport>(transport));
369 diagnostic.X = transport->GetPositionX();
370 diagnostic.Y = transport->GetPositionY();
371 diagnostic.Z = transport->GetPositionZ();
372 diagnostic.O = transport->GetOrientation();
373 LegacyTransport::LogCreateSuccess(diagnostic, transport->GetGUID(), uint32(GUID_HIPART(transport->GetGUID())), uint32(GUID_LOPART(transport->GetGUID())),
374 transport->GetTimer(), transport->GetTransportPeriod(), uint32(transport->GetGoState()), uint32(transport->GetGoType()),
376 return transport;
377}
378
379Transport* TransportMgr::CreateLocalTransport(uint32 entry, Map* map, float x, float y, float z, float o, uint32 animprogress)
380{
381 Transport* transport = new Transport();
382 if (!transport->CreateLocal(0, entry, map, x, y, z, o, 0.0f, 0.0f, 0.0f, 1.0f, animprogress))
383 {
384 delete transport;
385 return NULL;
386 }
387
388 ASSERT(transport->GetMap()->AddToMap<Transport>(transport));
389 return transport;
390}
391
392Transport* TransportMgr::CreateTransport(uint32 entry, uint32 guid /*= 0*/, Map* map /*= NULL*/)
393{
394 // instance case, execute GetGameObjectEntry hook
395 if (map)
396 {
397 // SetZoneScript() is called after adding to map, so fetch the script using map
398 if (map->IsInstance())
399 if (InstanceScript* instance = static_cast<InstanceMap*>(map)->GetInstanceScript())
400 entry = instance->GetGameObjectEntry(0, entry);
401
402 if (!entry)
403 return NULL;
404 }
405
406 TransportTemplate const* tInfo = GetTransportTemplate(entry);
407 if (!tInfo)
408 {
409 SF_LOG_ERROR("sql.sql", "Transport %u will not be loaded, `transport_template` missing", entry);
410 return NULL;
411 }
412
413 // create transport...
414 Transport* trans = new Transport();
415
416 // ...at first waypoint
417 TaxiPathNodeEntry const* startNode = tInfo->keyFrames.begin()->Node;
418 uint32 mapId = startNode->mapid;
419 float x = startNode->x;
420 float y = startNode->y;
421 float z = startNode->z;
422 float o = 0.0f;
423
424 // initialize the gameobject base
425 uint32 guidLow = guid ? guid : sObjectMgr->GenerateLowGuid(HIGHGUID_MO_TRANSPORT);
426 if (!trans->Create(guidLow, entry, mapId, x, y, z, o, 255))
427 {
428 delete trans;
429 return NULL;
430 }
431
432 if (MapEntry const* mapEntry = sMapStore.LookupEntry(mapId))
433 {
434 if (mapEntry->Instanceable() != tInfo->inInstance)
435 {
436 SF_LOG_ERROR("entities.transport", "Transport %u (name: %s) attempted creation in instance map (id: %u) but it is not an instanced transport!", entry, trans->GetName().c_str(), mapId);
437 delete trans;
438 return NULL;
439 }
440 }
441
442 // use preset map for instances (need to know which instance)
443 trans->SetMap(map ? map : sMapMgr->CreateMap(mapId, NULL));
444 if (map && map->IsInstance())
446
447 // Passengers will be loaded once a player is near
448
449 trans->GetMap()->AddToMap<Transport>(trans);
450 return trans;
451}
452
454{
455 if (_transportTemplates.empty())
456 return;
457
458 uint32 oldMSTime = getMSTime();
459
460 QueryResult result = WorldDatabase.Query("SELECT guid, entry FROM transports");
461
462 uint32 count = 0;
463 if (result)
464 {
465 do
466 {
467 Field* fields = result->Fetch();
468 uint32 guid = fields[0].GetUInt32();
469 uint32 entry = fields[1].GetUInt32();
470
471 if (TransportTemplate const* tInfo = GetTransportTemplate(entry))
472 if (!tInfo->inInstance)
473 if (CreateTransport(entry, guid))
474 ++count;
475 } while (result->NextRow());
476 }
477
478 SF_LOG_INFO("server.loading", ">> Spawned %u continent transports in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
479}
480
482{
483 TransportInstanceMap::const_iterator mapTransports = _instanceTransports.find(map->GetId());
484
485 // no transports here
486 if (mapTransports == _instanceTransports.end() || mapTransports->second.empty())
487 return;
488
489 // create transports
490 for (std::set<uint32>::const_iterator itr = mapTransports->second.begin(); itr != mapTransports->second.end(); ++itr)
491 CreateTransport(*itr, 0, map);
492}
493
495{
496 TransportInstanceMap::const_iterator itr = _localTransportSpawns.find(MAKE_PAIR32(map->GetId(), map->GetSpawnMode()));
497 if (itr == _localTransportSpawns.end())
498 {
500 return;
501 }
502
503 LegacyTransport::LogSpawnCount(uint32(itr->second.size()), map->GetId(), map->GetSpawnMode());
504 for (std::set<uint32>::const_iterator guidItr = itr->second.begin(); guidItr != itr->second.end(); ++guidItr)
505 CreateLocalTransport(*guidItr, map);
506}
507
509{
510 if (Path.empty())
511 return NULL;
512
513 for (TransportPathContainer::const_reverse_iterator itr2 = Path.rbegin(); itr2 != Path.rend(); ++itr2)
514 if (time >= itr2->first)
515 return itr2->second;
516
517 return Path.begin()->second;
518}
519
521{
522 if (Path.empty())
523 return NULL;
524
525 TransportPathContainer::const_iterator itr = Path.lower_bound(time);
526 if (itr != Path.begin())
527 {
528 --itr;
529 return itr->second;
530 }
531
532 return Path.rbegin()->second;
533}
534
536{
537 if (Path.empty())
538 return NULL;
539
540 TransportPathContainer::const_iterator itr = Path.lower_bound(time);
541 if (itr != Path.end())
542 return itr->second;
543
544 return Path.begin()->second;
545}
546
548{
549 if (Rotations.empty())
550 return G3D::Quat(0.0f, 0.0f, 0.0f, 1.0f);
551
552 TransportRotationEntry const* rot = Rotations.begin()->second;
553 for (TransportPathRotationContainer::const_reverse_iterator itr2 = Rotations.rbegin(); itr2 != Rotations.rend(); ++itr2)
554 {
555 if (time >= itr2->first)
556 {
557 rot = itr2->second;
558 break;
559 }
560 }
561
562 return G3D::Quat(rot->X, rot->Y, rot->Z, rot->W);
563}
@ IN_MILLISECONDS
Definition Common.h:125
TaxiPathNodesByPath sTaxiPathNodesByPath
DBCStorage< MapEntry > sMapStore(MapEntryfmt)
Path< TaxiPathNodePtr, TaxiPathNodeEntry const > TaxiPathNodeList
std::int32_t int32
Definition Define.h:73
std::uint32_t uint32
Definition Define.h:77
#define ASSERT
Definition Errors.h:29
#define SF_LOG_ERROR(filterType__,...)
Definition Log.h:143
#define SF_LOG_INFO(filterType__,...)
Definition Log.h:137
#define sMapMgr
Definition MapManager.h:145
uint32 GUID_LOPART(uint64 x)
uint32 MAKE_PAIR32(uint16 l, uint16 h)
@ HIGHGUID_MO_TRANSPORT
uint32 GUID_HIPART(uint64 guid)
#define sObjectMgr
Definition ObjectMgr.h:1617
Skyfire::AutoPtr< ResultSet, Skyfire::Mutex > QueryResult
Definition QueryResult.h:48
uint32 GetMSTimeDiffToNow(uint32 oldMSTime)
Definition Timer.h:22
uint32 getMSTime()
Definition Timer.h:12
Movement::Spline< double > TransportSpline
@ OBJECT_FIELD_DYNAMIC_FLAGS
Definition Field.h:16
uint32 GetUInt32() const
Definition Field.h:105
GOState GetGoState() const
Definition GameObject.h:717
uint32 GetTransportPeriod() const
GameobjectTypes GetGoType() const
Definition GameObject.h:719
InstanceScript * GetInstanceScript()
Definition Map.h:647
Definition Map.h:238
bool AddToMap(T *)
Definition Map.cpp:504
uint8 GetSpawnMode() const
Definition Map.h:358
InstanceMap * ToInstanceMap()
Definition Map.h:440
uint32 GetId(void) const
Definition Map.h:300
bool IsInstance() const
Definition Map.h:368
index_type last() const
Definition Spline.h:91
void init_spline(const Vector3 *controls, index_type count, EvaluationMode m)
Definition Spline.h:157
void init_cyclic_spline(const Vector3 *controls, index_type count, EvaluationMode m, index_type cyclic_point)
Definition Spline.h:158
length_type length() const
Definition Spline.h:184
uint64 GetGUID() const
Definition Object.h:119
uint32 GetUInt32Value(uint16 index) const
Definition Object.cpp:325
size_t size() const
Definition Path.h:23
bool Create(uint32 guidlow, uint32 entry, uint32 mapid, float x, float y, float z, float ang, uint32 animprogress)
Definition Transport.cpp:36
bool CreateLocal(uint32 guidlow, uint32 entry, Map *map, float x, float y, float z, float ang, float rotation0, float rotation1, float rotation2, float rotation3, uint32 animprogress)
Definition Transport.cpp:91
uint32 GetTimer() const
Definition Transport.h:52
void LoadTransportTemplates()
TransportTemplates _transportTemplates
TransportAnimation const * GetTransportAnimInfo(uint32 entry) const
TransportInstanceMap _localTransportSpawns
Transport * CreateLocalTransport(uint32 guid, Map *map)
TransportAnimationContainer _transportAnimations
uint32 GetLocalTransportEntry(uint32 entry) const
void SpawnLocalTransports(Map *map)
void CreateInstanceTransports(Map *map)
TransportTemplate const * GetTransportTemplate(uint32 entry) const
TransportInstanceMap _instanceTransports
Transport * CreateTransport(uint32 entry, uint32 guid=0, Map *map=NULL)
void AddPathNodeToTransport(uint32 transportEntry, uint32 timeSeg, TransportAnimationEntry const *node)
void GeneratePath(GameObjectTemplate const *goInfo, TransportTemplate *transport)
void SpawnContinentTransports()
Map * GetMap() const
Definition Object.h:740
ZoneScript * m_zoneScript
Definition Object.h:818
std::string const & GetName() const
Definition Object.h:664
virtual void SetMap(Map *map)
Definition Object.cpp:2514
WorldDatabaseWorkerPool WorldDatabase
Accessor to the world database.
Definition Main.cpp:40
void LogCreateAttempt(LegacyTransportSpawnDiagnostic const &)
uint32 GetClientEntryForDbEntry(uint32 dbEntry)
void LogCreateFailure(LegacyTransportSpawnDiagnostic const &)
void LogCreateSuccess(LegacyTransportSpawnDiagnostic const &, uint64, uint32, uint32, uint32, uint32, uint32, uint32, uint32)
void LogMissingCreateAnimationData(uint32, uint32, uint32)
void LogNoRegisteredSpawns(uint32, uint32)
bool IsAllowedOnMap(uint32 dbEntry, uint32 mapId, uint32 spawnMode)
void LogSpawnCount(uint32, uint32, uint32)
std::vector< Vector3 > PointsArray
uint32 animprogress
Definition GameObject.h:603
std::string name
Definition GameObject.h:28
struct GameObjectTemplate::@046065176235271051340241126110345143267101032070::@316212233253022127367165230227137227160036113140 moTransport
TaxiPathNodeEntry const * Node
float GetPositionZ() const
Definition Object.h:330
float GetOrientation() const
Definition Object.h:331
float GetPositionX() const
Definition Object.h:328
float GetPositionY() const
Definition Object.h:329
float y
uint32 actionFlag
float x
uint32 mapid
float z
TransportPathRotationContainer Rotations
TransportAnimationEntry const * GetAnimNode(uint32 time) const
TransportPathContainer Path
G3D::Quat GetAnimRotation(uint32 time) const
TransportAnimationEntry const * GetNextAnimNode(uint32 time) const
TransportAnimationEntry const * GetPrevAnimNode(uint32 time) const
float W
float Y
float Z
float X
std::set< uint32 > mapsUsed
KeyFrameVec keyFrames