Project SkyFire Core
SkyFire 5.4.8 server core API documentation
Loading...
Searching...
No Matches
SpellHandler.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
6#include "Common.h"
7#include "CreatureAI.h"
8#include "GameObjectAI.h"
9#include "GuildMgr.h"
10#include "Log.h"
11#include "ObjectMgr.h"
12#include "Opcodes.h"
13#include "Player.h"
14#include "ScriptMgr.h"
15#include "Spell.h"
16#include "SpellAuraEffects.h"
17#include "SpellAuras.h"
18#include "SpellMgr.h"
19#include "TemporarySummon.h"
20#include "Totem.h"
21#include "WorldPacket.h"
22#include "WorldSession.h"
23
24namespace
25{
26struct GuidRequest
27{
28 ObjectGuid guid;
29};
30
31struct OpenItemRequest
32{
33 uint8 bagIndex;
34 uint8 slot;
35};
36
37struct UseItemRequest
38{
39 uint8 bagIndex;
40 uint8 slot;
41 uint8 castCount;
42 uint8 castFlags;
43 uint32 spellId;
44 uint32 glyphIndex;
45 uint32 targetMask;
46 float elevation;
47 float missileSpeed;
48 ObjectGuid itemGuid;
49 ObjectGuid targetGuid;
50 ObjectGuid itemTargetGuid;
51 ObjectGuid destTransportGuid;
52 ObjectGuid srcTransportGuid;
53 Position srcPos;
54 Position destPos;
55 std::string targetString;
56 SpellResearchData researchData;
57 bool hasResearchData;
58};
59
60struct CastSpellRequest
61{
62 uint8 castCount;
63 uint8 castFlags;
64 uint32 spellId;
65 uint32 glyphIndex;
66 uint32 targetMask;
67 float elevation;
68 float missileSpeed;
69 ObjectGuid targetGuid;
70 ObjectGuid itemTargetGuid;
71 ObjectGuid destTransportGuid;
72 ObjectGuid srcTransportGuid;
73 Position srcPos;
74 Position destPos;
75 std::string targetString;
76 SpellResearchData researchData;
77 bool hasResearchData;
78};
79
80struct CancelCastRequest
81{
82 uint32 spellId;
83 uint8 counter;
84};
85
86struct CancelAuraRequest
87{
88 ObjectGuid guid;
89 uint32 spellId;
90};
91
92struct PetCancelAuraRequest
93{
94 ObjectGuid guid;
95 uint32 spellId;
96};
97
98struct TotemDestroyedRequest
99{
100 ObjectGuid guid;
101 uint8 slotId;
102};
103
104struct SpellClickRequest
105{
106 ObjectGuid guid;
107 bool tryAutoDismount;
108};
109
110struct ProjectilePositionRequest
111{
112 uint64 casterGuid;
113 uint32 spellId;
114 uint8 castCount;
115 float x;
116 float y;
117 float z;
118};
119
120UseItemRequest ReadUseItemRequest(WorldPacket& recvPacket, Unit* caster)
121{
122 UseItemRequest request = UseItemRequest();
123 request.hasResearchData = false;
124 memset(&request.researchData, 0, sizeof(SpellResearchData));
125 uint32 targetStringLength = 0;
126 uint8 researchTypes[4] = { 0, 0, 0, 0 };
127
128 // Movement data
129 MovementInfo movementInfo;
130 ObjectGuid movementTransportGuid = 0;
131 ObjectGuid movementGuid = 0;
132 bool hasTransport = false;
133 bool hasTransportTime2 = false;
134 bool hasTransportTime3 = false;
135 bool hasFallData = false;
136 bool hasFallDirection = false;
137 bool hasTimestamp = false;
138 bool hasSplineElevation = false;
139 bool hasPitch = false;
140 bool hasOrientation = false;
141 bool hasUnkMovementField = false;
142 uint32 unkMovementLoopCounter = 0;
143
144 recvPacket >> request.slot >> request.bagIndex;
145
146 bool hasElevation = !recvPacket.ReadBit();
147 request.itemGuid[6] = recvPacket.ReadBit();
148 bool hasTargetString = !recvPacket.ReadBit();
149 request.itemGuid[1] = recvPacket.ReadBit();
150 bool hasCastFlags = !recvPacket.ReadBit();
151 bool hasDestLocation = recvPacket.ReadBit();
152 request.itemGuid[2] = recvPacket.ReadBit();
153 request.itemGuid[7] = recvPacket.ReadBit();
154 request.itemGuid[0] = recvPacket.ReadBit();
155 bool hasTargetMask = !recvPacket.ReadBit();
156 bool hasMissileSpeed = !recvPacket.ReadBit();
157 bool hasMovement = recvPacket.ReadBit();
158 bool hasCastCount = !recvPacket.ReadBit();
159 bool hasSpellId = !recvPacket.ReadBit();
160 recvPacket.ReadBit();
161 bool hasGlyphIndex = !recvPacket.ReadBit();
162 recvPacket.ReadBit();
163 request.itemGuid[4] = recvPacket.ReadBit();
164 bool hasSrcLocation = recvPacket.ReadBit();
165 request.itemGuid[3] = recvPacket.ReadBit();
166 request.itemGuid[5] = recvPacket.ReadBit();
167 uint8 researchDataCount = recvPacket.ReadBits(2);
168
169 for (uint8 i = 0; i < researchDataCount; ++i)
170 researchTypes[i] = recvPacket.ReadBits(2);
171
172 if (hasMovement)
173 {
174 hasPitch = !recvPacket.ReadBit();
175 hasTransport = recvPacket.ReadBit();
176 recvPacket.ReadBit();
177
178 if (hasTransport)
179 {
180 movementTransportGuid[7] = recvPacket.ReadBit();
181 movementTransportGuid[2] = recvPacket.ReadBit();
182 movementTransportGuid[4] = recvPacket.ReadBit();
183 movementTransportGuid[5] = recvPacket.ReadBit();
184 movementTransportGuid[6] = recvPacket.ReadBit();
185 movementTransportGuid[0] = recvPacket.ReadBit();
186 movementTransportGuid[1] = recvPacket.ReadBit();
187 hasTransportTime3 = recvPacket.ReadBit();
188 movementTransportGuid[4] = recvPacket.ReadBit();
189 hasTransportTime2 = recvPacket.ReadBit();
190 }
191
192 movementGuid[6] = recvPacket.ReadBit();
193 movementGuid[2] = recvPacket.ReadBit();
194 movementGuid[1] = recvPacket.ReadBit();
195 unkMovementLoopCounter = recvPacket.ReadBits(22);
196 recvPacket.ReadBit();
197 bool hasMovementFlags2 = !recvPacket.ReadBit();
198 hasFallData = recvPacket.ReadBit();
199 movementGuid[5] = recvPacket.ReadBit();
200 hasSplineElevation = !recvPacket.ReadBit();
201 recvPacket.ReadBit();
202 movementGuid[7] = recvPacket.ReadBit();
203 movementGuid[0] = recvPacket.ReadBit();
204
205 if (hasFallData)
206 hasFallDirection = recvPacket.ReadBit();
207
208 hasOrientation = !recvPacket.ReadBit();
209 movementGuid[4] = recvPacket.ReadBit();
210 movementGuid[3] = recvPacket.ReadBit();
211 hasTimestamp = !recvPacket.ReadBit();
212 hasUnkMovementField = !recvPacket.ReadBit();
213 bool hasMovementFlags = !recvPacket.ReadBit();
214
215 if (hasMovementFlags2)
216 movementInfo.flags2 = recvPacket.ReadBits(13);
217
218 if (hasMovement)
219 movementInfo.flags = recvPacket.ReadBits(30);
220 }
221
222 if (hasSrcLocation)
223 {
224 request.srcTransportGuid[3] = recvPacket.ReadBit();
225 request.srcTransportGuid[1] = recvPacket.ReadBit();
226 request.srcTransportGuid[7] = recvPacket.ReadBit();
227 request.srcTransportGuid[4] = recvPacket.ReadBit();
228 request.srcTransportGuid[2] = recvPacket.ReadBit();
229 request.srcTransportGuid[0] = recvPacket.ReadBit();
230 request.srcTransportGuid[6] = recvPacket.ReadBit();
231 request.srcTransportGuid[5] = recvPacket.ReadBit();
232 }
233
234 if (hasDestLocation)
235 {
236 request.destTransportGuid[2] = recvPacket.ReadBit();
237 request.destTransportGuid[4] = recvPacket.ReadBit();
238 request.destTransportGuid[1] = recvPacket.ReadBit();
239 request.destTransportGuid[7] = recvPacket.ReadBit();
240 request.destTransportGuid[6] = recvPacket.ReadBit();
241 request.destTransportGuid[0] = recvPacket.ReadBit();
242 request.destTransportGuid[3] = recvPacket.ReadBit();
243 request.destTransportGuid[5] = recvPacket.ReadBit();
244 }
245
246 if (hasTargetString)
247 targetStringLength = recvPacket.ReadBits(7);
248
249 request.targetGuid[1] = recvPacket.ReadBit();
250 request.targetGuid[0] = recvPacket.ReadBit();
251 request.targetGuid[5] = recvPacket.ReadBit();
252 request.targetGuid[3] = recvPacket.ReadBit();
253 request.targetGuid[6] = recvPacket.ReadBit();
254 request.targetGuid[4] = recvPacket.ReadBit();
255 request.targetGuid[7] = recvPacket.ReadBit();
256 request.targetGuid[2] = recvPacket.ReadBit();
257
258 request.itemTargetGuid[4] = recvPacket.ReadBit();
259 request.itemTargetGuid[5] = recvPacket.ReadBit();
260 request.itemTargetGuid[0] = recvPacket.ReadBit();
261 request.itemTargetGuid[1] = recvPacket.ReadBit();
262 request.itemTargetGuid[3] = recvPacket.ReadBit();
263 request.itemTargetGuid[7] = recvPacket.ReadBit();
264 request.itemTargetGuid[6] = recvPacket.ReadBit();
265 request.itemTargetGuid[2] = recvPacket.ReadBit();
266
267 if (hasCastFlags)
268 request.castFlags = recvPacket.ReadBits(5);
269
270 if (hasTargetMask)
271 request.targetMask = recvPacket.ReadBits(20);
272
273 recvPacket.ReadByteSeq(request.itemGuid[0]);
274 recvPacket.ReadByteSeq(request.itemGuid[5]);
275 recvPacket.ReadByteSeq(request.itemGuid[6]);
276 recvPacket.ReadByteSeq(request.itemGuid[3]);
277 recvPacket.ReadByteSeq(request.itemGuid[4]);
278 recvPacket.ReadByteSeq(request.itemGuid[2]);
279 recvPacket.ReadByteSeq(request.itemGuid[1]);
280
281 for (uint8 i = 0; i < researchDataCount; ++i)
282 {
283 // Client sends (usedCount, entryId); type 1 = keystone item, type 2 = fragment currency.
284 uint32 usedCount = 0;
285 uint32 entry = 0;
286 recvPacket >> usedCount;
287 recvPacket >> entry;
288
289 switch (researchTypes[i])
290 {
291 case 1: // Keystones
292 request.researchData.keystoneItemId = entry;
293 request.researchData.keystoneCount = usedCount;
294 request.hasResearchData = true;
295 break;
296 case 2: // Fragments
297 request.researchData.fragmentCurrencyId = entry;
298 request.researchData.fragmentCount = usedCount;
299 request.hasResearchData = true;
300 break;
301 default:
302 break;
303 }
304 }
305
306 recvPacket.ReadByteSeq(request.itemGuid[7]);
307
308 if (hasMovement)
309 {
310 for (uint8 i = 0; i != unkMovementLoopCounter; i++)
311 recvPacket.read_skip<uint32>();
312
313 if (hasTransport)
314 {
315 recvPacket >> movementInfo.transport.pos.m_positionY;
316 recvPacket >> movementInfo.transport.pos.m_positionZ;
317 recvPacket.ReadByteSeq(movementTransportGuid[1]);
318
319 if (hasTransportTime3)
320 recvPacket >> movementInfo.transport.time3;
321
322 recvPacket.ReadByteSeq(movementTransportGuid[7]);
323 recvPacket.ReadByteSeq(movementTransportGuid[5]);
324 recvPacket.ReadByteSeq(movementTransportGuid[2]);
325 recvPacket.ReadByteSeq(movementTransportGuid[4]);
326 recvPacket >> movementInfo.transport.pos.m_positionX;
327 movementInfo.transport.pos.SetOrientation(recvPacket.read<float>());
328 recvPacket.ReadByteSeq(movementTransportGuid[0]);
329 recvPacket >> movementInfo.transport.seat;
330 recvPacket >> movementInfo.transport.time;
331 recvPacket.ReadByteSeq(movementTransportGuid[6]);
332 recvPacket.ReadByteSeq(movementTransportGuid[3]);
333
334 if (hasTransportTime2)
335 recvPacket >> movementInfo.transport.time2;
336 }
337
338 if (hasFallData)
339 {
340 recvPacket >> movementInfo.jump.zspeed;
341
342 if (hasFallDirection)
343 {
344 recvPacket >> movementInfo.jump.sinAngle;
345 recvPacket >> movementInfo.jump.cosAngle;
346 recvPacket >> movementInfo.jump.xyspeed;
347 }
348
349 recvPacket >> movementInfo.jump.fallTime;
350 }
351
352 recvPacket.ReadByteSeq(movementTransportGuid[3]);
353 recvPacket.ReadByteSeq(movementTransportGuid[7]);
354 recvPacket.ReadByteSeq(movementTransportGuid[6]);
355 recvPacket.ReadByteSeq(movementTransportGuid[1]);
356 recvPacket >> movementInfo.pos.m_positionY;
357
358 if (hasSplineElevation)
359 recvPacket >> movementInfo.splineElevation;
360
361 if (hasUnkMovementField)
362 recvPacket.read_skip<uint32>();
363
364 if (hasOrientation)
365 movementInfo.pos.SetOrientation(recvPacket.read<float>());
366
367 recvPacket.ReadByteSeq(movementTransportGuid[2]);
368 recvPacket >> movementInfo.pos.m_positionZ;
369
370 if (hasTimestamp)
371 recvPacket >> movementInfo.time;
372
373 recvPacket >> movementInfo.pos.m_positionX;
374 recvPacket.ReadByteSeq(movementTransportGuid[5]);
375 recvPacket.ReadByteSeq(movementTransportGuid[0]);
376
377 if (hasPitch)
378 movementInfo.pitch = G3D::wrap(recvPacket.read<float>(), float(-M_PI), float(M_PI));
379
380 recvPacket.ReadByteSeq(movementTransportGuid[4]);
381 }
382
383 if (hasDestLocation)
384 {
385 float x, y, z;
386
387 recvPacket.ReadByteSeq(request.destTransportGuid[7]);
388 recvPacket >> x;
389 recvPacket.ReadByteSeq(request.destTransportGuid[0]);
390 recvPacket.ReadByteSeq(request.destTransportGuid[6]);
391 recvPacket.ReadByteSeq(request.destTransportGuid[1]);
392 recvPacket.ReadByteSeq(request.destTransportGuid[3]);
393 recvPacket >> y;
394 recvPacket.ReadByteSeq(request.destTransportGuid[5]);
395 recvPacket >> z;
396 recvPacket.ReadByteSeq(request.destTransportGuid[4]);
397 recvPacket.ReadByteSeq(request.destTransportGuid[2]);
398
399 request.destPos.Relocate(x, y, z);
400 }
401 else
402 {
403 request.destTransportGuid = caster->GetTransGUID();
404
405 if (request.destTransportGuid)
406 request.destPos.Relocate(caster->GetTransOffsetX(), caster->GetTransOffsetY(), caster->GetTransOffsetZ(), caster->GetTransOffsetO());
407 else
408 request.destPos.Relocate(caster);
409 }
410
411 recvPacket.ReadByteSeq(request.itemTargetGuid[6]);
412 recvPacket.ReadByteSeq(request.itemTargetGuid[7]);
413 recvPacket.ReadByteSeq(request.itemTargetGuid[2]);
414 recvPacket.ReadByteSeq(request.itemTargetGuid[0]);
415 recvPacket.ReadByteSeq(request.itemTargetGuid[3]);
416 recvPacket.ReadByteSeq(request.itemTargetGuid[4]);
417 recvPacket.ReadByteSeq(request.itemTargetGuid[1]);
418 recvPacket.ReadByteSeq(request.itemTargetGuid[5]);
419
420 if (hasSrcLocation)
421 {
422 float x, y, z;
423
424 recvPacket.ReadByteSeq(request.srcTransportGuid[7]);
425 recvPacket >> x;
426 recvPacket.ReadByteSeq(request.srcTransportGuid[1]);
427 recvPacket.ReadByteSeq(request.srcTransportGuid[5]);
428 recvPacket.ReadByteSeq(request.srcTransportGuid[4]);
429 recvPacket >> z;
430 recvPacket.ReadByteSeq(request.srcTransportGuid[6]);
431 recvPacket.ReadByteSeq(request.srcTransportGuid[0]);
432 recvPacket.ReadByteSeq(request.srcTransportGuid[3]);
433 recvPacket >> y;
434 recvPacket.ReadByteSeq(request.srcTransportGuid[2]);
435
436 request.srcPos.Relocate(x, y, z);
437 }
438 else
439 {
440 request.srcTransportGuid = caster->GetTransGUID();
441 if (request.srcTransportGuid)
442 request.srcPos.Relocate(caster->GetTransOffsetX(), caster->GetTransOffsetY(), caster->GetTransOffsetZ(), caster->GetTransOffsetO());
443 else
444 request.srcPos.Relocate(caster);
445 }
446
447 if (hasSpellId)
448 recvPacket >> request.spellId;
449
450 recvPacket.ReadByteSeq(request.targetGuid[1]);
451 recvPacket.ReadByteSeq(request.targetGuid[4]);
452 recvPacket.ReadByteSeq(request.targetGuid[3]);
453 recvPacket.ReadByteSeq(request.targetGuid[6]);
454 recvPacket.ReadByteSeq(request.targetGuid[2]);
455 recvPacket.ReadByteSeq(request.targetGuid[0]);
456 recvPacket.ReadByteSeq(request.targetGuid[7]);
457 recvPacket.ReadByteSeq(request.targetGuid[5]);
458
459 if (hasTargetString)
460 request.targetString = recvPacket.ReadString(targetStringLength);
461
462 if (hasElevation)
463 recvPacket >> request.elevation;
464
465 if (hasGlyphIndex)
466 recvPacket >> request.glyphIndex;
467
468 if (hasMissileSpeed)
469 recvPacket >> request.missileSpeed;
470
471 if (hasCastCount)
472 recvPacket >> request.castCount;
473
474 return request;
475}
476
477OpenItemRequest ReadOpenItemRequest(WorldPacket& recvPacket)
478{
479 OpenItemRequest request = OpenItemRequest();
480 recvPacket >> request.bagIndex >> request.slot;
481 return request;
482}
483
484GuidRequest ReadGameObjectUseRequest(WorldPacket& recvData)
485{
486 GuidRequest request = GuidRequest();
487
488 request.guid[6] = recvData.ReadBit();
489 request.guid[1] = recvData.ReadBit();
490 request.guid[3] = recvData.ReadBit();
491 request.guid[4] = recvData.ReadBit();
492 request.guid[0] = recvData.ReadBit();
493 request.guid[5] = recvData.ReadBit();
494 request.guid[7] = recvData.ReadBit();
495 request.guid[2] = recvData.ReadBit();
496
497 recvData.ReadByteSeq(request.guid[0]);
498 recvData.ReadByteSeq(request.guid[1]);
499 recvData.ReadByteSeq(request.guid[6]);
500 recvData.ReadByteSeq(request.guid[2]);
501 recvData.ReadByteSeq(request.guid[3]);
502 recvData.ReadByteSeq(request.guid[4]);
503 recvData.ReadByteSeq(request.guid[5]);
504 recvData.ReadByteSeq(request.guid[7]);
505
506 return request;
507}
508
509GuidRequest ReadGameObjectReportUseRequest(WorldPacket& recvPacket)
510{
511 GuidRequest request = GuidRequest();
512
513 request.guid[4] = recvPacket.ReadBit();
514 request.guid[7] = recvPacket.ReadBit();
515 request.guid[5] = recvPacket.ReadBit();
516 request.guid[3] = recvPacket.ReadBit();
517 request.guid[6] = recvPacket.ReadBit();
518 request.guid[1] = recvPacket.ReadBit();
519 request.guid[2] = recvPacket.ReadBit();
520 request.guid[0] = recvPacket.ReadBit();
521
522 recvPacket.ReadByteSeq(request.guid[7]);
523 recvPacket.ReadByteSeq(request.guid[1]);
524 recvPacket.ReadByteSeq(request.guid[6]);
525 recvPacket.ReadByteSeq(request.guid[5]);
526 recvPacket.ReadByteSeq(request.guid[0]);
527 recvPacket.ReadByteSeq(request.guid[3]);
528 recvPacket.ReadByteSeq(request.guid[2]);
529 recvPacket.ReadByteSeq(request.guid[4]);
530
531 return request;
532}
533
534CastSpellRequest ReadCastSpellRequest(WorldPacket& recvPacket, Unit* caster)
535{
536 CastSpellRequest request = CastSpellRequest();
537 request.hasResearchData = false;
538 memset(&request.researchData, 0, sizeof(SpellResearchData));
539 uint32 targetStringLength = 0;
540 uint8 researchTypes[4] = { 0, 0, 0, 0 };
541
542 // Movement data
543 MovementInfo movementInfo;
544 ObjectGuid movementTransportGuid = 0;
545 ObjectGuid movementGuid = 0;
546 bool hasTransport = false;
547 bool hasTransportTime2 = false;
548 bool hasTransportTime3 = false;
549 bool hasFallData = false;
550 bool hasFallDirection = false;
551 bool hasTimestamp = false;
552 bool hasSplineElevation = false;
553 bool hasPitch = false;
554 bool hasOrientation = false;
555 bool hasUnkMovementField = false;
556 uint32 unkMovementLoopCounter = 0;
557
558 recvPacket.ReadBit(); // Fake bit
559 bool hasTargetString = !recvPacket.ReadBit();
560 recvPacket.ReadBit(); // Fake Bit
561 bool hasCastCount = !recvPacket.ReadBit();
562 bool hasSrcLocation = recvPacket.ReadBit();
563 bool hasDestLocation = recvPacket.ReadBit();
564 bool hasSpellId = !recvPacket.ReadBit();
565 uint8 researchDataCount = recvPacket.ReadBits(2);
566 bool hasTargetMask = !recvPacket.ReadBit();
567 bool hasMissileSpeed = !recvPacket.ReadBit();
568
569 for (uint8 i = 0; i < researchDataCount; ++i)
570 researchTypes[i] = recvPacket.ReadBits(2);
571
572 bool hasGlyphIndex = !recvPacket.ReadBit();
573 bool hasMovement = recvPacket.ReadBit();
574 bool hasElevation = !recvPacket.ReadBit();
575 bool hasCastFlags = !recvPacket.ReadBit();
576
577 request.targetGuid[5] = recvPacket.ReadBit();
578 request.targetGuid[4] = recvPacket.ReadBit();
579 request.targetGuid[2] = recvPacket.ReadBit();
580 request.targetGuid[7] = recvPacket.ReadBit();
581 request.targetGuid[1] = recvPacket.ReadBit();
582 request.targetGuid[6] = recvPacket.ReadBit();
583 request.targetGuid[3] = recvPacket.ReadBit();
584 request.targetGuid[0] = recvPacket.ReadBit();
585
586 if (hasDestLocation)
587 {
588 request.destTransportGuid[1] = recvPacket.ReadBit();
589 request.destTransportGuid[3] = recvPacket.ReadBit();
590 request.destTransportGuid[5] = recvPacket.ReadBit();
591 request.destTransportGuid[0] = recvPacket.ReadBit();
592 request.destTransportGuid[2] = recvPacket.ReadBit();
593 request.destTransportGuid[6] = recvPacket.ReadBit();
594 request.destTransportGuid[7] = recvPacket.ReadBit();
595 request.destTransportGuid[4] = recvPacket.ReadBit();
596 }
597
598
599 if (hasMovement)
600 {
601 unkMovementLoopCounter = recvPacket.ReadBits(22);
602 recvPacket.ReadBit();
603 movementGuid[4] = recvPacket.ReadBit();
604 hasTransport = recvPacket.ReadBit();
605
606 if (hasTransport)
607 {
608 hasTransportTime2 = recvPacket.ReadBit();
609 movementTransportGuid[7] = recvPacket.ReadBit();
610 movementTransportGuid[4] = recvPacket.ReadBit();
611 movementTransportGuid[1] = recvPacket.ReadBit();
612 movementTransportGuid[0] = recvPacket.ReadBit();
613 movementTransportGuid[6] = recvPacket.ReadBit();
614 movementTransportGuid[3] = recvPacket.ReadBit();
615 movementTransportGuid[5] = recvPacket.ReadBit();
616 hasTransportTime3 = recvPacket.ReadBit();
617 movementTransportGuid[2] = recvPacket.ReadBit();
618 }
619
620 recvPacket.ReadBit();
621 movementGuid[7] = recvPacket.ReadBit();
622 hasOrientation = !recvPacket.ReadBit();
623 movementGuid[6] = recvPacket.ReadBit();
624 hasSplineElevation = !recvPacket.ReadBit();
625 hasPitch = !recvPacket.ReadBit();
626 movementGuid[0] = recvPacket.ReadBit();
627 recvPacket.ReadBit();
628 bool hasMovementFlags = !recvPacket.ReadBit();
629 hasTimestamp = !recvPacket.ReadBit();
630 hasUnkMovementField = !recvPacket.ReadBit();
631
632 if (hasMovementFlags)
633 movementInfo.flags = recvPacket.ReadBits(30);
634
635 movementGuid[1] = recvPacket.ReadBit();
636 movementGuid[3] = recvPacket.ReadBit();
637 movementGuid[2] = recvPacket.ReadBit();
638 movementGuid[5] = recvPacket.ReadBit();
639 hasFallData = recvPacket.ReadBit();
640
641 if (hasFallData)
642 hasFallDirection = recvPacket.ReadBit();
643
644 bool hasMovementFlags2 = !recvPacket.ReadBit();
645
646 if (hasMovementFlags2)
647 movementInfo.flags2 = recvPacket.ReadBits(13);
648 }
649
650 request.itemTargetGuid[1] = recvPacket.ReadBit();
651 request.itemTargetGuid[0] = recvPacket.ReadBit();
652 request.itemTargetGuid[7] = recvPacket.ReadBit();
653 request.itemTargetGuid[4] = recvPacket.ReadBit();
654 request.itemTargetGuid[6] = recvPacket.ReadBit();
655 request.itemTargetGuid[5] = recvPacket.ReadBit();
656 request.itemTargetGuid[3] = recvPacket.ReadBit();
657 request.itemTargetGuid[2] = recvPacket.ReadBit();
658
659 if (hasSrcLocation)
660 {
661 request.srcTransportGuid[4] = recvPacket.ReadBit();
662 request.srcTransportGuid[5] = recvPacket.ReadBit();
663 request.srcTransportGuid[3] = recvPacket.ReadBit();
664 request.srcTransportGuid[0] = recvPacket.ReadBit();
665 request.srcTransportGuid[7] = recvPacket.ReadBit();
666 request.srcTransportGuid[1] = recvPacket.ReadBit();
667 request.srcTransportGuid[6] = recvPacket.ReadBit();
668 request.srcTransportGuid[2] = recvPacket.ReadBit();
669 }
670
671 if (hasTargetMask)
672 request.targetMask = recvPacket.ReadBits(20);
673
674 if (hasCastFlags)
675 request.castFlags = recvPacket.ReadBits(5);
676
677 if (hasTargetString)
678 targetStringLength = recvPacket.ReadBits(7);
679
680 for (uint8 i = 0; i < researchDataCount; ++i)
681 {
682 // Client sends (usedCount, entryId); type 1 = keystone item, type 2 = fragment currency.
683 uint32 usedCount = 0;
684 uint32 entry = 0;
685 recvPacket >> usedCount;
686 recvPacket >> entry;
687
688 switch (researchTypes[i])
689 {
690 case 1: // Keystones
691 request.researchData.keystoneItemId = entry;
692 request.researchData.keystoneCount = usedCount;
693 request.hasResearchData = true;
694 break;
695 case 2: // Fragments
696 request.researchData.fragmentCurrencyId = entry;
697 request.researchData.fragmentCount = usedCount;
698 request.hasResearchData = true;
699 break;
700 default:
701 break;
702 }
703 }
704
705 if (hasMovement)
706 {
707 recvPacket >> movementInfo.pos.m_positionX;
708 recvPacket.ReadByteSeq(movementGuid[0]);
709
710 if (hasTransport)
711 {
712 recvPacket.ReadByteSeq(movementTransportGuid[2]);
713 recvPacket >> movementInfo.transport.seat;
714 recvPacket.ReadByteSeq(movementTransportGuid[3]);
715 recvPacket.ReadByteSeq(movementTransportGuid[7]);
716 recvPacket >> movementInfo.transport.pos.m_positionX;
717 recvPacket.ReadByteSeq(movementTransportGuid[5]);
718
719 if (hasTransportTime3)
720 recvPacket >> movementInfo.transport.time3;
721
722 recvPacket >> movementInfo.transport.pos.m_positionZ;
723 recvPacket >> movementInfo.transport.pos.m_positionY;
724
725 recvPacket.ReadByteSeq(movementTransportGuid[6]);
726 recvPacket.ReadByteSeq(movementTransportGuid[1]);
727 movementInfo.transport.pos.SetOrientation(recvPacket.read<float>());
728
729 recvPacket.ReadByteSeq(movementTransportGuid[4]);
730
731 if (hasTransportTime2)
732 recvPacket >> movementInfo.transport.time2;
733
734 recvPacket.ReadByteSeq(movementTransportGuid[0]);
735 recvPacket >> movementInfo.transport.time;
736 }
737
738 recvPacket.ReadByteSeq(movementGuid[5]);
739
740 if (hasFallData)
741 {
742 recvPacket >> movementInfo.jump.fallTime;
743 recvPacket >> movementInfo.jump.zspeed;
744
745 if (hasFallDirection)
746 {
747 recvPacket >> movementInfo.jump.sinAngle;
748 recvPacket >> movementInfo.jump.xyspeed;
749 recvPacket >> movementInfo.jump.cosAngle;
750 }
751 }
752
753 if (hasSplineElevation)
754 recvPacket >> movementInfo.splineElevation;
755
756 recvPacket.ReadByteSeq(movementGuid[6]);
757
758 if (hasUnkMovementField)
759 recvPacket.read_skip<uint32>();
760
761 recvPacket.ReadByteSeq(movementGuid[4]);
762
763 if (hasOrientation)
764 movementInfo.pos.SetOrientation(recvPacket.read<float>());
765
766 if (hasTimestamp)
767 recvPacket >> movementInfo.time;
768
769 recvPacket.ReadByteSeq(movementGuid[1]);
770
771 if (hasPitch)
772 movementInfo.pitch = G3D::wrap(recvPacket.read<float>(), float(-M_PI), float(M_PI));
773
774 recvPacket.ReadByteSeq(movementGuid[3]);
775
776 for (uint8 i = 0; i != unkMovementLoopCounter; i++)
777 recvPacket.read_skip<uint32>();
778
779 recvPacket >> movementInfo.pos.m_positionY;
780 recvPacket.ReadByteSeq(movementGuid[7]);
781 recvPacket >> movementInfo.pos.m_positionZ;
782 recvPacket.ReadByteSeq(movementGuid[2]);
783 }
784
785 recvPacket.ReadByteSeq(request.itemTargetGuid[4]);
786 recvPacket.ReadByteSeq(request.itemTargetGuid[2]);
787 recvPacket.ReadByteSeq(request.itemTargetGuid[1]);
788 recvPacket.ReadByteSeq(request.itemTargetGuid[5]);
789 recvPacket.ReadByteSeq(request.itemTargetGuid[7]);
790 recvPacket.ReadByteSeq(request.itemTargetGuid[3]);
791 recvPacket.ReadByteSeq(request.itemTargetGuid[6]);
792 recvPacket.ReadByteSeq(request.itemTargetGuid[0]);
793
794 if (hasDestLocation)
795 {
796 float x, y, z;
797 recvPacket.ReadByteSeq(request.destTransportGuid[2]);
798 recvPacket >> x;
799 recvPacket.ReadByteSeq(request.destTransportGuid[4]);
800 recvPacket.ReadByteSeq(request.destTransportGuid[1]);
801 recvPacket.ReadByteSeq(request.destTransportGuid[0]);
802 recvPacket.ReadByteSeq(request.destTransportGuid[3]);
803 recvPacket >> y;
804 recvPacket.ReadByteSeq(request.destTransportGuid[7]);
805 recvPacket >> z;
806 recvPacket.ReadByteSeq(request.destTransportGuid[5]);
807 recvPacket.ReadByteSeq(request.destTransportGuid[6]);
808 request.destPos.Relocate(x, y, z);
809 }
810 else
811 {
812 request.destTransportGuid = caster->GetTransGUID();
813 if (request.destTransportGuid)
814 request.destPos.Relocate(caster->GetTransOffsetX(), caster->GetTransOffsetY(), caster->GetTransOffsetZ(), caster->GetTransOffsetO());
815 else
816 request.destPos.Relocate(caster);
817 }
818
819 recvPacket.ReadByteSeq(request.targetGuid[3]);
820 recvPacket.ReadByteSeq(request.targetGuid[4]);
821 recvPacket.ReadByteSeq(request.targetGuid[7]);
822 recvPacket.ReadByteSeq(request.targetGuid[6]);
823 recvPacket.ReadByteSeq(request.targetGuid[2]);
824 recvPacket.ReadByteSeq(request.targetGuid[0]);
825 recvPacket.ReadByteSeq(request.targetGuid[1]);
826 recvPacket.ReadByteSeq(request.targetGuid[5]);
827
828 if (hasSrcLocation)
829 {
830 float x, y, z;
831 recvPacket >> y;
832 recvPacket.ReadByteSeq(request.srcTransportGuid[5]);
833 recvPacket.ReadByteSeq(request.srcTransportGuid[1]);
834 recvPacket.ReadByteSeq(request.srcTransportGuid[7]);
835 recvPacket.ReadByteSeq(request.srcTransportGuid[6]);
836 recvPacket >> x;
837 recvPacket.ReadByteSeq(request.srcTransportGuid[3]);
838 recvPacket.ReadByteSeq(request.srcTransportGuid[2]);
839 recvPacket.ReadByteSeq(request.srcTransportGuid[0]);
840 recvPacket.ReadByteSeq(request.srcTransportGuid[4]);
841 recvPacket >> z;
842 request.srcPos.Relocate(x, y, z);
843 }
844 else
845 {
846 request.srcTransportGuid = caster->GetTransGUID();
847 if (request.srcTransportGuid)
848 request.srcPos.Relocate(caster->GetTransOffsetX(), caster->GetTransOffsetY(), caster->GetTransOffsetZ(), caster->GetTransOffsetO());
849 else
850 request.srcPos.Relocate(caster);
851 }
852
853 if (hasTargetString)
854 request.targetString = recvPacket.ReadString(targetStringLength);
855
856 if (hasMissileSpeed)
857 recvPacket >> request.missileSpeed;
858
859 if (hasElevation)
860 recvPacket >> request.elevation;
861
862 if (hasCastCount)
863 recvPacket >> request.castCount;
864
865 if (hasSpellId)
866 recvPacket >> request.spellId;
867
868 if (hasGlyphIndex)
869 recvPacket >> request.glyphIndex;
870
871 return request;
872}
873
874CancelCastRequest ReadCancelCastRequest(WorldPacket& recvPacket)
875{
876 CancelCastRequest request = CancelCastRequest();
877
878 bool hasCounter = !recvPacket.ReadBit();
879 bool hasSpellId = !recvPacket.ReadBit();
880
881 recvPacket.FlushBits();
882
883 if (hasSpellId)
884 recvPacket >> request.spellId;
885
886 if (hasCounter)
887 recvPacket >> request.counter;
888
889 return request;
890}
891
892CancelAuraRequest ReadCancelAuraRequest(WorldPacket& recvPacket)
893{
894 CancelAuraRequest request = CancelAuraRequest();
895
896 recvPacket >> request.spellId;
897
898 recvPacket.ReadBit(); // Fake Bit
899 request.guid[6] = recvPacket.ReadBit();
900 request.guid[5] = recvPacket.ReadBit();
901 request.guid[1] = recvPacket.ReadBit();
902 request.guid[0] = recvPacket.ReadBit();
903 request.guid[4] = recvPacket.ReadBit();
904 request.guid[3] = recvPacket.ReadBit();
905 request.guid[2] = recvPacket.ReadBit();
906 request.guid[7] = recvPacket.ReadBit();
907
908 recvPacket.FlushBits();
909
910 recvPacket.ReadByteSeq(request.guid[3]);
911 recvPacket.ReadByteSeq(request.guid[2]);
912 recvPacket.ReadByteSeq(request.guid[1]);
913 recvPacket.ReadByteSeq(request.guid[0]);
914 recvPacket.ReadByteSeq(request.guid[4]);
915 recvPacket.ReadByteSeq(request.guid[7]);
916 recvPacket.ReadByteSeq(request.guid[5]);
917 recvPacket.ReadByteSeq(request.guid[6]);
918
919 return request;
920}
921
922PetCancelAuraRequest ReadPetCancelAuraRequest(WorldPacket& recvPacket)
923{
924 PetCancelAuraRequest request = PetCancelAuraRequest();
925
926 request.spellId = recvPacket.read<uint32>();
927 recvPacket.ReadGuidMask(request.guid, 0, 3, 1, 4, 6, 2, 7, 5);
928 recvPacket.ReadGuidBytes(request.guid, 0, 5, 3, 4, 7, 2, 6, 1);
929
930 return request;
931}
932
933void ReadCancelChannelingRequest(WorldPacket& recvData)
934{
935 recvData.read_skip<uint32>(); // spellid, not used
936}
937
938TotemDestroyedRequest ReadTotemDestroyedRequest(WorldPacket& recvPacket)
939{
940 TotemDestroyedRequest request = TotemDestroyedRequest();
941
942 recvPacket >> request.slotId;
943
944 request.guid[4] = recvPacket.ReadBit();
945 request.guid[2] = recvPacket.ReadBit();
946 request.guid[1] = recvPacket.ReadBit();
947 request.guid[3] = recvPacket.ReadBit();
948 request.guid[0] = recvPacket.ReadBit();
949 request.guid[6] = recvPacket.ReadBit();
950 request.guid[7] = recvPacket.ReadBit();
951 request.guid[5] = recvPacket.ReadBit();
952
953 recvPacket.ReadByteSeq(request.guid[6]);
954 recvPacket.ReadByteSeq(request.guid[2]);
955 recvPacket.ReadByteSeq(request.guid[4]);
956 recvPacket.ReadByteSeq(request.guid[1]);
957 recvPacket.ReadByteSeq(request.guid[5]);
958 recvPacket.ReadByteSeq(request.guid[0]);
959 recvPacket.ReadByteSeq(request.guid[3]);
960 recvPacket.ReadByteSeq(request.guid[7]);
961
962 return request;
963}
964
965SpellClickRequest ReadSpellClickRequest(WorldPacket& recvData)
966{
967 SpellClickRequest request = SpellClickRequest();
968
969 recvData.ReadGuidMask(request.guid, 7, 4, 0, 3, 6, 5);
970 request.tryAutoDismount = recvData.ReadBit();
971 recvData.ReadGuidMask(request.guid, 1, 2);
972 recvData.ReadGuidBytes(request.guid, 6, 1, 5, 4, 7, 2, 3, 0);
973
974 return request;
975}
976
977GuidRequest ReadMirrorImageDataRequest(WorldPacket& recvData)
978{
979 GuidRequest request = GuidRequest();
980
981 recvData.read_skip<uint32>(); // DisplayId
982
983 request.guid[0] = recvData.ReadBit();
984 request.guid[2] = recvData.ReadBit();
985 request.guid[1] = recvData.ReadBit();
986 request.guid[6] = recvData.ReadBit();
987 request.guid[5] = recvData.ReadBit();
988 request.guid[4] = recvData.ReadBit();
989 request.guid[7] = recvData.ReadBit();
990 request.guid[3] = recvData.ReadBit();
991
992 recvData.ReadByteSeq(request.guid[6]);
993 recvData.ReadByteSeq(request.guid[0]);
994 recvData.ReadByteSeq(request.guid[3]);
995 recvData.ReadByteSeq(request.guid[5]);
996 recvData.ReadByteSeq(request.guid[4]);
997 recvData.ReadByteSeq(request.guid[2]);
998 recvData.ReadByteSeq(request.guid[1]);
999 recvData.ReadByteSeq(request.guid[7]);
1000
1001 return request;
1002}
1003
1004ProjectilePositionRequest ReadUpdateProjectilePositionRequest(WorldPacket& recvPacket)
1005{
1006 ProjectilePositionRequest request = ProjectilePositionRequest();
1007
1008 recvPacket >> request.casterGuid;
1009 recvPacket >> request.spellId;
1010 recvPacket >> request.castCount;
1011 recvPacket >> request.x;
1012 recvPacket >> request.y;
1013 recvPacket >> request.z;
1014
1015 return request;
1016}
1017
1018bool CanProcessUseItemRequest(Player* player, Unit* mover)
1019{
1020 return mover == player;
1021}
1022
1023bool ValidateUseItemSelection(Player* player, UseItemRequest& request, Item*& item)
1024{
1025 item = NULL;
1026
1027 if (request.glyphIndex >= MAX_GLYPH_SLOT_INDEX)
1028 {
1029 player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL);
1030 return false;
1031 }
1032
1033 item = player->GetUseableItemByPos(request.bagIndex, request.slot);
1034 if (!item)
1035 {
1036 player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL);
1037 return false;
1038 }
1039
1040 if (item->GetGUID() != request.itemGuid)
1041 {
1042 player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL);
1043 return false;
1044 }
1045
1046 return true;
1047}
1048
1049bool ValidateUseItemCombat(Player* player, Item* item, ItemTemplate const* proto)
1050{
1051 if (!player->IsInCombat())
1052 return true;
1053
1054 for (int i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i)
1055 {
1056 if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(proto->Spells[i].SpellId))
1057 {
1058 if (!spellInfo->CanBeUsedInCombat())
1059 {
1060 player->SendEquipError(EQUIP_ERR_NOT_IN_COMBAT, item, NULL);
1061 return false;
1062 }
1063 }
1064 }
1065
1066 return true;
1067}
1068
1069bool ValidateUseItemTemplate(Player* player, Item* item, ItemTemplate const*& proto)
1070{
1071 proto = item->GetTemplate();
1072 if (!proto)
1073 {
1074 player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, item, NULL);
1075 return false;
1076 }
1077
1078 // some item classes can be used only in equipped state
1079 if (proto->InventoryType != INVTYPE_NON_EQUIP && !item->IsEquipped())
1080 {
1081 player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, item, NULL);
1082 return false;
1083 }
1084
1085 InventoryResult msg = player->CanUseItem(item);
1086 if (msg != EQUIP_ERR_OK)
1087 {
1088 player->SendEquipError(msg, item, NULL);
1089 return false;
1090 }
1091
1092 // only allow conjured consumable, bandage, poisons (all should have the 2^21 item flag set in DB)
1093 if (proto->Class == ITEM_CLASS_CONSUMABLE && !(proto->Flags & ITEM_PROTO_FLAG_USEABLE_IN_ARENA) && player->InArena())
1094 {
1096 return false;
1097 }
1098
1099 // don't allow items banned in arena
1100 if (proto->Flags & ITEM_PROTO_FLAG_NOT_USEABLE_IN_ARENA && player->InArena())
1101 {
1103 return false;
1104 }
1105
1106 return ValidateUseItemCombat(player, item, proto);
1107}
1108
1109bool CanProcessCastSpellRequest(WorldPacket& recvPacket, Player* player, Unit* mover)
1110{
1111 if (mover != player && mover->GetTypeId() == TypeID::TYPEID_PLAYER)
1112 {
1113 recvPacket.rfinish(); // prevent spam at ignore packet
1114 return false;
1115 }
1116
1117 return true;
1118}
1119
1120SpellInfo const* ValidateCastSpellInfo(WorldPacket& recvPacket, uint32 spellId)
1121{
1122 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
1123 if (!spellInfo)
1124 {
1125 SF_LOG_ERROR("network", "WORLD: unknown spell id %u", spellId);
1126 recvPacket.rfinish(); // prevent spam at ignore packet
1127 return NULL;
1128 }
1129
1130 if (spellInfo->IsPassive())
1131 {
1132 recvPacket.rfinish(); // prevent spam at ignore packet
1133 return NULL;
1134 }
1135
1136 return spellInfo;
1137}
1138
1139bool ValidateCastSource(WorldPacket& recvPacket, Player* player, Unit*& caster, SpellInfo const* spellInfo, uint32 spellId)
1140{
1141 if (caster->GetTypeId() == TypeID::TYPEID_UNIT && !caster->ToCreature()->HasSpell(spellId))
1142 {
1143 // If the vehicle creature does not have the spell but it allows the passenger to cast own spells
1144 // change caster to player and let him cast
1145 if (!player->IsOnVehicle(caster) || spellInfo->CheckVehicle(player) != SpellCastResult::SPELL_CAST_OK)
1146 {
1147 recvPacket.rfinish(); // prevent spam at ignore packet
1148 return false;
1149 }
1150
1151 caster = player;
1152 }
1153
1154 if (caster->GetTypeId() == TypeID::TYPEID_PLAYER && !caster->ToPlayer()->HasActiveSpell(spellId))
1155 {
1156 // Archaeology solves are cast from the journal UI, not the spellbook.
1157 Player* casterPlayer = caster->ToPlayer();
1158 if (!spellInfo->ResearchProject || !casterPlayer->HasResearchingProject(spellInfo->ResearchProject))
1159 {
1160 recvPacket.rfinish(); // prevent spam at ignore packet
1161 return false;
1162 }
1163 }
1164
1165 return true;
1166}
1167
1168bool ValidateCastExecution(WorldPacket& recvPacket, Player* player, Unit* caster, SpellInfo const* spellInfo)
1169{
1170 // Client is resending autoshot cast opcode when other spell is casted during shoot rotation.
1171 // Skip it to prevent "interrupt" message.
1173 && caster->GetCurrentSpell(CURRENT_AUTOREPEAT_SPELL)->m_spellInfo == spellInfo)
1174 {
1175 recvPacket.rfinish();
1176 return false;
1177 }
1178
1179 // can't use our own spells when we're in possession of another unit,
1180 if (player->isPossessing())
1181 {
1182 recvPacket.rfinish(); // prevent spam at ignore packet
1183 return false;
1184 }
1185
1186 return true;
1187}
1188
1189SpellInfo const* ValidateCancelAuraSpell(CancelAuraRequest const& request)
1190{
1191 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(request.spellId);
1192 if (!spellInfo)
1193 return NULL;
1194
1195 // not allow remove spells with attr SPELL_ATTR0_CANT_CANCEL
1196 if (spellInfo->Attributes & SPELL_ATTR0_CANT_CANCEL)
1197 return NULL;
1198
1199 return spellInfo;
1200}
1201
1202bool TryInterruptMatchingChannel(Player* player, SpellInfo const* spellInfo, uint32 spellId)
1203{
1204 if (!spellInfo->IsChanneled())
1205 return false;
1206
1207 if (Spell* curSpell = player->GetCurrentSpell(CURRENT_CHANNELED_SPELL))
1208 if (curSpell->m_spellInfo->Id == spellId)
1210
1211 return true;
1212}
1213
1214bool IsPlayerCancelableAura(SpellInfo const* spellInfo)
1215{
1216 // don't allow remove non positive spells
1217 // don't allow cancelling passive auras (some of them are visible)
1218 return spellInfo->IsPositive() && !spellInfo->IsPassive();
1219}
1220
1221Creature* ValidatePetCancelAuraRequest(Player* player, PetCancelAuraRequest& request)
1222{
1223 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(request.spellId);
1224 if (!spellInfo)
1225 {
1226 SF_LOG_ERROR("network", "WORLD: unknown PET spell id %u", request.spellId);
1227 return NULL;
1228 }
1229
1230 Creature* pet = ObjectAccessor::GetCreatureOrPetOrVehicle(*player, request.guid);
1231
1232 if (!pet)
1233 {
1234 SF_LOG_ERROR("network", "HandlePetCancelAura: Attempt to cancel an aura for non-existant pet %u by player '%s'", uint32(GUID_LOPART(request.guid)), player->GetName().c_str());
1235 return NULL;
1236 }
1237
1238 if (pet != player->GetGuardianPet() && pet != player->GetCharm())
1239 {
1240 SF_LOG_ERROR("network", "HandlePetCancelAura: Pet %u is not a pet of player '%s'", uint32(GUID_LOPART(request.guid)), player->GetName().c_str());
1241 return NULL;
1242 }
1243
1244 if (!pet->IsAlive())
1245 {
1247 return NULL;
1248 }
1249
1250 return pet;
1251}
1252}
1253
1255{
1256 // some spell cast packet including more data (for projectiles?)
1257 if (castFlags & 0x02)
1258 {
1259 // not sure about these two
1260 float elevation, speed;
1261 recvPacket >> elevation;
1262 recvPacket >> speed;
1263
1264 targets.SetElevation(elevation);
1265 targets.SetSpeed(speed);
1266
1267 uint8 hasMovementData;
1268 recvPacket >> hasMovementData;
1269 if (hasMovementData)
1270 HandleMovementOpcodes(recvPacket);
1271 }
1272 else if (castFlags & 0x8) // Archaeology
1273 {
1274 uint32 count, entry, usedCount;
1275 uint8 type;
1276 recvPacket >> count;
1277 for (uint32 i = 0; i < count; ++i)
1278 {
1279 recvPacket >> type;
1280 switch (type)
1281 {
1282 case 2: // Keystones
1283 recvPacket >> entry; // Item id
1284 recvPacket >> usedCount; // Item count
1285 break;
1286 case 1: // Fragments
1287 recvPacket >> entry; // Currency id
1288 recvPacket >> usedCount; // Currency count
1289 break;
1290 }
1291 }
1292 }
1293}
1294
1296{
1298 Player* pUser = _player;
1299 Unit* mover = _player->m_mover;
1300
1301 // ignore for remote control state
1302 if (!CanProcessUseItemRequest(pUser, mover))
1303 return;
1304
1305 UseItemRequest request = ReadUseItemRequest(recvPacket, mover);
1306 Unit* caster = mover;
1307
1308 Item* pItem = NULL;
1309 if (!ValidateUseItemSelection(pUser, request, pItem))
1310 return;
1311
1312 SF_LOG_DEBUG("network", "WORLD: CMSG_USE_ITEM packet, bagIndex: %u, slot: %u, castCount: %u, spellId: %u, Item: %u, glyphIndex: %u, data length = %i", request.bagIndex, request.slot, request.castCount, request.spellId, pItem->GetEntry(), request.glyphIndex, (uint32)recvPacket.size());
1313
1314 ItemTemplate const* proto = NULL;
1315 if (!ValidateUseItemTemplate(pUser, pItem, proto))
1316 return;
1317
1318 // check also BIND_WHEN_PICKED_UP and BIND_QUEST_ITEM for .additem or .additemset case by GM (not binded at adding to inventory)
1319 if (proto->Bonding == BIND_WHEN_USE || proto->Bonding == BIND_WHEN_PICKED_UP || proto->Bonding == BIND_QUEST_ITEM)
1320 {
1321 if (!pItem->IsSoulBound())
1322 {
1323 pItem->SetState(ITEM_CHANGED, pUser);
1324 pItem->SetBinding(true);
1325 }
1326 }
1327
1328 SpellCastTargets targets(caster, request.targetMask, request.targetGuid, request.itemTargetGuid, request.srcTransportGuid, request.destTransportGuid, request.srcPos, request.destPos, request.elevation, request.missileSpeed, request.targetString);
1329
1330 // Note: If script stop casting it must send appropriate data to client to prevent stuck item in gray state.
1331 if (!sScriptMgr->OnItemUse(pUser, pItem, targets))
1332 {
1333 // no script or script not process request by self
1334 pUser->CastItemUseSpell(pItem, targets, request.castCount, request.glyphIndex,
1335 request.hasResearchData ? &request.researchData : NULL);
1336 }
1337}
1338
1340{
1341 SF_LOG_DEBUG("network", "WORLD: CMSG_OPEN_ITEM packet, data length = %i", (uint32)recvPacket.size());
1342
1343 Player* pUser = _player;
1344
1345 // ignore for remote control state
1346 if (pUser->m_mover != pUser)
1347 return;
1348
1349 OpenItemRequest request = ReadOpenItemRequest(recvPacket);
1350
1351 SF_LOG_INFO("network", "bagIndex: %u, slot: %u", request.bagIndex, request.slot);
1352
1353 Item* item = pUser->GetItemByPos(request.bagIndex, request.slot);
1354 if (!item)
1355 {
1356 pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL);
1357 return;
1358 }
1359
1360 ItemTemplate const* proto = item->GetTemplate();
1361 if (!proto)
1362 {
1363 pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, item, NULL);
1364 return;
1365 }
1366
1367 // Verify that the bag is an actual bag or wrapped item that can be used "normally"
1369 {
1370 pUser->SendEquipError(EQUIP_ERR_CLIENT_LOCKED_OUT, item, NULL);
1371 SF_LOG_ERROR("network", "Possible hacking attempt: Player %s [guid: %u] tried to open item [guid: %u, entry: %u] which is not openable!",
1372 pUser->GetName().c_str(), pUser->GetGUIDLow(), item->GetGUIDLow(), proto->ItemId);
1373 return;
1374 }
1375
1376 // locked item
1377 uint32 lockId = proto->LockID;
1378 if (lockId)
1379 {
1380 LockEntry const* lockInfo = sLockStore.LookupEntry(lockId);
1381
1382 if (!lockInfo)
1383 {
1384 pUser->SendEquipError(EQUIP_ERR_ITEM_LOCKED, item, NULL);
1385 SF_LOG_ERROR("network", "WORLD::OpenItem: item [guid = %u] has an unknown lockId: %u!", item->GetGUIDLow(), lockId);
1386 return;
1387 }
1388
1389 // was not unlocked yet
1390 if (item->IsLocked())
1391 {
1392 pUser->SendEquipError(EQUIP_ERR_ITEM_LOCKED, item, NULL);
1393 return;
1394 }
1395 }
1396
1397 if (item->HasFlag(ITEM_FIELD_DYNAMIC_FLAGS, ITEM_FLAG_WRAPPED))// wrapped?
1398 {
1400
1401 stmt->setUInt32(0, item->GetGUIDLow());
1402
1403 PreparedQueryResult result = CharacterDatabase.Query(stmt);
1404
1405 if (result)
1406 {
1407 Field* fields = result->Fetch();
1408 uint32 entry = fields[0].GetUInt32();
1409 uint32 flags = fields[1].GetUInt32();
1410
1412 item->SetEntry(entry);
1414 item->SetState(ITEM_CHANGED, pUser);
1415 }
1416 else
1417 {
1418 SF_LOG_ERROR("network", "Wrapped item %u don't have record in character_gifts table and will deleted", item->GetGUIDLow());
1419 pUser->DestroyItem(item->GetBagSlot(), item->GetSlot(), true);
1420 return;
1421 }
1422
1423 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GIFT);
1424
1425 stmt->setUInt32(0, item->GetGUIDLow());
1426
1427 CharacterDatabase.Execute(stmt);
1428 }
1429 else
1430 pUser->SendLoot(item->GetGUID(), LootType::LOOT_CORPSE);
1431}
1432
1434{
1435 GuidRequest request = ReadGameObjectUseRequest(recvData);
1436 ObjectGuid guid = request.guid;
1437
1438 SF_LOG_DEBUG("network", "WORLD: Recvd CMSG_GAME_OBJ_REPORT_USE Message [guid=%u]", GUID_LOPART(guid));
1439
1440 if (GameObject* obj = GetPlayer()->GetMap()->GetGameObject(guid))
1441 {
1442 // ignore for remote control state
1443 if (_player->m_mover != _player)
1444 if (!(_player->IsOnVehicle(_player->m_mover) || _player->IsMounted()) && !obj->GetGOInfo()->IsUsableMounted())
1445 return;
1446
1447 obj->Use(_player);
1448 }
1449}
1450
1452{
1453 GuidRequest request = ReadGameObjectReportUseRequest(recvPacket);
1454 ObjectGuid guid = request.guid;
1455
1456 SF_LOG_DEBUG("network", "WORLD: Recvd CMSG_GAME_OBJ_USE Message [in game guid: %u]", GUID_LOPART(guid));
1457
1458 // ignore for remote control state
1459 if (_player->m_mover != _player)
1460 return;
1461
1462 GameObject* go = GetPlayer()->GetMap()->GetGameObject(guid);
1463 if (!go)
1464 return;
1465
1466 // we cannot use go with not selectable flags
1468 return;
1469
1471 return;
1472
1473 if (go->AI()->GossipHello(_player))
1474 return;
1475
1476 _player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_USE_GAMEOBJECT, go->GetEntry());
1477}
1478
1480{
1481 // ignore for remote control state (for player case)
1482 Unit* mover = _player->m_mover;
1483 if (!CanProcessCastSpellRequest(recvPacket, _player, mover))
1484 return;
1485
1486 CastSpellRequest request = ReadCastSpellRequest(recvPacket, mover);
1487 Unit* caster = mover;
1488 uint8 castCount = request.castCount;
1489 uint8 castFlags = request.castFlags;
1490 uint32 spellId = request.spellId;
1491 uint32 glyphIndex = request.glyphIndex;
1492
1493 SF_LOG_DEBUG("network", "WORLD: got cast spell packet, castCount: %u, spellId: %u, castFlags: %u, data length = %u", castCount, spellId, castFlags, (uint32)recvPacket.size());
1494
1495 SpellInfo const* spellInfo = ValidateCastSpellInfo(recvPacket, spellId);
1496 if (!spellInfo)
1497 return;
1498
1499 if (!ValidateCastSource(recvPacket, _player, caster, spellInfo, spellId))
1500 return;
1501
1502 // Aura Overriden Spells
1505 if (!swaps2.empty())
1506 swaps.insert(swaps.end(), swaps2.begin(), swaps2.end());
1507
1508 if (!swaps.empty())
1509 {
1510 for (Unit::AuraEffectList::const_iterator itr = swaps.begin(); itr != swaps.end(); ++itr)
1511 {
1512 if ((*itr)->IsAffectingSpell(spellInfo))
1513 {
1514 if (SpellInfo const* newInfo = sSpellMgr->GetSpellInfo((*itr)->GetAmount()))
1515 {
1516 if (caster->ToPlayer()->getLevel() < spellInfo->SpellLevel ||
1517 caster->ToPlayer()->getLevel() < spellInfo->BaseLevel)
1518 continue;
1519
1520 if (caster->ToPlayer()->getLevel() < newInfo->SpellLevel ||
1521 caster->ToPlayer()->getLevel() < newInfo->BaseLevel)
1522 continue;
1523
1524 spellInfo = newInfo;
1525 spellId = newInfo->Id;
1526 }
1527 break;
1528 }
1529 }
1530 }
1531
1532 // Specialization Overriden Spells
1533 uint32 SpecializationID = caster->ToPlayer()->GetTalentSpecialization(caster->ToPlayer()->GetActiveSpec());
1534 if (SpecializationID)
1535 {
1536 for (uint32 i = 0; i < sSpecializationSpellsStore.GetNumRows(); i++)
1537 {
1538 SpecializationSpellsEntry const* specializationInfo = sSpecializationSpellsStore.LookupEntry(i);
1539 if (!specializationInfo)
1540 continue;
1541
1542 if (specializationInfo->SpecializationId != SpecializationID)
1543 continue;
1544
1545 if (specializationInfo->RemovesSpellId == spellId)
1546 {
1547 if (SpellInfo const* newInfo = sSpellMgr->GetSpellInfo(specializationInfo->SpellId))
1548 {
1549 if (caster->ToPlayer()->getLevel() < spellInfo->SpellLevel ||
1550 caster->ToPlayer()->getLevel() < spellInfo->BaseLevel)
1551 continue;
1552
1553 if (caster->ToPlayer()->getLevel() < newInfo->SpellLevel ||
1554 caster->ToPlayer()->getLevel() < newInfo->BaseLevel)
1555 continue;
1556
1557 spellInfo = newInfo;
1558 spellId = newInfo->Id;
1559 }
1560 break;
1561 }
1562 }
1563 }
1564
1565 // Talent Overriden Spells
1566 uint32 ClassID = caster->ToPlayer()->getClass();
1567 if (ClassID)
1568 {
1569 for (uint32 i = 0; i < sTalentStore.GetNumRows(); i++)
1570 {
1571 TalentEntry const* talentInfo = sTalentStore.LookupEntry(i);
1572 if (!talentInfo)
1573 continue;
1574
1575 if (talentInfo->playerClass != ClassID)
1576 continue;
1577
1578 if (!caster->ToPlayer()->HasActiveSpell(talentInfo->SpellId))
1579 continue;
1580
1581 if (talentInfo->OverrideSpellID == spellId)
1582 {
1583 if (SpellInfo const* newInfo = sSpellMgr->GetSpellInfo(talentInfo->SpellId))
1584 {
1585 if (caster->ToPlayer()->getLevel() < spellInfo->SpellLevel ||
1586 caster->ToPlayer()->getLevel() < spellInfo->BaseLevel)
1587 continue;
1588
1589 if (caster->ToPlayer()->getLevel() < newInfo->SpellLevel ||
1590 caster->ToPlayer()->getLevel() < newInfo->BaseLevel)
1591 continue;
1592
1593 spellInfo = newInfo;
1594 spellId = newInfo->Id;
1595 }
1596 break;
1597 }
1598 }
1599 }
1600
1601 if (!ValidateCastExecution(recvPacket, _player, caster, spellInfo))
1602 return;
1603
1604 // client provided targets
1605 SpellCastTargets targets(caster, request.targetMask, request.targetGuid, request.itemTargetGuid, request.srcTransportGuid, request.destTransportGuid, request.srcPos, request.destPos, request.elevation, request.missileSpeed, request.targetString);
1606
1607 // auto-selection buff level base at target level (in spellInfo)
1608 if (targets.GetUnitTarget())
1609 {
1610 SpellInfo const* actualSpellInfo = spellInfo->GetAuraRankForLevel(targets.GetUnitTarget()->getLevel());
1611
1612 // if rank not found then function return NULL but in explicit cast case original spell can be casted and later failed with appropriate error message
1613 if (actualSpellInfo)
1614 spellInfo = actualSpellInfo;
1615 }
1616
1617 Spell* spell = new Spell(caster, spellInfo, TRIGGERED_NONE, 0, false);
1618 spell->m_cast_count = castCount; // set count of casts
1619 spell->m_glyphIndex = glyphIndex;
1620
1621 if (request.hasResearchData)
1622 {
1623 SpellResearchData* researchData = new SpellResearchData();
1624 *researchData = request.researchData;
1625 spell->m_researchData = researchData;
1626 }
1627
1628 spell->prepare(&targets);
1629}
1630
1632{
1633 CancelCastRequest request = ReadCancelCastRequest(recvPacket);
1634
1635 if (_player->IsNonMeleeSpellCasted(false))
1636 _player->InterruptNonMeleeSpells(false, request.spellId, false);
1637}
1638
1640{
1641 CancelAuraRequest request = ReadCancelAuraRequest(recvPacket);
1642
1643 SpellInfo const* spellInfo = ValidateCancelAuraSpell(request);
1644 if (!spellInfo)
1645 return;
1646
1647 // channeled spell case (it currently casted then)
1648 if (TryInterruptMatchingChannel(_player, spellInfo, request.spellId))
1649 return;
1650
1651 if (!IsPlayerCancelableAura(spellInfo))
1652 return;
1653
1654 // maybe should only remove one buff when there are multiple?
1655 _player->RemoveOwnedAura(request.spellId, 0, 0, AURA_REMOVE_BY_CANCEL);
1656}
1657
1659{
1660 PetCancelAuraRequest request = ReadPetCancelAuraRequest(recvPacket);
1661
1662 Creature* pet = ValidatePetCancelAuraRequest(_player, request);
1663 if (!pet)
1664 return;
1665
1666 pet->RemoveOwnedAura(request.spellId, 0, 0, AURA_REMOVE_BY_CANCEL);
1667
1668 pet->AddCreatureSpellCooldown(request.spellId);
1669}
1670
1672
1674{
1675 // may be better send SMSG_CANCEL_AUTO_REPEAT?
1676 // cancel and prepare for deleting
1677 _player->InterruptSpell(CURRENT_AUTOREPEAT_SPELL);
1678}
1679
1681{
1682 ReadCancelChannelingRequest(recvData);
1683
1684 // ignore for remote control state (for player case)
1685 Unit* mover = _player->m_mover;
1686 if (mover != _player && mover->GetTypeId() == TypeID::TYPEID_PLAYER)
1687 return;
1688
1690}
1691
1693{
1694 // ignore for remote control state
1695 if (_player->m_mover != _player)
1696 return;
1697
1698 TotemDestroyedRequest request = ReadTotemDestroyedRequest(recvPacket);
1699
1700 ++request.slotId;
1701 if (request.slotId >= MAX_TOTEM_SLOT)
1702 return;
1703
1704 if (!_player->m_SummonSlot[request.slotId])
1705 return;
1706
1707 Creature* totem = GetPlayer()->GetMap()->GetCreature(_player->m_SummonSlot[request.slotId]);
1708 if (totem && totem->IsTotem() && totem->GetGUID() == request.guid)
1709 totem->ToTotem()->UnSummon();
1710}
1711
1713{
1714 SF_LOG_DEBUG("network", "WORLD: CMSG_SELF_RES"); // empty opcode
1715
1716 if (_player->HasAuraType(SPELL_AURA_PREVENT_RESURRECTION))
1717 return; // silent return, client should display error by itself and not send this opcode
1718
1719 if (_player->GetUInt32Value(PLAYER_FIELD_SELF_RES_SPELL))
1720 {
1721 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(_player->GetUInt32Value(PLAYER_FIELD_SELF_RES_SPELL));
1722 if (spellInfo)
1723 _player->CastSpell(_player, spellInfo, false, 0);
1724
1725 _player->SetUInt32Value(PLAYER_FIELD_SELF_RES_SPELL, 0);
1726 }
1727}
1728
1730{
1731 SF_LOG_DEBUG("network", "WORLD: CMSG_SPELLCLICK");
1732
1733 SpellClickRequest request = ReadSpellClickRequest(recvData);
1734
1735 // this will get something not in world. crash
1737
1738 if (!unit)
1739 return;
1740
1742 if (!unit->IsInWorld())
1743 return;
1744
1745 if (_player->IsMounted() && request.tryAutoDismount)
1746 _player->Dismount();
1747
1749}
1750
1752{
1753 SF_LOG_DEBUG("network", "WORLD: CMSG_GET_MIRROR_IMAGE_DATA");
1754
1755 GuidRequest request = ReadMirrorImageDataRequest(recvData);
1756 ObjectGuid guid = request.guid;
1757
1758 // Get unit for which data is needed by client
1759 Unit* unit = ObjectAccessor::GetObjectInWorld(guid, (Unit*)NULL);
1760 if (!unit)
1761 return;
1762
1764 return;
1765
1766 // Get creator of the unit (SPELL_AURA_CLONE_CASTER does not stack)
1767 Unit* creator = unit->GetAuraEffectsByType(SPELL_AURA_CLONE_CASTER).front()->GetCaster();
1768 if (!creator)
1769 return;
1770
1771 if (Player* player = creator->ToPlayer())
1772 {
1773 WorldPacket data(SMSG_MIRROR_IMAGE_COMPONENTED_DATA, 8 + 4 + 8 * 1 + 8 + 11 * 4);
1774 Guild* guild = player->GetGuild();
1775 ObjectGuid guildGuid = guild ? guild->GetGUID() : 0;
1776
1777 data.WriteBit(guid[4]);
1778 data.WriteBit(guildGuid[3]);
1779 data.WriteBit(guildGuid[6]);
1780 data.WriteBit(guid[0]);
1781 data.WriteBit(guildGuid[7]);
1782 data.WriteBit(guid[1]);
1783 data.WriteBit(guid[5]);
1784 data.WriteBit(guildGuid[2]);
1785 data.WriteBit(guildGuid[1]);
1786 data.WriteBit(guid[7]);
1787 data.WriteBit(guildGuid[4]);
1788 data.WriteBit(guildGuid[0]);
1789 data.WriteBit(guid[2]);
1790 data.WriteBit(guildGuid[5]);
1791 data.WriteBit(guid[3]);
1792 data.WriteBits(11, 22); // item slots count
1793 data.WriteBit(guid[6]);
1794 data.FlushBits();
1795
1796 data << uint8(player->GetByteValue(PLAYER_FIELD_HAIR_COLOR_ID, 3)); // haircolor
1797 data << uint32(creator->GetDisplayId());
1798 data << uint8(player->GetByteValue(PLAYER_FIELD_REST_STATE, 0)); // facial hair
1799
1800 data.WriteByteSeq(guildGuid[6]);
1801 data.WriteByteSeq(guildGuid[4]);
1802 data.WriteByteSeq(guid[7]);
1803 data.WriteByteSeq(guildGuid[1]);
1804 data.WriteByteSeq(guid[3]);
1805 data << uint8(player->GetByteValue(PLAYER_FIELD_HAIR_COLOR_ID, 2)); // hair
1806 data.WriteByteSeq(guid[2]);
1807 data.WriteByteSeq(guid[0]);
1808 data << uint8(creator->getRace());
1809 data << uint8(player->GetByteValue(PLAYER_FIELD_HAIR_COLOR_ID, 0)); // skin
1810 data.WriteByteSeq(guildGuid[7]);
1811
1812 static EquipmentSlots const itemSlots[] =
1813 {
1826 };
1827
1828 // Display items in visible slots
1829 for (EquipmentSlots const* itr = &itemSlots[0]; *itr != EQUIPMENT_SLOT_END; ++itr)
1830 {
1832 data << uint32(0);
1834 data << uint32(0);
1835 else if (Item const* item = player->GetItemByPos(INVENTORY_SLOT_BAG_0, *itr))
1836 data << uint32(item->GetTemplate()->DisplayInfoID);
1837 else
1838 data << uint32(0);
1839 }
1840
1841 data.WriteByteSeq(guid[4]);
1842 data << uint8(creator->getClass());
1843 data << uint8(creator->getGender());
1844 data << uint8(player->GetByteValue(PLAYER_FIELD_HAIR_COLOR_ID, 1)); // face
1845 data.WriteByteSeq(guid[5]);
1846 data.WriteByteSeq(guildGuid[3]);
1847 data.WriteByteSeq(guildGuid[2]);
1848 data.WriteByteSeq(guid[1]);
1849 data.WriteByteSeq(guildGuid[0]);
1850 data.WriteByteSeq(guildGuid[5]);
1851 data.WriteByteSeq(guid[6]);
1852
1853 SendPacket(&data);
1854 }
1855 else
1856 {
1858 data.WriteGuidMask(guid, 0, 1, 3, 5, 7, 6, 4, 2);
1859
1860 data.WriteGuidBytes(guid, 0, 3, 6, 5, 7);
1861 data << uint32(creator->GetDisplayId());
1862 data.WriteGuidBytes(guid, 4, 2, 1);
1863
1864 SendPacket(&data);
1865 }
1866}
1867
1869{
1870 SF_LOG_DEBUG("network", "WORLD: CMSG_UPDATE_PROJECTILE_POSITION");
1871
1872 ProjectilePositionRequest request = ReadUpdateProjectilePositionRequest(recvPacket);
1873
1874 Unit* caster = ObjectAccessor::GetUnit(*_player, request.casterGuid);
1875 if (!caster)
1876 return;
1877
1878 Spell* spell = caster->FindCurrentSpellBySpellId(request.spellId);
1879 if (!spell || !spell->m_targets.HasDst())
1880 return;
1881
1882 Position pos = *spell->m_targets.GetDstPos();
1883 pos.Relocate(request.x, request.y, request.z);
1884 spell->m_targets.ModDst(pos);
1885
1887 data << uint64(request.casterGuid);
1888 data << uint8(request.castCount);
1889 data << float(request.x);
1890 data << float(request.y);
1891 data << float(request.z);
1892 caster->SendMessageToSet(&data, true);
1893}
1894
1896{
1897 std::map<uint32, int32> categoryMods;
1898 Unit::AuraEffectList const& categoryCooldownAuras = _player->GetAuraEffectsByType(SPELL_AURA_MOD_SPELL_CATEGORY_COOLDOWN);
1899 for (Unit::AuraEffectList::const_iterator itr = categoryCooldownAuras.begin(); itr != categoryCooldownAuras.end(); ++itr)
1900 {
1901 std::map<uint32, int32>::iterator cItr = categoryMods.find((*itr)->GetMiscValue());
1902 if (cItr == categoryMods.end())
1903 categoryMods[(*itr)->GetMiscValue()] = (*itr)->GetAmount();
1904 else
1905 cItr->second += (*itr)->GetAmount();
1906 }
1907
1909 data.WriteBits(categoryMods.size(), 21);
1910 data.FlushBits();
1911
1912 for (std::map<uint32, int32>::const_iterator itr = categoryMods.begin(); itr != categoryMods.end(); ++itr)
1913 {
1914 data << int32(-itr->second);
1915 data << uint32(itr->first);
1916 }
1917
1918 SendPacket(&data);
1919}
1920
1921void WorldSession::SendTotemCreated(ObjectGuid TotemGUID, uint32 Duration, uint32 SpellID, uint8 Slot)
1922{
1924 data.WriteGuidMask(TotemGUID, 6, 1, 2, 5, 3, 4, 7, 0);
1925 data << uint32(Duration);
1926 data << uint32(SpellID);
1927 data.WriteGuidBytes(TotemGUID, 3, 4, 5, 6, 0, 2);
1928 data << uint8(Slot);
1929 data.WriteGuidBytes(TotemGUID, 1, 7);
1930 _player->SendDirectMessage(&data);
1931}
1932
1933void WorldSession::SendModifyCooldown(ObjectGuid UnitGUID, int32 DeltaTime, int32 SpellID)
1934{
1935 WorldPacket data(SMSG_MODIFY_COOLDOWN, 4 + 8 + 4);
1936 data.WriteGuidMask(UnitGUID, 2, 1, 0, 4, 7, 3, 6, 5);
1937 data.WriteGuidBytes(UnitGUID, 4, 1);
1938 data << int32(DeltaTime); // Cooldown mod in milliseconds
1939 data.WriteGuidBytes(UnitGUID, 3, 6, 7, 5, 0);
1940 data << uint32(SpellID); // Spell ID
1941 data.WriteGuidBytes(UnitGUID, 2);
1942 SendPacket(&data);
1943}
@ CHAR_DEL_GIFT
@ CHAR_SEL_CHARACTER_GIFT_BY_ITEM
#define M_PI
Definition Common.h:192
@ ACHIEVEMENT_CRITERIA_TYPE_USE_GAMEOBJECT
Definition DBCEnums.h:231
DBCStorage< LockEntry > sLockStore(LockEntryfmt)
DBCStorage< TalentEntry > sTalentStore(TalentEntryfmt)
DBCStorage< SpecializationSpellsEntry > sSpecializationSpellsStore(SpecializationSpellsfmt)
std::int32_t int32
Definition Define.h:73
std::uint8_t uint8
Definition Define.h:79
std::uint32_t uint32
Definition Define.h:77
std::uint64_t uint64
Definition Define.h:76
InventoryResult
Definition Item.h:27
@ EQUIP_ERR_NOT_DURING_ARENA_MATCH
Definition Item.h:106
@ EQUIP_ERR_CLIENT_LOCKED_OUT
Definition Item.h:67
@ EQUIP_ERR_NOT_IN_COMBAT
Definition Item.h:88
@ EQUIP_ERR_ITEM_LOCKED
Definition Item.h:64
@ EQUIP_ERR_ITEM_NOT_FOUND
Definition Item.h:51
@ EQUIP_ERR_OK
Definition Item.h:28
@ ITEM_CHANGED
Definition Item.h:192
@ INVTYPE_NON_EQUIP
@ ITEM_PROTO_FLAG_NOT_USEABLE_IN_ARENA
@ ITEM_PROTO_FLAG_USEABLE_IN_ARENA
@ ITEM_PROTO_FLAG_OPENABLE
#define MAX_ITEM_PROTO_SPELLS
@ BIND_WHEN_USE
@ BIND_QUEST_ITEM
@ BIND_WHEN_PICKED_UP
@ ITEM_CLASS_CONSUMABLE
@ ITEM_FLAG_WRAPPED
#define SF_LOG_DEBUG(filterType__,...)
Definition Log.h:134
#define SF_LOG_ERROR(filterType__,...)
Definition Log.h:143
#define SF_LOG_INFO(filterType__,...)
Definition Log.h:137
@ LOOT_CORPSE
Definition LootMgr.h:67
@ TYPEID_PLAYER
Definition Object.h:55
@ TYPEID_UNIT
Definition Object.h:54
#define INTERACTION_DISTANCE
Definition Object.h:21
uint32 GUID_LOPART(uint64 x)
@ FEEDBACK_PET_DEAD
Definition PetDefines.h:46
@ PLAYER_FLAGS_HIDE_CLOAK
Definition Player.h:548
@ PLAYER_FLAGS_HIDE_HELM
Definition Player.h:547
EquipmentSlots
Definition Player.h:687
@ EQUIPMENT_SLOT_SHOULDERS
Definition Player.h:691
@ EQUIPMENT_SLOT_BODY
Definition Player.h:692
@ EQUIPMENT_SLOT_HANDS
Definition Player.h:698
@ EQUIPMENT_SLOT_TABARD
Definition Player.h:707
@ EQUIPMENT_SLOT_END
Definition Player.h:708
@ EQUIPMENT_SLOT_HEAD
Definition Player.h:689
@ EQUIPMENT_SLOT_LEGS
Definition Player.h:695
@ EQUIPMENT_SLOT_BACK
Definition Player.h:703
@ EQUIPMENT_SLOT_WAIST
Definition Player.h:694
@ EQUIPMENT_SLOT_FEET
Definition Player.h:696
@ EQUIPMENT_SLOT_CHEST
Definition Player.h:693
@ EQUIPMENT_SLOT_WRISTS
Definition Player.h:697
#define INVENTORY_SLOT_BAG_0
Definition Player.h:684
Skyfire::AutoPtr< PreparedResultSet, Skyfire::Mutex > PreparedQueryResult
Definition QueryResult.h:94
#define sScriptMgr
Definition ScriptMgr.h:764
@ SPELL_ATTR0_CANT_CANCEL
#define MAX_GLYPH_SLOT_INDEX
@ GO_FLAG_NOT_SELECTABLE
@ SPELL_AURA_PREVENT_RESURRECTION
@ SPELL_AURA_CLONE_CASTER
@ SPELL_AURA_OVERRIDE_ACTIONBAR_SPELLS_2
@ SPELL_AURA_MOD_SPELL_CATEGORY_COOLDOWN
@ SPELL_AURA_OVERRIDE_ACTIONBAR_SPELLS
#define sSpellMgr
Definition SpellMgr.h:744
@ AURA_REMOVE_BY_CANCEL
Definition Unit.h:408
@ TRIGGERED_NONE
Definition Unit.h:416
#define MAX_TOTEM_SLOT
Definition Unit.h:1341
@ CURRENT_CHANNELED_SPELL
Definition Unit.h:1110
@ CURRENT_AUTOREPEAT_SPELL
Definition Unit.h:1111
@ ITEM_FIELD_GIFT_CREATOR
@ ITEM_FIELD_DYNAMIC_FLAGS
@ GAMEOBJECT_FIELD_FLAGS
@ PLAYER_FIELD_HAIR_COLOR_ID
@ PLAYER_FIELD_SELF_RES_SPELL
@ PLAYER_FIELD_PLAYER_FLAGS
@ PLAYER_FIELD_REST_STATE
void WriteGuidBytes(const ObjectGuid &guid, Offsets... offsets)
Definition ByteBuffer.h:264
bool WriteBit(uint32 bit)
Definition ByteBuffer.h:164
void read_skip()
Definition ByteBuffer.h:502
void WriteGuidMask(const ObjectGuid &guid, Offsets... offsets)
Definition ByteBuffer.h:248
uint32 ReadBits(size_t bits)
Definition ByteBuffer.h:198
void ReadGuidBytes(ObjectGuid &guid, Offsets... offsets)
Definition ByteBuffer.h:256
void ReadByteSeq(uint8 &b)
Definition ByteBuffer.h:215
void rfinish()
Definition ByteBuffer.h:478
std::string ReadString(size_t length)
Definition ByteBuffer.h:565
void ReadGuidMask(ObjectGuid &guid, Offsets... offsets)
Definition ByteBuffer.h:240
void WriteBits(T value, size_t bits)
Definition ByteBuffer.h:192
size_t size() const
Definition ByteBuffer.h:609
void WriteByteSeq(uint8 b)
Definition ByteBuffer.h:227
void FlushBits()
Definition ByteBuffer.h:154
bool ReadBit()
Definition ByteBuffer.h:180
void AddCreatureSpellCooldown(uint32 spellid)
bool HasSpell(uint32 spellID) const OVERRIDE
Definition Field.h:16
uint32 GetUInt32() const
Definition Field.h:105
virtual bool GossipHello(Player *)
GameObjectAI * AI() const
Definition GameObject.h:824
Definition Guild.h:324
uint64 GetGUID() const
Definition Guild.h:758
Definition Item.h:202
uint8 GetSlot() const
Definition Item.h:265
void SetBinding(bool val)
Definition Item.h:217
void SetState(ItemUpdateState state, Player *forplayer=NULL)
Definition Item.cpp:667
bool IsLocked() const
Definition Item.h:243
ItemTemplate const * GetTemplate() const
Definition Item.cpp:528
bool IsSoulBound() const
Definition Item.h:218
bool IsEquipped() const
Definition Item.cpp:739
uint8 GetBagSlot() const
Definition Item.cpp:734
GameObject * GetGameObject(uint64 guid)
Definition Map.cpp:3184
Creature * GetCreature(uint64 guid)
Definition Map.cpp:3179
static Creature * GetCreatureOrPetOrVehicle(WorldObject const &, uint64)
static Unit * GetUnit(WorldObject const &, uint64 guid)
static T * GetObjectInWorld(uint64 guid, T *)
uint8 GetByteValue(uint16 index, uint8 offset) const
Definition Object.cpp:343
uint64 GetGUID() const
Definition Object.h:119
Player * ToPlayer()
Definition Object.h:204
bool IsInWorld() const
Definition Object.h:114
uint32 GetGUIDLow() const
Definition Object.h:120
TypeID GetTypeId() const
Definition Object.h:131
uint32 GetEntry() const
Definition Object.h:125
Creature * ToCreature()
Definition Object.h:207
bool HasFlag(uint16 index, uint32 flag) const
Definition Object.cpp:1309
void SetEntry(uint32 entry)
Definition Object.h:126
void SetUInt32Value(uint16 index, uint32 value)
Definition Object.cpp:1038
void SetUInt64Value(uint16 index, uint64 value)
Definition Object.cpp:1079
void SendEquipError(InventoryResult msg, Item *pItem, Item *pItem2=NULL, uint32 itemid=0)
bool HasResearchingProject(uint32 projectId) const
Definition Player.h:3215
uint32 GetTalentSpecialization(uint8 spec) const
Definition Player.h:2075
Item * GetUseableItemByPos(uint8 bag, uint8 slot) const
Unit * m_mover
Definition Player.h:2807
bool HasActiveSpell(uint32 spell) const
Definition Player.cpp:4687
Guild * GetGuild()
Definition Player.cpp:22662
Item * GetItemByPos(uint16 pos) const
void DestroyItem(uint8 bag, uint8 slot, bool update)
uint8 GetActiveSpec() const
Definition Player.h:2077
bool InArena() const
Definition Player.cpp:19310
void SendLoot(uint64 guid, LootType loot_type, bool isAoE=false)
Definition Player.cpp:9346
void CastItemUseSpell(Item *item, SpellCastTargets const &targets, uint8 cast_count, uint32 glyphIndex, SpellResearchData const *researchData=NULL)
Definition Player.cpp:9064
InventoryResult CanUseItem(Item *pItem, bool not_loading=true) const
void setUInt32(const uint8 index, const uint32 value)
void ModDst(Position const &pos)
Definition Spell.cpp:412
void SetSpeed(float speed)
Definition Spell.h:223
bool HasDst() const
Definition Spell.h:217
void SetElevation(float elevation)
Definition Spell.h:221
Unit * GetUnitTarget() const
Definition Spell.cpp:221
WorldLocation const * GetDstPos() const
Definition Spell.cpp:383
Definition Spell.h:289
SpellCastTargets m_targets
Definition Spell.h:535
SpellResearchData const * m_researchData
Definition Spell.h:538
void prepare(SpellCastTargets const *targets, AuraEffect const *triggeredByAura=NULL)
Definition Spell.cpp:2939
uint8 m_cast_count
Definition Spell.h:533
uint32 m_glyphIndex
Definition Spell.h:534
SpellInfo const *const m_spellInfo
Definition Spell.h:530
uint32 BaseLevel
Definition SpellInfo.h:205
uint32 SpellLevel
Definition SpellInfo.h:206
uint32 ResearchProject
Definition SpellInfo.h:247
bool IsPassive() const
uint32 Id
Definition SpellInfo.h:160
SpellInfo const * GetAuraRankForLevel(uint8 level) const
bool IsChanneled() const
uint32 Attributes
Definition SpellInfo.h:164
SpellCastResult CheckVehicle(Unit const *caster) const
bool IsPositive() const
bool IsAutoRepeatRangedSpell() const
void UnSummon(uint32 msTime=0) OVERRIDE
Definition Totem.cpp:77
Definition Unit.h:1367
void RemoveOwnedAura(AuraMap::iterator &i, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
AuraEffectList const & GetAuraEffectsByType(AuraType type) const
Definition Unit.h:2243
uint8 getGender() const
Definition Unit.h:1551
Unit * GetCharm() const
Definition Unit.cpp:2405
void SendPetActionFeedback(uint8 msg) const
-------—Pet responses methods--------------—
Definition Unit.cpp:5833
Spell * FindCurrentSpellBySpellId(uint32 spell_id) const
Definition Unit.cpp:1448
Totem * ToTotem()
Definition Unit.h:2812
uint8 getClass() const
Definition Unit.h:1543
bool IsAlive() const
Definition Unit.h:2032
bool IsOnVehicle(const Unit *vehicle) const
Definition Unit.cpp:7198
uint32 GetDisplayId() const
Definition Unit.h:2490
bool isPossessing() const
Definition Unit.cpp:2818
uint64 GetTransGUID() const override
Definition Unit.cpp:7217
bool HasAuraType(AuraType auraType) const
bool HandleSpellClick(Unit *clicker, int8 seatId=-1)
Definition Unit.cpp:8160
uint8 getLevel() const
Definition Unit.h:1528
std::list< AuraEffect * > AuraEffectList
Definition Unit.h:1383
bool IsTotem() const
Definition Unit.h:1519
Guardian * GetGuardianPet() const
Definition Unit.cpp:2390
bool IsInCombat() const
Definition Unit.h:1896
void InterruptSpell(CurrentSpellTypes spellType, bool withDelayed=true, bool withInstant=true)
Definition Unit.cpp:1365
uint8 getRace() const
Definition Unit.h:1535
Spell * GetCurrentSpell(CurrentSpellTypes spellType) const
Definition Unit.h:2363
Map * GetMap() const
Definition Object.h:740
bool IsWithinDistInMap(WorldObject const *obj, float dist2compare, bool is3D=true) const
Definition Object.cpp:1735
float GetTransOffsetX() const
Definition Object.h:798
float GetTransOffsetY() const
Definition Object.h:799
std::string const & GetName() const
Definition Object.h:664
float GetTransOffsetZ() const
Definition Object.h:800
float GetTransOffsetO() const
Definition Object.h:801
virtual void SendMessageToSet(WorldPacket *data, bool self)
Definition Object.cpp:2485
void HandleCancelGrowthAuraOpcode(WorldPacket &recvPacket)
void HandlePetCancelAuraOpcode(WorldPacket &recvPacket)
void HandleOpenItemOpcode(WorldPacket &recvPacket)
void HandleGameObjectUseOpcode(WorldPacket &recPacket)
void HandleMovementOpcodes(WorldPacket &recvPacket)
void HandleUpdateProjectilePosition(WorldPacket &recvPacket)
Player * GetPlayer() const
void HandleCancelCastOpcode(WorldPacket &recvPacket)
void HandleSelfResOpcode(WorldPacket &recvData)
void HandleCastSpellOpcode(WorldPacket &recvPacket)
void HandleMirrorImageDataRequest(WorldPacket &recvData)
void HandleTotemDestroyed(WorldPacket &recvData)
void HandleGameobjectReportUse(WorldPacket &recvPacket)
void HandleRequestCategoryCooldowns(WorldPacket &recvPacket)
void SendPacket(WorldPacket const *packet, bool forced=false)
Send a packet to the client.
void HandleCancelChanneling(WorldPacket &recvData)
Player * _player
void HandleCancelAutoRepeatSpellOpcode(WorldPacket &recvPacket)
void SendModifyCooldown(ObjectGuid UnitGUID, int32 DeltaTime, int32 SpellID)
void HandleUseItemOpcode(WorldPacket &recvPacket)
void HandleClientCastFlags(WorldPacket &recvPacket, uint8 castFlags, SpellCastTargets &targets)
void HandleSpellClick(WorldPacket &recvData)
void SendTotemCreated(ObjectGuid TotemGUID, uint32 Duration, uint32 SpellID, uint8 Slot)
void HandleCancelAuraOpcode(WorldPacket &recvPacket)
CharacterDatabaseWorkerPool CharacterDatabase
Accessor to the character database.
Definition Main.cpp:41
@ SMSG_TOTEM_CREATED
Definition Opcodes.h:1032
@ SMSG_SET_PROJECTILE_POSITION
Definition Opcodes.h:962
@ SMSG_MODIFY_COOLDOWN
Definition Opcodes.h:784
@ SMSG_CATEGORY_COOLDOWN
Definition Opcodes.h:596
@ SMSG_MIRROR_IMAGE_CREATURE_DATA
Definition Opcodes.h:782
@ SMSG_MIRROR_IMAGE_COMPONENTED_DATA
Definition Opcodes.h:781
int32 SpellId
_Spell Spells[MAX_ITEM_PROTO_SPELLS]
uint32 DisplayInfoID
uint32 InventoryType
uint32 time
Definition Object.h:453
struct MovementInfo::JumpInfo jump
uint16 flags2
Definition Object.h:451
uint32 flags
Definition Object.h:450
struct MovementInfo::TransportInfo transport
float splineElevation
Definition Object.h:494
float pitch
Definition Object.h:477
Position pos
Definition Object.h:452
float m_positionZ
Definition Object.h:289
float m_positionX
Definition Object.h:287
float m_positionY
Definition Object.h:288
void SetOrientation(float orientation)
Definition Object.h:323
void Relocate(float x, float y)
Definition Object.h:302
uint32 SpellId
uint32 RemovesSpellId
uint32 SpecializationId
uint32 fragmentCurrencyId
Definition Spell.h:284
uint32 fragmentCount
Definition Spell.h:285
uint32 keystoneItemId
Definition Spell.h:282
uint32 keystoneCount
Definition Spell.h:283
uint32 SpellId
uint32 playerClass
uint32 OverrideSpellID