TrinityCore
Loading...
Searching...
No Matches
SpellHandler.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 "WorldSession.h"
19#include "Common.h"
20#include "Config.h"
21#include "DatabaseEnv.h"
22#include "Log.h"
23#include "DBCStores.h"
24#include "GameClient.h"
25#include "GameObject.h"
26#include "GameObjectAI.h"
27#include "Item.h"
28#include "MovementPackets.h"
29#include "ObjectAccessor.h"
30#include "ObjectMgr.h"
31#include "Opcodes.h"
32#include "Player.h"
33#include "ScriptMgr.h"
34#include "Spell.h"
35#include "SpellAuraEffects.h"
36#include "SpellMgr.h"
37#include "SpellPackets.h"
38#include "Totem.h"
39#include "TotemPackets.h"
40#include "World.h"
41#include "WorldPacket.h"
42
44{
45 // some spell cast packet including more data (for projectiles?)
46 if (castFlags & 0x02)
47 {
48 // not sure about these two
49 float elevation, speed;
50 recvPacket >> elevation;
51 recvPacket >> speed;
52
53 targets.SetElevation(elevation);
54 targets.SetSpeed(speed);
55
56 uint8 hasMovementData;
57 recvPacket >> hasMovementData;
58 if (hasMovementData)
59 {
60 OpcodeClient opcode = static_cast<OpcodeClient>(recvPacket.read<uint32>());
61 MovementInfo movementInfo;
62 recvPacket >> movementInfo.guid.ReadAsPacked();
63 recvPacket >> movementInfo;
64 HandleMovementOpcode(opcode, movementInfo);
65 }
66 }
67}
68
70{
72 Player* pUser = _player;
73
74 uint8 bagIndex, slot, castFlags;
75 uint8 castCount; // next cast if exists (single or not)
76 ObjectGuid itemGUID;
77 uint32 glyphIndex; // something to do with glyphs?
78 uint32 spellId; // cast spell id
79
80 recvPacket >> bagIndex >> slot >> castCount >> spellId >> itemGUID >> glyphIndex >> castFlags;
81
82 if (glyphIndex >= MAX_GLYPH_SLOT_INDEX)
83 {
84 pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, nullptr, nullptr);
85 return;
86 }
87
88 Item* pItem = pUser->GetUseableItemByPos(bagIndex, slot);
89 if (!pItem)
90 {
91 pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, nullptr, nullptr);
92 return;
93 }
94
95 if (pItem->GetGUID() != itemGUID)
96 {
97 pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, nullptr, nullptr);
98 return;
99 }
100
101 TC_LOG_DEBUG("network", "WORLD: CMSG_USE_ITEM packet, bagIndex: {}, slot: {}, castCount: {}, spellId: {}, Item: {}, glyphIndex: {}, data length = {}", bagIndex, slot, castCount, spellId, pItem->GetEntry(), glyphIndex, (uint32)recvPacket.size());
102
103 ItemTemplate const* proto = pItem->GetTemplate();
104 if (!proto)
105 {
106 pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, pItem, nullptr);
107 return;
108 }
109
110 // some item classes can be used only in equipped state
111 if (proto->InventoryType != INVTYPE_NON_EQUIP && !pItem->IsEquipped())
112 {
113 pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, pItem, nullptr);
114 return;
115 }
116
117 InventoryResult msg = pUser->CanUseItem(pItem);
118 if (msg != EQUIP_ERR_OK)
119 {
120 pUser->SendEquipError(msg, pItem, nullptr);
121 return;
122 }
123
124 // only allow conjured consumable, bandage, poisons (all should have the 2^21 item flag set in DB)
126 {
127 pUser->SendEquipError(EQUIP_ERR_NOT_DURING_ARENA_MATCH, pItem, nullptr);
128 return;
129 }
130
131 // don't allow items banned in arena
132 if (proto->HasFlag(ITEM_FLAG_NOT_USEABLE_IN_ARENA) && pUser->InArena())
133 {
134 pUser->SendEquipError(EQUIP_ERR_NOT_DURING_ARENA_MATCH, pItem, nullptr);
135 return;
136 }
137
138 if (pUser->IsInCombat())
139 {
140 for (ItemEffect const& effectData : proto->Effects)
141 {
142 if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(effectData.SpellID))
143 {
144 if (!spellInfo->CanBeUsedInCombat())
145 {
146 pUser->SendEquipError(EQUIP_ERR_NOT_IN_COMBAT, pItem, nullptr);
147 return;
148 }
149 }
150 }
151 }
152
153 // check also BIND_WHEN_PICKED_UP and BIND_QUEST_ITEM for .additem or .additemset case by GM (not binded at adding to inventory)
155 {
156 if (!pItem->IsSoulBound())
157 {
158 pItem->SetState(ITEM_CHANGED, pUser);
159 pItem->SetBinding(true);
160 }
161 }
162
163 SpellCastTargets targets;
164 targets.Read(recvPacket, pUser);
165 HandleClientCastFlags(recvPacket, castFlags, targets);
166
167 // Note: If script stop casting it must send appropriate data to client to prevent stuck item in gray state.
168 if (!sScriptMgr->OnItemUse(pUser, pItem, targets))
169 {
170 // no script or script not process request by self
171 pUser->CastItemUseSpell(pItem, spellId, targets, castCount, glyphIndex);
172 }
173}
174
176{
177 TC_LOG_DEBUG("network", "WORLD: CMSG_OPEN_ITEM packet, data length = {}", (uint32)recvPacket.size());
178
179 Player* player = GetPlayer();
180
181 // ignore for remote control state
182 if (player->IsCharmed())
183 return;
184
185 // additional check, client outputs message on its own
186 if (!player->IsAlive())
187 {
188 player->SendEquipError(EQUIP_ERR_PLAYER_DEAD, nullptr, nullptr);
189 return;
190 }
191
192 uint8 bagIndex, slot;
193 recvPacket >> bagIndex >> slot;
194
195 TC_LOG_INFO("network", "bagIndex: {}, slot: {}", bagIndex, slot);
196
197 Item* item = player->GetItemByPos(bagIndex, slot);
198 if (!item)
199 {
200 player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, nullptr, nullptr);
201 return;
202 }
203
204 ItemTemplate const* proto = item->GetTemplate();
205 if (!proto)
206 {
207 player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, item, nullptr);
208 return;
209 }
210
211 // Verify that the bag is an actual bag or wrapped item that can be used "normally"
212 if (!proto->HasFlag(ITEM_FLAG_HAS_LOOT) && !item->IsWrapped())
213 {
214 player->SendEquipError(EQUIP_ERR_CLIENT_LOCKED_OUT, item, nullptr);
215 TC_LOG_ERROR("entities.player.cheat", "Possible hacking attempt: Player {} {} tried to open item [{}, entry: {}] which is not openable!",
216 player->GetName(), player->GetGUID().ToString(), item->GetGUID().ToString(), proto->ItemId);
217 return;
218 }
219
220 // locked item
221 uint32 lockId = proto->LockID;
222 if (lockId)
223 {
224 LockEntry const* lockInfo = sLockStore.LookupEntry(lockId);
225
226 if (!lockInfo)
227 {
228 player->SendEquipError(EQUIP_ERR_ITEM_LOCKED, item, nullptr);
229 TC_LOG_ERROR("network", "WORLD::OpenItem: item {} has an unknown lockId: {}!", item->GetGUID().ToString(), lockId);
230 return;
231 }
232
233 // was not unlocked yet
234 if (item->IsLocked())
235 {
236 player->SendEquipError(EQUIP_ERR_ITEM_LOCKED, item, nullptr);
237 return;
238 }
239 }
240
241 if (item->IsWrapped())
242 {
244 stmt->setUInt32(0, item->GetGUID().GetCounter());
246 .WithPreparedCallback(std::bind(&WorldSession::HandleOpenWrappedItemCallback, this, item->GetPos(), item->GetGUID(), std::placeholders::_1)));
247 }
248 else
249 player->SendLoot(item->GetGUID(), LOOT_CORPSE);
250}
251
253{
254 if (!GetPlayer())
255 return;
256
257 Item* item = GetPlayer()->GetItemByPos(pos);
258 if (!item)
259 return;
260
261 if (item->GetGUID() != itemGuid || !item->IsWrapped()) // during getting result, gift was swapped with another item
262 return;
263
264 if (!result)
265 {
266 TC_LOG_ERROR("network", "Wrapped item {} does't have record in character_gifts table and will deleted", itemGuid.ToString());
267 GetPlayer()->DestroyItem(item->GetBagSlot(), item->GetSlot(), true);
268 return;
269 }
270
271 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
272
273 Field* fields = result->Fetch();
274 uint32 entry = fields[0].GetUInt32();
275 uint32 flags = fields[1].GetUInt32();
276
278 item->SetEntry(entry);
282
284
286 stmt->setUInt32(0, itemGuid.GetCounter());
287 trans->Append(stmt);
288
289 CharacterDatabase.CommitTransaction(trans);
290}
291
293{
294 ObjectGuid guid;
295 recvData >> guid;
296
297 TC_LOG_DEBUG("network", "WORLD: Recvd CMSG_GAMEOBJ_USE Message [{}]", guid.ToString());
298
299 if (GameObject* obj = GetPlayer()->GetGameObjectIfCanInteractWith(guid))
300 {
301 // ignore for remote control state
302 if (GetPlayer()->IsCharmed())
303 if (!(GetPlayer()->IsOnVehicle(GetPlayer()->GetCharmed()) || GetPlayer()->IsMounted()) && !obj->GetGOInfo()->IsUsableMounted())
304 return;
305
306 obj->Use(GetPlayer());
307 }
308}
309
311{
312 ObjectGuid guid;
313 recvPacket >> guid;
314
315 TC_LOG_DEBUG("network", "WORLD: Recvd CMSG_GAMEOBJ_REPORT_USE Message [{}]", guid.ToString());
316
317 // ignore for remote control state
318 if (_player->IsCharmed())
319 return;
320
321 if (GameObject* go = GetPlayer()->GetGameObjectIfCanInteractWith(guid))
322 {
323 if (go->AI()->OnReportUse(_player))
324 return;
325
327 }
328}
329
331{
332 uint32 spellId;
333 uint8 castCount, castFlags;
334 recvPacket >> castCount >> spellId >> castFlags;
335 TriggerCastFlags triggerFlag = TRIGGERED_NONE;
336
337 TC_LOG_DEBUG("network", "WORLD: got cast spell packet, castCount: {}, spellId: {}, castFlags: {}, data length = {}", castCount, spellId, castFlags, (uint32)recvPacket.size());
338
339 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
340 if (!spellInfo)
341 {
342 TC_LOG_ERROR("network", "WORLD: unknown spell id {}", spellId);
343 recvPacket.rfinish(); // prevent spam at ignore packet
344 return;
345 }
346
347 if (spellInfo->IsPassive())
348 {
349 recvPacket.rfinish(); // prevent spam at ignore packet
350 return;
351 }
352
353 // client provided targets
354 SpellCastTargets targets;
355 targets.Read(recvPacket, _player);
356 HandleClientCastFlags(recvPacket, castFlags, targets);
357
358 // not have spell in spellbook
359 if (!_player->HasActiveSpell(spellId))
360 {
361 bool allow = false;
362
363 // allow casting of unknown spells for special lock cases
364 if (GameObject* go = targets.GetGOTarget())
365 if (go->GetSpellForLock(_player) == spellInfo)
366 allow = true;
367
368 // allow casting of spells triggered by clientside periodic trigger auras
370 {
371 allow = true;
372 triggerFlag = TRIGGERED_FULL_MASK;
373 }
374
375 if (!allow)
376 return;
377 }
378
379 // Client is resending autoshot cast opcode when other spell is cast during shoot rotation
380 // Skip it to prevent "interrupt" message
381 // Also check targets! target may have changed and we need to interrupt current spell
382 if (spellInfo->IsAutoRepeatRangedSpell())
383 {
385 {
386 if (spell->m_spellInfo == spellInfo && spell->m_targets.GetUnitTargetGUID() == targets.GetUnitTargetGUID())
387 {
388 recvPacket.rfinish();
389 return;
390 }
391 }
392 }
393
394 // auto-selection buff level base at target level (in spellInfo)
395 // TODO: is this even necessary? client already seems to send correct rank for "standard" buffs
396 if (spellInfo->IsPositive())
397 if (Unit* target = targets.GetUnitTarget())
398 {
399 SpellInfo const* actualSpellInfo = spellInfo->GetAuraRankForLevel(target->GetLevel());
400
401 // if rank not found then function return NULL but in explicit cast case original spell can be cast and later failed with appropriate error message
402 if (actualSpellInfo)
403 spellInfo = actualSpellInfo;
404 }
405
406 Spell* spell = new Spell(_player, spellInfo, triggerFlag);
407 spell->m_fromClient = true;
408 spell->m_cast_count = castCount; // set count of casts
409 spell->prepare(targets);
410}
411
413{
414 if (_player->IsCharmed())
415 return;
416
417 if (_player->IsNonMeleeSpellCast(false))
418 _player->InterruptNonMeleeSpells(false, cancelCast.SpellID, false);
419}
420
422{
423 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(cancelAura.SpellID);
424 if (!spellInfo)
425 return;
426
427 // not allow remove spells with attr SPELL_ATTR0_CANT_CANCEL
429 return;
430
431 // channeled spell case (it currently cast then)
432 if (spellInfo->IsChanneled())
433 {
435 if (curSpell->m_spellInfo->Id == cancelAura.SpellID)
437 return;
438 }
439
440 // non channeled case:
441 // don't allow remove non positive spells
442 // don't allow cancelling passive auras (some of them are visible)
443 if (!spellInfo->IsPositive() || spellInfo->IsPassive())
444 return;
445
446 // maybe should only remove one buff when there are multiple?
448
449 // If spell being removed is a resource tracker, see if player was tracking both (herbs / minerals) and remove the other
451 {
453 if (!auraEffects.empty())
454 {
455 // Build list of spell IDs to cancel. Trying to cancel the aura while iterating
456 // over AuraEffectList caused "incompatible iterator" errors on second pass
457 std::list<uint32> spellIDs;
458
459 for (Unit::AuraEffectList::const_iterator auraEffect = auraEffects.begin(); auraEffect != auraEffects.end(); ++auraEffect)
460 spellIDs.push_back((*auraEffect)->GetId());
461
462 // Remove all auras related to resource tracking (only Herbs and Minerals in 3.3.5a)
463 for (std::list<uint32>::iterator it = spellIDs.begin(); it != spellIDs.end(); ++it)
465 }
466 }
467}
468
470{
471 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(packet.SpellID);
472 if (!spellInfo)
473 {
474 TC_LOG_ERROR("network", "WORLD: unknown PET spell id {}", packet.SpellID);
475 return;
476 }
477
479
480 if (!pet)
481 {
482 TC_LOG_ERROR("network", "HandlePetCancelAura: Attempt to cancel an aura for non-existant {} by player '{}'", packet.PetGUID.ToString(), GetPlayer()->GetName());
483 return;
484 }
485
486 if (pet != GetPlayer()->GetGuardianPet() && pet != GetPlayer()->GetCharmed())
487 {
488 TC_LOG_ERROR("network", "HandlePetCancelAura: {} is not a pet of player '{}'", packet.PetGUID.ToString(), GetPlayer()->GetName());
489 return;
490 }
491
492 if (!pet->IsAlive())
493 {
495 return;
496 }
497
499}
500
502{
504 {
505 SpellInfo const* spellInfo = aurApp->GetBase()->GetSpellInfo();
506 return !spellInfo->HasAttribute(SPELL_ATTR0_CANT_CANCEL) && spellInfo->IsPositive() && !spellInfo->IsPassive();
507 });
508}
509
511{
513 {
514 SpellInfo const* spellInfo = aurApp->GetBase()->GetSpellInfo();
515 return !spellInfo->HasAttribute(SPELL_ATTR0_CANT_CANCEL) && spellInfo->IsPositive() && !spellInfo->IsPassive();
516 });
517}
518
520{
521 // may be better send SMSG_CANCEL_AUTO_REPEAT?
522 // cancel and prepare for deleting
524}
525
527{
529
530 // ignore for remote control state (for player case)
531 if (!mover)
532 return;
533
534 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(cancelChanneling.ChannelSpell);
535 if (!spellInfo)
536 return;
537
538 // not allow remove spells with attr SPELL_ATTR0_CANT_CANCEL
540 return;
541
543 if (!spell || spell->GetSpellInfo()->Id != spellInfo->Id)
544 return;
545
547}
548
550{
551 // ignore for remote control state
552 if (_player->IsCharmed())
553 return;
554
555 uint8 slotId = totemDestroyed.Slot;
556 slotId += SUMMON_SLOT_TOTEM_FIRE;
557
558 if (slotId >= MAX_TOTEM_SLOT)
559 return;
560
561 if (!_player->m_SummonSlot[slotId])
562 return;
563
565 if (totem && totem->IsTotem())
566 totem->ToTotem()->UnSummon();
567}
568
570{
571 TC_LOG_DEBUG("network", "WORLD: CMSG_SELF_RES"); // empty opcode
572
573 if (SpellInfo const* spell = sSpellMgr->GetSpellInfo(_player->GetUInt32Value(PLAYER_SELF_RES_SPELL)))
574 {
576 return; // silent return, client should display error by itself and not send this opcode
577
578 _player->CastSpell(_player, spell->Id);
580 }
581}
582
584{
585 ObjectGuid guid;
586 recvData >> guid;
587
588 // this will get something not in world. crash
590
591 if (!unit)
592 return;
593
595 if (!unit->IsInWorld())
596 return;
597
599}
600
602{
603 TC_LOG_DEBUG("network", "WORLD: CMSG_GET_MIRRORIMAGE_DATA");
604 ObjectGuid guid;
605 recvData >> guid;
606
607 // Get unit for which data is needed by client
608 Unit* unit = ObjectAccessor::GetUnit(*_player, guid);
609 if (!unit)
610 return;
611
613 return;
614
615 // Get creator of the unit (SPELL_AURA_CLONE_CASTER does not stack)
616 Unit* creator = unit->GetAuraEffectsByType(SPELL_AURA_CLONE_CASTER).front()->GetCaster();
617 if (!creator)
618 return;
619
621 data << guid;
622 data << uint32(creator->GetDisplayId());
623 data << uint8(creator->GetRace());
624 data << uint8(creator->GetGender());
625 data << uint8(creator->GetClass());
626
627 if (Player* player = creator->ToPlayer())
628 {
629 data << uint8(player->GetSkinId());
630 data << uint8(player->GetFaceId());
631 data << uint8(player->GetHairStyleId());
632 data << uint8(player->GetHairColorId());
633 data << uint8(player->GetFacialStyle());
634 data << uint32(player->GetGuildId());
635
636 static EquipmentSlots const itemSlots[] =
637 {
650 };
651
652 // Display items in visible slots
653 for (EquipmentSlots const* itr = &itemSlots[0]; *itr != EQUIPMENT_SLOT_END; ++itr)
654 {
655 if (*itr == EQUIPMENT_SLOT_HEAD && player->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_HIDE_HELM))
656 data << uint32(0);
657 else if (*itr == EQUIPMENT_SLOT_BACK && player->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_HIDE_CLOAK))
658 data << uint32(0);
659 else if (Item const* item = player->GetItemByPos(INVENTORY_SLOT_BAG_0, *itr))
660 data << uint32(item->GetTemplate()->DisplayInfoID);
661 else
662 data << uint32(0);
663 }
664 }
665 else
666 {
667 // Skip player data for creatures
668 data << uint8(0);
669 data << uint32(0);
670 data << uint32(0);
671 data << uint32(0);
672 data << uint32(0);
673 data << uint32(0);
674 data << uint32(0);
675 data << uint32(0);
676 data << uint32(0);
677 data << uint32(0);
678 data << uint32(0);
679 data << uint32(0);
680 data << uint32(0);
681 data << uint32(0);
682 }
683
684 SendPacket(&data);
685}
686
688{
689 TC_LOG_DEBUG("network", "WORLD: CMSG_UPDATE_PROJECTILE_POSITION");
690
691 ObjectGuid casterGuid;
692 uint32 spellId;
693 uint8 castCount;
694 float x, y, z; // Position of missile hit
695
696 recvPacket >> casterGuid;
697 recvPacket >> spellId;
698 recvPacket >> castCount;
699 recvPacket >> x;
700 recvPacket >> y;
701 recvPacket >> z;
702
703 Unit* caster = ObjectAccessor::GetUnit(*_player, casterGuid);
704 if (!caster)
705 return;
706
707 Spell* spell = caster->FindCurrentSpellBySpellId(spellId);
708 if (!spell || !spell->m_targets.HasDst())
709 return;
710
711 Position pos = *spell->m_targets.GetDstPos();
712 pos.Relocate(x, y, z);
713 spell->m_targets.ModDst(pos);
714
715 // we changed dest, recalculate flight time
717
719 data << casterGuid;
720 data << uint8(castCount);
721 data << float(x);
722 data << float(y);
723 data << float(z);
724 caster->SendMessageToSet(&data, true);
725}
@ CHAR_DEL_GIFT
@ CHAR_SEL_CHARACTER_GIFT_BY_ITEM
@ ACHIEVEMENT_CRITERIA_TYPE_USE_GAMEOBJECT
Definition DBCEnums.h:192
DBCStorage< LockEntry > sLockStore(LockEntryfmt)
SQLTransaction< CharacterDatabaseConnection > CharacterDatabaseTransaction
std::shared_ptr< PreparedResultSet > PreparedQueryResult
DatabaseWorkerPool< CharacterDatabaseConnection > CharacterDatabase
Accessor to the character database.
uint8_t uint8
Definition Define.h:135
uint16_t uint16
Definition Define.h:134
uint32_t uint32
Definition Define.h:133
uint16 flags
InventoryResult
Definition ItemDefines.h:25
@ EQUIP_ERR_NOT_DURING_ARENA_MATCH
@ EQUIP_ERR_PLAYER_DEAD
Definition ItemDefines.h:64
@ EQUIP_ERR_CLIENT_LOCKED_OUT
Definition ItemDefines.h:65
@ EQUIP_ERR_NOT_IN_COMBAT
Definition ItemDefines.h:86
@ EQUIP_ERR_ITEM_LOCKED
Definition ItemDefines.h:62
@ EQUIP_ERR_ITEM_NOT_FOUND
Definition ItemDefines.h:49
@ EQUIP_ERR_OK
Definition ItemDefines.h:26
@ ITEM_CLASS_CONSUMABLE
@ ITEM_FLAG_IGNORE_DEFAULT_ARENA_RESTRICTIONS
@ ITEM_FLAG_HAS_LOOT
@ ITEM_FLAG_NOT_USEABLE_IN_ARENA
@ BIND_WHEN_USE
@ BIND_QUEST_ITEM
@ BIND_WHEN_PICKED_UP
@ INVTYPE_NON_EQUIP
@ ITEM_CHANGED
Definition Item.h:54
#define TC_LOG_DEBUG(filterType__,...)
Definition Log.h:156
#define TC_LOG_ERROR(filterType__,...)
Definition Log.h:165
#define TC_LOG_INFO(filterType__,...)
Definition Log.h:159
@ LOOT_CORPSE
Definition Loot.h:84
EquipmentSlots
Definition Player.h:550
@ EQUIPMENT_SLOT_SHOULDERS
Definition Player.h:554
@ EQUIPMENT_SLOT_BODY
Definition Player.h:555
@ EQUIPMENT_SLOT_HANDS
Definition Player.h:561
@ EQUIPMENT_SLOT_TABARD
Definition Player.h:570
@ EQUIPMENT_SLOT_END
Definition Player.h:571
@ EQUIPMENT_SLOT_HEAD
Definition Player.h:552
@ EQUIPMENT_SLOT_LEGS
Definition Player.h:558
@ EQUIPMENT_SLOT_BACK
Definition Player.h:566
@ EQUIPMENT_SLOT_WAIST
Definition Player.h:557
@ EQUIPMENT_SLOT_FEET
Definition Player.h:559
@ EQUIPMENT_SLOT_CHEST
Definition Player.h:556
@ EQUIPMENT_SLOT_WRISTS
Definition Player.h:560
@ PLAYER_FLAGS_HIDE_CLOAK
Definition Player.h:355
@ PLAYER_FLAGS_HIDE_HELM
Definition Player.h:354
#define INVENTORY_SLOT_BAG_0
Definition Player.h:547
#define sScriptMgr
Definition ScriptMgr.h:1168
@ SPELL_ATTR7_BYPASS_NO_RESURRECT_AURA
#define MAX_GLYPH_SLOT_INDEX
@ SPELL_ATTR0_CANT_CANCEL
#define MAX_TOTEM_SLOT
@ SUMMON_SLOT_TOTEM_FIRE
@ AURA_REMOVE_BY_CANCEL
@ SPELL_AURA_PREVENT_RESURRECTION
@ SPELL_AURA_CLONE_CASTER
@ SPELL_AURA_TRACK_RESOURCES
@ SPELL_AURA_MOUNTED
@ SPELL_AURA_MOD_SCALE
@ SPELL_AURA_PERIODIC_TRIGGER_SPELL_FROM_CLIENT
TriggerCastFlags
@ TRIGGERED_FULL_MASK
Will return SPELL_FAILED_DONT_REPORT in CheckCast functions.
@ TRIGGERED_NONE
#define sSpellMgr
Definition SpellMgr.h:738
@ CURRENT_CHANNELED_SPELL
Definition Unit.h:608
@ CURRENT_AUTOREPEAT_SPELL
Definition Unit.h:609
@ PLAYER_FLAGS
@ PLAYER_SELF_RES_SPELL
@ ITEM_FIELD_FLAGS
@ ITEM_FIELD_MAXDURABILITY
@ ITEM_FIELD_GIFTCREATOR
Aura * GetBase() const
Definition SpellAuras.h:67
void rfinish()
Definition ByteBuffer.h:316
size_t size() const
Definition ByteBuffer.h:409
Class used to access individual fields of database query result.
Definition Field.h:92
uint32 GetUInt32() const
Definition Field.cpp:61
Unit * GetActivelyMovedUnit() const
Definition GameClient.h:37
Definition Item.h:62
void SetState(ItemUpdateState state, Player *forplayer=nullptr)
Definition Item.cpp:638
uint8 GetSlot() const
Definition Item.h:126
bool IsWrapped() const
Definition Item.h:100
void SetBinding(bool val)
Definition Item.h:80
bool IsLocked() const
Definition Item.h:101
ItemTemplate const * GetTemplate() const
Definition Item.cpp:535
bool IsSoulBound() const
Definition Item.h:81
bool IsEquipped() const
Definition Item.cpp:716
uint16 GetPos() const
Definition Item.h:130
uint8 GetBagSlot() const
Definition Item.cpp:711
LowType GetCounter() const
Definition ObjectGuid.h:156
static ObjectGuid const Empty
Definition ObjectGuid.h:140
std::string ToString() const
PackedGuidReader ReadAsPacked()
Definition ObjectGuid.h:146
uint32 GetUInt32Value(uint16 index) const
Definition Object.cpp:249
bool IsInWorld() const
Definition Object.h:73
void SetGuidValue(uint16 index, ObjectGuid value)
Definition Object.cpp:699
uint32 GetEntry() const
Definition Object.h:81
static ObjectGuid GetGUID(Object const *o)
Definition Object.h:78
void SetEntry(uint32 entry)
Definition Object.h:82
void SetUInt32Value(uint16 index, uint32 value)
Definition Object.cpp:585
static Player * ToPlayer(Object *o)
Definition Object.h:180
Item * GetUseableItemByPos(uint8 bag, uint8 slot) const
Definition Player.cpp:9569
void SaveInventoryAndGoldToDB(CharacterDatabaseTransaction trans)
Definition Player.cpp:19311
void UpdateAchievementCriteria(AchievementCriteriaTypes type, uint32 miscValue1=0, uint32 miscValue2=0, WorldObject *ref=nullptr)
Definition Player.cpp:24940
bool HasActiveSpell(uint32 spell) const
Definition Player.cpp:3866
Item * GetItemByPos(uint16 pos) const
Definition Player.cpp:9552
void DestroyItem(uint8 bag, uint8 slot, bool update)
Definition Player.cpp:12113
void SendLoot(ObjectGuid guid, LootType loot_type)
Definition Player.cpp:8079
void CastItemUseSpell(Item *item, uint32 spellId, SpellCastTargets const &targets, uint8 cast_count, uint32 glyphIndex)
Definition Player.cpp:7825
void SendEquipError(InventoryResult msg, Item *pItem, Item *pItem2=nullptr, uint32 itemid=0) const
Definition Player.cpp:13075
bool InArena() const
Definition Player.cpp:23148
InventoryResult CanUseItem(Item *pItem, bool not_loading=true) const
Definition Player.cpp:11370
void setUInt32(uint8 index, uint32 value)
ObjectGuid GetUnitTargetGUID() const
Definition Spell.cpp:221
void ModDst(Position const &pos)
Definition Spell.cpp:414
GameObject * GetGOTarget() const
Definition Spell.cpp:255
void SetSpeed(float speed)
void Read(ByteBuffer &data, Unit *caster)
Definition Spell.cpp:130
bool HasDst() const
Definition Spell.cpp:436
void SetElevation(float elevation)
Unit * GetUnitTarget() const
Definition Spell.cpp:229
WorldLocation const * GetDstPos() const
Definition Spell.cpp:379
bool IsPassive() const
uint32 Id
Definition SpellInfo.h:289
SpellInfo const * GetAuraRankForLevel(uint8 level) const
bool IsChanneled() const
bool HasAttribute(SpellAttr0 attribute) const
Definition SpellInfo.h:375
bool IsPositive() const
bool IsAutoRepeatRangedSpell() const
bool HasAura(AuraType aura) const
Definition Spell.h:152
SpellInfo const * GetSpellInfo() const
Definition Spell.h:452
bool m_fromClient
Definition Spell.h:400
SpellCastTargets m_targets
Definition Spell.h:402
uint8 m_cast_count
Definition Spell.h:399
SpellCastResult prepare(SpellCastTargets const &targets, AuraEffect const *triggeredByAura=nullptr)
Definition Spell.cpp:3070
void RecalculateDelayMomentForDst()
Definition Spell.cpp:920
void UnSummon(uint32 msTime=0) override
Definition Totem.cpp:103
Definition Unit.h:769
bool IsCharmed() const
Definition Unit.h:1280
void RemoveOwnedAura(AuraMap::iterator &i, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition Unit.cpp:3561
void RemoveAurasByType(AuraType auraType, std::function< bool(AuraApplication const *)> const &check, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition Unit.cpp:3765
AuraEffectList const & GetAuraEffectsByType(AuraType type) const
Definition Unit.h:1384
uint8 GetClass() const
Definition Unit.h:895
void HandleSpellClick(Unit *clicker, int8 seatId=-1)
Definition Unit.cpp:12478
Spell * FindCurrentSpellBySpellId(uint32 spell_id) const
Definition Unit.cpp:3108
Totem * ToTotem()
Definition Unit.h:1791
void InterruptNonMeleeSpells(bool withDelayed, uint32 spellid=0, bool withInstant=true)
Definition Unit.cpp:3093
bool IsNonMeleeSpellCast(bool withDelayed, bool skipChanneled=false, bool skipAutorepeat=false, bool isAutoshoot=false, bool skipInstant=true) const
Definition Unit.cpp:3063
bool IsAlive() const
Definition Unit.h:1234
Gender GetGender() const
Definition Unit.h:898
uint32 GetDisplayId() const
Definition Unit.h:1582
void InterruptSpell(CurrentSpellTypes spellType, bool withDelayed=true, bool withInstant=true, SpellCastResult result=SPELL_FAILED_INTERRUPTED, Optional< SpellCastResult > resultOther={})
Definition Unit.cpp:3021
bool HasAuraType(AuraType auraType) const
Definition Unit.cpp:4542
bool HasAuraTypeWithTriggerSpell(AuraType auratype, uint32 triggerSpell) const
Definition Unit.cpp:4582
std::list< AuraEffect * > AuraEffectList
Definition Unit.h:787
bool IsTotem() const
Definition Unit.h:886
void SendPetActionFeedback(PetActionFeedback msg, uint32 spellId) const
-------—Pet responses methods--------------—
Definition Unit.cpp:10256
ObjectGuid m_SummonSlot[MAX_SUMMON_SLOT]
Definition Unit.h:1487
uint8 GetRace() const
Definition Unit.h:892
bool IsInCombat() const
Definition Unit.h:1144
Spell * GetCurrentSpell(CurrentSpellTypes spellType) const
Definition Unit.h:1476
virtual void SendMessageToSet(WorldPacket const *data, bool self) const
Definition Object.cpp:1783
SpellCastResult CastSpell(CastSpellTargetArg const &targets, uint32 spellId, CastSpellExtraArgs const &args={ })
Definition Object.cpp:2832
std::string const & GetName() const
Definition Object.h:382
void HandleMovementOpcode(OpcodeClient opcode, MovementInfo &movementInfo)
void HandleCancelChanneling(WorldPackets::Spells::CancelChannelling &cancelChanneling)
void SendPacket(WorldPacket const *packet)
Send a packet to the client.
void HandleOpenItemOpcode(WorldPacket &recvPacket)
void HandleGameObjectUseOpcode(WorldPacket &recPacket)
QueryCallbackProcessor _queryProcessor
void HandleUpdateProjectilePosition(WorldPacket &recvPacket)
Player * GetPlayer() const
void HandleSelfResOpcode(WorldPacket &recvData)
void HandleCastSpellOpcode(WorldPacket &recvPacket)
void HandleMirrorImageDataRequest(WorldPacket &recvData)
void HandleGameobjectReportUse(WorldPacket &recvPacket)
Player * _player
void HandleCancelAutoRepeatSpellOpcode(WorldPackets::Spells::CancelAutoRepeatSpell &cancelAutoRepeatSpell)
void HandleCancelAuraOpcode(WorldPackets::Spells::CancelAura &cancelAura)
void HandleOpenWrappedItemCallback(uint16 pos, ObjectGuid itemGuid, PreparedQueryResult result)
void HandleCancelMountAuraOpcode(WorldPackets::Spells::CancelMountAura &cancelMountAura)
void HandleTotemDestroyed(WorldPackets::Totem::TotemDestroyed &totemDestroyed)
void HandleUseItemOpcode(WorldPacket &recvPacket)
void HandleClientCastFlags(WorldPacket &recvPacket, uint8 castFlags, SpellCastTargets &targets)
GameClient * GetGameClient() const
void HandleSpellClick(WorldPacket &recvData)
void HandleCancelGrowthAuraOpcode(WorldPackets::Spells::CancelGrowthAura &cancelGrowthAura)
void HandleCancelCastOpcode(WorldPackets::Spells::CancelCast &cancelCast)
void HandlePetCancelAuraOpcode(WorldPackets::Spells::PetCancelAura &packet)
Opcodes
Definition Opcodes.h:29
@ SMSG_SET_PROJECTILE_POSITION
Definition Opcodes.h:1244
@ SMSG_MIRRORIMAGE_DATA
Definition Opcodes.h:1055
#define sWorld
Definition World.h:900
@ CONFIG_ALLOW_TRACK_BOTH_RESOURCES
Definition World.h:162
TC_GAME_API Unit * GetUnit(WorldObject const &, ObjectGuid const &guid)
TC_GAME_API Creature * GetCreature(WorldObject const &u, ObjectGuid const &guid)
TC_GAME_API Creature * GetCreatureOrPetOrVehicle(WorldObject const &, ObjectGuid const &)
std::array< ItemEffect, MAX_ITEM_PROTO_SPELLS > Effects
bool HasFlag(ItemFlags flag) const
uint32 MaxDurability
uint32 InventoryType
ObjectGuid guid
void Relocate(float x, float y)
Definition Position.h:66