Project SkyFire Core
SkyFire 5.4.8 server core API documentation
Loading...
Searching...
No Matches
WaypointMovementGenerator.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//Basic headers
8//Extended headers
9#include "ObjectMgr.h"
10#include "World.h"
11#include "Transport.h"
12//Flightmaster grid preloading
13#include "MapManager.h"
14//Creature-specific headers
15#include "Creature.h"
16#include "CreatureAI.h"
17#include "CreatureGroups.h"
18//Player-specific
19#include "Player.h"
20#include "MoveSplineInit.h"
21#include "MoveSpline.h"
22
24{
25 if (!path_id)
26 path_id = creature->GetWaypointPath();
27
28 i_path = sWaypointMgr->GetPath(path_id);
29
30 if (!i_path)
31 {
32 // No path id found for entry
33 SF_LOG_ERROR("sql.sql", "WaypointMovementGenerator::LoadPath: creature %s (Entry: %u GUID: %u DB GUID: %u) doesn't have waypoint path id: %u", creature->GetName().c_str(), creature->GetEntry(), creature->GetGUIDLow(), creature->GetDBTableGUIDLow(), path_id);
34 return;
35 }
36
37 StartMoveNow(creature);
38}
39
45
51
57
59{
60 if (!i_path || i_path->empty())
61 return;
63 return;
64
66 m_isArrivalDone = true;
67
68 if (i_path->at(i_currentNode)->event_id && (std::rand() % 99) < i_path->at(i_currentNode)->event_chance)
69 {
70 SF_LOG_DEBUG("maps.script", "Creature movement start script %u at point %u for " UI64FMTD ".", i_path->at(i_currentNode)->event_id, i_currentNode, creature->GetGUID());
71 creature->GetMap()->ScriptsStart(sWaypointScripts, i_path->at(i_currentNode)->event_id, creature, NULL);
72 }
73
74 // Inform script
75 MovementInform(creature);
77 Stop(i_path->at(i_currentNode)->delay);
78}
79
81{
82 if (!i_path || i_path->empty())
83 return false;
84
85 if (Stopped())
86 return true;
87
88 bool transportPath = creature->GetTransport() != NULL;
89
91 {
92 if ((i_currentNode == i_path->size() - 1) && !repeating) // If that's our last waypoint
93 {
94 float x = i_path->at(i_currentNode)->x;
95 float y = i_path->at(i_currentNode)->y;
96 float z = i_path->at(i_currentNode)->z;
97 float o = creature->GetOrientation();
98
99 if (!transportPath)
100 creature->SetHomePosition(x, y, z, o);
101 else
102 {
103 if (Transport* trans = creature->GetTransport())
104 {
105 o -= trans->GetOrientation();
106 creature->SetTransportHomePosition(x, y, z, o);
107 trans->CalculatePassengerPosition(x, y, z, &o);
108 creature->SetHomePosition(x, y, z, o);
109 }
110 else
111 transportPath = false;
112 // else if (vehicle) - this should never happen, vehicle offsets are const
113 }
114
115 creature->GetMotionMaster()->Initialize();
116 return false;
117 }
118
119 i_currentNode = (i_currentNode + 1) % i_path->size();
120 }
121
122 WaypointData const* node = i_path->at(i_currentNode);
123
124 m_isArrivalDone = false;
125
127
128 Movement::Location formationDest(node->x, node->y, node->z, 0.0f);
129 Movement::MoveSplineInit init(creature);
130
132 if (transportPath)
133 {
135 if (TransportBase* trans = creature->GetDirectTransport())
136 trans->CalculatePassengerPosition(formationDest.x, formationDest.y, formationDest.z, &formationDest.orientation);
137 }
138
141 init.MoveTo(node->x, node->y, node->z);
142
144 if (node->orientation && node->delay)
145 init.SetFacing(node->orientation);
146
147 init.SetWalk(!node->run);
148 init.Launch();
149
150 //Call for creature group update
151 if (creature->GetFormation() && creature->GetFormation()->getLeader() == creature)
152 creature->GetFormation()->LeaderMoveTo(formationDest.x, formationDest.y, formationDest.z);
153
154 return true;
155}
156
158{
159 // Waypoint movement can be switched on/off
160 // This is quite handy for escort quests and other stuff
161 if (creature->HasUnitState(UNIT_STATE_NOT_MOVE))
162 {
164 return true;
165 }
166 // prevent a crash at empty waypoint path.
167 if (!i_path || i_path->empty())
168 return false;
169
170 if (Stopped())
171 {
172 if (CanMove(diff))
173 return StartMove(creature);
174 }
175 else
176 {
177 if (creature->IsStopped())
179 else if (creature->movespline->Finalized())
180 {
181 OnArrived(creature);
182 return StartMove(creature);
183 }
184 }
185 return true;
186}
187
193
195{
196 // prevent a crash at empty waypoint path.
197 if (!i_path || i_path->empty())
198 return false;
199
200 const WaypointData* node = i_path->at(i_currentNode);
201 x = node->x; y = node->y; z = node->z;
202 return true;
203}
204
205
206//----------------------------------------------------//
207
209{
210 if (i_currentNode >= i_path->size())
211 return i_path->size();
212
213 uint32 curMapId = (*i_path)[i_currentNode].mapid;
214 for (uint32 i = i_currentNode; i < i_path->size(); ++i)
215 {
216 if ((*i_path)[i].mapid != curMapId)
217 return i;
218 }
219
220 return i_path->size();
221}
222
224{
225 Reset(player);
227}
228
230{
231 // remove flag to prevent send object build movement packets for flight state and crash (movement generator already not at top of stack)
233
234 player->Dismount();
236
237 if (player->m_taxi.empty())
238 {
240 // update z position to ground and orientation for landing point
241 // this prevent cheating with landing point at lags
242 // when client side flight end early in comparison server side
243 player->StopMoving();
244 }
245
247}
248
249#define PLAYER_FLIGHT_SPEED 32.0f
250
252{
256
257 Movement::MoveSplineInit init(player);
258 uint32 end = GetPathAtMapEnd();
259 for (uint32 i = GetCurrentNode(); i != end; ++i)
260 {
261 G3D::Vector3 vertice((*i_path)[i].x, (*i_path)[i].y, (*i_path)[i].z);
262 init.Path().push_back(vertice);
263 }
265 init.SetFly();
266 init.SetSmooth();
267 init.SetUncompressed();
268 init.SetWalk(true);
270 init.Launch();
271}
272
274{
275 uint32 pointId = (uint32)player->movespline->currentPathIdx();
276 if (pointId > i_currentNode)
277 {
278 bool departureEvent = true;
279 do
280 {
281 DoEventIfAny(player, (*i_path)[i_currentNode], departureEvent);
282 if (pointId == i_currentNode)
283 break;
286 i_currentNode += (uint32)departureEvent;
287 departureEvent = !departureEvent;
288 } while (true);
289 }
290
291 return i_currentNode < (i_path->size() - 1);
292}
293
295{
296 if (i_path->empty())
297 return;
298
299 uint32 map0 = (*i_path)[0].mapid;
300 for (size_t i = 1; i < i_path->size(); ++i)
301 {
302 if ((*i_path)[i].mapid != map0)
303 {
304 i_currentNode = i;
305 return;
306 }
307 }
308}
309
311{
312 if (uint32 eventid = departure ? node.departureEventID : node.arrivalEventID)
313 {
314 SF_LOG_DEBUG("maps.script", "Taxi %s event %u of node %u of path %u for player %s", departure ? "departure" : "arrival", eventid, node.index, node.path, player->GetName().c_str());
315 player->GetMap()->ScriptsStart(sEventScripts, eventid, player, player);
316 }
317}
318
319bool FlightPathMovementGenerator::GetResetPos(Player*, float& x, float& y, float& z)
320{
321 const TaxiPathNodeEntry& node = (*i_path)[i_currentNode];
322 x = node.x; y = node.y; z = node.z;
323 return true;
324}
325
327{
330 uint32 nodeCount = (*i_path).size();
331 _endMapId = (*i_path)[nodeCount - 1].mapid;
332 _preloadTargetNode = nodeCount - 3;
333 _endGridX = (*i_path)[nodeCount - 1].x;
334 _endGridY = (*i_path)[nodeCount - 1].y;
335}
336
338{
339 // used to preload the final grid where the flightmaster is
340 Map* endMap = sMapMgr->FindBaseNonInstanceMap(_endMapId);
341
342 // Load the grid
343 if (endMap)
344 {
345 SF_LOG_INFO("misc", "Preloading rid (%f, %f) for map %u at node index %u/%u", _endGridX, _endGridY, _endMapId, _preloadTargetNode, (uint32)(i_path->size() - 1));
346 endMap->LoadGrid(_endGridX, _endGridY);
347 }
348 else
349 SF_LOG_INFO("misc", "Unable to determine map to preload flightmaster grid");
350}
#define UI64FMTD
Definition Define.h:64
std::uint32_t uint32
Definition Define.h:77
#define SF_LOG_DEBUG(filterType__,...)
Definition Log.h:134
#define SF_LOG_ERROR(filterType__,...)
Definition Log.h:143
#define SF_LOG_INFO(filterType__,...)
Definition Log.h:137
#define sMapMgr
Definition MapManager.h:145
@ WAYPOINT_MOTION_TYPE
ScriptMapMap sEventScripts
Definition ObjectMgr.cpp:51
ScriptMapMap sWaypointScripts
Definition ObjectMgr.cpp:52
@ PLAYER_FLAGS_TAXI_BENCHMARK
Definition Player.h:554
@ UNIT_STATE_NOT_MOVE
Definition Unit.h:549
@ UNIT_STATE_ROAMING_MOVE
Definition Unit.h:534
@ UNIT_STATE_ROAMING
Definition Unit.h:516
@ UNIT_STATE_IN_FLIGHT
Definition Unit.h:520
@ UNIT_FLAG_TAXI_FLIGHT
Definition Unit.h:645
@ UNIT_FLAG_DISABLE_MOVE
Definition Unit.h:627
@ UNIT_FIELD_FLAGS
@ PLAYER_FIELD_PLAYER_FLAGS
#define sWaypointMgr
#define PLAYER_FLIGHT_SPEED
#define STOP_TIME_FOR_PLAYER
virtual void MovementInform(uint32, uint32)
Definition CreatureAI.h:118
void LeaderMoveTo(float x, float y, float z)
Creature * getLeader() const
void SetHomePosition(float x, float y, float z, float o)
Definition Creature.h:626
uint32 GetDBTableGUIDLow() const
Definition Creature.h:445
uint32 GetWaypointPath() const
Definition Creature.h:636
void UpdateWaypointID(uint32 wpID)
Definition Creature.h:640
CreatureGroup * GetFormation()
Definition Creature.h:643
void SetTransportHomePosition(float x, float y, float z, float o)
Definition Creature.h:631
CreatureAI * AI() const
Definition Creature.h:483
float _endGridY
X coord of last node location.
uint32 _preloadTargetNode
map Id of last node location
uint32 _endMapId
Y coord of last node location.
void DoEventIfAny(Player *player, TaxiPathNodeEntry const &node, bool departure)
bool GetResetPos(Player *, float &x, float &y, float &z)
void setOnlineOfflineState(bool isOnline)
Definition Map.h:238
void ScriptsStart(std::map< uint32, std::multimap< uint32, ScriptInfo > > const &scripts, uint32 id, Object *source, Object *target)
Put scripts in the execution queue.
void LoadGrid(float x, float y)
Definition Map.cpp:455
void SetWalk(bool enable)
void SetFirstPointId(int32 pointId)
void SetVelocity(float velocity)
void SetFacing(float angle)
void MoveTo(const Vector3 &destination, bool generatePath=true, bool forceDestination=false)
uint64 GetGUID() const
Definition Object.h:119
uint32 GetGUIDLow() const
Definition Object.h:120
void SetFlag(uint16 index, uint32 newFlag)
Definition Object.cpp:1261
void RemoveFlag(uint16 index, uint32 oldFlag)
Definition Object.cpp:1280
uint32 GetEntry() const
Definition Object.h:125
PlayerTaxi m_taxi
Definition Player.h:1351
bool empty() const
Definition PlayerTaxi.h:70
void ClearUnitState(uint32 f)
Definition Unit.h:1489
bool IsStopped() const
Definition Unit.h:2614
MotionMaster * GetMotionMaster()
Definition Unit.h:2605
void Dismount()
Definition Unit.cpp:3685
void StopMoving()
-------—End of Pet responses methods-------—
Definition Unit.cpp:5877
void AddUnitState(uint32 f)
Definition Unit.h:1481
TransportBase * GetDirectTransport() const
Returns the transport this unit is on directly (if on vehicle and transport, return vehicle).
Definition Unit.cpp:7227
bool SetWalk(bool enable)
Definition Unit.cpp:9137
HostileRefManager & getHostileRefManager()
Definition Unit.h:2466
bool HasUnitState(const uint32 f) const
Definition Unit.h:1485
std::unique_ptr< Movement::MoveSpline > movespline
Definition Unit.h:2837
WaypointMovementGenerator(uint32 _path_id=0, bool _repeating=true)
Map * GetMap() const
Definition Object.h:740
std::string const & GetName() const
Definition Object.h:664
Transport * GetTransport() const
Definition Object.h:797
float GetOrientation() const
Definition Object.h:331
float y
uint32 arrivalEventID
uint32 departureEventID
float x
uint32 path
float z
uint32 index