Project SkyFire Core
SkyFire 5.4.8 server core API documentation
Loading...
Searching...
No Matches
MovementPacketBuilder.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
7#include "MoveSpline.h"
8#include "Object.h"
9#include "Unit.h"
10#include "WorldPacket.h"
11
12namespace Movement
13{
14 inline void operator << (ByteBuffer& b, const Vector3& v)
15 {
16 b << v.x << v.y << v.z;
17 }
18
19 inline void operator >> (ByteBuffer& b, Vector3& v)
20 {
21 b >> v.x >> v.y >> v.z;
22 }
23
38
39 void PacketBuilder::WriteStopMovement(Vector3 const& pos, uint32 splineId, ByteBuffer& data, Unit* unit)
40 {
41 bool hasVehicle = unit->GetVehicle();
42 ObjectGuid guid = unit->GetGUID();
43 ObjectGuid transport = unit->GetTransGUID();
44
45 data << float(pos.z);
46 data << float(pos.x);
47 data << uint32(splineId);
48 data << float(pos.y);
49 data << float(unit->GetTransOffsetY()); // Most likely transport Y
50 data << float(unit->GetTransOffsetZ()); // Most likely transport Z
51 data << float(unit->GetTransOffsetX()); // Most likely transport X
52
53 data.WriteBit(1); // Parabolic speed // esi+4Ch
54 data.WriteBit(guid[0]);
56 data.WriteBit(1);
57 data.WriteBit(1);
58 data.WriteBit(!hasVehicle);
59 data.WriteBits(0, 20);
60 data.WriteBit(1);
61 data.WriteBit(guid[3]);
62 data.WriteBit(1);
63 data.WriteBit(1);
64 data.WriteBit(1);
65 data.WriteBit(1);
66 data.WriteBit(guid[7]);
67 data.WriteBit(guid[4]);
68 data.WriteBit(1);
69 data.WriteBit(guid[5]);
70 data.WriteBits(0, 22); // WP count
71 data.WriteBit(guid[6]);
72 data.WriteBit(0); // Fake bit
73 data.WriteBit(transport[7]);
74 data.WriteBit(transport[1]);
75 data.WriteBit(transport[3]);
76 data.WriteBit(transport[0]);
77 data.WriteBit(transport[6]);
78 data.WriteBit(transport[4]);
79 data.WriteBit(transport[5]);
80 data.WriteBit(transport[2]);
81 data.WriteBit(0); // Send no block
82 data.WriteBit(0);
83 data.WriteBit(guid[2]);
84 data.WriteBit(guid[1]);
85
86 data.FlushBits();
87
88 data.WriteByteSeq(guid[1]);
89 data.WriteByteSeq(transport[6]);
90 data.WriteByteSeq(transport[4]);
91 data.WriteByteSeq(transport[1]);
92 data.WriteByteSeq(transport[7]);
93 data.WriteByteSeq(transport[0]);
94 data.WriteByteSeq(transport[3]);
95 data.WriteByteSeq(transport[5]);
96 data.WriteByteSeq(transport[2]);
97 data.WriteByteSeq(guid[5]);
98 data.WriteByteSeq(guid[3]);
99 data.WriteByteSeq(guid[6]);
100 data.WriteByteSeq(guid[0]);
101 if (hasVehicle)
102 data << uint8(unit->GetTransSeat());
103 data.WriteByteSeq(guid[7]);
104 data.WriteByteSeq(guid[2]);
105 data.WriteByteSeq(guid[4]);
106 }
107
108 void WriteLinearPath(Spline<int32> const& spline, ByteBuffer& data)
109 {
110 uint32 last_idx = spline.getPointCount() - 3;
111 Vector3 const* real_path = &spline.getPoint(1);
112
113 if (last_idx > 0)
114 {
115 Vector3 middle = (real_path[0] + real_path[last_idx]) / 2.f;
116 Vector3 offset;
117 // first and last points already appended
118 for (uint32 i = 0; i < last_idx; ++i)
119 {
120 offset = middle - real_path[i];
121 data.appendPackXYZ(offset.x, offset.y, offset.z);
122 }
123 }
124 }
125
127 {
128 for (int i = 1; i < spline.getPointCount() - 1; i++)
129 data << spline.getPoint(i).y << spline.getPoint(i).x << spline.getPoint(i).z;
130 }
131
133 {
134 data << spline.getPoint(1).y << spline.getPoint(1).x << spline.getPoint(1).z; // Fake point, client will erase it from the spline after first cycle done
135
136 for (int i = 1; i < spline.getPointCount() - 3; i++)
137 data << spline.getPoint(i).y << spline.getPoint(i).x << spline.getPoint(i).z;
138 }
139
140 void PacketBuilder::WriteMonsterMove(const MoveSpline& moveSpline, WorldPacket& data, Unit* unit)
141 {
142 bool hasVehicle = unit->GetVehicle();
143 ObjectGuid guid = unit->GetGUID();
144 ObjectGuid transport = unit->GetTransGUID();
145 MonsterMoveType type = GetMonsterMoveType(moveSpline);
146 G3D::Vector3 const& firstPoint = moveSpline.spline.getPoint(moveSpline.spline.first());
147 data << float(firstPoint.z);
148 data << float(firstPoint.x);
149 data << uint32(moveSpline.GetId());
150 data << float(firstPoint.y);
151 data << float(unit->GetTransOffsetY()); // Most likely transport Y
152 data << float(unit->GetTransOffsetZ()); // Most likely transport Z
153 data << float(unit->GetTransOffsetX()); // Most likely transport X
154
155 data.WriteBit(1); // Parabolic speed // esi+4Ch
156 data.WriteBit(guid[0]);
157 data.WriteBits(type, 3);
158
159 if (type == MonsterMoveFacingTarget)
160 {
161 ObjectGuid targetGuid = moveSpline.facing.target;
162 data.WriteBit(targetGuid[6]);
163 data.WriteBit(targetGuid[4]);
164 data.WriteBit(targetGuid[3]);
165 data.WriteBit(targetGuid[0]);
166 data.WriteBit(targetGuid[5]);
167 data.WriteBit(targetGuid[7]);
168 data.WriteBit(targetGuid[1]);
169 data.WriteBit(targetGuid[2]);
170 }
171
172 data.WriteBit(1);
173 data.WriteBit(1);
174 data.WriteBit(!hasVehicle);
175
176 uint32 uncompressedSplineCount = moveSpline.splineflags & MoveSplineFlag::UncompressedPath ? moveSpline.splineflags.cyclic ? moveSpline.spline.getPointCount() - 3 : moveSpline.spline.getPointCount() - 2 : 1;
177 data.WriteBits(uncompressedSplineCount, 20);
178
179 data.WriteBit(!moveSpline.splineflags.raw());
180 data.WriteBit(guid[3]);
181 data.WriteBit(1);
182 data.WriteBit(1);
183 data.WriteBit(1);
184 data.WriteBit(!moveSpline.Duration());
185 data.WriteBit(guid[7]);
186 data.WriteBit(guid[4]);
187 data.WriteBit(1);
188 data.WriteBit(guid[5]);
189
190 int32 compressedSplineCount = moveSpline.splineflags & MoveSplineFlag::UncompressedPath ? 0 : moveSpline.spline.getPointCount() - 3;
191 data.WriteBits(compressedSplineCount, 22); // WP count
192
193 data.WriteBit(guid[6]);
194 data.WriteBit(0); // Fake bit
195
196 data.WriteBit(transport[7]);
197 data.WriteBit(transport[1]);
198 data.WriteBit(transport[3]);
199 data.WriteBit(transport[0]);
200 data.WriteBit(transport[6]);
201 data.WriteBit(transport[4]);
202 data.WriteBit(transport[5]);
203 data.WriteBit(transport[2]);
204
205 data.WriteBit(0); // Send no block
206 data.WriteBit(0);
207 data.WriteBit(guid[2]);
208 data.WriteBit(guid[1]);
209
210 data.FlushBits();
211
212 if (compressedSplineCount)
213 WriteLinearPath(moveSpline.spline, data);
214
215 data.WriteByteSeq(guid[1]);
216 data.WriteByteSeq(transport[6]);
217 data.WriteByteSeq(transport[4]);
218 data.WriteByteSeq(transport[1]);
219 data.WriteByteSeq(transport[7]);
220 data.WriteByteSeq(transport[0]);
221 data.WriteByteSeq(transport[3]);
222 data.WriteByteSeq(transport[5]);
223 data.WriteByteSeq(transport[2]);
224
226 {
227 if (moveSpline.splineflags.cyclic)
228 WriteUncompressedCyclicPath(moveSpline.spline, data);
229 else
230 WriteUncompressedPath(moveSpline.spline, data);
231 }
232 else
233 {
234 G3D::Vector3 const& point = moveSpline.spline.getPoint(moveSpline.spline.getPointCount() - 2);
235 data << point.y << point.x << point.z;
236 }
237
238 if (type == MonsterMoveFacingTarget)
239 {
240 ObjectGuid targetGuid = moveSpline.facing.target;
241 data.WriteByteSeq(targetGuid[5]);
242 data.WriteByteSeq(targetGuid[7]);
243 data.WriteByteSeq(targetGuid[0]);
244 data.WriteByteSeq(targetGuid[4]);
245 data.WriteByteSeq(targetGuid[3]);
246 data.WriteByteSeq(targetGuid[2]);
247 data.WriteByteSeq(targetGuid[6]);
248 data.WriteByteSeq(targetGuid[1]);
249 }
250
251 data.WriteByteSeq(guid[5]);
252
253 if (type == MonsterMoveFacingAngle)
254 data << float(moveSpline.facing.angle);
255
256 data.WriteByteSeq(guid[3]);
257
258 if (moveSpline.splineflags.raw())
259 data << uint32(moveSpline.splineflags.raw());
260
261 data.WriteByteSeq(guid[6]);
262
263 if (type == MonsterMoveFacingPoint)
264 data << moveSpline.facing.f.x << moveSpline.facing.f.y << moveSpline.facing.f.z;
265
266 data.WriteByteSeq(guid[0]);
267 if (hasVehicle)
268 data << uint8(unit->GetTransSeat());
269 data.WriteByteSeq(guid[7]);
270 data.WriteByteSeq(guid[2]);
271 data.WriteByteSeq(guid[4]);
272
273 if (moveSpline.Duration())
274 data << uint32(moveSpline.Duration());
275 }
276
278 {
279 if (!data.WriteBit(!moveSpline.Finalized()))
280 return;
281
283 data.WriteBit((moveSpline.splineflags & MoveSplineFlag::Parabolic) && moveSpline.effect_start_time < moveSpline.Duration());
284 data.WriteBit(0); // NYI Block
285 data.WriteBits(moveSpline.getPath().size(), 20);
286 data.WriteBits(moveSpline.spline.mode(), 2);
287 data.WriteBits(moveSpline.splineflags.raw(), 25);
288 }
289
291 {
292 if (!moveSpline.Finalized())
293 {
294 MoveSplineFlag const& splineFlags = moveSpline.splineflags;
295 MonsterMoveType type = GetMonsterMoveType(moveSpline);
296
297 data << moveSpline.timePassed();
298 data << float(1.f); // splineInfo.duration_mod_next; added in 3.1
299 data << float(1.f); // splineInfo.duration_mod; added in 3.1
300
301 uint32 nodes = moveSpline.getPath().size();
302 for (uint32 i = 0; i < nodes; ++i)
303 {
304 data << float(moveSpline.getPath()[i].x);
305 data << float(moveSpline.getPath()[i].z);
306 data << float(moveSpline.getPath()[i].y);
307 }
308
310 data << moveSpline.effect_start_time; // added in 3.1
311
312 data << uint8(type);
313
314 if (type == MonsterMoveFacingAngle)
315 data << float(moveSpline.facing.angle);
316
317 if (type == MonsterMoveFacingPoint)
318 data << moveSpline.facing.f.x << moveSpline.facing.f.z << moveSpline.facing.f.y;
319
320 if ((splineFlags & MoveSplineFlag::Parabolic) && moveSpline.effect_start_time < moveSpline.Duration())
321 data << float(moveSpline.vertical_acceleration); // added in 3.1
322
323 // NYI block here
324 data << moveSpline.Duration();
325 }
326
327 Vector3 destination = moveSpline.isCyclic() ? Vector3::zero() : moveSpline.FinalDestination();
328
329 data << float(destination.x);
330 data << float(destination.z);
331 data << moveSpline.GetId();
332 data << float(destination.y);
333 }
334
336 {
337 if (GetMonsterMoveType(moveSpline) == MonsterMoveFacingTarget && !moveSpline.Finalized())
338 {
339 ObjectGuid facingGuid = moveSpline.facing.target;
340 data.WriteGuidMask(facingGuid, 4, 7, 0, 5, 1, 2, 3, 6);
341 data.WriteGuidBytes(facingGuid, 4, 2, 0, 5, 6, 3, 1, 7);
342 }
343 }
344}
std::int32_t int32
Definition Define.h:73
std::uint8_t uint8
Definition Define.h:79
std::uint32_t uint32
Definition Define.h:77
void WriteGuidBytes(const ObjectGuid &guid, Offsets... offsets)
Definition ByteBuffer.h:264
bool WriteBit(uint32 bit)
Definition ByteBuffer.h:164
void appendPackXYZ(float x, float y, float z)
Definition ByteBuffer.h:672
void WriteGuidMask(const ObjectGuid &guid, Offsets... offsets)
Definition ByteBuffer.h:248
void WriteBits(T value, size_t bits)
Definition ByteBuffer.h:192
void WriteByteSeq(uint8 b)
Definition ByteBuffer.h:227
void FlushBits()
Definition ByteBuffer.h:154
bool isCyclic() const
Definition MoveSpline.h:105
uint32 GetId() const
Definition MoveSpline.h:103
bool Finalized() const
Definition MoveSpline.h:104
MySpline::ControlArray const & getPath() const
Definition MoveSpline.h:62
int32 timePassed() const
Definition MoveSpline.h:70
Vector3 FinalDestination() const
Definition MoveSpline.h:107
int32 Duration() const
Definition MoveSpline.h:73
MoveSplineFlag splineflags
Definition MoveSpline.h:47
static void WriteCreateData(MoveSpline const &moveSpline, ByteBuffer &data)
static void WriteStopMovement(Vector3 const &loc, uint32 splineId, ByteBuffer &data, Unit *unit)
static void WriteFacingTargetPart(MoveSpline const &moveSpline, ByteBuffer &data)
static MonsterMoveType GetMonsterMoveType(MoveSpline const &moveSpline)
static void WriteCreateBits(MoveSpline const &moveSpline, ByteBuffer &data)
static void WriteMonsterMove(const MoveSpline &mov, WorldPacket &data, Unit *unit)
const Vector3 & getPoint(index_type i) const
Definition Spline.h:99
index_type first() const
Definition Spline.h:90
index_type getPointCount() const
Definition Spline.h:98
EvaluationMode mode() const
Definition Spline.h:94
uint64 GetGUID() const
Definition Object.h:119
Definition Unit.h:1367
Vehicle * GetVehicle() const
Definition Unit.h:2743
uint64 GetTransGUID() const override
Definition Unit.cpp:7217
int8 GetTransSeat() const
Definition Object.h:803
float GetTransOffsetX() const
Definition Object.h:798
float GetTransOffsetY() const
Definition Object.h:799
float GetTransOffsetZ() const
Definition Object.h:800
void WriteUncompressedCyclicPath(Spline< int32 > const &spline, ByteBuffer &data)
void WriteUncompressedPath(Spline< int32 > const &spline, ByteBuffer &data)
void WriteLinearPath(Spline< int32 > const &spline, ByteBuffer &data)
void operator<<(ByteBuffer &b, const Vector3 &v)
void operator>>(ByteBuffer &b, Vector3 &v)
struct Movement::FacingInfo::@351377220111011221135323375214233350203142103173 f