TrinityCore
Loading...
Searching...
No Matches
SpellEffects.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 "Spell.h"
19#include "AccountMgr.h"
20#include "AreaTrigger.h"
22#include "AzeriteItem.h"
23#include "Battleground.h"
24#include "BattlegroundMgr.h"
25#include "BattlePetMgr.h"
26#include "CellImpl.h"
27#include "CharmInfo.h"
28#include "CombatLogPackets.h"
29#include "CombatPackets.h"
30#include "Common.h"
31#include "Conversation.h"
32#include "Creature.h"
33#include "CreatureAI.h"
34#include "CreatureTextMgr.h"
35#include "DatabaseEnv.h"
36#include "DB2Stores.h"
37#include "DuelPackets.h"
38#include "DynamicObject.h"
39#include "GameEventSender.h"
40#include "GameObject.h"
41#include "GameObjectAI.h"
42#include "GameTime.h"
43#include "Garrison.h"
44#include "GossipDef.h"
45#include "GridNotifiers.h"
46#include "GridNotifiersImpl.h"
47#include "Group.h"
48#include "Guild.h"
49#include "InstanceScript.h"
50#include "Item.h"
51#include "Language.h"
52#include "Log.h"
53#include "Loot.h"
54#include "LootMgr.h"
55#include "Map.h"
56#include "MiscPackets.h"
57#include "MotionMaster.h"
58#include "MoveSpline.h"
59#include "ObjectAccessor.h"
60#include "ObjectMgr.h"
61#include "OutdoorPvPMgr.h"
62#include "PathGenerator.h"
63#include "Pet.h"
64#include "PhasingHandler.h"
65#include "Player.h"
66#include "QuestMgr.h"
67#include "ReputationMgr.h"
68#include "RestMgr.h"
69#include "SceneObject.h"
70#include "ScriptMgr.h"
71#include "SharedDefines.h"
72#include "SkillExtraItems.h"
73#include "SocialMgr.h"
74#include "SpellAuraEffects.h"
75#include "SpellAuras.h"
76#include "SpellHistory.h"
77#include "SpellMgr.h"
78#include "SpellPackets.h"
79#include "TalentPackets.h"
80#include "TemporarySummon.h"
81#include "Totem.h"
82#include "TraitMgr.h"
83#include "TraitPacketsCommon.h"
84#include "Unit.h"
85#include "Util.h"
86#include "World.h"
87#include "WorldPacket.h"
88#include "WorldSession.h"
89
91{
93 &Spell::EffectInstaKill, // 1 SPELL_EFFECT_INSTAKILL
94 &Spell::EffectSchoolDMG, // 2 SPELL_EFFECT_SCHOOL_DAMAGE
95 &Spell::EffectDummy, // 3 SPELL_EFFECT_DUMMY
96 &Spell::EffectUnused, // 4 SPELL_EFFECT_PORTAL_TELEPORT unused
97 &Spell::EffectNULL, // 5 SPELL_EFFECT_5
98 &Spell::EffectApplyAura, // 6 SPELL_EFFECT_APPLY_AURA
99 &Spell::EffectEnvironmentalDMG, // 7 SPELL_EFFECT_ENVIRONMENTAL_DAMAGE
100 &Spell::EffectPowerDrain, // 8 SPELL_EFFECT_POWER_DRAIN
101 &Spell::EffectHealthLeech, // 9 SPELL_EFFECT_HEALTH_LEECH
102 &Spell::EffectHeal, // 10 SPELL_EFFECT_HEAL
103 &Spell::EffectBind, // 11 SPELL_EFFECT_BIND
104 &Spell::EffectNULL, // 12 SPELL_EFFECT_PORTAL
105 &Spell::EffectTeleportToReturnPoint, // 13 SPELL_EFFECT_TELEPORT_TO_RETURN_POINT
106 &Spell::EffectIncreaseCurrencyCap, // 14 SPELL_EFFECT_INCREASE_CURRENCY_CAP
107 &Spell::EffectTeleportUnitsWithVisualLoadingScreen, // 15 SPELL_EFFECT_TELEPORT_WITH_SPELL_VISUAL_KIT_LOADING_SCREEN
108 &Spell::EffectQuestComplete, // 16 SPELL_EFFECT_QUEST_COMPLETE
109 &Spell::EffectWeaponDmg, // 17 SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL
110 &Spell::EffectResurrect, // 18 SPELL_EFFECT_RESURRECT
111 &Spell::EffectAddExtraAttacks, // 19 SPELL_EFFECT_ADD_EXTRA_ATTACKS
112 &Spell::EffectUnused, // 20 SPELL_EFFECT_DODGE one spell: Dodge
113 &Spell::EffectUnused, // 21 SPELL_EFFECT_EVADE one spell: Evade (DND)
114 &Spell::EffectParry, // 22 SPELL_EFFECT_PARRY
115 &Spell::EffectBlock, // 23 SPELL_EFFECT_BLOCK one spell: Block
116 &Spell::EffectCreateItem, // 24 SPELL_EFFECT_CREATE_ITEM
117 &Spell::EffectUnused, // 25 SPELL_EFFECT_WEAPON
118 &Spell::EffectUnused, // 26 SPELL_EFFECT_DEFENSE one spell: Defense
119 &Spell::EffectPersistentAA, // 27 SPELL_EFFECT_PERSISTENT_AREA_AURA
120 &Spell::EffectSummonType, // 28 SPELL_EFFECT_SUMMON
121 &Spell::EffectLeap, // 29 SPELL_EFFECT_LEAP
122 &Spell::EffectEnergize, // 30 SPELL_EFFECT_ENERGIZE
123 &Spell::EffectWeaponDmg, // 31 SPELL_EFFECT_WEAPON_PERCENT_DAMAGE
124 &Spell::EffectTriggerMissileSpell, // 32 SPELL_EFFECT_TRIGGER_MISSILE
125 &Spell::EffectOpenLock, // 33 SPELL_EFFECT_OPEN_LOCK
126 &Spell::EffectSummonChangeItem, // 34 SPELL_EFFECT_SUMMON_CHANGE_ITEM
127 &Spell::EffectUnused, // 35 SPELL_EFFECT_APPLY_AREA_AURA_PARTY
128 &Spell::EffectLearnSpell, // 36 SPELL_EFFECT_LEARN_SPELL
129 &Spell::EffectUnused, // 37 SPELL_EFFECT_SPELL_DEFENSE one spell: SPELLDEFENSE (DND)
130 &Spell::EffectDispel, // 38 SPELL_EFFECT_DISPEL
131 &Spell::EffectUnused, // 39 SPELL_EFFECT_LANGUAGE
132 &Spell::EffectDualWield, // 40 SPELL_EFFECT_DUAL_WIELD
133 &Spell::EffectJump, // 41 SPELL_EFFECT_JUMP
134 &Spell::EffectJumpDest, // 42 SPELL_EFFECT_JUMP_DEST
135 &Spell::EffectTeleUnitsFaceCaster, // 43 SPELL_EFFECT_TELEPORT_UNITS_FACE_CASTER
136 &Spell::EffectLearnSkill, // 44 SPELL_EFFECT_SKILL_STEP
137 &Spell::EffectPlayMovie, // 45 SPELL_EFFECT_PLAY_MOVIE
138 &Spell::EffectUnused, // 46 SPELL_EFFECT_SPAWN clientside, unit appears as if it was just spawned
139 &Spell::EffectTradeSkill, // 47 SPELL_EFFECT_TRADE_SKILL
140 &Spell::EffectUnused, // 48 SPELL_EFFECT_STEALTH one spell: Base Stealth
141 &Spell::EffectUnused, // 49 SPELL_EFFECT_DETECT one spell: Detect
142 &Spell::EffectTransmitted, // 50 SPELL_EFFECT_TRANS_DOOR
143 &Spell::EffectUnused, // 51 SPELL_EFFECT_FORCE_CRITICAL_HIT unused
144 &Spell::EffectNULL, // 52 SPELL_EFFECT_SET_MAX_BATTLE_PET_COUNT
145 &Spell::EffectEnchantItemPerm, // 53 SPELL_EFFECT_ENCHANT_ITEM
146 &Spell::EffectEnchantItemTmp, // 54 SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY
147 &Spell::EffectTameCreature, // 55 SPELL_EFFECT_TAMECREATURE
148 &Spell::EffectSummonPet, // 56 SPELL_EFFECT_SUMMON_PET
149 &Spell::EffectLearnPetSpell, // 57 SPELL_EFFECT_LEARN_PET_SPELL
150 &Spell::EffectWeaponDmg, // 58 SPELL_EFFECT_WEAPON_DAMAGE
151 &Spell::EffectCreateRandomItem, // 59 SPELL_EFFECT_CREATE_RANDOM_ITEM create item base at spell specific loot
152 &Spell::EffectProficiency, // 60 SPELL_EFFECT_PROFICIENCY
153 &Spell::EffectSendEvent, // 61 SPELL_EFFECT_SEND_EVENT
154 &Spell::EffectPowerBurn, // 62 SPELL_EFFECT_POWER_BURN
155 &Spell::EffectThreat, // 63 SPELL_EFFECT_THREAT
156 &Spell::EffectTriggerSpell, // 64 SPELL_EFFECT_TRIGGER_SPELL
157 &Spell::EffectUnused, // 65 SPELL_EFFECT_APPLY_AREA_AURA_RAID
158 &Spell::EffectRechargeItem, // 66 SPELL_EFFECT_RECHARGE_ITEM
159 &Spell::EffectHealMaxHealth, // 67 SPELL_EFFECT_HEAL_MAX_HEALTH
160 &Spell::EffectInterruptCast, // 68 SPELL_EFFECT_INTERRUPT_CAST
161 &Spell::EffectDistract, // 69 SPELL_EFFECT_DISTRACT
162 &Spell::EffectNULL, // 70 SPELL_EFFECT_COMPLETE_AND_REWARD_WORLD_QUEST
163 &Spell::EffectPickPocket, // 71 SPELL_EFFECT_PICKPOCKET
164 &Spell::EffectAddFarsight, // 72 SPELL_EFFECT_ADD_FARSIGHT
165 &Spell::EffectUntrainTalents, // 73 SPELL_EFFECT_UNTRAIN_TALENTS
166 &Spell::EffectApplyGlyph, // 74 SPELL_EFFECT_APPLY_GLYPH
167 &Spell::EffectHealMechanical, // 75 SPELL_EFFECT_HEAL_MECHANICAL one spell: Mechanical Patch Kit
168 &Spell::EffectSummonObjectWild, // 76 SPELL_EFFECT_SUMMON_OBJECT_WILD
169 &Spell::EffectScriptEffect, // 77 SPELL_EFFECT_SCRIPT_EFFECT
170 &Spell::EffectUnused, // 78 SPELL_EFFECT_ATTACK
171 &Spell::EffectSanctuary, // 79 SPELL_EFFECT_SANCTUARY
172 &Spell::EffectNULL, // 80 SPELL_EFFECT_MODIFY_FOLLOWER_ITEM_LEVEL
173 &Spell::EffectNULL, // 81 SPELL_EFFECT_PUSH_ABILITY_TO_ACTION_BAR
174 &Spell::EffectNULL, // 82 SPELL_EFFECT_BIND_SIGHT
175 &Spell::EffectDuel, // 83 SPELL_EFFECT_DUEL
176 &Spell::EffectStuck, // 84 SPELL_EFFECT_STUCK
177 &Spell::EffectSummonPlayer, // 85 SPELL_EFFECT_SUMMON_PLAYER
178 &Spell::EffectActivateObject, // 86 SPELL_EFFECT_ACTIVATE_OBJECT
179 &Spell::EffectGameObjectDamage, // 87 SPELL_EFFECT_GAMEOBJECT_DAMAGE
180 &Spell::EffectGameObjectRepair, // 88 SPELL_EFFECT_GAMEOBJECT_REPAIR
181 &Spell::EffectGameObjectSetDestructionState, // 89 SPELL_EFFECT_GAMEOBJECT_SET_DESTRUCTION_STATE
182 &Spell::EffectKillCreditPersonal, // 90 SPELL_EFFECT_KILL_CREDIT Kill credit but only for single person
183 &Spell::EffectNULL, // 91 SPELL_EFFECT_THREAT_ALL
184 &Spell::EffectEnchantHeldItem, // 92 SPELL_EFFECT_ENCHANT_HELD_ITEM
185 &Spell::EffectForceDeselect, // 93 SPELL_EFFECT_FORCE_DESELECT
186 &Spell::EffectSelfResurrect, // 94 SPELL_EFFECT_SELF_RESURRECT
187 &Spell::EffectSkinning, // 95 SPELL_EFFECT_SKINNING
188 &Spell::EffectCharge, // 96 SPELL_EFFECT_CHARGE
189 &Spell::EffectCastButtons, // 97 SPELL_EFFECT_CAST_BUTTON (totem bar since 3.2.2a)
190 &Spell::EffectKnockBack, // 98 SPELL_EFFECT_KNOCK_BACK
191 &Spell::EffectDisEnchant, // 99 SPELL_EFFECT_DISENCHANT
192 &Spell::EffectInebriate, //100 SPELL_EFFECT_INEBRIATE
193 &Spell::EffectFeedPet, //101 SPELL_EFFECT_FEED_PET
194 &Spell::EffectDismissPet, //102 SPELL_EFFECT_DISMISS_PET
195 &Spell::EffectReputation, //103 SPELL_EFFECT_REPUTATION
196 &Spell::EffectSummonObject, //104 SPELL_EFFECT_SUMMON_OBJECT_SLOT1
197 &Spell::EffectNULL, //105 SPELL_EFFECT_SURVEY
198 &Spell::EffectChangeRaidMarker, //106 SPELL_EFFECT_CHANGE_RAID_MARKER
199 &Spell::EffectNULL, //107 SPELL_EFFECT_SHOW_CORPSE_LOOT
200 &Spell::EffectDispelMechanic, //108 SPELL_EFFECT_DISPEL_MECHANIC
201 &Spell::EffectResurrectPet, //109 SPELL_EFFECT_RESURRECT_PET
202 &Spell::EffectDestroyAllTotems, //110 SPELL_EFFECT_DESTROY_ALL_TOTEMS
203 &Spell::EffectDurabilityDamage, //111 SPELL_EFFECT_DURABILITY_DAMAGE
204 &Spell::EffectNULL, //112 SPELL_EFFECT_112
205 &Spell::EffectCancelConversation, //113 SPELL_EFFECT_CANCEL_CONVERSATION
206 &Spell::EffectTaunt, //114 SPELL_EFFECT_ATTACK_ME
207 &Spell::EffectDurabilityDamagePCT, //115 SPELL_EFFECT_DURABILITY_DAMAGE_PCT
208 &Spell::EffectSkinPlayerCorpse, //116 SPELL_EFFECT_SKIN_PLAYER_CORPSE one spell: Remove Insignia, bg usage, required special corpse flags...
209 &Spell::EffectSpiritHeal, //117 SPELL_EFFECT_SPIRIT_HEAL one spell: Spirit Heal
210 &Spell::EffectSkill, //118 SPELL_EFFECT_SKILL professions and more
211 &Spell::EffectUnused, //119 SPELL_EFFECT_APPLY_AREA_AURA_PET
212 &Spell::EffectTeleportGraveyard, //120 SPELL_EFFECT_TELEPORT_GRAVEYARD
213 &Spell::EffectWeaponDmg, //121 SPELL_EFFECT_NORMALIZED_WEAPON_DMG
214 &Spell::EffectUnused, //122 SPELL_EFFECT_122 unused
215 &Spell::EffectSendTaxi, //123 SPELL_EFFECT_SEND_TAXI taxi/flight related (misc value is taxi path id)
216 &Spell::EffectPullTowards, //124 SPELL_EFFECT_PULL_TOWARDS
217 &Spell::EffectModifyThreatPercent, //125 SPELL_EFFECT_MODIFY_THREAT_PERCENT
218 &Spell::EffectStealBeneficialBuff, //126 SPELL_EFFECT_STEAL_BENEFICIAL_BUFF spell steal effect?
219 &Spell::EffectProspecting, //127 SPELL_EFFECT_PROSPECTING Prospecting spell
220 &Spell::EffectUnused, //128 SPELL_EFFECT_APPLY_AREA_AURA_FRIEND
221 &Spell::EffectUnused, //129 SPELL_EFFECT_APPLY_AREA_AURA_ENEMY
222 &Spell::EffectRedirectThreat, //130 SPELL_EFFECT_REDIRECT_THREAT
223 &Spell::EffectPlaySound, //131 SPELL_EFFECT_PLAY_SOUND sound id in misc value (SoundEntries.dbc)
224 &Spell::EffectPlayMusic, //132 SPELL_EFFECT_PLAY_MUSIC sound id in misc value (SoundEntries.dbc)
225 &Spell::EffectUnlearnSpecialization, //133 SPELL_EFFECT_UNLEARN_SPECIALIZATION unlearn profession specialization
226 &Spell::EffectKillCredit, //134 SPELL_EFFECT_KILL_CREDIT misc value is creature entry
227 &Spell::EffectNULL, //135 SPELL_EFFECT_CALL_PET
228 &Spell::EffectHealPct, //136 SPELL_EFFECT_HEAL_PCT
229 &Spell::EffectEnergizePct, //137 SPELL_EFFECT_ENERGIZE_PCT
230 &Spell::EffectLeapBack, //138 SPELL_EFFECT_LEAP_BACK Leap back
231 &Spell::EffectQuestClear, //139 SPELL_EFFECT_CLEAR_QUEST Reset quest status (miscValue - quest ID)
232 &Spell::EffectForceCast, //140 SPELL_EFFECT_FORCE_CAST
233 &Spell::EffectForceCast, //141 SPELL_EFFECT_FORCE_CAST_WITH_VALUE
234 &Spell::EffectTriggerSpell, //142 SPELL_EFFECT_TRIGGER_SPELL_WITH_VALUE
235 &Spell::EffectUnused, //143 SPELL_EFFECT_APPLY_AREA_AURA_OWNER
236 &Spell::EffectKnockBack, //144 SPELL_EFFECT_KNOCK_BACK_DEST
237 &Spell::EffectPullTowardsDest, //145 SPELL_EFFECT_PULL_TOWARDS_DEST Black Hole Effect
238 &Spell::EffectNULL, //146 SPELL_EFFECT_RESTORE_GARRISON_TROOP_VITALITY
239 &Spell::EffectQuestFail, //147 SPELL_EFFECT_QUEST_FAIL quest fail
240 &Spell::EffectTriggerMissileSpell, //148 SPELL_EFFECT_TRIGGER_MISSILE_SPELL_WITH_VALUE
241 &Spell::EffectChargeDest, //149 SPELL_EFFECT_CHARGE_DEST
242 &Spell::EffectQuestStart, //150 SPELL_EFFECT_QUEST_START
243 &Spell::EffectTriggerRitualOfSummoning, //151 SPELL_EFFECT_TRIGGER_SPELL_2
244 &Spell::EffectSummonRaFFriend, //152 SPELL_EFFECT_SUMMON_RAF_FRIEND summon Refer-a-Friend
245 &Spell::EffectCreateTamedPet, //153 SPELL_EFFECT_CREATE_TAMED_PET misc value is creature entry
246 &Spell::EffectDiscoverTaxi, //154 SPELL_EFFECT_DISCOVER_TAXI
247 &Spell::EffectTitanGrip, //155 SPELL_EFFECT_TITAN_GRIP Allows you to equip two-handed axes, maces and swords in one hand, but you attack $49152s1% slower than normal.
248 &Spell::EffectEnchantItemPrismatic, //156 SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC
249 &Spell::EffectCreateItem2, //157 SPELL_EFFECT_CREATE_ITEM_2 create item or create item template and replace by some randon spell loot item
250 &Spell::EffectMilling, //158 SPELL_EFFECT_MILLING milling
251 &Spell::EffectRenamePet, //159 SPELL_EFFECT_ALLOW_RENAME_PET allow rename pet once again
252 &Spell::EffectForceCast2, //160 SPELL_EFFECT_FORCE_CAST_2
253 &Spell::EffectNULL, //161 SPELL_EFFECT_TALENT_SPEC_COUNT second talent spec (learn/revert)
254 &Spell::EffectActivateSpec, //162 SPELL_EFFECT_TALENT_SPEC_SELECT activate primary/secondary spec
255 &Spell::EffectNULL, //163 SPELL_EFFECT_OBLITERATE_ITEM
256 &Spell::EffectRemoveAura, //164 SPELL_EFFECT_REMOVE_AURA
257 &Spell::EffectDamageFromMaxHealthPCT, //165 SPELL_EFFECT_DAMAGE_FROM_MAX_HEALTH_PCT
258 &Spell::EffectGiveCurrency, //166 SPELL_EFFECT_GIVE_CURRENCY
259 &Spell::EffectUpdatePlayerPhase, //167 SPELL_EFFECT_UPDATE_PLAYER_PHASE
260 &Spell::EffectNULL, //168 SPELL_EFFECT_ALLOW_CONTROL_PET
261 &Spell::EffectDestroyItem, //169 SPELL_EFFECT_DESTROY_ITEM
262 &Spell::EffectUpdateZoneAurasAndPhases, //170 SPELL_EFFECT_UPDATE_ZONE_AURAS_AND_PHASES
263 &Spell::EffectSummonPersonalGameObject, //171 SPELL_EFFECT_SUMMON_PERSONAL_GAMEOBJECT
264 &Spell::EffectResurrectWithAura, //172 SPELL_EFFECT_RESURRECT_WITH_AURA
265 &Spell::EffectUnlockGuildVaultTab, //173 SPELL_EFFECT_UNLOCK_GUILD_VAULT_TAB
266 &Spell::EffectApplyAura, //174 SPELL_EFFECT_APPLY_AURA_ON_PET
267 &Spell::EffectNULL, //175 SPELL_EFFECT_175
268 &Spell::EffectSanctuary, //176 SPELL_EFFECT_SANCTUARY_2
269 &Spell::EffectNULL, //177 SPELL_EFFECT_DESPAWN_PERSISTENT_AREA_AURA
270 &Spell::EffectUnused, //178 SPELL_EFFECT_178 unused
271 &Spell::EffectCreateAreaTrigger, //179 SPELL_EFFECT_CREATE_AREATRIGGER
272 &Spell::EffectNULL, //180 SPELL_EFFECT_UPDATE_AREATRIGGER
273 &Spell::EffectRemoveTalent, //181 SPELL_EFFECT_REMOVE_TALENT
274 &Spell::EffectNULL, //182 SPELL_EFFECT_DESPAWN_AREATRIGGER
275 &Spell::EffectNULL, //183 SPELL_EFFECT_183
276 &Spell::EffectReputation, //184 SPELL_EFFECT_REPUTATION_2
277 &Spell::EffectNULL, //185 SPELL_EFFECT_185
278 &Spell::EffectNULL, //186 SPELL_EFFECT_186
279 &Spell::EffectNULL, //187 SPELL_EFFECT_RANDOMIZE_ARCHAEOLOGY_DIGSITES
280 &Spell::EffectNULL, //188 SPELL_EFFECT_SUMMON_STABLED_PET_AS_GUARDIAN
281 &Spell::EffectNULL, //189 SPELL_EFFECT_LOOT
282 &Spell::EffectNULL, //190 SPELL_EFFECT_CHANGE_PARTY_MEMBERS
283 &Spell::EffectNULL, //191 SPELL_EFFECT_TELEPORT_TO_DIGSITE
284 &Spell::EffectUncageBattlePet, //192 SPELL_EFFECT_UNCAGE_BATTLEPET
285 &Spell::EffectNULL, //193 SPELL_EFFECT_START_PET_BATTLE
286 &Spell::EffectUnused, //194 SPELL_EFFECT_194
287 &Spell::EffectPlaySceneScriptPackage, //195 SPELL_EFFECT_PLAY_SCENE_SCRIPT_PACKAGE
288 &Spell::EffectCreateSceneObject, //196 SPELL_EFFECT_CREATE_SCENE_OBJECT
289 &Spell::EffectCreatePrivateSceneObject, //197 SPELL_EFFECT_CREATE_PERSONAL_SCENE_OBJECT
290 &Spell::EffectPlayScene, //198 SPELL_EFFECT_PLAY_SCENE
291 &Spell::EffectNULL, //199 SPELL_EFFECT_DESPAWN_SUMMON
292 &Spell::EffectHealBattlePetPct, //200 SPELL_EFFECT_HEAL_BATTLEPET_PCT
293 &Spell::EffectEnableBattlePets, //201 SPELL_EFFECT_ENABLE_BATTLE_PETS
294 &Spell::EffectUnused, //202 SPELL_EFFECT_APPLY_AREA_AURA_SUMMONS
295 &Spell::EffectRemoveAura, //203 SPELL_EFFECT_REMOVE_AURA_2
296 &Spell::EffectChangeBattlePetQuality, //204 SPELL_EFFECT_CHANGE_BATTLEPET_QUALITY
297 &Spell::EffectLaunchQuestChoice, //205 SPELL_EFFECT_LAUNCH_QUEST_CHOICE
298 &Spell::EffectNULL, //206 SPELL_EFFECT_ALTER_ITEM
299 &Spell::EffectNULL, //207 SPELL_EFFECT_LAUNCH_QUEST_TASK
300 &Spell::EffectNULL, //208 SPELL_EFFECT_SET_REPUTATION
301 &Spell::EffectUnused, //209 SPELL_EFFECT_209
302 &Spell::EffectLearnGarrisonBuilding, //210 SPELL_EFFECT_LEARN_GARRISON_BUILDING
303 &Spell::EffectNULL, //211 SPELL_EFFECT_LEARN_GARRISON_SPECIALIZATION
304 &Spell::EffectRemoveAuraBySpellLabel, //212 SPELL_EFFECT_REMOVE_AURA_BY_SPELL_LABEL
305 &Spell::EffectJumpDest, //213 SPELL_EFFECT_JUMP_DEST_2
306 &Spell::EffectCreateGarrison, //214 SPELL_EFFECT_CREATE_GARRISON
307 &Spell::EffectNULL, //215 SPELL_EFFECT_UPGRADE_CHARACTER_SPELLS
308 &Spell::EffectNULL, //216 SPELL_EFFECT_CREATE_SHIPMENT
309 &Spell::EffectNULL, //217 SPELL_EFFECT_UPGRADE_GARRISON
310 &Spell::EffectNULL, //218 SPELL_EFFECT_218
311 &Spell::EffectCreateConversation, //219 SPELL_EFFECT_CREATE_CONVERSATION
312 &Spell::EffectAddGarrisonFollower, //220 SPELL_EFFECT_ADD_GARRISON_FOLLOWER
313 &Spell::EffectNULL, //221 SPELL_EFFECT_ADD_GARRISON_MISSION
314 &Spell::EffectCreateHeirloomItem, //222 SPELL_EFFECT_CREATE_HEIRLOOM_ITEM
315 &Spell::EffectNULL, //223 SPELL_EFFECT_CHANGE_ITEM_BONUSES
316 &Spell::EffectActivateGarrisonBuilding, //224 SPELL_EFFECT_ACTIVATE_GARRISON_BUILDING
317 &Spell::EffectGrantBattlePetLevel, //225 SPELL_EFFECT_GRANT_BATTLEPET_LEVEL
318 &Spell::EffectNULL, //226 SPELL_EFFECT_TRIGGER_ACTION_SET
319 &Spell::EffectNULL, //227 SPELL_EFFECT_TELEPORT_TO_LFG_DUNGEON
320 &Spell::EffectNULL, //228 SPELL_EFFECT_228
321 &Spell::EffectNULL, //229 SPELL_EFFECT_SET_FOLLOWER_QUALITY
322 &Spell::EffectNULL, //230 SPELL_EFFECT_230
323 &Spell::EffectNULL, //231 SPELL_EFFECT_INCREASE_FOLLOWER_EXPERIENCE
324 &Spell::EffectNULL, //232 SPELL_EFFECT_REMOVE_PHASE
325 &Spell::EffectNULL, //233 SPELL_EFFECT_RANDOMIZE_FOLLOWER_ABILITIES
326 &Spell::EffectNULL, //234 SPELL_EFFECT_234
327 &Spell::EffectUnused, //235 SPELL_EFFECT_235
328 &Spell::EffectGiveExperience, //236 SPELL_EFFECT_GIVE_EXPERIENCE
329 &Spell::EffectGiveRestedExperience, //237 SPELL_EFFECT_GIVE_RESTED_EXPERIENCE_BONUS
330 &Spell::EffectNULL, //238 SPELL_EFFECT_INCREASE_SKILL
331 &Spell::EffectNULL, //239 SPELL_EFFECT_END_GARRISON_BUILDING_CONSTRUCTION
332 &Spell::EffectGiveArtifactPower, //240 SPELL_EFFECT_GIVE_ARTIFACT_POWER
333 &Spell::EffectUnused, //241 SPELL_EFFECT_241
334 &Spell::EffectGiveArtifactPowerNoBonus, //242 SPELL_EFFECT_GIVE_ARTIFACT_POWER_NO_BONUS
335 &Spell::EffectApplyEnchantIllusion, //243 SPELL_EFFECT_APPLY_ENCHANT_ILLUSION
336 &Spell::EffectNULL, //244 SPELL_EFFECT_LEARN_FOLLOWER_ABILITY
337 &Spell::EffectUpgradeHeirloom, //245 SPELL_EFFECT_UPGRADE_HEIRLOOM
338 &Spell::EffectNULL, //246 SPELL_EFFECT_FINISH_GARRISON_MISSION
339 &Spell::EffectNULL, //247 SPELL_EFFECT_ADD_GARRISON_MISSION_SET
340 &Spell::EffectNULL, //248 SPELL_EFFECT_FINISH_SHIPMENT
341 &Spell::EffectNULL, //249 SPELL_EFFECT_FORCE_EQUIP_ITEM
342 &Spell::EffectNULL, //250 SPELL_EFFECT_TAKE_SCREENSHOT
343 &Spell::EffectNULL, //251 SPELL_EFFECT_SET_GARRISON_CACHE_SIZE
344 &Spell::EffectTeleportUnits, //252 SPELL_EFFECT_TELEPORT_UNITS
345 &Spell::EffectGiveHonor, //253 SPELL_EFFECT_GIVE_HONOR
346 &Spell::EffectJumpCharge, //254 SPELL_EFFECT_JUMP_CHARGE
347 &Spell::EffectLearnTransmogSet, //255 SPELL_EFFECT_LEARN_TRANSMOG_SET
348 &Spell::EffectUnused, //256 SPELL_EFFECT_256
349 &Spell::EffectUnused, //257 SPELL_EFFECT_257
350 &Spell::EffectNULL, //258 SPELL_EFFECT_MODIFY_KEYSTONE
351 &Spell::EffectRespecAzeriteEmpoweredItem, //259 SPELL_EFFECT_RESPEC_AZERITE_EMPOWERED_ITEM
352 &Spell::EffectNULL, //260 SPELL_EFFECT_SUMMON_STABLED_PET
353 &Spell::EffectNULL, //261 SPELL_EFFECT_SCRAP_ITEM
354 &Spell::EffectUnused, //262 SPELL_EFFECT_262
355 &Spell::EffectNULL, //263 SPELL_EFFECT_REPAIR_ITEM
356 &Spell::EffectNULL, //264 SPELL_EFFECT_REMOVE_GEM
357 &Spell::EffectLearnAzeriteEssencePower, //265 SPELL_EFFECT_LEARN_AZERITE_ESSENCE_POWER
358 &Spell::EffectNULL, //266 SPELL_EFFECT_SET_ITEM_BONUS_LIST_GROUP_ENTRY
359 &Spell::EffectCreatePrivateConversation, //267 SPELL_EFFECT_CREATE_PRIVATE_CONVERSATION
360 &Spell::EffectApplyMountEquipment, //268 SPELL_EFFECT_APPLY_MOUNT_EQUIPMENT
361 &Spell::EffectNULL, //269 SPELL_EFFECT_INCREASE_ITEM_BONUS_LIST_GROUP_STEP
362 &Spell::EffectNULL, //270 SPELL_EFFECT_270
363 &Spell::EffectUnused, //271 SPELL_EFFECT_APPLY_AREA_AURA_PARTY_NONRANDOM
364 &Spell::EffectNULL, //272 SPELL_EFFECT_SET_COVENANT
365 &Spell::EffectNULL, //273 SPELL_EFFECT_CRAFT_RUNEFORGE_LEGENDARY
366 &Spell::EffectUnused, //274 SPELL_EFFECT_274
367 &Spell::EffectUnused, //275 SPELL_EFFECT_275
368 &Spell::EffectLearnTransmogIllusion, //276 SPELL_EFFECT_LEARN_TRANSMOG_ILLUSION
369 &Spell::EffectNULL, //277 SPELL_EFFECT_SET_CHROMIE_TIME
370 &Spell::EffectNULL, //278 SPELL_EFFECT_278
371 &Spell::EffectNULL, //279 SPELL_EFFECT_LEARN_GARR_TALENT
372 &Spell::EffectUnused, //280 SPELL_EFFECT_280
373 &Spell::EffectNULL, //281 SPELL_EFFECT_LEARN_SOULBIND_CONDUIT
374 &Spell::EffectNULL, //282 SPELL_EFFECT_CONVERT_ITEMS_TO_CURRENCY
375 &Spell::EffectSkipCampaign, //283 SPELL_EFFECT_COMPLETE_CAMPAIGN
376 &Spell::EffectSendChatMessage, //284 SPELL_EFFECT_SEND_CHAT_MESSAGE
377 &Spell::EffectNULL, //285 SPELL_EFFECT_MODIFY_KEYSTONE_2
378 &Spell::EffectGrantBattlePetExperience, //286 SPELL_EFFECT_GRANT_BATTLEPET_EXPERIENCE
379 &Spell::EffectNULL, //287 SPELL_EFFECT_SET_GARRISON_FOLLOWER_LEVEL
380 &Spell::EffectNULL, //288 SPELL_EFFECT_CRAFT_ITEM
381 &Spell::EffectModifyAuraStacks, //289 SPELL_EFFECT_MODIFY_AURA_STACKS
382 &Spell::EffectModifyCooldown, //290 SPELL_EFFECT_MODIFY_COOLDOWN
383 &Spell::EffectModifyCooldowns, //291 SPELL_EFFECT_MODIFY_COOLDOWNS
384 &Spell::EffectModifyCooldownsByCategory, //292 SPELL_EFFECT_MODIFY_COOLDOWNS_BY_CATEGORY
385 &Spell::EffectModifySpellCharges, //293 SPELL_EFFECT_MODIFY_CHARGES
386 &Spell::EffectNULL, //294 SPELL_EFFECT_CRAFT_LOOT
387 &Spell::EffectNULL, //295 SPELL_EFFECT_SALVAGE_ITEM
388 &Spell::EffectNULL, //296 SPELL_EFFECT_CRAFT_SALVAGE_ITEM
389 &Spell::EffectNULL, //297 SPELL_EFFECT_RECRAFT_ITEM
390 &Spell::EffectNULL, //298 SPELL_EFFECT_CANCEL_ALL_PRIVATE_CONVERSATIONS
391 &Spell::EffectNULL, //299 SPELL_EFFECT_299
392 &Spell::EffectUnused, //300 SPELL_EFFECT_300
393 &Spell::EffectNULL, //301 SPELL_EFFECT_CRAFT_ENCHANT
394 &Spell::EffectNULL, //302 SPELL_EFFECT_GATHERING
395 &Spell::EffectCreateTraitTreeConfig, //303 SPELL_EFFECT_CREATE_TRAIT_TREE_CONFIG
396 &Spell::EffectChangeActiveCombatTraitConfig, //304 SPELL_EFFECT_CHANGE_ACTIVE_COMBAT_TRAIT_CONFIG
397 &Spell::EffectNULL, //305 SPELL_EFFECT_305
398 &Spell::EffectUpdateInteractions, //306 SPELL_EFFECT_UPDATE_INTERACTIONS
399 &Spell::EffectNULL, //307 SPELL_EFFECT_307
400 &Spell::EffectNULL, //308 SPELL_EFFECT_CANCEL_PRELOAD_WORLD
401 &Spell::EffectNULL, //309 SPELL_EFFECT_PRELOAD_WORLD
402 &Spell::EffectNULL, //310 SPELL_EFFECT_310
403 &Spell::EffectSkipQuestLine, //311 SPELL_EFFECT_SKIP_QUESTLINE
404 &Spell::EffectNULL, //312 SPELL_EFFECT_312
405 &Spell::EffectNULL, //313 SPELL_EFFECT_CHANGE_ITEM_BONUSES_2
406 &Spell::EffectNULL, //314 SPELL_EFFECT_ADD_SOCKET_BONUS
407 &Spell::EffectNULL, //315 SPELL_EFFECT_LEARN_TRANSMOG_APPEARANCE_FROM_ITEM_MOD_APPEARANCE_GROUP
408 &Spell::EffectKillCreditLabel, //316 SPELL_EFFECT_KILL_CREDIT_LABEL_1
409 &Spell::EffectKillCreditLabel, //317 SPELL_EFFECT_KILL_CREDIT_LABEL_2
410 &Spell::EffectNULL, //318 SPELL_EFFECT_318
411 &Spell::EffectNULL, //319 SPELL_EFFECT_319
412 &Spell::EffectNULL, //320 SPELL_EFFECT_320
413 &Spell::EffectNULL, //321 SPELL_EFFECT_321
414 &Spell::EffectNULL, //322 SPELL_EFFECT_322
415 &Spell::EffectNULL, //323 SPELL_EFFECT_323
416 &Spell::EffectNULL, //324 SPELL_EFFECT_324
417 &Spell::EffectNULL, //325 SPELL_EFFECT_325
418 &Spell::EffectNULL, //326 SPELL_EFFECT_326
419 &Spell::EffectNULL, //327 SPELL_EFFECT_327
420 &Spell::EffectNULL, //328 SPELL_EFFECT_328
421 &Spell::EffectNULL, //329 SPELL_EFFECT_329
422 &Spell::EffectNULL, //330 SPELL_EFFECT_330
423 &Spell::EffectNULL, //331 SPELL_EFFECT_331
424 &Spell::EffectNULL, //332 SPELL_EFFECT_332
425 &Spell::EffectNULL, //333 SPELL_EFFECT_333
426 &Spell::EffectNULL, //334 SPELL_EFFECT_334
427 &Spell::EffectSetPlayerDataElementAccount, //335 SPELL_EFFECT_SET_PLAYER_DATA_ELEMENT_ACCOUNT
428 &Spell::EffectSetPlayerDataElementCharacter, //336 SPELL_EFFECT_SET_PLAYER_DATA_ELEMENT_CHARACTER
429 &Spell::EffectSetPlayerDataFlagAccount, //337 SPELL_EFFECT_SET_PLAYER_DATA_FLAG_ACCOUNT
430 &Spell::EffectSetPlayerDataFlagCharacter, //338 SPELL_EFFECT_SET_PLAYER_DATA_FLAG_CHARACTER
431 &Spell::EffectNULL, //339 SPELL_EFFECT_UI_ACTION
432 &Spell::EffectNULL, //340 SPELL_EFFECT_340
433 &Spell::EffectLearnWarbandScene, //341 SPELL_EFFECT_LEARN_WARBAND_SCENE
434 &Spell::EffectNULL, //342 SPELL_EFFECT_342
435 &Spell::EffectNULL, //343 SPELL_EFFECT_343
436 &Spell::EffectNULL, //344 SPELL_EFFECT_344
437 &Spell::EffectNULL, //345 SPELL_EFFECT_ASSIST_ACTION
438 &Spell::EffectNULL, //346 SPELL_EFFECT_346
439 &Spell::EffectEquipTransmogOutfit, //347 SPELL_EFFECT_EQUIP_TRANSMOG_OUTFIT
440 &Spell::EffectNULL, //348 SPELL_EFFECT_GIVE_HOUSE_LEVEL
441 &Spell::EffectNULL, //349 SPELL_EFFECT_LEARN_HOUSE_ROOM
442 &Spell::EffectNULL, //350 SPELL_EFFECT_LEARN_HOUSE_EXTERIOR_COMPONENT
443 &Spell::EffectNULL, //351 SPELL_EFFECT_LEARN_HOUSE_THEME
444 &Spell::EffectNULL, //352 SPELL_EFFECT_LEARN_HOUSE_ROOM_COMPONENT_TEXTURE
445 &Spell::EffectCreateAreaTrigger, //353 SPELL_EFFECT_CREATE_AREATRIGGER_2
446 &Spell::EffectNULL, //354 SPELL_EFFECT_SET_NEIGHBORHOOD_INITIATIVE
447 &Spell::EffectNULL, //355 SPELL_EFFECT_LEARN_HOUSE_TYPE
448};
449
451{
452 TC_LOG_DEBUG("spells", "WORLD: Spell Effect DUMMY");
453}
454
456{
457 // NOT USED BY ANY SPELL OR USELESS OR IMPLEMENTED IN DIFFERENT WAY IN TRINITY
458}
459
461{
463 return;
464
465 if (!m_corpseTarget && !unitTarget)
466 return;
467
468 Player* player = nullptr;
469
470 if (m_corpseTarget)
472 else if (unitTarget)
473 player = unitTarget->ToPlayer();
474
475 if (!player || player->IsAlive() || !player->IsInWorld())
476 return;
477
478 if (player->IsResurrectRequested()) // already have one active request
479 return;
480
481 uint32 health = GetEffectValueAsInt();
484 player->SetResurrectRequestData(m_caster, health, mana, 0);
485 SendResurrectRequest(player);
486}
487
489{
491 return;
492
493 if (!unitTarget || !unitTarget->IsAlive())
494 return;
495
498 return;
499
500 if (m_caster == unitTarget) // prevent interrupt message
501 finish();
502
504 data.Target = unitTarget->GetGUID();
505 data.Caster = m_caster->GetGUID();
506 data.SpellID = m_spellInfo->Id;
507 m_caster->SendMessageToSet(data.Write(), true);
508
510}
511
513{
515 return;
516
517 if (!unitTarget || !unitTarget->IsAlive())
518 return;
519
520 uint32 damage = GetEffectValueAsInt();
521 // CalcAbsorbResist already in Player::EnvironmentalDamage
524 else
525 {
526 Unit* unitCaster = GetUnitCasterForEffectHandlers();
528 Unit::CalcAbsorbResist(damageInfo);
529
531 log.damage = damageInfo.GetDamage();
532 log.originalDamage = damage;
533 log.absorb = damageInfo.GetAbsorb();
534 log.resist = damageInfo.GetResist();
535
536 if (unitCaster)
537 unitCaster->SendSpellNonMeleeDamageLog(&log);
538 }
539}
540
542{
544 return;
545
546 if (unitTarget && unitTarget->IsAlive())
547 {
548 int32 damage = GetEffectValueAsInt();
549 bool apply_direct_bonus = true;
550
551 // Meteor like spells (divided damage to targets)
553 {
554 // divide to all targets
556 damage /= count;
557 }
558
559 Unit* unitCaster = GetUnitCasterForEffectHandlers();
560 if (unitCaster && apply_direct_bonus)
561 {
562 int32 bonus = unitCaster->SpellDamageBonusDone(unitTarget, m_spellInfo, damage, SPELL_DIRECT_DAMAGE, *effectInfo, 1, this);
563 damage = bonus + int32(bonus * variance);
564 damage = unitTarget->SpellDamageBonusTaken(unitCaster, m_spellInfo, damage, SPELL_DIRECT_DAMAGE);
565 }
566
567 m_damage += damage;
568 }
569}
570
572{
574 return;
575
577 return;
578
579 // pet auras
581 {
582 if (PetAura const* petSpell = sSpellMgr->GetPetAura(m_spellInfo->Id, effectInfo->EffectIndex))
583 {
584 m_caster->ToPlayer()->AddPetAura(petSpell);
585 return;
586 }
587 }
588
589 // normal DB scripted effect
590 TC_LOG_DEBUG("spells", "Spell ScriptStart spellid {} in EffectDummy({})", m_spellInfo->Id, effectInfo->EffectIndex);
592}
593
595{
598 return;
599
600 uint32 triggered_spell_id = effectInfo->TriggerSpell;
601
605 {
606 // special cases
607 switch (triggered_spell_id)
608 {
609 // Demonic Empowerment -- succubus
610 case 54437:
611 {
615
616 // Cast Lesser Invisibility
617 unitTarget->CastSpell(unitTarget, 7870, this);
618 return;
619 }
620 // Brittle Armor - (need add max stack of 24575 Brittle Armor)
621 case 29284:
622 {
623 // Brittle Armor
624 SpellInfo const* spell = sSpellMgr->GetSpellInfo(24575, GetCastDifficulty());
625 if (!spell)
626 return;
627
628 for (uint32 j = 0; j < spell->StackAmount; ++j)
629 m_caster->CastSpell(unitTarget, spell->Id, this);
630 return;
631 }
632 // Mercurial Shield - (need add max stack of 26464 Mercurial Shield)
633 case 29286:
634 {
635 // Mercurial Shield
636 SpellInfo const* spell = sSpellMgr->GetSpellInfo(26464, GetCastDifficulty());
637 if (!spell)
638 return;
639
640 for (uint32 j = 0; j < spell->StackAmount; ++j)
641 m_caster->CastSpell(unitTarget, spell->Id, this);
642 return;
643 }
644 }
645 }
646
647 if (triggered_spell_id == 0)
648 {
649 TC_LOG_WARN("spells.effect.nospell", "Spell::EffectTriggerSpell: Spell {} [EffectIndex: {}] does not have triggered spell.", m_spellInfo->Id, effectInfo->EffectIndex);
650 return;
651 }
652
653 // normal case
654 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(triggered_spell_id, GetCastDifficulty());
655 if (!spellInfo)
656 {
657 TC_LOG_ERROR("spells.effect.nospell", "Spell::EffectTriggerSpell spell {} tried to trigger unknown spell {}", m_spellInfo->Id, triggered_spell_id);
658 return;
659 }
660
661 SpellCastTargets targets;
662 Optional<int32> targetCount;
663 Optional<int32> targetIndex;
665 {
667 return;
668 targets.SetUnitTarget(unitTarget);
671 }
672 else //if (effectHandleMode == SPELL_EFFECT_HANDLE_LAUNCH)
673 {
675 return;
676
678 targets.SetDst(m_targets);
679
680 if (Unit* target = m_targets.GetUnitTarget())
681 targets.SetUnitTarget(target);
682 else
683 {
684 if (Unit* unit = m_caster->ToUnit())
685 targets.SetUnitTarget(unit);
686 else if (GameObject* go = m_caster->ToGameObject())
687 targets.SetGOTarget(go);
688 }
689 }
690
691 Milliseconds delay = 0ms;
694
695 m_caster->m_Events.AddEventAtOffset([caster = m_caster, targets, originalCaster = m_originalCasterGUID, castItemGuid = m_castItemGUID, originalCastId = m_castId,
696 spellEffectInfo = effectInfo, value = effectValue, itemLevel = m_castItemLevel, targetCount, targetIndex]() mutable
697 {
698 targets.Update(caster); // refresh pointers stored in targets
699
700 // original caster guid only for GO cast
702 args.SetOriginalCaster(originalCaster);
703 args.OriginalCastId = originalCastId;
704 args.OriginalCastItemLevel = itemLevel;
705 SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(spellEffectInfo->TriggerSpell, caster->GetMap()->GetDifficultyID());
706 if (!castItemGuid.IsEmpty() && spellInfo->HasAttribute(SPELL_ATTR2_RETAIN_ITEM_CAST))
707 if (Player const* triggeringAuraCaster = Object::ToPlayer(caster))
708 args.CastItem = triggeringAuraCaster->GetItemByGuid(castItemGuid);
709
710 // set basepoints for trigger with value effect
711 if (spellEffectInfo->Effect == SPELL_EFFECT_TRIGGER_SPELL_WITH_VALUE)
712 for (std::size_t i = 0; i < spellInfo->GetEffects().size(); ++i)
714
715 if (targetCount)
717
718 if (targetIndex)
720
721 caster->CastSpell(std::move(targets), spellEffectInfo->TriggerSpell, args);
722 }, delay);
723}
724
726{
729 return;
730
731 uint32 triggered_spell_id = effectInfo->TriggerSpell;
732 if (triggered_spell_id == 0)
733 {
734 TC_LOG_WARN("spells.effect.nospell", "Spell::EffectTriggerMissileSpell: Spell {} [EffectIndex: {}] does not have triggered spell.", m_spellInfo->Id, effectInfo->EffectIndex);
735 return;
736 }
737
738 // normal case
739 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(triggered_spell_id, GetCastDifficulty());
740 if (!spellInfo)
741 {
742 TC_LOG_ERROR("spells.effect.nospell", "Spell::EffectTriggerMissileSpell spell {} tried to trigger unknown spell {}.", m_spellInfo->Id, triggered_spell_id);
743 return;
744 }
745
746 SpellCastTargets targets;
747 Optional<int32> targetCount;
748 Optional<int32> targetIndex;
750 {
752 return;
753 targets.SetUnitTarget(unitTarget);
756 }
757 else //if (effectHandleMode == SPELL_EFFECT_HANDLE_HIT)
758 {
760 return;
761
763 targets.SetDst(m_targets);
764
765 if (Unit* unit = m_caster->ToUnit())
766 targets.SetUnitTarget(unit);
767 else if (GameObject* go = m_caster->ToGameObject())
768 targets.SetGOTarget(go);
769 }
770
773 args.SetTriggeringSpell(this);
775
776 // set basepoints for trigger with value effect
778 for (std::size_t i = 0; i < spellInfo->GetEffects().size(); ++i)
780
781 if (targetCount)
783
784 if (targetIndex)
786
787 // original caster guid only for GO cast
788 m_caster->CastSpell(std::move(targets), spellInfo->Id, args);
789}
790
792{
794 return;
795
796 if (!unitTarget)
797 return;
798
799 uint32 triggered_spell_id = effectInfo->TriggerSpell;
800 if (triggered_spell_id == 0)
801 {
802 TC_LOG_WARN("spells.effect.nospell", "Spell::EffectForceCast: Spell {} [EffectIndex: {}] does not have triggered spell.", m_spellInfo->Id, effectInfo->EffectIndex);
803 return;
804 }
805
806 // normal case
807 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(triggered_spell_id, GetCastDifficulty());
808
809 if (!spellInfo)
810 {
811 TC_LOG_ERROR("spells.effect.nospell", "Spell::EffectForceCast of spell {}: triggering unknown spell id {}.", m_spellInfo->Id, triggered_spell_id);
812 return;
813 }
814
816 {
817 switch (m_spellInfo->Id)
818 {
819 case 52588: // Skeletal Gryphon Escape
820 case 48598: // Ride Flamebringer Cue
822 break;
823 case 52463: // Hide In Mine Car
824 case 52349: // Overtake
825 {
829 unitTarget->CastSpell(unitTarget, spellInfo->Id, args);
830 return;
831 }
832 }
833 }
834
835 switch (spellInfo->Id)
836 {
837 case 72298: // Malleable Goo Summon
839 .SetOriginalCaster(m_originalCasterGUID));
840 return;
841 }
842
845 for (std::size_t i = 0; i < spellInfo->GetEffects().size(); ++i)
847
848 unitTarget->CastSpell(m_caster, spellInfo->Id, args);
849}
850
852{
854 return;
855
856 if (!unitTarget)
857 return;
858
859 uint32 triggered_spell_id = effectInfo->TriggerSpell;
860 if (triggered_spell_id == 0)
861 {
862 TC_LOG_WARN("spells.effect.nospell", "Spell::EffectForceCast2: Spell {} [EffectIndex: {}] does not have triggered spell.", m_spellInfo->Id, effectInfo->EffectIndex);
863 return;
864 }
865
866 // normal case
867 if (!sSpellMgr->GetSpellInfo(triggered_spell_id, GetCastDifficulty()))
868 {
869 TC_LOG_ERROR("spells.effect.nospell", "Spell::EffectForceCast2 of spell {}: triggering unknown spell id {}.", m_spellInfo->Id, triggered_spell_id);
870 return;
871 }
872
873 // Start the cast during next update tick
874 // This is neccessary to preserve proper SMSG_SPELL_START and SMSG_SPELL_GO packet sequence
875 // (if packet sequence is not preserved then client cast bar in UI bugs and doesn't stop when the spell is interrupted)
876 // Triggered spells from effects handled during launch phase (such as SPELL_EFFECT_TRIGGER_SPELL)
877 // normally have their SMSG_SPELL_GO sent before parent spell SMSG_SPELL_GO
878 // SPELL_EFFECT_FORCE_CAST_2 requires these packets to be sent after parent spell
879 // but also needs to be handled during launch phase as well
880 unitTarget->m_Events.AddEventAtOffset([triggered_spell_id, target = CastSpellTargetArg(m_caster), caster = unitTarget]() mutable
881 {
882 if (!target.Targets)
883 return;
884
885 target.Targets->Update(caster);
886
887 caster->CastSpell(target, triggered_spell_id);
888 }, 0ms);
889}
890
892{
894 return;
895
896 uint32 triggered_spell_id = effectInfo->TriggerSpell;
897 if (triggered_spell_id == 0)
898 {
899 TC_LOG_WARN("spells.effect.nospell", "Spell::EffectTriggerRitualOfSummoning: Spell {} [EffectIndex: {}] does not have triggered spell.", m_spellInfo->Id, effectInfo->EffectIndex);
900 return;
901 }
902
903 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(triggered_spell_id, GetCastDifficulty());
904
905 if (!spellInfo)
906 {
907 TC_LOG_ERROR("spells.effect.nospell", "EffectTriggerRitualOfSummoning of spell {}: triggering unknown spell id {}.", m_spellInfo->Id, triggered_spell_id);
908 return;
909 }
910
911 finish();
912
913 m_caster->CastSpell(nullptr, spellInfo->Id, CastSpellExtraArgs()
914 .SetTriggeringSpell(this));
915}
916
918{
920 return;
921
922 Unit* unitCaster = GetUnitCasterForEffectHandlers();
923 if (!unitCaster)
924 return;
925
926 if (unitCaster->IsInFlight())
927 return;
928
929 if (!unitTarget)
930 return;
931
932 Optional<float> speedMultiplier = effectInfo->Amplitude > 0.0f ? Optional<float>(effectInfo->Amplitude) : std::nullopt;
933 Optional<float> minHeight = effectInfo->MiscValue ? Optional<float>(effectInfo->MiscValue / 10.0f) : std::nullopt;
934 Optional<float> maxHeight = effectInfo->MiscValueB ? Optional<float>(effectInfo->MiscValueB / 10.0f) : std::nullopt;
935
937 if (Unit const* target = m_targets.GetUnitTarget())
938 {
940 facing = target;
941 }
942
943 JumpArrivalCastArgs arrivalCast;
944 arrivalCast.SpellId = effectInfo->TriggerSpell;
945 arrivalCast.Target = unitTarget->GetGUID();
946 unitCaster->GetMotionMaster()->MoveJump(EVENT_JUMP, *unitTarget, {}, minHeight, maxHeight,
948 false, speedMultiplier, &arrivalCast);
949}
950
952{
954 return;
955
956 Unit* unitCaster = GetUnitCasterForEffectHandlers();
957 if (!unitCaster)
958 return;
959
960 if (unitCaster->IsInFlight())
961 return;
962
963 if (!m_targets.HasDst())
964 return;
965
966 Optional<float> speedMultiplier = effectInfo->Amplitude > 0.0f ? Optional<float>(effectInfo->Amplitude) : std::nullopt;
967 Optional<float> minHeight = effectInfo->MiscValue ? Optional<float>(effectInfo->MiscValue / 10.0f) : std::nullopt;
968 Optional<float> maxHeight = effectInfo->MiscValueB ? Optional<float>(effectInfo->MiscValueB / 10.0f) : std::nullopt;
969
971 if (Unit const* target = m_targets.GetUnitTarget())
972 {
974 facing = target;
975 }
976 else
977 facing = destTarget->GetOrientation();
978
979 JumpArrivalCastArgs arrivalCast;
980 arrivalCast.SpellId = effectInfo->TriggerSpell;
981 unitCaster->GetMotionMaster()->MoveJump(EVENT_JUMP, *destTarget, {}, minHeight, maxHeight,
983 false, speedMultiplier, &arrivalCast);
984}
985
986TeleportToOptions GetTeleportOptions(WorldObject const* caster, Unit const* unitTarget, SpellDestination const& targetDest)
987{
989 if (caster == unitTarget)
990 options |= TELE_TO_SPELL;
991
992 if (targetDest._position.GetMapId() == unitTarget->GetMapId())
993 {
995
996 if (unitTarget->GetTransGUID() == targetDest._transportGUID)
998 }
999
1000 return options;
1001}
1002
1004{
1006 return;
1007
1008 if (!unitTarget || unitTarget->IsInFlight())
1009 return;
1010
1011 // If not exist data for dest location - return
1012 if (!m_targets.HasDst())
1013 {
1014 TC_LOG_ERROR("spells", "Spell::EffectTeleportUnits - does not have a destination for spellId {}.", m_spellInfo->Id);
1015 return;
1016 }
1017
1018 // Init dest coordinates
1019 TeleportLocation targetDest{ .Location = *destTarget };
1020 if (targetDest.Location.GetMapId() == MAPID_INVALID)
1021 targetDest.Location.m_mapId = unitTarget->GetMapId();
1022
1023 if (!targetDest.Location.GetOrientation() && m_targets.GetUnitTarget())
1024 targetDest.Location.SetOrientation(m_targets.GetUnitTarget()->GetOrientation());
1025
1026 Player* player = unitTarget->ToPlayer();
1027
1028 if (player)
1029 {
1030 // Custom loading screen
1031 if (uint32 customLoadingScreenId = effectInfo->MiscValue)
1032 if (targetDest.Location.GetMapId() != unitTarget->GetMapId() || !unitTarget->IsInDist2d(targetDest.Location, TELEPORT_MIN_LOAD_SCREEN_DISTANCE))
1034
1035 if (ObjectGuid transportGuid = m_destTargets[effectInfo->EffectIndex]._transportGUID; !transportGuid.IsEmpty())
1036 {
1037 targetDest.TransportGuid = transportGuid;
1038 targetDest.Location.Relocate(m_destTargets[effectInfo->EffectIndex]._transportOffset);
1039 }
1040
1042 player->TeleportTo(targetDest, options, m_spellInfo->Id);
1043
1044 }
1045 else if (targetDest.Location.GetMapId() == unitTarget->GetMapId())
1046 unitTarget->NearTeleportTo(targetDest.Location, unitTarget == m_caster);
1047 else
1048 TC_LOG_ERROR("spells", "Spell::EffectTeleportUnits - spellId {} attempted to teleport creature to a different map.", m_spellInfo->Id);
1049}
1050
1052{
1053public:
1054 explicit DelayedSpellTeleportEvent(Unit* target, TeleportLocation const& targetDest, TeleportToOptions options, uint32 spellId)
1055 : _target(target), _targetDest(targetDest), _options(options), _spellId(spellId){ }
1056
1057 bool Execute(uint64 /*e_time*/, uint32 /*p_time*/) override
1058 {
1059 if (Player* player = _target->ToPlayer())
1060 player->TeleportTo(_targetDest, _options);
1061 else if (_targetDest.Location.GetMapId() == _target->GetMapId())
1063 else
1064 TC_LOG_ERROR("spells", "Spell::EffectTeleportUnitsWithVisualLoadingScreen - spellId {} attempted to teleport creature to a different map.", _spellId);
1065
1066 return true;
1067 }
1068
1069private:
1074};
1075
1077{
1079 return;
1080
1081 if (!unitTarget)
1082 return;
1083
1084 // If not exist data for dest location - return
1085 if (!m_targets.HasDst())
1086 {
1087 TC_LOG_ERROR("spells", "Spell::EffectTeleportUnitsWithVisualLoadingScreen - does not have a destination for spellId {}.", m_spellInfo->Id);
1088 return;
1089 }
1090
1091 // Init dest coordinates
1092 TeleportLocation targetDest{ .Location = *destTarget };
1093 if (targetDest.Location.GetMapId() == MAPID_INVALID)
1094 targetDest.Location.m_mapId = unitTarget->GetMapId();
1095
1096 if (!targetDest.Location.GetOrientation() && m_targets.GetUnitTarget())
1097 targetDest.Location.SetOrientation(m_targets.GetUnitTarget()->GetOrientation());
1098
1099 if (ObjectGuid transportGuid = m_destTargets[effectInfo->EffectIndex]._transportGUID; !transportGuid.IsEmpty())
1100 {
1101 targetDest.TransportGuid = transportGuid;
1102 targetDest.Location.Relocate(m_destTargets[effectInfo->EffectIndex]._transportOffset);
1103 }
1104
1106 if (Player* playerTarget = unitTarget->ToPlayer())
1108
1112}
1113
1115{
1117 return;
1118
1120 return;
1121
1122 // register target/effect on aura
1124 if (!aurApp)
1126 else
1128}
1129
1131{
1133 return;
1134
1136 return;
1137
1138 Player* player = unitTarget->ToPlayer();
1139 uint32 spellToUnlearn = effectInfo->TriggerSpell;
1140
1141 player->RemoveSpell(spellToUnlearn);
1142
1143 TC_LOG_DEBUG("spells", "Spell: Player {} has unlearned spell {} from Npc {}", player->GetGUID().ToString(), spellToUnlearn, m_caster->GetGUID().ToString());
1144}
1145
1147{
1149 return;
1150
1152 return;
1153
1154 int32 drainAmount = GetEffectValueAsInt();
1155 Powers powerType = Powers(effectInfo->MiscValue);
1156 if (!unitTarget || !unitTarget->IsAlive() || unitTarget->GetPowerType() != powerType || drainAmount < 0)
1157 return;
1158
1159 Unit* unitCaster = GetUnitCasterForEffectHandlers();
1160 // add spell damage bonus
1161 if (unitCaster)
1162 {
1163 int32 bonus = unitCaster->SpellDamageBonusDone(unitTarget, m_spellInfo, drainAmount, SPELL_DIRECT_DAMAGE, *effectInfo, 1, this);
1164 drainAmount = bonus + int32(bonus * variance);
1165 drainAmount = unitTarget->SpellDamageBonusTaken(unitCaster, m_spellInfo, drainAmount, SPELL_DIRECT_DAMAGE);
1166 }
1167
1168 int32 damage = -unitTarget->ModifyPower(powerType, -drainAmount);
1169
1170 // Don't restore from self drain
1171 float gainMultiplier = 0.f;
1172 if (unitCaster && unitCaster != unitTarget)
1173 {
1174 gainMultiplier = effectInfo->CalcValueMultiplier(unitCaster, this);
1175 int32 const gain = int32(damage * gainMultiplier);
1176
1177 unitCaster->EnergizeBySpell(unitCaster, m_spellInfo, gain, powerType);
1178 }
1179 ExecuteLogEffectTakeTargetPower(SpellEffectName(effectInfo->Effect), unitTarget, powerType, damage, gainMultiplier);
1180}
1181
1183{
1184 // we do not handle a flag dropping or clicking on flag in battleground by sendevent system
1187 return;
1188
1189 WorldObject* target = nullptr;
1190
1191 // call events for object target if present
1193 {
1194 if (unitTarget)
1195 target = unitTarget;
1196 else if (gameObjTarget)
1197 target = gameObjTarget;
1198 else if (m_corpseTarget)
1199 target = m_corpseTarget;
1200 }
1201 else // if (effectHandleMode == SPELL_EFFECT_HANDLE_HIT)
1202 {
1203 // let's prevent executing effect handler twice in case when spell effect is capable of targeting an object
1204 // this check was requested by scripters, but it has some downsides:
1205 // now it's impossible to script (using sEventScripts) a cast which misses all targets
1206 // or to have an ability to script the moment spell hits dest (in a case when there are object targets present)
1208 return;
1209 // some spells have no target entries in dbc and they use focus target
1210 if (focusObject)
1211 target = focusObject;
1213 }
1214
1215 TC_LOG_DEBUG("spells", "Spell ScriptStart {} for spellid {} in EffectSendEvent ", effectInfo->MiscValue, m_spellInfo->Id);
1216
1218}
1219
1221{
1223 return;
1224
1226 return;
1227
1228 int32 burnAmount = GetEffectValueAsInt();
1229 Powers powerType = Powers(effectInfo->MiscValue);
1230 if (!unitTarget || !unitTarget->IsAlive() || unitTarget->GetPowerType() != powerType || burnAmount < 0)
1231 return;
1232
1233 int32 damage = -unitTarget->ModifyPower(powerType, -burnAmount);
1234
1235 // NO - Not a typo - EffectPowerBurn uses effect value multiplier - not effect damage multiplier
1236 float dmgMultiplier = effectInfo->CalcValueMultiplier(GetUnitCasterForEffectHandlers(), this);
1237
1238 // add log data before multiplication (need power amount, not damage)
1240
1241 damage = int32(damage * dmgMultiplier);
1242
1243 m_damage += damage;
1244}
1245
1247{
1249 return;
1250
1251 int32 addhealth = GetEffectValueAsInt();
1252
1253 if (!unitTarget || !unitTarget->IsAlive() || addhealth < 0)
1254 return;
1255
1256 Unit* unitCaster = GetUnitCasterForEffectHandlers();
1257
1258 // Skip if m_originalCaster not available
1259 if (!unitCaster)
1260 return;
1261
1262 // Vessel of the Naaru (Vial of the Sunwell trinket)
1264 if (m_spellInfo->Id == 45064)
1265 {
1266 // Amount of heal - depends from stacked Holy Energy
1267 int32 damageAmount = 0;
1268 if (AuraEffect const* aurEff = unitCaster->GetAuraEffect(45062, 0))
1269 {
1270 damageAmount += aurEff->GetAmount();
1271 unitCaster->RemoveAurasDueToSpell(45062);
1272 }
1273
1274 addhealth += damageAmount;
1275 }
1276 // Death Pact - return pct of max health to caster
1278 addhealth = unitCaster->SpellHealingBonusDone(unitTarget, m_spellInfo, int32(unitCaster->CountPctFromMaxHealth(addhealth)), HEAL, *effectInfo, 1, this);
1279 else
1280 {
1281 int32 bonus = unitCaster->SpellHealingBonusDone(unitTarget, m_spellInfo, addhealth, HEAL, *effectInfo, 1, this);
1282 addhealth = bonus + int32(bonus * variance);
1283 }
1284
1285 addhealth = unitTarget->SpellHealingBonusTaken(unitCaster, m_spellInfo, addhealth, HEAL);
1286
1287 // Remove Grievious bite if fully healed
1288 if (unitTarget->HasAura(48920) && (unitTarget->GetHealth() + addhealth >= unitTarget->GetMaxHealth()))
1289 unitTarget->RemoveAura(48920);
1290
1291 m_healing += addhealth;
1292}
1293
1295{
1297 return;
1298
1299 if (!unitTarget || !unitTarget->IsAlive() || effectValue < 0)
1300 return;
1301
1303 if (Unit* unitCaster = GetUnitCasterForEffectHandlers())
1304 {
1305 heal = unitCaster->SpellHealingBonusDone(unitTarget, m_spellInfo, heal, HEAL, *effectInfo, 1, this);
1306 heal = unitTarget->SpellHealingBonusTaken(unitCaster, m_spellInfo, heal, HEAL);
1307 }
1308
1309 m_healing += heal;
1310}
1311
1313{
1315 return;
1316
1317 if (!unitTarget || !unitTarget->IsAlive() || effectValue < 0)
1318 return;
1319
1320 Unit* unitCaster = GetUnitCasterForEffectHandlers();
1321 int32 heal = GetEffectValueAsInt();
1322 if (unitCaster)
1323 heal = unitCaster->SpellHealingBonusDone(unitTarget, m_spellInfo, heal, HEAL, *effectInfo, 1, this);
1324
1325 heal += int32(heal * variance);
1326 if (unitCaster)
1327 heal = unitTarget->SpellHealingBonusTaken(unitCaster, m_spellInfo, heal, HEAL);
1328
1329 m_healing += heal;
1330}
1331
1333{
1335 return;
1336
1337 int32 damage = GetEffectValueAsInt();
1338 if (!unitTarget || !unitTarget->IsAlive() || damage < 0)
1339 return;
1340
1341 Unit* unitCaster = GetUnitCasterForEffectHandlers();
1342 int32 bonus = 0;
1343 if (unitCaster)
1344 bonus = unitCaster->SpellDamageBonusDone(unitTarget, m_spellInfo, damage, SPELL_DIRECT_DAMAGE, *effectInfo, 1, this);
1345
1346 damage = bonus + int32(bonus * variance);
1347
1348 if (unitCaster)
1349 damage = unitTarget->SpellDamageBonusTaken(unitCaster, m_spellInfo, damage, SPELL_DIRECT_DAMAGE);
1350
1351 float healMultiplier = effectInfo->CalcValueMultiplier(unitCaster, this);
1352
1353 m_damage += damage;
1354
1356 Unit::CalcAbsorbResist(damageInfo);
1357 uint32 const absorb = damageInfo.GetAbsorb();
1358 damage -= absorb;
1359
1360 // get max possible damage, don't count overkill for heal
1361 int32 healthGain = int32(-unitTarget->GetHealthGain(-damage) * healMultiplier);
1362
1363 if (unitCaster && unitCaster->IsAlive())
1364 {
1365 healthGain = unitCaster->SpellHealingBonusDone(unitCaster, m_spellInfo, healthGain, HEAL, *effectInfo, 1, this);
1366 healthGain = unitCaster->SpellHealingBonusTaken(unitCaster, m_spellInfo, healthGain, HEAL);
1367
1368 HealInfo healInfo(unitCaster, unitCaster, healthGain, m_spellInfo, m_spellSchoolMask);
1369 unitCaster->HealBySpell(healInfo);
1370 }
1371}
1372
1373void Spell::DoCreateItem(uint32 itemId, ItemContext context /*= ItemContext::NONE*/, std::vector<int32> const* bonusListIDs /*= nullptr*/)
1374{
1376 return;
1377
1378 Player* player = unitTarget->ToPlayer();
1379
1380 uint32 newitemid = itemId;
1381 ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(newitemid);
1382 if (!pProto)
1383 {
1384 player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, nullptr, nullptr);
1385 return;
1386 }
1387
1388 uint32 num_to_add = std::clamp<int32>(GetEffectValueAsInt(), 1, pProto->GetMaxStackSize());
1389
1390 /* == gem perfection handling == */
1391 // this is bad, should be done using spell_loot_template (and conditions)
1392
1393 // the chance of getting a perfect result
1394 float perfectCreateChance = 0.0f;
1395 // the resulting perfect item if successful
1396 uint32 perfectItemType = itemId;
1397 // get perfection capability and chance
1398 if (CanCreatePerfectItem(player, m_spellInfo->Id, perfectCreateChance, perfectItemType))
1399 if (roll_chance(perfectCreateChance)) // if the roll succeeds...
1400 newitemid = perfectItemType; // the perfect item replaces the regular one
1401
1402 /* == gem perfection handling over == */
1403
1404 /* == profession specialization handling == */
1405
1406 // init items_count to 1, since 1 item will be created regardless of specialization
1407 int items_count=1;
1408 // the chance to create additional items
1409 float additionalCreateChance=0.0f;
1410 // the maximum number of created additional items
1411 uint8 additionalMaxNum=0;
1412 // get the chance and maximum number for creating extra items
1413 if (CanCreateExtraItems(player, m_spellInfo->Id, additionalCreateChance, additionalMaxNum))
1414 // roll with this chance till we roll not to create or we create the max num
1415 while (roll_chance(additionalCreateChance) && items_count <= additionalMaxNum)
1416 ++items_count;
1417
1418 // really will be created more items
1419 num_to_add *= items_count;
1420
1421 /* == profession specialization handling over == */
1422
1423 // can the player store the new item?
1424 ItemPosCountVec dest;
1425 uint32 no_space = 0;
1426 InventoryResult msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, newitemid, num_to_add, &no_space);
1427 if (msg != EQUIP_ERR_OK)
1428 {
1429 // convert to possible store amount
1430 if (msg == EQUIP_ERR_INV_FULL || msg == EQUIP_ERR_ITEM_MAX_COUNT)
1431 num_to_add -= no_space;
1432 else
1433 {
1434 // if not created by another reason from full inventory or unique items amount limitation
1435 player->SendEquipError(msg, nullptr, nullptr, newitemid);
1436 return;
1437 }
1438 }
1439
1440 if (num_to_add)
1441 {
1442 // create the new item and store it
1443 if (Item* pItem = player->StoreNewItem(dest, newitemid, true, GenerateItemRandomBonusListId(newitemid), GuidSet(), context, bonusListIDs))
1444 {
1445 // set the "Crafted by ..." property of the item
1446 if (pItem->GetTemplate()->HasSignature())
1447 pItem->SetCreator(player->GetGUID());
1448
1449 // send info to the client
1450 player->SendNewItem(pItem, num_to_add, true, true);
1451
1452 if (pItem->GetQuality() > ITEM_QUALITY_EPIC || (pItem->GetQuality() == ITEM_QUALITY_EPIC && pItem->GetItemLevel(player) >= MinNewsItemLevel))
1453 if (Guild* guild = player->GetGuild())
1454 guild->AddGuildNews(GUILD_NEWS_ITEM_CRAFTED, player->GetGUID(), 0, pProto->GetId());
1455 }
1456
1457 // we succeeded in creating at least one item, so a levelup is possible
1458 if (!m_CastItem)
1460 }
1461}
1462
1471
1473{
1475 return;
1476
1478 return;
1479
1480 Player* player = unitTarget->ToPlayer();
1481
1483
1484 // Pick a random item from spell_loot_template
1486 {
1487 player->AutoStoreLoot(m_spellInfo->Id, LootTemplates_Spell, context, false, true);
1488 if (!m_CastItem)
1490 }
1491 else // If there's no random loot entries for this spell, pick the item associated with this spell
1492 {
1493 uint32 item_id = effectInfo->ItemType;
1494
1495 if (item_id)
1496 DoCreateItem(item_id, context);
1497 }
1498
1500}
1501
1515
1517{
1519 return;
1520
1521 Unit* unitCaster = GetUnitCasterForEffectHandlers();
1522 if (!unitCaster)
1523 return;
1524
1525 // Caster not in world, might be spell triggered from aura removal
1526 if (!unitCaster->IsInWorld())
1527 return;
1528
1529 // only handle at last effect
1530 for (size_t i = effectInfo->EffectIndex + 1; i < m_spellInfo->GetEffects().size(); ++i)
1532 return;
1533
1535
1536 float radius = 0.0f;
1537 for (size_t i = 0; i <= effectInfo->EffectIndex; ++i)
1538 {
1539 SpellEffectInfo const& spellEffectInfo = m_spellInfo->GetEffect(SpellEffIndex(i));
1540 if (spellEffectInfo.IsEffect(SPELL_EFFECT_PERSISTENT_AREA_AURA))
1541 radius = std::max(radius, spellEffectInfo.CalcRadius(unitCaster).Max);
1542 }
1543
1544 DynamicObject* dynObj = new DynamicObject(false);
1546 {
1547 delete dynObj;
1548 return;
1549 }
1550
1552 createInfo
1553 .SetCaster(unitCaster)
1556
1557 if (Aura* aura = Aura::TryCreate(createInfo))
1558 {
1559 _dynObjAura = aura->ToDynObjAura();
1561 }
1562 else
1563 return;
1564
1566 for (size_t i = 0; i < m_spellInfo->GetEffects().size(); ++i)
1569
1570 if (m_spellInfo->IsChanneled())
1571 unitCaster->AddChannelObject(dynObj->GetGUID());
1572}
1573
1575{
1577 return;
1578
1579 Unit* unitCaster = GetUnitCasterForEffectHandlers();
1580 if (!unitCaster || !unitTarget)
1581 return;
1582
1583 if (!unitTarget->IsAlive())
1584 return;
1585
1587 return;
1588
1590 if (unitTarget->GetMaxPower(power) == 0)
1591 return;
1592
1593 int32 energizeAmount = GetEffectValueAsInt();
1594 // Some level depends spells
1595 switch (m_spellInfo->Id)
1596 {
1597 case 24571: // Blood Fury
1598 // Instantly increases your rage by ${(300-10*$max(0,$PL-60))/10}.
1599 energizeAmount -= 10 * std::max(0, std::min(30, unitCaster->GetLevel() - 60));
1600 break;
1601 case 24532: // Burst of Energy
1602 // Instantly increases your energy by ${60-4*$max(0,$min(15,$PL-60))}.
1603 energizeAmount -= 4 * std::max(0, std::min(15, unitCaster->GetLevel() - 60));
1604 break;
1605 case 67490: // Runic Mana Injector (mana gain increased by 25% for engineers - 3.2.0 patch change)
1606 {
1607 if (Player* player = unitCaster->ToPlayer())
1608 if (player->HasSkill(SKILL_ENGINEERING))
1609 AddPct(energizeAmount, 25);
1610 break;
1611 }
1612 default:
1613 break;
1614 }
1615
1616 unitCaster->EnergizeBySpell(unitTarget, m_spellInfo, energizeAmount, power);
1617}
1618
1620{
1622 return;
1623
1624 Unit* unitCaster = GetUnitCasterForEffectHandlers();
1625 if (!unitCaster || !unitTarget)
1626 return;
1627
1628 if (!unitTarget->IsAlive())
1629 return;
1630
1632 return;
1633
1635 uint32 maxPower = unitTarget->GetMaxPower(power);
1636 if (!maxPower)
1637 return;
1638
1639 uint32 const gain = CalculatePct(maxPower, effectValue);
1640 unitCaster->EnergizeBySpell(unitTarget, m_spellInfo, gain, power);
1641}
1642
1644{
1646 return;
1647
1649 {
1650 TC_LOG_DEBUG("spells", "WORLD: Open Lock - No Player Caster!");
1651 return;
1652 }
1653
1654 Player* player = m_caster->ToPlayer();
1655
1656 uint32 lockId = 0;
1657 ObjectGuid guid;
1658
1659 // Get lockId
1660 if (gameObjTarget)
1661 {
1662 GameObjectTemplate const* goInfo = gameObjTarget->GetGOInfo();
1663
1664 if (goInfo->GetNoDamageImmune() && player->HasUnitFlag(UNIT_FLAG_IMMUNE))
1665 return;
1666
1668 {
1670 return;
1671 }
1673 // handle outdoor pvp object opening, return true if go was registered for handling
1674 // these objects must have been spawned by outdoorpvp!
1675 else if (gameObjTarget->GetGOInfo()->type == GAMEOBJECT_TYPE_GOOBER && sOutdoorPvPMgr->HandleOpenGo(player, gameObjTarget))
1676 return;
1677 lockId = goInfo->GetLockId();
1678 guid = gameObjTarget->GetGUID();
1679 }
1680 else if (itemTarget)
1681 {
1682 lockId = itemTarget->GetTemplate()->GetLockID();
1683 guid = itemTarget->GetGUID();
1684 }
1685 else
1686 {
1687 TC_LOG_DEBUG("spells", "WORLD: Open Lock - No GameObject/Item Target!");
1688 return;
1689 }
1690
1691 SkillType skillId = SKILL_NONE;
1692 int32 reqSkillValue = 0;
1693 int32 skillValue;
1694
1695 SpellCastResult res = CanOpenLock(*effectInfo, lockId, skillId, reqSkillValue, skillValue);
1696 if (res != SPELL_CAST_OK)
1697 {
1698 SendCastResult(res);
1699 return;
1700 }
1701
1702 if (gameObjTarget)
1703 gameObjTarget->Use(player, true);
1704 else if (itemTarget)
1705 {
1708 }
1709
1710 // not allow use skill grow at item base open
1711 if (!m_CastItem && skillId != SKILL_NONE)
1712 {
1713 // update skill if really known
1714 if (uint32 pureSkillValue = player->GetPureSkillValue(skillId))
1715 {
1716 if (gameObjTarget)
1717 {
1718 // Allow one skill-up until respawned
1719 if (!gameObjTarget->IsInSkillupList(player->GetGUID()))
1720 {
1721 player->UpdateGatherSkill(skillId, pureSkillValue, reqSkillValue, 1, gameObjTarget);
1723 }
1724 }
1725 else if (itemTarget)
1726 {
1727 // Do one skill-up
1728 player->UpdateGatherSkill(skillId, pureSkillValue, reqSkillValue);
1729 }
1730 }
1731 }
1733}
1734
1736{
1738 return;
1739
1741 return;
1742
1743 Player* player = m_caster->ToPlayer();
1744
1745 // applied only to using item
1746 if (!m_CastItem)
1747 return;
1748
1749 // ... only to item in own inventory/bank/equip_slot
1750 if (m_CastItem->GetOwnerGUID() != player->GetGUID())
1751 return;
1752
1753 uint32 newitemid = effectInfo->ItemType;
1754 if (!newitemid)
1755 return;
1756
1757 uint16 pos = m_CastItem->GetPos();
1758
1759 Item* pNewItem = Item::CreateItem(newitemid, 1, m_CastItem->GetContext(), player);
1760 if (!pNewItem)
1761 return;
1762
1766
1767 if (*m_CastItem->m_itemData->Durability < *m_CastItem->m_itemData->MaxDurability)
1768 {
1769 double lossPercent = 1 - *m_CastItem->m_itemData->Durability / double(m_CastItem->m_itemData->MaxDurability);
1770 player->DurabilityLoss(pNewItem, lossPercent);
1771 }
1772
1773 if (player->IsInventoryPos(pos))
1774 {
1775 ItemPosCountVec dest;
1776 InventoryResult msg = player->CanStoreItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), dest, pNewItem, true);
1777 if (msg == EQUIP_ERR_OK)
1778 {
1779 player->DestroyItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), true);
1780
1781 // prevent crash at access and unexpected charges counting with item update queue corrupt
1783 m_targets.SetItemTarget(nullptr);
1784
1785 m_CastItem = nullptr;
1787 m_castItemEntry = 0;
1788 m_castItemLevel = -1;
1789
1790 player->StoreItem(dest, pNewItem, true);
1791 player->SendNewItem(pNewItem, 1, true, false);
1792 player->ItemAddedQuestCheck(newitemid, 1);
1793 return;
1794 }
1795 }
1796 else if (player->IsBankPos(pos))
1797 {
1798 ItemPosCountVec dest;
1799 if (player->CanBankItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), dest, pNewItem, true) == EQUIP_ERR_OK)
1800 {
1801 player->DestroyItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), true);
1802
1803 // prevent crash at access and unexpected charges counting with item update queue corrupt
1805 m_targets.SetItemTarget(nullptr);
1806
1807 m_CastItem = nullptr;
1809 m_castItemEntry = 0;
1810 m_castItemLevel = -1;
1811
1812 player->BankItem(dest, pNewItem, true);
1813 return;
1814 }
1815 }
1816 else if (player->IsEquipmentPos(pos))
1817 {
1818 uint16 dest;
1819
1820 player->DestroyItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), true);
1821
1822 InventoryResult msg = player->CanEquipItem(m_CastItem->GetSlot(), dest, pNewItem, true);
1823
1824 if (msg == EQUIP_ERR_OK || msg == EQUIP_ERR_CLIENT_LOCKED_OUT)
1825 {
1827
1828 // prevent crash at access and unexpected charges counting with item update queue corrupt
1830 m_targets.SetItemTarget(nullptr);
1831
1832 m_CastItem = nullptr;
1834 m_castItemEntry = 0;
1835 m_castItemLevel = -1;
1836
1837 player->EquipItem(dest, pNewItem, true);
1838 player->AutoUnequipOffhandIfNeed();
1839 player->SendNewItem(pNewItem, 1, true, false);
1840 player->ItemAddedQuestCheck(newitemid, 1);
1841 return;
1842 }
1843 }
1844
1845 // fail
1846 delete pNewItem;
1847}
1848
1850{
1852 return;
1853
1855 return;
1856 Player* p_target = m_caster->ToPlayer();
1857
1859 if (m_spellInfo->EquippedItemClass == ITEM_CLASS_WEAPON && !(p_target->GetWeaponProficiency() & subClassMask))
1860 {
1861 p_target->AddWeaponProficiency(subClassMask);
1863 }
1864 if (m_spellInfo->EquippedItemClass == ITEM_CLASS_ARMOR && !(p_target->GetArmorProficiency() & subClassMask))
1865 {
1866 p_target->AddArmorProficiency(subClassMask);
1868 }
1869}
1870
1872{
1874 return;
1875
1876 uint32 entry = effectInfo->MiscValue;
1877 if (!entry)
1878 return;
1879
1880 SummonPropertiesEntry const* properties = sSummonPropertiesStore.LookupEntry(effectInfo->MiscValueB);
1881 if (!properties)
1882 {
1883 TC_LOG_ERROR("spells", "EffectSummonType: Unhandled summon type {}.", effectInfo->MiscValueB);
1884 return;
1885 }
1886
1887 WorldObject* caster = m_caster;
1888 if (m_originalCaster)
1889 caster = m_originalCaster;
1890
1891 ObjectGuid privateObjectOwner = [&]()
1892 {
1894 return ObjectGuid::Empty;
1895
1896 if (caster->IsPrivateObject())
1897 return caster->GetPrivateObjectOwner();
1898
1900 if (caster->IsPlayer() && m_originalCaster->ToPlayer()->GetGroup())
1901 return caster->ToPlayer()->GetGroup()->GetGUID();
1902
1903 return caster->GetGUID();
1904 }();
1905
1907
1908 Unit* unitCaster = GetUnitCasterForEffectHandlers();
1909
1910 TempSummon* summon = nullptr;
1911
1912 // determine how many units should be summoned
1913 uint32 numSummons;
1914
1915 // some spells need to summon many units, for those spells number of summons is stored in effect value
1916 // however so far noone found a generic check to find all of those (there's no related data in summonproperties.dbc
1917 // and in spell attributes, possibly we need to add a table for those)
1918 // so here's a list of MiscValueB values, which is currently most generic check
1919 switch (effectInfo->MiscValueB)
1920 {
1921 case 64:
1922 case 61:
1923 case 1101:
1924 case 66:
1925 case 648:
1926 case 2301:
1927 case 1061:
1928 case 1261:
1929 case 629:
1930 case 181:
1931 case 715:
1932 case 1562:
1933 case 833:
1934 case 1161:
1935 case 713:
1936 numSummons = std::max(GetEffectValueAsInt(), 1);
1937 break;
1938 default:
1939 numSummons = 1;
1940 break;
1941 }
1942
1943 switch (properties->Control)
1944 {
1947 {
1949 {
1950 SummonGuardian(effectInfo, entry, properties, numSummons, privateObjectOwner);
1951 break;
1952 }
1953
1954 switch (SummonTitle(properties->Title))
1955 {
1956 case SummonTitle::Pet:
1960 SummonGuardian(effectInfo, entry, properties, numSummons, privateObjectOwner);
1961 break;
1962 // Summons a vehicle, but doesn't force anyone to enter it (see SUMMON_CATEGORY_VEHICLE)
1964 case SummonTitle::Mount:
1965 {
1966 if (!unitCaster)
1967 return;
1968
1969 summon = unitCaster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, unitCaster, m_spellInfo->Id, 0, privateObjectOwner);
1970 break;
1971 }
1973 case SummonTitle::Totem:
1974 {
1975 if (!unitCaster)
1976 return;
1977
1978 summon = unitCaster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, unitCaster, m_spellInfo->Id, 0, privateObjectOwner);
1979 if (!summon || !summon->IsTotem())
1980 return;
1981
1982 if (int32 health = GetEffectValueAsInt()) // if not spell info, DB values used
1983 {
1984 summon->SetMaxHealth(health);
1985 summon->SetHealth(health);
1986 }
1987 break;
1988 }
1990 {
1991 if (!unitCaster)
1992 return;
1993
1994 summon = unitCaster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, unitCaster, m_spellInfo->Id, 0, privateObjectOwner);
1995 if (!summon || !summon->HasUnitTypeMask(UNIT_MASK_MINION))
1996 return;
1997
1998 summon->SetImmuneToAll(true);
1999 break;
2000 }
2001 default:
2002 {
2003 SpellRange radius = effectInfo->CalcRadius();
2004
2006 if (duration == 0ms)
2007 summonType = TEMPSUMMON_DEAD_DESPAWN;
2008 else if (duration == -1ms)
2009 summonType = TEMPSUMMON_MANUAL_DESPAWN;
2010 else if (properties->GetFlags().HasFlag(SummonPropertiesFlags::UseDemonTimeout))
2012
2013 for (uint32 count = 0; count < numSummons; ++count)
2014 {
2015 Position pos;
2016 if (count == 0)
2017 pos = destTarget->GetPosition();
2018 else
2019 // randomize position for multiple summons
2020 pos = caster->GetRandomPoint(*destTarget, radius.Max, radius.Min);
2021
2022 summon = caster->GetMap()->SummonCreature(entry, pos, properties, duration, unitCaster, m_spellInfo->Id, 0, privateObjectOwner);
2023 if (!summon)
2024 continue;
2025
2026 summon->SetTempSummonType(summonType);
2027 if (properties->Control == SUMMON_CATEGORY_ALLY)
2028 summon->SetOwnerGUID(caster->GetGUID());
2029 else if (properties->Control == SUMMON_CATEGORY_WILD && caster->IsPlayer()) // there might be more conditions involved
2030 summon->SetDemonCreatorGUID(caster->GetGUID());
2031
2033 }
2034 return;
2035 }
2036 }
2037 break;
2038 }
2040 SummonGuardian(effectInfo, entry, properties, numSummons, privateObjectOwner);
2041 break;
2043 {
2044 if (!unitCaster)
2045 return;
2046
2047 summon = unitCaster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, unitCaster, m_spellInfo->Id, 0, privateObjectOwner);
2048 break;
2049 }
2052 {
2053 if (!unitCaster)
2054 return;
2055
2056 // Summoning spells (usually triggered by npc_spellclick) that spawn a vehicle and that cause the clicker
2057 // to cast a ride vehicle spell on the summoned unit.
2058 summon = unitCaster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, unitCaster, m_spellInfo->Id, 0, privateObjectOwner);
2059 if (!summon || !summon->IsVehicle())
2060 return;
2061
2062 // The spell that this effect will trigger. It has SPELL_AURA_CONTROL_VEHICLE
2064 SpellEffectValue basePoints = effectInfo->CalcValue();
2065 if (basePoints > MAX_VEHICLE_SEATS)
2066 {
2067 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(basePoints, GetCastDifficulty());
2068 if (spellInfo && spellInfo->HasAura(SPELL_AURA_CONTROL_VEHICLE))
2069 spellId = spellInfo->Id;
2070 }
2071
2073 args.SetTriggeringSpell(this);
2074
2075 // if we have small value, it indicates seat position
2076 if (basePoints > 0 && basePoints < MAX_VEHICLE_SEATS)
2077 args.AddSpellMod(SPELLVALUE_BASE_POINT0, basePoints);
2078
2079 unitCaster->CastSpell(summon, spellId, args);
2080 break;
2081 }
2082 }
2083
2084 if (summon)
2085 {
2086 summon->SetCreatorGUID(caster->GetGUID());
2088 }
2089}
2090
2092{
2094 return;
2095
2096 if (!unitTarget)
2097 return;
2098
2100 {
2101 if (unitTarget->ToPet())
2103 return;
2104 }
2105
2106 Player* player = unitTarget->ToPlayer();
2107
2109 {
2110 for (ItemEffectEntry const* itemEffect : m_CastItem->GetEffects())
2111 {
2112 if (itemEffect->TriggerType != ITEM_SPELLTRIGGER_ON_LEARN)
2113 continue;
2114
2115 bool dependent = false;
2116
2117 if (BattlePetSpeciesEntry const* speciesEntry = BattlePets::BattlePetMgr::GetBattlePetSpeciesBySpell(uint32(itemEffect->SpellID)))
2118 {
2119 player->GetSession()->GetBattlePetMgr()->AddPet(speciesEntry->ID, BattlePets::BattlePetMgr::SelectPetDisplay(speciesEntry),
2121 // If the spell summons a battle pet, we fake that it has been learned and the battle pet is added
2122 // marking as dependent prevents saving the spell to database (intended)
2123 dependent = true;
2124 }
2125
2126 player->LearnSpell(itemEffect->SpellID, dependent);
2127 }
2128 }
2129
2131 {
2132 player->LearnSpell(effectInfo->TriggerSpell, false);
2133 TC_LOG_DEBUG("spells", "Spell: Player {} has learned spell {} from Npc {}", player->GetGUID().ToString(), effectInfo->TriggerSpell, m_caster->GetGUID().ToString());
2134 }
2135}
2136
2138{
2140 return;
2141
2142 if (!unitTarget)
2143 return;
2144
2145 // Create dispel mask by dispel type
2146 uint32 dispel_type = effectInfo->MiscValue;
2147 uint32 dispelMask = SpellInfo::GetDispelMask(DispelType(dispel_type));
2148
2149 DispelChargesList dispelList;
2151 if (dispelList.empty())
2152 return;
2153
2154 size_t remaining = dispelList.size();
2155
2156 int32 dispelAmount = GetEffectValueAsInt();
2157
2158 // Ok if exist some buffs for dispel try dispel it
2159 DispelChargesList successList;
2160 successList.reserve(dispelAmount);
2161
2163 dispelFailed.CasterGUID = m_caster->GetGUID();
2164 dispelFailed.VictimGUID = unitTarget->GetGUID();
2165 dispelFailed.SpellID = m_spellInfo->Id;
2166
2167 // dispel N = damage buffs (or while exist buffs for dispel)
2168 for (int32 count = 0; count < dispelAmount && remaining > 0;)
2169 {
2170 // Random select buff for dispel
2171 auto itr = dispelList.begin();
2172 std::advance(itr, urand(0, remaining - 1));
2173
2174 if (itr->RollDispel())
2175 {
2176 auto successItr = std::find_if(successList.begin(), successList.end(), [&itr](DispelableAura& dispelAura) -> bool
2177 {
2178 if (dispelAura.GetAura()->GetId() == itr->GetAura()->GetId() && dispelAura.GetAura()->GetCaster() == itr->GetAura()->GetCaster())
2179 return true;
2180
2181 return false;
2182 });
2183
2184 uint8 dispelledCharges = 1;
2185 if (itr->GetAura()->GetSpellInfo()->HasAttribute(SPELL_ATTR1_DISPEL_ALL_STACKS))
2186 dispelledCharges = itr->GetDispelCharges();
2187
2188 if (successItr == successList.end())
2189 successList.emplace_back(itr->GetAura(), 0, dispelledCharges);
2190 else
2191 successItr->IncrementCharges();
2192
2193 if (!itr->DecrementCharge(dispelledCharges))
2194 {
2195 --remaining;
2196 std::swap(*itr, dispelList[remaining]);
2197 }
2198 }
2199 else
2200 {
2201 dispelFailed.FailedSpells.push_back(int32(itr->GetAura()->GetId()));
2202 }
2203 ++count;
2204 }
2205
2206 if (!dispelFailed.FailedSpells.empty())
2207 m_caster->SendMessageToSet(dispelFailed.Write(), true);
2208
2209 if (successList.empty())
2210 return;
2211
2213 spellDispellLog.IsBreak = false; // TODO: use me
2214 spellDispellLog.IsSteal = false;
2215
2216 spellDispellLog.TargetGUID = unitTarget->GetGUID();
2217 spellDispellLog.CasterGUID = m_caster->GetGUID();
2218 spellDispellLog.DispelledBySpellID = m_spellInfo->Id;
2219
2220 for (DispelableAura const& dispelableAura : successList)
2221 {
2223 dispellData.SpellID = dispelableAura.GetAura()->GetId();
2224 dispellData.Harmful = false; // TODO: use me
2225
2226 unitTarget->RemoveAurasDueToSpellByDispel(dispelableAura.GetAura()->GetId(), m_spellInfo->Id, dispelableAura.GetAura()->GetCasterGUID(), m_caster, dispelableAura.GetDispelCharges());
2227
2228 spellDispellLog.DispellData.emplace_back(dispellData);
2229 }
2230
2231 m_caster->SendMessageToSet(spellDispellLog.Write(), true);
2232
2234
2236 PROC_SPELL_TYPE_MASK_ALL, PROC_SPELL_PHASE_HIT, PROC_HIT_NONE, nullptr, nullptr, nullptr);
2237
2238 std::ranges::find(m_UniqueTargetInfo, unitTarget->GetGUID(), &TargetInfo::TargetGUID)->ProcHitMask |= PROC_HIT_DISPEL;
2239}
2240
2242{
2244 return;
2245
2247}
2248
2250{
2252 return;
2253
2254 // Check for possible target
2255 if (!unitTarget || unitTarget->IsEngaged())
2256 return;
2257
2258 // target must be OK to do this
2260 return;
2261
2263}
2264
2266{
2268 return;
2269
2270 Player* player = m_caster->ToPlayer();
2272 return;
2273
2275 if (!creature)
2276 return;
2277
2278 if (creature->CanGeneratePickPocketLoot())
2279 {
2280 creature->StartPickPocketRefillTimer();
2281
2282 creature->m_loot.reset(new Loot(creature->GetMap(), creature->GetGUID(), LOOT_PICKPOCKETING, nullptr));
2283 if (uint32 lootid = creature->GetCreatureDifficulty()->PickPocketLootID)
2284 creature->m_loot->FillLoot(lootid, LootTemplates_Pickpocketing, player, true);
2285
2286 // Generate extra money for pick pocket loot
2287 const uint32 a = urand(0, creature->GetLevel() / 2);
2288 const uint32 b = urand(0, player->GetLevel() / 2);
2289 creature->m_loot->gold = uint32(10 * (a + b) * sWorld->getRate(RATE_DROP_MONEY));
2290 }
2291 else if (creature->m_loot)
2292 {
2293 if (creature->m_loot->loot_type == LOOT_PICKPOCKETING && creature->m_loot->isLooted())
2294 player->SendLootError(creature->m_loot->GetGUID(), creature->GetGUID(), LOOT_ERROR_ALREADY_PICKPOCKETED);
2295
2296 return;
2297 }
2298
2299 player->SendLoot(*creature->m_loot);
2300}
2301
2303{
2305 return;
2306
2307 Player* player = m_caster->ToPlayer();
2308 if (!player)
2309 return;
2310
2311 float radius = effectInfo->CalcRadius().Max;
2313 // Caster not in world, might be spell triggered from aura removal
2314 if (!player->IsInWorld())
2315 return;
2316
2317 DynamicObject* dynObj = new DynamicObject(true);
2319 {
2320 delete dynObj;
2321 return;
2322 }
2323
2324 dynObj->SetDuration(duration);
2325 dynObj->SetCasterViewpoint();
2326}
2327
2338
2340{
2342 return;
2343
2344 if (!unitTarget)
2345 return;
2346
2347 if (unitTarget->IsInFlight())
2348 return;
2349
2350 if (!m_targets.HasDst())
2351 return;
2352
2353 TeleportLocation targetDest{ .Location = *destTarget };
2354 if (ObjectGuid transportGuid = m_destTargets[effectInfo->EffectIndex]._transportGUID; !transportGuid.IsEmpty())
2355 {
2356 targetDest.TransportGuid = transportGuid;
2358 targetDest.Location.SetOrientation(destTarget->GetAbsoluteAngle(m_caster) - targetDest.Location.GetOrientation());
2359 }
2360 else
2361 targetDest.Location.SetOrientation(destTarget->GetAbsoluteAngle(m_caster));
2362
2364}
2365
2367{
2369 return;
2370
2371 Player* playerTarget = Object::ToPlayer(unitTarget);
2372 if (!playerTarget)
2373 return;
2374
2375 uint16 skillTier = GetEffectValueAsInt();
2376 if (skillTier < 1)
2377 return;
2378
2379 uint32 skillid = effectInfo->MiscValue;
2380 SkillRaceClassInfoEntry const* rcEntry = sDB2Manager.GetSkillRaceClassInfo(skillid, playerTarget->GetRace(), playerTarget->GetClass());
2381 if (!rcEntry)
2382 return;
2383
2384 SkillTiersEntry const* tier = sObjectMgr->GetSkillTier(rcEntry->SkillTierID);
2385 if (!tier)
2386 return;
2387
2388 uint16 skillval = std::max<uint16>(1, playerTarget->GetPureSkillValue(skillid));
2389 uint16 maxSkillVal = tier->GetValueForTierIndex(skillTier - 1);
2390
2391 if (rcEntry->Flags & SKILL_FLAG_ALWAYS_MAX_VALUE)
2392 skillval = maxSkillVal;
2393
2394 playerTarget->SetSkill(skillid, skillTier, skillval, maxSkillVal);
2395}
2396
2398{
2400 return;
2401
2403 return;
2404
2405 uint32 movieId = effectInfo->MiscValue;
2406 if (!sMovieStore.LookupEntry(movieId))
2407 return;
2408
2409 unitTarget->ToPlayer()->SendMovieStart(movieId);
2410}
2411
2413{
2415 return;
2416
2418 return;
2419 // uint32 skillid = m_spellInfo->Effects[i].MiscValue;
2420 // uint16 skillmax = unitTarget->ToPlayer()->(skillid);
2421 // m_caster->ToPlayer()->SetSkill(skillid, skillval?skillval:1, skillmax+75);
2422}
2423
2425{
2427 return;
2428
2429 if (!itemTarget)
2430 return;
2431
2432 Player* player = m_caster->ToPlayer();
2433 if (!player)
2434 return;
2435
2436 // Handle vellums
2437 if (itemTarget->IsVellum())
2438 {
2439 // destroy one vellum from stack
2440 uint32 count = 1;
2441 player->DestroyItemCount(itemTarget, count, true);
2442 unitTarget = player;
2443 // and add a scroll
2444 effectValue = 1.0;
2446 itemTarget = nullptr;
2447 m_targets.SetItemTarget(nullptr);
2448 }
2449 else
2450 {
2451 // do not increase skill if vellum used
2452 if (!m_CastItem)
2454
2455 uint32 enchant_id = effectInfo->MiscValue;
2456 if (!enchant_id)
2457 return;
2458
2459 SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
2460 if (!pEnchant)
2461 return;
2462
2463 // item can be in trade slot and have owner diff. from caster
2464 Player* item_owner = itemTarget->GetOwner();
2465 if (!item_owner)
2466 return;
2467
2468 if (item_owner != player && player->GetSession()->HasPermission(rbac::RBAC_PERM_LOG_GM_TRADE))
2469 {
2470 sLog->OutCommand(player->GetSession()->GetAccountId(), "GM {} (Account: {}) enchanting(perm): {} (Entry: {}) for player: {} (Account: {})",
2471 player->GetName(), player->GetSession()->GetAccountId(),
2473 item_owner->GetName(), item_owner->GetSession()->GetAccountId());
2474 }
2475
2476 // remove old enchanting before applying new if equipped
2478
2480
2481 // add new enchanting if equipped
2483
2484 item_owner->RemoveTradeableItem(itemTarget);
2486 }
2487}
2488
2490{
2492 return;
2493
2494 if (!itemTarget)
2495 return;
2496
2497 Player* player = m_caster->ToPlayer();
2498 if (!player)
2499 return;
2500
2501 uint32 enchantId = effectInfo->MiscValue;
2502 if (!enchantId)
2503 return;
2504
2505 SpellItemEnchantmentEntry const* enchant = sSpellItemEnchantmentStore.LookupEntry(enchantId);
2506 if (!enchant)
2507 return;
2508
2509 // support only enchantings with add socket in this slot
2510 {
2511 bool add_socket = false;
2512 for (uint8 i = 0; i < MAX_ITEM_ENCHANTMENT_EFFECTS; ++i)
2513 {
2515 {
2516 add_socket = true;
2517 break;
2518 }
2519 }
2520 if (!add_socket)
2521 {
2522 TC_LOG_ERROR("spells", "Spell::EffectEnchantItemPrismatic: attempt to apply the enchant spell {} with SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC ({}), but without ITEM_ENCHANTMENT_TYPE_PRISMATIC_SOCKET ({}), not supported yet.",
2524 return;
2525 }
2526 }
2527
2528 // item can be in trade slot and have owner diff. from caster
2529 Player* item_owner = itemTarget->GetOwner();
2530 if (!item_owner)
2531 return;
2532
2533 if (item_owner != player && player->GetSession()->HasPermission(rbac::RBAC_PERM_LOG_GM_TRADE))
2534 {
2535 sLog->OutCommand(player->GetSession()->GetAccountId(), "GM {} (Account: {}) enchanting(perm): {} (Entry: {}) for player: {} (Account: {})",
2536 player->GetName(), player->GetSession()->GetAccountId(),
2538 item_owner->GetName(), item_owner->GetSession()->GetAccountId());
2539 }
2540
2541 // remove old enchanting before applying new if equipped
2543
2545
2546 // add new enchanting if equipped
2548
2549 item_owner->RemoveTradeableItem(itemTarget);
2551}
2552
2554{
2556 return;
2557
2558 if (!itemTarget)
2559 return;
2560
2561 Player* player = m_caster->ToPlayer();
2562 if (!player)
2563 return;
2564
2565 uint32 enchant_id = effectInfo->MiscValue;
2566
2567 if (!enchant_id)
2568 {
2569 TC_LOG_ERROR("spells", "Spell {} Effect {} (SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY) has enchanting id 0.", m_spellInfo->Id, effectInfo->EffectIndex);
2570 return;
2571 }
2572
2573 SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
2574 if (!pEnchant)
2575 {
2576 TC_LOG_ERROR("spells", "Spell {} Effect {} (SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY) has a non-existing enchanting id {} ", m_spellInfo->Id, effectInfo->EffectIndex, enchant_id);
2577 return;
2578 }
2579
2580 // select enchantment duration
2581 uint32 duration = pEnchant->Duration;
2582
2583 // item can be in trade slot and have owner diff. from caster
2584 Player* item_owner = itemTarget->GetOwner();
2585 if (!item_owner)
2586 return;
2587
2588 if (item_owner != player && player->GetSession()->HasPermission(rbac::RBAC_PERM_LOG_GM_TRADE))
2589 {
2590 sLog->OutCommand(player->GetSession()->GetAccountId(), "GM {} (Account: {}) enchanting(temp): {} (Entry: {}) for player: {} (Account: {})",
2591 player->GetName(), player->GetSession()->GetAccountId(),
2593 item_owner->GetName(), item_owner->GetSession()->GetAccountId());
2594 }
2595
2596 // remove old enchanting before applying new if equipped
2598
2599 itemTarget->SetEnchantment(TEMP_ENCHANTMENT_SLOT, enchant_id, duration * 1000, 0, m_caster->GetGUID());
2600
2601 // add new enchanting if equipped
2603}
2604
2606{
2608 return;
2609
2610 Unit* unitCaster = GetUnitCasterForEffectHandlers();
2611 if (!unitCaster || !unitCaster->GetPetGUID().IsEmpty())
2612 return;
2613
2614 if (!unitTarget)
2615 return;
2616
2618 return;
2619
2620 Creature* creatureTarget = unitTarget->ToCreature();
2621
2622 if (creatureTarget->IsPet())
2623 return;
2624
2625 if (unitCaster->GetClass() != CLASS_HUNTER)
2626 return;
2627
2628 // cast finish successfully
2629 //SendChannelUpdate(0);
2630 finish();
2631
2632 Pet* pet = unitCaster->CreateTamedPetFrom(creatureTarget, m_spellInfo->Id);
2633 if (!pet) // in very specific state like near world end/etc.
2634 return;
2635
2636 // "kill" original creature
2637 creatureTarget->DespawnOrUnsummon();
2638
2639 uint8 level = (creatureTarget->GetLevelForTarget(m_caster) < (m_caster->GetLevelForTarget(creatureTarget) - 5)) ? (m_caster->GetLevelForTarget(creatureTarget) - 5) : creatureTarget->GetLevelForTarget(m_caster);
2640
2641 // prepare visual effect for levelup
2642 pet->SetLevel(level - 1);
2643
2644 // add to world
2645 pet->GetMap()->AddToMap(pet->ToCreature());
2646
2647 // visual effect for levelup
2648 pet->SetLevel(level);
2649
2650 // caster have pet now
2651 unitCaster->SetMinion(pet, true);
2652
2653 if (unitCaster->GetTypeId() == TYPEID_PLAYER)
2654 {
2656 unitCaster->ToPlayer()->PetSpellInitialize();
2657 }
2658}
2659
2661{
2663 return;
2664
2665 Player* owner = nullptr;
2666 if (Unit* unitCaster = GetUnitCasterForEffectHandlers())
2667 {
2668 owner = unitCaster->ToPlayer();
2669 if (!owner && unitCaster->IsTotem())
2670 owner = unitCaster->GetCharmerOrOwnerPlayerOrPlayerItself();
2671 }
2672
2673 uint32 petentry = effectInfo->MiscValue;
2674
2675 if (!owner)
2676 {
2677 SummonPropertiesEntry const* properties = sSummonPropertiesStore.LookupEntry(67);
2678 if (properties)
2679 SummonGuardian(effectInfo, petentry, properties, 1, ObjectGuid::Empty);
2680 return;
2681 }
2682
2683 Pet* OldSummon = owner->GetPet();
2684
2685 // if pet requested type already exist
2686 if (OldSummon)
2687 {
2688 if (petentry == 0 || OldSummon->GetEntry() == petentry)
2689 {
2690 // pet in corpse state can't be summoned
2691 if (OldSummon->isDead())
2692 return;
2693
2694 ASSERT(OldSummon->GetMap() == owner->GetMap());
2695
2696 //OldSummon->GetMap()->Remove(OldSummon->ToCreature(), false);
2697
2698 float px, py, pz;
2699 owner->GetClosePoint(px, py, pz, OldSummon->GetCombatReach());
2700
2701 OldSummon->NearTeleportTo(px, py, pz, OldSummon->GetOrientation());
2702 //OldSummon->Relocate(px, py, pz, OldSummon->GetOrientation());
2703 //OldSummon->SetMap(owner->GetMap());
2704 //owner->GetMap()->Add(OldSummon->ToCreature());
2705
2706 if (owner->GetTypeId() == TYPEID_PLAYER && OldSummon->isControlled())
2707 owner->ToPlayer()->PetSpellInitialize();
2708
2709 return;
2710 }
2711
2712 if (owner->GetTypeId() == TYPEID_PLAYER)
2713 owner->ToPlayer()->RemovePet(OldSummon, PET_SAVE_NOT_IN_SLOT, false);
2714 else
2715 return;
2716 }
2717
2718 Optional<PetSaveMode> petSlot;
2719 if (!petentry)
2720 petSlot = PetSaveMode(GetEffectValueAsInt());
2721
2722 float x, y, z;
2723 owner->GetClosePoint(x, y, z, owner->GetCombatReach());
2724 bool isNew = false;
2725 Pet* pet = owner->SummonPet(petentry, petSlot, x, y, z, owner->GetOrientation(), 0, &isNew);
2726 if (!pet)
2727 return;
2728
2729 if (isNew)
2730 {
2731 if (m_caster->GetTypeId() == TYPEID_UNIT)
2732 {
2733 if (m_caster->ToCreature()->IsTotem())
2735 else
2737 }
2738
2740
2741 // generate new name for summon pet
2742 std::string new_name = sObjectMgr->GeneratePetName(petentry);
2743 if (!new_name.empty())
2744 pet->SetName(new_name);
2745 }
2746
2748}
2749
2751{
2753 return;
2754
2755 if (!unitTarget)
2756 return;
2757
2758 if (unitTarget->ToPlayer())
2759 {
2761 return;
2762 }
2763 Pet* pet = unitTarget->ToPet();
2764 if (!pet)
2765 return;
2766
2767 SpellInfo const* learn_spellproto = sSpellMgr->GetSpellInfo(effectInfo->TriggerSpell, DIFFICULTY_NONE);
2768 if (!learn_spellproto)
2769 return;
2770
2771 pet->learnSpell(learn_spellproto->Id);
2773 pet->GetOwner()->PetSpellInitialize();
2774}
2775
2777{
2779 return;
2780
2781 Unit* unitCaster = GetUnitCasterForEffectHandlers();
2782 if (!unitCaster)
2783 return;
2784
2785 // this effect use before aura Taunt apply for prevent taunt already attacking target
2786 // for spell as marked "non effective at already attacking target"
2787 if (!unitTarget || unitTarget->IsTotem())
2788 {
2790 return;
2791 }
2792
2793 // Hand of Reckoning can hit some entities that can't have a threat list (including players' pets)
2794 if (m_spellInfo->Id == 62124)
2795 if (unitTarget->GetTypeId() != TYPEID_PLAYER && unitTarget->GetTarget() != unitCaster->GetGUID())
2796 unitCaster->CastSpell(unitTarget, 67485, true);
2797
2799 {
2801 return;
2802 }
2803
2805 if (mgr.GetCurrentVictim() == unitCaster)
2806 {
2808 return;
2809 }
2810
2811 if (!mgr.IsThreatListEmpty())
2812 // Set threat equal to highest threat currently on target
2813 mgr.MatchUnitThreatToHighestThreat(unitCaster);
2814}
2815
2817{
2819 return;
2820
2821 Unit* unitCaster = GetUnitCasterForEffectHandlers();
2822 if (!unitCaster)
2823 return;
2824
2825 if (!unitTarget || !unitTarget->IsAlive())
2826 return;
2827
2828 // multiple weapon dmg effect workaround
2829 // execute only the last weapon damage
2830 // and handle all effects at once
2831 uint32 effectMask = std::ranges::find(m_UniqueTargetInfo, unitTarget->GetGUID(), &TargetInfo::TargetGUID)->EffectMask;
2832 for (size_t j = effectInfo->EffectIndex + 1; j < m_spellInfo->GetEffects().size(); ++j)
2833 {
2834 if (!(effectMask & (1 << j)))
2835 continue;
2836
2838 {
2843 return; // we must calculate only at last weapon effect
2844 default:
2845 break;
2846 }
2847 }
2848
2849 // some spell specific modifiers
2850 float totalDamagePercentMod = 1.0f; // applied to final bonus+weapon damage
2851 SpellEffectValue fixed_bonus = 0;
2852 SpellEffectValue spell_bonus = 0; // bonus specific for spell
2853
2855 {
2856 case SPELLFAMILY_SHAMAN:
2857 {
2858 // Skyshatter Harness item set bonus
2859 // Stormstrike
2860 if (AuraEffect* aurEff = unitCaster->IsScriptOverriden(m_spellInfo, 5634))
2861 unitCaster->CastSpell(nullptr, 38430, aurEff);
2862 break;
2863 }
2864 }
2865
2866 bool normalized = false;
2867 float weaponDamagePercentMod = 1.0f;
2868 for (SpellEffectInfo const& spellEffectInfo : m_spellInfo->GetEffects())
2869 {
2870 if (!(effectMask & (1 << spellEffectInfo.EffectIndex)))
2871 continue;
2872
2873 switch (spellEffectInfo.Effect)
2874 {
2877 fixed_bonus += CalculateDamage(spellEffectInfo, unitTarget);
2878 break;
2880 fixed_bonus += CalculateDamage(spellEffectInfo, unitTarget);
2881 normalized = true;
2882 break;
2884 ApplyPct(weaponDamagePercentMod, CalculateDamage(spellEffectInfo, unitTarget));
2885 break;
2886 default:
2887 break; // not weapon damage effect, just skip
2888 }
2889 }
2890
2891 // if (addPctMods) { percent mods are added in Unit::CalculateDamage } else { percent mods are added in Unit::MeleeDamageBonusDone }
2892 // this distinction is neccessary to properly inform the client about his autoattack damage values from Script_UnitDamage
2894 if (addPctMods)
2895 {
2896 UnitMods unitMod;
2897 switch (m_attackType)
2898 {
2899 default:
2900 case BASE_ATTACK: unitMod = UNIT_MOD_DAMAGE_MAINHAND; break;
2901 case OFF_ATTACK: unitMod = UNIT_MOD_DAMAGE_OFFHAND; break;
2902 case RANGED_ATTACK: unitMod = UNIT_MOD_DAMAGE_RANGED; break;
2903 }
2904
2905 float weapon_total_pct = unitCaster->GetPctModifierValue(unitMod, TOTAL_PCT);
2906 if (fixed_bonus)
2907 fixed_bonus = fixed_bonus * weapon_total_pct;
2908 if (spell_bonus)
2909 spell_bonus = spell_bonus * weapon_total_pct;
2910 }
2911
2912 SpellEffectValue weaponDamage = unitCaster->CalculateDamage(m_attackType, normalized, addPctMods);
2913 Mechanics mechanic = MECHANIC_NONE;
2914
2915 // Sequence is important
2916 for (SpellEffectInfo const& spellEffectInfo : m_spellInfo->GetEffects())
2917 {
2918 if (!(effectMask & (1 << spellEffectInfo.EffectIndex)))
2919 continue;
2920
2921 // We assume that a spell have at most one fixed_bonus
2922 // and at most one weaponDamagePercentMod
2923 switch (spellEffectInfo.Effect)
2924 {
2928 weaponDamage += fixed_bonus;
2929 break;
2931 weaponDamage = weaponDamage * weaponDamagePercentMod;
2932 break;
2933 default:
2934 continue; // not weapon damage effect, just skip
2935 }
2936
2937 if (spellEffectInfo.Mechanic != MECHANIC_NONE && mechanic == MECHANIC_NONE)
2938 mechanic = spellEffectInfo.Mechanic;
2939 }
2940
2941 weaponDamage += spell_bonus;
2942 weaponDamage = weaponDamage * totalDamagePercentMod;
2943
2944 // prevent negative damage
2945 weaponDamage = std::max(std::round(weaponDamage), 0.0);
2946
2947 // Add melee damage bonuses (also check for negative)
2948 weaponDamage = unitCaster->MeleeDamageBonusDone(unitTarget, weaponDamage, m_attackType, SPELL_DIRECT_DAMAGE, m_spellInfo, effectInfo, mechanic, m_spellSchoolMask, this);
2950}
2951
2953{
2955 return;
2956
2957 Unit* unitCaster = GetUnitCasterForEffectHandlers();
2958 if (!unitCaster || !unitCaster->IsAlive())
2959 return;
2960
2961 if (!unitTarget)
2962 return;
2963
2965 return;
2966
2968}
2969
2971{
2973 return;
2974
2975 Unit* unitCaster = GetUnitCasterForEffectHandlers();
2976 if (!unitCaster)
2977 return;
2978
2979 if (!unitTarget || !unitTarget->IsAlive())
2980 return;
2981
2982 int32 addhealth = 0;
2983
2984 // damage == 0 - heal for caster max health
2985 if (GetEffectValueAsInt() == 0)
2986 addhealth = unitCaster->GetMaxHealth();
2987 else
2988 addhealth = unitTarget->GetMaxHealth() - unitTarget->GetHealth();
2989
2990 m_healing += addhealth;
2991}
2992
2994{
2996 return;
2997
2998 if (!unitTarget || !unitTarget->IsAlive())
2999 return;
3000
3002 // also exist case: apply cooldown to interrupted cast only and to all spells
3003 // there is no CURRENT_AUTOREPEAT_SPELL spells that can be interrupted
3005 {
3007 {
3008 SpellInfo const* curSpellInfo = spell->m_spellInfo;
3009 // check if we can interrupt spell
3010 if ((spell->getState() == SPELL_STATE_CHANNELING
3011 || (spell->getState() == SPELL_STATE_PREPARING && spell->GetCastTime() > 0.0f))
3012 && curSpellInfo->CanBeInterrupted(m_caster, unitTarget))
3013 {
3014 int32 duration = m_spellInfo->GetDuration();
3015 duration = unitTarget->ModSpellDuration(m_spellInfo, unitTarget, duration, false, 1 << effectInfo->EffectIndex);
3017 std::ranges::find(m_UniqueTargetInfo, unitTarget->GetGUID(), &TargetInfo::TargetGUID)->ProcHitMask |= PROC_HIT_INTERRUPT;
3018 SendSpellInterruptLog(unitTarget, curSpellInfo->Id);
3020 }
3021 }
3022 }
3023}
3024
3026{
3028 return;
3029
3030 WorldObject* target = focusObject;
3031 if (!target)
3032 target = m_caster;
3033
3034 float x, y, z, o;
3035 if (m_targets.HasDst())
3036 destTarget->GetPosition(x, y, z, o);
3037 else
3038 {
3040 o = target->GetOrientation();
3041 }
3042
3043 Map* map = target->GetMap();
3044 Position pos = Position(x, y, z, o);
3047 if (!go)
3048 return;
3049
3051
3053
3054 go->SetRespawnTime(duration > 0 ? duration/IN_MILLISECONDS : 0);
3056
3058
3059 // Wild object not have owner and check clickable by players
3060 map->AddToMap(go);
3061
3062 if (GameObject* linkedTrap = go->GetLinkedTrap())
3063 {
3065
3066 linkedTrap->SetRespawnTime(duration > 0 ? duration / IN_MILLISECONDS : 0);
3067 linkedTrap->SetSpellId(m_spellInfo->Id);
3068
3070 }
3071}
3072
3074{
3076 return;
3077
3078 Unit* unitCaster = GetUnitCasterForEffectHandlers();
3079
3083 {
3085 {
3086 switch (m_spellInfo->Id)
3087 {
3088 // Shadow Flame (All script effects, not just end ones to prevent player from dodging the last triggered spell)
3089 case 22539:
3090 case 22972:
3091 case 22975:
3092 case 22976:
3093 case 22977:
3094 case 22978:
3095 case 22979:
3096 case 22980:
3097 case 22981:
3098 case 22982:
3099 case 22983:
3100 case 22984:
3101 case 22985:
3102 {
3103 if (!unitTarget || !unitTarget->IsAlive())
3104 return;
3105
3106 // Onyxia Scale Cloak
3107 if (unitTarget->HasAura(22683))
3108 return;
3109
3110 // Shadow Flame
3111 m_caster->CastSpell(unitTarget, 22682, this);
3112 return;
3113 }
3114 // Mug Transformation
3115 case 41931:
3116 {
3118 return;
3119
3120 uint8 bag = 19;
3121 uint8 slot = 0;
3122 Item* item = nullptr;
3123
3124 while (bag) // 256 = 0 due to var type
3125 {
3126 item = m_caster->ToPlayer()->GetItemByPos(bag, slot);
3127 if (item && item->GetEntry() == 38587)
3128 break;
3129
3130 ++slot;
3131 if (slot == 39)
3132 {
3133 slot = 0;
3134 ++bag;
3135 }
3136 }
3137 if (bag)
3138 {
3139 if (m_caster->ToPlayer()->GetItemByPos(bag, slot)->GetCount() == 1) m_caster->ToPlayer()->RemoveItem(bag, slot, true);
3140 else m_caster->ToPlayer()->GetItemByPos(bag, slot)->SetCount(m_caster->ToPlayer()->GetItemByPos(bag, slot)->GetCount()-1);
3141 // Spell 42518 (Braufest - Gratisprobe des Braufest herstellen)
3142 m_caster->CastSpell(m_caster, 42518, this);
3143 return;
3144 }
3145 break;
3146 }
3147 // Brutallus - Burn
3148 case 45141:
3149 case 45151:
3150 {
3151 //Workaround for Range ... should be global for every ScriptEffect
3152 float radius = effectInfo->CalcRadius(nullptr, SpellTargetIndex::TargetB).Max;
3154 unitTarget->CastSpell(unitTarget, 46394, this);
3155
3156 break;
3157 }
3158 // Summon Ghouls On Scarlet Crusade
3159 case 51904:
3160 {
3161 if (!m_targets.HasDst())
3162 return;
3163
3164 SpellRange radius = effectInfo->CalcRadius();
3165 for (uint8 i = 0; i < 15; ++i)
3166 m_caster->CastSpell(m_caster->GetRandomPoint(*destTarget, radius.Max, radius.Min), 54522, this);
3167 break;
3168 }
3169 case 52173: // Coyote Spirit Despawn
3170 case 60243: // Blood Parrot Despawn
3173 return;
3174 case 57347: // Retrieving (Wintergrasp RP-GG pickup spell)
3175 {
3177 return;
3178
3180
3181 return;
3182 }
3183 case 57349: // Drop RP-GG (Wintergrasp RP-GG at death drop spell)
3184 {
3186 return;
3187
3188 // Delete item from inventory at death
3190
3191 return;
3192 }
3193 case 62482: // Grab Crate
3194 {
3195 if (!unitCaster)
3196 return;
3197
3198 if (unitTarget)
3199 {
3200 if (Unit* seat = unitCaster->GetVehicleBase())
3201 {
3202 if (Unit* parent = seat->GetVehicleBase())
3203 {
3205 unitCaster->CastSpell(parent, 62496, this);
3207 .SetTriggeringSpell(this)); // DIFFICULTY_NONE, so effect always valid
3208 }
3209 }
3210 }
3211 return;
3212 }
3213 }
3214 break;
3215 }
3216 }
3217
3218 // normal DB scripted effect
3219 TC_LOG_DEBUG("spells", "Spell ScriptStart spellid {} in EffectScriptEffect({})", m_spellInfo->Id, effectInfo->EffectIndex);
3221}
3222
3224{
3226 return;
3227
3228 if (!unitTarget)
3229 return;
3230
3231 auto isAffectedBySanctuary = [](Unit const* attacker)
3232 {
3233 Creature const* attackerCreature = attacker->ToCreature();
3234 return !attackerCreature || !attackerCreature->IsIgnoringSanctuarySpellEffect();
3235 };
3236
3238 {
3239 // stop all pve combat for players outside dungeons, suppress pvp combat
3240 unitTarget->CombatStop(false, false, isAffectedBySanctuary);
3241 }
3242 else
3243 {
3244 // in dungeons (or for nonplayers), reset this unit on all enemies' threat lists
3245 for (auto const& [guid, ref] : unitTarget->GetThreatManager().GetThreatenedByMeList())
3246 if (isAffectedBySanctuary(ref->GetOwner()))
3247 ref->ScaleThreat(0.0f);
3248 }
3249
3250 // makes spells cast before this time fizzle
3252}
3253
3255{
3257 return;
3258
3260 return;
3261
3262 Player* caster = m_caster->ToPlayer();
3263 Player* target = unitTarget->ToPlayer();
3264
3265 // caster or target already have requested duel
3266 if (caster->duel || target->duel || !target->GetSocial() || target->GetSocial()->HasIgnore(caster->GetGUID(), caster->GetSession()->GetAccountGUID()))
3267 return;
3268
3269 // Players can only fight a duel in zones with this flag
3270 AreaTableEntry const* casterAreaEntry = sAreaTableStore.LookupEntry(caster->GetAreaId());
3271 if (casterAreaEntry && !(casterAreaEntry->GetFlags().HasFlag(AreaFlags::AllowDueling)))
3272 {
3273 SendCastResult(SPELL_FAILED_NO_DUELING); // Dueling isn't allowed here
3274 return;
3275 }
3276
3277 AreaTableEntry const* targetAreaEntry = sAreaTableStore.LookupEntry(target->GetAreaId());
3278 if (targetAreaEntry && !(targetAreaEntry->GetFlags().HasFlag(AreaFlags::AllowDueling)))
3279 {
3280 SendCastResult(SPELL_FAILED_NO_DUELING); // Dueling isn't allowed here
3281 return;
3282 }
3283
3284 //CREATE DUEL FLAG OBJECT
3285 Map* map = caster->GetMap();
3286 Position const pos =
3287 {
3288 caster->GetPositionX() + (unitTarget->GetPositionX() - caster->GetPositionX()) / 2,
3289 caster->GetPositionY() + (unitTarget->GetPositionY() - caster->GetPositionY()) / 2,
3290 caster->GetPositionZ(),
3291 caster->GetOrientation()
3292 };
3294
3296 if (!go)
3297 return;
3298
3300
3301 go->SetFaction(caster->GetFaction());
3302 go->SetLevel(caster->GetLevel() + 1);
3303 int32 duration = m_spellInfo->CalcDuration(caster);
3304 go->SetRespawnTime(duration > 0 ? duration/IN_MILLISECONDS : 0);
3306
3308
3309 caster->AddGameObject(go);
3310 map->AddToMap(go);
3311 //END
3312
3313 // Send request
3315 packet.ArbiterGUID = go->GetGUID();
3316 packet.RequestedByGUID = caster->GetGUID();
3317 packet.RequestedByWowAccount = caster->GetSession()->GetAccountGUID();
3318
3319 WorldPacket const* worldPacket = packet.Write();
3320 caster->SendDirectMessage(worldPacket);
3321 target->SendDirectMessage(worldPacket);
3322
3323 // create duel-info
3324 bool isMounted = (GetSpellInfo()->Id == 62875);
3325 caster->duel = std::make_unique<DuelInfo>(target, caster, isMounted);
3326 target->duel = std::make_unique<DuelInfo>(caster, caster, isMounted);
3327
3328 caster->SetDuelArbiter(go->GetGUID());
3329 target->SetDuelArbiter(go->GetGUID());
3330
3331 sScriptMgr->OnPlayerDuelRequest(target, caster);
3332}
3333
3335{
3337 return;
3338
3339 if (!sWorld->getBoolConfig(CONFIG_CAST_UNSTUCK))
3340 return;
3341
3342 Player* player = m_caster->ToPlayer();
3343 if (!player)
3344 return;
3345
3346 TC_LOG_DEBUG("spells", "Spell Effect: Stuck");
3347 TC_LOG_DEBUG("spells", "Player {} {} used the auto-unstuck feature at map {} ({}, {}, {}).", player->GetName(), player->GetGUID().ToString(), player->GetMapId(), player->GetPositionX(), player->GetPositionY(), player->GetPositionZ());
3348
3349 if (player->IsInFlight())
3350 return;
3351
3352 // if player is dead without death timer is teleported to graveyard, otherwise not apply the effect
3353 if (player->isDead())
3354 {
3355 if (!player->GetDeathTimer())
3356 player->RepopAtGraveyard();
3357
3358 return;
3359 }
3360
3361 // the player dies if hearthstone is in cooldown, else the player is teleported to home
3362 if (player->GetSpellHistory()->HasCooldown(8690))
3363 {
3364 player->KillSelf();
3365 return;
3366 }
3367
3368 player->TeleportTo(player->m_homebind, TELE_TO_SPELL);
3369
3370 // Stuck spell trigger Hearthstone cooldown
3371 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(8690, GetCastDifficulty());
3372 if (!spellInfo)
3373 return;
3374 Spell spell(player, spellInfo, TRIGGERED_FULL_MASK);
3375 spell.SendSpellCooldown();
3376}
3377
3379{
3380 // workaround - this effect should not use target map
3382 return;
3383
3384 Unit* unitCaster = GetUnitCasterForEffectHandlers();
3385 if (!unitCaster)
3386 return;
3387
3389 return;
3390
3392}
3393
3406
3408{
3410 return;
3411
3412 Player* player = m_caster->ToPlayer();
3413 if (!player)
3414 return;
3415
3416 std::vector<uint32>& glyphs = player->GetGlyphs(player->GetActiveTalentGroup());
3417 std::size_t replacedGlyph = glyphs.size();
3418 for (std::size_t i = 0; i < glyphs.size(); ++i)
3419 {
3420 if (std::vector<uint32> const* activeGlyphBindableSpells = sDB2Manager.GetGlyphBindableSpells(glyphs[i]))
3421 {
3422 if (std::find(activeGlyphBindableSpells->begin(), activeGlyphBindableSpells->end(), m_misc.SpellId) != activeGlyphBindableSpells->end())
3423 {
3424 replacedGlyph = i;
3425 player->RemoveAurasDueToSpell(sGlyphPropertiesStore.AssertEntry(glyphs[i])->SpellID);
3426 break;
3427 }
3428 }
3429 }
3430
3431 uint32 glyphId = effectInfo->MiscValue;
3432 if (replacedGlyph < glyphs.size())
3433 {
3434 if (glyphId)
3435 glyphs[replacedGlyph] = glyphId;
3436 else
3437 glyphs.erase(glyphs.begin() + replacedGlyph);
3438 }
3439 else if (glyphId)
3440 glyphs.push_back(glyphId);
3441
3443
3444 if (GlyphPropertiesEntry const* glyphProperties = sGlyphPropertiesStore.LookupEntry(glyphId))
3445 player->CastSpell(player, glyphProperties->SpellID, this);
3446
3448 activeGlyphs.Glyphs.emplace_back(m_misc.SpellId, uint16(glyphId));
3449 activeGlyphs.IsFullUpdate = false;
3450 player->SendDirectMessage(activeGlyphs.Write());
3451}
3452
3454{
3456 return;
3457
3458 // this is only item spell effect applied to main-hand weapon of target player (players in area)
3460 return;
3461
3462 Player* item_owner = unitTarget->ToPlayer();
3464
3465 if (!item)
3466 return;
3467
3468 // must be equipped
3469 if (!item->IsEquipped())
3470 return;
3471
3472 if (effectInfo->MiscValue)
3473 {
3474 uint32 enchant_id = effectInfo->MiscValue;
3475 int32 duration = m_spellInfo->GetDuration(); //Try duration index first ..
3476 if (!duration)
3477 duration = GetEffectValueAsInt();//+1; //Base points after ..
3478 if (!duration)
3479 duration = 10 * IN_MILLISECONDS; //10 seconds for enchants which don't have listed duration
3480
3481 if (m_spellInfo->Id == 14792) // Venomhide Poison
3482 duration = 5 * MINUTE * IN_MILLISECONDS;
3483
3484 SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
3485 if (!pEnchant)
3486 return;
3487
3488 // Always go to temp enchantment slot
3490
3491 // Enchantment will not be applied if a different one already exists
3492 if (item->GetEnchantmentId(slot) && item->GetEnchantmentId(slot) != enchant_id)
3493 return;
3494
3495 // Apply the temporary enchantment
3496 item->SetEnchantment(slot, enchant_id, duration, 0, m_caster->GetGUID());
3497 item_owner->ApplyEnchantment(item, slot, true);
3498 }
3499}
3500
3502{
3504 return;
3505
3506 if (Player* caster = m_caster->ToPlayer())
3507 {
3508 if (!m_CastItem)
3509 caster->UpdateCraftSkill(m_spellInfo);
3510
3511 itemTarget->m_loot.reset(new Loot(caster->GetMap(), itemTarget->GetGUID(), LOOT_DISENCHANTING, nullptr));
3513 caster->SendLoot(*itemTarget->m_loot);
3514 }
3515
3516 // item will be removed at disenchanting end
3517}
3518
3520{
3522 return;
3523
3524 if (!unitTarget || !unitTarget->IsPlayer())
3525 return;
3526
3527 Player* player = unitTarget->ToPlayer();
3528
3529 uint8 currentDrunkValue = player->GetDrunkValue();
3530 uint8 drunkValue = std::clamp<int32>(GetEffectValueAsInt() + currentDrunkValue, 0, 100);
3531 if (currentDrunkValue == 100 && currentDrunkValue == drunkValue)
3532 if (roll_chance(25.0f))
3533 player->CastSpell(player, 67468, CastSpellExtraArgs()
3534 .SetTriggeringSpell(this)); // Drunken Vomit
3535
3536 player->SetDrunkValue(drunkValue, m_CastItem ? m_CastItem->GetEntry() : 0);
3537}
3538
3540{
3542 return;
3543
3544 Player* player = m_caster->ToPlayer();
3545 if (!player)
3546 return;
3547
3548 Item* foodItem = itemTarget;
3549 if (!foodItem)
3550 return;
3551
3552 Pet* pet = player->GetPet();
3553 if (!pet)
3554 return;
3555
3556 if (!pet->IsAlive())
3557 return;
3558
3560
3561 int32 pct;
3562 int32 levelDiff = int32(pet->GetLevel()) - int32(foodItem->GetTemplate()->GetBaseItemLevel());
3563 if (levelDiff >= 30)
3564 return;
3565 else if (levelDiff >= 20)
3566 pct = int32(12.5); // we can't pass double so keeping the cast here for future references
3567 else if (levelDiff >= 10)
3568 pct = 25;
3569 else
3570 pct = 50;
3571
3572 uint32 count = 1;
3573 player->DestroyItemCount(foodItem, count, true);
3575
3577 args.SetTriggeringSpell(this);
3580}
3581
3583{
3585 return;
3586
3587 if (!unitTarget || !unitTarget->IsPet())
3588 return;
3589
3590 Pet* pet = unitTarget->ToPet();
3591
3594}
3595
3597{
3599 return;
3600
3601 Unit* unitCaster = GetUnitCasterForEffectHandlers();
3602 if (!unitCaster)
3603 return;
3604
3606 ObjectGuid guid = unitCaster->m_ObjectSlot[slot];
3607 if (!guid.IsEmpty())
3608 {
3609 if (GameObject* obj = unitCaster->GetMap()->GetGameObject(guid))
3610 {
3611 // Recast case - null spell id to make auras not be removed on object remove from world
3612 if (m_spellInfo->Id == obj->GetSpellId())
3613 obj->SetSpellId(0);
3614 unitCaster->RemoveGameObject(obj, true);
3615 }
3616 unitCaster->m_ObjectSlot[slot].Clear();
3617 }
3618
3619 float x, y, z, o;
3620 // If dest location if present
3621 if (m_targets.HasDst())
3622 destTarget->GetPosition(x, y, z, o);
3623 // Summon in random point all other units if location present
3624 else
3625 {
3626 unitCaster->GetClosePoint(x, y, z, DEFAULT_PLAYER_BOUNDING_RADIUS);
3627 o = unitCaster->GetOrientation();
3628 }
3629
3630 Map* map = m_caster->GetMap();
3631 Position pos = Position(x, y, z, o);
3633
3635 if (!go)
3636 return;
3637
3639
3640 go->SetFaction(unitCaster->GetFaction());
3641 go->SetLevel(unitCaster->GetLevel());
3643 go->SetRespawnTime(duration > 0 ? duration / IN_MILLISECONDS : 0);
3645 unitCaster->AddGameObject(go);
3646
3648
3649 map->AddToMap(go);
3650
3651 unitCaster->m_ObjectSlot[slot] = go->GetGUID();
3652}
3653
3655{
3657 return;
3658
3659 if (!m_corpseTarget && !unitTarget)
3660 return;
3661
3662 Player* player = nullptr;
3663
3664 if (m_corpseTarget)
3666 else if (unitTarget)
3667 player = unitTarget->ToPlayer();
3668
3669 if (!player || player->IsAlive() || !player->IsInWorld())
3670 return;
3671
3672 if (player->IsResurrectRequested()) // already have one active request
3673 return;
3674
3675 uint32 health = player->CountPctFromMaxHealth(effectValue);
3677
3679
3680 player->SetResurrectRequestData(m_caster, health, mana, 0);
3681 SendResurrectRequest(player);
3682}
3683
3685{
3687 return;
3688
3689 if (!unitTarget || !unitTarget->IsAlive())
3690 return;
3691
3692 int32 extraAttacks = GetEffectValueAsInt();
3693
3694 unitTarget->AddExtraAttacks(extraAttacks);
3695
3697}
3698
3700{
3702 return;
3703
3705 m_caster->ToPlayer()->SetCanParry(true);
3706}
3707
3709{
3711 return;
3712
3714 m_caster->ToPlayer()->SetCanBlock(true);
3715}
3716
3718{
3720 return;
3721
3722 if (!unitTarget || unitTarget->IsInFlight())
3723 return;
3724
3725 if (!m_targets.HasDst())
3726 return;
3727
3728 TeleportLocation targetDest{ .Location = *destTarget };
3729 if (ObjectGuid transportGuid = m_destTargets[effectInfo->EffectIndex]._transportGUID; !transportGuid.IsEmpty())
3730 {
3731 targetDest.TransportGuid = transportGuid;
3733 }
3734
3736}
3737
3739{
3741 return;
3742
3744 return;
3745
3746 Player* player = unitTarget->ToPlayer();
3747
3748 int32 repChange = GetEffectValueAsInt();
3749
3750 uint32 factionId = effectInfo->MiscValue;
3751
3752 FactionEntry const* factionEntry = sFactionStore.LookupEntry(factionId);
3753 if (!factionEntry)
3754 return;
3755
3756 repChange = player->CalculateReputationGain(REPUTATION_SOURCE_SPELL, 0, repChange, factionId);
3757
3758 player->GetReputationMgr().ModifyReputation(factionEntry, repChange);
3759}
3760
3762{
3764 return;
3765
3767 return;
3768 Player* player = unitTarget->ToPlayer();
3769
3770 uint32 questId = effectInfo->MiscValue;
3771 if (questId)
3772 {
3773 Quest const* quest = sObjectMgr->GetQuestTemplate(questId);
3774 if (!quest)
3775 return;
3776
3777 QuestStatus questStatus = player->GetQuestStatus(questId);
3778 if (questStatus == QUEST_STATUS_REWARDED)
3779 return;
3780
3782 {
3783 if (questStatus == QUEST_STATUS_INCOMPLETE)
3784 player->AreaExploredOrEventHappens(questId);
3785 }
3786 else if (quest->HasFlag(QUEST_FLAGS_TRACKING_EVENT)) // Check if the quest is used as a serverside flag
3787 player->CompleteQuest(questId);
3788 }
3789}
3790
3792{
3794 return;
3795
3796 Unit* unitCaster = GetUnitCasterForEffectHandlers();
3797 if (!unitCaster)
3798 return;
3799
3800 float dist = unitCaster->GetVisibilityRange();
3801
3802 // clear focus
3804 breakTarget.Data.UnitGUID = m_caster->GetGUID();
3805 breakTarget.Data.Write();
3807 Cell::VisitWorldObjects(m_caster, notifierBreak, dist);
3808
3809 // and selection
3811 clearTarget.Data.Guid = m_caster->GetGUID();
3812 clearTarget.Data.Write();
3814 Cell::VisitWorldObjects(m_caster, notifierClear, dist);
3815
3816 // we should also force pets to remove us from current target
3817 Unit::AttackerSet attackerSet;
3818 for (Unit::AttackerSet::const_iterator itr = unitCaster->getAttackers().begin(); itr != unitCaster->getAttackers().end(); ++itr)
3819 if ((*itr)->GetTypeId() == TYPEID_UNIT && !(*itr)->CanHaveThreatList())
3820 attackerSet.insert(*itr);
3821
3822 for (Unit::AttackerSet::const_iterator itr = attackerSet.begin(); itr != attackerSet.end(); ++itr)
3823 (*itr)->AttackStop();
3824}
3825
3827{
3829 return;
3830
3831 Player* player = m_caster->ToPlayer();
3832 if (!player || !player->IsInWorld() || player->IsAlive())
3833 return;
3834
3835 uint32 health = 0;
3836 uint32 mana = 0;
3837
3838 // flat case
3839 if (effectValue < 0)
3840 {
3841 health = uint32(-GetEffectValueAsInt());
3842 mana = effectInfo->MiscValue;
3843 }
3844 // percent case
3845 else
3846 {
3847 health = player->CountPctFromMaxHealth(effectValue);
3848 if (player->GetMaxPower(POWER_MANA) > 0)
3850 }
3851
3852 player->ResurrectPlayer(0.0f);
3853
3854 player->SetHealth(health);
3855 player->SetPower(POWER_MANA, mana);
3856 player->SetPower(POWER_RAGE, 0);
3857 player->SetFullPower(POWER_ENERGY);
3858 player->SetPower(POWER_FOCUS, 0);
3859
3860 player->SpawnCorpseBones();
3861}
3862
3864{
3866 return;
3867
3869 return;
3870
3871 Player* player = m_caster->ToPlayer();
3872 if (!player)
3873 return;
3874
3875 Creature* creature = unitTarget->ToCreature();
3876 int32 targetLevel = creature->GetLevelForTarget(m_caster);
3877
3878 uint32 skill = creature->GetCreatureDifficulty()->GetRequiredLootSkill();
3879
3882 Loot* loot = new Loot(creature->GetMap(), creature->GetGUID(), LOOT_SKINNING, nullptr);
3883 creature->m_personalLoot[player->GetGUID()].reset(loot);
3884 loot->FillLoot(creature->GetCreatureDifficulty()->SkinLootID, LootTemplates_Skinning, player, true);
3885 player->SendLoot(*loot);
3886
3887 if (!IsPartOfSkillLine(skill, m_spellInfo->Id))
3888 return;
3889
3890 // Skill gain for skinning
3891 // This formula is still used (10.0.5.48526)
3892 if (skill == SKILL_SKINNING)
3893 {
3894 int32 reqValue;
3895 if (targetLevel <= 10)
3896 reqValue = 1;
3897 else if (targetLevel < 20)
3898 reqValue = (targetLevel - 10) * 10;
3899 else if (targetLevel <= 73)
3900 reqValue = targetLevel * 5;
3901 else if (targetLevel < 80)
3902 reqValue = targetLevel * 10 - 365;
3903 else if (targetLevel <= 84)
3904 reqValue = targetLevel * 5 + 35;
3905 else if (targetLevel <= 87)
3906 reqValue = targetLevel * 15 - 805;
3907 else if (targetLevel <= 92)
3908 reqValue = (targetLevel - 62) * 20;
3909 else if (targetLevel <= 104)
3910 reqValue = targetLevel * 5 + 175;
3911 else if (targetLevel <= 107)
3912 reqValue = targetLevel * 15 - 905;
3913 else if (targetLevel <= 112)
3914 reqValue = (targetLevel - 72) * 20;
3915 else if (targetLevel <= 122)
3916 reqValue = (targetLevel - 32) * 10;
3917 else
3918 reqValue = 900;
3919
3920 ContentTuningEntry const* contentTuning = sContentTuningStore.LookupEntry(creature->GetContentTuning());
3921 if (!contentTuning)
3922 return;
3923
3924 uint32 skinningSkill = player->GetProfessionSkillForExp(skill, contentTuning->ExpansionID);
3925 if (!skinningSkill)
3926 return;
3927
3928 if (uint32 pureSkillValue = player->GetPureSkillValue(skinningSkill))
3929 {
3930 // Double chances for elites
3931 player->UpdateGatherSkill(skinningSkill, pureSkillValue, reqValue, creature->IsElite() ? 2 : 1);
3932 }
3933 }
3934}
3935
3937{
3938 if (!unitTarget)
3939 return;
3940
3941 Unit* unitCaster = GetUnitCasterForEffectHandlers();
3942 if (!unitCaster)
3943 return;
3944
3946 {
3947 // charge changes fall time
3948 if (unitCaster->GetTypeId() == TYPEID_PLAYER)
3949 unitCaster->ToPlayer()->SetFallInformation(0, unitCaster->GetPositionZ());
3950
3951 float speed = G3D::fuzzyGt(m_spellInfo->Speed, 0.0f) ? m_spellInfo->Speed : SPEED_CHARGE;
3952
3953 Optional<Movement::SpellEffectExtraData> spellEffectExtraData;
3955 {
3956 spellEffectExtraData.emplace();
3957 spellEffectExtraData->Target = unitTarget->GetGUID();
3958 spellEffectExtraData->SpellVisualId = effectInfo->MiscValueB;
3959 }
3960 // Spell is not using explicit target - no generated path
3961 if (!m_preGeneratedPath)
3962 {
3964
3965 m_preGeneratedPath = std::make_unique<PathGenerator>(unitCaster);
3966 m_preGeneratedPath->CalculatePath(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), false);
3967 }
3968
3970 speed = m_preGeneratedPath->GetPathLength() / speed;
3971
3972 unitCaster->GetMotionMaster()->MoveCharge(*m_preGeneratedPath, speed, unitTarget, spellEffectExtraData ? &*spellEffectExtraData : nullptr);
3973
3974 // abuse implementation detail of MoveCharge accepting PathGenerator argument (instantly started spline)
3975 UpdateDelayMomentForUnitTarget(unitTarget, unitCaster->movespline->Duration());
3976 }
3977
3979 {
3980 // not all charge effects used in negative spells
3982 unitCaster->Attack(unitTarget, true);
3983
3986 .SetOriginalCaster(m_originalCasterGUID)
3987 .SetTriggeringSpell(this));
3988 }
3989}
3990
3992{
3993 if (!destTarget)
3994 return;
3995
3996 Unit* unitCaster = GetUnitCasterForEffectHandlers();
3997 if (!unitCaster)
3998 return;
3999
4001 {
4003
4004 if (!unitCaster->IsWithinLOS(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ()))
4005 {
4006 float angle = unitCaster->GetRelativeAngle(pos.GetPositionX(), pos.GetPositionY());
4007 float dist = unitCaster->GetDistance(pos);
4008 pos = unitCaster->GetFirstCollisionPosition(dist, angle);
4009 }
4010
4011 PathGenerator path(unitCaster);
4012 path.CalculatePath(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), false);
4013
4014 float speed = G3D::fuzzyGt(m_spellInfo->Speed, 0.0f) ? m_spellInfo->Speed : SPEED_CHARGE;
4015
4017 speed = path.GetPathLength() / speed;
4018
4019 unitCaster->GetMotionMaster()->MoveCharge(path, speed);
4020
4021 // abuse implementation detail of MoveCharge accepting PathGenerator argument (instantly started spline)
4022 UpdateDelayMomentForDst(unitCaster->movespline->Duration());
4023 }
4025 {
4028 .SetOriginalCaster(m_originalCasterGUID)
4029 .SetTriggeringSpell(this));
4030 }
4031}
4032
4034{
4036 return;
4037
4038 if (!unitTarget)
4039 return;
4040
4042 if (Creature* creatureTarget = unitTarget->ToCreature())
4043 if (creatureTarget->isWorldBoss() || creatureTarget->IsDungeonBoss())
4044 return;
4045
4046 // Spells with SPELL_EFFECT_KNOCK_BACK (like Thunderstorm) can't knockback target if target has ROOT/STUN
4048 return;
4049
4050 float ratio = 0.1f;
4051 float speedXY = float(effectInfo->MiscValue) * ratio;
4052 float speedZ = effectValue * ratio;
4053 if (std::abs(speedXY) < 0.01f && std::abs(speedZ) < 0.01f)
4054 return;
4055
4056 Position origin;
4058 {
4059 if (m_targets.HasDst())
4060 origin = destTarget->GetPosition();
4061 else
4062 return;
4063 }
4064 else //if (effectInfo->Effect == SPELL_EFFECT_KNOCK_BACK)
4065 origin = m_caster->GetPosition();
4066
4067 unitTarget->KnockbackFrom(origin, speedXY, speedZ);
4068
4070 PROC_SPELL_TYPE_MASK_ALL, PROC_SPELL_PHASE_HIT, PROC_HIT_NONE, nullptr, nullptr, nullptr);
4071}
4072
4074{
4076 return;
4077
4078 if (!unitTarget)
4079 return;
4080
4081 float speedxy = effectInfo->MiscValue / 10.f;
4082 float speedz = effectValue / 10.f;
4083
4084 // Disengage
4086
4087 // changes fall time
4090}
4091
4093{
4095 return;
4096
4098 return;
4099 Player* player = unitTarget->ToPlayer();
4100
4101 uint32 quest_id = effectInfo->MiscValue;
4102
4103 Quest const* quest = sObjectMgr->GetQuestTemplate(quest_id);
4104
4105 if (!quest)
4106 return;
4107
4108 QuestStatus oldStatus = player->GetQuestStatus(quest_id);
4109
4110 // Player has never done this quest
4111 if (oldStatus == QUEST_STATUS_NONE)
4112 return;
4113
4114 player->RemoveActiveQuest(quest_id, false);
4115
4116 // remove all quest entries for 'entry' from quest log
4117 if (oldStatus != QUEST_STATUS_REWARDED)
4118 {
4119 // we ignore unequippable quest items in this case, it's still be equipped
4120 player->TakeQuestSourceItem(quest_id, false);
4121
4122 if (quest->HasFlag(QUEST_FLAGS_FLAGS_PVP))
4123 {
4124 player->pvpInfo.IsHostile = player->pvpInfo.IsInHostileArea || player->HasPvPForcingQuest();
4125 player->UpdatePvPState();
4126 }
4127 }
4128
4129 player->RemoveRewardedQuest(quest_id);
4130 player->DespawnPersonalSummonsForQuest(quest_id);
4131
4132 sScriptMgr->OnQuestStatusChange(player, quest_id);
4133 sScriptMgr->OnQuestStatusChange(player, quest, oldStatus, QUEST_STATUS_NONE);
4134}
4135
4146
4148{
4150 return;
4151
4152 if (!unitTarget)
4153 return;
4154
4156
4157 // This is a blizzlike mistake: this should be 2D distance according to projectile motion formulas, but Blizzard erroneously used 3D distance.
4158 float distXY = unitTarget->GetExactDist(pos);
4159
4160 // Avoid division by 0
4161 if (distXY < 0.001)
4162 return;
4163
4164 float distZ = pos.GetPositionZ() - unitTarget->GetPositionZ();
4165 float speedXY = effectInfo->MiscValue ? effectInfo->MiscValue / 10.0f : 30.0f;
4166 float speedZ = (2 * speedXY * speedXY * distZ + Movement::gravity * distXY * distXY) / (2 * speedXY * distXY);
4167
4168 if (!std::isfinite(speedZ))
4169 {
4170 TC_LOG_ERROR("spells", "Spell {} with SPELL_EFFECT_PULL_TOWARDS called with invalid speedZ. {}", m_spellInfo->Id, GetDebugInfo());
4171 return;
4172 }
4173
4175}
4176
4178{
4180 return;
4181
4182 if (!unitTarget)
4183 return;
4184
4185 if (!m_targets.HasDst())
4186 {
4187 TC_LOG_ERROR("spells", "Spell {} with SPELL_EFFECT_PULL_TOWARDS_DEST has no dest target", m_spellInfo->Id);
4188 return;
4189 }
4190
4191 Position const* pos = m_targets.GetDstPos();
4192 // This is a blizzlike mistake: this should be 2D distance according to projectile motion formulas, but Blizzard erroneously used 3D distance
4193 float distXY = unitTarget->GetExactDist(pos);
4194
4195 // Avoid division by 0
4196 if (distXY < 0.001)
4197 return;
4198
4199 float distZ = pos->GetPositionZ() - unitTarget->GetPositionZ();
4200
4201 float speedXY = effectInfo->MiscValue ? effectInfo->MiscValue / 10.0f : 30.0f;
4202 float speedZ = (2 * speedXY * speedXY * distZ + Movement::gravity * distXY * distXY) / (2 * speedXY * distXY);
4203
4204 if (!std::isfinite(speedZ))
4205 {
4206 TC_LOG_ERROR("spells", "Spell {} with SPELL_EFFECT_PULL_TOWARDS_DEST called with invalid speedZ. {}", m_spellInfo->Id, GetDebugInfo());
4207 return;
4208 }
4209
4211}
4212
4214{
4216 return;
4217
4218 Player* player = m_caster->ToPlayer();
4219 if (!player || !m_targets.HasDst())
4220 return;
4221
4222 Group* group = player->GetGroup();
4223 if (!group || (group->isRaidGroup() && !group->IsLeader(player->GetGUID()) && !group->IsAssistant(player->GetGUID())))
4224 return;
4225
4226 float x, y, z;
4227 destTarget->GetPosition(x, y, z);
4228
4229 group->AddRaidMarker(GetEffectValueAsInt(), player->GetMapId(), x, y, z);
4230}
4231
4233{
4235 return;
4236
4237 if (!unitTarget)
4238 return;
4239
4240 uint32 mechanic = effectInfo->MiscValue;
4241 DispelList dispel_list;
4242 Unit::AuraMap const& auras = unitTarget->GetOwnedAuras();
4243 for (Unit::AuraMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
4244 {
4245 Aura* aura = itr->second;
4247 continue;
4249 if ((aura->GetSpellInfo()->GetAllEffectsMechanicMask() & (UI64LIT(1) << mechanic)))
4250 dispel_list.emplace_back(aura->GetId(), aura->GetCasterGUID());
4251 }
4252
4253 if (dispel_list.empty())
4254 return;
4255
4256 for (auto itr = dispel_list.begin(); itr != dispel_list.end(); ++itr)
4257 unitTarget->RemoveAura(itr->first, itr->second, 0, AURA_REMOVE_BY_ENEMY_SPELL);
4258
4260
4262 PROC_SPELL_TYPE_MASK_ALL, PROC_SPELL_PHASE_HIT, PROC_HIT_NONE, nullptr, nullptr, nullptr);
4263
4264 std::ranges::find(m_UniqueTargetInfo, unitTarget->GetGUID(), &TargetInfo::TargetGUID)->ProcHitMask |= PROC_HIT_DISPEL;
4265}
4266
4268{
4270 return;
4271
4272 if (effectValue < 0)
4273 return;
4274
4275 Player* player = m_caster->ToPlayer();
4276 if (!player)
4277 return;
4278
4279 // Maybe player dismissed dead pet or pet despawned?
4280 bool hadPet = true;
4281
4282 if (!player->GetPet())
4283 {
4284 PetStable const* petStable = player->GetPetStable();
4285 auto deadPetItr = std::ranges::find_if(petStable->ActivePets, [](Optional<PetStable::PetInfo> const& petInfo)
4286 {
4287 return petInfo && !petInfo->Health;
4288 });
4289
4290 PetSaveMode slot = PetSaveMode(std::distance(petStable->ActivePets.begin(), deadPetItr));
4291
4292 // Position passed to SummonPet is irrelevant with current implementation,
4293 // pet will be relocated without using these coords in Pet::LoadPetFromDB
4294 player->SummonPet(0, slot, 0.0f, 0.0f, 0.0f, 0.0f, 0);
4295 hadPet = false;
4296 }
4297
4298 // TODO: Better to fail Hunter's "Revive Pet" at cast instead of here when casting ends
4299 Pet* pet = player->GetPet(); // Attempt to get current pet
4300 if (!pet || pet->IsAlive())
4301 return;
4302
4303 // If player did have a pet before reviving, teleport it
4304 if (hadPet)
4305 {
4306 // Reposition the pet's corpse before reviving so as not to grab aggro
4307 // We can use a different, more accurate version of GetClosePoint() since we have a pet
4308 float x, y, z; // Will be used later to reposition the pet if we have one
4309 player->GetClosePoint(x, y, z, pet->GetCombatReach(), PET_FOLLOW_DIST, pet->GetFollowAngle());
4310 pet->NearTeleportTo(x, y, z, player->GetOrientation());
4311 pet->Relocate(x, y, z, player->GetOrientation()); // This is needed so SaveStayPosition() will get the proper coords.
4312 }
4313
4316 pet->setDeathState(ALIVE);
4319
4320 // Reset things for when the AI to takes over
4321 CharmInfo *ci = pet->GetCharmInfo();
4322 if (ci)
4323 {
4324 // In case the pet was at stay, we don't want it running back
4325 ci->SaveStayPosition();
4327
4328 ci->SetIsFollowing(false);
4329 ci->SetIsCommandAttack(false);
4330 ci->SetIsCommandFollow(false);
4331 ci->SetIsReturning(false);
4332 }
4333
4335}
4336
4338{
4340 return;
4341
4342 Unit* unitCaster = GetUnitCasterForEffectHandlers();
4343 if (!unitCaster)
4344 return;
4345
4346 int32 mana = 0;
4347 for (uint8 slot = SUMMON_SLOT_TOTEM; slot < MAX_TOTEM_SLOT; ++slot)
4348 {
4349 if (!unitCaster->m_SummonSlot[slot])
4350 continue;
4351
4352 Creature* totem = unitCaster->GetMap()->GetCreature(unitCaster->m_SummonSlot[slot]);
4353 if (totem && totem->IsTotem())
4354 {
4355 uint32 spell_id = totem->m_unitData->CreatedBySpell;
4356 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell_id, GetCastDifficulty());
4357 if (spellInfo)
4358 {
4359 std::vector<SpellPowerCost> costs = spellInfo->CalcPowerCost(unitCaster, spellInfo->GetSchoolMask());
4360 auto m = std::find_if(costs.begin(), costs.end(), [](SpellPowerCost const& cost) { return cost.Power == POWER_MANA; });
4361 if (m != costs.end())
4362 mana += m->Amount;
4363 }
4364
4365 totem->ToTotem()->UnSummon();
4366 }
4367 }
4368
4369 ApplyPct(mana, effectValue);
4370
4371 if (mana)
4372 {
4374 args.SetTriggeringSpell(this);
4376 unitCaster->CastSpell(unitCaster, 39104, args);
4377 }
4378}
4379
4381{
4383 return;
4384
4386 return;
4387
4388 int32 slot = effectInfo->MiscValue;
4389
4390 // -1 means all player equipped items and -2 all items
4391 if (slot < 0)
4392 {
4395 return;
4396 }
4397
4398 // invalid slot value
4399 if (slot >= INVENTORY_SLOT_BAG_END)
4400 return;
4401
4403 {
4406 }
4407}
4408
4410{
4412 return;
4413
4415 return;
4416
4417 int32 slot = effectInfo->MiscValue;
4418
4419 // FIXME: some spells effects have value -1/-2
4420 // Possibly its mean -1 all player equipped items and -2 all items
4421 if (slot < 0)
4422 {
4423 unitTarget->ToPlayer()->DurabilityLossAll(effectValue / 100.0, (slot < -1));
4424 return;
4425 }
4426
4427 // invalid slot value
4428 if (slot >= INVENTORY_SLOT_BAG_END)
4429 return;
4430
4431 if (effectValue <= 0)
4432 return;
4433
4435 unitTarget->ToPlayer()->DurabilityLoss(item, effectValue / 100.0);
4436}
4437
4439{
4441 return;
4442
4443 Unit* unitCaster = GetUnitCasterForEffectHandlers();
4444 if (!unitCaster || !unitTarget)
4445 return;
4446
4448}
4449
4451{
4453 return;
4454
4455 Unit* unitCaster = GetUnitCasterForEffectHandlers();
4456 if (!unitCaster)
4457 return;
4458
4459 uint32 name_id = effectInfo->MiscValue;
4460 Unit::AuraEffectList const& overrideSummonedGameObjects = unitCaster->GetAuraEffectsByType(SPELL_AURA_OVERRIDE_SUMMONED_OBJECT);
4461 for (AuraEffect const* aurEff : overrideSummonedGameObjects)
4462 {
4463 if (uint32(aurEff->GetMiscValue()) == name_id)
4464 {
4465 name_id = uint32(aurEff->GetMiscValueB());
4466 break;
4467 }
4468 }
4469
4470 GameObjectTemplate const* goinfo = sObjectMgr->GetGameObjectTemplate(name_id);
4471 if (!goinfo)
4472 {
4473 TC_LOG_ERROR("sql.sql", "Gameobject (Entry: {}) does not exist and is not created by spell (ID: {}) cast.", name_id, m_spellInfo->Id);
4474 return;
4475 }
4476
4477 float fx, fy, fz, fo;
4478
4479 if (m_targets.HasDst())
4480 destTarget->GetPosition(fx, fy, fz, fo);
4481 //FIXME: this can be better check for most objects but still hack
4483 {
4484 float dis = effectInfo->CalcRadius(unitCaster).Min;
4485 unitCaster->GetClosePoint(fx, fy, fz, DEFAULT_PLAYER_BOUNDING_RADIUS, dis);
4486 fo = unitCaster->GetOrientation();
4487 }
4488 else
4489 {
4490 //GO is always friendly to it's creator, get range for friends
4491 auto [min_dis, max_dis] = m_spellInfo->GetMinMaxRange(true);
4492 float dis = rand_norm() * (max_dis - min_dis) + min_dis;
4493
4494 unitCaster->GetClosePoint(fx, fy, fz, DEFAULT_PLAYER_BOUNDING_RADIUS, dis);
4495 fo = unitCaster->GetOrientation();
4496 }
4497
4498 Map* cMap = unitCaster->GetMap();
4499 // if gameobject is summoning object, it should be spawned right on caster's position
4500 if (goinfo->type == GAMEOBJECT_TYPE_RITUAL)
4501 unitCaster->GetPosition(fx, fy, fz, fo);
4502
4503 Position pos = { fx, fy, fz, fo };
4505
4506 GameObject* go = GameObject::CreateGameObject(name_id, cMap, pos, rot, 255, GO_STATE_READY);
4507 if (!go)
4508 return;
4509
4512
4513 switch (goinfo->type)
4514 {
4516 {
4517 go->SetFaction(unitCaster->GetFaction());
4518 ObjectGuid bobberGuid = go->GetGUID();
4519 // client requires fishing bobber guid in channel object slot 0 to be usable
4520 unitCaster->SetChannelObject(0, bobberGuid);
4521 unitCaster->AddGameObject(go); // will removed at spell cancel
4522
4523 // end time of range when possible catch fish (FISHING_BOBBER_READY_TIME..GetDuration(m_spellInfo))
4524 // start time == fish-FISHING_BOBBER_READY_TIME (0..GetDuration(m_spellInfo)-FISHING_BOBBER_READY_TIME)
4525 int32 lastSec = 0;
4526 switch (urand(0, 2))
4527 {
4528 case 0: lastSec = 3; break;
4529 case 1: lastSec = 7; break;
4530 case 2: lastSec = 13; break;
4531 }
4532
4533 // Duration of the fishing bobber can't be higher than the Fishing channeling duration
4534 duration = std::min(duration, duration - lastSec*IN_MILLISECONDS + FISHING_BOBBER_READY_TIME*IN_MILLISECONDS);
4535 break;
4536 }
4538 {
4539 if (unitCaster->GetTypeId() == TYPEID_PLAYER)
4540 {
4541 go->AddUniqueUse(unitCaster->ToPlayer());
4542 unitCaster->AddGameObject(go); // will be removed at spell cancel
4543 }
4544 break;
4545 }
4546 case GAMEOBJECT_TYPE_DUEL_ARBITER: // 52991
4547 unitCaster->AddGameObject(go);
4548 break;
4551 default:
4552 break;
4553 }
4554
4555 go->SetRespawnTime(duration > 0 ? duration/IN_MILLISECONDS : 0);
4556
4557 go->SetOwnerGUID(unitCaster->GetGUID());
4558
4559 //go->SetLevel(unitCaster->getLevel());
4561
4563
4564 TC_LOG_DEBUG("spells", "AddObject at SpellEfects.cpp EffectTransmitted");
4565 //unitCaster->AddGameObject(go);
4566 //m_ObjToDel.push_back(go);
4567
4568 cMap->AddToMap(go);
4569
4570 if (GameObject* linkedTrap = go->GetLinkedTrap())
4571 {
4573
4574 linkedTrap->SetRespawnTime(duration > 0 ? duration / IN_MILLISECONDS : 0);
4575 //linkedTrap->SetLevel(unitCaster->getLevel());
4576 linkedTrap->SetSpellId(m_spellInfo->Id);
4577 linkedTrap->SetOwnerGUID(unitCaster->GetGUID());
4578
4580 }
4581}
4582
4584{
4586 return;
4587
4588 Player* player = m_caster->ToPlayer();
4589 if (!player)
4590 return;
4591
4593 return;
4594
4595 if (itemTarget->GetCount() < 5)
4596 return;
4597
4598 if (sWorld->getBoolConfig(CONFIG_SKILL_PROSPECTING))
4599 {
4600 uint32 SkillValue = player->GetPureSkillValue(SKILL_JEWELCRAFTING);
4601 uint32 reqSkillValue = itemTarget->GetTemplate()->GetRequiredSkillRank();
4602 player->UpdateGatherSkill(SKILL_JEWELCRAFTING, SkillValue, reqSkillValue);
4603 }
4604
4605 itemTarget->m_loot.reset(new Loot(player->GetMap(), itemTarget->GetGUID(), LOOT_PROSPECTING, nullptr));
4606 itemTarget->m_loot->FillLoot(itemTarget->GetEntry(), LootTemplates_Prospecting, player, true);
4607 player->SendLoot(*itemTarget->m_loot);
4608}
4609
4611{
4613 return;
4614
4615 Player* player = m_caster->ToPlayer();
4616 if (!player)
4617 return;
4618
4620 return;
4621
4622 if (itemTarget->GetCount() < 5)
4623 return;
4624
4625 if (sWorld->getBoolConfig(CONFIG_SKILL_MILLING))
4626 {
4627 uint32 SkillValue = player->GetPureSkillValue(SKILL_INSCRIPTION);
4628 uint32 reqSkillValue = itemTarget->GetTemplate()->GetRequiredSkillRank();
4629 player->UpdateGatherSkill(SKILL_INSCRIPTION, SkillValue, reqSkillValue);
4630 }
4631
4632 itemTarget->m_loot.reset(new Loot(player->GetMap(), itemTarget->GetGUID(), LOOT_MILLING, nullptr));
4633 itemTarget->m_loot->FillLoot(itemTarget->GetEntry(), LootTemplates_Milling, player, true);
4634 player->SendLoot(*itemTarget->m_loot);
4635}
4636
4638{
4640 return;
4641
4643 if (!playerTarget)
4644 return;
4645
4646 uint16 skillStep = GetEffectValueAsInt();
4647 if (skillStep < 1)
4648 return;
4649
4650 uint32 skillid = effectInfo->MiscValue;
4651 if (playerTarget->GetSkillStep(skillid) >= skillStep)
4652 return;
4653
4654 SkillRaceClassInfoEntry const* rcEntry = sDB2Manager.GetSkillRaceClassInfo(skillid, playerTarget->GetRace(), playerTarget->GetClass());
4655 if (!rcEntry)
4656 return;
4657
4658 SkillTiersEntry const* tier = sObjectMgr->GetSkillTier(rcEntry->SkillTierID);
4659 if (!tier)
4660 return;
4661
4662 uint16 skillval = std::max<uint16>(1, playerTarget->GetPureSkillValue(skillid));
4663 uint16 maxSkillVal = tier->GetValueForTierIndex(skillStep - 1);
4664
4665 if (rcEntry->Flags & SKILL_FLAG_ALWAYS_MAX_VALUE)
4666 skillval = maxSkillVal;
4667
4668 playerTarget->SetSkill(skillid, skillStep, skillval, maxSkillVal);
4669}
4670
4672{
4673 Unit* caster = GetCaster()->ToUnit();
4675 caster->CastSpell(nullptr, SPELL_RESURRECTION_VISUAL, true);
4676
4678 return;
4679
4680 if (Player* playerTarget = unitTarget->ToPlayer())
4681 {
4682 if (!playerTarget->IsInWorld())
4683 return;
4684
4685 // skip if player does not want to live
4686 if (!playerTarget->CanAcceptAreaSpiritHealFrom(caster))
4687 return;
4688
4689 playerTarget->ResurrectPlayer(1.0f);
4690 playerTarget->CastSpell(playerTarget, SPELL_PET_SUMMONED, true);
4691 playerTarget->CastSpell(playerTarget, SPELL_SPIRIT_HEAL_MANA, true);
4692 playerTarget->SpawnCorpseBones(false);
4693 }
4694}
4695
4696// remove insignia spell effect
4698{
4700 return;
4701
4702 TC_LOG_DEBUG("spells", "Effect: SkinPlayerCorpse");
4703
4704 Player* player = m_caster->ToPlayer();
4705
4706 Player* target = nullptr;
4707 if (unitTarget)
4708 target = unitTarget->ToPlayer();
4709 else if (m_corpseTarget)
4711
4712 if (!player || !target || target->IsAlive())
4713 return;
4714
4715 target->RemovedInsignia(player);
4716}
4717
4719{
4721 return;
4722
4723 TC_LOG_DEBUG("spells", "Effect: StealBeneficialBuff");
4724
4725 if (!unitTarget || unitTarget == m_caster) // can't steal from self
4726 return;
4727
4728 DispelChargesList stealList;
4729
4730 // Create dispel mask by dispel type
4732 Unit::AuraMap const& auras = unitTarget->GetOwnedAuras();
4733 for (Unit::AuraMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
4734 {
4735 Aura* aura = itr->second;
4736 AuraApplication const* aurApp = aura->GetApplicationOfTarget(unitTarget->GetGUID());
4737 if (!aurApp)
4738 continue;
4739
4740 if ((aura->GetSpellInfo()->GetDispelMask()) & dispelMask)
4741 {
4742 // Need check for passive? this
4743 if (!aurApp->IsPositive() || aura->IsPassive() || aura->GetSpellInfo()->HasAttribute(SPELL_ATTR4_CANNOT_BE_STOLEN))
4744 continue;
4745
4746 // 2.4.3 Patch Notes: "Dispel effects will no longer attempt to remove effects that have 100% dispel resistance."
4748 if (!chance)
4749 continue;
4750
4751 // The charges / stack amounts don't count towards the total number of auras that can be dispelled.
4752 // Ie: A dispel on a target with 5 stacks of Winters Chill and a Polymorph has 1 / (1 + 1) -> 50% chance to dispell
4753 // Polymorph instead of 1 / (5 + 1) -> 16%.
4754 bool dispelCharges = aura->GetSpellInfo()->HasAttribute(SPELL_ATTR7_DISPEL_REMOVES_CHARGES);
4755 uint8 charges = dispelCharges ? aura->GetCharges() : aura->GetStackAmount();
4756 if (charges > 0)
4757 stealList.emplace_back(aura, chance, charges);
4758 }
4759 }
4760
4761 if (stealList.empty())
4762 return;
4763
4764 size_t remaining = stealList.size();
4765
4766 int32 stealAmount = GetEffectValueAsInt();
4767
4768 // Ok if exist some buffs for dispel try dispel it
4769 std::vector<std::tuple<uint32, ObjectGuid, int32>> successList;
4770 successList.reserve(stealAmount);
4771
4773 dispelFailed.CasterGUID = m_caster->GetGUID();
4774 dispelFailed.VictimGUID = unitTarget->GetGUID();
4775 dispelFailed.SpellID = m_spellInfo->Id;
4776
4777 // dispel N = damage buffs (or while exist buffs for dispel)
4778 for (int32 count = 0; count < stealAmount && remaining > 0;)
4779 {
4780 // Random select buff for dispel
4781 DispelChargesList::iterator itr = stealList.begin();
4782 std::advance(itr, urand(0, remaining - 1));
4783
4784 if (itr->RollDispel())
4785 {
4786 uint8 stolenCharges = 1;
4787 if (itr->GetAura()->GetSpellInfo()->HasAttribute(SPELL_ATTR1_DISPEL_ALL_STACKS))
4788 stolenCharges = itr->GetDispelCharges();
4789
4790 successList.emplace_back(itr->GetAura()->GetId(), itr->GetAura()->GetCasterGUID(), int32(stolenCharges));
4791 if (!itr->DecrementCharge(stolenCharges))
4792 {
4793 --remaining;
4794 std::swap(*itr, stealList[remaining]);
4795 }
4796 }
4797 else
4798 {
4799 dispelFailed.FailedSpells.push_back(int32(itr->GetAura()->GetId()));
4800 }
4801 ++count;
4802 }
4803
4804 if (!dispelFailed.FailedSpells.empty())
4805 m_caster->SendMessageToSet(dispelFailed.Write(), true);
4806
4807 if (successList.empty())
4808 return;
4809
4811 spellDispellLog.IsBreak = false; // TODO: use me
4812 spellDispellLog.IsSteal = true;
4813
4814 spellDispellLog.TargetGUID = unitTarget->GetGUID();
4815 spellDispellLog.CasterGUID = m_caster->GetGUID();
4816 spellDispellLog.DispelledBySpellID = m_spellInfo->Id;
4817
4818 for (auto const& [spellId, auraCaster, stolenCharges] : successList)
4819 {
4821 dispellData.SpellID = spellId;
4822 dispellData.Harmful = false; // TODO: use me
4823
4824 unitTarget->RemoveAurasDueToSpellBySteal(spellId, auraCaster, m_caster, stolenCharges);
4825
4826 spellDispellLog.DispellData.emplace_back(dispellData);
4827 }
4828
4829 m_caster->SendMessageToSet(spellDispellLog.Write(), true);
4830
4831 std::ranges::find(m_UniqueTargetInfo, unitTarget->GetGUID(), &TargetInfo::TargetGUID)->ProcHitMask |= PROC_HIT_DISPEL;
4832}
4833
4844
4846{
4848 return;
4849
4851 return;
4852
4853 if (int32 creatureEntry = effectInfo->MiscValue)
4855}
4856
4858{
4860 return;
4861
4862 Player* playerTarget = Object::ToPlayer(unitTarget);
4863 if (!playerTarget)
4864 return;
4865
4867}
4868
4870{
4872 return;
4873
4875 return;
4876
4878}
4879
4881{
4883 return;
4884
4885 if (!unitTarget)
4886 return;
4887
4888 Player* player = unitTarget->ToPlayer();
4889 if (!player)
4890 return;
4891
4892 if (Quest const* quest = sObjectMgr->GetQuestTemplate(effectInfo->MiscValue))
4893 {
4894 if (!player->CanTakeQuest(quest, false))
4895 return;
4896
4897 if (quest->IsAutoAccept() && player->CanAddQuest(quest, false))
4898 {
4899 player->AddQuestAndCheckCompletion(quest, player);
4900 player->PlayerTalkClass->SendQuestGiverQuestDetails(quest, player->GetGUID(), true, true);
4901 }
4902 else
4903 player->PlayerTalkClass->SendQuestGiverQuestDetails(quest, player->GetGUID(), true, false);
4904 }
4905}
4906
4908{
4910 return;
4911
4913 return;
4914
4915 uint32 creatureEntry = effectInfo->MiscValue;
4916 Pet* pet = unitTarget->CreateTamedPetFrom(creatureEntry, m_spellInfo->Id);
4917 if (!pet)
4918 return;
4919
4920 // relocate
4921 float px, py, pz;
4923 pet->Relocate(px, py, pz, unitTarget->GetOrientation());
4924
4925 // add to world
4926 pet->GetMap()->AddToMap(pet->ToCreature());
4927
4928 // unitTarget has pet now
4929 unitTarget->SetMinion(pet, true);
4930
4932 {
4935 }
4936}
4937
4939{
4941 return;
4942
4944 return;
4945 uint32 nodeid = effectInfo->MiscValue;
4946 if (sTaxiNodesStore.LookupEntry(nodeid))
4948}
4949
4958
4960{
4962 return;
4963
4964 Unit* unitCaster = GetUnitCasterForEffectHandlers();
4965 if (!unitCaster)
4966 return;
4967
4968 if (unitTarget)
4970}
4971
4973{
4975 return;
4976
4977 if (!gameObjTarget)
4978 return;
4979
4980 FactionTemplateEntry const* casterFaction = m_caster->GetFactionTemplateEntry();
4981 FactionTemplateEntry const* targetFaction = sFactionTemplateStore.LookupEntry(gameObjTarget->GetFaction());
4982 // Do not allow to damage GO's of friendly factions (ie: Wintergrasp Walls/Ulduar Storm Beacons)
4983 if (!targetFaction || (casterFaction && !casterFaction->IsFriendlyTo(targetFaction)))
4985}
4986
4988{
4990 return;
4991
4992 if (!gameObjTarget)
4993 return;
4994
4996}
4997
5008
5009void Spell::SummonGuardian(SpellEffectInfo const* effect, uint32 entry, SummonPropertiesEntry const* properties, uint32 numGuardians, ObjectGuid privateObjectOwner)
5010{
5011 Unit* unitCaster = GetUnitCasterForEffectHandlers();
5012 if (!unitCaster)
5013 return;
5014
5015 if (unitCaster->IsTotem())
5016 unitCaster = unitCaster->ToTotem()->GetOwner();
5017
5018 // in another case summon new
5019 float radius = 5.0f;
5021
5022 //TempSummonType summonType = (duration == 0) ? TEMPSUMMON_DEAD_DESPAWN : TEMPSUMMON_TIMED_DESPAWN;
5023 Map* map = unitCaster->GetMap();
5024 for (uint32 count = 0; count < numGuardians; ++count)
5025 {
5026 Position pos;
5027 if (count == 0)
5028 pos = destTarget->GetPosition();
5029 else
5030 // randomize position for multiple summons
5031 pos = unitCaster->GetRandomPoint(*destTarget, radius);
5032
5033 TempSummon* summon = map->SummonCreature(entry, pos, properties, duration, unitCaster, m_spellInfo->Id, 0, privateObjectOwner);
5034 if (!summon)
5035 return;
5036
5037 if (summon->IsGuardian())
5038 {
5039 // level of pet summoned using engineering item based at engineering skill level
5040 if (m_CastItem && unitCaster->GetTypeId() == TYPEID_PLAYER)
5041 if (ItemTemplate const* proto = m_CastItem->GetTemplate())
5042 if (proto->GetRequiredSkill() == SKILL_ENGINEERING)
5043 if (uint16 skill202 = unitCaster->ToPlayer()->GetSkillValue(SKILL_ENGINEERING))
5044 static_cast<Guardian*>(summon)->InitStatsForLevel(skill202 / 5);
5045 }
5046
5048 ((Minion*)summon)->SetFollowAngle(unitCaster->GetAbsoluteAngle(summon));
5049
5050 if (summon->GetEntry() == 27893)
5051 {
5052 UF::VisibleItem const& weapon = m_caster->ToPlayer()->m_playerData->VisibleItems[EQUIPMENT_SLOT_MAINHAND];
5053 if (weapon.ItemID)
5054 {
5055 summon->SetDisplayId(11686); // modelid2
5056 summon->SetVirtualItem(0, weapon.ItemID, weapon.ItemAppearanceModID, weapon.ItemVisual);
5057 }
5058 else
5059 summon->SetDisplayId(1126); // modelid1
5060 }
5061
5063 }
5064}
5065
5067{
5069 return;
5070
5072 !unitTarget->IsPet() || ((Pet*)unitTarget)->getPetType() != HUNTER_PET)
5073 return;
5074
5076}
5077
5079{
5081 return;
5082
5084 return;
5085
5086 uint32 soundid = effectInfo->MiscValue;
5087
5088 if (!sSoundKitStore.LookupEntry(soundid))
5089 {
5090 TC_LOG_ERROR("spells", "EffectPlayMusic: Sound (Id: {}) does not exist in spell {}.", soundid, m_spellInfo->Id);
5091 return;
5092 }
5093
5095}
5096
5098{
5100 return;
5101
5103 return;
5104
5105 Player* player = unitTarget->ToPlayer();
5106 uint32 specID = m_misc.SpecializationId;
5107 ChrSpecializationEntry const* spec = sChrSpecializationStore.AssertEntry(specID);
5108
5109 // Safety checks done in Spell::CheckCast
5110 if (!spec->IsPetSpecialization())
5111 player->ActivateTalentGroup(spec);
5112 else
5113 player->GetPet()->SetSpecialization(specID);
5114}
5115
5117{
5119 return;
5120
5121 if (!unitTarget)
5122 return;
5123
5124 Player* player = unitTarget->ToPlayer();
5125 if (!player)
5126 return;
5127
5128 switch (m_spellInfo->Id)
5129 {
5130 case 91604: // Restricted Flight Area
5132 break;
5133 default:
5134 break;
5135 }
5136
5137 uint32 soundId = effectInfo->MiscValue;
5138
5139 if (!sSoundKitStore.LookupEntry(soundId))
5140 {
5141 TC_LOG_ERROR("spells", "EffectPlaySound: Sound (Id: {}) does not exist in spell {}.", soundId, m_spellInfo->Id);
5142 return;
5143 }
5144
5145 player->PlayDirectSound(soundId, player);
5146}
5147
5149{
5151 return;
5152
5153 if (!unitTarget)
5154 return;
5155 // there may be need of specifying casterguid of removed auras
5157}
5158
5160{
5162 return;
5163
5164 if (!unitTarget)
5165 return;
5166
5168}
5169
5183
5185{
5187 return;
5188
5189 Player* player = m_caster->ToPlayer();
5190 if (!player)
5191 return;
5192
5193 uint32 button_id = effectInfo->MiscValue + 132;
5194 uint32 n_buttons = effectInfo->MiscValueB;
5195
5196 for (; n_buttons; --n_buttons, ++button_id)
5197 {
5198 ActionButton const* ab = player->GetActionButton(button_id);
5199 if (!ab || ab->GetType() != ACTION_BUTTON_SPELL)
5200 continue;
5201
5204 uint32 spell_id = ab->GetAction();
5205 if (!spell_id)
5206 continue;
5207
5208 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell_id, GetCastDifficulty());
5209 if (!spellInfo)
5210 continue;
5211
5212 if (!player->HasSpell(spell_id) || player->GetSpellHistory()->HasCooldown(spell_id))
5213 continue;
5214
5216 continue;
5217
5218 CastSpellExtraArgs args;
5220 args.OriginalCastId = m_castId;
5222 m_caster->CastSpell(m_caster, spellInfo->Id, args);
5223 }
5224}
5225
5227{
5229 return;
5230
5231 if (!unitTarget)
5232 return;
5233
5234 Player* player = unitTarget->ToPlayer();
5235 if (!player)
5236 return;
5237
5238 if (Item* item = player->GetItemByEntry(effectInfo->ItemType))
5239 {
5240 for (ItemEffectEntry const* itemEffect : item->GetEffects())
5241 item->SetSpellCharges(itemEffect, itemEffect->Charges);
5242
5243 item->SetState(ITEM_CHANGED, player);
5244 }
5245}
5246
5248{
5250 return;
5251
5253 return;
5254
5255 Player* player = unitTarget->ToPlayer();
5256
5257 WorldLocation homeLoc;
5258 uint32 areaId = player->GetAreaId();
5259
5260 if (effectInfo->MiscValue)
5261 areaId = effectInfo->MiscValue;
5262
5263 if (m_targets.HasDst())
5264 homeLoc.WorldRelocate(*destTarget);
5265 else
5266 homeLoc = player->GetWorldLocation();
5267
5268 player->SetHomebind(homeLoc, areaId);
5269 player->SendBindPointUpdate();
5270
5271 TC_LOG_DEBUG("spells", "EffectBind: New homebind X: {}, Y: {}, Z: {} O: {}, MapId: {}, AreaId: {}",
5272 homeLoc.GetPositionX(), homeLoc.GetPositionY(), homeLoc.GetPositionZ(), homeLoc.GetOrientation(), homeLoc.GetMapId(), areaId);
5273
5274 // zone update
5275 player->SendPlayerBound(m_caster->GetGUID(), areaId);
5276}
5277
5279{
5281 return;
5282
5283 if (Player* player = unitTarget->ToPlayer())
5284 if (WorldLocation const* dest = player->GetStoredAuraTeleportLocation(effectInfo->MiscValue))
5285 player->TeleportTo(*dest, unitTarget == m_caster ? TELE_TO_SPELL | TELE_TO_NOT_LEAVE_COMBAT : TELE_TO_NONE);
5286}
5287
5289{
5291 return;
5292
5293 if (effectValue <= 0)
5294 return;
5295
5296 if (Player* player = unitTarget->ToPlayer())
5297 player->IncreaseCurrencyCap(effectInfo->MiscValue, GetEffectValueAsInt());
5298}
5299
5310
5312{
5314 return;
5315
5316 // Safety checks done in Spell::CheckCast
5317 Player* caster = m_caster->ToPlayer();
5318 if (Guild* guild = caster->GetGuild())
5319 guild->HandleBuyBankTab(caster->GetSession(), GetEffectValueAsInt() - 1); // Bank tabs start at zero internally
5320}
5321
5323{
5325 return;
5326
5327 uint32 goId = effectInfo->MiscValue;
5328 if (!goId)
5329 return;
5330
5331 float x, y, z, o;
5332 if (m_targets.HasDst())
5333 destTarget->GetPosition(x, y, z, o);
5334 else
5335 {
5337 o = m_caster->GetOrientation();
5338 }
5339
5340 Map* map = m_caster->GetMap();
5341 Position pos = Position(x, y, z, o);
5343 GameObject* go = GameObject::CreateGameObject(goId, map, pos, rot, 255, GO_STATE_READY);
5344
5345 if (!go)
5346 {
5347 TC_LOG_WARN("spells", "SpellEffect Failed to summon personal gameobject. SpellId {}, effect {}", m_spellInfo->Id, effectInfo->EffectIndex);
5348 return;
5349 }
5350
5352
5354
5355 go->SetRespawnTime(duration > 0 ? duration / IN_MILLISECONDS : 0);
5358
5360
5361 map->AddToMap(go);
5362
5363 if (GameObject* linkedTrap = go->GetLinkedTrap())
5364 {
5366
5367 linkedTrap->SetRespawnTime(duration > 0 ? duration / IN_MILLISECONDS : 0);
5368 linkedTrap->SetSpellId(m_spellInfo->Id);
5369
5371 }
5372}
5373
5375{
5377 return;
5378
5379 if (!unitTarget || !unitTarget->IsInWorld())
5380 return;
5381
5382 Player* target = unitTarget->ToPlayer();
5383 if (!target)
5384 return;
5385
5386 if (unitTarget->IsAlive())
5387 return;
5388
5389 if (target->IsResurrectRequested()) // already have one active request
5390 return;
5391
5392 uint32 health = target->CountPctFromMaxHealth(effectValue);
5394 uint32 resurrectAura = 0;
5395 if (sSpellMgr->GetSpellInfo(effectInfo->TriggerSpell, DIFFICULTY_NONE))
5396 resurrectAura = effectInfo->TriggerSpell;
5397
5398 if (resurrectAura && target->HasAura(resurrectAura))
5399 return;
5400
5402 target->SetResurrectRequestData(m_caster, health, mana, resurrectAura);
5403 SendResurrectRequest(target);
5404}
5405
5407{
5409 return;
5410
5411 Unit* unitCaster = GetUnitCasterForEffectHandlers();
5412 if (!unitCaster || !m_targets.HasDst())
5413 return;
5414
5415 AreaTriggerCreatePropertiesId createPropertiesId = { uint32(effectInfo->MiscValue), false };
5416 int32 duration = GetSpellInfo()->CalcDuration(GetCaster());
5417
5418 AreaTrigger::CreateAreaTrigger(createPropertiesId, destTarget->GetPosition(), duration, unitCaster, nullptr, m_SpellVisual, GetSpellInfo(), this);
5419}
5420
5422{
5424 return;
5425
5426 TalentEntry const* talent = sTalentStore.LookupEntry(m_misc.TalentId);
5427 if (!talent)
5428 return;
5429
5430 Player* player = unitTarget ? unitTarget->ToPlayer() : nullptr;
5431 if (!player)
5432 return;
5433
5434 player->RemoveTalent(talent);
5435 player->SendTalentsInfoData();
5436}
5437
5439{
5441 return;
5442
5444 return;
5445
5446 Player* player = unitTarget->ToPlayer();
5447 if (Item* item = player->GetItemByEntry(effectInfo->ItemType))
5448 player->DestroyItem(item->GetBagSlot(), item->GetSlot(), true);
5449}
5450
5452{
5454 return;
5455
5457 return;
5458
5459 if (Garrison* garrison = unitTarget->ToPlayer()->GetGarrison())
5460 garrison->LearnBlueprint(effectInfo->MiscValue);
5461}
5462
5464{
5466 return;
5467
5468 if (!unitTarget)
5469 return;
5470
5472 {
5473 return aurApp->GetBase()->GetSpellInfo()->HasLabel(effectInfo->MiscValue);
5474 });
5475}
5476
5487
5489{
5491 return;
5492
5493 Unit* unitCaster = GetUnitCasterForEffectHandlers();
5494 if (!unitCaster || !m_targets.HasDst())
5495 return;
5496
5498}
5499
5501{
5503 return;
5504
5505 if (!unitTarget)
5506 return;
5507
5509 {
5510 if (check(conversation))
5511 conversation->Remove();
5512 };
5514 Cell::VisitGridObjects(unitTarget, worker, 100.0f);
5515}
5516
5518{
5520 return;
5521
5523 return;
5524
5525 if (Garrison* garrison = unitTarget->ToPlayer()->GetGarrison())
5526 garrison->AddFollower(effectInfo->MiscValue);
5527}
5528
5530{
5532 return;
5533
5534 Player* player = m_caster->ToPlayer();
5535 if (!player)
5536 return;
5537
5538 CollectionMgr* collectionMgr = player->GetSession()->GetCollectionMgr();
5539 if (!collectionMgr)
5540 return;
5541
5542 std::vector<int32> bonusList;
5543 bonusList.push_back(collectionMgr->GetHeirloomBonus(m_misc.Raw.Data[0]));
5544
5545 DoCreateItem(m_misc.Raw.Data[0], ItemContext::NONE, &bonusList);
5547}
5548
5550{
5552 return;
5553
5555 return;
5556
5557 if (Garrison* garrison = unitTarget->ToPlayer()->GetGarrison())
5558 garrison->ActivateBuilding(effectInfo->MiscValue);
5559}
5560
5562{
5564 return;
5565
5566 Player* playerCaster = m_caster->ToPlayer();
5567 if (!playerCaster)
5568 return;
5569
5570 if (!unitTarget || !unitTarget->IsCreature())
5571 return;
5572
5574}
5575
5577{
5579 return;
5580
5581 Player* playerTarget = Object::ToPlayer(unitTarget);
5582 if (!playerTarget)
5583 return;
5584
5586 playerTarget->GiveXP(xp, nullptr);
5587}
5588
5590{
5592 return;
5593
5594 Player* playerTarget = Object::ToPlayer(unitTarget);
5595 if (!playerTarget)
5596 return;
5597
5598 // effect value is number of resting hours
5599 playerTarget->GetRestMgr().AddRestBonus(REST_TYPE_XP, effectValue * float(HOUR) * playerTarget->GetRestMgr().CalcExtraPerSec(REST_TYPE_XP, 0.125f));
5600}
5601
5603{
5605 return;
5606
5608 return;
5609
5611 battlePetMgr->HealBattlePetsPct(GetEffectValueAsInt());
5612}
5613
5626
5628{
5630 return;
5631
5632 Player* playerCaster = m_caster->ToPlayer();
5633 if (!playerCaster)
5634 return;
5635
5636 if (!unitTarget || !unitTarget->IsCreature())
5637 return;
5638
5639 auto qualityItr = std::ranges::lower_bound(sBattlePetBreedQualityStore, GetEffectValueAsInt(), {}, &BattlePetBreedQualityEntry::MaxQualityRoll);
5640
5642 if (qualityItr != sBattlePetBreedQualityStore.end())
5643 quality = BattlePets::BattlePetBreedQuality(qualityItr->QualityEnum);
5644
5646}
5647
5649{
5651 return;
5652
5653 if (!unitTarget || !unitTarget->IsPlayer())
5654 return;
5655
5657}
5658
5660{
5662 return;
5663
5665 return;
5666
5672
5673 BattlePetSpeciesEntry const* speciesEntry = sBattlePetSpeciesStore.LookupEntry(speciesId);
5674 if (!speciesEntry)
5675 return;
5676
5677 Player* player = m_caster->ToPlayer();
5678 BattlePets::BattlePetMgr* battlePetMgr = player->GetSession()->GetBattlePetMgr();
5679 if (!battlePetMgr)
5680 return;
5681
5682 if (battlePetMgr->GetMaxPetLevel() < level)
5683 {
5686 return;
5687 }
5688
5689 if (battlePetMgr->HasMaxPetCount(speciesEntry, player->GetGUID()))
5690 {
5693 return;
5694 }
5695
5696 battlePetMgr->AddPet(speciesId, displayId, breed, BattlePets::BattlePetBreedQuality(quality), level);
5697
5698 player->SendPlaySpellVisual(player, BattlePets::SPELL_VISUAL_UNCAGE_PET, 0, 0, 0.f, false);
5699
5700 player->DestroyItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), true);
5701 m_CastItem = nullptr;
5702}
5703
5705{
5707 return;
5708
5709 if (Player* player = m_caster->ToPlayer())
5710 if (CollectionMgr* collectionMgr = player->GetSession()->GetCollectionMgr())
5711 collectionMgr->UpgradeHeirloom(m_misc.Raw.Data[0], int32(m_castItemEntry));
5712}
5713
5715{
5717 return;
5718
5719 if (!itemTarget)
5720 return;
5721
5722 Player* player = m_caster->ToPlayer();
5723 if (!player || player->GetGUID() != itemTarget->GetOwnerGUID())
5724 return;
5725
5728 if (itemTarget->IsEquipped())
5730
5733}
5734
5745
5756
5758{
5760 return;
5761
5762 Player* playerCaster = m_caster->ToPlayer();
5763 if (!playerCaster)
5764 return;
5765
5766 if (Aura* artifactAura = playerCaster->GetAura(ARTIFACTS_ALL_WEAPONS_GENERAL_WEAPON_EQUIPPED_PASSIVE))
5767 if (Item* artifact = playerCaster->GetItemByGuid(artifactAura->GetCastItemGUID()))
5768 artifact->GiveArtifactXp(uint64(effectValue), m_CastItem, uint32(effectInfo->MiscValue));
5769}
5770
5772{
5774 return;
5775
5777 return;
5778
5780 if (Item* artifact = unitTarget->ToPlayer()->GetItemByGuid(artifactAura->GetCastItemGUID()))
5781 artifact->GiveArtifactXp(uint64(effectValue), m_CastItem, 0);
5782}
5783
5794
5795template<typename TargetInfo>
5796bool IsUnitTargetSceneObjectAura(Spell const* spell, TargetInfo const& target)
5797{
5798 if (target.TargetGUID != spell->GetCaster()->GetGUID())
5799 return false;
5800
5801 for (SpellEffectInfo const& spellEffectInfo : spell->GetSpellInfo()->GetEffects())
5802 if (target.EffectMask & (1 << spellEffectInfo.EffectIndex) && spellEffectInfo.IsUnitOwnedAuraEffect())
5803 return true;
5804
5805 return false;
5806}
5807
5809{
5811 return;
5812
5813 Unit* unitCaster = GetUnitCasterForEffectHandlers();
5814 if (!unitCaster || !m_targets.HasDst())
5815 return;
5816
5818 {
5819 bool hasAuraTargetingCaster = std::find_if(m_UniqueTargetInfo.begin(), m_UniqueTargetInfo.end(), [this](TargetInfo const& target)
5820 {
5821 return IsUnitTargetSceneObjectAura(this, target);
5822 }) != m_UniqueTargetInfo.end();
5823
5824 if (hasAuraTargetingCaster)
5825 sceneObject->SetCreatedBySpellCast(m_castId);
5826 }
5827}
5828
5830{
5832 return;
5833
5834 Unit* unitCaster = GetUnitCasterForEffectHandlers();
5835 if (!unitCaster || !m_targets.HasDst())
5836 return;
5837
5838 if (SceneObject* sceneObject = SceneObject::CreateSceneObject(effectInfo->MiscValue, unitCaster, destTarget->GetPosition(), unitCaster->GetGUID()))
5839 {
5840 bool hasAuraTargetingCaster = std::find_if(m_UniqueTargetInfo.begin(), m_UniqueTargetInfo.end(), [this](TargetInfo const& target)
5841 {
5842 return IsUnitTargetSceneObjectAura(this, target);
5843 }) != m_UniqueTargetInfo.end();
5844
5845 if (hasAuraTargetingCaster)
5846 sceneObject->SetCreatedBySpellCast(m_castId);
5847 }
5848}
5849
5851{
5853 return;
5854
5856 return;
5857
5859}
5860
5862{
5864 return;
5865
5867 return;
5868
5869 int32 honor = GetEffectValueAsInt();
5870
5872 packet.Honor = honor;
5873 packet.OriginalHonor = honor;
5874
5875 Player* playerTarget = unitTarget->ToPlayer();
5876 playerTarget->AddHonorXP(honor);
5877 playerTarget->SendDirectMessage(packet.Write());
5878}
5879
5881{
5883 return;
5884
5885 Unit* unitCaster = GetUnitCasterForEffectHandlers();
5886 if (!unitCaster)
5887 return;
5888
5889 if (unitCaster->IsInFlight())
5890 return;
5891
5892 JumpChargeParams const* params = sObjectMgr->GetJumpChargeParams(effectInfo->MiscValue);
5893 if (!params)
5894 return;
5895
5896 std::variant<std::monostate, float, Milliseconds> speedOrTime = [params]() -> std::variant<std::monostate, float, Milliseconds>
5897 {
5898 if (params->TreatSpeedAsMoveTimeSeconds)
5899 return duration_cast<Milliseconds>(FloatSeconds(params->MoveTimeInSec));
5900
5901 return params->Speed;
5902 }();
5903
5904 MovementFacingTarget facing;
5905 if (Unit const* target = m_targets.GetUnitTarget())
5906 {
5908 facing = target;
5909 }
5910
5912 if (effectInfo->TriggerSpell || params->TriggerSpellId)
5913 {
5914 arrivalCast.emplace();
5915 arrivalCast->SpellId = params->TriggerSpellId ? *params->TriggerSpellId : effectInfo->TriggerSpell;
5916 arrivalCast->Target = unitTarget ? unitTarget->GetGUID() : ObjectGuid::Empty;
5917 }
5918
5920 if (params->SpellVisualId || params->ProgressCurveId || params->ParabolicCurveId)
5921 {
5922 effectExtra.emplace();
5923 if (params->SpellVisualId)
5924 effectExtra->SpellVisualId = *params->SpellVisualId;
5925
5926 if (params->ProgressCurveId)
5927 effectExtra->ProgressCurveId = *params->ProgressCurveId;
5928
5929 if (params->ParabolicCurveId)
5930 effectExtra->ParabolicCurveId = *params->ParabolicCurveId;
5931 }
5932
5933 unitCaster->GetMotionMaster()->MoveJump(EVENT_JUMP, *destTarget, speedOrTime, params->MinHeight, params->MaxHeight,
5935 arrivalCast ? &*arrivalCast : nullptr,
5936 effectExtra ? &*effectExtra : nullptr);
5937}
5938
5949
5951{
5953 return;
5954
5956 return;
5957
5958 Player* owner = m_caster->ToPlayer();
5959 if (!owner)
5960 return;
5961
5962 AzeriteEmpoweredItem* azeriteEmpoweredItem = itemTarget->ToAzeriteEmpoweredItem();
5963 owner->ModifyMoney(-azeriteEmpoweredItem->GetRespecCost());
5964
5965 // reapply all item mods - item level change affects stats and auras
5966 if (azeriteEmpoweredItem->IsEquipped())
5967 owner->_ApplyItemMods(azeriteEmpoweredItem, azeriteEmpoweredItem->GetSlot(), false);
5968
5969 azeriteEmpoweredItem->ClearSelectedAzeritePowers();
5970
5971 if (azeriteEmpoweredItem->IsEquipped())
5972 owner->_ApplyItemMods(azeriteEmpoweredItem, azeriteEmpoweredItem->GetSlot(), true);
5973
5974 azeriteEmpoweredItem->SetState(ITEM_CHANGED, owner);
5975 owner->SetNumRespecs(owner->GetNumRespecs() + 1);
5976}
5977
5979{
5981 return;
5982
5983 Player* playerTarget = unitTarget ? unitTarget->ToPlayer() : nullptr;
5984 if (!playerTarget)
5985 return;
5986
5988 if (!heartOfAzeroth)
5989 return;
5990
5991 AzeriteItem* azeriteItem = heartOfAzeroth->ToAzeriteItem();
5992 if (!azeriteItem)
5993 return;
5994
5995 // remove old rank and apply new one
5996 if (azeriteItem->IsEquipped())
5997 {
5998 if (UF::SelectedAzeriteEssences const* selectedEssences = azeriteItem->GetSelectedAzeriteEssences())
5999 {
6000 for (int32 slot = 0; slot < MAX_AZERITE_ESSENCE_SLOT; ++slot)
6001 {
6002 if (selectedEssences->AzeriteEssenceID[slot] == uint32(effectInfo->MiscValue))
6003 {
6004 bool major = AzeriteItemMilestoneType(sDB2Manager.GetAzeriteItemMilestonePower(slot)->Type) == AzeriteItemMilestoneType::MajorEssence;
6005 playerTarget->ApplyAzeriteEssence(azeriteItem, effectInfo->MiscValue, MAX_AZERITE_ESSENCE_RANK, major, false);
6006 playerTarget->ApplyAzeriteEssence(azeriteItem, effectInfo->MiscValue, effectInfo->MiscValueB, major, false);
6007 break;
6008 }
6009 }
6010 }
6011 }
6012
6014 azeriteItem->SetState(ITEM_CHANGED, playerTarget);
6015}
6016
6027
6029{
6031 return;
6032
6033 Player* playerTarget = unitTarget->ToPlayer();
6034 if (!playerTarget)
6035 return;
6036
6037 for (MountEquipmentEntry const* mountEquipment : sMountEquipmentStore)
6038 {
6039 if (mountEquipment->LearnedBySpell == effectInfo->TriggerSpell)
6040 {
6041 playerTarget->LearnSpell(mountEquipment->LearnedBySpell, false, 0, true);
6042 Unit::AuraEffectList const& mountAuras = playerTarget->GetAuraEffectsByType(SPELL_AURA_MOUNTED);
6043 if (!mountAuras.empty())
6044 if (MountEntry const* mountEntry = sDB2Manager.GetMount(mountAuras.front()->GetId()))
6045 if (!mountEntry->GetFlags().HasFlag(MountFlags::MountEquipmentEffectsSuppressed))
6046 playerTarget->CastSpell(playerTarget, mountEquipment->BuffSpell, true);
6047 }
6048 else
6049 {
6050 playerTarget->RemoveOwnedAura(mountEquipment->BuffSpell);
6051 playerTarget->RemoveSpell(mountEquipment->LearnedBySpell, false, false, true);
6052 }
6053 }
6054
6055 WorldPackets::Spells::ApplyMountEquipmentResult applyMountEquipmentResult;
6056 applyMountEquipmentResult.ItemGUID = m_castItemGUID;
6057 applyMountEquipmentResult.ItemID = m_castItemEntry;
6059 playerTarget->SendDirectMessage(applyMountEquipmentResult.Write());
6060}
6061
6063{
6065 return;
6066
6068 if (!target)
6069 return;
6070
6072}
6073
6075{
6077 return;
6078
6079 Unit* unitCaster = GetUnitCasterForEffectHandlers();
6080 if (!unitCaster)
6081 return;
6082
6083 uint32 broadcastTextId = effectInfo->MiscValue;
6084 if (!sBroadcastTextStore.LookupEntry(broadcastTextId))
6085 return;
6086
6087 ChatMsg chatType = ChatMsg(effectInfo->MiscValueB);
6088 unitCaster->Talk(broadcastTextId, chatType, CreatureTextMgr::GetRangeForChatType(chatType), unitTarget);
6089}
6090
6092{
6094 return;
6095
6096 Player* playerCaster = m_caster->ToPlayer();
6097 if (!playerCaster)
6098 return;
6099
6100 if (!unitTarget || !unitTarget->IsCreature())
6101 return;
6102
6104}
6105
6107{
6109 return;
6110
6112 if (!player)
6113 return;
6114
6115 uint32 illusionId = effectInfo->MiscValue;
6116 if (!sTransmogIllusionStore.LookupEntry(illusionId))
6117 return;
6118
6119 player->GetSession()->GetCollectionMgr()->AddTransmogIllusion(illusionId);
6120}
6121
6123{
6125 return;
6126
6128 if (!targetAura)
6129 return;
6130
6131 switch (effectInfo->MiscValue)
6132 {
6133 case 0:
6134 targetAura->ModStackAmount(GetEffectValueAsInt());
6135 break;
6136 case 1:
6137 targetAura->SetStackAmount(GetEffectValueAsInt());
6138 break;
6139 default:
6140 break;
6141 }
6142}
6143
6151
6153{
6155 return;
6156
6158 {
6159 SpellInfo const* spellOnCooldown = sSpellMgr->AssertSpellInfo(cooldown.SpellId, DIFFICULTY_NONE);
6160 if (spellOnCooldown->SpellFamilyName != uint32(effectInfo->MiscValue))
6161 return false;
6162
6163 int32 bitIndex = effectInfo->MiscValueB - 1;
6164 if (bitIndex < 0 || uint32(bitIndex) >= sizeof(flag128) * 8)
6165 return false;
6166
6167 return (spellOnCooldown->SpellFamilyFlags[bitIndex / 32] & 1u << (bitIndex % 32)) != 0;
6169}
6170
6172{
6174 return;
6175
6177 {
6178 return sSpellMgr->AssertSpellInfo(cooldown.SpellId, DIFFICULTY_NONE)->CategoryId == uint32(effectInfo->MiscValue);
6180}
6181
6190
6192{
6194 return;
6195
6197 if (!target)
6198 return;
6199
6200 if (target->IsLoading() && target->m_activePlayerData->TraitConfigs.empty())
6201 return; // traits not loaded yet
6202
6205 if (newConfig.Type != TraitConfigType::Generic)
6206 return;
6207
6208 newConfig.TraitSystemID = sTraitTreeStore.AssertEntry(effectInfo->MiscValue)->TraitSystemID;
6209 TraitSystemEntry const* traitSystem = sTraitSystemStore.LookupEntry(newConfig.TraitSystemID);
6210 if (!traitSystem)
6211 return;
6212
6213 switch (traitSystem->GetVariationType())
6214 {
6216 newConfig.VariationID = 0;
6217 break;
6220 break;
6221 default:
6222 return;
6223 }
6224
6225 int32 const* existingConfigIdForSystem = target->m_activePlayerData->TraitConfigs.FindIf([&](UF::TraitConfig const& config)
6226 {
6227 return static_cast<TraitConfigType>(*config.Type) == TraitConfigType::Generic
6228 && config.TraitSystemID == newConfig.TraitSystemID
6229 && config.VariationID == newConfig.VariationID;
6230 }).first;
6231
6232 if (!existingConfigIdForSystem)
6233 target->CreateTraitConfig(newConfig);
6234}
6235
6237{
6239 return;
6240
6242 if (!target)
6243 return;
6244
6245 WorldPackets::Traits::TraitConfig* traitConfig = std::any_cast<WorldPackets::Traits::TraitConfig>(&m_customArg);
6246 if (!traitConfig)
6247 return;
6248
6249 target->UpdateTraitConfig(std::move(*traitConfig), GetEffectValueAsInt(), false);
6250}
6251
6253{
6255 return;
6256
6258 if (!target)
6259 return;
6260
6261 target->RepopAtGraveyard();
6262}
6263
6265{
6267 return;
6268
6270 if (!target)
6271 return;
6272
6273 target->UpdateVisibleObjectInteractions(true, false, true, true);
6274}
6275
6277{
6279 return;
6280
6282 if (!target)
6283 return;
6284
6286}
6287
6289{
6291 return;
6292
6294 if (!target)
6295 return;
6296
6298}
6299
6301{
6303 return;
6304
6306 if (!target)
6307 return;
6308
6310}
6311
6313{
6315 return;
6316
6318 if (!target)
6319 return;
6320
6322}
6323
6325{
6327 return;
6328
6330 if (!target)
6331 return;
6332
6334}
6335
6337{
6339 return;
6340
6342 if (!target)
6343 return;
6344
6346}
6347
6349{
6351 return;
6352
6354 if (!target)
6355 return;
6356
6357 Optional<bool> locked;
6358 switch (static_cast<TransmogOutfitEquipAction>(m_misc.EquipTransmogOutfit.EquipAction))
6359 {
6363 locked = true;
6364 break;
6366 locked = false;
6367 break;
6368 default:
6369 break;
6370 }
6371
6372 target->EquipTransmogOutfit(m_misc.EquipTransmogOutfit.TransmogOutfitId, static_cast<TransmogSituationTrigger>(m_misc.EquipTransmogOutfit.SituationTrigger), locked);
6373}
constexpr uint32 ITEM_ID_HEART_OF_AZEROTH
Definition AzeriteItem.h:23
@ SPELL_PET_SUMMONED
@ SPELL_SPIRIT_HEAL_MANA
@ SPELL_RESURRECTION_VISUAL
@ IN_MILLISECONDS
Definition Common.h:38
@ MINUTE
Definition Common.h:32
@ HOUR
Definition Common.h:33
DB2Storage< BattlePetBreedQualityEntry > sBattlePetBreedQualityStore("BattlePetBreedQuality.db2", &BattlePetBreedQualityLoadInfo::Instance)
DB2Storage< TaxiNodesEntry > sTaxiNodesStore("TaxiNodes.db2", &TaxiNodesLoadInfo::Instance)
DB2Storage< TransmogIllusionEntry > sTransmogIllusionStore("TransmogIllusion.db2", &TransmogIllusionLoadInfo::Instance)
DB2Storage< TraitTreeEntry > sTraitTreeStore("TraitTree.db2", &TraitTreeLoadInfo::Instance)
DB2Storage< MountEquipmentEntry > sMountEquipmentStore("MountEquipment.db2", &MountEquipmentLoadInfo::Instance)
DB2Storage< ChrSpecializationEntry > sChrSpecializationStore("ChrSpecialization.db2", &ChrSpecializationLoadInfo::Instance)
DB2Storage< TraitSystemEntry > sTraitSystemStore("TraitSystem.db2", &TraitSystemLoadInfo::Instance)
DB2Storage< BattlePetSpeciesEntry > sBattlePetSpeciesStore("BattlePetSpecies.db2", &BattlePetSpeciesLoadInfo::Instance)
DB2Storage< SummonPropertiesEntry > sSummonPropertiesStore("SummonProperties.db2", &SummonPropertiesLoadInfo::Instance)
DB2Storage< BroadcastTextEntry > sBroadcastTextStore("BroadcastText.db2", &BroadcastTextLoadInfo::Instance)
DB2Storage< CurrencyTypesEntry > sCurrencyTypesStore("CurrencyTypes.db2", &CurrencyTypesLoadInfo::Instance)
DB2Storage< GlyphPropertiesEntry > sGlyphPropertiesStore("GlyphProperties.db2", &GlyphPropertiesLoadInfo::Instance)
DB2Storage< ContentTuningEntry > sContentTuningStore("ContentTuning.db2", &ContentTuningLoadInfo::Instance)
DB2Storage< SpellItemEnchantmentEntry > sSpellItemEnchantmentStore("SpellItemEnchantment.db2", &SpellItemEnchantmentLoadInfo::Instance)
DB2Storage< TalentEntry > sTalentStore("Talent.db2", &TalentLoadInfo::Instance)
DB2Storage< MovieEntry > sMovieStore("Movie.db2", &MovieLoadInfo::Instance)
DB2Storage< FactionTemplateEntry > sFactionTemplateStore("FactionTemplate.db2", &FactionTemplateLoadInfo::Instance)
DB2Storage< SoundKitEntry > sSoundKitStore("SoundKit.db2", &SoundKitLoadInfo::Instance)
DB2Storage< AreaTableEntry > sAreaTableStore("AreaTable.db2", &AreaTableLoadInfo::Instance)
DB2Storage< FactionEntry > sFactionStore("Faction.db2", &FactionLoadInfo::Instance)
#define sDB2Manager
Definition DB2Stores.h:569
#define MAX_VEHICLE_SEATS
#define MAX_ITEM_ENCHANTMENT_EFFECTS
TraitConfigType
Definition DBCEnums.h:2851
@ MountEquipmentEffectsSuppressed
@ SKILL_FLAG_ALWAYS_MAX_VALUE
Definition DBCEnums.h:2379
@ ITEM_ENCHANTMENT_TYPE_PRISMATIC_SOCKET
Definition DBCEnums.h:1230
#define MAX_EFFECT_MASK
Definition DBCEnums.h:2431
AzeriteItemMilestoneType
Definition DBCEnums.h:233
ItemContext
Definition DBCEnums.h:1315
TransmogSituationTrigger
Definition DBCEnums.h:2700
@ DIFFICULTY_NONE
Definition DBCEnums.h:933
#define MAX_AZERITE_ESSENCE_RANK
Definition DBCEnums.h:230
#define MAX_AZERITE_ESSENCE_SLOT
Definition DBCEnums.h:229
TransmogOutfitEquipAction
Definition DBCEnums.h:2554
uint8_t uint8
Definition Define.h:156
int64_t int64
Definition Define.h:149
int8_t int8
Definition Define.h:152
int32_t int32
Definition Define.h:150
uint64_t uint64
Definition Define.h:153
#define UI64LIT(N)
Definition Define.h:139
uint16_t uint16
Definition Define.h:155
uint32_t uint32
Definition Define.h:154
std::unordered_set< uint32 > params[2]
std::chrono::milliseconds Milliseconds
Milliseconds shorthand typedef.
Definition Duration.h:24
std::chrono::duration< double, Seconds::period > FloatSeconds
Definition Duration.h:29
@ DYNAMIC_OBJECT_FARSIGHT_FOCUS
@ DYNAMIC_OBJECT_AREA_SPELL
#define ASSERT
Definition Errors.h:80
GameObjectActions
@ GO_JUST_DEACTIVATED
Definition GameObject.h:159
#define FISHING_BOBBER_READY_TIME
Definition GameObject.h:163
uint32 const MinNewsItemLevel
Definition Guild.h:260
@ GUILD_NEWS_ITEM_CRAFTED
Definition Guild.h:244
EnchantmentSlot
@ PERM_ENCHANTMENT_SLOT
@ TEMP_ENCHANTMENT_SLOT
@ PRISMATIC_ENCHANTMENT_SLOT
InventoryResult
Definition ItemDefines.h:25
@ EQUIP_ERR_CLIENT_LOCKED_OUT
Definition ItemDefines.h:66
@ EQUIP_ERR_ITEM_NOT_FOUND
Definition ItemDefines.h:49
@ EQUIP_ERR_OK
Definition ItemDefines.h:26
@ EQUIP_ERR_INV_FULL
Definition ItemDefines.h:77
@ EQUIP_ERR_ITEM_MAX_COUNT
Definition ItemDefines.h:43
@ ITEM_MODIFIER_ENCHANT_ILLUSION_ALL_SPECS
@ ITEM_MODIFIER_BATTLE_PET_DISPLAY_ID
@ ITEM_MODIFIER_BATTLE_PET_BREED_DATA
@ ITEM_MODIFIER_BATTLE_PET_SPECIES_ID
@ ITEM_MODIFIER_BATTLE_PET_LEVEL
ItemRandomBonusListId GenerateItemRandomBonusListId(uint32 item_id)
@ ITEM_CLASS_ARMOR
@ ITEM_CLASS_WEAPON
@ ITEM_FIELD_FLAG_UNLOCKED
@ ITEM_SPELLTRIGGER_ON_LEARN
@ ITEM_FLAG_IS_MILLABLE
@ ITEM_FLAG_IS_PROSPECTABLE
@ ITEM_CHANGED
Definition Item.h:47
@ LANG_ZONE_NOFLYZONE
Definition Language.h:771
#define TC_LOG_DEBUG(filterType__, message__,...)
Definition Log.h:181
#define TC_LOG_ERROR(filterType__, message__,...)
Definition Log.h:190
#define sLog
Definition Log.h:156
#define TC_LOG_WARN(filterType__, message__,...)
Definition Log.h:187
LootStore LootTemplates_Spell("spell_loot_template", "spell id (random item creating)", false)
LootStore LootTemplates_Skinning("skinning_loot_template", "creature skinning id", true)
LootStore LootTemplates_Milling("milling_loot_template", "item entry (herb)", true)
LootStore LootTemplates_Disenchant("disenchant_loot_template", "item disenchant id", true)
LootStore LootTemplates_Prospecting("prospecting_loot_template", "item entry (ore)", true)
LootStore LootTemplates_Pickpocketing("pickpocketing_loot_template", "creature pickpocket lootid", true)
@ LOOT_PICKPOCKETING
Definition Loot.h:103
@ LOOT_MILLING
Definition Loot.h:116
@ LOOT_DISENCHANTING
Definition Loot.h:105
@ LOOT_SKINNING
Definition Loot.h:107
@ LOOT_PROSPECTING
Definition Loot.h:115
@ LOOT_ERROR_ALREADY_PICKPOCKETED
Definition Loot.h:150
#define SPEED_CHARGE
std::variant< std::monostate, Position, Unit const *, float > MovementFacingTarget
TempSummonType
@ TEMPSUMMON_DEAD_DESPAWN
@ TEMPSUMMON_MANUAL_DESPAWN
@ TEMPSUMMON_TIMED_DESPAWN
@ TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT
#define DEFAULT_PLAYER_BOUNDING_RADIUS
@ TYPEID_UNIT
Definition ObjectGuid.h:43
@ TYPEID_PLAYER
Definition ObjectGuid.h:44
std::set< ObjectGuid > GuidSet
Definition ObjectGuid.h:432
ScriptMapMap sSpellScripts
Definition ObjectMgr.cpp:84
#define sObjectMgr
Definition ObjectMgr.h:1885
std::optional< T > Optional
Optional helper class to wrap optional values within.
Definition Optional.h:25
#define sOutdoorPvPMgr
#define PET_FOLLOW_DIST
Definition PetDefines.h:98
@ HUNTER_PET
Definition PetDefines.h:32
PetSaveMode
Definition PetDefines.h:41
@ PET_SAVE_NOT_IN_SLOT
Definition PetDefines.h:48
@ PET_SAVE_AS_CURRENT
Definition PetDefines.h:43
@ EQUIPMENT_SLOT_MAINHAND
Definition Player.h:744
std::vector< ItemPosCount > ItemPosCountVec
Definition Player.h:841
@ DAMAGE_FIRE
Definition Player.h:943
@ INVENTORY_SLOT_BAG_END
Definition Player.h:774
TeleportToOptions
Definition Player.h:921
@ TELE_TO_SPELL
Definition Player.h:927
@ TELE_TO_NOT_LEAVE_COMBAT
Definition Player.h:925
@ TELE_TO_NOT_UNSUMMON_PET
Definition Player.h:926
@ TELE_TO_NONE
Definition Player.h:922
@ TELE_TO_NOT_LEAVE_TRANSPORT
Definition Player.h:924
@ PLAYER_FLAGS_PET_BATTLES_UNLOCKED
Definition Player.h:544
@ CHEAT_GOD
Definition Player.h:1076
@ ACTION_BUTTON_SPELL
Definition Player.h:368
@ SPEC_RESET_TALENTS
Definition Player.h:245
float constexpr TELEPORT_MIN_LOAD_SCREEN_DISTANCE
Definition Player.h:1222
#define INVENTORY_SLOT_BAG_0
Definition Player.h:723
@ REPUTATION_SOURCE_SPELL
Definition Player.h:404
#define MAPID_INVALID
Definition Position.h:189
@ QUEST_OBJECTIVE_KILL_WITH_LABEL
Definition QuestDef.h:379
QuestStatus
Definition QuestDef.h:146
@ QUEST_STATUS_REWARDED
Definition QuestDef.h:153
@ QUEST_STATUS_INCOMPLETE
Definition QuestDef.h:150
@ QUEST_STATUS_NONE
Definition QuestDef.h:147
@ QUEST_FLAGS_FLAGS_PVP
Definition QuestDef.h:231
@ QUEST_FLAGS_COMPLETION_AREA_TRIGGER
Definition QuestDef.h:220
@ QUEST_FLAGS_COMPLETION_EVENT
Definition QuestDef.h:219
@ QUEST_FLAGS_TRACKING_EVENT
Definition QuestDef.h:228
float rand_norm()
Definition Random.cpp:75
uint32 urand(uint32 min, uint32 max)
Definition Random.cpp:42
bool roll_chance(T chance)
Definition Random.h:55
@ REST_TYPE_XP
Definition RestMgr.h:29
@ PlayerNonInteractablePhased
#define sScriptMgr
Definition ScriptMgr.h:1449
SpellEffIndex
@ SPELL_ATTR9_JUMPCHARGE__NO_FACING_CONTROL
@ SPELL_ATTR9_MISSILE_SPEED_IS_DELAY_IN_SEC
@ SPELL_ATTR9_FACE_UNIT_TARGET_UPON_COMPLETION_OF_JUMP_CHARGE
@ SPELL_ATTR7_DISPEL_REMOVES_CHARGES
@ SPELL_ATTR7_CAN_BE_MULTI_CAST
@ SPELL_ATTR7_ATTACK_ON_CHARGE_TO_UNIT
@ CLASS_HUNTER
@ GAMEOBJECT_TYPE_DUEL_ARBITER
@ GAMEOBJECT_TYPE_TRAP
@ GAMEOBJECT_TYPE_CHEST
@ GAMEOBJECT_TYPE_FISHINGHOLE
@ GAMEOBJECT_TYPE_GOOBER
@ GAMEOBJECT_TYPE_FISHINGNODE
@ GAMEOBJECT_TYPE_RITUAL
@ SPELL_MISS_REFLECT
@ ITEM_QUALITY_EPIC
@ SPELL_SCHOOL_MASK_NORMAL
@ EVENT_JUMP
@ SPELL_ATTR2_RETAIN_ITEM_CAST
SummonTitle
@ SPELL_ATTR1_DISPEL_ALL_STACKS
@ UNIT_DYNFLAG_LOOTABLE
@ UNIT_DYNFLAG_NONE
SpellEffectName
@ SPELL_EFFECT_TRIGGER_MISSILE_SPELL_WITH_VALUE
@ SPELL_EFFECT_TRIGGER_SPELL_WITH_VALUE
@ SPELL_EFFECT_SUMMON_OBJECT_SLOT1
@ SPELL_EFFECT_WEAPON_DAMAGE
@ SPELL_EFFECT_NORMALIZED_WEAPON_DMG
@ SPELL_EFFECT_TRIGGER_SPELL
@ SPELL_EFFECT_WEAPON_PERCENT_DAMAGE
@ SPELL_EFFECT_KNOCK_BACK_DEST
@ SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL
@ SPELL_EFFECT_PERSISTENT_AREA_AURA
@ TOTAL_SPELL_EFFECTS
@ SPELL_EFFECT_FORCE_CAST
@ SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC
@ SPELL_EFFECT_FORCE_CAST_WITH_VALUE
@ SUMMON_SLOT_TOTEM
@ OFF_ATTACK
@ BASE_ATTACK
@ RANGED_ATTACK
Mechanics
@ MECHANIC_NONE
GameObjectDestructibleState
Powers
@ MAX_POWERS
@ POWER_RAGE
@ POWER_ENERGY
@ POWER_MANA
@ POWER_FOCUS
@ SPELL_ATTR0_IS_TRADESKILL
#define MAX_TOTEM_SLOT
SpellCastResult
@ SPELL_FAILED_DONT_REPORT
@ SPELL_FAILED_NO_DUELING
@ SPELL_CAST_OK
@ SPELL_FAILED_CANT_ADD_BATTLE_PET
@ SPELLFAMILY_GENERIC
@ SPELLFAMILY_SHAMAN
@ SPELLFAMILY_DEATHKNIGHT
DispelType
ChatMsg
@ GO_STATE_READY
@ SPELL_ATTR4_CANNOT_BE_STOLEN
@ SUMMON_CATEGORY_POSSESSED_VEHICLE
@ SUMMON_CATEGORY_PET
@ SUMMON_CATEGORY_VEHICLE
@ SUMMON_CATEGORY_ALLY
@ SUMMON_CATEGORY_PUPPET
@ SUMMON_CATEGORY_WILD
SkillType
@ SKILL_INSCRIPTION
@ SKILL_ENGINEERING
@ SKILL_NONE
@ SKILL_SKINNING
@ SKILL_JEWELCRAFTING
@ SPELL_ATTR6_IGNORE_CASTER_DAMAGE_MODIFIERS
bool CanCreateExtraItems(Player *player, uint32 spellId, float &additionalChance, uint8 &additionalMax)
bool CanCreatePerfectItem(Player *player, uint32 spellId, float &perfectCreateChance, uint32 &perfectItemType)
@ AURA_REMOVE_BY_ENEMY_SPELL
@ SPELL_AURA_CONTROL_VEHICLE
@ SPELL_AURA_MOD_STALKED
@ SPELL_AURA_MOUNTED
@ SPELL_AURA_OVERRIDE_SUMMONED_OBJECT
@ SPELL_AURA_MOD_STUN
@ SPELLVALUE_PARENT_SPELL_TARGET_COUNT
@ SPELLVALUE_PARENT_SPELL_TARGET_INDEX
double SpellEffectValue
This is a double instead of float to be able to store full range of int32.
@ TARGET_FLAG_DEST_LOCATION
@ TARGET_FLAG_UNIT_MASK
@ TARGET_FLAG_GAMEOBJECT_MASK
@ TRIGGERED_FULL_MASK
Used when doing CastSpell with triggered == true.
@ TRIGGERED_CAST_DIRECTLY
In Spell::prepare, will be cast directly without setting containers for executed spell.
@ TRIGGERED_IGNORE_CAST_IN_PROGRESS
Will not check if a current cast is in progress.
@ TRIGGERED_IGNORE_POWER_COST
Will ignore power and reagent cost.
@ TRIGGERED_IGNORE_REAGENT_COST
Will ignore reagent cost.
@ TRIGGERED_IGNORE_GCD
Will ignore GCD.
@ TRIGGERED_DONT_REPORT_CAST_ERROR
Will return SPELL_FAILED_DONT_REPORT in CheckCast functions.
@ TRIGGERED_IGNORE_CAST_TIME
Will always be instantly cast.
SpellValueModFloat
@ SPELLVALUE_BASE_POINT0
TeleportToOptions GetTeleportOptions(WorldObject const *caster, Unit const *unitTarget, SpellDestination const &targetDest)
bool IsUnitTargetSceneObjectAura(Spell const *spell, TargetInfo const &target)
NonDefaultConstructible< SpellEffectHandlerFn > SpellEffectHandlers[TOTAL_SPELL_EFFECTS]
@ SPELL_ATTR0_CU_SHARE_DAMAGE
Definition SpellInfo.h:147
bool IsPartOfSkillLine(uint32 skillId, uint32 spellId)
Definition SpellMgr.cpp:119
@ PROC_SPELL_PHASE_HIT
Definition SpellMgr.h:225
#define sSpellMgr
Definition SpellMgr.h:812
@ PROC_SPELL_TYPE_MASK_ALL
Definition SpellMgr.h:216
@ PROC_FLAG_NONE
Definition SpellMgr.h:92
@ PROC_FLAG_2_KNOCKBACK
Definition SpellMgr.h:191
@ PROC_FLAG_2_SUCCESSFUL_DISPEL
Definition SpellMgr.h:194
@ PROC_HIT_DISPEL
Definition SpellMgr.h:249
@ PROC_HIT_INTERRUPT
Definition SpellMgr.h:247
@ PROC_HIT_NONE
Definition SpellMgr.h:234
std::vector< std::pair< uint32, ObjectGuid > > DispelList
Definition Spell.h:272
@ SPELL_EFFECT_HANDLE_LAUNCH_TARGET
Definition Spell.h:267
@ SPELL_EFFECT_HANDLE_LAUNCH
Definition Spell.h:266
@ SPELL_EFFECT_HANDLE_HIT
Definition Spell.h:268
@ SPELL_EFFECT_HANDLE_HIT_TARGET
Definition Spell.h:269
@ SPELL_STATE_CHANNELING
Definition Spell.h:259
@ SPELL_STATE_PREPARING
Definition Spell.h:257
@ UNIT_PET_FLAG_CAN_BE_RENAMED
@ REACT_DEFENSIVE
@ REACT_AGGRESSIVE
@ SPELL_DIRECT_DAMAGE
@ HEAL
@ UNIT_FLAG3_ALREADY_SKINNED
@ COMMAND_STAY
@ UNIT_FLAG_IMMUNE
@ UNIT_FLAG_SKINNABLE
@ UNIT_MASK_MINION
Definition Unit.h:357
UnitMods
Definition Unit.h:176
@ UNIT_MOD_DAMAGE_OFFHAND
Definition Unit.h:219
@ UNIT_MOD_DAMAGE_RANGED
Definition Unit.h:220
@ UNIT_MOD_DAMAGE_MAINHAND
Definition Unit.h:218
@ ALIVE
Definition Unit.h:252
#define CURRENT_FIRST_NON_MELEE_SPELL
Definition Unit.h:603
CurrentSpellTypes
Definition Unit.h:596
@ CURRENT_AUTOREPEAT_SPELL
Definition Unit.h:600
@ UNIT_STATE_CONFUSED
Definition Unit.h:272
@ UNIT_STATE_ROOT
Definition Unit.h:271
@ UNIT_STATE_FLEEING
Definition Unit.h:268
@ UNIT_STATE_ALL_ERASABLE
Definition Unit.h:308
@ UNIT_STATE_STUNNED
Definition Unit.h:264
std::vector< DispelableAura > DispelChargesList
Definition Unit.h:150
@ NULL_BAG
Definition Unit.h:63
@ NULL_SLOT
Definition Unit.h:64
#define ARTIFACTS_ALL_WEAPONS_GENERAL_WEAPON_EQUIPPED_PASSIVE
Definition Unit.h:38
@ TOTAL_PCT
Definition Unit.h:165
T AddPct(T &base, U pct)
Definition Util.h:85
constexpr std::underlying_type< E >::type AsUnderlyingType(E enumValue)
Definition Util.h:565
T ApplyPct(T &base, U pct)
Definition Util.h:91
T CalculatePct(T base, U pct)
Definition Util.h:72
@ VEHICLE_SPELL_RIDE_HARDCODED
static AreaTrigger * CreateAreaTrigger(AreaTriggerCreatePropertiesId areaTriggerCreatePropertiesId, Position const &pos, int32 duration, Unit *caster, Unit *target, SpellCastVisual spellVisual={ 0, 0 }, SpellInfo const *spellInfo=nullptr, Spell *spell=nullptr, AuraEffect const *aurEff=nullptr)
bool IsPositive() const
Definition SpellAuras.h:88
void AddEffectToApplyEffectMask(SpellEffIndex spellEffectIndex)
Aura * GetBase() const
Definition SpellAuras.h:82
static Aura * TryCreate(AuraCreateInfo &createInfo)
void SetStackAmount(uint8 num)
AuraApplication const * GetApplicationOfTarget(ObjectGuid guid) const
DynamicObject * GetDynobjOwner() const
Definition SpellAuras.h:197
void _RegisterForTargets()
Definition SpellAuras.h:209
ObjectGuid GetCasterGUID() const
Definition SpellAuras.h:187
bool IsRemoved() const
Definition SpellAuras.h:254
uint32 GetId() const
Definition SpellAuras.h:183
int32 CalcDispelChance(Unit const *auraTarget, bool offensive) const
DynObjAura * ToDynObjAura()
Definition SpellAuras.h:351
bool ModStackAmount(int32 num, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT, bool resetPeriodicTimer=true)
uint8 GetStackAmount() const
Definition SpellAuras.h:238
void _ApplyEffectForTargets(uint8 effIndex)
uint8 GetCharges() const
Definition SpellAuras.h:229
SpellInfo const * GetSpellInfo() const
Definition SpellAuras.h:182
bool IsPassive() const
UF::SelectedAzeriteEssences const * GetSelectedAzeriteEssences() const
void SetEssenceRank(uint32 azeriteEssenceId, uint32 rank)
ObjectGuid const & GetGUID() const
Definition BaseEntity.h:163
bool IsInWorld() const
Definition BaseEntity.h:158
bool IsCreature() const
Definition BaseEntity.h:172
bool IsPlayer() const
Definition BaseEntity.h:173
TypeID GetTypeId() const
Definition BaseEntity.h:166
void GrantBattlePetExperience(ObjectGuid guid, uint16 xp, BattlePetXpSource xpSource)
static uint16 RollPetBreed(uint32 species)
uint16 GetMaxPetLevel() const
static uint32 SelectPetDisplay(BattlePetSpeciesEntry const *speciesEntry)
void UnlockSlot(BattlePetSlot slot)
static BattlePetSpeciesEntry const * GetBattlePetSpeciesBySpell(uint32 spellId)
void AddPet(uint32 species, uint32 display, uint16 breed, BattlePetBreedQuality quality, uint16 level=1)
void GrantBattlePetLevel(ObjectGuid guid, uint16 grantedLevels)
bool HasMaxPetCount(BattlePetSpeciesEntry const *battlePetSpecies, ObjectGuid ownerGuid) const
void SendError(BattlePetError error, uint32 creatureId)
void ChangeBattlePetQuality(ObjectGuid guid, BattlePetBreedQuality quality)
static BattlePetBreedQuality GetDefaultPetQuality(uint32 species)
void AddTransmogSet(uint32 transmogSetId)
uint32 GetHeirloomBonus(uint32 itemId) const
void AddWarbandScene(uint32 warbandSceneId)
void AddTransmogIllusion(uint32 transmogIllusionId)
static Conversation * CreateConversation(uint32 conversationEntry, Unit *creator, Position const &pos, ObjectGuid privateObjectOwner, SpellInfo const *spellInfo=nullptr, bool autoStart=true)
ObjectGuid GetOwnerGUID() const override
Definition Corpse.h:99
static float GetRangeForChatType(ChatMsg msgType)
std::unique_ptr< Loot > m_loot
Definition Creature.h:299
CreatureDifficulty const * GetCreatureDifficulty() const
Definition Creature.h:268
std::unordered_map< ObjectGuid, std::unique_ptr< Loot > > m_personalLoot
Definition Creature.h:300
uint8 GetLevelForTarget(WorldObject const *target) const override
void StartPickPocketRefillTimer()
void SetReactState(ReactStates st)
Definition Creature.h:174
void DespawnOrUnsummon(Milliseconds timeToDespawn=0s, Seconds forceRespawnTime=0s)
bool CanGeneratePickPocketLoot() const
bool IsElite() const
void SetImmuneToAll(bool apply) override
Definition Creature.h:181
bool IsIgnoringSanctuarySpellEffect() const
Definition Creature.h:346
void SetDisplayId(uint32 displayId, bool setNative=false) override
uint32 GetResist() const
Definition Unit.h:455
uint32 GetDamage() const
Definition Unit.h:452
uint32 GetAbsorb() const
Definition Unit.h:454
DelayedSpellTeleportEvent(Unit *target, TeleportLocation const &targetDest, TeleportToOptions options, uint32 spellId)
bool Execute(uint64, uint32) override
void SetCasterViewpoint()
void SetDuration(int32 newDuration)
bool CreateDynamicObject(ObjectGuid::LowType guidlow, Unit *caster, SpellInfo const *spell, Position const &pos, float radius, DynamicObjectType type, SpellCastVisual spellVisual)
void AddEventAtOffset(BasicEvent *event, Milliseconds offset)
GameObjectTemplate const * GetGOInfo() const
Definition GameObject.h:203
uint32 GetFaction() const override
Definition GameObject.h:397
static GameObject * CreateGameObject(uint32 entry, Map *map, Position const &pos, QuaternionData const &rotation, uint32 animProgress, GOState goState, uint32 artKit=0)
void SetOwnerGUID(ObjectGuid owner)
Definition GameObject.h:235
void SetDestructibleState(GameObjectDestructibleState state, WorldObject *attackerOrHealer=nullptr, bool setHealth=false)
void AddToSkillupList(ObjectGuid const &PlayerGuidLow)
Definition GameObject.h:316
void SetLootState(LootState s, Unit *unit=nullptr)
GameObject * GetLinkedTrap()
void SetRespawnTime(int32 respawn)
bool IsInSkillupList(ObjectGuid const &playerGuid) const
Definition GameObject.h:317
void Use(Unit *user, bool ignoreCastInProgress=false)
void SetLevel(uint32 level)
Definition GameObject.h:281
void ModifyHealth(int32 change, WorldObject *attackerOrHealer=nullptr, uint32 spellId=0)
void ActivateObject(GameObjectActions action, int32 param, WorldObject *spellCaster=nullptr, uint32 spellId=0, int32 effectIndex=-1)
void AddUniqueUse(Player *player)
void SetSpellId(uint32 id)
Definition GameObject.h:247
void SetFaction(uint32 faction) override
Definition GameObject.h:398
Definition Group.h:205
bool IsAssistant(ObjectGuid guid) const
Definition Group.h:319
void AddRaidMarker(uint8 markerId, uint32 mapId, float positionX, float positionY, float positionZ, ObjectGuid transportGuid=ObjectGuid::Empty)
Definition Group.cpp:1576
bool IsLeader(ObjectGuid guid) const
Definition Group.cpp:1690
ObjectGuid GetGUID() const
Definition Group.cpp:1653
bool isRaidGroup() const
Definition Group.cpp:1628
Definition Guild.h:329
Definition Item.h:179
void SetState(ItemUpdateState state, Player *forplayer=nullptr)
Definition Item.cpp:1258
uint8 GetSlot() const
Definition Item.h:290
void SetItemFlag(ItemFieldFlags flags)
Definition Item.h:218
std::span< ItemEffectEntry const *const > GetEffects() const
Definition Item.h:365
uint32 GetEnchantmentId(EnchantmentSlot slot) const
Definition Item.h:308
bool IsVellum() const
Definition Item.h:345
bool IsAzeriteEmpoweredItem() const
Definition Item.h:264
AzeriteItem * ToAzeriteItem()
Definition Item.h:253
uint32 GetEnchantmentDuration(EnchantmentSlot slot) const
Definition Item.h:309
void SetCount(uint32 value)
Definition Item.cpp:1367
void SetModifier(ItemModifier modifier, uint32 value)
Definition Item.cpp:2483
ItemTemplate const * GetTemplate() const
Definition Item.cpp:1233
UF::UpdateField< UF::ItemData, uint32(WowCS::EntityFragment::CGObject), TYPEID_ITEM > m_itemData
Definition Item.h:459
ItemContext GetContext() const
Definition Item.h:451
bool IsEquipped() const
Definition Item.cpp:1336
Player * GetOwner() const
Definition Item.cpp:1238
ObjectGuid GetOwnerGUID() const
Definition Item.h:197
uint16 GetPos() const
Definition Item.h:294
Optional< uint32 > GetDisenchantLootId() const
Definition Item.cpp:2378
std::unique_ptr< Loot > m_loot
Definition Item.h:328
uint32 GetEnchantmentCharges(EnchantmentSlot slot) const
Definition Item.h:310
void ClearSoulboundTradeable(Player *currentOwner)
Definition Item.cpp:1969
uint32 GetCount() const
Definition Item.h:283
AzeriteEmpoweredItem * ToAzeriteEmpoweredItem()
Definition Item.h:255
uint8 GetBagSlot() const
Definition Item.cpp:1331
uint32 GetModifier(ItemModifier modifier) const
Definition Item.cpp:2470
void SetEnchantment(EnchantmentSlot slot, uint32 id, uint32 duration, uint32 charges, ObjectGuid caster=ObjectGuid::Empty)
Definition Item.cpp:1511
static Item * CreateItem(uint32 itemEntry, uint32 count, ItemContext context, Player const *player=nullptr, bool addDefaultBonuses=true)
Definition Item.cpp:1721
Definition Map.h:225
bool IsDungeon() const
Definition Map.cpp:3267
void ScriptsStart(std::map< uint32, std::multimap< uint32, ScriptInfo > > const &scripts, uint32 id, Object *source, Object *target)
Put scripts in the execution queue.
bool AddToMap(T *)
Definition Map.cpp:517
TempSummon * SummonCreature(uint32 entry, Position const &pos, SummonPropertiesEntry const *properties=nullptr, Milliseconds duration=0ms, WorldObject *summoner=nullptr, uint32 spellId=0, uint32 vehId=0, ObjectGuid privateObjectOwner=ObjectGuid::Empty, SmoothPhasingInfo const *smoothPhasingInfo=nullptr)
Definition Object.cpp:1186
ObjectGuid::LowType GenerateLowGuid()
Definition Map.h:558
GameObject * GetGameObject(ObjectGuid const &guid)
Definition Map.cpp:3552
Creature * GetCreature(ObjectGuid const &guid)
Definition Map.cpp:3542
Unit * GetOwner() const
float GetFollowAngle() const override
void MoveJump(uint32 id, Position const &pos, std::variant< std::monostate, float, Milliseconds > speedOrTime={}, Optional< float > minHeight={}, Optional< float > maxHeight={}, MovementFacingTarget const &facing={}, bool orientationFixed=false, bool unlimitedSpeed=false, Optional< float > speedMultiplier={}, JumpArrivalCastArgs const *arrivalCast=nullptr, Movement::SpellEffectExtraData const *spellEffectExtraData=nullptr, Scripting::v2::ActionResultSetter< MovementStopReason > &&scriptResult={})
void MoveCharge(float x, float y, float z, float speed=SPEED_CHARGE, uint32 id=EVENT_CHARGE, bool generatePath=false, Unit const *target=nullptr, Movement::SpellEffectExtraData const *spellEffectExtraData=nullptr)
void MoveDistract(uint32 time, float orientation)
static ObjectGuid const Empty
Definition ObjectGuid.h:314
bool IsEmpty() const
Definition ObjectGuid.h:362
std::string ToString() const
void Clear()
Definition ObjectGuid.h:329
void SetDynamicFlag(uint32 flag)
Definition Object.h:97
Player * ToPlayer()
Definition Object.h:126
GameObject * ToGameObject()
Definition Object.h:131
void ReplaceAllDynamicFlags(uint32 flag)
Definition Object.h:99
uint32 GetEntry() const
Definition Object.h:89
Creature * ToCreature()
Definition Object.h:121
Unit * ToUnit()
Definition Object.h:116
float GetPathLength() const
bool CalculatePath(float srcX, float srcY, float srcZ, float destX, float destY, float destZ, bool forceDest=false)
std::array< Optional< PetInfo >, MAX_ACTIVE_PETS > ActivePets
Definition PetDefines.h:169
Definition Pet.h:40
void SetSpecialization(uint16 spec)
Definition Pet.cpp:1905
Player * GetOwner() const
Definition Pet.cpp:1801
void SavePetToDB(PetSaveMode mode)
Definition Pet.cpp:451
bool isControlled() const
Definition Pet.h:53
void setDeathState(DeathState s) override
Definition Pet.cpp:598
void Remove(PetSaveMode mode, bool returnreagent=false)
Definition Pet.cpp:711
bool learnSpell(uint32 spell_id)
Definition Pet.cpp:1453
static void InheritPhaseShift(WorldObject *target, WorldObject const *source)
static bool OnConditionChange(WorldObject *object, bool updateVisibility=true)
bool HasIgnore(ObjectGuid const &ignoreGuid, ObjectGuid const &ignoreAccountGuid)
void AutoStoreLoot(uint8 bag, uint8 slot, uint32 loot_id, LootStore const &store, ItemContext context=ItemContext::NONE, bool broadcast=false, bool createdByPlayer=false)
Definition Player.cpp:27179
void SendMovieStart(uint32 movieId)
Definition Player.cpp:6297
void SendLootError(ObjectGuid const &lootObj, ObjectGuid const &owner, LootError error) const
Definition Player.cpp:9196
ChrSpecialization GetPrimarySpecialization() const
Definition Player.h:2008
void SendEquipError(InventoryResult msg, Item const *item1=nullptr, Item const *item2=nullptr, uint32 itemId=0) const
Definition Player.cpp:13130
UF::UpdateField< UF::PlayerData, int32(WowCS::EntityFragment::CGObject), TYPEID_PLAYER > m_playerData
Definition Player.h:3061
void KilledMonsterCredit(uint32 entry, ObjectGuid guid=ObjectGuid::Empty)
Definition Player.cpp:16679
void SetDataFlagCharacter(uint32 dataFlagId, bool on)
Definition Player.cpp:30468
void SendPlayerBound(ObjectGuid const &binderGuid, uint32 areaId) const
Definition Player.cpp:17952
uint32 GetArmorProficiency() const
Definition Player.h:1640
static bool IsEquipmentPos(uint16 pos)
Definition Player.h:1488
void ApplyAzeriteEssence(AzeriteItem *item, uint32 azeriteEssenceId, uint32 rank, bool major, bool apply)
Definition Player.cpp:8602
uint8 GetNumRespecs() const
Definition Player.h:3012
Item * StoreNewItem(ItemPosCountVec const &pos, uint32 itemId, bool update, ItemRandomBonusListId randomBonusListId=0, GuidSet const &allowedLooters=GuidSet(), ItemContext context=ItemContext::NONE, std::vector< int32 > const *bonusListIDs=nullptr, bool addToCollection=true)
Definition Player.cpp:11370
bool HasPvPForcingQuest() const
Definition Player.cpp:17520
uint32 GetNextResetTalentsCost() const
Definition Player.cpp:3475
bool ModifyMoney(int64 amount, bool sendError=true)
Definition Player.cpp:24850
InventoryResult CanEquipItem(uint8 slot, uint16 &dest, Item *pItem, bool swap, bool not_loading=true) const
Definition Player.cpp:10788
void SetPlayerFlag(PlayerFlags flags)
Definition Player.h:2911
PlayerSocial * GetSocial() const
Definition Player.h:1290
void SetVisibleItemSlot(uint8 slot, Item const *item)
Definition Player.cpp:11830
void SendBindPointUpdate() const
Definition Player.cpp:17943
uint32 EnvironmentalDamage(EnviromentalDamage type, uint32 damage)
Definition Player.cpp:627
uint8 GetDrunkValue() const
Definition Player.h:2479
void SendDirectMessage(WorldPacket const *data) const
Definition Player.cpp:6283
uint16 GetSkillValue(uint32 skill) const
Definition Player.cpp:6010
Item * BankItem(ItemPosCountVec const &dest, Item *pItem, bool update)
Definition Player.cpp:11984
void RemoveTalent(TalentEntry const *talent)
Definition Player.cpp:2719
void DespawnPersonalSummonsForQuest(uint32 questId)
Definition Player.cpp:16314
UF::UpdateField< UF::ActivePlayerData, int32(WowCS::EntityFragment::CGObject), TYPEID_ACTIVE_PLAYER > m_activePlayerData
Definition Player.h:3062
void SetCanParry(bool value)
Definition Player.cpp:26887
void UpdateQuestObjectiveProgress(QuestObjectiveType objectiveType, int32 objectId, int64 addCount, ObjectGuid victimGuid=ObjectGuid::Empty, std::vector< QuestObjective const * > *updatedObjectives=nullptr, std::function< bool(QuestObjective const *)> const *objectiveFilter=nullptr)
Definition Player.cpp:16737
InventoryResult CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec &dest, Item *pItem, bool swap=false) const
Definition Player.cpp:10055
void CreateGarrison(uint32 garrSiteId)
Definition Player.cpp:30149
Pet * SummonPet(uint32 entry, Optional< PetSaveMode > slot, float x, float y, float z, float ang, uint32 despwtime, bool *isNew=nullptr)
Definition Player.cpp:30523
void SetCanTitanGrip(bool value, uint32 penaltySpellId=0)
Definition Player.cpp:13202
void SendProficiency(ItemClass itemClass, uint32 itemSubclassMask) const
Definition Player.cpp:23098
void SendTalentsInfoData()
Definition Player.cpp:28107
void UpdatePvPState(bool onlyFFA=false)
Definition Player.cpp:24066
void DurabilityLossAll(double percent, bool inventory)
Definition Player.cpp:4567
void AddHonorXP(uint32 xp)
Definition Player.cpp:6959
uint32 GetDeathTimer() const
Definition Player.h:2482
void SendPlayerChoice(ObjectGuid sender, int32 choiceId)
Definition Player.cpp:30184
void _ApplyItemMods(Item *item, uint8 slot, bool apply, bool updateItemAuras=true)
Definition Player.cpp:7917
void GiveXP(uint32 xp, Unit *victim, float group_rate=1.0f)
Definition Player.cpp:2199
void SetResurrectRequestData(WorldObject const *caster, uint32 health, uint32 mana, uint32 appliedAura)
Definition Player.cpp:24151
Item * GetItemByEntry(uint32 entry, ItemSearchLocation where=ItemSearchLocation::Default) const
Definition Player.cpp:12475
void SpawnCorpseBones(bool triggerSave=true)
Definition Player.cpp:4554
void SetDrunkValue(uint8 newDrunkValue, uint32 itemId=0)
Definition Player.cpp:880
std::vector< uint32 > const & GetGlyphs(uint8 spec) const
Definition Player.h:2044
PetStable * GetPetStable()
Definition Player.h:1355
void PetSpellInitialize()
Definition Player.cpp:22471
SceneMgr & GetSceneMgr()
Definition Player.h:2888
void SetFallInformation(uint32 time, float z)
Definition Player.cpp:27493
void ApplyEnchantment(Item *item, EnchantmentSlot slot, bool apply, bool apply_dur=true, bool ignore_condition=false)
Definition Player.cpp:13455
bool IsLoading() const override
Definition Player.cpp:17958
void ActivateTalentGroup(ChrSpecializationEntry const *spec)
Definition Player.cpp:28842
bool UpdateCraftSkill(SpellInfo const *spellInfo)
Definition Player.cpp:5499
bool CanAddQuest(Quest const *quest, bool msg) const
Definition Player.cpp:14534
InventoryResult CanBankItem(uint8 bag, uint8 slot, ItemPosCountVec &dest, Item *pItem, bool swap, bool not_loading=true, bool reagentBankOnly=false) const
Definition Player.cpp:11064
void SetSkill(uint32 id, uint16 step, uint16 newVal, uint16 maxVal)
Definition Player.cpp:5744
void UpdateVisibleObjectInteractions(bool allUnits, bool onlySpellClicks, bool gameObjectQuestGiverStatus, bool questObjectiveGameObjects)
Definition Player.cpp:25949
Pet * GetPet() const
Definition Player.cpp:22060
WorldLocation m_homebind
Definition Player.h:2693
Guild * GetGuild()
Definition Player.cpp:30511
void SetNumRespecs(uint8 numRespecs)
Definition Player.h:3013
uint16 GetPureSkillValue(uint32 skill) const
Definition Player.cpp:6066
void RemoveTradeableItem(Item *item)
Definition Player.cpp:13292
void CompleteQuest(uint32 quest_id)
Definition Player.cpp:14936
void SetCanBlock(bool value)
Definition Player.cpp:26896
bool GetCommandStatus(uint32 command) const
Definition Player.h:1339
Item * StoreItem(ItemPosCountVec const &pos, Item *pItem, bool update)
Definition Player.cpp:11447
WorldSession * GetSession() const
Definition Player.h:2272
void LearnSpell(uint32 spell_id, bool dependent, int32 fromSkill=0, bool suppressMessaging=false, Optional< PlayerSpellTrait > trait={})
Definition Player.cpp:3178
void UpdateAreaDependentAuras(uint32 area_id)
Definition Player.cpp:26546
Item * GetItemByPos(uint16 pos) const
Definition Player.cpp:9630
void EquipTransmogOutfit(uint32 id, TransmogSituationTrigger trigger, Optional< bool > locked)
Definition Player.cpp:31251
RestMgr & GetRestMgr() const
Definition Player.h:2890
void RepopAtGraveyard()
Definition Player.cpp:4788
void SetDataElementCharacter(uint32 dataElementId, std::variant< int64, float > value)
Definition Player.cpp:30391
void DestroyItem(uint8 bag, uint8 slot, bool update)
Definition Player.cpp:12121
bool IsResurrectRequested() const
Definition Player.h:2104
static bool IsInventoryPos(uint16 pos)
Definition Player.h:1486
void SendLoot(Loot &loot, bool aeLooting=false)
Definition Player.cpp:9167
void UpdateTraitConfig(WorldPackets::Traits::TraitConfig &&newConfig, int32 savedConfigId, bool withCastTime)
Definition Player.cpp:29197
uint32 DestroyItemCount(uint32 item, uint32 count, bool update, bool unequip_check=false)
Definition Player.cpp:12222
void RemovePet(Pet *pet, PetSaveMode mode, bool returnreagent=false)
Definition Player.cpp:22084
int32 CalculateReputationGain(ReputationSource source, uint32 creatureOrQuestLevel, int32 rep, int32 faction, bool noQuestBonus=false)
Definition Player.cpp:6512
bool TeleportTo(uint32 mapid, float x, float y, float z, float orientation, TeleportToOptions options=TELE_TO_NONE, Optional< uint32 > instanceId={}, uint32 teleportSpellId=0)
Definition Player.cpp:1226
ActionButton const * GetActionButton(uint8 button)
Definition Player.cpp:6223
void DurabilityLoss(Item *item, double percent)
Definition Player.cpp:4591
uint32 GetWeaponProficiency() const
Definition Player.h:1639
void SendRespecWipeConfirm(ObjectGuid const &guid, uint32 cost, SpecResetType respecType) const
Definition Player.cpp:9256
uint16 GetSkillStep(uint32 skill) const
Definition Player.cpp:5998
void SetDataElementAccount(uint32 dataElementId, std::variant< int64, float > value)
Definition Player.cpp:30337
void AutoUnequipOffhandIfNeed(bool force=false)
Definition Player.cpp:26170
void ItemAddedQuestCheck(uint32 entry, uint32 count, Optional< bool > boundItemFlagRequirement={}, bool *hadBoundItemObjective=nullptr)
Definition Player.cpp:16599
Item * EquipItem(uint16 pos, Item *pItem, bool update)
Definition Player.cpp:11589
void SetDuelArbiter(ObjectGuid guid)
Definition Player.h:2147
PvPInfo pvpInfo
Definition Player.h:2124
void AddQuestAndCheckCompletion(Quest const *quest, Object *questGiver)
Definition Player.cpp:14676
void DurabilityPointsLossAll(int32 points, bool inventory)
Definition Player.cpp:4611
bool CanTakeQuest(Quest const *quest, bool msg) const
Definition Player.cpp:14522
uint32 GetProfessionSkillForExp(uint32 skill, int32 expansion) const
Definition Player.cpp:5963
uint8 GetActiveTalentGroup() const
Definition Player.h:2010
void RemoveSpell(uint32 spell_id, bool disabled=false, bool learn_low_rank=true, bool suppressMessaging=false)
Definition Player.cpp:3223
void SendSummonRequestFrom(Unit *summoner)
Definition Player.cpp:26074
void AreaExploredOrEventHappens(uint32 questId)
Definition Player.cpp:16552
bool TakeQuestSourceItem(uint32 questId, bool msg)
Definition Player.cpp:15911
void RemoveActiveQuest(uint32 questId, bool update=true)
Definition Player.cpp:16005
QuestStatus GetQuestStatus(uint32 quest_id) const
Definition Player.cpp:15962
Garrison * GetGarrison() const
Definition Player.h:2883
void CreateTraitConfig(WorldPackets::Traits::TraitConfig &traitConfig)
Definition Player.cpp:29124
void AddArmorProficiency(uint32 newflag)
Definition Player.h:1638
void SetHomebind(WorldLocation const &loc, uint32 areaId)
Definition Player.cpp:17926
void FailQuest(uint32 quest_id)
Definition Player.cpp:15347
bool ActivateTaxiPathTo(std::vector< uint32 > const &nodes, Creature *npc=nullptr, uint32 spellid=0, uint32 preferredMountDisplay=0, Optional< float > speed={}, Scripting::v2::ActionResultSetter< MovementStopReason > const &scriptResult={})
Definition Player.cpp:23160
static bool IsBankPos(uint16 pos)
Definition Player.h:1491
void RemoveItem(uint8 bag, uint8 slot, bool update)
Definition Player.cpp:11989
bool HasSpell(uint32 spell) const override
Definition Player.cpp:3735
Group * GetGroup(Optional< uint8 > partyIndex)
Definition Player.h:2796
std::unique_ptr< DuelInfo > duel
Definition Player.h:2143
void RemoveRewardedQuest(uint32 questId, bool update=true)
Definition Player.cpp:16038
void DurabilityPointsLoss(Item *item, int32 points)
Definition Player.cpp:4635
Item * GetItemByGuid(ObjectGuid guid) const
Definition Player.cpp:9614
void SetDataFlagAccount(uint32 dataFlagId, bool on)
Definition Player.cpp:30431
void RemovedInsignia(Player *looterPlr)
Definition Player.cpp:9110
bool UpdateGatherSkill(uint32 skillId, uint32 skillValue, uint32 redLevel, uint32 multiplicator=1, WorldObject const *object=nullptr)
Definition Player.cpp:5534
void AddWeaponProficiency(uint32 newflag)
Definition Player.h:1637
void ModifyCurrency(uint32 id, int32 amount, CurrencyGainSource gainSource=CurrencyGainSource::Cheat, CurrencyDestroyReason destroyReason=CurrencyDestroyReason::Cheat)
Modify currency amount.
Definition Player.cpp:7146
InventoryResult CanStoreNewItem(uint8 bag, uint8 slot, ItemPosCountVec &dest, uint32 item, uint32 count, uint32 *no_space_count=nullptr) const
Definition Player.cpp:10050
std::unique_ptr< PlayerMenu > PlayerTalkClass
Definition Player.h:2570
ReputationMgr & GetReputationMgr()
Definition Player.h:2439
void AddPetAura(PetAura const *petSpell)
Definition Player.cpp:22228
void RewardPlayerAndGroupAtEvent(uint32 creature_id, WorldObject *pRewardSource)
Definition Player.cpp:26409
void SendNewItem(Item *item, uint32 quantity, bool received, bool created, bool broadcast=false, uint32 dungeonEncounterId=0)
Definition Player.cpp:13878
void ResurrectPlayer(float restore_percent, bool applySickness=false)
Definition Player.cpp:4379
uint32 XPValue(Player const *player) const
Definition QuestDef.cpp:428
bool HasFlag(QuestFlags flag) const
Definition QuestDef.h:619
bool ModifyReputation(FactionEntry const *factionEntry, int32 standing, bool spillOverOnly=false, bool noSpillover=false)
void AddRestBonus(RestTypes restType, float restBonus)
Definition RestMgr.cpp:85
float CalcExtraPerSec(RestTypes restType, float bubble) const
Definition RestMgr.cpp:158
uint32 PlaySceneByPackageId(uint32 sceneScriptPackageId, EnumFlag< SceneFlag > playbackflags, Position const *position=nullptr)
Definition SceneMgr.cpp:83
uint32 PlayScene(uint32 sceneId, Position const *position=nullptr)
Definition SceneMgr.cpp:36
static SceneObject * CreateSceneObject(uint32 sceneId, Unit *creator, Position const &pos, ObjectGuid privateObjectOwner)
void SetItemTarget(Item *item)
Definition Spell.cpp:263
void SetDst(float x, float y, float z, float orientation, uint32 mapId=MAPID_INVALID)
Definition Spell.cpp:341
void SetGOTarget(GameObject *target)
Definition Spell.cpp:220
void SetUnitTarget(Unit *target)
Definition Spell.cpp:194
bool HasDst() const
Definition Spell.cpp:393
Item * GetItemTarget() const
Unit * GetUnitTarget() const
Definition Spell.cpp:186
void Update(WorldObject *caster)
Definition Spell.cpp:398
WorldLocation const * GetDstPos() const
Definition Spell.cpp:336
float PositionFacing
Definition SpellInfo.h:227
bool HasRadius(SpellTargetIndex targetIndex) const
SpellEffectValue CalcValue(WorldObject const *caster=nullptr, SpellEffectValue const *basePoints=nullptr, Unit const *target=nullptr, float *variance=nullptr, uint32 castItemId=0, int32 itemLevel=-1) const
float CalcValueMultiplier(WorldObject *caster, Spell *spell=nullptr) const
uint32 TriggerSpell
Definition SpellInfo.h:234
SpellEffectName Effect
Definition SpellInfo.h:215
bool IsEffect() const
SpellRange CalcRadius(WorldObject const *caster=nullptr, SpellTargetIndex targetIndex=SpellTargetIndex::TargetA, Spell *spell=nullptr) const
SpellEffIndex EffectIndex
Definition SpellInfo.h:214
uint32 GetProvidedTargetMask() const
void RestoreCharge(uint32 chargeCategoryId)
void LockSpellSchool(SpellSchoolMask schoolMask, Duration lockoutTime)
void ModifyCoooldowns(Predicate &&predicate, Duration cooldownMod, bool withoutCategoryCooldown=false)
void ModifyCooldown(uint32 spellId, Duration cooldownMod, bool withoutCategoryCooldown=false)
bool HasCooldown(SpellInfo const *spellInfo, uint32 itemId=0) const
SpellRange GetMinMaxRange(bool positive=false, WorldObject const *caster=nullptr, Spell *spell=nullptr) const
Optional< SpellPowerCost > CalcPowerCost(Powers powerType, bool optionalCost, WorldObject const *caster, SpellSchoolMask schoolMask, Spell *spell=nullptr) const
uint64 GetAllEffectsMechanicMask() const
uint32 const Id
Definition SpellInfo.h:328
uint32 StackAmount
Definition SpellInfo.h:396
bool IsLootCrafting() const
uint32 GetDispelMask() const
bool NeedsToBeTriggeredByCaster(SpellInfo const *triggeringSpell) const
float Speed
Definition SpellInfo.h:393
int32 EquippedItemClass
Definition SpellInfo.h:402
flag128 SpellFamilyFlags
Definition SpellInfo.h:415
SpellSchoolMask GetSchoolMask() const
bool IsChanneled() const
bool HasAttribute(SpellAttr0 attribute) const
Definition SpellInfo.h:456
int32 GetDuration() const
SpellEffectInfo const & GetEffect(SpellEffIndex index) const
Definition SpellInfo.h:588
std::vector< SpellEffectInfo > const & GetEffects() const
Definition SpellInfo.h:587
int32 EquippedItemSubClassMask
Definition SpellInfo.h:403
uint32 GetExplicitTargetMask() const
int32 CalcDuration(WorldObject const *caster=nullptr) const
bool HasAura(AuraType aura) const
uint32 SpellFamilyName
Definition SpellInfo.h:414
bool CanBeInterrupted(WorldObject const *interruptCaster, Unit const *interruptTarget, bool ignoreImmunity=false) const
Definition Spell.h:277
void EffectSummonRaFFriend()
SpellInfo const * GetSpellInfo() const
Definition Spell.h:702
void EffectSendEvent()
void EffectTransmitted()
void EffectUpgradeHeirloom()
void ExecuteLogEffectSummonObject(SpellEffectName effect, WorldObject *obj)
Definition Spell.cpp:5211
void EffectSpiritHeal()
void EffectRemoveAuraBySpellLabel()
void EffectBlock()
void EffectPlayMusic()
void EffectChangeBattlePetQuality()
GameObject * gameObjTarget
Definition Spell.h:799
void EffectGrantBattlePetExperience()
SpellMissInfo targetMissInfo
Definition Spell.h:804
void UpdateDelayMomentForUnitTarget(Unit *unit, uint64 hitDelay)
Definition Spell.cpp:869
void EffectCreateItem2()
void EffectEnchantHeldItem()
Unit * m_originalCaster
Definition Spell.h:751
void EffectHealMaxHealth()
void EffectProspecting()
DynObjAura * _dynObjAura
Definition Spell.h:811
void EffectSetPlayerDataFlagCharacter()
void ExecuteLogEffectUnsummonObject(SpellEffectName effect, WorldObject *obj)
Definition Spell.cpp:5219
void EffectCharge()
void EffectSummonObject()
void ExecuteLogEffectResurrect(SpellEffectName effect, Unit *target)
Definition Spell.cpp:5227
void EffectSendTaxi()
void EffectCreateItem()
void ExecuteLogEffectDestroyItem(SpellEffectName effect, uint32 entry)
Definition Spell.cpp:5203
void EffectTameCreature()
void ExecuteLogEffectOpenLock(SpellEffectName effect, Object *obj)
Definition Spell.cpp:5187
void EffectGameObjectDamage()
SpellCastTargets m_targets
Definition Spell.h:651
void EffectSummonChangeItem()
void EffectDummy()
std::unique_ptr< PathGenerator > m_preGeneratedPath
Definition Spell.h:1000
Difficulty GetCastDifficulty() const
Definition Spell.cpp:8233
union Spell::@321 m_misc
void EffectLearnAzeriteEssencePower()
void EffectHealthLeech()
void EffectActivateGarrisonBuilding()
void EffectStealBeneficialBuff()
void EffectCancelConversation()
void EffectStuck()
void EffectInterruptCast()
void EffectSummonPlayer()
void EffectWeaponDmg()
SpellCastResult CanOpenLock(SpellEffectInfo const &effect, uint32 lockid, SkillType &skillid, int32 &reqSkillValue, int32 &skillValue)
Definition Spell.cpp:8716
void EffectEnchantItemPrismatic()
void EffectSummonType()
void EffectSkinPlayerCorpse()
SpellEffectHandleMode effectHandleMode
Definition Spell.h:806
void EffectEquipTransmogOutfit()
void SummonGuardian(SpellEffectInfo const *effect, uint32 entry, SummonPropertiesEntry const *properties, uint32 numSummons, ObjectGuid privateObjectOwner)
void EffectHealMechanical()
void EffectGameObjectRepair()
void EffectCreateGarrison()
void EffectSummonObjectWild()
void EffectSendChatMessage()
uint32 Id
Definition Spell.h:626
void EffectActivateObject()
std::vector< TargetInfo > m_UniqueTargetInfo
Definition Spell.h:877
void EffectSkill()
SpellDestination m_destTargets[MAX_SPELL_EFFECTS]
Definition Spell.h:909
void EffectSetPlayerDataElementCharacter()
void EffectLeap()
void UpdateDelayMomentForDst(uint64 hitDelay)
Definition Spell.cpp:861
void EffectTradeSkill()
void EffectPersistentAA()
void EffectQuestClear()
void EffectModifyThreatPercent()
void EffectForceDeselect()
int32 GetEffectValueAsInt() const
Definition Spell.h:803
void EffectParry()
void EffectRenamePet()
void ExecuteLogEffectExtraAttacks(SpellEffectName effect, Unit *victim, uint32 numAttacks)
Definition Spell.cpp:5157
void EffectResurrect()
void EffectDestroyAllTotems()
WeaponAttackType m_attackType
Definition Spell.h:755
void ExecuteLogEffectTakeTargetPower(SpellEffectName effect, Unit *target, Powers powerType, uint32 points, float amplitude)
Definition Spell.cpp:5145
void EffectCreateTraitTreeConfig()
void EffectResurrectPet()
void EffectApplyEnchantIllusion()
void EffectTriggerSpell()
SpellEffectValue CalculateDamage(SpellEffectInfo const &spellEffectInfo, Unit const *target, float *var=nullptr) const
Definition Spell.cpp:7266
void EffectGiveHonor()
void SendSpellInterruptLog(Unit *victim, uint32 spellId)
Definition Spell.cpp:5166
std::any m_customArg
Definition Spell.h:649
void EffectPullTowards()
ObjectGuid m_originalCasterGUID
Definition Spell.h:749
WorldObject *const m_caster
Definition Spell.h:745
void EffectCreatePrivateSceneObject()
void EffectRechargeItem()
void EffectLearnGarrisonBuilding()
void EffectPowerBurn()
void EffectUpdateInteractions()
std::string GetDebugInfo() const
Definition Spell.cpp:9306
void EffectDurabilityDamage()
void EffectKillCreditLabel()
void ExecuteLogEffectDurabilityDamage(SpellEffectName effect, Unit *victim, int32 itemId, int32 amount)
Definition Spell.cpp:5177
void EffectSanctuary()
void EffectHealBattlePetPct()
void EffectCastButtons()
Item * itemTarget
Definition Spell.h:798
static void SendCastResult(Player *caster, SpellInfo const *spellInfo, SpellCastVisual spellVisual, ObjectGuid cast_count, SpellCastResult result, SpellCustomErrors customError=SPELL_CUSTOM_ERROR_NONE, int32 *param1=nullptr, int32 *param2=nullptr)
Definition Spell.cpp:4699
float variance
Definition Spell.h:805
int32 m_damage
Definition Spell.h:817
void EffectGiveArtifactPower()
void EffectKnockBack()
void EffectReputation()
void EffectDistract()
void EffectKillCredit()
void DoCreateItem(uint32 itemId, ItemContext context=ItemContext::NONE, std::vector< int32 > const *bonusListIDs=nullptr)
void EffectRespecAzeriteEmpoweredItem()
void EffectSummonPet()
void EffectModifyCooldownsByCategory()
SpellEffectValue effectValue
Definition Spell.h:802
void EffectEnergizePct()
void EffectDispelMechanic()
void EffectSelfResurrect()
void EffectGiveRestedExperience()
void EffectDispel()
void EffectBind()
void SendSpellCooldown()
Definition Spell.cpp:4209
void EffectLearnTransmogIllusion()
void EffectPlayMovie()
void EffectFeedPet()
void EffectNULL()
void EffectApplyAura()
void EffectUncageBattlePet()
void EffectTriggerRitualOfSummoning()
void EffectInstaKill()
void EffectCreateAreaTrigger()
void EffectInebriate()
void EffectOpenLock()
void EffectEnvironmentalDMG()
void EffectRedirectThreat()
void EffectChangeActiveCombatTraitConfig()
void EffectLearnTransmogSet()
void EffectRemoveAura()
void EffectDualWield()
void EffectUpdatePlayerPhase()
int32 m_healing
Definition Spell.h:818
void EffectPickPocket()
void EffectTeleportUnitsWithVisualLoadingScreen()
void EffectModifyAuraStacks()
void EffectProficiency()
void EffectSummonPersonalGameObject()
SpellEffectInfo const * effectInfo
Definition Spell.h:807
void EffectDisEnchant()
void EffectEnableBattlePets()
void EffectGiveArtifactPowerNoBonus()
Unit * GetUnitCasterForEffectHandlers() const
Definition Spell.cpp:8417
void EffectTeleportToReturnPoint()
void EffectAddExtraAttacks()
int32 m_castItemLevel
Definition Spell.h:603
void EffectTriggerMissileSpell()
UnitAura * _spellAura
Definition Spell.h:810
void EffectModifyCooldown()
Unit * unitTarget
Definition Spell.h:797
void EffectEnchantItemTmp()
SpellSchoolMask m_spellSchoolMask
Definition Spell.h:754
void EffectCreateRandomItem()
void EffectTeleUnitsFaceCaster()
void EffectDamageFromMaxHealthPCT()
void EffectCreateHeirloomItem()
WorldObject * GetCaster() const
Definition Spell.h:699
void EffectPullTowardsDest()
void EffectSetPlayerDataElementAccount()
void EffectKillCreditPersonal()
void EffectLaunchQuestChoice()
void EffectSchoolDMG()
void EffectChangeRaidMarker()
void EffectGrantBattlePetLevel()
void EffectThreat()
Corpse * m_corpseTarget
Definition Spell.h:800
void EffectResurrectNew()
void EffectChargeDest()
void EffectUntrainTalents()
void EffectUnlockGuildVaultTab()
void EffectLearnSpell()
void ExecuteLogEffectCreateItem(SpellEffectName effect, uint32 entry)
Definition Spell.cpp:5195
void EffectMilling()
void EffectHealPct()
void EffectJumpCharge()
void EffectJumpDest()
void EffectScriptEffect()
void EffectAddFarsight()
void EffectEnergize()
void EffectCreateSceneObject()
WorldLocation * destTarget
Definition Spell.h:801
void EffectGameObjectSetDestructionState()
void EffectIncreaseCurrencyCap()
void EffectApplyGlyph()
void EffectResurrectWithAura()
void EffectGiveCurrency()
void EffectModifyCooldowns()
void EffectQuestComplete()
void EffectDiscoverTaxi()
void EffectModifySpellCharges()
void EffectForceCast2()
void EffectTeleportUnits()
void EffectGiveExperience()
void EffectCreatePrivateConversation()
void EffectPlaySceneScriptPackage()
void EffectPlaySound()
void EffectLearnPetSpell()
void EffectTeleportGraveyard()
void EffectPowerDrain()
Item * m_CastItem
Definition Spell.h:600
void CallScriptSuccessfulDispel(SpellEffIndex effIndex)
Definition Spell.cpp:8970
uint32 m_castItemEntry
Definition Spell.h:602
int32 GetUnitTargetIndexForEffect(ObjectGuid const &target, SpellEffIndex effect) const
Definition Spell.cpp:2683
void EffectTaunt()
void EffectLeapBack()
void EffectDurabilityDamagePCT()
SpellValue *const m_spellValue
Definition Spell.h:747
void EffectLearnSkill()
void finish(SpellCastResult result=SPELL_CAST_OK)
Definition Spell.cpp:4342
void SendResurrectRequest(Player *target)
Definition Spell.cpp:5403
void EffectActivateSpec()
void EffectForceCast()
void EffectDismissPet()
void EffectPlayScene()
void EffectEnchantItemPerm()
void EffectQuestFail()
void EffectCreateTamedPet()
void EffectSetPlayerDataFlagAccount()
void EffectAddGarrisonFollower()
void EffectLearnWarbandScene()
void EffectJump()
void EffectSkipQuestLine()
void EffectDestroyItem()
ObjectGuid m_castItemGUID
Definition Spell.h:601
void EffectRemoveTalent()
SpellCastVisual m_SpellVisual
Definition Spell.h:650
int64 GetUnitTargetCountForEffect(SpellEffIndex effect) const
Definition Spell.cpp:2700
GameObject * focusObject
Definition Spell.h:814
void EffectTitanGrip()
ObjectGuid m_castId
Definition Spell.h:604
SpellInfo const *const m_spellInfo
Definition Spell.h:599
void EffectUnlearnSpecialization()
void EffectUpdateZoneAurasAndPhases()
void EffectQuestStart()
void EffectApplyMountEquipment()
void EffectSkipCampaign()
void EffectDuel()
void EffectUnused()
void EffectCreateConversation()
void EffectSkinning()
void EffectHeal()
virtual void UnSummon(uint32 msTime=0)
void SetTempSummonType(TempSummonType type)
void RegisterRedirectThreat(uint32 spellId, ObjectGuid const &victim, float pct)
== REDIRECT SYSTEM ==
Unit * GetCurrentVictim()
auto const & GetThreatenedByMeList() const
void ModifyThreatByPercent(Unit *target, float percent)
bool IsThreatListEmpty(bool includeOffline=false) const
void AddThreat(Unit *target, float amount, SpellInfo const *spell=nullptr, bool ignoreModifiers=false, bool ignoreRedirects=false)
== AFFECT MY THREAT LIST ==
void MatchUnitThreatToHighestThreat(Unit *target)
void UnSummon(uint32 msTime=0) override
Definition Totem.cpp:100
Definition Unit.h:635
float GetPctModifierValue(UnitMods unitMod, UnitModifierPctType modifierType) const
Definition Unit.cpp:9664
void ClearUnitState(uint32 f)
Definition Unit.h:744
bool IsVehicle() const
Definition Unit.h:754
int32 GetContentTuning() const
Definition Unit.h:756
void SetMinion(Minion *minion, bool apply)
Definition Unit.cpp:6247
int32 ModifyPower(Powers power, int32 val, bool withPowerUpdate=true)
Definition Unit.cpp:8697
int32 SpellDamageBonusDone(Unit *victim, SpellInfo const *spellProto, int32 pdamage, DamageEffectType damagetype, SpellEffectInfo const &spellEffectInfo, uint32 stack=1, Spell *spell=nullptr, AuraEffect const *aurEff=nullptr) const
Definition Unit.cpp:6811
void RemoveOwnedAura(AuraMap::iterator &i, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition Unit.cpp:3751
void RemoveAurasByType(AuraType auraType, std::function< bool(AuraApplication const *)> const &check, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition Unit.cpp:3955
void RemoveGameObject(GameObject *gameObj, bool del)
Definition Unit.cpp:5378
AuraEffectList const & GetAuraEffectsByType(AuraType type) const
Definition Unit.h:1342
void CombatStop(bool includingCast=false, bool mutualPvP=true, bool(*unitFilter)(Unit const *otherUnit)=nullptr)
Definition Unit.cpp:6012
uint32 m_lastSanctuaryTime
Definition Unit.h:1590
int32 MeleeDamageBonusTaken(Unit *attacker, int32 pdamage, WeaponAttackType attType, DamageEffectType damagetype, SpellInfo const *spellProto=nullptr, SpellSchoolMask damageSchoolMask=SPELL_SCHOOL_MASK_NORMAL)
Definition Unit.cpp:8133
void SetHealth(uint64 val)
Definition Unit.cpp:9973
void SetVirtualItem(uint32 slot, uint32 itemId, uint16 appearanceModId=0, uint16 itemVisual=0)
Definition Unit.cpp:14374
uint64 CountPctFromMaxHealth(float pct) const
Definition Unit.h:797
int32 SpellHealingBonusTaken(Unit *caster, SpellInfo const *spellProto, int32 healamount, DamageEffectType damagetype) const
Definition Unit.cpp:7495
Pet * ToPet()
Definition Unit.h:1822
bool CanHaveThreatList() const
====================== THREAT & COMBAT ====================
Definition Unit.h:1030
void SetUnitFlag3(UnitFlags3 flags)
Definition Unit.h:856
void RemoveAura(AuraApplicationMap::iterator &i, AuraRemoveMode mode=AURA_REMOVE_BY_DEFAULT)
Definition Unit.cpp:3828
void EnergizeBySpell(Unit *victim, SpellInfo const *spellInfo, int32 damage, Powers powerType)
Definition Unit.cpp:6798
void SendPlaySpellVisual(Unit *target, uint32 spellVisualId, uint8 missReason, uint8 reflectStatus, float travelSpeed, bool speedAsTime=false, float launchDelay=0.0f)
Definition Unit.cpp:12305
ThreatManager & GetThreatManager()
Definition Unit.h:1078
virtual void SetCanDualWield(bool value)
Definition Unit.h:704
uint8 GetClass() const
Definition Unit.h:764
std::array< ObjectGuid, MAX_SUMMON_SLOT > m_SummonSlot
Definition Unit.h:1501
Totem * ToTotem()
Definition Unit.h:1825
int64 GetHealthGain(int64 dVal)
Definition Unit.cpp:8641
void RemoveAurasDueToSpellByDispel(uint32 spellId, uint32 dispellerSpellId, ObjectGuid casterGUID, WorldObject *dispeller, uint8 chargesRemoved=1)
Definition Unit.cpp:4007
std::forward_list< AuraEffect * > AuraEffectList
Definition Unit.h:652
void SetPower(Powers power, int32 val, bool withPowerUpdate=true)
Definition Unit.cpp:10046
Pet * CreateTamedPetFrom(Creature *creatureTarget, uint32 spell_id=0)
Definition Unit.cpp:11072
uint32 CalculateDamage(WeaponAttackType attType, bool normalized, bool addTotalPct) const
Definition Unit.cpp:2499
static void CalcAbsorbResist(DamageInfo &damageInfo, Spell *spell=nullptr)
Definition Unit.cpp:1876
Unit * GetVehicleBase() const
Definition Unit.cpp:12111
MotionMaster * GetMotionMaster()
Definition Unit.h:1723
bool IsPet() const
Definition Unit.h:751
Powers GetPowerType() const
Definition Unit.h:811
bool HasUnitFlag(UnitFlags flags) const
Definition Unit.h:845
std::array< ObjectGuid, MAX_GAMEOBJECT_SLOT > m_ObjectSlot
Definition Unit.h:1502
void SetCreatedBySpell(int32 spellId)
Definition Unit.h:860
void AddChannelObject(ObjectGuid guid)
Definition Unit.cpp:3059
AuraEffect * GetAuraEffect(uint32 spellId, uint8 effIndex, ObjectGuid casterGUID=ObjectGuid::Empty) const
Definition Unit.cpp:4604
void SetDemonCreatorGUID(ObjectGuid guid)
Definition Unit.h:1204
bool IsAlive() const
Definition Unit.h:1185
AuraEffect * IsScriptOverriden(SpellInfo const *spell, int32 script) const
Definition Unit.cpp:4916
float GetCombatReach() const override
Definition Unit.h:705
int32 GetMaxPower(Powers power) const
Definition Unit.cpp:10037
int32 HealBySpell(HealInfo &healInfo, bool critical=false)
Definition Unit.cpp:6776
void SendSpellNonMeleeDamageLog(SpellNonMeleeDamage const *log)
Definition Unit.cpp:5540
void SetPetFlag(UnitPetFlag flags)
Definition Unit.h:892
TempSummon * ToTempSummon()
Definition Unit.h:1828
CharmInfo * GetCharmInfo()
Definition Unit.h:1242
void AddGameObject(GameObject *gameObj)
Definition Unit.cpp:5357
bool IsInFlight() const
Definition Unit.h:1027
void SetChannelObject(uint32 slot, ObjectGuid guid)
Definition Unit.cpp:3064
uint64 GetMaxHealth() const
Definition Unit.h:789
bool Attack(Unit *victim, bool meleeAttack)
Definition Unit.cpp:5853
Aura * GetAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint32 reqEffMask=0) const
Definition Unit.cpp:4700
uint64 GetHealth() const
Definition Unit.h:788
bool IsSummon() const
Definition Unit.h:749
uint32 GetFaction() const override
Definition Unit.h:871
void GetDispellableAuraList(WorldObject const *caster, uint32 dispelMask, DispelChargesList &dispelList, bool isReflect=false) const
Definition Unit.cpp:4736
AttackerSet const & getAttackers() const
Definition Unit.h:724
std::multimap< uint32, Aura * > AuraMap
Definition Unit.h:641
void SetFullPower(Powers power)
Definition Unit.h:825
void RemoveAurasWithInterruptFlags(InterruptFlags flag, SpellInfo const *source=nullptr)
Definition Unit.cpp:4241
void SetMaxHealth(uint64 val)
Definition Unit.cpp:10004
std::set< Unit * > AttackerSet
Definition Unit.h:637
void RemoveAppliedAuras(std::function< bool(AuraApplication const *)> const &check, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition Unit.cpp:3901
bool IsGuardian() const
Definition Unit.h:750
UF::UpdateField< UF::UnitData, int32(WowCS::EntityFragment::CGObject), TYPEID_UNIT > m_unitData
Definition Unit.h:1881
void AddExtraAttacks(uint32 count)
Definition Unit.cpp:2372
void SetOwnerGUID(ObjectGuid owner)
Definition Unit.cpp:6171
ObjectGuid GetTransGUID() const override
Definition Unit.cpp:12141
void NearTeleportTo(TeleportLocation const &target, bool casting=false)
Definition Unit.cpp:12958
bool HasUnitState(const uint32 f) const
Definition Unit.h:743
AuraApplication * _CreateAuraApplication(Aura *aura, uint32 effMask)
Definition Unit.cpp:3489
int32 SpellDamageBonusTaken(Unit *caster, SpellInfo const *spellProto, int32 pdamage, DamageEffectType damagetype) const
Definition Unit.cpp:6994
void SetLevel(uint8 lvl, bool sendUpdate=true)
Definition Unit.cpp:9956
std::unique_ptr< Movement::MoveSpline > movespline
Definition Unit.h:1838
void KnockbackFrom(Position const &origin, float speedXY, float speedZ, float angle=M_PI, Movement::SpellEffectExtraData const *spellEffectExtraData=nullptr)
Definition Unit.cpp:12491
bool HasAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint32 reqEffMask=0) const
Definition Unit.cpp:4804
uint32 HasUnitTypeMask(uint32 mask) const
Definition Unit.h:747
int32 MeleeDamageBonusDone(Unit *pVictim, int32 damage, WeaponAttackType attType, DamageEffectType damagetype, SpellInfo const *spellProto=nullptr, SpellEffectInfo const *spellEffectInfo=nullptr, Mechanics mechanic=MECHANIC_NONE, SpellSchoolMask damageSchoolMask=SPELL_SCHOOL_MASK_NORMAL, Spell *spell=nullptr, AuraEffect const *aurEff=nullptr)
Definition Unit.cpp:8021
SpellHistory * GetSpellHistory()
Definition Unit.h:1498
void SetCreatorGUID(ObjectGuid creator)
Definition Unit.h:1194
void RemoveMovementImpairingAuras(bool withRoot)
Definition Unit.cpp:4294
bool IsTotem() const
Definition Unit.h:753
ObjectGuid GetBattlePetCompanionGUID() const
Definition Unit.h:1201
void KillSelf(bool durabilityLoss=true, bool skipSettingDeathState=false)
Definition Unit.h:936
virtual void Talk(std::string_view text, ChatMsg msgType, Language language, float textRange, WorldObject const *target)
Definition Unit.cpp:14324
static void ProcSkillsAndAuras(Unit *actor, Unit *actionTarget, ProcFlagsInit const &typeMaskActor, ProcFlagsInit const &typeMaskActionTarget, ProcFlagsSpellType spellTypeMask, ProcFlagsSpellPhase spellPhaseMask, ProcFlagsHit hitMask, Spell *spell, DamageInfo *damageInfo, HealInfo *healInfo)
Definition Unit.cpp:5570
virtual bool IsEngaged() const
Definition Unit.h:1034
AuraMap & GetOwnedAuras()
Definition Unit.h:1285
void RemoveAurasDueToSpell(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, uint32 reqEffMask=0, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition Unit.cpp:3974
static void Kill(Unit *attacker, Unit *victim, bool durabilityLoss=true, bool skipSettingDeathState=false)
Definition Unit.cpp:11225
int32 SpellHealingBonusDone(Unit *victim, SpellInfo const *spellProto, int32 healamount, DamageEffectType damagetype, SpellEffectInfo const &spellEffectInfo, uint32 stack=1, Spell *spell=nullptr, AuraEffect const *aurEff=nullptr) const
Definition Unit.cpp:7328
ObjectGuid GetTarget() const
Definition Unit.h:1831
uint8 GetLevel() const
Definition Unit.h:757
uint8 GetRace() const
Definition Unit.h:761
void InterruptSpell(CurrentSpellTypes spellType, bool withDelayed=true, bool withInstant=true)
Definition Unit.cpp:3159
void RemoveUnitFlag(UnitFlags flags)
Definition Unit.h:847
void RemoveAurasDueToSpellBySteal(uint32 spellId, ObjectGuid casterGUID, WorldObject *stealer, int32 stolenCharges=1)
Definition Unit.cpp:4035
ObjectGuid GetPetGUID() const
Definition Unit.h:1197
bool isDead() const
Definition Unit.h:1187
Spell * GetCurrentSpell(CurrentSpellTypes spellType) const
Definition Unit.h:1466
constexpr void WorldRelocate(WorldLocation const &loc)
Definition Position.h:202
constexpr uint32 GetMapId() const
Definition Position.h:216
uint32 m_mapId
Definition Position.h:218
constexpr WorldLocation GetWorldLocation() const
Definition Position.h:211
void PlayDirectSound(uint32 soundId, Player const *target=nullptr, uint32 broadcastTextId=0) const
Definition Object.cpp:2938
virtual void SendMessageToSet(WorldPacket const *data, bool self) const
Definition Object.cpp:1094
Map * GetMap() const
Definition Object.h:411
Position GetRandomPoint(Position const &srcPos, float distance, float minDistance=0.0f) const
Definition Object.cpp:680
virtual uint8 GetLevelForTarget(WorldObject const *) const
Definition Object.h:385
bool IsWithinLOS(float x, float y, float z, LineOfSightChecks checks=LINEOFSIGHT_ALL_CHECKS, VMAP::ModelIgnoreFlags ignoreFlags=VMAP::ModelIgnoreFlags::Nothing) const
Definition Object.cpp:515
ObjectGuid GetPrivateObjectOwner() const
Definition Object.h:569
void GetClosePoint(float &x, float &y, float &z, float size, float distance2d=0, float relAngle=0) const
Definition Object.cpp:2749
SpellCastResult CastSpell(CastSpellTargetArg const &targets, uint32 spellId, CastSpellExtraArgs const &args={ })
Definition Object.cpp:2217
bool IsValidAttackTarget(WorldObject const *target, SpellInfo const *bySpell=nullptr) const
Definition Object.cpp:2324
Unit * GetOwner() const
Definition Object.cpp:1598
bool IsPrivateObject() const
Definition Object.h:568
void SetPrivateObjectOwner(ObjectGuid const &owner)
Definition Object.h:570
int32 ModSpellDuration(SpellInfo const *spellInfo, WorldObject const *target, int32 duration, bool positive, uint32 effectMask) const
Definition Object.cpp:1720
std::string const & GetName() const
Definition Object.h:342
Player * GetCharmerOrOwnerPlayerOrPlayerItself() const
Definition Object.cpp:1621
void SetName(std::string newname)
Definition Object.h:343
EventProcessor m_Events
Definition Object.h:561
float GetVisibilityRange() const
Definition Object.cpp:787
float GetDistance(WorldObject const *obj) const
Definition Object.cpp:432
uint32 GetAreaId() const
Definition Object.h:333
Position GetFirstCollisionPosition(float dist, float angle)
Definition Object.cpp:2762
bool IsFriendlyTo(WorldObject const *target) const
Definition Object.cpp:2186
virtual float GetCombatReach() const
Definition Object.h:302
Player * GetAffectingPlayer() const
Definition Object.cpp:1630
FactionTemplateEntry const * GetFactionTemplateEntry() const
Definition Object.cpp:2000
std::vector< SpellDispellData > DispellData
WorldPacket const * Write() override
WorldPacket const * Write() override
WorldPacket const * Write() override
WorldPacket const * Write() override
WorldPacket const * Write() override
std::vector< GlyphBinding > Glyphs
WorldPacket const * Write() override
void SendNotification(char const *format,...) ATTR_PRINTF(2
ObjectGuid GetAccountGUID() const
bool HasPermission(uint32 permissionId)
uint32 GetAccountId() const
CollectionMgr * GetCollectionMgr() const
void SendDiscoverNewTaxiNode(uint32 nodeid)
BattlePets::BattlePetMgr * GetBattlePetMgr() const
#define sWorld
Definition World.h:916
@ RATE_DROP_MONEY
Definition World.h:476
@ CONFIG_SKILL_MILLING
Definition World.h:124
@ CONFIG_SKILL_PROSPECTING
Definition World.h:123
@ CONFIG_NO_RESET_TALENT_COST
Definition World.h:151
@ CONFIG_CAST_UNSTUCK
Definition World.h:120
@ SPELL_VISUAL_UNCAGE_PET
TC_GAME_API void Trigger(uint32 gameEventId, WorldObject *source, WorldObject *target)
uint32 GetGameTimeMS()
Definition GameTime.cpp:57
float constexpr gravity
TC_GAME_API Player * FindPlayer(ObjectGuid const &)
TC_GAME_API void SkipCampaignForPlayer(uint32 campaignId, Player *player)
Definition QuestMgr.cpp:205
TC_GAME_API void SkipQuestLineForPlayer(uint32 questLineId, Player *player)
Definition QuestMgr.cpp:148
TraitConfigType GetConfigTypeForTree(int32 traitTreeId)
Definition TraitMgr.cpp:324
@ RBAC_PERM_LOG_GM_TRADE
Definition RBAC.h:64
uint64 GetAction() const
Definition Player.h:420
ActionButtonType GetType() const
Definition Player.h:419
EnumFlag< AreaFlags > GetFlags() const
AuraCreateInfo & SetCaster(Unit *caster)
Definition SpellAuras.h:115
AuraCreateInfo & SetCastItem(ObjectGuid const &guid, uint32 itemId, int32 itemLevel)
Definition SpellAuras.h:117
AuraCreateInfo & SetBaseAmount(SpellEffectValue const *bp)
Definition SpellAuras.h:116
TriggerCastFlags TriggerFlags
Optional< int32 > OriginalCastItemLevel
CastSpellExtraArgs & SetTriggeringSpell(Spell const *triggeringSpell)
Definition Spell.cpp:9707
CastSpellExtraArgs & SetOriginalCaster(ObjectGuid const &guid)
CastSpellExtraArgs & SetCustomArg(std::any customArg)
CastSpellExtraArgs & AddSpellMod(SpellValueMod mod, int32 val)
static void VisitGridObjects(WorldObject const *obj, T &visitor, float radius, bool dont_load=true)
Definition CellImpl.h:179
static void VisitWorldObjects(WorldObject const *obj, T &visitor, float radius, bool dont_load=true)
Definition CellImpl.h:191
void SaveStayPosition()
Definition Unit.cpp:13232
void SetIsCommandFollow(bool val)
Definition Unit.cpp:13222
void SetIsAtStay(bool val)
Definition Unit.cpp:13253
void SetIsFollowing(bool val)
Definition Unit.cpp:13263
void SetIsReturning(bool val)
Definition Unit.cpp:13273
bool HasCommandState(CommandStates state) const
Definition CharmInfo.h:98
void SetIsCommandAttack(bool val)
Definition Unit.cpp:13212
bool IsPetSpecialization() const
SkillType GetRequiredLootSkill() const
bool IsFriendlyTo(FactionTemplateEntry const *entry) const
uint32 GetNoDamageImmune() const
uint32 GetLockId() const
uint32 GetRequiredSkillRank() const
uint32 GetBaseItemLevel() const
uint32 GetId() const
uint32 GetMaxStackSize() const
bool HasFlag(ItemFlags flag) const
char const * GetDefaultLocaleName() const
uint32 GetLockID() const
Definition Loot.h:286
bool FillLoot(uint32 lootId, LootStore const &store, Player *lootOwner, bool personal, bool noEmptyError=false, uint16 lootMode=LOOT_MODE_DEFAULT, ItemContext context=ItemContext::NONE)
Definition Loot.cpp:859
constexpr float GetPositionX() const
Definition Position.h:87
constexpr float GetPositionY() const
Definition Position.h:88
float GetRelativeAngle(float x, float y) const
Definition Position.h:147
constexpr bool IsInDist2d(float x, float y, float dist) const
Definition Position.h:151
float GetExactDist(float x, float y, float z) const
Definition Position.h:129
float GetAbsoluteAngle(float x, float y) const
Definition Position.h:136
constexpr void GetPosition(float &x, float &y) const
Definition Position.h:92
constexpr void Relocate(float x, float y)
Definition Position.h:74
constexpr float GetOrientation() const
Definition Position.h:90
constexpr float GetPositionZ() const
Definition Position.h:89
bool IsHostile
Definition Player.h:441
bool IsInHostileArea
Definition Player.h:442
static QuaternionData fromEulerAnglesZYX(float Z, float Y, float X)
uint32 GetValueForTierIndex(uint32 tierIndex) const
Position _transportOffset
WorldLocation _position
ObjectGuid _transportGUID
std::array< uint8, MAX_ITEM_ENCHANTMENT_EFFECTS > Effect
uint32 originalDamage
Definition Unit.h:564
SpellEffectValue EffectBasePoints[MAX_SPELL_EFFECTS]
Definition Spell.h:242
ObjectGuid TargetGUID
Definition Spell.h:853
EnumFlag< SummonPropertiesFlags > GetFlags() const
WorldLocation Location
Definition Player.h:1226
TraitSystemVariationType GetVariationType() const
UpdateField< int32, 12, 13 > TraitSystemID
UpdateField< int32, 4, 6 > Type
UpdateField< int32, 12, 14 > VariationID
UpdateField< uint16, 0, 7 > ItemVisual
UpdateField< int32, 0, 3 > ItemID
UpdateField< uint16, 0, 6 > ItemAppearanceModID