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"
22#include "Unit.h"
23#include "PathGenerator.h"
24#include "Transport.h"
25#include "Opcodes.h"
26#include "WorldPacket.h"
27
28namespace Movement
29{
31 {
32 if (moveFlags & MOVEMENTFLAG_FLYING)
33 {
34 if (moveFlags & MOVEMENTFLAG_BACKWARD /*&& speed_obj.flight >= speed_obj.flight_back*/)
35 return MOVE_FLIGHT_BACK;
36 else
37 return MOVE_FLIGHT;
38 }
39 else if (moveFlags & MOVEMENTFLAG_SWIMMING)
40 {
41 if (moveFlags & MOVEMENTFLAG_BACKWARD /*&& speed_obj.swim >= speed_obj.swim_back*/)
42 return MOVE_SWIM_BACK;
43 else
44 return MOVE_SWIM;
45 }
46 else if (moveFlags & MOVEMENTFLAG_WALKING)
47 {
48 //if (speed_obj.run > speed_obj.walk)
49 return MOVE_WALK;
50 }
51 else if (moveFlags & MOVEMENTFLAG_BACKWARD /*&& speed_obj.run >= speed_obj.run_back*/)
52 return MOVE_RUN_BACK;
53
54 // Flying creatures use MOVEMENTFLAG_CAN_FLY or MOVEMENTFLAG_DISABLE_GRAVITY
55 // Run speed is their default flight speed.
56 return MOVE_RUN;
57 }
58
60 {
61 MoveSpline& move_spline = *unit->movespline;
62
63 // Elevators also use MOVEMENTFLAG_ONTRANSPORT but we do not keep track of their position changes (movementInfo.transport.guid is 0 in that case)
65 Location real_position;
66 // there is a big chance that current position is unknown if current state is not finalized, need compute it
67 // this also allows CalculatePath spline position and update map position in much greater intervals
68 // Don't compute for transport movement if the unit is in a motion between two transports
69 if (!move_spline.Finalized() && move_spline.onTransport == transport)
70 real_position = move_spline.ComputePosition();
71 else
72 {
73 Position const* pos;
74 if (!transport)
75 pos = unit;
76 else
78
79 real_position.x = pos->GetPositionX();
80 real_position.y = pos->GetPositionY();
81 real_position.z = pos->GetPositionZ();
82 real_position.orientation = unit->GetOrientation();
83 }
84
85 // should i do the things that user should do? - no.
86 if (args.path.empty())
87 return 0;
88
89 // corrent first vertex
90 args.path[0] = real_position;
91 args.initialOrientation = real_position.orientation;
93 move_spline.onTransport = transport;
94
96 moveFlags |= MOVEMENTFLAG_SPLINE_ENABLED;
97
98 if (!args.flags.backward)
99 moveFlags = (moveFlags & ~(MOVEMENTFLAG_BACKWARD)) | MOVEMENTFLAG_FORWARD;
100 else
101 moveFlags = (moveFlags & ~(MOVEMENTFLAG_FORWARD)) | MOVEMENTFLAG_BACKWARD;
102
103 if (moveFlags & MOVEMENTFLAG_ROOT)
104 moveFlags &= ~MOVEMENTFLAG_MASK_MOVING;
105
106 if (!args.HasVelocity)
107 {
108 // If spline is initialized with SetWalk method it only means we need to select
109 // walk move speed for it but not add walk flag to unit
110 uint32 moveFlagsForSpeed = moveFlags;
111 if (args.walk)
112 moveFlagsForSpeed |= MOVEMENTFLAG_WALKING;
113 else
114 moveFlagsForSpeed &= ~MOVEMENTFLAG_WALKING;
115
116 args.velocity = unit->GetSpeed(SelectSpeedType(moveFlagsForSpeed));
117 if (Creature* creature = unit->ToCreature())
118 if (creature->HasSearchedAssistance())
119 args.velocity *= 0.66f;
120 }
121
122 // limit the speed in the same way the client does
123 args.velocity = std::min(args.velocity, args.flags.catmullrom || args.flags.flying ? 50.0f : std::max(28.0f, unit->GetSpeed(MOVE_RUN) * 4.0f));
124
125 if (!args.Validate(unit))
126 return 0;
127
129 move_spline.Initialize(args);
130
132 data << unit->GetPackGUID();
133 if (transport)
134 {
136 data << unit->GetTransGUID().WriteAsPacked();
137 data << int8(unit->GetTransSeat());
138 }
139
140 PacketBuilder::WriteMonsterMove(move_spline, data);
141 unit->SendMessageToSet(&data, true);
142
143 return move_spline.Duration();
144 }
145
146 void MoveSplineInit::Stop(bool force /*= false*/)
147 {
148 MoveSpline& move_spline = *unit->movespline;
149
150 // No need to stop if we are not moving
151 if (!force && move_spline.Finalized())
152 return;
153
155 Location loc;
156 if (move_spline.onTransport == transport && !move_spline.Finalized())
157 loc = move_spline.ComputePosition();
158 else
159 {
160 Position const* pos;
161 if (!transport)
162 pos = unit;
163 else
165
166 loc.x = pos->GetPositionX();
167 loc.y = pos->GetPositionY();
168 loc.z = pos->GetPositionZ();
170 }
171
174 move_spline.onTransport = transport;
175 move_spline.Initialize(args);
176
178 data << unit->GetPackGUID();
179 if (transport)
180 {
182 data << unit->GetTransGUID().WriteAsPacked();
183 data << int8(unit->GetTransSeat());
184 }
185
187 unit->SendMessageToSet(&data, true);
188 }
189
191 {
193 // Elevators also use MOVEMENTFLAG_ONTRANSPORT but we do not keep track of their position changes
195 // mix existing state into new
199 }
200
202
203 void MoveSplineInit::SetFacing(Vector3 const& spot)
204 {
206 Vector3 finalSpot = transform(spot);
207 args.facing.f.x = finalSpot.x;
208 args.facing.f.y = finalSpot.y;
209 args.facing.f.z = finalSpot.z;
211 }
212
213 void MoveSplineInit::SetFacing(Unit const* target)
214 {
215 SetFacing(target->GetGUID());
216 }
217
219 {
221 args.facing.target = target;
222 }
223
225 {
227 {
228 if (Unit* vehicle = unit->GetVehicleBase())
229 angle -= vehicle->GetOrientation();
230 else if (Transport* transport = unit->GetTransport())
231 angle -= transport->GetOrientation();
232 }
233
234 args.facing.angle = G3D::wrap(angle, 0.f, (float)G3D::twoPi());
236 }
237
238 void MoveSplineInit::MovebyPath(PointsArray const& controls, int32 path_offset)
239 {
240 args.path_Idx_offset = path_offset;
241 args.path.resize(controls.size());
242 std::transform(controls.begin(), controls.end(), args.path.begin(), TransportPathTransform(unit, args.TransformForTransport));
243 }
244
245 void MoveSplineInit::MoveTo(float x, float y, float z, bool generatePath, bool forceDestination)
246 {
247 MoveTo(G3D::Vector3(x, y, z), generatePath, forceDestination);
248 }
249
250 void MoveSplineInit::MoveTo(Vector3 const& dest, bool generatePath, bool forceDestination)
251 {
252 if (generatePath)
253 {
254 PathGenerator path(unit);
255 bool result = path.CalculatePath(dest.x, dest.y, dest.z, forceDestination);
256 if (result && !(path.GetPathType() & PATHFIND_NOPATH))
257 {
258 MovebyPath(path.GetPath());
259 return;
260 }
261 }
262
264 args.path.resize(2);
266 args.path[1] = transform(dest);
267 }
268
273
275 {
277 if (TransportBase* transport = _owner->GetDirectTransport())
278 transport->CalculatePassengerOffset(input.x, input.y, input.z);
279
280 return input;
281 }
282}
int8_t int8
Definition Define.h:131
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
bool Finalized() const
Definition MoveSpline.h:121
void Initialize(MoveSplineInitArgs const &)
int32 Duration() const
Definition MoveSpline.h:89
static void WriteStopMovement(G3D::Vector3 const &loc, uint32 splineId, ByteBuffer &data)
static void WriteMonsterMove(MoveSpline const &mov, ByteBuffer &data)
Vector3 operator()(Vector3 input)
bool IsEmpty() const
Definition ObjectGuid.h:172
PackedGuidWriter WriteAsPacked() const
Definition ObjectGuid.h:152
static Creature * ToCreature(Object *o)
Definition Object.h:186
PackedGuid const & GetPackGUID() const
Definition Object.h:80
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:769
Movement::MoveSpline * movespline
Definition Unit.h:1804
float GetSpeed(UnitMoveType mtype) const
Definition Unit.cpp:8668
Unit * GetVehicleBase() const
Definition Unit.cpp:11826
bool HasUnitMovementFlag(uint32 f) const
Definition Unit.h:1678
TransportBase * GetDirectTransport() const
Returns the transport this unit is on directly (if on vehicle and transport, return vehicle)
Definition Unit.cpp:11866
ObjectGuid GetTransGUID() const override
Definition Unit.cpp:11856
virtual bool CanSwim() const
Definition Unit.cpp:12818
int8 GetTransSeat() const
Definition Object.h:571
virtual void SendMessageToSet(WorldPacket const *data, bool self) const
Definition Object.cpp:1783
Transport * GetTransport() const
Definition Object.h:564
MovementInfo m_movementInfo
Definition Object.h:575
void SetOpcode(uint16 opcode)
Definition WorldPacket.h:81
@ SMSG_MONSTER_MOVE
Definition Opcodes.h:250
@ SMSG_MONSTER_MOVE_TRANSPORT
Definition Opcodes.h:715
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