TrinityCore
Loading...
Searching...
No Matches
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 "MoveSpline.h"
21#include "MovementPackets.h"
22#include "Unit.h"
23#include "PathGenerator.h"
24#include "Transport.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 // Elevators also use MOVEMENTFLAG_ONTRANSPORT but we do not keep track of their position changes (movementInfo.transport.guid is 0 in that case)
63 Location real_position;
64 // there is a big chance that current position is unknown if current state is not finalized, need compute it
65 // this also allows CalculatePath spline position and update map position in much greater intervals
66 // Don't compute for transport movement if the unit is in a motion between two transports
67 if (!move_spline.Finalized() && move_spline.onTransport == transport)
68 real_position = move_spline.ComputePosition();
69 else
70 {
71 Position const* pos;
72 if (!transport)
73 pos = unit;
74 else
76
77 real_position.x = pos->GetPositionX();
78 real_position.y = pos->GetPositionY();
79 real_position.z = pos->GetPositionZ();
80 real_position.orientation = unit->GetOrientation();
81 }
82
83 // should i do the things that user should do? - no.
84 if (args.path.empty())
85 return 0;
86
87 // corrent first vertex
88 args.path[0] = real_position;
89 args.initialOrientation = real_position.orientation;
91 move_spline.onTransport = transport;
92
94 moveFlags |= MOVEMENTFLAG_SPLINE_ENABLED;
95
96 if (!args.flags.backward)
97 moveFlags = (moveFlags & ~(MOVEMENTFLAG_BACKWARD)) | MOVEMENTFLAG_FORWARD;
98 else
99 moveFlags = (moveFlags & ~(MOVEMENTFLAG_FORWARD)) | MOVEMENTFLAG_BACKWARD;
100
101 if (moveFlags & MOVEMENTFLAG_ROOT)
102 moveFlags &= ~MOVEMENTFLAG_MASK_MOVING;
103
104 if (!args.HasVelocity)
105 {
106 // If spline is initialized with SetWalk method it only means we need to select
107 // walk move speed for it but not add walk flag to unit
108 uint32 moveFlagsForSpeed = moveFlags;
109 if (args.walk)
110 moveFlagsForSpeed |= MOVEMENTFLAG_WALKING;
111 else
112 moveFlagsForSpeed &= ~MOVEMENTFLAG_WALKING;
113
114 args.velocity = unit->GetSpeed(SelectSpeedType(moveFlagsForSpeed));
115 if (Creature* creature = unit->ToCreature())
116 if (creature->HasSearchedAssistance())
117 args.velocity *= 0.66f;
118 }
119
120 // limit the speed in the same way the client does
121 args.velocity = std::min(args.velocity, args.flags.catmullrom || args.flags.flying ? 50.0f : std::max(28.0f, unit->GetSpeed(MOVE_RUN) * 4.0f));
122
123 if (!args.Validate(unit))
124 return 0;
125
127 move_spline.Initialize(args);
128
130 packet.MoverGUID = unit->GetGUID();
131 packet.Pos = Position(real_position.x, real_position.y, real_position.z, real_position.orientation);
132 packet.InitializeSplineData(move_spline);
133 if (transport)
134 {
135 WorldPackets::Movement::MovementSplineTransport& movementSplineTransport = packet.Transport.emplace();
136 movementSplineTransport.TransportGUID = unit->GetTransGUID();
137 movementSplineTransport.VehicleSeat = unit->GetTransSeat();
138 }
139
140 unit->SendMessageToSet(packet.Write(), true);
141
142 return move_spline.Duration();
143 }
144
145 void MoveSplineInit::Stop(bool force /*= false*/)
146 {
147 MoveSpline& move_spline = *unit->movespline;
148
149 // No need to stop if we are not moving
150 if (!force && move_spline.Finalized())
151 return;
152
154 Location loc;
155 if (move_spline.onTransport == transport && !move_spline.Finalized())
156 loc = move_spline.ComputePosition();
157 else
158 {
159 Position const* pos;
160 if (!transport)
161 pos = unit;
162 else
164
165 loc.x = pos->GetPositionX();
166 loc.y = pos->GetPositionY();
167 loc.z = pos->GetPositionZ();
169 }
170
173 move_spline.onTransport = transport;
174 move_spline.Initialize(args);
175
177 packet.MoverGUID = unit->GetGUID();
178 packet.Pos = Position(loc.x, loc.y, loc.z, loc.orientation);
180 packet.SplineData.ID = move_spline.GetId();
181
182 if (transport)
183 {
184 WorldPackets::Movement::MovementSplineTransport& movementSplineTransport = packet.Transport.emplace();
185 movementSplineTransport.TransportGUID = unit->GetTransGUID();
186 movementSplineTransport.VehicleSeat = unit->GetTransSeat();
187 }
188
189 unit->SendMessageToSet(packet.Write(), true);
190 }
191
193 {
195 // Elevators also use MOVEMENTFLAG_ONTRANSPORT but we do not keep track of their position changes
197 // mix existing state into new
201 }
202
204
205 void MoveSplineInit::SetFacing(Vector3 const& spot)
206 {
208 Vector3 finalSpot = transform(spot);
209 args.facing.f.x = finalSpot.x;
210 args.facing.f.y = finalSpot.y;
211 args.facing.f.z = finalSpot.z;
213 }
214
215 void MoveSplineInit::SetFacing(Unit const* target)
216 {
217 SetFacing(target->GetGUID());
218 }
219
221 {
223 args.facing.target = target;
224 }
225
227 {
229 {
230 if (Unit* vehicle = unit->GetVehicleBase())
231 angle -= vehicle->GetOrientation();
232 else if (Transport* transport = unit->GetTransport())
233 angle -= transport->GetOrientation();
234 }
235
236 args.facing.angle = G3D::wrap(angle, 0.f, (float)G3D::twoPi());
238 }
239
240 void MoveSplineInit::MovebyPath(PointsArray const& controls, int32 path_offset)
241 {
242 args.path_Idx_offset = path_offset;
243 args.path.resize(controls.size());
244 std::transform(controls.begin(), controls.end(), args.path.begin(), TransportPathTransform(unit, args.TransformForTransport));
245 }
246
247 void MoveSplineInit::MoveTo(float x, float y, float z, bool generatePath, bool forceDestination)
248 {
249 MoveTo(G3D::Vector3(x, y, z), generatePath, forceDestination);
250 }
251
252 void MoveSplineInit::MoveTo(Vector3 const& dest, bool generatePath, bool forceDestination)
253 {
254 if (generatePath)
255 {
256 PathGenerator path(unit);
257 bool result = path.CalculatePath(dest.x, dest.y, dest.z, forceDestination);
258 if (result && !(path.GetPathType() & PATHFIND_NOPATH))
259 {
260 MovebyPath(path.GetPath());
261 return;
262 }
263 }
264
266 args.path.resize(2);
268 args.path[1] = transform(dest);
269 }
270
275
277 {
279 if (TransportBase* transport = _owner->GetDirectTransport())
280 transport->CalculatePassengerOffset(input.x, input.y, input.z);
281
282 return input;
283 }
284}
int32_t int32
Definition Define.h:129
uint32_t uint32
Definition Define.h:133
@ PATHFIND_NOPATH
@ MOVEMENTFLAG_SPLINE_ENABLED
@ MOVEMENTFLAG_FORWARD
@ MOVEMENTFLAG_ONTRANSPORT
@ MOVEMENTFLAG_BACKWARD
@ MOVEMENTFLAG_DISABLE_GRAVITY
@ MOVEMENTFLAG_FLYING
@ MOVEMENTFLAG_CAN_FLY
@ MOVEMENTFLAG_ROOT
@ MOVEMENTFLAG_SWIMMING
@ MOVEMENTFLAG_WALKING
UnitMoveType
@ MOVE_FLIGHT
@ MOVE_SWIM
@ MOVE_FLIGHT_BACK
@ MOVE_SWIM_BACK
@ MOVE_RUN
@ MOVE_RUN_BACK
@ MOVE_WALK
void MoveTo(Vector3 const &destination, bool generatePath=true, bool forceDestination=false)
void Stop(bool force=false)
void SetFacing(float angle)
void MovebyPath(PointsArray const &path, int32 pointId=0)
MoveSplineInitArgs args
Location ComputePosition() const
uint32 GetId() const
Definition MoveSpline.h:132
bool Finalized() const
Definition MoveSpline.h:133
void Initialize(MoveSplineInitArgs const &)
int32 Duration() const
Definition MoveSpline.h:101
Vector3 operator()(Vector3 input)
bool IsEmpty() const
Definition ObjectGuid.h:172
static Creature * ToCreature(Object *o)
Definition Object.h:189
static ObjectGuid GetGUID(Object const *o)
Definition Object.h:78
Movement::PointsArray const & GetPath() const
PathType GetPathType() const
bool CalculatePath(float destX, float destY, float destZ, bool forceDest=false)
Definition Unit.h:783
Movement::MoveSpline * movespline
Definition Unit.h:1820
float GetSpeed(UnitMoveType mtype) const
Definition Unit.cpp:8608
Unit * GetVehicleBase() const
Definition Unit.cpp:11797
bool HasUnitMovementFlag(uint32 f) const
Definition Unit.h:1694
TransportBase * GetDirectTransport() const
Returns the transport this unit is on directly (if on vehicle and transport, return vehicle)
Definition Unit.cpp:11837
ObjectGuid GetTransGUID() const override
Definition Unit.cpp:11827
virtual bool CanSwim() const
Definition Unit.cpp:12789
int8 GetTransSeat() const
Definition Object.h:573
virtual void SendMessageToSet(WorldPacket const *data, bool self) const
Definition Object.cpp:1784
Transport * GetTransport() const
Definition Object.h:566
MovementInfo m_movementInfo
Definition Object.h:577
WorldPacket const * Write() override
TaggedPosition< Position::XYZ > Pos
Optional< MovementSplineTransport > Transport
void InitializeSplineData(::Movement::MoveSpline const &moveSpline)
UnitMoveType SelectSpeedType(uint32 moveFlags)
TC_GAME_API UInt32Counter splineIdGen
std::vector< Vector3 > PointsArray
void RemoveMovementFlag(uint32 flag)
struct MovementInfo::TransportInfo transport
void SetMovementFlags(uint32 flag)
bool HasMovementFlag(uint32 flag) const
uint32 GetMovementFlags() const
bool Validate(Unit *unit) const
============================================================================================
float GetPositionZ() const
Definition Position.h:81
float GetOrientation() const
Definition Position.h:82
float GetPositionX() const
Definition Position.h:79
float GetPositionY() const
Definition Position.h:80
struct Movement::FacingInfo::@263 f