TrinityCore
MoveSplineInit.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 "MoveSplineInit.h"
19#include "Creature.h"
20#include "MovementPackets.h"
21#include "MoveSpline.h"
22#include "PathGenerator.h"
23#include "Transport.h"
24#include "Unit.h"
25
26namespace Movement
27{
29 {
30 if (moveFlags & MOVEMENTFLAG_FLYING)
31 {
32 if (moveFlags & MOVEMENTFLAG_BACKWARD /*&& speed_obj.flight >= speed_obj.flight_back*/)
33 return MOVE_FLIGHT_BACK;
34 else
35 return MOVE_FLIGHT;
36 }
37 else if (moveFlags & MOVEMENTFLAG_SWIMMING)
38 {
39 if (moveFlags & MOVEMENTFLAG_BACKWARD /*&& speed_obj.swim >= speed_obj.swim_back*/)
40 return MOVE_SWIM_BACK;
41 else
42 return MOVE_SWIM;
43 }
44 else if (moveFlags & MOVEMENTFLAG_WALKING)
45 {
46 //if (speed_obj.run > speed_obj.walk)
47 return MOVE_WALK;
48 }
49 else if (moveFlags & MOVEMENTFLAG_BACKWARD /*&& speed_obj.run >= speed_obj.run_back*/)
50 return MOVE_RUN_BACK;
51
52 // Flying creatures use MOVEMENTFLAG_CAN_FLY or MOVEMENTFLAG_DISABLE_GRAVITY
53 // Run speed is their default flight speed.
54 return MOVE_RUN;
55 }
56
58 {
59 MoveSpline& move_spline = *unit->movespline;
60
61 bool transport = !unit->GetTransGUID().IsEmpty();
62 Location real_position;
63 // there is a big chance that current position is unknown if current state is not finalized, need compute it
64 // this also allows calculate spline position and update map position in much greater intervals
65 // Don't compute for transport movement if the unit is in a motion between two transports
66 if (!move_spline.Finalized() && move_spline.onTransport == transport)
67 real_position = move_spline.ComputePosition();
68 else
69 {
70 Position const* pos;
71 if (!transport)
72 pos = unit;
73 else
75
76 real_position.x = pos->GetPositionX();
77 real_position.y = pos->GetPositionY();
78 real_position.z = pos->GetPositionZ();
79 real_position.orientation = unit->GetOrientation();
80 }
81
82 // should i do the things that user should do? - no.
83 if (args.path.empty())
84 return 0;
85
86 // correct first vertex
87 args.path[0] = real_position;
88 args.initialOrientation = real_position.orientation;
90 move_spline.onTransport = transport;
91
93 if (!args.flags.backward)
94 moveFlags = (moveFlags & ~MOVEMENTFLAG_BACKWARD) | MOVEMENTFLAG_FORWARD;
95 else
96 moveFlags = (moveFlags & ~MOVEMENTFLAG_FORWARD) | MOVEMENTFLAG_BACKWARD;
97
98 if (moveFlags & MOVEMENTFLAG_ROOT)
99 moveFlags &= ~MOVEMENTFLAG_MASK_MOVING;
100
101 if (!args.HasVelocity)
102 {
103 // If spline is initialized with SetWalk method it only means we need to select
104 // walk move speed for it but not add walk flag to unit
105 uint32 moveFlagsForSpeed = moveFlags;
106 if (args.walk)
107 moveFlagsForSpeed |= MOVEMENTFLAG_WALKING;
108 else
109 moveFlagsForSpeed &= ~MOVEMENTFLAG_WALKING;
110
111 args.velocity = unit->GetSpeed(SelectSpeedType(moveFlagsForSpeed));
112 if (Creature* creature = unit->ToCreature())
113 if (creature->HasSearchedAssistance())
114 args.velocity *= 0.66f;
115 }
116
117 // limit the speed in the same way the client does
118 float speedLimit = [&]()
119 {
121 return std::numeric_limits<float>::max();
122
124 return 50.0f;
125
126 return std::max(28.0f, unit->GetSpeed(MOVE_RUN) * 4.0f);
127 }();
128
129 args.velocity = std::min(args.velocity, speedLimit);
130
131 if (!args.Validate(unit))
132 return 0;
133
135 move_spline.Initialize(args);
136
138 packet.MoverGUID = unit->GetGUID();
139 packet.Pos = Position(real_position.x, real_position.y, real_position.z, real_position.orientation);
140 packet.InitializeSplineData(move_spline);
141 if (transport)
142 {
145 }
146
147 unit->SendMessageToSet(packet.Write(), true);
148
149 return move_spline.Duration();
150 }
151
153 {
154 MoveSpline& move_spline = *unit->movespline;
155
156 // No need to stop if we are not moving
157 if (move_spline.Finalized())
158 return;
159
160 bool transport = !unit->GetTransGUID().IsEmpty();
161 Location loc;
162 if (move_spline.onTransport == transport)
163 loc = move_spline.ComputePosition();
164 else
165 {
166 Position const* pos;
167 if (!transport)
168 pos = unit;
169 else
171
172 loc.x = pos->GetPositionX();
173 loc.y = pos->GetPositionY();
174 loc.z = pos->GetPositionZ();
176 }
177
180 move_spline.onTransport = transport;
181 move_spline.Initialize(args);
182
184 packet.MoverGUID = unit->GetGUID();
185 packet.Pos = Position(loc.x, loc.y, loc.z, loc.orientation);
187 packet.SplineData.ID = move_spline.GetId();
188
189 if (transport)
190 {
193 }
194
195 unit->SendMessageToSet(packet.Write(), true);
196 }
197
199 {
201 // Elevators also use MOVEMENTFLAG_ONTRANSPORT but we do not keep track of their position changes
203 // mix existing state into new
207 args.flags.smoothGroundPath = true; // enabled by default, CatmullRom mode or client config "pathSmoothing" will disable this
209 }
210
212
213 void MoveSplineInit::SetFacing(Vector3 const& spot)
214 {
216 Vector3 finalSpot = transform(spot);
217 args.facing.f.x = finalSpot.x;
218 args.facing.f.y = finalSpot.y;
219 args.facing.f.z = finalSpot.z;
221 }
222
223 void MoveSplineInit::SetFacing(float x, float y, float z)
224 {
225 SetFacing({ x, y, z });
226 }
227
228 void MoveSplineInit::SetFacing(Unit const* target)
229 {
231 args.facing.target = target->GetGUID();
233 }
234
236 {
238 {
239 if (Unit* vehicle = unit->GetVehicleBase())
240 angle -= vehicle->GetOrientation();
241 else if (TransportBase* transport = unit->GetTransport())
242 angle -= transport->GetTransportOrientation();
243 }
244
245 args.facing.angle = G3D::wrap(angle, 0.f, (float)G3D::twoPi());
247 }
248
249 void MoveSplineInit::MovebyPath(PointsArray const& controls, int32 path_offset)
250 {
251 args.path_Idx_offset = path_offset;
252 args.path.reserve(controls.size());
253 std::transform(controls.begin(), controls.end(), std::back_inserter(args.path), TransportPathTransform(unit, args.TransformForTransport));
254 }
255
256 void MoveSplineInit::MoveTo(float x, float y, float z, bool generatePath, bool forceDestination)
257 {
258 MoveTo(G3D::Vector3(x, y, z), generatePath, forceDestination);
259 }
260
261 void MoveSplineInit::MoveTo(Vector3 const& dest, bool generatePath, bool forceDestination)
262 {
263 if (generatePath)
264 {
265 PathGenerator path(unit);
266 bool result = path.CalculatePath(dest.x, dest.y, dest.z, forceDestination);
267 if (result && !(path.GetPathType() & PATHFIND_NOPATH))
268 {
269 MovebyPath(path.GetPath());
270 return;
271 }
272 }
273
275 args.path.resize(2);
277 args.path[1] = transform(dest);
278 }
279
281 {
284 }
285
287 {
289 if (TransportBase* transport = _owner->GetDirectTransport())
290 transport->CalculatePassengerOffset(input.x, input.y, input.z);
291
292 return input;
293 }
294}
int32_t int32
Definition: Define.h:138
uint32_t uint32
Definition: Define.h:142
@ PATHFIND_NOPATH
Definition: PathGenerator.h:47
UnitMoveType
Definition: UnitDefines.h:116
@ MOVE_FLIGHT
Definition: UnitDefines.h:123
@ MOVE_SWIM
Definition: UnitDefines.h:120
@ MOVE_FLIGHT_BACK
Definition: UnitDefines.h:124
@ MOVE_SWIM_BACK
Definition: UnitDefines.h:121
@ MOVE_RUN
Definition: UnitDefines.h:118
@ MOVE_RUN_BACK
Definition: UnitDefines.h:119
@ MOVE_WALK
Definition: UnitDefines.h:117
MovementFlags
Definition: UnitDefines.h:356
@ MOVEMENTFLAG_FORWARD
Definition: UnitDefines.h:358
@ MOVEMENTFLAG_BACKWARD
Definition: UnitDefines.h:359
@ MOVEMENTFLAG_DISABLE_GRAVITY
Definition: UnitDefines.h:367
@ MOVEMENTFLAG_FLYING
Definition: UnitDefines.h:382
@ MOVEMENTFLAG_FALLING_SLOW
Definition: UnitDefines.h:385
@ MOVEMENTFLAG_CAN_FLY
Definition: UnitDefines.h:381
@ MOVEMENTFLAG_ROOT
Definition: UnitDefines.h:368
@ MOVEMENTFLAG_SWIMMING
Definition: UnitDefines.h:378
@ MOVEMENTFLAG_WALKING
Definition: UnitDefines.h:366
@ UNIT_NPC_FLAG_2_STEERING
Definition: UnitDefines.h:339
void MoveTo(Vector3 const &destination, bool generatePath=true, bool forceDestination=false)
void SetFacing(float angle)
void MovebyPath(PointsArray const &path, int32 pointId=0)
MoveSplineInitArgs args
Location ComputePosition() const
Definition: MoveSpline.cpp:71
uint32 GetId() const
Definition: MoveSpline.h:136
bool Finalized() const
Definition: MoveSpline.h:137
void Initialize(MoveSplineInitArgs const &)
Definition: MoveSpline.cpp:182
int32 Duration() const
Definition: MoveSpline.h:104
Vector3 operator()(Vector3 input)
bool IsEmpty() const
Definition: ObjectGuid.h:319
static Creature * ToCreature(Object *o)
Definition: Object.h:219
static ObjectGuid GetGUID(Object const *o)
Definition: Object.h:159
Movement::PointsArray const & GetPath() const
Definition: PathGenerator.h:81
PathType GetPathType() const
Definition: PathGenerator.h:84
bool CalculatePath(float destX, float destY, float destZ, bool forceDest=false)
Definition: Unit.h:627
float GetSpeed(UnitMoveType mtype) const
Definition: Unit.cpp:8515
Unit * GetVehicleBase() const
Definition: Unit.cpp:11480
bool HasNpcFlag2(NPCFlags2 flags) const
Definition: Unit.h:987
bool HasUnitMovementFlag(uint32 f) const
Definition: Unit.h:1663
TransportBase * GetDirectTransport() const
Returns the transport this unit is on directly (if on vehicle and transport, return vehicle)
Definition: Unit.cpp:11520
ObjectGuid GetTransGUID() const override
Definition: Unit.cpp:11510
std::unique_ptr< Movement::MoveSpline > movespline
Definition: Unit.h:1766
virtual bool CanSwim() const
Definition: Unit.cpp:12313
int8 GetTransSeat() const
Definition: Object.h:757
virtual void SendMessageToSet(WorldPacket const *data, bool self) const
Definition: Object.cpp:1744
TransportBase * GetTransport() const
Definition: Object.h:750
MovementInfo m_movementInfo
Definition: Object.h:761
WorldPacket const * Write() override
TaggedPosition< Position::XYZ > Pos
void InitializeSplineData(::Movement::MoveSpline const &moveSpline)
UnitMoveType SelectSpeedType(uint32 moveFlags)
TC_GAME_API UInt32Counter splineIdGen
std::vector< Vector3 > PointsArray
@ MONSTER_MOVE_FACING_TARGET
@ MONSTER_MOVE_FACING_ANGLE
@ MONSTER_MOVE_FACING_SPOT
void RemoveMovementFlag(uint32 flag)
Definition: MovementInfo.h:111
struct MovementInfo::TransportInfo transport
void SetMovementFlags(uint32 flag)
Definition: MovementInfo.h:109
uint32 GetMovementFlags() const
Definition: MovementInfo.h:108
struct Movement::FacingInfo::@323 f
bool Validate(Unit *unit) const
============================================================================================
Definition: MoveSpline.cpp:241
constexpr float GetPositionX() const
Definition: Position.h:76
constexpr float GetPositionY() const
Definition: Position.h:77
float GetAbsoluteAngle(float x, float y) const
Definition: Position.h:125
constexpr float GetOrientation() const
Definition: Position.h:79
constexpr float GetPositionZ() const
Definition: Position.h:78