OregonCore  revision 3611e8a-git
Your Favourite TBC server
WaypointMovementGenerator.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of the OregonCore 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 
19 #include "ObjectMgr.h"
20 #include "MapManager.h" // for flightmaster grid preloading
21 #include "Creature.h"
22 #include "CreatureAI.h"
23 #include "CreatureGroups.h"
24 #include "Player.h"
25 #include "MoveSplineInit.h"
26 #include "MoveSpline.h"
27 
28 template<class T>
30 
31 template<>
33 {
36 }
37 
38 template<>
40 
41 template<class T>
43 
44 template<>
46 {
47  unit.AI()->MovementInform(WAYPOINT_MOTION_TYPE, i_currentNode);
48 }
49 
50 template<>
52 {
53  StopedByPlayer = true;
54  i_nextMoveTime.Reset(0);
55 }
56 
57 template<>
59 
60 template<>
61 void
63 {
64  Movement::MoveSplineInit init(unit);
65  init.MoveTo(node.x, node.y, node.z, true);
66 
67  if (node.orientation != 100 && node.delay != 0)
68  init.SetFacing(node.orientation);
69 
70  if (!node.run)
71  init.SetWalk(true);
72  else
73  init.SetWalk(false);
74 
75  if (unit.canFly())
76  init.SetFly();
77 
78  int32 traveltime = init.Launch();
79 
80  i_nextMoveTime.Reset(traveltime);
81 }
82 
83 template<>
85 {
88 
90 }
91 
92 template<>
94 {
95  u.StopMoving();
96  //i_currentNode = -1; // uint32, become 0 in the first update
97  //i_nextMoveTime.Reset(0);
98  StopedByPlayer = false;
99  if (!path_id)
100  path_id = u.GetWaypointPath();
101  waypoints = sWaypointMgr->GetPath(path_id);
102  i_currentNode = 0;
103  if (waypoints && waypoints->size())
104  {
105  node = waypoints->front();
106  InitTraveller(u);
107  MoveToNextNode(u, *node);
108 
109  //Call for creature group update
110  if (u.GetFormation() && u.GetFormation()->getLeader() == &u)
111  u.GetFormation()->LeaderMoveTo(node->x, node->y, node->z);
112  }
113  else
114  node = NULL;
115 }
116 
117 template<>
119 
120 template<class T>
121 bool
122 WaypointMovementGenerator<T>::Update(T& /*unit*/, const uint32& /*diff*/)
123 {
124  return false;
125 }
126 
127 template<>
129 {
130  if (!path_id)
131  return false;
132 
133  // Waypoint movement can be switched on/off
134  // This is quite handy for escort quests and other stuff
136  return true;
137 
138  // Clear the generator if the path doesn't exist
139  if (!waypoints || !waypoints->size())
140  return false;
141 
142  i_nextMoveTime.Update(diff);
143 
144  if (i_nextMoveTime.GetExpiry() < TIMEDIFF_NEXT_WP)
145  {
146  if (unit.IsStopped())
147  {
148  if (StopedByPlayer)
149  {
150  ASSERT(node);
151  InitTraveller(unit);
152  MoveToNextNode(unit, *node);
153  StopedByPlayer = false;
154  return true;
155  }
156 
157  if (i_currentNode == waypoints->size() - 1) // If that's our last waypoint
158  {
159  if (repeating) // If the movement is repeating
160  i_currentNode = 0; // Start moving all over again
161  else
162  {
163  unit.SetHomePosition(node->x, node->y, node->z, unit.GetOrientation());
164  unit.GetMotionMaster()->Initialize();
165  return false; // Clear the waypoint movement
166  }
167  }
168  else
169  ++i_currentNode;
170 
171  node = waypoints->at(i_currentNode);
172  InitTraveller(unit);
173  MoveToNextNode(unit, *node);
174 
175  //Call for creature group update
176  if (unit.GetFormation() && unit.GetFormation()->getLeader() == &unit)
177  unit.GetFormation()->LeaderMoveTo(node->x, node->y, node->z);
178  }
179  else if (i_nextMoveTime.Passed()) //don't begin delay until movement is actually finished
180  {
181  // Determine wait time
182  if (node->delay)
183  i_nextMoveTime.Reset(node->delay);
184 
185  if (node->event_id && urand(0, 99) < node->event_chance)
186  {
187  sLog.outDebug("Creature movement start script %u at point %u for " UI64FMTD ".", node->event_id, i_currentNode, unit.GetGUID());
188  unit.GetMap()->ScriptsStart(sWaypointScripts, node->event_id, &unit, NULL);
189  }
190 
191  MovementInform(unit);
192  unit.UpdateWaypointID(i_currentNode);
194  }
195  }
196  else
197  {
198  if (unit.IsStopped() && !unit.movespline->Finalized())
199  {
200  if (!StopedByPlayer)
201  {
202  i_nextMoveTime.Reset(STOP_TIME_FOR_PLAYER);
203  StopedByPlayer = true;
204  }
205  }
206  }
207  return true;
208 }
209 
213 
214 //----------------------------------------------------//
216 {
217  if (i_currentNode >= i_path->size())
218  return i_path->size();
219 
220  uint32 curMapId = (*i_path)[i_currentNode].mapid;
221  for (uint32 i = i_currentNode; i < i_path->size(); ++i)
222  {
223  if ((*i_path)[i].mapid != curMapId)
224  return i;
225  }
226 
227  return i_path->size();
228 }
229 
231 {
232  Reset(player);
233 
234  // For preloading end grid
235  InitEndGridInfo();
236 }
237 
239 {
240  // remove flag to prevent send object build movement packets for flight state and crash (movement generator already not at top of stack)
242 
243  player.Dismount();
245  player.SetClientControl(&player, 1);
246 
247  if (player.m_taxi.empty())
248  {
250  if (player.pvpInfo.inHostileArea)
251  player.CastSpell(&player, 2479, true);
252 
253  // update z position to ground and orientation for landing point
254  // this prevent cheating with landing point at lags
255  // when client side flight end early in comparison server side
256  player.StopMoving();
257  }
258 }
259 
260 #define PLAYER_FLIGHT_SPEED 32.0f
261 
263 {
267  player.SetClientControl(&player, 0);
268 
269  Movement::MoveSplineInit init(player);
270  uint32 end = GetPathAtMapEnd();
271  for (uint32 i = GetCurrentNode(); i != end; ++i)
272  {
273  G3D::Vector3 vertice((*i_path)[i].x, (*i_path)[i].y, (*i_path)[i].z);
274  init.Path().push_back(vertice);
275  }
277  init.SetFly();
279  init.Launch();
280 }
281 
283 {
284  uint32 pointId = (uint32)player.movespline->currentPathIdx();
285  if (pointId > i_currentNode)
286  {
287  bool departureEvent = true;
288  do
289  {
290  DoEventIfAny(player, (*i_path)[i_currentNode], departureEvent);
291  if (pointId == i_currentNode)
292  break;
293  if (i_currentNode == m_preloadTargetNode)
294  PreloadEndGrid();
295  i_currentNode += (uint32)departureEvent;
296  departureEvent = !departureEvent;
297  }
298  while (true);
299  }
300 
301  const bool flying = (i_currentNode < (i_path->size() - 1));
302 
303  // Multi-map flight paths
304  if (flying && (*i_path)[i_currentNode + 1].mapid != player.GetMapId())
305  {
306  // short preparations to continue flight
308  TaxiPathNodeEntry const& node = (*i_path)[i_currentNode];
309  SkipCurrentNode();
310  player.TeleportTo(node.mapid, node.x, node.y, node.z, player.GetOrientation());
311  }
312 
313  return flying;
314 }
315 
317 {
318  if (i_path->empty())
319  return;
320 
321  uint32 map0 = (*i_path)[0].mapid;
322  for (size_t i = 1; i < i_path->size(); ++i)
323  {
324  if ((*i_path)[i].mapid != map0)
325  {
326  i_currentNode = i;
327  return;
328  }
329  }
330 }
331 
332 void FlightPathMovementGenerator::DoEventIfAny(Player& player, TaxiPathNodeEntry const& node, bool departure)
333 {
334  if (uint32 eventid = departure ? node.departureEventID : node.arrivalEventID)
335  {
336  sLog.outDebug("Taxi %s event %u of node %u of path %u for player %s", departure ? "departure" : "arrival", eventid, node.index, node.path, player.GetName());
337  player.GetMap()->ScriptsStart(sEventScripts, eventid, &player, &player);
338  }
339 }
340 
341 bool FlightPathMovementGenerator::GetResetPosition(Player&, float& x, float& y, float& z, float& o) const
342 {
343  const TaxiPathNodeEntry& node = (*i_path)[i_currentNode];
344  x = node.x; y = node.y; z = node.z;
345  return true;
346 }
347 
349 {
352  uint32 nodeCount = (*i_path).size();
353  m_endMapId = (*i_path)[nodeCount - 1].mapid;
354  m_preloadTargetNode = nodeCount - 3;
355  m_endGridX = (*i_path)[nodeCount - 1].x;
356  m_endGridY = (*i_path)[nodeCount - 1].y;
357 }
358 
360 {
361  // used to preload the final grid where the flightmaster is
363 
364  // Load the grid
365  if (endMap)
366  {
367  sLog.outDetail("Preloading flightmaster at grid (%f, %f) for map %u", m_endGridX, m_endGridY, m_endMapId);
368  endMap->LoadGrid(m_endGridX, m_endGridY);
369  }
370  else
371  sLog.outDetail("Unable to determine map to preload flightmaster grid");
372 }
void SetVelocity(float velocity)
bool SetWalk(bool enable) override
Definition: Creature.cpp:2514
int32 currentPathIdx() const
Definition: MoveSpline.cpp:276
PlayerTaxi m_taxi
Definition: Player.h:990
void ScriptsStart(std::map< uint32, std::multimap< uint32, ScriptInfo > > const &scripts, uint32 id, Object *source, Object *target)
Definition: MapScripts.cpp:33
void LoadGrid(float x, float y)
Definition: Map.cpp:388
Map * GetMap() const
Definition: Object.h:829
bool Update(Player &, const uint32 &)
bool empty() const
Definition: Path.h:39
void setOnlineOfflineState(bool pIsOnline)
void AddUnitState(uint32 f)
Definition: Unit.h:998
void UpdateWaypointID(uint32 wpID)
Definition: Creature.h:829
void MoveToNextNode(T &, const WaypointData &)
void Dismount()
Definition: Unit.cpp:9229
Movement::MoveSpline * movespline
Definition: Unit.h:2018
uint32 GetWaypointPath()
Definition: Creature.h:816
MotionMaster * GetMotionMaster()
Definition: Unit.h:2001
#define sLog
Log class singleton.
Definition: Log.h:187
void SetUInt32Value(uint16 index, uint32 value)
Definition: Object.cpp:779
ACE_INT32 int32
Definition: Define.h:67
void SetHomePosition(float x, float y, float z, float o)
Definition: Creature.h:794
bool empty() const
Definition: Player.h:880
Creature * getLeader() const
void SetFlag(uint16 index, uint32 newFlag)
Definition: Object.cpp:985
void MoveTo(const Vector3 &destination, bool generatePath=false, bool forceDestination=false)
#define TIMEDIFF_NEXT_WP
void ClearUnitState(uint32 f)
Definition: Unit.h:1006
bool canFly() const
Definition: Creature.h:520
bool TeleportTo(uint32 mapid, float x, float y, float z, float orientation, uint32 options=0)
Definition: Player.cpp:1556
float GetOrientation() const
Definition: Position.h:100
#define sWaypointMgr
#define STOP_TIME_FOR_PLAYER
#define UI64FMTD
Definition: Common.h:149
HostileRefManager & getHostileRefManager()
Definition: Unit.h:1842
bool IsStopped() const
Definition: Unit.h:2006
void CastSpell(Unit *Victim, uint32 spellId, bool triggered, Item *castItem=NULL, Aura *triggeredByAura=NULL, uint64 originalCaster=0)
Definition: Unit.cpp:1174
CreatureAI * AI() const
Definition: Creature.h:548
bool Update(T &, const uint32 &)
bool Finalized() const
Definition: MoveSpline.h:117
PvPInfo pvpInfo
Definition: Player.h:1773
uint32 GetMapId() const
Definition: Object.h:585
Definition: Map.h:266
Map * FindMap(uint32 mapid, uint32 instanceId=0) const
Definition: MapManager.cpp:137
void SetWalk(bool enable)
const char * GetName() const
Definition: Object.h:692
CreatureGroup * GetFormation()
Definition: Creature.h:835
void RemoveFlag(uint16 index, uint32 oldFlag)
Definition: Object.cpp:1006
#define PLAYER_FLIGHT_SPEED
ScriptMapMap sEventScripts
Definition: ObjectMgr.cpp:52
void SetFirstPointId(int32 pointId)
bool HasUnitState(const uint32 f) const
Definition: Unit.h:1002
void DoEventIfAny(Player &player, TaxiPathNodeEntry const &node, bool departure)
#define ASSERT
Definition: Errors.h:33
bool GetResetPosition(Player &, float &, float &, float &, float &) const
bool inHostileArea
Definition: Player.h:222
void SetClientControl(Unit *target, bool allowMove)
Definition: Player.cpp:19966
ACE_UINT32 uint32
Definition: Define.h:71
void Initialize()
void LeaderMoveTo(float x, float y, float z)
size_t size() const
Definition: Path.h:35
void StopMoving()
Definition: Unit.cpp:11838
Definition: Player.h:922
virtual void MovementInform(uint32, uint32)
Definition: CreatureAI.h:145
void SetFacing(float angle)
ScriptMapMap sWaypointScripts
Definition: ObjectMgr.cpp:54
uint32 urand(uint32 min, uint32 max)
Definition: Util.cpp:71
const uint64 & GetGUID() const
Definition: Object.h:156