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 "Battleground.h"
21#include "CellImpl.h"
22#include "Common.h"
23#include "Creature.h"
24#include "CreatureAI.h"
25#include "DatabaseEnv.h"
26#include "DynamicObject.h"
27#include "Formulas.h"
28#include "GameObject.h"
29#include "GameObjectAI.h"
30#include "GossipDef.h"
31#include "GridNotifiers.h"
32#include "InstanceScript.h"
33#include "Item.h"
34#include "Language.h"
35#include "Log.h"
36#include "LootMgr.h"
37#include "MiscPackets.h"
38#include "MotionMaster.h"
39#include "ObjectAccessor.h"
40#include "ObjectMgr.h"
41#include "Opcodes.h"
42#include "OutdoorPvPMgr.h"
43#include "PathGenerator.h"
44#include "Pet.h"
45#include "Player.h"
46#include "ReputationMgr.h"
47#include "ScriptMgr.h"
48#include "SkillExtraItems.h"
49#include "SharedDefines.h"
50#include "SocialMgr.h"
51#include "SpellAuraEffects.h"
52#include "SpellAuras.h"
53#include "SpellHistory.h"
54#include "SpellMgr.h"
55#include "TemporarySummon.h"
56#include "Totem.h"
57#include "UpdateMask.h"
58#include "Unit.h"
59#include "Util.h"
60#include "World.h"
61#include "WorldPacket.h"
62#include "WorldSession.h"
63
65{
67 &Spell::EffectInstaKill, // 1 SPELL_EFFECT_INSTAKILL
68 &Spell::EffectSchoolDMG, // 2 SPELL_EFFECT_SCHOOL_DAMAGE
69 &Spell::EffectDummy, // 3 SPELL_EFFECT_DUMMY
70 &Spell::EffectUnused, // 4 SPELL_EFFECT_PORTAL_TELEPORT unused
71 &Spell::EffectTeleportUnits, // 5 SPELL_EFFECT_TELEPORT_UNITS
72 &Spell::EffectApplyAura, // 6 SPELL_EFFECT_APPLY_AURA
73 &Spell::EffectEnvironmentalDMG, // 7 SPELL_EFFECT_ENVIRONMENTAL_DAMAGE
74 &Spell::EffectPowerDrain, // 8 SPELL_EFFECT_POWER_DRAIN
75 &Spell::EffectHealthLeech, // 9 SPELL_EFFECT_HEALTH_LEECH
76 &Spell::EffectHeal, // 10 SPELL_EFFECT_HEAL
77 &Spell::EffectBind, // 11 SPELL_EFFECT_BIND
78 &Spell::EffectNULL, // 12 SPELL_EFFECT_PORTAL
79 &Spell::EffectUnused, // 13 SPELL_EFFECT_RITUAL_BASE unused
80 &Spell::EffectUnused, // 14 SPELL_EFFECT_RITUAL_SPECIALIZE unused
81 &Spell::EffectUnused, // 15 SPELL_EFFECT_RITUAL_ACTIVATE_PORTAL unused
82 &Spell::EffectQuestComplete, // 16 SPELL_EFFECT_QUEST_COMPLETE
83 &Spell::EffectWeaponDmg, // 17 SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL
84 &Spell::EffectResurrect, // 18 SPELL_EFFECT_RESURRECT
85 &Spell::EffectAddExtraAttacks, // 19 SPELL_EFFECT_ADD_EXTRA_ATTACKS
86 &Spell::EffectUnused, // 20 SPELL_EFFECT_DODGE one spell: Dodge
87 &Spell::EffectUnused, // 21 SPELL_EFFECT_EVADE one spell: Evade (DND)
88 &Spell::EffectParry, // 22 SPELL_EFFECT_PARRY
89 &Spell::EffectBlock, // 23 SPELL_EFFECT_BLOCK one spell: Block
90 &Spell::EffectCreateItem, // 24 SPELL_EFFECT_CREATE_ITEM
91 &Spell::EffectUnused, // 25 SPELL_EFFECT_WEAPON
92 &Spell::EffectUnused, // 26 SPELL_EFFECT_DEFENSE one spell: Defense
93 &Spell::EffectPersistentAA, // 27 SPELL_EFFECT_PERSISTENT_AREA_AURA
94 &Spell::EffectSummonType, // 28 SPELL_EFFECT_SUMMON
95 &Spell::EffectLeap, // 29 SPELL_EFFECT_LEAP
96 &Spell::EffectEnergize, // 30 SPELL_EFFECT_ENERGIZE
97 &Spell::EffectWeaponDmg, // 31 SPELL_EFFECT_WEAPON_PERCENT_DAMAGE
98 &Spell::EffectTriggerMissileSpell, // 32 SPELL_EFFECT_TRIGGER_MISSILE
99 &Spell::EffectOpenLock, // 33 SPELL_EFFECT_OPEN_LOCK
100 &Spell::EffectSummonChangeItem, // 34 SPELL_EFFECT_SUMMON_CHANGE_ITEM
101 &Spell::EffectUnused, // 35 SPELL_EFFECT_APPLY_AREA_AURA_PARTY
102 &Spell::EffectLearnSpell, // 36 SPELL_EFFECT_LEARN_SPELL
103 &Spell::EffectUnused, // 37 SPELL_EFFECT_SPELL_DEFENSE one spell: SPELLDEFENSE (DND)
104 &Spell::EffectDispel, // 38 SPELL_EFFECT_DISPEL
105 &Spell::EffectUnused, // 39 SPELL_EFFECT_LANGUAGE
106 &Spell::EffectDualWield, // 40 SPELL_EFFECT_DUAL_WIELD
107 &Spell::EffectJump, // 41 SPELL_EFFECT_JUMP
108 &Spell::EffectJumpDest, // 42 SPELL_EFFECT_JUMP_DEST
109 &Spell::EffectTeleUnitsFaceCaster, // 43 SPELL_EFFECT_TELEPORT_UNITS_FACE_CASTER
110 &Spell::EffectLearnSkill, // 44 SPELL_EFFECT_SKILL_STEP
111 &Spell::EffectAddHonor, // 45 SPELL_EFFECT_ADD_HONOR honor/pvp related
112 &Spell::EffectUnused, // 46 SPELL_EFFECT_SPAWN clientside, unit appears as if it was just spawned
113 &Spell::EffectTradeSkill, // 47 SPELL_EFFECT_TRADE_SKILL
114 &Spell::EffectUnused, // 48 SPELL_EFFECT_STEALTH one spell: Base Stealth
115 &Spell::EffectUnused, // 49 SPELL_EFFECT_DETECT one spell: Detect
116 &Spell::EffectTransmitted, // 50 SPELL_EFFECT_TRANS_DOOR
117 &Spell::EffectUnused, // 51 SPELL_EFFECT_FORCE_CRITICAL_HIT unused
118 &Spell::EffectUnused, // 52 SPELL_EFFECT_GUARANTEE_HIT one spell: zzOLDCritical Shot
119 &Spell::EffectEnchantItemPerm, // 53 SPELL_EFFECT_ENCHANT_ITEM
120 &Spell::EffectEnchantItemTmp, // 54 SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY
121 &Spell::EffectTameCreature, // 55 SPELL_EFFECT_TAMECREATURE
122 &Spell::EffectSummonPet, // 56 SPELL_EFFECT_SUMMON_PET
123 &Spell::EffectLearnPetSpell, // 57 SPELL_EFFECT_LEARN_PET_SPELL
124 &Spell::EffectWeaponDmg, // 58 SPELL_EFFECT_WEAPON_DAMAGE
125 &Spell::EffectCreateRandomItem, // 59 SPELL_EFFECT_CREATE_RANDOM_ITEM create item base at spell specific loot
126 &Spell::EffectProficiency, // 60 SPELL_EFFECT_PROFICIENCY
127 &Spell::EffectSendEvent, // 61 SPELL_EFFECT_SEND_EVENT
128 &Spell::EffectPowerBurn, // 62 SPELL_EFFECT_POWER_BURN
129 &Spell::EffectThreat, // 63 SPELL_EFFECT_THREAT
130 &Spell::EffectTriggerSpell, // 64 SPELL_EFFECT_TRIGGER_SPELL
131 &Spell::EffectUnused, // 65 SPELL_EFFECT_APPLY_AREA_AURA_RAID
132 &Spell::EffectRechargeManaGem, // 66 SPELL_EFFECT_CREATE_MANA_GEM (possibly recharge it, misc - is item ID)
133 &Spell::EffectHealMaxHealth, // 67 SPELL_EFFECT_HEAL_MAX_HEALTH
134 &Spell::EffectInterruptCast, // 68 SPELL_EFFECT_INTERRUPT_CAST
135 &Spell::EffectDistract, // 69 SPELL_EFFECT_DISTRACT
136 &Spell::EffectPull, // 70 SPELL_EFFECT_PULL one spell: Distract Move
137 &Spell::EffectPickPocket, // 71 SPELL_EFFECT_PICKPOCKET
138 &Spell::EffectAddFarsight, // 72 SPELL_EFFECT_ADD_FARSIGHT
139 &Spell::EffectUntrainTalents, // 73 SPELL_EFFECT_UNTRAIN_TALENTS
140 &Spell::EffectApplyGlyph, // 74 SPELL_EFFECT_APPLY_GLYPH
141 &Spell::EffectHealMechanical, // 75 SPELL_EFFECT_HEAL_MECHANICAL one spell: Mechanical Patch Kit
142 &Spell::EffectSummonObjectWild, // 76 SPELL_EFFECT_SUMMON_OBJECT_WILD
143 &Spell::EffectScriptEffect, // 77 SPELL_EFFECT_SCRIPT_EFFECT
144 &Spell::EffectUnused, // 78 SPELL_EFFECT_ATTACK
145 &Spell::EffectSanctuary, // 79 SPELL_EFFECT_SANCTUARY
146 &Spell::EffectAddComboPoints, // 80 SPELL_EFFECT_ADD_COMBO_POINTS
147 &Spell::EffectUnused, // 81 SPELL_EFFECT_CREATE_HOUSE one spell: Create House (TEST)
148 &Spell::EffectNULL, // 82 SPELL_EFFECT_BIND_SIGHT
149 &Spell::EffectDuel, // 83 SPELL_EFFECT_DUEL
150 &Spell::EffectStuck, // 84 SPELL_EFFECT_STUCK
151 &Spell::EffectSummonPlayer, // 85 SPELL_EFFECT_SUMMON_PLAYER
152 &Spell::EffectActivateObject, // 86 SPELL_EFFECT_ACTIVATE_OBJECT
153 &Spell::EffectGameObjectDamage, // 87 SPELL_EFFECT_GAMEOBJECT_DAMAGE
154 &Spell::EffectGameObjectRepair, // 88 SPELL_EFFECT_GAMEOBJECT_REPAIR
155 &Spell::EffectGameObjectSetDestructionState, // 89 SPELL_EFFECT_GAMEOBJECT_SET_DESTRUCTION_STATE
156 &Spell::EffectKillCreditPersonal, // 90 SPELL_EFFECT_KILL_CREDIT Kill credit but only for single person
157 &Spell::EffectUnused, // 91 SPELL_EFFECT_THREAT_ALL one spell: zzOLDBrainwash
158 &Spell::EffectEnchantHeldItem, // 92 SPELL_EFFECT_ENCHANT_HELD_ITEM
159 &Spell::EffectForceDeselect, // 93 SPELL_EFFECT_FORCE_DESELECT
160 &Spell::EffectSelfResurrect, // 94 SPELL_EFFECT_SELF_RESURRECT
161 &Spell::EffectSkinning, // 95 SPELL_EFFECT_SKINNING
162 &Spell::EffectCharge, // 96 SPELL_EFFECT_CHARGE
163 &Spell::EffectCastButtons, // 97 SPELL_EFFECT_CAST_BUTTON (totem bar since 3.2.2a)
164 &Spell::EffectKnockBack, // 98 SPELL_EFFECT_KNOCK_BACK
165 &Spell::EffectDisEnchant, // 99 SPELL_EFFECT_DISENCHANT
166 &Spell::EffectInebriate, //100 SPELL_EFFECT_INEBRIATE
167 &Spell::EffectFeedPet, //101 SPELL_EFFECT_FEED_PET
168 &Spell::EffectDismissPet, //102 SPELL_EFFECT_DISMISS_PET
169 &Spell::EffectReputation, //103 SPELL_EFFECT_REPUTATION
170 &Spell::EffectSummonObject, //104 SPELL_EFFECT_SUMMON_OBJECT_SLOT1
171 &Spell::EffectSummonObject, //105 SPELL_EFFECT_SUMMON_OBJECT_SLOT2
172 &Spell::EffectSummonObject, //106 SPELL_EFFECT_SUMMON_OBJECT_SLOT3
173 &Spell::EffectSummonObject, //107 SPELL_EFFECT_SUMMON_OBJECT_SLOT4
174 &Spell::EffectDispelMechanic, //108 SPELL_EFFECT_DISPEL_MECHANIC
175 &Spell::EffectResurrectPet, //109 SPELL_EFFECT_RESURRECT_PET
176 &Spell::EffectDestroyAllTotems, //110 SPELL_EFFECT_DESTROY_ALL_TOTEMS
177 &Spell::EffectDurabilityDamage, //111 SPELL_EFFECT_DURABILITY_DAMAGE
178 &Spell::EffectUnused, //112 SPELL_EFFECT_112
179 &Spell::EffectResurrectNew, //113 SPELL_EFFECT_RESURRECT_NEW
180 &Spell::EffectTaunt, //114 SPELL_EFFECT_ATTACK_ME
181 &Spell::EffectDurabilityDamagePCT, //115 SPELL_EFFECT_DURABILITY_DAMAGE_PCT
182 &Spell::EffectSkinPlayerCorpse, //116 SPELL_EFFECT_SKIN_PLAYER_CORPSE one spell: Remove Insignia, bg usage, required special corpse flags...
183 &Spell::EffectSpiritHeal, //117 SPELL_EFFECT_SPIRIT_HEAL one spell: Spirit Heal
184 &Spell::EffectSkill, //118 SPELL_EFFECT_SKILL professions and more
185 &Spell::EffectUnused, //119 SPELL_EFFECT_APPLY_AREA_AURA_PET
186 &Spell::EffectUnused, //120 SPELL_EFFECT_TELEPORT_GRAVEYARD one spell: Graveyard Teleport Test
187 &Spell::EffectWeaponDmg, //121 SPELL_EFFECT_NORMALIZED_WEAPON_DMG
188 &Spell::EffectUnused, //122 SPELL_EFFECT_122 unused
189 &Spell::EffectSendTaxi, //123 SPELL_EFFECT_SEND_TAXI taxi/flight related (misc value is taxi path id)
190 &Spell::EffectPullTowards, //124 SPELL_EFFECT_PULL_TOWARDS
191 &Spell::EffectModifyThreatPercent, //125 SPELL_EFFECT_MODIFY_THREAT_PERCENT
192 &Spell::EffectStealBeneficialBuff, //126 SPELL_EFFECT_STEAL_BENEFICIAL_BUFF spell steal effect?
193 &Spell::EffectProspecting, //127 SPELL_EFFECT_PROSPECTING Prospecting spell
194 &Spell::EffectUnused, //128 SPELL_EFFECT_APPLY_AREA_AURA_FRIEND
195 &Spell::EffectUnused, //129 SPELL_EFFECT_APPLY_AREA_AURA_ENEMY
196 &Spell::EffectRedirectThreat, //130 SPELL_EFFECT_REDIRECT_THREAT
197 &Spell::EffectPlaySound, //131 SPELL_EFFECT_PLAY_SOUND sound id in misc value (SoundEntries.dbc)
198 &Spell::EffectPlayMusic, //132 SPELL_EFFECT_PLAY_MUSIC sound id in misc value (SoundEntries.dbc)
199 &Spell::EffectUnlearnSpecialization, //133 SPELL_EFFECT_UNLEARN_SPECIALIZATION unlearn profession specialization
200 &Spell::EffectKillCredit, //134 SPELL_EFFECT_KILL_CREDIT misc value is creature entry
201 &Spell::EffectNULL, //135 SPELL_EFFECT_CALL_PET
202 &Spell::EffectHealPct, //136 SPELL_EFFECT_HEAL_PCT
203 &Spell::EffectEnergizePct, //137 SPELL_EFFECT_ENERGIZE_PCT
204 &Spell::EffectLeapBack, //138 SPELL_EFFECT_LEAP_BACK Leap back
205 &Spell::EffectQuestClear, //139 SPELL_EFFECT_CLEAR_QUEST Reset quest status (miscValue - quest ID)
206 &Spell::EffectForceCast, //140 SPELL_EFFECT_FORCE_CAST
207 &Spell::EffectForceCast, //141 SPELL_EFFECT_FORCE_CAST_WITH_VALUE
208 &Spell::EffectTriggerSpell, //142 SPELL_EFFECT_TRIGGER_SPELL_WITH_VALUE
209 &Spell::EffectUnused, //143 SPELL_EFFECT_APPLY_AREA_AURA_OWNER
210 &Spell::EffectKnockBack, //144 SPELL_EFFECT_KNOCK_BACK_DEST
211 &Spell::EffectPullTowardsDest, //145 SPELL_EFFECT_PULL_TOWARDS_DEST Black Hole Effect
212 &Spell::EffectActivateRune, //146 SPELL_EFFECT_ACTIVATE_RUNE
213 &Spell::EffectQuestFail, //147 SPELL_EFFECT_QUEST_FAIL quest fail
214 &Spell::EffectTriggerMissileSpell, //148 SPELL_EFFECT_TRIGGER_MISSILE_SPELL_WITH_VALUE
215 &Spell::EffectChargeDest, //149 SPELL_EFFECT_CHARGE_DEST
216 &Spell::EffectQuestStart, //150 SPELL_EFFECT_QUEST_START
217 &Spell::EffectTriggerRitualOfSummoning, //151 SPELL_EFFECT_TRIGGER_SPELL_2
218 &Spell::EffectSummonRaFFriend, //152 SPELL_EFFECT_SUMMON_RAF_FRIEND summon Refer-a-Friend
219 &Spell::EffectCreateTamedPet, //153 SPELL_EFFECT_CREATE_TAMED_PET misc value is creature entry
220 &Spell::EffectDiscoverTaxi, //154 SPELL_EFFECT_DISCOVER_TAXI
221 &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.
222 &Spell::EffectEnchantItemPrismatic, //156 SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC
223 &Spell::EffectCreateItem2, //157 SPELL_EFFECT_CREATE_ITEM_2 create item or create item template and replace by some randon spell loot item
224 &Spell::EffectMilling, //158 SPELL_EFFECT_MILLING milling
225 &Spell::EffectRenamePet, //159 SPELL_EFFECT_ALLOW_RENAME_PET allow rename pet once again
226 &Spell::EffectForceCast, //160 SPELL_EFFECT_FORCE_CAST_2
227 &Spell::EffectSpecCount, //161 SPELL_EFFECT_TALENT_SPEC_COUNT second talent spec (learn/revert)
228 &Spell::EffectActivateSpec, //162 SPELL_EFFECT_TALENT_SPEC_SELECT activate primary/secondary spec
229 &Spell::EffectNULL, //163 unused
230 &Spell::EffectRemoveAura, //164 SPELL_EFFECT_REMOVE_AURA
231};
232
234{
235 TC_LOG_DEBUG("spells", "WORLD: Spell Effect DUMMY");
236}
237
239{
240 // NOT USED BY ANY SPELL OR USELESS OR IMPLEMENTED IN DIFFERENT WAY IN TRINITY
241}
242
244{
246 return;
247
248 if (!m_corpseTarget && !unitTarget)
249 return;
250
251 Player* player = nullptr;
252
253 if (m_corpseTarget)
255 else if (unitTarget)
256 player = unitTarget->ToPlayer();
257
258 if (!player || player->IsAlive() || !player->IsInWorld())
259 return;
260
261 if (player->IsResurrectRequested()) // already have one active request
262 return;
263
264 uint32 health = damage;
267 player->SetResurrectRequestData(m_caster, health, mana, 0);
268 SendResurrectRequest(player);
269}
270
272{
274 return;
275
276 if (!unitTarget || !unitTarget->IsAlive())
277 return;
278
281 return;
282
283 if (m_caster == unitTarget) // prevent interrupt message
284 finish();
285
287 data << m_caster->GetGUID();
288 data << unitTarget->GetGUID();
289 data << uint32(m_spellInfo->Id);
290 m_caster->SendMessageToSet(&data, true);
291
293}
294
296{
298 return;
299
300 if (!unitTarget || !unitTarget->IsAlive())
301 return;
302
303 // CalcAbsorbResist already in Player::EnvironmentalDamage
306 else
307 {
308 Unit* unitCaster = GetUnitCasterForEffectHandlers();
310 Unit::CalcAbsorbResist(damageInfo);
311
312 uint32 const absorb = damageInfo.GetAbsorb();
313 uint32 const resist = damageInfo.GetResist();
314 if (unitCaster)
315 unitCaster->SendSpellNonMeleeDamageLog(unitTarget, m_spellInfo->Id, damage, m_spellInfo->GetSchoolMask(), absorb, resist, false, 0, false);
316 }
317}
318
320{
322 return;
323
324 if (unitTarget && unitTarget->IsAlive())
325 {
326 bool apply_direct_bonus = true;
327 Unit* unitCaster = GetUnitCasterForEffectHandlers();
329 {
331 {
332 // Meteor like spells (divided damage to targets)
334 {
335 // divide to all targets
337 damage /= count;
338 }
339
340 break;
341 }
343 {
344 if (!unitCaster)
345 break;
346
347 // Shield Slam
348 if ((m_spellInfo->SpellFamilyFlags[1] & 0x200) && m_spellInfo->GetCategory() == 1209)
349 {
350 uint8 level = unitCaster->GetLevel();
351 uint32 block_value = unitCaster->GetShieldBlockValue(uint32(float(level) * 24.5f), uint32(float(level) * 34.5f));
352 damage += int32(unitCaster->ApplyEffectModifiers(m_spellInfo, effectInfo->EffectIndex, float(block_value)));
353 }
354 // Victory Rush
355 else if (m_spellInfo->SpellFamilyFlags[1] & 0x100)
357 // Shockwave
358 else if (m_spellInfo->Id == 46968)
359 {
361 if (pct > 0)
363 break;
364 }
365 break;
366 }
368 {
369 if (!unitCaster)
370 break;
371
372 // Incinerate Rank 1 & 2
373 if ((m_spellInfo->SpellFamilyFlags[1] & 0x000040) && m_spellInfo->SpellIconID == 2128)
374 {
375 // Incinerate does more dmg (dmg*0.25) if the target have Immolate debuff.
376 // Check aura state for speed but aura state set not only for Immolate spell
378 {
380 damage += damage / 4;
381 }
382 }
383 // Conflagrate - consumes Immolate or Shadowflame
385 {
386 AuraEffect const* aura = nullptr; // found req. aura for damage calculation
387
389 for (Unit::AuraEffectList::const_iterator i = mPeriodic.begin(); i != mPeriodic.end(); ++i)
390 {
391 // for caster applied auras only
392 if ((*i)->GetSpellInfo()->SpellFamilyName != SPELLFAMILY_WARLOCK ||
393 (*i)->GetCasterGUID() != unitCaster->GetGUID())
394 continue;
395
396 // Immolate
397 if ((*i)->GetSpellInfo()->SpellFamilyFlags[0] & 0x4)
398 {
399 aura = *i; // it selected always if exist
400 break;
401 }
402
403 // Shadowflame
404 if ((*i)->GetSpellInfo()->SpellFamilyFlags[2] & 0x00000002)
405 aura = *i; // remember but wait possible Immolate as primary priority
406 }
407
408 // found Immolate or Shadowflame
409 if (aura)
410 {
411 // Calculate damage of Immolate/Shadowflame tick
412 int32 pdamage = aura->GetAmount();
413
414 // And multiply by amount of ticks to get damage potential
415 pdamage *= aura->GetSpellInfo()->GetMaxTicks();
416
418 damage += CalculatePct(pdamage, pct_dir);
419
421 int32 const dotBasePoints = CalculatePct(pdamage, pct_dot);
422
425
426 // Glyph of Conflagrate
427 if (!unitCaster->HasAura(56235))
428 unitTarget->RemoveAurasDueToSpell(aura->GetId(), unitCaster->GetGUID());
429
430 break;
431 }
432 }
433 // Shadow Bite
434 else if (m_spellInfo->SpellFamilyFlags[1] & 0x400000)
435 {
436 if (unitCaster->GetTypeId() == TYPEID_UNIT && unitCaster->IsPet())
437 {
438 if (Player* owner = unitCaster->GetOwner()->ToPlayer())
439 {
440 if (AuraEffect* aurEff = owner->GetAuraEffect(SPELL_AURA_ADD_FLAT_MODIFIER, SPELLFAMILY_WARLOCK, 214, 0))
441 {
442 int32 bp0 = aurEff->GetId() == 54037 ? 4 : 8;
445 unitCaster->CastSpell(nullptr, 54425, args);
446 }
447 }
448 }
449 }
450 break;
451 }
453 {
454 if (!unitCaster)
455 break;
456
457 // Improved Mind Blast (Mind Blast in shadow form bonus)
458 if (unitCaster->GetShapeshiftForm() == FORM_SHADOW && (m_spellInfo->SpellFamilyFlags[0] & 0x00002000))
459 {
461 for (Unit::AuraEffectList::const_iterator i = ImprMindBlast.begin(); i != ImprMindBlast.end(); ++i)
462 {
463 if ((*i)->GetSpellInfo()->SpellFamilyName == SPELLFAMILY_PRIEST &&
464 ((*i)->GetSpellInfo()->SpellIconID == 95))
465 {
466 // Mind Trauma
467 int32 const chance = (*i)->GetSpellInfo()->GetEffect(EFFECT_1).CalcValue(unitCaster);
468 if (roll_chance_i(chance))
469 unitCaster->CastSpell(unitTarget, 48301, true);
470 break;
471 }
472 }
473 }
474 break;
475 }
477 {
478 if (!unitCaster)
479 break;
480
481 // Ferocious Bite
482 if (unitCaster->GetTypeId() == TYPEID_PLAYER && (m_spellInfo->SpellFamilyFlags[0] & 0x000800000) && m_spellInfo->SpellVisual[0] == 6587)
483 {
484 // converts each extra point of energy into ($f1+$AP/410) additional damage
485 float ap = unitCaster->GetTotalAttackPowerValue(BASE_ATTACK);
486 float multiple = ap / 410 + effectInfo->ChainAmplitude;
487 int32 energy = -(unitCaster->ModifyPower(POWER_ENERGY, -30));
488 damage += int32(energy * multiple);
489 damage += int32(CalculatePct(unitCaster->ToPlayer()->GetComboPoints() * ap, 7));
490 }
491 // Wrath
492 else if (m_spellInfo->SpellFamilyFlags[0] & 0x00000001)
493 {
494 // Improved Insect Swarm
495 if (AuraEffect const* aurEff = unitCaster->GetDummyAuraEffect(SPELLFAMILY_DRUID, 1771, 0))
497 AddPct(damage, aurEff->GetAmount());
498 }
499 break;
500 }
502 {
503 if (!unitCaster)
504 break;
505
506 // Envenom
507 if (m_spellInfo->SpellFamilyFlags[1] & 0x00000008)
508 {
509 if (Player* player = unitCaster->ToPlayer())
510 {
511 // consume from stack dozes not more that have combo-points
512 if (uint32 combo = player->GetComboPoints())
513 {
514 // Lookup for Deadly poison (only attacker applied)
515 if (AuraEffect const* aurEff = unitTarget->GetAuraEffect(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_ROGUE, 0x00010000, 0, 0, unitCaster->GetGUID()))
516 {
517 // count consumed deadly poison doses at target
518 bool needConsume = true;
519 uint32 spellId = aurEff->GetId();
520
521 uint32 doses = aurEff->GetBase()->GetStackAmount();
522 if (doses > combo)
523 doses = combo;
524
525 // Master Poisoner
526 Unit::AuraEffectList const& auraList = player->GetAuraEffectsByType(SPELL_AURA_MOD_AURA_DURATION_BY_DISPEL_NOT_STACK);
527 for (Unit::AuraEffectList::const_iterator iter = auraList.begin(); iter != auraList.end(); ++iter)
528 {
529 if ((*iter)->GetSpellInfo()->SpellFamilyName == SPELLFAMILY_ROGUE && (*iter)->GetSpellInfo()->SpellIconID == 1960)
530 {
531 uint32 chance = (*iter)->GetSpellInfo()->GetEffect(EFFECT_2).CalcValue(unitCaster);
532
533 if (chance && roll_chance_i(chance))
534 needConsume = false;
535
536 break;
537 }
538 }
539
540 if (needConsume)
541 for (uint32 i = 0; i < doses; ++i)
542 unitTarget->RemoveAuraFromStack(spellId, unitCaster->GetGUID());
543
544 damage *= doses;
545 damage += int32(player->GetTotalAttackPowerValue(BASE_ATTACK) * 0.09f * combo);
546 }
547
548 // Eviscerate and Envenom Bonus Damage (item set effect)
549 if (unitCaster->HasAura(37169))
550 damage += combo * 40;
551 }
552 }
553 }
554 // Eviscerate
555 else if (m_spellInfo->SpellFamilyFlags[0] & 0x00020000)
556 {
557 if (Player* player = unitCaster->ToPlayer())
558 {
559 if (uint32 combo = player->GetComboPoints())
560 {
561 float ap = unitCaster->GetTotalAttackPowerValue(BASE_ATTACK);
562 damage += std::lroundf(ap * combo * 0.07f);
563
564 // Eviscerate and Envenom Bonus Damage (item set effect)
565 if (unitCaster->HasAura(37169))
566 damage += combo*40;
567 }
568 }
569 }
570 break;
571 }
573 {
574 if (!unitCaster)
575 break;
576
577 //Gore
578 if (m_spellInfo->SpellIconID == 1578)
579 {
580 if (unitCaster->HasAura(57627)) // Charge 6 sec post-affect
581 damage *= 2;
582 }
583 // Steady Shot
584 else if (m_spellInfo->SpellFamilyFlags[1] & 0x1)
585 {
586 bool found = false;
587 // check dazed affect
589 for (Unit::AuraEffectList::const_iterator iter = decSpeedList.begin(); iter != decSpeedList.end(); ++iter)
590 {
591 if ((*iter)->GetSpellInfo()->SpellIconID == 15 && (*iter)->GetSpellInfo()->Dispel == 0)
592 {
593 found = true;
594 break;
595 }
596 }
597
599 if (found)
601
602 if (Player* caster = unitCaster->ToPlayer())
603 {
604 // Add Ammo and Weapon damage plus RAP * 0.1
605 float dmg_min = 0.f;
606 float dmg_max = 0.f;
607 for (uint8 i = 0; i < MAX_ITEM_PROTO_DAMAGES; ++i)
608 {
609 dmg_min += caster->GetWeaponDamageRange(RANGED_ATTACK, MINDAMAGE, i);
610 dmg_max += caster->GetWeaponDamageRange(RANGED_ATTACK, MAXDAMAGE, i);
611 }
612
613 if (dmg_max == 0.0f && dmg_min > dmg_max)
614 damage += int32(dmg_min);
615 else
616 damage += irand(int32(dmg_min), int32(dmg_max));
617 damage += int32(caster->GetAmmoDPS() * caster->GetAttackTime(RANGED_ATTACK) * 0.001f);
618 }
619 }
620 break;
621 }
623 {
624 if (!unitCaster)
625 break;
626
627 // Hammer of the Righteous
628 if (m_spellInfo->SpellFamilyFlags[1] & 0x00040000)
629 {
630 float minTotal = 0.f;
631 float maxTotal = 0.f;
632
633 float tmpMin, tmpMax;
634 for (uint8 i = 0; i < MAX_ITEM_PROTO_DAMAGES; ++i)
635 {
636 unitCaster->CalculateMinMaxDamage(BASE_ATTACK, false, false, tmpMin, tmpMax, i);
637 minTotal += tmpMin;
638 maxTotal += tmpMax;
639 }
640
641 float average = (minTotal + maxTotal) / 2;
642 // Add main hand dps * effect[2] amount
644 damage += count * int32(average * float(IN_MILLISECONDS)) / unitCaster->GetAttackTime(BASE_ATTACK);
645 break;
646 }
647 // Shield of Righteousness
648 if (m_spellInfo->SpellFamilyFlags[EFFECT_1] & 0x100000)
649 {
650 uint8 level = unitCaster->GetLevel();
651 uint32 block_value = unitCaster->GetShieldBlockValue(uint32(float(level) * 29.5f), uint32(float(level) * 39.5f));
653 break;
654 }
655 break;
656 }
658 {
659 if (!unitCaster)
660 break;
661
662 // Blood Boil - bonus for diseased targets
663 if (m_spellInfo->SpellFamilyFlags[0] & 0x00040000)
664 {
666 {
667 damage += m_damage / 2;
668 damage += int32(unitCaster->GetTotalAttackPowerValue(BASE_ATTACK) * 0.035f);
669 }
670 }
671 break;
672 }
673 }
674
675 if (unitCaster && damage > 0 && apply_direct_bonus)
676 {
679 }
680
681 m_damage += damage;
682 }
683}
684
686{
688 return;
689
691 return;
692
693 // pet auras
695 {
696 if (PetAura const* petSpell = sSpellMgr->GetPetAura(m_spellInfo->Id, effectInfo->EffectIndex))
697 {
698 m_caster->ToPlayer()->AddPetAura(petSpell);
699 return;
700 }
701 }
702}
703
705{
708 return;
709
710 uint32 triggered_spell_id = effectInfo->TriggerSpell;
711
715 {
716 Unit* unitCaster = GetUnitCasterForEffectHandlers();
717 // special cases
718 switch (triggered_spell_id)
719 {
720 // Mirror Image
721 case 58832:
722 {
723 if (!unitCaster)
724 break;
725
726 // Glyph of Mirror Image
727 if (unitCaster->HasAura(63093))
728 unitCaster->CastSpell(nullptr, 65047, true); // Mirror Image
729 break;
730 }
731 // Demonic Empowerment -- succubus
732 case 54437:
733 {
737
738 // Cast Lesser Invisibility
739 unitTarget->CastSpell(unitTarget, 7870, true);
740 return;
741 }
742 // Brittle Armor - (need add max stack of 24575 Brittle Armor)
743 case 29284:
744 {
745 // Brittle Armor
746 SpellInfo const* spell = sSpellMgr->GetSpellInfo(24575);
747 if (!spell)
748 return;
749
750 for (uint32 j = 0; j < spell->StackAmount; ++j)
751 m_caster->CastSpell(unitTarget, spell->Id, true);
752 return;
753 }
754 // Mercurial Shield - (need add max stack of 26464 Mercurial Shield)
755 case 29286:
756 {
757 // Mercurial Shield
758 SpellInfo const* spell = sSpellMgr->GetSpellInfo(26464);
759 if (!spell)
760 return;
761
762 for (uint32 j = 0; j < spell->StackAmount; ++j)
763 m_caster->CastSpell(unitTarget, spell->Id, true);
764 return;
765 }
766 }
767 }
768
769 if (triggered_spell_id == 0)
770 {
771 TC_LOG_WARN("spells.effect.nospell", "Spell::EffectTriggerSpell: Spell {} [EffectIndex: {}] does not have triggered spell.", m_spellInfo->Id, uint32(effectInfo->EffectIndex));
772 return;
773 }
774
775 // normal case
776 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(triggered_spell_id);
777 if (!spellInfo)
778 {
779 TC_LOG_ERROR("spells.effect.nospell", "Spell::EffectTriggerSpell spell {} tried to trigger unknown spell {}", m_spellInfo->Id, triggered_spell_id);
780 return;
781 }
782
783 SpellCastTargets targets;
785 {
787 return;
788 targets.SetUnitTarget(unitTarget);
789 }
790 else //if (effectHandleMode == SPELL_EFFECT_HANDLE_LAUNCH)
791 {
793 return;
794
796 targets.SetDst(m_targets);
797
798 if (Unit* target = m_targets.GetUnitTarget())
799 targets.SetUnitTarget(target);
800 else
801 {
802 if (Unit* unit = m_caster->ToUnit())
803 targets.SetUnitTarget(unit);
804 else if (GameObject* go = m_caster->ToGameObject())
805 targets.SetGOTarget(go);
806 }
807 }
808
810 // set basepoints for trigger with value effect
812 for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
814
815 // original caster guid only for GO cast
816 m_caster->CastSpell(std::move(targets), spellInfo->Id, args);
817}
818
820{
823 return;
824
825 uint32 triggered_spell_id = effectInfo->TriggerSpell;
826 if (triggered_spell_id == 0)
827 {
828 TC_LOG_WARN("spells.effect.nospell", "Spell::EffectTriggerMissileSpell: Spell {} [EffectIndex: {}] does not have triggered spell.", m_spellInfo->Id, uint32(effectInfo->EffectIndex));
829 return;
830 }
831
832 // normal case
833 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(triggered_spell_id);
834 if (!spellInfo)
835 {
836 TC_LOG_ERROR("spells.effect.nospell", "Spell::EffectTriggerMissileSpell spell {} tried to trigger unknown spell {}.", m_spellInfo->Id, triggered_spell_id);
837 return;
838 }
839
840 SpellCastTargets targets;
842 {
844 return;
845 targets.SetUnitTarget(unitTarget);
846 }
847 else //if (effectHandleMode == SPELL_EFFECT_HANDLE_HIT)
848 {
850 return;
851
853 targets.SetDst(m_targets);
854
855 if (Unit* unit = m_caster->ToUnit())
856 targets.SetUnitTarget(unit);
857 else if (GameObject* go = m_caster->ToGameObject())
858 targets.SetGOTarget(go);
859 }
860
862 // set basepoints for trigger with value effect
864 for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
866
867 // original caster guid only for GO cast
868 m_caster->CastSpell(std::move(targets), spellInfo->Id, args);
869}
870
872{
874 return;
875
876 if (!unitTarget)
877 return;
878
879 uint32 triggered_spell_id = effectInfo->TriggerSpell;
880 if (triggered_spell_id == 0)
881 {
882 TC_LOG_WARN("spells.effect.nospell", "Spell::EffectForceCast: Spell {} [EffectIndex: {}] does not have triggered spell.", m_spellInfo->Id, uint32(effectInfo->EffectIndex));
883 return;
884 }
885
886 // normal case
887 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(triggered_spell_id);
888
889 if (!spellInfo)
890 {
891 TC_LOG_ERROR("spells.effect.nospell", "Spell::EffectForceCast of spell {}: triggering unknown spell id {}.", m_spellInfo->Id, triggered_spell_id);
892 return;
893 }
894
896 {
897 switch (m_spellInfo->Id)
898 {
899 case 52588: // Skeletal Gryphon Escape
900 case 48598: // Ride Flamebringer Cue
902 break;
903 case 52463: // Hide In Mine Car
904 case 52349: // Overtake
905 {
908 unitTarget->CastSpell(unitTarget, spellInfo->Id, args);
909 return;
910 }
911 }
912 }
913
914 switch (spellInfo->Id)
915 {
916 case 72298: // Malleable Goo Summon
918 return;
919 }
920
923 for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
925
926 unitTarget->CastSpell(m_caster, spellInfo->Id, args);
927}
928
930{
932 return;
933
934 uint32 triggered_spell_id = effectInfo->TriggerSpell;
935 if (triggered_spell_id == 0)
936 {
937 TC_LOG_WARN("spells.effect.nospell", "Spell::EffectTriggerRitualOfSummoning: Spell {} [EffectIndex: {}] does not have triggered spell.", m_spellInfo->Id, uint32(effectInfo->EffectIndex));
938 return;
939 }
940
941 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(triggered_spell_id);
942
943 if (!spellInfo)
944 {
945 TC_LOG_ERROR("spells.effect.nospell", "EffectTriggerRitualOfSummoning of spell {}: triggering unknown spell id {}.", m_spellInfo->Id, triggered_spell_id);
946 return;
947 }
948
949 finish();
950
951 m_caster->CastSpell(nullptr, spellInfo->Id, false);
952}
953
954void Spell::CalculateJumpSpeeds(SpellEffectInfo const& spellEffectInfo, float dist, float& speedXY, float& speedZ)
955{
956 Unit* unitCaster = GetUnitCasterForEffectHandlers();
957 ASSERT(unitCaster);
958 float runSpeed = unitCaster->IsControlledByPlayer() ? playerBaseMoveSpeed[MOVE_RUN] : baseMoveSpeed[MOVE_RUN];
959 if (Creature* creature = unitCaster->ToCreature())
960 runSpeed *= creature->GetCreatureTemplate()->speed_run;
961
962 float multiplier = spellEffectInfo.Amplitude;
963 if (multiplier <= 0.0f)
964 multiplier = 1.0f;
965
966 speedXY = std::min(runSpeed * 3.0f * multiplier, std::max(28.0f, unitCaster->GetSpeed(MOVE_RUN) * 4.0f));
967
968 float duration = dist / speedXY;
969 float durationSqr = duration * duration;
970 float minHeight = spellEffectInfo.MiscValue ? spellEffectInfo.MiscValue / 10.0f : 0.5f; // Lower bound is blizzlike
971 float maxHeight = spellEffectInfo.MiscValueB ? spellEffectInfo.MiscValueB / 10.0f : 1000.0f; // Upper bound is unknown
972 float height;
973 if (durationSqr < minHeight * 8 / Movement::gravity)
974 height = minHeight;
975 else if (durationSqr > maxHeight * 8 / Movement::gravity)
976 height = maxHeight;
977 else
978 height = Movement::gravity * durationSqr / 8;
979
980 speedZ = std::sqrt(2 * Movement::gravity * height);
981}
982
984{
986 return;
987
988 Unit* unitCaster = GetUnitCasterForEffectHandlers();
989 if (!unitCaster)
990 return;
991
992 if (unitCaster->IsInFlight())
993 return;
994
995 if (!unitTarget)
996 return;
997
998 float speedXY, speedZ;
999 CalculateJumpSpeeds(*effectInfo, unitCaster->GetExactDist2d(unitTarget), speedXY, speedZ);
1000 unitCaster->GetMotionMaster()->MoveJump(*unitTarget, speedXY, speedZ, EVENT_JUMP, false);
1001}
1002
1004{
1006 return;
1007
1008 Unit* unitCaster = GetUnitCasterForEffectHandlers();
1009 if (!unitCaster)
1010 return;
1011
1012 if (unitCaster->IsInFlight())
1013 return;
1014
1015 if (!m_targets.HasDst())
1016 return;
1017
1018 float speedXY, speedZ;
1019 CalculateJumpSpeeds(*effectInfo, unitCaster->GetExactDist2d(destTarget), speedXY, speedZ);
1020 unitCaster->GetMotionMaster()->MoveJump(*destTarget, speedXY, speedZ, EVENT_JUMP, !m_targets.GetObjectTargetGUID().IsEmpty());
1021}
1022
1024{
1026 return;
1027
1028 if (!unitTarget || unitTarget->IsInFlight())
1029 return;
1030
1031 // If not exist data for dest location - return
1032 if (!m_targets.HasDst())
1033 {
1034 TC_LOG_ERROR("spells", "Spell::EffectTeleportUnits - does not have a destination for spellId {}.", m_spellInfo->Id);
1035 return;
1036 }
1037
1038 // Init dest coordinates
1039 WorldLocation targetDest(*destTarget);
1040 if (targetDest.GetMapId() == MAPID_INVALID)
1041 targetDest.m_mapId = unitTarget->GetMapId();
1042
1043 if (!targetDest.GetOrientation() && m_targets.GetUnitTarget())
1045
1046 if (targetDest.GetMapId() == unitTarget->GetMapId())
1048 else if (unitTarget->GetTypeId() == TYPEID_PLAYER)
1050 else
1051 {
1052 TC_LOG_ERROR("spells", "Spell::EffectTeleportUnits - spellId {} attempted to teleport creature to a different map.", m_spellInfo->Id);
1053 return;
1054 }
1055}
1056
1058{
1060 return;
1061
1062 if (!_spellAura || !unitTarget)
1063 return;
1064
1065 // register target/effect on aura
1067 if (!aurApp)
1069 else
1070 aurApp->UpdateApplyEffectMask(aurApp->GetEffectsToApply() | 1 << effectInfo->EffectIndex, false);
1071}
1072
1074{
1076 return;
1077
1079 return;
1080
1081 Player* player = unitTarget->ToPlayer();
1082 uint32 spellToUnlearn = effectInfo->TriggerSpell;
1083
1084 player->RemoveSpell(spellToUnlearn);
1085
1086 TC_LOG_DEBUG("spells", "Spell: Player {} has unlearned spell {} from Npc {}", player->GetGUID().ToString(), spellToUnlearn, m_caster->GetGUID().ToString());
1087}
1088
1090{
1092 return;
1093
1095 return;
1096
1097 Powers powerType = Powers(effectInfo->MiscValue);
1098 if (!unitTarget || !unitTarget->IsAlive() || (unitTarget->GetPowerType() != powerType && powerType != POWER_HAPPINESS) || damage < 0)
1099 return;
1100
1101 Unit* unitCaster = GetUnitCasterForEffectHandlers();
1102 // add spell damage bonus
1103 if (unitCaster)
1104 {
1107 }
1108
1109 // resilience reduce mana draining effect at spell crit damage reduction (added in 2.4)
1110 int32 power = damage;
1111 if (powerType == POWER_MANA)
1112 power -= unitTarget->GetSpellCritDamageReduction(power);
1113
1114 int32 newDamage = -(unitTarget->ModifyPower(powerType, -int32(power)));
1115
1116 // Don't restore from self drain
1117 float gainMultiplier = 0.f;
1118 if (unitCaster && unitCaster != unitTarget)
1119 {
1120 gainMultiplier = effectInfo->CalcValueMultiplier(unitCaster, this);
1121 int32 const gain = int32(newDamage * gainMultiplier);
1122
1123 unitCaster->EnergizeBySpell(unitCaster, m_spellInfo, gain, powerType);
1124 }
1125 ExecuteLogEffectTakeTargetPower(effectInfo->EffectIndex, unitTarget, powerType, newDamage, gainMultiplier);
1126}
1127
1129{
1130 // we do not handle a flag dropping or clicking on flag in battleground by sendevent system
1133 return;
1134
1135 WorldObject* target = nullptr;
1136
1137 // call events for object target if present
1139 {
1140 if (unitTarget)
1141 target = unitTarget;
1142 else if (gameObjTarget)
1143 target = gameObjTarget;
1144 else if (m_corpseTarget)
1145 target = m_corpseTarget;
1146 }
1147 else // if (effectHandleMode == SPELL_EFFECT_HANDLE_HIT)
1148 {
1149 // let's prevent executing effect handler twice in case when spell effect is capable of targeting an object
1150 // this check was requested by scripters, but it has some downsides:
1151 // now it's impossible to script (using sEventScripts) a cast which misses all targets
1152 // or to have an ability to script the moment spell hits dest (in a case when there are object targets present)
1154 return;
1155 // some spells have no target entries in dbc and they use focus target
1156 if (focusObject)
1157 target = focusObject;
1159 }
1160
1161 TC_LOG_DEBUG("spells", "Spell ScriptStart {} for spellid {} in EffectSendEvent ", effectInfo->MiscValue, m_spellInfo->Id);
1162
1163 if (ZoneScript* zoneScript = m_caster->GetZoneScript())
1164 zoneScript->ProcessEvent(target, effectInfo->MiscValue);
1165 else if (InstanceScript* instanceScript = m_caster->GetInstanceScript()) // needed in case Player is the caster
1166 instanceScript->ProcessEvent(target, effectInfo->MiscValue);
1167
1169}
1170
1172{
1174 return;
1175
1177 return;
1178
1179 Powers powerType = Powers(effectInfo->MiscValue);
1180 if (!unitTarget || !unitTarget->IsAlive() || unitTarget->GetPowerType() != powerType || damage < 0)
1181 return;
1182
1183 Unit* unitCaster = GetUnitCasterForEffectHandlers();
1184
1185 // burn x% of target's mana, up to maximum of 2x% of caster's mana (Mana Burn)
1187 if (unitCaster && m_spellInfo->Id == 8129)
1188 {
1189 int32 maxDamage = int32(CalculatePct(unitCaster->GetMaxPower(powerType), damage * 2));
1191 damage = std::min(damage, maxDamage);
1192 }
1193
1194 int32 power = damage;
1195 // resilience reduce mana draining effect at spell crit damage reduction (added in 2.4)
1196 if (powerType == POWER_MANA)
1197 power -= unitTarget->GetSpellCritDamageReduction(power);
1198
1199 int32 newDamage = -(unitTarget->ModifyPower(powerType, -power));
1200
1201 // NO - Not a typo - EffectPowerBurn uses effect value multiplier - not effect damage multiplier
1202 float dmgMultiplier = effectInfo->CalcValueMultiplier(unitCaster, this);
1203
1204 // add log data before multiplication (need power amount, not damage)
1206
1207 newDamage = int32(newDamage * dmgMultiplier);
1208
1209 m_damage += newDamage;
1210}
1211
1213{
1215 return;
1216
1217 if (!unitTarget || !unitTarget->IsAlive() || damage < 0)
1218 return;
1219
1220 Unit* unitCaster = GetUnitCasterForEffectHandlers();
1221
1222 // Skip if m_originalCaster not available
1223 if (!unitCaster)
1224 return;
1225
1226 int32 addhealth = damage;
1227
1228 // Vessel of the Naaru (Vial of the Sunwell trinket)
1230 if (m_spellInfo->Id == 45064)
1231 {
1232 // Amount of heal - depends from stacked Holy Energy
1233 int32 damageAmount = 0;
1234 if (AuraEffect const* aurEff = unitCaster->GetAuraEffect(45062, 0))
1235 {
1236 damageAmount += aurEff->GetAmount();
1237 unitCaster->RemoveAurasDueToSpell(45062);
1238 }
1239
1240 addhealth += damageAmount;
1241 }
1242 // Swiftmend - consumes Regrowth or Rejuvenation
1244 {
1246 // find most short by duration
1247 AuraEffect* targetAura = nullptr;
1248 for (Unit::AuraEffectList::const_iterator i = RejorRegr.begin(); i != RejorRegr.end(); ++i)
1249 {
1250 if ((*i)->GetSpellInfo()->SpellFamilyName == SPELLFAMILY_DRUID
1251 && (*i)->GetSpellInfo()->SpellFamilyFlags[0] & 0x50)
1252 {
1253 if (!targetAura || (*i)->GetBase()->GetDuration() < targetAura->GetBase()->GetDuration())
1254 targetAura = *i;
1255 }
1256 }
1257
1258 if (!targetAura)
1259 {
1260 TC_LOG_ERROR("spells", "Target ({}) has the aurastate AURA_STATE_SWIFTMEND, but no matching aura.", unitTarget->GetGUID().ToString());
1261 return;
1262 }
1263
1264 int32 tickheal = targetAura->GetAmount();
1265 unitTarget->SpellHealingBonusTaken(unitCaster, targetAura->GetSpellInfo(), tickheal, DOT);
1266
1267 int32 tickcount = 0;
1268 // Rejuvenation
1269 if (targetAura->GetSpellInfo()->SpellFamilyFlags[0] & 0x10)
1270 tickcount = 4;
1271 // Regrowth
1272 else // if (targetAura->GetSpellInfo()->SpellFamilyFlags[0] & 0x40)
1273 tickcount = 6;
1274
1275 addhealth += tickheal * tickcount;
1276
1277 // Glyph of Swiftmend
1278 if (!unitCaster->HasAura(54824))
1279 unitTarget->RemoveAura(targetAura->GetId(), targetAura->GetCasterGUID());
1280 }
1281 // Death Pact - return pct of max health to caster
1283 addhealth = unitCaster->SpellHealingBonusDone(unitTarget, m_spellInfo, int32(unitCaster->CountPctFromMaxHealth(damage)), HEAL, *effectInfo, { });
1284 else
1285 addhealth = unitCaster->SpellHealingBonusDone(unitTarget, m_spellInfo, addhealth, HEAL, *effectInfo, { });
1286
1287 addhealth = unitTarget->SpellHealingBonusTaken(unitCaster, m_spellInfo, addhealth, HEAL);
1288
1289 // Remove Grievious bite if fully healed
1290 if (unitTarget->HasAura(48920) && (unitTarget->GetHealth() + addhealth >= unitTarget->GetMaxHealth()))
1291 unitTarget->RemoveAura(48920);
1292
1293 m_healing += addhealth;
1294}
1295
1297{
1299 return;
1300
1301 if (!unitTarget || !unitTarget->IsAlive() || damage < 0)
1302 return;
1303
1305 if (Unit* unitCaster = GetUnitCasterForEffectHandlers())
1306 {
1307 heal = unitCaster->SpellHealingBonusDone(unitTarget, m_spellInfo, heal, HEAL, *effectInfo, { });
1308 heal = unitTarget->SpellHealingBonusTaken(unitCaster, m_spellInfo, heal, HEAL);
1309 }
1310
1311 m_healing += heal;
1312}
1313
1315{
1317 return;
1318
1319 if (!unitTarget || !unitTarget->IsAlive() || damage < 0)
1320 return;
1321
1322 uint32 heal = damage;
1323 if (Unit* unitCaster = GetUnitCasterForEffectHandlers())
1324 {
1325 heal = unitCaster->SpellHealingBonusDone(unitTarget, m_spellInfo, heal, HEAL, *effectInfo, { });
1326 heal = unitTarget->SpellHealingBonusTaken(unitCaster, m_spellInfo, heal, HEAL);
1327 }
1328
1329 m_healing += heal;
1330}
1331
1333{
1335 return;
1336
1337 if (!unitTarget || !unitTarget->IsAlive() || damage < 0)
1338 return;
1339
1340 Unit* unitCaster = GetUnitCasterForEffectHandlers();
1341 if (unitCaster)
1342 {
1345 }
1346
1347 TC_LOG_DEBUG("spells", "HealthLeech :{}", damage);
1348
1349 float healMultiplier = effectInfo->CalcValueMultiplier(unitCaster, this);
1350
1351 m_damage += damage;
1352
1354 Unit::CalcAbsorbResist(damageInfo);
1355 uint32 const absorb = damageInfo.GetAbsorb();
1356 damage -= absorb;
1357
1358 // get max possible damage, don't count overkill for heal
1359 uint32 healthGain = uint32(-unitTarget->GetHealthGain(-damage) * healMultiplier);
1360
1361 if (unitCaster && unitCaster->IsAlive())
1362 {
1363 healthGain = unitCaster->SpellHealingBonusDone(unitCaster, m_spellInfo, healthGain, HEAL, *effectInfo, { });
1364 healthGain = unitCaster->SpellHealingBonusTaken(unitCaster, m_spellInfo, healthGain, HEAL);
1365
1366 HealInfo healInfo(unitCaster, unitCaster, healthGain, m_spellInfo, m_spellSchoolMask);
1367 unitCaster->HealBySpell(healInfo);
1368 }
1369}
1370
1372{
1374 return;
1375
1376 Player* player = unitTarget->ToPlayer();
1377
1378 uint32 newitemid = itemId;
1379 ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(newitemid);
1380 if (!pProto)
1381 {
1382 player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, nullptr, nullptr);
1383 return;
1384 }
1385
1386 // bg reward have some special in code work
1387 uint32 bgType = 0;
1388 switch (m_spellInfo->Id)
1389 {
1392 bgType = BATTLEGROUND_AV;
1393 break;
1396 bgType = BATTLEGROUND_WS;
1397 break;
1400 bgType = BATTLEGROUND_AB;
1401 break;
1402 default:
1403 break;
1404 }
1405
1406 uint32 num_to_add = damage;
1407
1408 if (num_to_add < 1)
1409 num_to_add = 1;
1410 if (num_to_add > pProto->GetMaxStackSize())
1411 num_to_add = pProto->GetMaxStackSize();
1412
1413 /* == gem perfection handling == */
1414
1415 // the chance of getting a perfect result
1416 float perfectCreateChance = 0.0f;
1417 // the resulting perfect item if successful
1418 uint32 perfectItemType = itemId;
1419 // get perfection capability and chance
1420 if (CanCreatePerfectItem(player, m_spellInfo->Id, perfectCreateChance, perfectItemType))
1421 if (roll_chance_f(perfectCreateChance)) // if the roll succeeds...
1422 newitemid = perfectItemType; // the perfect item replaces the regular one
1423
1424 /* == gem perfection handling over == */
1425
1426 /* == profession specialization handling == */
1427
1428 // init items_count to 1, since 1 item will be created regardless of specialization
1429 int items_count=1;
1430 // the chance to create additional items
1431 float additionalCreateChance=0.0f;
1432 // the maximum number of created additional items
1433 uint8 additionalMaxNum=0;
1434 // get the chance and maximum number for creating extra items
1435 if (CanCreateExtraItems(player, m_spellInfo->Id, additionalCreateChance, additionalMaxNum))
1436 // roll with this chance till we roll not to create or we create the max num
1437 while (roll_chance_f(additionalCreateChance) && items_count <= additionalMaxNum)
1438 ++items_count;
1439
1440 // really will be created more items
1441 num_to_add *= items_count;
1442
1443 /* == profession specialization handling over == */
1444
1445 // can the player store the new item?
1446 ItemPosCountVec dest;
1447 uint32 no_space = 0;
1448 InventoryResult msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, newitemid, num_to_add, &no_space);
1449 if (msg != EQUIP_ERR_OK)
1450 {
1451 // convert to possible store amount
1452 if (msg == EQUIP_ERR_INV_FULL || msg == EQUIP_ERR_ITEM_MAX_COUNT)
1453 num_to_add -= no_space;
1454 else
1455 {
1456 // if not created by another reason from full inventory or unique items amount limitation
1457 player->SendEquipError(msg, nullptr, nullptr, newitemid);
1458 return;
1459 }
1460 }
1461
1462 if (num_to_add)
1463 {
1464 // create the new item and store it
1465 Item* pItem = player->StoreNewItem(dest, newitemid, true, GenerateItemRandomPropertyId(newitemid));
1466
1467 // was it successful? return error if not
1468 if (!pItem)
1469 {
1470 player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, nullptr, nullptr);
1471 return;
1472 }
1473
1474 // set the "Crafted by ..." property of the item
1475 if (pItem->GetTemplate()->HasSignature())
1476 pItem->SetGuidValue(ITEM_FIELD_CREATOR, player->GetGUID());
1477
1478 // send info to the client
1479 player->SendNewItem(pItem, num_to_add, true, bgType == 0);
1480
1481 // we succeeded in creating at least one item, so a levelup is possible
1482 if (bgType == 0)
1484 }
1485
1486/*
1487 // for battleground marks send by mail if not add all expected
1488 if (no_space > 0 && bgType)
1489 {
1490 if (Battleground* bg = sBattlegroundMgr->GetBattlegroundTemplate(BattlegroundTypeId(bgType)))
1491 bg->SendRewardMarkByMail(player, newitemid, no_space);
1492 }
1493*/
1494}
1495
1504
1506{
1508 return;
1509
1511 return;
1512
1513 Player* player = unitTarget->ToPlayer();
1514
1515 // Pick a random item from spell_loot_template
1517 {
1518 player->AutoStoreLoot(m_spellInfo->Id, LootTemplates_Spell, false, true);
1520 }
1521 else // If there's no random loot entries for this spell, pick the item associated with this spell
1522 {
1523 uint32 item_id = effectInfo->ItemType;
1524
1525 if (item_id)
1526 DoCreateItem(item_id);
1527 }
1528
1530}
1531
1533{
1535 return;
1536
1538 return;
1539 Player* player = unitTarget->ToPlayer();
1540
1541 // create some random items
1544}
1545
1547{
1549 return;
1550
1551 Unit* unitCaster = GetUnitCasterForEffectHandlers();
1552 if (!unitCaster)
1553 return;
1554
1555 // Caster not in world, might be spell triggered from aura removal
1556 if (!unitCaster->IsInWorld())
1557 return;
1558
1559 // only handle at last effect
1560 for (size_t i = effectInfo->EffectIndex + 1; i < m_spellInfo->GetEffects().size(); ++i)
1562 return;
1563
1565
1566 float radius = 0.0f;
1567 for (size_t i = 0; i <= effectInfo->EffectIndex; ++i)
1568 {
1569 SpellEffectInfo const& spellEffectInfo = m_spellInfo->GetEffect(SpellEffIndex(i));
1570 if (spellEffectInfo.IsEffect(SPELL_EFFECT_PERSISTENT_AREA_AURA))
1571 radius = std::max(radius, spellEffectInfo.CalcRadius(unitCaster));
1572 }
1573
1574 DynamicObject* dynObj = new DynamicObject(false);
1576 {
1577 delete dynObj;
1578 return;
1579 }
1580
1581 AuraCreateInfo createInfo(m_spellInfo, MAX_EFFECT_MASK, dynObj);
1582 createInfo
1583 .SetCaster(unitCaster)
1585
1586 if (Aura* aura = Aura::TryCreate(createInfo))
1587 {
1588 _dynObjAura = aura->ToDynObjAura();
1590 }
1591 else
1592 return;
1593
1595 for (size_t i = 0; i < m_spellInfo->GetEffects().size(); ++i)
1598}
1599
1601{
1603 return;
1604
1605 Unit* unitCaster = GetUnitCasterForEffectHandlers();
1606 if (!unitCaster || !unitTarget)
1607 return;
1608
1609 if (!unitTarget->IsAlive())
1610 return;
1611
1613 return;
1614
1618 return;
1619
1620 if (unitTarget->GetMaxPower(power) == 0)
1621 return;
1622
1623 // Some level depends spells
1625 int32 level_multiplier = 0;
1626 int32 level_diff = 0;
1627 switch (m_spellInfo->Id)
1628 {
1629 case 9512: // Restore Energy
1630 level_diff = unitCaster->GetLevel() - 40;
1631 level_multiplier = 2;
1632 break;
1633 case 24571: // Blood Fury
1634 level_diff = unitCaster->GetLevel() - 60;
1635 level_multiplier = 10;
1636 break;
1637 case 24532: // Burst of Energy
1638 level_diff = unitCaster->GetLevel() - 60;
1639 level_multiplier = 4;
1640 break;
1641 case 31930: // Judgements of the Wise
1642 case 63375: // Improved Stormstrike
1643 case 68082: // Glyph of Seal of Command
1645 break;
1646 case 48542: // Revitalize
1648 break;
1649 case 67490: // Runic Mana Injector (mana gain increased by 25% for engineers - 3.2.0 patch change)
1650 {
1651 if (Player* player = unitCaster->ToPlayer())
1652 if (player->HasSkill(SKILL_ENGINEERING))
1653 AddPct(damage, 25);
1654 break;
1655 }
1656 case 71132: // Glyph of Shadow Word: Pain
1657 damage = int32(CalculatePct(unitTarget->GetCreateMana(), 1)); // set 1 as value, missing in dbc
1658 break;
1659 default:
1660 break;
1661 }
1662
1663 if (level_diff > 0)
1664 damage -= level_multiplier * level_diff;
1665
1666 if (damage < 0)
1667 return;
1668
1669 unitCaster->EnergizeBySpell(unitTarget, m_spellInfo, damage, power);
1670}
1671
1673{
1675 return;
1676
1677 Unit* unitCaster = GetUnitCasterForEffectHandlers();
1678 if (!unitCaster || !unitTarget)
1679 return;
1680
1681 if (!unitTarget->IsAlive())
1682 return;
1683
1685 return;
1686
1688
1690 return;
1691
1692 uint32 maxPower = unitTarget->GetMaxPower(power);
1693 if (!maxPower)
1694 return;
1695
1696 uint32 const gain = CalculatePct(maxPower, damage);
1697 unitCaster->EnergizeBySpell(unitTarget, m_spellInfo, gain, power);
1698}
1699
1701{
1702 Player* player = m_caster->ToPlayer();
1703 if (!player)
1704 return;
1705
1706 if (gameObjTarget)
1707 {
1708 // Players shouldn't be able to loot gameobjects that are currently despawned
1709 if (!gameObjTarget->isSpawned() && !player->IsGameMaster())
1710 {
1711 TC_LOG_ERROR("entities.player.cheat", "Possible hacking attempt: Player {} {} tried to loot a gameobject {} which is on respawn timer without being in GM mode!",
1712 player->GetName(), player->GetGUID().ToString(), gameObjTarget->GetGUID().ToString());
1713 return;
1714 }
1715 // special case, already has GossipHello inside so return and avoid calling twice
1717 {
1718 gameObjTarget->Use(player);
1719 return;
1720 }
1721
1722 player->PlayerTalkClass->ClearMenus();
1723 if (gameObjTarget->AI()->OnGossipHello(player))
1724 return;
1725
1726 switch (gameObjTarget->GetGoType())
1727 {
1730 gameObjTarget->UseDoorOrButton(0, false, player);
1731 return;
1732
1736 return;
1737
1739 // triggering linked GO
1741 gameObjTarget->TriggeringLinkedGameObject(trapEntry, player);
1742 return;
1743
1747 {
1748 TC_LOG_DEBUG("spells", "Chest ScriptStart id {} for GO {}", gameObjTarget->GetGOInfo()->chest.eventId, gameObjTarget->GetSpawnId());
1750 }
1751
1752 // triggering linked GO
1753 if (uint32 trapEntry = gameObjTarget->GetGOInfo()->chest.linkedTrapId)
1754 gameObjTarget->TriggeringLinkedGameObject(trapEntry, player);
1755
1756 // Don't return, let loots been taken
1757 break;
1758 default:
1759 break;
1760 }
1761 }
1762
1763 // Send loot
1764 player->SendLoot(guid, loottype);
1765}
1766
1768{
1770 return;
1771
1773 {
1774 TC_LOG_DEBUG("spells", "WORLD: Open Lock - No Player Caster!");
1775 return;
1776 }
1777
1778 Player* player = m_caster->ToPlayer();
1779
1780 uint32 lockId = 0;
1781 ObjectGuid guid;
1782
1783 // Get lockId
1784 if (gameObjTarget)
1785 {
1786 GameObjectTemplate const* goInfo = gameObjTarget->GetGOInfo();
1787
1788 if (goInfo->CannotBeUsedUnderImmunity() && player->HasUnitFlag(UNIT_FLAG_IMMUNE))
1789 return;
1790
1791 // Arathi Basin banner opening. /// @todo Verify correctness of this check
1792 if ((goInfo->type == GAMEOBJECT_TYPE_BUTTON && goInfo->button.noDamageImmune) ||
1793 (goInfo->type == GAMEOBJECT_TYPE_GOOBER && goInfo->goober.losOK))
1794 {
1795 //CanUseBattlegroundObject() already called in CheckCast()
1796 // in battleground check
1797 if (Battleground* bg = player->GetBattleground())
1798 {
1799 bg->EventPlayerClickedOnFlag(player, gameObjTarget);
1800 return;
1801 }
1802 }
1803 else if (goInfo->type == GAMEOBJECT_TYPE_FLAGSTAND)
1804 {
1805 //CanUseBattlegroundObject() already called in CheckCast()
1806 // in battleground check
1807 if (Battleground* bg = player->GetBattleground())
1808 {
1809 if (bg->GetTypeID(true) == BATTLEGROUND_EY)
1810 bg->EventPlayerClickedOnFlag(player, gameObjTarget);
1811 return;
1812 }
1813 }
1815 {
1817 return;
1818 }
1820 // handle outdoor pvp object opening, return true if go was registered for handling
1821 // these objects must have been spawned by outdoorpvp!
1822 else if (gameObjTarget->GetGOInfo()->type == GAMEOBJECT_TYPE_GOOBER && sOutdoorPvPMgr->HandleOpenGo(player, gameObjTarget))
1823 return;
1824 lockId = goInfo->GetLockId();
1825 guid = gameObjTarget->GetGUID();
1826 }
1827 else if (itemTarget)
1828 {
1829 lockId = itemTarget->GetTemplate()->LockID;
1830 guid = itemTarget->GetGUID();
1831 }
1832 else
1833 {
1834 TC_LOG_DEBUG("spells", "WORLD: Open Lock - No GameObject/Item Target!");
1835 return;
1836 }
1837
1838 SkillType skillId = SKILL_NONE;
1839 int32 reqSkillValue = 0;
1840 int32 skillValue;
1841
1842 SpellCastResult res = CanOpenLock(*effectInfo, lockId, skillId, reqSkillValue, skillValue);
1843 if (res != SPELL_CAST_OK)
1844 {
1845 SendCastResult(res);
1846 return;
1847 }
1848
1849 if (gameObjTarget)
1850 SendLoot(guid, LOOT_SKINNING);
1851 else if (itemTarget)
1852 {
1855 }
1856
1857 // not allow use skill grow at item base open
1858 if (!m_CastItem && skillId != SKILL_NONE)
1859 {
1860 // update skill if really known
1861 if (uint32 pureSkillValue = player->GetPureSkillValue(skillId))
1862 {
1863 if (gameObjTarget)
1864 {
1865 // Allow one skill-up until respawned
1866 if (!gameObjTarget->IsInSkillupList(player->GetGUID()))
1867 {
1868 player->UpdateGatherSkill(skillId, pureSkillValue, reqSkillValue);
1870 }
1871 }
1872 else if (itemTarget)
1873 {
1874 // Do one skill-up
1875 player->UpdateGatherSkill(skillId, pureSkillValue, reqSkillValue);
1876 }
1877 }
1878 }
1880}
1881
1883{
1885 return;
1886
1888 return;
1889
1890 Player* player = m_caster->ToPlayer();
1891
1892 // applied only to using item
1893 if (!m_CastItem)
1894 return;
1895
1896 // ... only to item in own inventory/bank/equip_slot
1897 if (m_CastItem->GetOwnerGUID() != player->GetGUID())
1898 return;
1899
1900 uint32 newitemid = effectInfo->ItemType;
1901 if (!newitemid)
1902 return;
1903
1904 uint16 pos = m_CastItem->GetPos();
1905
1906 Item* pNewItem = Item::CreateItem(newitemid, 1, player);
1907 if (!pNewItem)
1908 return;
1909
1913
1915 {
1917 player->DurabilityLoss(pNewItem, lossPercent);
1918 }
1919
1920 if (player->IsInventoryPos(pos))
1921 {
1922 ItemPosCountVec dest;
1923 InventoryResult msg = player->CanStoreItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), dest, pNewItem, true);
1924 if (msg == EQUIP_ERR_OK)
1925 {
1926 player->DestroyItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), true);
1927
1928 // prevent crash at access and unexpected charges counting with item update queue corrupt
1930 m_targets.SetItemTarget(nullptr);
1931
1932 m_CastItem = nullptr;
1934 m_castItemEntry = 0;
1935
1936 player->StoreItem(dest, pNewItem, true);
1937 player->SendNewItem(pNewItem, 1, true, false);
1938 player->ItemAddedQuestCheck(newitemid, 1);
1939 return;
1940 }
1941 }
1942 else if (player->IsBankPos(pos))
1943 {
1944 ItemPosCountVec dest;
1945 if (player->CanBankItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), dest, pNewItem, true) == EQUIP_ERR_OK)
1946 {
1947 player->DestroyItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), true);
1948
1949 // prevent crash at access and unexpected charges counting with item update queue corrupt
1951 m_targets.SetItemTarget(nullptr);
1952
1953 m_CastItem = nullptr;
1955 m_castItemEntry = 0;
1956
1957 player->BankItem(dest, pNewItem, true);
1958 return;
1959 }
1960 }
1961 else if (player->IsEquipmentPos(pos))
1962 {
1963 uint16 dest;
1964
1965 player->DestroyItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), true);
1966
1967 InventoryResult msg = player->CanEquipItem(m_CastItem->GetSlot(), dest, pNewItem, true);
1968
1969 if (msg == EQUIP_ERR_OK || msg == EQUIP_ERR_CLIENT_LOCKED_OUT)
1970 {
1972
1973 // prevent crash at access and unexpected charges counting with item update queue corrupt
1975 m_targets.SetItemTarget(nullptr);
1976
1977 m_CastItem = nullptr;
1979 m_castItemEntry = 0;
1980
1981 player->EquipItem(dest, pNewItem, true);
1982 player->AutoUnequipOffhandIfNeed();
1983 player->SendNewItem(pNewItem, 1, true, false);
1984 player->ItemAddedQuestCheck(newitemid, 1);
1985 return;
1986 }
1987 }
1988
1989 // fail
1990 delete pNewItem;
1991}
1992
1994{
1996 return;
1997
1999 return;
2000 Player* p_target = m_caster->ToPlayer();
2001
2003 if (m_spellInfo->EquippedItemClass == ITEM_CLASS_WEAPON && !(p_target->GetWeaponProficiency() & subClassMask))
2004 {
2005 p_target->AddWeaponProficiency(subClassMask);
2007 }
2008 if (m_spellInfo->EquippedItemClass == ITEM_CLASS_ARMOR && !(p_target->GetArmorProficiency() & subClassMask))
2009 {
2010 p_target->AddArmorProficiency(subClassMask);
2012 }
2013}
2014
2016{
2018 return;
2019
2020 uint32 entry = effectInfo->MiscValue;
2021 if (!entry)
2022 return;
2023
2024 SummonPropertiesEntry const* properties = sSummonPropertiesStore.LookupEntry(effectInfo->MiscValueB);
2025 if (!properties)
2026 {
2027 TC_LOG_ERROR("spells", "EffectSummonType: Unhandled summon type {}.", effectInfo->MiscValueB);
2028 return;
2029 }
2030
2031 WorldObject* caster = m_caster;
2032 if (m_originalCaster)
2033 caster = m_originalCaster;
2034
2035 ObjectGuid privateObjectOwner;
2036 if (properties->Flags & SUMMON_PROP_FLAG_PERSONAL_SPAWN)
2038 int32 duration = m_spellInfo->GetDuration();
2039 if (Player* modOwner = caster->GetSpellModOwner())
2040 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DURATION, duration);
2041
2042 Unit* unitCaster = GetUnitCasterForEffectHandlers();
2043
2044 TempSummon* summon = nullptr;
2045
2046 // determine how many units should be summoned
2047 uint32 numSummons;
2048
2049 // some spells need to summon many units, for those spells number of summons is stored in effect value
2050 // however so far noone found a generic check to find all of those (there's no related data in summonproperties.dbc
2051 // and in spell attributes, possibly we need to add a table for those)
2052 // so here's a list of MiscValueB values, which is currently most generic check
2053 switch (properties->ID)
2054 {
2055 case 64:
2056 case 61:
2057 case 1101:
2058 case 66:
2059 case 648:
2060 case 2301:
2061 case 1061:
2062 case 1261:
2063 case 629:
2064 case 181:
2065 case 715:
2066 case 1562:
2067 case 833:
2068 case 1161:
2069 case 713:
2070 numSummons = (damage > 0) ? damage : 1;
2071 break;
2072 default:
2073 numSummons = 1;
2074 break;
2075 }
2076
2077 switch (properties->Control)
2078 {
2082 {
2083 if (properties->Flags & 512)
2084 {
2085 SummonGuardian(*effectInfo, entry, properties, numSummons);
2086 break;
2087 }
2088
2089 switch (properties->Title)
2090 {
2091 case SUMMON_TYPE_PET:
2094 case SUMMON_TYPE_MINION:
2095 SummonGuardian(*effectInfo, entry, properties, numSummons);
2096 break;
2097 // Summons a vehicle, but doesn't force anyone to enter it (see SUMMON_CATEGORY_VEHICLE)
2101 {
2102 if (!unitCaster)
2103 return;
2104
2105 summon = unitCaster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, unitCaster, m_spellInfo->Id);
2106 break;
2107 }
2108 case SUMMON_TYPE_TOTEM:
2109 {
2110 if (!unitCaster)
2111 return;
2112
2113 summon = unitCaster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, unitCaster, m_spellInfo->Id, 0, privateObjectOwner);
2114 if (!summon || !summon->IsTotem())
2115 return;
2116
2117 // Mana Tide Totem
2118 if (m_spellInfo->Id == 16190)
2119 damage = unitCaster->CountPctFromMaxHealth(10);
2120
2121 if (damage) // if not spell info, DB values used
2122 {
2123 summon->SetMaxHealth(damage);
2124 summon->SetHealth(damage);
2125 }
2126 break;
2127 }
2129 {
2130 if (!unitCaster)
2131 return;
2132
2133 summon = unitCaster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, unitCaster, m_spellInfo->Id, 0, privateObjectOwner);
2134 if (!summon || !summon->HasUnitTypeMask(UNIT_MASK_MINION))
2135 return;
2136
2137 summon->SelectLevel(); // some summoned creaters have different from 1 DB data for level/hp
2139 summon->SetImmuneToAll(true);
2140 break;
2141 }
2142 default:
2143 {
2144 float radius = effectInfo->CalcRadius();
2145
2146 TempSummonType summonType = (duration == 0) ? TEMPSUMMON_DEAD_DESPAWN : TEMPSUMMON_TIMED_DESPAWN;
2147
2148 for (uint32 count = 0; count < numSummons; ++count)
2149 {
2150 Position pos;
2151 if (count == 0)
2152 pos = *destTarget;
2153 else
2154 // randomize position for multiple summons
2155 pos = caster->GetRandomPoint(*destTarget, radius);
2156
2157 summon = caster->SummonCreature(entry, pos, summonType, Milliseconds(duration), 0, m_spellInfo->Id, privateObjectOwner);
2158 if (!summon)
2159 continue;
2160
2161 if (properties->Control == SUMMON_CATEGORY_ALLY)
2162 {
2163 summon->SetOwnerGUID(caster->GetGUID());
2164 summon->SetFaction(caster->GetFaction());
2165 }
2166
2168 }
2169 return;
2170 }
2171 }
2172 break;
2173 }
2175 SummonGuardian(*effectInfo, entry, properties, numSummons);
2176 break;
2178 {
2179 if (!unitCaster)
2180 return;
2181
2182 summon = unitCaster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, unitCaster, m_spellInfo->Id, 0, privateObjectOwner);
2183 break;
2184 }
2186 {
2187 if (!unitCaster)
2188 return;
2189
2190 // Summoning spells (usually triggered by npc_spellclick) that spawn a vehicle and that cause the clicker
2191 // to cast a ride vehicle spell on the summoned unit.
2192 summon = unitCaster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, unitCaster, m_spellInfo->Id);
2193 if (!summon || !summon->IsVehicle())
2194 return;
2195
2196 // The spell that this effect will trigger. It has SPELL_AURA_CONTROL_VEHICLE
2198 int32 basePoints = effectInfo->CalcValue();
2199 if (basePoints > MAX_VEHICLE_SEATS)
2200 {
2201 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(basePoints);
2202 if (spellInfo && spellInfo->HasAura(SPELL_AURA_CONTROL_VEHICLE))
2203 spellId = spellInfo->Id;
2204 }
2205
2207
2208 // if we have small value, it indicates seat position
2209 if (basePoints > 0 && basePoints < MAX_VEHICLE_SEATS)
2210 args.AddSpellMod(SPELLVALUE_BASE_POINT0, basePoints);
2211
2212 unitCaster->CastSpell(summon, spellId, args);
2213
2214 uint32 faction = properties->Faction;
2215 if (!faction)
2216 faction = unitCaster->GetFaction();
2217
2218 summon->SetFaction(faction);
2219 break;
2220 }
2221 }
2222
2223 if (summon)
2224 {
2225 summon->SetCreatorGUID(caster->GetGUID());
2227 }
2228}
2229
2231{
2233 return;
2234
2235 if (!unitTarget)
2236 return;
2237
2239 {
2240 if (unitTarget->ToPet())
2242 return;
2243 }
2244
2245 Player* player = unitTarget->ToPlayer();
2246
2248 {
2249 for (ItemEffect const& itemEffect : m_CastItem->GetTemplate()->Effects)
2250 {
2251 if (itemEffect.TriggerType != ITEM_SPELLTRIGGER_LEARN_SPELL_ID)
2252 continue;
2253
2254 player->LearnSpell(itemEffect.SpellID, false);
2255 }
2256 }
2257
2259 {
2260 player->LearnSpell(effectInfo->TriggerSpell, false);
2261 TC_LOG_DEBUG("spells", "Spell: Player {} has learned spell {} from Npc {}", player->GetGUID().ToString(), effectInfo->TriggerSpell, m_caster->GetGUID().ToString());
2262 }
2263}
2264
2266{
2268 return;
2269
2270 if (!unitTarget)
2271 return;
2272
2273 // Create dispel mask by dispel type
2274 uint32 dispel_type = effectInfo->MiscValue;
2275 uint32 dispelMask = SpellInfo::GetDispelMask(DispelType(dispel_type));
2276
2277 DispelChargesList dispelList;
2279 if (dispelList.empty())
2280 return;
2281
2282 size_t remaining = dispelList.size();
2283
2284 // Ok if exist some buffs for dispel try dispel it
2285 uint32 failCount = 0;
2286 DispelChargesList successList;
2287 successList.reserve(damage);
2288
2289 WorldPacket dataFail(SMSG_DISPEL_FAILED, 8 + 8 + 4 + 4 + damage * 4);
2290 // dispel N = damage buffs (or while exist buffs for dispel)
2291 for (int32 count = 0; count < damage && remaining > 0;)
2292 {
2293 // Random select buff for dispel
2294 auto itr = dispelList.begin();
2295 std::advance(itr, urand(0, remaining - 1));
2296
2297 if (itr->RollDispel())
2298 {
2299 auto successItr = std::find_if(successList.begin(), successList.end(), [&itr](DispelableAura& dispelAura) -> bool
2300 {
2301 if (dispelAura.GetAura()->GetId() == itr->GetAura()->GetId() && dispelAura.GetAura()->GetCaster() == itr->GetAura()->GetCaster())
2302 return true;
2303
2304 return false;
2305 });
2306
2307 if (successItr == successList.end())
2308 successList.emplace_back(itr->GetAura(), 0, 1);
2309 else
2310 successItr->IncrementCharges();
2311
2312 if (!itr->DecrementCharge())
2313 {
2314 --remaining;
2315 std::swap(*itr, dispelList[remaining]);
2316 }
2317 }
2318 else
2319 {
2320 if (!failCount)
2321 {
2322 // Failed to dispell
2323 dataFail << m_caster->GetGUID(); // Caster GUID
2324 dataFail << unitTarget->GetGUID(); // Victim GUID
2325 dataFail << uint32(m_spellInfo->Id); // dispel spell id
2326 }
2327 ++failCount;
2328 dataFail << uint32(itr->GetAura()->GetId()); // Spell Id
2329 }
2330 ++count;
2331 }
2332
2333 if (failCount)
2334 m_caster->SendMessageToSet(&dataFail, true);
2335
2336 if (successList.empty())
2337 return;
2338
2339 WorldPacket dataSuccess(SMSG_SPELLDISPELLOG, 8 + 8 + 4 + 1 + 4 + successList.size() * 5);
2340 // Send packet header
2341 dataSuccess << unitTarget->GetPackGUID(); // Victim GUID
2342 dataSuccess << m_caster->GetPackGUID(); // Caster GUID
2343 dataSuccess << uint32(m_spellInfo->Id); // dispel spell id
2344 dataSuccess << uint8(0); // not used
2345 dataSuccess << uint32(successList.size()); // count
2346 for (DispelChargesList::iterator itr = successList.begin(); itr != successList.end(); ++itr)
2347 {
2348 // Send dispelled spell info
2349 dataSuccess << uint32(itr->GetAura()->GetId()); // Spell Id
2350 dataSuccess << uint8(0); // 0 - dispelled !=0 cleansed
2351 unitTarget->RemoveAurasDueToSpellByDispel(itr->GetAura()->GetId(), m_spellInfo->Id, itr->GetAura()->GetCasterGUID(), m_caster, itr->GetDispelCharges());
2352 }
2353 m_caster->SendMessageToSet(&dataSuccess, true);
2354
2355 // On success dispel
2356 // Devour Magic
2358 {
2361 m_caster->CastSpell(m_caster, 19658, args);
2362 // Glyph of Felhunter
2363 if (Unit* owner = m_caster->GetOwner())
2364 if (owner->GetAura(56249))
2365 owner->CastSpell(owner, 19658, args);
2366 }
2367}
2368
2370{
2372 return;
2373
2375}
2376
2378{
2380 EffectNULL();
2381}
2382
2384{
2386 return;
2387
2388 // Check for possible target
2389 if (!unitTarget || unitTarget->IsEngaged())
2390 return;
2391
2392 // target must be OK to do this
2394 return;
2395
2397}
2398
2400{
2402 return;
2403
2405 return;
2406
2407 // victim must be creature and attackable
2409 return;
2410
2411 // victim have to be alive and humanoid or undead
2414}
2415
2417{
2419 return;
2420
2421 Player* player = m_caster->ToPlayer();
2422 if (!player)
2423 return;
2424
2425 float radius = effectInfo->CalcRadius();
2426 int32 duration = m_spellInfo->GetDuration();
2427 // Caster not in world, might be spell triggered from aura removal
2428 if (!player->IsInWorld())
2429 return;
2430
2431 DynamicObject* dynObj = new DynamicObject(true);
2433 {
2434 delete dynObj;
2435 return;
2436 }
2437
2438 dynObj->SetDuration(duration);
2439 dynObj->SetCasterViewpoint();
2440}
2441
2452
2467
2469{
2471 return;
2472
2474 return;
2475
2476 if (damage < 0)
2477 return;
2478
2479 uint32 skillid = effectInfo->MiscValue;
2481 if (!rcEntry)
2482 return;
2483
2484 SkillTiersEntry const* tier = sSkillTiersStore.LookupEntry(rcEntry->SkillTierID);
2485 if (!tier)
2486 return;
2487
2488 uint16 skillval = unitTarget->ToPlayer()->GetPureSkillValue(skillid);
2489 unitTarget->ToPlayer()->SetSkill(skillid, effectInfo->CalcValue(), std::max<uint16>(skillval, 1), tier->Value[damage - 1]);
2490}
2491
2493{
2495 return;
2496
2498 return;
2499
2500 // not scale value for item based reward (/10 value expected)
2501 if (m_CastItem)
2502 {
2503 unitTarget->ToPlayer()->RewardHonor(nullptr, 1, damage/10);
2504 TC_LOG_DEBUG("spells", "SpellEffect::AddHonor (spell_id {}) rewards {} honor points (item {}) for player {}", m_spellInfo->Id, damage/10, m_CastItem->GetEntry(), unitTarget->ToPlayer()->GetGUID().ToString());
2505 return;
2506 }
2507
2508 // do not allow to add too many honor for player (50 * 21) = 1040 at level 70, or (50 * 31) = 1550 at level 80
2509 if (damage <= 50)
2510 {
2512 unitTarget->ToPlayer()->RewardHonor(nullptr, 1, honor_reward);
2513 TC_LOG_DEBUG("spells", "SpellEffect::AddHonor (spell_id {}) rewards {} honor points (scale) to player {}", m_spellInfo->Id, honor_reward, unitTarget->ToPlayer()->GetGUID().ToString());
2514 }
2515 else
2516 {
2517 //maybe we have correct honor_gain in damage already
2518 unitTarget->ToPlayer()->RewardHonor(nullptr, 1, damage);
2519 TC_LOG_DEBUG("spells", "SpellEffect::AddHonor (spell_id {}) rewards {} honor points (non scale) for player {}", m_spellInfo->Id, damage, unitTarget->ToPlayer()->GetGUID().ToString());
2520 }
2521}
2522
2524{
2526 return;
2527
2529 return;
2530 // uint32 skillid = effectInfo->MiscValue;
2531 // uint16 skillmax = unitTarget->ToPlayer()->(skillid);
2532 // m_caster->ToPlayer()->SetSkill(skillid, skillval?skillval:1, skillmax+75);
2533}
2534
2536{
2538 return;
2539
2540 if (!itemTarget)
2541 return;
2542
2543 Player* player = m_caster->ToPlayer();
2544 if (!player)
2545 return;
2546
2547 // Handle vellums
2549 {
2550 // destroy one vellum from stack
2551 uint32 count = 1;
2552 player->DestroyItemCount(itemTarget, count, true);
2553 unitTarget = player;
2554 // and add a scroll
2556 itemTarget = nullptr;
2557 m_targets.SetItemTarget(nullptr);
2558 }
2559 else
2560 {
2561 // do not increase skill if vellum used
2564
2565 uint32 enchant_id = effectInfo->MiscValue;
2566 if (!enchant_id)
2567 return;
2568
2569 SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
2570 if (!pEnchant)
2571 return;
2572
2573 // item can be in trade slot and have owner diff. from caster
2574 Player* item_owner = itemTarget->GetOwner();
2575 if (!item_owner)
2576 return;
2577
2578 if (item_owner != player && player->GetSession()->HasPermission(rbac::RBAC_PERM_LOG_GM_TRADE))
2579 {
2580 sLog->OutCommand(player->GetSession()->GetAccountId(), "GM {} (Account: {}) enchanting(perm): {} (Entry: {}) for player: {} (Account: {})",
2581 player->GetName(), player->GetSession()->GetAccountId(),
2583 item_owner->GetName(), item_owner->GetSession()->GetAccountId());
2584 }
2585
2586 // remove old enchanting before applying new if equipped
2588
2590
2591 // add new enchanting if equipped
2593
2594 item_owner->RemoveTradeableItem(itemTarget);
2596 }
2597}
2598
2600{
2602 return;
2603
2604 if (!itemTarget)
2605 return;
2606
2607 Player* player = m_caster->ToPlayer();
2608 if (!player)
2609 return;
2610
2611 uint32 enchantId = effectInfo->MiscValue;
2612 if (!enchantId)
2613 return;
2614
2615 SpellItemEnchantmentEntry const* enchant = sSpellItemEnchantmentStore.LookupEntry(enchantId);
2616 if (!enchant)
2617 return;
2618
2619 // support only enchantings with add socket in this slot
2620 {
2621 bool add_socket = false;
2622 for (uint8 i = 0; i < MAX_ITEM_ENCHANTMENT_EFFECTS; ++i)
2623 {
2625 {
2626 add_socket = true;
2627 break;
2628 }
2629 }
2630 if (!add_socket)
2631 {
2632 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.",
2634 return;
2635 }
2636 }
2637
2638 // item can be in trade slot and have owner diff. from caster
2639 Player* item_owner = itemTarget->GetOwner();
2640 if (!item_owner)
2641 return;
2642
2643 if (item_owner != player && player->GetSession()->HasPermission(rbac::RBAC_PERM_LOG_GM_TRADE))
2644 {
2645 sLog->OutCommand(player->GetSession()->GetAccountId(), "GM {} (Account: {}) enchanting(perm): {} (Entry: {}) for player: {} (Account: {})",
2646 player->GetName(), player->GetSession()->GetAccountId(),
2648 item_owner->GetName(), item_owner->GetSession()->GetAccountId());
2649 }
2650
2651 // remove old enchanting before applying new if equipped
2653
2655
2656 // add new enchanting if equipped
2658
2659 item_owner->RemoveTradeableItem(itemTarget);
2661}
2662
2664{
2666 return;
2667
2668 Player* player = m_caster->ToPlayer();
2669 if (!player)
2670 return;
2671
2672 // Rockbiter Weapon apply to both weapon
2673 if (!itemTarget)
2674 return;
2676 {
2677 uint32 spell_id = 0;
2678
2679 // enchanting spell selected by calculated damage-per-sec stored in Effect[1] base value
2680 // Note: damage calculated (correctly) with rounding int32(float(v)) but
2681 // RW enchantments applied damage int32(float(v)+0.5), this create 0..1 difference sometime
2682 switch (damage)
2683 {
2684 // Rank 1
2685 case 2: spell_id = 36744; break; // 0% [ 7% == 2, 14% == 2, 20% == 2]
2686 // Rank 2
2687 case 4: spell_id = 36753; break; // 0% [ 7% == 4, 14% == 4]
2688 case 5: spell_id = 36751; break; // 20%
2689 // Rank 3
2690 case 6: spell_id = 36754; break; // 0% [ 7% == 6, 14% == 6]
2691 case 7: spell_id = 36755; break; // 20%
2692 // Rank 4
2693 case 9: spell_id = 36761; break; // 0% [ 7% == 6]
2694 case 10: spell_id = 36758; break; // 14%
2695 case 11: spell_id = 36760; break; // 20%
2696 default:
2697 TC_LOG_ERROR("spells", "Spell::EffectEnchantItemTmp: Damage {} not handled in S'RW.", damage);
2698 return;
2699 }
2700
2701 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell_id);
2702 if (!spellInfo)
2703 {
2704 TC_LOG_ERROR("spells", "Spell::EffectEnchantItemTmp: unknown spell id {}", spell_id);
2705 return;
2706
2707 }
2708
2709 for (int j = BASE_ATTACK; j <= OFF_ATTACK; ++j)
2710 {
2711 if (Item* item = player->GetWeaponForAttack(WeaponAttackType(j)))
2712 {
2713 if (item->IsFitToSpellRequirements(m_spellInfo))
2714 {
2715 Spell* spell = new Spell(m_caster, spellInfo, TRIGGERED_FULL_MASK);
2716 SpellCastTargets targets;
2717 targets.SetItemTarget(item);
2718 spell->prepare(targets);
2719 }
2720 }
2721 }
2722 return;
2723 }
2724
2725 uint32 enchant_id = effectInfo->MiscValue;
2726
2727 if (!enchant_id)
2728 {
2729 TC_LOG_ERROR("spells", "Spell {} Effect {} (SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY) has enchanting id 0.", m_spellInfo->Id, uint32(effectInfo->EffectIndex));
2730 return;
2731 }
2732
2733 SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
2734 if (!pEnchant)
2735 {
2736 TC_LOG_ERROR("spells", "Spell {} Effect {} (SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY) has a non-existing enchanting id {} ", m_spellInfo->Id, uint32(effectInfo->EffectIndex), enchant_id);
2737 return;
2738 }
2739
2740 // select enchantment duration
2741 uint32 duration;
2742
2743 // rogue family enchantments exception by duration
2744 if (m_spellInfo->Id == 38615)
2745 duration = 1800; // 30 mins
2746 // other rogue family enchantments always 1 hour (some have spell damage=0, but some have wrong data in EffBasePoints)
2748 duration = 3600; // 1 hour
2749 // shaman family enchantments
2751 duration = 1800; // 30 mins
2752 // other cases with this SpellVisual already selected
2753 else if (m_spellInfo->SpellVisual[0] == 215)
2754 duration = 1800; // 30 mins
2755 // some fishing pole bonuses except Glow Worm which lasts full hour
2756 else if (m_spellInfo->SpellVisual[0] == 563 && m_spellInfo->Id != 64401)
2757 duration = 600; // 10 mins
2758 // shaman rockbiter enchantments
2759 else if (m_spellInfo->SpellVisual[0] == 0)
2760 duration = 1800; // 30 mins
2761 else if (m_spellInfo->Id == 29702)
2762 duration = 300; // 5 mins
2763 else if (m_spellInfo->Id == 37360)
2764 duration = 300; // 5 mins
2765 // default case
2766 else
2767 duration = 3600; // 1 hour
2768
2769 // item can be in trade slot and have owner diff. from caster
2770 Player* item_owner = itemTarget->GetOwner();
2771 if (!item_owner)
2772 return;
2773
2774 if (item_owner != player && player->GetSession()->HasPermission(rbac::RBAC_PERM_LOG_GM_TRADE))
2775 {
2776 sLog->OutCommand(player->GetSession()->GetAccountId(), "GM {} (Account: {}) enchanting(temp): {} (Entry: {}) for player: {} (Account: {})",
2777 player->GetName(), player->GetSession()->GetAccountId(),
2779 item_owner->GetName(), item_owner->GetSession()->GetAccountId());
2780 }
2781
2782 // remove old enchanting before applying new if equipped
2784
2785 itemTarget->SetEnchantment(TEMP_ENCHANTMENT_SLOT, enchant_id, duration * 1000, 0, m_caster->GetGUID());
2786
2787 // add new enchanting if equipped
2789}
2790
2792{
2794 return;
2795
2796 Unit* unitCaster = GetUnitCasterForEffectHandlers();
2797 if (!unitCaster || !unitCaster->GetPetGUID().IsEmpty())
2798 return;
2799
2800 if (!unitTarget)
2801 return;
2802
2804 return;
2805
2806 Creature* creatureTarget = unitTarget->ToCreature();
2807
2808 if (creatureTarget->IsPet())
2809 return;
2810
2811 if (unitCaster->GetClass() != CLASS_HUNTER)
2812 return;
2813
2814 // cast finish successfully
2815 //SendChannelUpdate(0);
2816 finish();
2817
2818 Pet* pet = unitCaster->CreateTamedPetFrom(creatureTarget, m_spellInfo->Id);
2819 if (!pet) // in very specific state like near world end/etc.
2820 return;
2821
2822 // "kill" original creature
2823 creatureTarget->DespawnOrUnsummon();
2824
2825 uint8 level = (creatureTarget->GetLevel() < (unitCaster->GetLevel() - 5)) ? (unitCaster->GetLevel() - 5) : creatureTarget->GetLevel();
2826
2827 // prepare visual effect for levelup
2828 pet->SetUInt32Value(UNIT_FIELD_LEVEL, level - 1);
2829
2830 // add to world
2831 pet->GetMap()->AddToMap(pet->ToCreature());
2832
2833 // visual effect for levelup
2834 pet->SetUInt32Value(UNIT_FIELD_LEVEL, level);
2835
2836 // caster have pet now
2837 unitCaster->SetMinion(pet, true);
2838
2839 pet->InitTalentForLevel();
2840
2841 if (unitCaster->GetTypeId() == TYPEID_PLAYER)
2842 {
2844 unitCaster->ToPlayer()->PetSpellInitialize();
2845 }
2846}
2847
2849{
2851 return;
2852
2853 Player* owner = nullptr;
2854 if (Unit* unitCaster = GetUnitCasterForEffectHandlers())
2855 {
2856 owner = unitCaster->ToPlayer();
2857 if (!owner && unitCaster->IsTotem())
2858 owner = unitCaster->GetCharmerOrOwnerPlayerOrPlayerItself();
2859 }
2860
2861 uint32 petentry = effectInfo->MiscValue;
2862
2863 if (!owner)
2864 {
2865 SummonPropertiesEntry const* properties = sSummonPropertiesStore.LookupEntry(67);
2866 if (properties)
2867 SummonGuardian(*effectInfo, petentry, properties, 1);
2868 return;
2869 }
2870
2871 Pet* OldSummon = owner->GetPet();
2872
2873 // if pet requested type already exist
2874 if (OldSummon)
2875 {
2876 if (petentry == 0 || OldSummon->GetEntry() == petentry)
2877 {
2878 // pet in corpse state can't be summoned
2879 if (OldSummon->isDead())
2880 return;
2881
2882 ASSERT(OldSummon->GetMap() == owner->GetMap());
2883
2884 //OldSummon->GetMap()->Remove(OldSummon->ToCreature(), false);
2885
2886 float px, py, pz;
2887 owner->GetClosePoint(px, py, pz, OldSummon->GetCombatReach());
2888
2889 OldSummon->NearTeleportTo(px, py, pz, OldSummon->GetOrientation());
2890 //OldSummon->Relocate(px, py, pz, OldSummon->GetOrientation());
2891 //OldSummon->SetMap(owner->GetMap());
2892 //owner->GetMap()->Add(OldSummon->ToCreature());
2893 if (OldSummon->getPetType() == SUMMON_PET)
2894 {
2895 OldSummon->SetHealth(OldSummon->GetMaxHealth());
2896 OldSummon->SetPower(OldSummon->GetPowerType(), OldSummon->GetMaxPower(OldSummon->GetPowerType()));
2897 OldSummon->GetSpellHistory()->ResetAllCooldowns();
2898 }
2899
2900 if (owner->GetTypeId() == TYPEID_PLAYER && OldSummon->isControlled())
2901 owner->ToPlayer()->PetSpellInitialize();
2902
2903 return;
2904 }
2905
2906 if (owner->GetTypeId() == TYPEID_PLAYER)
2907 owner->ToPlayer()->RemovePet(OldSummon, PET_SAVE_NOT_IN_SLOT, false);
2908 else
2909 return;
2910 }
2911
2912 float x, y, z;
2913 owner->GetClosePoint(x, y, z, owner->GetCombatReach());
2914 Pet* pet = owner->SummonPet(petentry, x, y, z, owner->GetOrientation(), SUMMON_PET, 0);
2915 if (!pet)
2916 return;
2917
2918 if (m_caster->GetTypeId() == TYPEID_UNIT)
2919 {
2920 if (m_caster->ToCreature()->IsTotem())
2922 else
2924 }
2925
2927
2928 // generate new name for summon pet
2929 std::string new_name = sObjectMgr->GeneratePetName(petentry);
2930 if (!new_name.empty())
2931 pet->SetName(new_name);
2932
2934}
2935
2937{
2939 return;
2940
2941 if (!unitTarget)
2942 return;
2943
2944 if (unitTarget->ToPlayer())
2945 {
2947 return;
2948 }
2949 Pet* pet = unitTarget->ToPet();
2950 if (!pet)
2951 return;
2952
2953 SpellInfo const* learn_spellproto = sSpellMgr->GetSpellInfo(effectInfo->TriggerSpell);
2954 if (!learn_spellproto)
2955 return;
2956
2957 pet->learnSpell(learn_spellproto->Id);
2959 pet->GetOwner()->PetSpellInitialize();
2960}
2961
2963{
2965 return;
2966
2967 Unit* unitCaster = GetUnitCasterForEffectHandlers();
2968 if (!unitCaster)
2969 return;
2970
2971 // this effect use before aura Taunt apply for prevent taunt already attacking target
2972 // for spell as marked "non effective at already attacking target"
2973 if (!unitTarget || unitTarget->IsTotem())
2974 {
2976 return;
2977 }
2978
2979 // Hand of Reckoning can hit some entities that can't have a threat list (including players' pets)
2980 if (m_spellInfo->Id == 62124)
2981 if (unitTarget->GetTypeId() != TYPEID_PLAYER && unitTarget->GetTarget() != unitCaster->GetGUID())
2982 unitCaster->CastSpell(unitTarget, 67485, true);
2983
2985 {
2987 return;
2988 }
2989
2991 if (mgr.GetCurrentVictim() == unitCaster)
2992 {
2994 return;
2995 }
2996
2997 if (!mgr.IsThreatListEmpty())
2998 // Set threat equal to highest threat currently on target
2999 mgr.MatchUnitThreatToHighestThreat(unitCaster);
3000}
3001
3003{
3005 return;
3006
3007 Unit* unitCaster = GetUnitCasterForEffectHandlers();
3008 if (!unitCaster)
3009 return;
3010
3011 if (!unitTarget || !unitTarget->IsAlive())
3012 return;
3013
3014 // multiple weapon dmg effect workaround
3015 // execute only the last weapon damage
3016 // and handle all effects at once
3017 for (size_t j = effectInfo->EffectIndex + 1; j < m_spellInfo->GetEffects().size(); ++j)
3018 {
3020 {
3025 return; // we must calculate only at last weapon effect
3026 default:
3027 break;
3028 }
3029 }
3030
3031 // some spell specific modifiers
3032 float totalDamagePercentMod = 1.0f; // applied to final bonus+weapon damage
3033 int32 fixed_bonus = 0;
3034 int32 spell_bonus = 0; // bonus specific for spell
3035
3037 {
3039 {
3040 // Devastate (player ones)
3041 if (m_spellInfo->SpellFamilyFlags[1] & 0x40)
3042 {
3043 unitCaster->CastSpell(unitTarget, 58567, true);
3044 // 58388 - Glyph of Devastate dummy aura.
3045 if (unitCaster->HasAura(58388))
3046 unitCaster->CastSpell(unitTarget, 58567, true);
3047
3048 if (Aura* aur = unitTarget->GetAura(58567, unitCaster->GetGUID()))
3049 fixed_bonus += (aur->GetStackAmount() - 1) * CalculateDamage(m_spellInfo->GetEffect(EFFECT_2)); // subtract 1 so fixed bonus is not applied twice
3050 }
3051 else if (m_spellInfo->SpellFamilyFlags[0] & 0x8000000) // Mocking Blow
3052 {
3054 {
3055 m_damage = 0;
3056 return;
3057 }
3058 }
3059 break;
3060 }
3061 case SPELLFAMILY_ROGUE:
3062 {
3063 // Fan of Knives, Hemorrhage, Ghostly Strike
3064 if ((m_spellInfo->SpellFamilyFlags[1] & 0x40000)
3065 || (m_spellInfo->SpellFamilyFlags[0] & 0x6000000))
3066 {
3067 // Hemorrhage
3068 if (m_spellInfo->SpellFamilyFlags[0] & 0x2000000)
3070
3071 // 50% more damage with daggers
3072 if (unitCaster->GetTypeId() == TYPEID_PLAYER)
3073 if (Item* item = unitCaster->ToPlayer()->GetWeaponForAttack(m_attackType, true))
3074 if (item->GetTemplate()->SubClass == ITEM_SUBCLASS_WEAPON_DAGGER)
3075 totalDamagePercentMod *= 1.5f;
3076 }
3077 // Mutilate (for each hand)
3078 else if (m_spellInfo->SpellFamilyFlags[1] & 0x6)
3079 {
3080 bool found = false;
3081 // fast check
3083 found = true;
3084 // full aura scan
3085 else
3086 {
3088 for (Unit::AuraApplicationMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
3089 {
3090 if (itr->second->GetBase()->GetSpellInfo()->Dispel == DISPEL_POISON)
3091 {
3092 found = true;
3093 break;
3094 }
3095 }
3096 }
3097
3098 if (found)
3099 totalDamagePercentMod *= 1.2f; // 120% if poisoned
3100 }
3101 break;
3102 }
3104 {
3105 // Seal of Command Unleashed
3106 if (m_spellInfo->Id == 20467)
3107 {
3108 spell_bonus += int32(0.08f * unitCaster->GetTotalAttackPowerValue(BASE_ATTACK));
3109 spell_bonus += int32(0.13f * unitCaster->SpellBaseDamageBonusDone(m_spellInfo->GetSchoolMask()));
3110 }
3111 break;
3112 }
3113 case SPELLFAMILY_SHAMAN:
3114 {
3115 // Skyshatter Harness item set bonus
3116 // Stormstrike
3117 if (AuraEffect* aurEff = unitCaster->IsScriptOverriden(m_spellInfo, 5634))
3118 unitCaster->CastSpell(nullptr, 38430, aurEff);
3119 break;
3120 }
3121 case SPELLFAMILY_DRUID:
3122 {
3123 // Mangle (Cat): CP
3124 if (m_spellInfo->SpellFamilyFlags[1] & 0x400)
3126
3127 // Shred, Maul - Rend and Tear
3129 {
3130 if (AuraEffect const* rendAndTear = unitCaster->GetDummyAuraEffect(SPELLFAMILY_DRUID, 2859, 0))
3131 AddPct(totalDamagePercentMod, rendAndTear->GetAmount());
3132 }
3133 break;
3134 }
3135 case SPELLFAMILY_HUNTER:
3136 {
3137 // Kill Shot - bonus damage from Ranged Attack Power
3138 if (m_spellInfo->SpellFamilyFlags[1] & 0x800000)
3139 spell_bonus += int32(0.4f * unitCaster->GetTotalAttackPowerValue(RANGED_ATTACK));
3140 break;
3141 }
3143 {
3144 // Plague Strike
3145 if (m_spellInfo->SpellFamilyFlags[0] & 0x1)
3146 {
3147 // Glyph of Plague Strike
3148 if (AuraEffect const* aurEff = unitCaster->GetAuraEffect(58657, EFFECT_0))
3149 AddPct(totalDamagePercentMod, aurEff->GetAmount());
3150 break;
3151 }
3152 // Blood Strike
3153 if (m_spellInfo->SpellFamilyFlags[0] & 0x400000)
3154 {
3155 float bonusPct = m_spellInfo->GetEffect(EFFECT_2).CalcValue() * unitTarget->GetDiseasesByCaster(unitCaster->GetGUID()) / 2.0f;
3156 // Death Knight T8 Melee 4P Bonus
3157 if (AuraEffect const* aurEff = unitCaster->GetAuraEffect(64736, EFFECT_0))
3158 AddPct(bonusPct, aurEff->GetAmount());
3159 AddPct(totalDamagePercentMod, bonusPct);
3160
3161 // Glyph of Blood Strike
3162 if (unitCaster->GetAuraEffect(59332, EFFECT_0))
3164 AddPct(totalDamagePercentMod, 20);
3165 break;
3166 }
3167 // Death Strike
3168 if (m_spellInfo->SpellFamilyFlags[0] & 0x10)
3169 {
3170 // Glyph of Death Strike
3171 if (AuraEffect const* aurEff = unitCaster->GetAuraEffect(59336, EFFECT_0))
3172 if (uint32 runic = std::min<uint32>(unitCaster->GetPower(POWER_RUNIC_POWER), aurEff->GetSpellInfo()->GetEffect(EFFECT_1).CalcValue()))
3173 AddPct(totalDamagePercentMod, runic);
3174 break;
3175 }
3176 // Obliterate (12.5% more damage per disease)
3177 if (m_spellInfo->SpellFamilyFlags[1] & 0x20000)
3178 {
3179 bool consumeDiseases = true;
3180 // Annihilation
3181 if (AuraEffect const* aurEff = unitCaster->GetDummyAuraEffect(SPELLFAMILY_DEATHKNIGHT, 2710, EFFECT_0))
3182 // Do not consume diseases if roll sucesses
3183 if (roll_chance_i(aurEff->GetAmount()))
3184 consumeDiseases = false;
3185
3186 float bonusPct = m_spellInfo->GetEffect(EFFECT_2).CalcValue() * unitTarget->GetDiseasesByCaster(unitCaster->GetGUID(), consumeDiseases) / 2.0f;
3187 // Death Knight T8 Melee 4P Bonus
3188 if (AuraEffect const* aurEff = unitCaster->GetAuraEffect(64736, EFFECT_0))
3189 AddPct(bonusPct, aurEff->GetAmount());
3190 AddPct(totalDamagePercentMod, bonusPct);
3191 break;
3192 }
3193 // Blood-Caked Strike - Blood-Caked Blade
3194 if (m_spellInfo->SpellIconID == 1736)
3195 {
3196 AddPct(totalDamagePercentMod, unitTarget->GetDiseasesByCaster(unitCaster->GetGUID()) * 50.0f);
3197 break;
3198 }
3199 // Heart Strike
3200 if (m_spellInfo->SpellFamilyFlags[0] & 0x1000000)
3201 {
3202 float bonusPct = m_spellInfo->GetEffect(EFFECT_2).CalcValue() * unitTarget->GetDiseasesByCaster(unitCaster->GetGUID());
3203 // Death Knight T8 Melee 4P Bonus
3204 if (AuraEffect const* aurEff = unitCaster->GetAuraEffect(64736, EFFECT_0))
3205 AddPct(bonusPct, aurEff->GetAmount());
3206
3207 AddPct(totalDamagePercentMod, bonusPct);
3208 break;
3209 }
3210 break;
3211 }
3212 }
3213
3214 bool normalized = false;
3215 float weaponDamagePercentMod = 1.0f;
3216 for (SpellEffectInfo const& spellEffectInfo : m_spellInfo->GetEffects())
3217 {
3218 switch (spellEffectInfo.Effect)
3219 {
3222 fixed_bonus += CalculateDamage(spellEffectInfo);
3223 break;
3225 fixed_bonus += CalculateDamage(spellEffectInfo);
3226 normalized = true;
3227 break;
3229 ApplyPct(weaponDamagePercentMod, CalculateDamage(spellEffectInfo));
3230 break;
3231 default:
3232 break; // not weapon damage effect, just skip
3233 }
3234 }
3235
3236 // if (addPctMods) { percent mods are added in Unit::CalculateDamage } else { percent mods are added in Unit::MeleeDamageBonusDone }
3237 // this distinction is neccessary to properly inform the client about his autoattack damage values from Script_UnitDamage
3239 if (addPctMods)
3240 {
3241 UnitMods unitMod;
3242 switch (m_attackType)
3243 {
3244 default:
3245 case BASE_ATTACK: unitMod = UNIT_MOD_DAMAGE_MAINHAND; break;
3246 case OFF_ATTACK: unitMod = UNIT_MOD_DAMAGE_OFFHAND; break;
3247 case RANGED_ATTACK: unitMod = UNIT_MOD_DAMAGE_RANGED; break;
3248 }
3249
3250 float weapon_total_pct = unitCaster->GetPctModifierValue(unitMod, TOTAL_PCT);
3251 if (fixed_bonus)
3252 fixed_bonus = int32(fixed_bonus * weapon_total_pct);
3253 if (spell_bonus)
3254 spell_bonus = int32(spell_bonus * weapon_total_pct);
3255 }
3256
3257 int32 weaponDamage = unitCaster->CalculateDamage(m_attackType, normalized, addPctMods);
3258
3259 // Sequence is important
3260 for (SpellEffectInfo const& spellEffectInfo : m_spellInfo->GetEffects())
3261 {
3262 // We assume that a spell have at most one fixed_bonus
3263 // and at most one weaponDamagePercentMod
3264 switch (spellEffectInfo.Effect)
3265 {
3269 weaponDamage += fixed_bonus;
3270 break;
3272 weaponDamage = int32(weaponDamage * weaponDamagePercentMod);
3273 break;
3274 default:
3275 break; // not weapon damage effect, just skip
3276 }
3277 }
3278
3279 weaponDamage += spell_bonus;
3280 weaponDamage = int32(weaponDamage * totalDamagePercentMod);
3281
3282 // apply spellmod to Done damage
3283 if (Player* modOwner = unitCaster->GetSpellModOwner())
3284 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DAMAGE, weaponDamage);
3285
3286 // prevent negative damage
3287 weaponDamage = std::max(weaponDamage, 0);
3288
3289 // Add melee damage bonuses (also check for negative)
3290 weaponDamage = unitCaster->MeleeDamageBonusDone(unitTarget, weaponDamage, m_attackType, m_spellInfo);
3291 m_damage += unitTarget->MeleeDamageBonusTaken(unitCaster, weaponDamage, m_attackType, m_spellInfo);
3292}
3293
3295{
3297 return;
3298
3299 Unit* unitCaster = GetUnitCasterForEffectHandlers();
3300 if (!unitCaster || !unitCaster->IsAlive())
3301 return;
3302
3303 if (!unitTarget)
3304 return;
3305
3307 return;
3308
3309 unitTarget->GetThreatManager().AddThreat(unitCaster, float(damage), m_spellInfo, true);
3310}
3311
3313{
3315 return;
3316
3317 Unit* unitCaster = GetUnitCasterForEffectHandlers();
3318 if (!unitCaster)
3319 return;
3320
3321 if (!unitTarget || !unitTarget->IsAlive())
3322 return;
3323
3324 int32 addhealth = 0;
3325
3326 // damage == 0 - heal for caster max health
3327 if (damage == 0)
3328 addhealth = unitCaster->GetMaxHealth();
3329 else
3330 addhealth = unitTarget->GetMaxHealth() - unitTarget->GetHealth();
3331
3332 m_healing += addhealth;
3333}
3334
3336{
3338 return;
3339
3340 if (!unitTarget || !unitTarget->IsAlive())
3341 return;
3342
3344 // also exist case: apply cooldown to interrupted cast only and to all spells
3345 // there is no CURRENT_AUTOREPEAT_SPELL spells that can be interrupted
3347 {
3349 {
3350 SpellInfo const* curSpellInfo = spell->m_spellInfo;
3351 // check if we can interrupt spell
3352 if ((spell->getState() == SPELL_STATE_CASTING
3353 || (spell->getState() == SPELL_STATE_PREPARING && spell->GetCastTime() > 0.0f))
3357 {
3358 if (Unit* unitCaster = GetUnitCasterForEffectHandlers())
3359 {
3360 int32 duration = m_spellInfo->GetDuration();
3368 }
3371 }
3372 }
3373 }
3374}
3375
3377{
3379 return;
3380
3381 uint32 gameobject_id = effectInfo->MiscValue;
3382
3383 GameObject* pGameObj = new GameObject();
3384
3385 WorldObject* target = focusObject;
3386 if (!target)
3387 target = m_caster;
3388
3389 float x, y, z;
3390 if (m_targets.HasDst())
3391 destTarget->GetPosition(x, y, z);
3392 else
3394
3395 Map* map = target->GetMap();
3396
3398 if (!pGameObj->Create(map->GenerateLowGuid<HighGuid::GameObject>(), gameobject_id, map, m_caster->GetPhaseMask(), Position(x, y, z, target->GetOrientation()), rot, 255, GO_STATE_READY))
3399 {
3400 delete pGameObj;
3401 return;
3402 }
3403
3404 int32 duration = m_spellInfo->GetDuration();
3405
3406 pGameObj->SetRespawnTime(duration > 0 ? duration/IN_MILLISECONDS : 0);
3407 pGameObj->SetSpellId(m_spellInfo->Id);
3408
3410
3411 // Wild object not have owner and check clickable by players
3412 map->AddToMap(pGameObj);
3413
3414 if (pGameObj->GetGoType() == GAMEOBJECT_TYPE_FLAGDROP)
3415 if (Player* player = m_caster->ToPlayer())
3416 if (Battleground* bg = player->GetBattleground())
3417 bg->SetDroppedFlagGUID(pGameObj->GetGUID(), player->GetTeam() == ALLIANCE ? TEAM_HORDE: TEAM_ALLIANCE);
3418
3419 if (GameObject* linkedTrap = pGameObj->GetLinkedTrap())
3420 {
3421 linkedTrap->SetRespawnTime(duration > 0 ? duration / IN_MILLISECONDS : 0);
3422 linkedTrap->SetSpellId(m_spellInfo->Id);
3423
3425 }
3426}
3427
3429{
3431 return;
3432
3433 Unit* unitCaster = GetUnitCasterForEffectHandlers();
3434
3438 {
3440 {
3441 switch (m_spellInfo->Id)
3442 {
3443 // Shadow Flame (All script effects, not just end ones to prevent player from dodging the last triggered spell)
3444 case 22539:
3445 case 22972:
3446 case 22975:
3447 case 22976:
3448 case 22977:
3449 case 22978:
3450 case 22979:
3451 case 22980:
3452 case 22981:
3453 case 22982:
3454 case 22983:
3455 case 22984:
3456 case 22985:
3457 {
3458 if (!unitTarget || !unitTarget->IsAlive())
3459 return;
3460
3461 // Onyxia Scale Cloak
3462 if (unitTarget->HasAura(22683))
3463 return;
3464
3465 // Shadow Flame
3466 m_caster->CastSpell(unitTarget, 22682, true);
3467 return;
3468 }
3469 // Mug Transformation
3470 case 41931:
3471 {
3473 return;
3474
3475 uint8 bag = 19;
3476 uint8 slot = 0;
3477 Item* item = nullptr;
3478
3479 while (bag) // 256 = 0 due to var type
3480 {
3481 item = m_caster->ToPlayer()->GetItemByPos(bag, slot);
3482 if (item && item->GetEntry() == 38587)
3483 break;
3484
3485 ++slot;
3486 if (slot == 39)
3487 {
3488 slot = 0;
3489 ++bag;
3490 }
3491 }
3492 if (bag)
3493 {
3494 if (m_caster->ToPlayer()->GetItemByPos(bag, slot)->GetCount() == 1) m_caster->ToPlayer()->RemoveItem(bag, slot, true);
3495 else m_caster->ToPlayer()->GetItemByPos(bag, slot)->SetCount(m_caster->ToPlayer()->GetItemByPos(bag, slot)->GetCount()-1);
3496 // Spell 42518 (Braufest - Gratisprobe des Braufest herstellen)
3497 m_caster->CastSpell(m_caster, 42518, true);
3498 return;
3499 }
3500 break;
3501 }
3502 // Brutallus - Burn
3503 case 45141:
3504 case 45151:
3505 {
3506 //Workaround for Range ... should be global for every ScriptEffect
3507 float radius = effectInfo->CalcRadius();
3509 unitTarget->CastSpell(unitTarget, 46394, true);
3510
3511 break;
3512 }
3513 // Summon Ghouls On Scarlet Crusade
3514 case 51904:
3515 {
3516 if (!m_targets.HasDst())
3517 return;
3518
3519 float radius = effectInfo->CalcRadius();
3520 for (uint8 i = 0; i < 15; ++i)
3521 m_caster->CastSpell(m_caster->GetRandomPoint(*destTarget, radius), 54522, true);
3522 break;
3523 }
3524 case 52173: // Coyote Spirit Despawn
3525 case 60243: // Blood Parrot Despawn
3528 return;
3529 case 57347: // Retrieving (Wintergrasp RP-GG pickup spell)
3530 {
3532 return;
3533
3535
3536 return;
3537 }
3538 case 57349: // Drop RP-GG (Wintergrasp RP-GG at death drop spell)
3539 {
3541 return;
3542
3543 // Delete item from inventory at death
3545
3546 return;
3547 }
3548 case 62482: // Grab Crate
3549 {
3550 if (!unitCaster)
3551 return;
3552
3553 if (unitTarget)
3554 {
3555 if (Unit* seat = unitCaster->GetVehicleBase())
3556 {
3557 if (Unit* parent = seat->GetVehicleBase())
3558 {
3560 unitCaster->CastSpell(parent, 62496, true);
3562 }
3563 }
3564 }
3565 return;
3566 }
3567 }
3568 break;
3569 }
3570 }
3571}
3572
3574{
3576 return;
3577
3578 if (!unitTarget)
3579 return;
3580
3582 {
3583 // stop all pve combat for players outside dungeons, suppress pvp combat
3584 unitTarget->CombatStop(false, false);
3585 }
3586 else
3587 {
3588 // in dungeons (or for nonplayers), reset this unit on all enemies' threat lists
3589 for (auto const& pair : unitTarget->GetThreatManager().GetThreatenedByMeList())
3590 pair.second->ScaleThreat(0.0f);
3591 }
3592
3593 // makes spells cast before this time fizzle
3595}
3596
3598{
3600 return;
3601
3602 if (!unitTarget)
3603 return;
3604
3605 if (damage <= 0)
3606 return;
3607
3609}
3610
3612{
3614 return;
3615
3617 return;
3618
3619 Player* caster = m_caster->ToPlayer();
3620 Player* target = unitTarget->ToPlayer();
3621
3622 // caster or target already have requested duel
3623 if (caster->duel || target->duel || !target->GetSocial() || target->GetSocial()->HasIgnore(caster->GetGUID()))
3624 return;
3625
3626 // Players can only fight a duel in zones with this flag
3627 AreaTableEntry const* casterAreaEntry = sAreaTableStore.LookupEntry(caster->GetAreaId());
3628 if (casterAreaEntry && !(casterAreaEntry->Flags & AREA_FLAG_ALLOW_DUELS))
3629 {
3630 SendCastResult(SPELL_FAILED_NO_DUELING); // Dueling isn't allowed here
3631 return;
3632 }
3633
3634 AreaTableEntry const* targetAreaEntry = sAreaTableStore.LookupEntry(target->GetAreaId());
3635 if (targetAreaEntry && !(targetAreaEntry->Flags & AREA_FLAG_ALLOW_DUELS))
3636 {
3637 SendCastResult(SPELL_FAILED_NO_DUELING); // Dueling isn't allowed here
3638 return;
3639 }
3640
3641 //CREATE DUEL FLAG OBJECT
3642 GameObject* pGameObj = new GameObject;
3643
3644 uint32 gameobject_id = effectInfo->MiscValue;
3645
3646 Position const pos =
3647 {
3648 caster->GetPositionX() + (unitTarget->GetPositionX() - caster->GetPositionX()) / 2,
3649 caster->GetPositionY() + (unitTarget->GetPositionY() - caster->GetPositionY()) / 2,
3650 caster->GetPositionZ(),
3651 caster->GetOrientation()
3652 };
3653
3654 Map* map = caster->GetMap();
3656 if (!pGameObj->Create(map->GenerateLowGuid<HighGuid::GameObject>(), gameobject_id, map, caster->GetPhaseMask(), pos, rot, 0, GO_STATE_READY))
3657 {
3658 delete pGameObj;
3659 return;
3660 }
3661
3662 pGameObj->SetFaction(caster->GetFaction());
3663 pGameObj->SetLevel(caster->GetLevel() + 1);
3664 int32 duration = m_spellInfo->GetDuration();
3665 pGameObj->SetRespawnTime(duration > 0 ? duration/IN_MILLISECONDS : 0);
3666 pGameObj->SetSpellId(m_spellInfo->Id);
3667
3669
3670 caster->AddGameObject(pGameObj);
3671 map->AddToMap(pGameObj);
3672 //END
3673
3674 // Send request
3675 WorldPacket data(SMSG_DUEL_REQUESTED, 8 + 8);
3676 data << pGameObj->GetGUID();
3677 data << caster->GetGUID();
3678 caster->SendDirectMessage(&data);
3679 target->SendDirectMessage(&data);
3680
3681 // create duel-info
3682 bool isMounted = (GetSpellInfo()->Id == 62875);
3683 caster->duel = std::make_unique<DuelInfo>(target, caster, isMounted);
3684 target->duel = std::make_unique<DuelInfo>(caster, caster, isMounted);
3685
3686 caster->SetGuidValue(PLAYER_DUEL_ARBITER, pGameObj->GetGUID());
3687 target->SetGuidValue(PLAYER_DUEL_ARBITER, pGameObj->GetGUID());
3688
3689 sScriptMgr->OnPlayerDuelRequest(target, caster);
3690}
3691
3693{
3695 return;
3696
3697 if (!sWorld->getBoolConfig(CONFIG_CAST_UNSTUCK))
3698 return;
3699
3700 Player* player = m_caster->ToPlayer();
3701 if (!player)
3702 return;
3703
3704 TC_LOG_DEBUG("spells", "Spell Effect: Stuck");
3705 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());
3706
3707 if (player->IsInFlight())
3708 return;
3709
3710 // if player is dead - teleport to graveyard
3711 if (!player->IsAlive())
3712 {
3714 return;
3715
3716 // player is in corpse
3718 player->BuildPlayerRepop();
3719 player->RepopAtGraveyard();
3720 return;
3721 }
3722
3723 // no hearthstone in bag or on cooldown
3724 Item* hearthStone = player->GetItemByEntry(6948 /*Hearthstone*/);
3725 if (!hearthStone || player->GetSpellHistory()->HasCooldown(8690 /*Spell Hearthstone*/))
3726 {
3727 float o = rand_norm() * 2 * M_PI;
3728 Position pos = *player;
3729 player->MovePositionToFirstCollision(pos, 5.0f, o);
3730 player->NearTeleportTo(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), player->GetOrientation());
3731 return;
3732 }
3733
3734 // we have hearthstone not on cooldown, just use it
3736}
3737
3739{
3740 // workaround - this effect should not use target map
3742 return;
3743
3744 Unit* unitCaster = GetUnitCasterForEffectHandlers();
3745 if (!unitCaster)
3746 return;
3747
3749 return;
3750
3752}
3753
3766
3768{
3770 return;
3771
3773 return;
3774
3775 Player* player = m_caster->ToPlayer();
3776 if (!player)
3777 return;
3778
3779 // glyph sockets level requirement
3780 uint8 minLevel = 0;
3781 switch (m_glyphIndex)
3782 {
3783 case 0:
3784 case 1: minLevel = 15; break;
3785 case 2: minLevel = 50; break;
3786 case 3: minLevel = 30; break;
3787 case 4: minLevel = 70; break;
3788 case 5: minLevel = 80; break;
3789 }
3790 if (minLevel && player->GetLevel() < minLevel)
3791 {
3793 return;
3794 }
3795
3796 // apply new one
3797 if (uint32 newGlyph = effectInfo->MiscValue)
3798 {
3799 if (GlyphPropertiesEntry const* newGlyphProperties = sGlyphPropertiesStore.LookupEntry(newGlyph))
3800 {
3801 if (GlyphSlotEntry const* newGlyphSlot = sGlyphSlotStore.LookupEntry(player->GetGlyphSlot(m_glyphIndex)))
3802 {
3803 if (newGlyphProperties->GlyphSlotFlags != newGlyphSlot->Type)
3804 {
3806 return; // glyph slot mismatch
3807 }
3808 }
3809
3810 // remove old glyph
3811 if (uint32 oldGlyph = player->GetGlyph(player->GetActiveTalentGroup(), m_glyphIndex))
3812 {
3813 if (GlyphPropertiesEntry const* oldGlyphProperties = sGlyphPropertiesStore.LookupEntry(oldGlyph))
3814 {
3815 player->RemoveAurasDueToSpell(oldGlyphProperties->SpellID);
3816 player->SetGlyph(m_glyphIndex, 0);
3817 }
3818 }
3819
3820 player->CastSpell(player, newGlyphProperties->SpellID, true);
3821 player->SetGlyph(m_glyphIndex, newGlyph);
3822 player->SendTalentsInfoData(false);
3823 }
3824 }
3825}
3826
3828{
3830 return;
3831
3832 // this is only item spell effect applied to main-hand weapon of target player (players in area)
3834 return;
3835
3836 Player* item_owner = unitTarget->ToPlayer();
3838
3839 if (!item)
3840 return;
3841
3842 // must be equipped
3843 if (!item->IsEquipped())
3844 return;
3845
3846 if (effectInfo->MiscValue)
3847 {
3848 uint32 enchant_id = effectInfo->MiscValue;
3849 int32 duration = m_spellInfo->GetDuration(); // Try duration index first ..
3850 if (!duration)
3851 duration = damage;//+1; // Base points after ..
3852 if (!duration)
3853 duration = 10 * IN_MILLISECONDS; // 10 seconds for enchants which don't have listed duration
3854
3855 if (m_spellInfo->Id == 14792) // Venomhide Poison
3856 duration = 5 * MINUTE * IN_MILLISECONDS;
3857
3858 SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
3859 if (!pEnchant)
3860 return;
3861
3862 // Always go to temp enchantment slot
3864
3865 // Enchantment will not be applied if a different one already exists
3866 if (item->GetEnchantmentId(slot) && item->GetEnchantmentId(slot) != enchant_id)
3867 return;
3868
3869 // Apply the temporary enchantment
3870 item->SetEnchantment(slot, enchant_id, duration, 0, m_caster->GetGUID());
3871 item_owner->ApplyEnchantment(item, slot, true);
3872 }
3873}
3874
3876{
3878 return;
3879
3881 return;
3882
3883 if (Player* caster = m_caster->ToPlayer())
3884 {
3885 caster->UpdateCraftSkill(m_spellInfo->Id);
3886 caster->SendLoot(itemTarget->GetGUID(), LOOT_DISENCHANTING);
3887 }
3888
3889 // item will be removed at disenchanting end
3890}
3891
3893{
3895 return;
3896
3898 return;
3899
3900 Player* player = unitTarget->ToPlayer();
3901 uint8 currentDrunk = player->GetDrunkValue();
3902 int32 drunkMod = damage;
3903
3904 if (drunkMod == 0)
3905 return;
3906
3907 // drunkMod may contain values that are guaranteed to cause uint8 overflow/underflow (examples: 29690, 46874)
3908 // In addition, we would not want currentDrunk to become more than 100.
3909 // So before adding the values, let's check that everything is fine.
3910 if (drunkMod > static_cast<int32>(100 - currentDrunk))
3911 currentDrunk = 100;
3912 else if (drunkMod < static_cast<int32>(0 - currentDrunk))
3913 currentDrunk = 0;
3914 else
3915 currentDrunk += drunkMod; // Due to previous checks we can be sure that currentDrunk will not go beyond [0-100] range.
3916
3917 player->SetDrunkValue(currentDrunk, m_CastItem ? m_CastItem->GetEntry() : 0);
3918
3919 if (currentDrunk == 100 && roll_chance_i(25))
3920 player->CastSpell(player, 67468, false); // Drunken Vomit
3921}
3922
3924{
3926 return;
3927
3928 Player* player = m_caster->ToPlayer();
3929 if (!player)
3930 return;
3931
3932 Item* foodItem = itemTarget;
3933 if (!foodItem)
3934 return;
3935
3936 Pet* pet = player->GetPet();
3937 if (!pet)
3938 return;
3939
3940 if (!pet->IsAlive())
3941 return;
3942
3943 int32 benefit = pet->GetCurrentFoodBenefitLevel(foodItem->GetTemplate()->ItemLevel);
3944 if (benefit <= 0)
3945 return;
3946
3948
3949 uint32 count = 1;
3950 player->DestroyItemCount(foodItem, count, true);
3952
3954 args.AddSpellMod(SPELLVALUE_BASE_POINT0, benefit);
3956}
3957
3959{
3961 return;
3962
3963 if (!unitTarget || !unitTarget->IsPet())
3964 return;
3965
3966 Pet* pet = unitTarget->ToPet();
3967
3970}
3971
3973{
3975 return;
3976
3977 Unit* unitCaster = GetUnitCasterForEffectHandlers();
3978 if (!unitCaster)
3979 return;
3980
3981 uint32 go_id = effectInfo->MiscValue;
3983
3984 ObjectGuid guid = unitCaster->m_ObjectSlot[slot];
3985 if (!guid.IsEmpty())
3986 {
3987 if (GameObject* obj = unitCaster->GetMap()->GetGameObject(guid))
3988 {
3989 // Recast case - null spell id to make auras not be removed on object remove from world
3990 if (m_spellInfo->Id == obj->GetSpellId())
3991 obj->SetSpellId(0);
3992 unitCaster->RemoveGameObject(obj, true);
3993 }
3994 unitCaster->m_ObjectSlot[slot].Clear();
3995 }
3996
3997 GameObject* go = new GameObject();
3998 float x, y, z;
3999 // If dest location if present
4000 if (m_targets.HasDst())
4001 destTarget->GetPosition(x, y, z);
4002 // Summon in random point all other units if location present
4003 else
4004 unitCaster->GetClosePoint(x, y, z, DEFAULT_PLAYER_BOUNDING_RADIUS);
4005
4006 Map* map = unitCaster->GetMap();
4008 if (!go->Create(map->GenerateLowGuid<HighGuid::GameObject>(), go_id, map, unitCaster->GetPhaseMask(), Position(x, y, z, unitCaster->GetOrientation()), rot, 255, GO_STATE_READY))
4009 {
4010 delete go;
4011 return;
4012 }
4013
4014 go->SetFaction(unitCaster->GetFaction());
4015 go->SetLevel(unitCaster->GetLevel());
4016 int32 duration = m_spellInfo->GetDuration();
4017 go->SetRespawnTime(duration > 0 ? duration / IN_MILLISECONDS : 0);
4019 unitCaster->AddGameObject(go);
4020
4022
4023 map->AddToMap(go);
4024
4025 unitCaster->m_ObjectSlot[slot] = go->GetGUID();
4026}
4027
4029{
4031 return;
4032
4033 if (!m_corpseTarget && !unitTarget)
4034 return;
4035
4036 Player* player = nullptr;
4037
4038 if (m_corpseTarget)
4040 else if (unitTarget)
4041 player = unitTarget->ToPlayer();
4042
4043 if (!player || player->IsAlive() || !player->IsInWorld())
4044 return;
4045
4046 if (player->IsResurrectRequested()) // already have one active request
4047 return;
4048
4049 uint32 health = player->CountPctFromMaxHealth(damage);
4051
4053
4054 player->SetResurrectRequestData(m_caster, health, mana, 0);
4055 SendResurrectRequest(player);
4056}
4057
4070
4072{
4074 return;
4075
4077 m_caster->ToPlayer()->SetCanParry(true);
4078}
4079
4081{
4083 return;
4084
4086 m_caster->ToPlayer()->SetCanBlock(true);
4087}
4088
4090{
4092 return;
4093
4094 if (!unitTarget || unitTarget->IsInFlight())
4095 return;
4096
4097 if (!m_targets.HasDst())
4098 return;
4099
4102}
4103
4105{
4107 return;
4108
4110 return;
4111
4112 Player* player = unitTarget->ToPlayer();
4113
4114 int32 repChange = damage;
4115
4116 uint32 factionId = effectInfo->MiscValue;
4117
4118 FactionEntry const* factionEntry = sFactionStore.LookupEntry(factionId);
4119 if (!factionEntry)
4120 return;
4121
4122 repChange = player->CalculateReputationGain(REPUTATION_SOURCE_SPELL, 0, repChange, factionId);
4123
4124 player->GetReputationMgr().ModifyReputation(factionEntry, repChange);
4125}
4126
4128{
4130 return;
4131
4133 return;
4134 Player* player = unitTarget->ToPlayer();
4135
4136 uint32 questId = effectInfo->MiscValue;
4137 if (questId)
4138 {
4139 Quest const* quest = sObjectMgr->GetQuestTemplate(questId);
4140 if (!quest)
4141 return;
4142
4143 uint16 logSlot = player->FindQuestSlot(questId);
4144 if (logSlot < MAX_QUEST_LOG_SIZE)
4145 player->AreaExploredOrEventHappens(questId);
4146 else if (quest->HasFlag(QUEST_FLAGS_TRACKING)) // Check if the quest is used as a serverside flag.
4147 player->SetRewardedQuest(questId); // If so, set status to rewarded without broadcasting it to client.
4148 }
4149}
4150
4152{
4154 return;
4155
4156 Unit* unitCaster = GetUnitCasterForEffectHandlers();
4157 if (!unitCaster)
4158 return;
4159
4160 float dist = unitCaster->GetVisibilityRange();
4161
4162 // clear focus
4163 WorldPacket data(SMSG_BREAK_TARGET, unitCaster->GetPackGUID().size());
4164 data << unitCaster->GetPackGUID();
4165 Trinity::MessageDistDelivererToHostile notifierBreak(unitCaster, &data, dist);
4166 Cell::VisitWorldObjects(unitCaster, notifierBreak, dist);
4167
4168 // and selection
4170 data << unitCaster->GetGUID();
4171 Trinity::MessageDistDelivererToHostile notifierClear(unitCaster, &data, dist);
4172 Cell::VisitWorldObjects(unitCaster, notifierClear, dist);
4173
4174 // we should also force pets to remove us from current target
4175 Unit::AttackerSet attackerSet;
4176 for (Unit::AttackerSet::const_iterator itr = unitCaster->getAttackers().begin(); itr != unitCaster->getAttackers().end(); ++itr)
4177 if ((*itr)->GetTypeId() == TYPEID_UNIT && !(*itr)->CanHaveThreatList())
4178 attackerSet.insert(*itr);
4179
4180 for (Unit::AttackerSet::const_iterator itr = attackerSet.begin(); itr != attackerSet.end(); ++itr)
4181 (*itr)->AttackStop();
4182}
4183
4185{
4187 return;
4188
4189 Player* player = m_caster->ToPlayer();
4190 if (!player || !player->IsInWorld() || player->IsAlive())
4191 return;
4192
4193 uint32 health = 0;
4194 uint32 mana = 0;
4195
4196 // flat case
4197 if (damage < 0)
4198 {
4199 health = uint32(-damage);
4200 mana = effectInfo->MiscValue;
4201 }
4202 // percent case
4203 else
4204 {
4205 health = player->CountPctFromMaxHealth(damage);
4206 if (player->GetMaxPower(POWER_MANA) > 0)
4207 mana = CalculatePct(player->GetMaxPower(POWER_MANA), damage);
4208 }
4209
4210 player->ResurrectPlayer(0.0f);
4211
4212 player->SetHealth(health);
4213 player->SetPower(POWER_MANA, mana);
4214 player->SetPower(POWER_RAGE, 0);
4215 player->SetPower(POWER_ENERGY, player->GetMaxPower(POWER_ENERGY));
4216
4217 player->SpawnCorpseBones();
4218}
4219
4221{
4223 return;
4224
4226 return;
4227
4228 Player* player = m_caster->ToPlayer();
4229 if (!player)
4230 return;
4231
4232 Creature* creature = unitTarget->ToCreature();
4233 int32 targetLevel = creature->GetLevel();
4234
4235 uint32 skill = creature->GetCreatureTemplate()->GetRequiredLootSkill();
4236
4239 player->SendLoot(creature->GetGUID(), LOOT_SKINNING);
4240
4241 int32 const reqValue = targetLevel < 10 ? 0 : (targetLevel < 20 ? (targetLevel - 10) * 10 : targetLevel * 5);
4242 int32 const skillValue = player->GetPureSkillValue(skill);
4243
4244 // Double chances for elites
4245 player->UpdateGatherSkill(skill, skillValue, reqValue, creature->isElite() ? 2 : 1);
4246}
4247
4249{
4250 if (!unitTarget)
4251 return;
4252
4253 Unit* unitCaster = GetUnitCasterForEffectHandlers();
4254 if (!unitCaster)
4255 return;
4256
4258 {
4259 // charge changes fall time
4260 if (unitCaster->GetTypeId() == TYPEID_PLAYER)
4261 unitCaster->ToPlayer()->SetFallInformation(0, unitCaster->GetPositionZ());
4262
4263 float speed = G3D::fuzzyGt(m_spellInfo->Speed, 0.0f) ? m_spellInfo->Speed : SPEED_CHARGE;
4264 // Spell is not using explicit target - no generated path
4265 if (!m_preGeneratedPath)
4266 {
4267 //unitTarget->GetContactPoint(m_caster, pos.m_positionX, pos.m_positionY, pos.m_positionZ);
4269 unitCaster->GetMotionMaster()->MoveCharge(pos.m_positionX, pos.m_positionY, pos.m_positionZ, speed);
4270 }
4271 else
4272 unitCaster->GetMotionMaster()->MoveCharge(*m_preGeneratedPath, speed);
4273 }
4274
4276 {
4277 // not all charge effects used in negative spells
4279 unitCaster->Attack(unitTarget, true);
4280 }
4281}
4282
4284{
4286 return;
4287
4288 Unit* unitCaster = GetUnitCasterForEffectHandlers();
4289 if (!unitCaster)
4290 return;
4291
4292 if (m_targets.HasDst())
4293 {
4295
4296 if (!unitCaster->IsWithinLOS(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ()))
4297 {
4298 float angle = unitCaster->GetRelativeAngle(pos.GetPositionX(), pos.GetPositionY());
4299 float dist = unitCaster->GetDistance(pos);
4300 pos = unitCaster->GetFirstCollisionPosition(dist, angle);
4301 }
4302
4303 unitCaster->GetMotionMaster()->MoveCharge(pos.m_positionX, pos.m_positionY, pos.m_positionZ);
4304 }
4305}
4306
4308{
4310 return;
4311
4312 if (!unitTarget)
4313 return;
4314
4316 if (Creature* creatureTarget = unitTarget->ToCreature())
4317 if (creatureTarget->isWorldBoss() || creatureTarget->IsDungeonBoss())
4318 return;
4319
4320 // Spells with SPELL_EFFECT_KNOCK_BACK (like Thunderstorm) can't knockback target if target has ROOT
4322 return;
4323
4324 float ratio = 0.1f;
4325 float speedxy = float(effectInfo->MiscValue) * ratio;
4326 float speedz = float(damage) * ratio;
4327 if (speedxy < 0.01f && speedz < 0.01f)
4328 return;
4329
4330 float x, y;
4332 {
4333 if (m_targets.HasDst())
4334 destTarget->GetPosition(x, y);
4335 else
4336 return;
4337 }
4338 else //if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_KNOCK_BACK)
4339 m_caster->GetPosition(x, y);
4340
4341 unitTarget->KnockbackFrom(x, y, speedxy, speedz);
4342}
4343
4345{
4347 return;
4348
4349 if (!unitTarget)
4350 return;
4351
4352 float speedxy = effectInfo->MiscValue / 10.f;
4353 float speedz = damage/ 10.f;
4354 //1891: Disengage
4355 unitTarget->JumpTo(speedxy, speedz, m_spellInfo->SpellIconID != 1891);
4356
4357 // changes fall time
4360}
4361
4363{
4365 return;
4366
4368 return;
4369 Player* player = unitTarget->ToPlayer();
4370
4371 uint32 quest_id = effectInfo->MiscValue;
4372
4373 Quest const* quest = sObjectMgr->GetQuestTemplate(quest_id);
4374
4375 if (!quest)
4376 return;
4377
4378 // Player has never done this quest
4379 if (player->GetQuestStatus(quest_id) == QUEST_STATUS_NONE)
4380 return;
4381
4382 // remove all quest entries for 'entry' from quest log
4383 for (uint8 slot = 0; slot < MAX_QUEST_LOG_SIZE; ++slot)
4384 {
4385 uint32 logQuest = player->GetQuestSlotQuestId(slot);
4386 if (logQuest == quest_id)
4387 {
4388 player->SetQuestSlot(slot, 0);
4389
4390 // we ignore unequippable quest items in this case, it's still be equipped
4391 player->TakeQuestSourceItem(logQuest, false);
4392
4393 if (quest->HasFlag(QUEST_FLAGS_FLAGS_PVP))
4394 {
4395 player->pvpInfo.IsHostile = player->pvpInfo.IsInHostileArea || player->HasPvPForcingQuest();
4396 player->UpdatePvPState();
4397 }
4398 }
4399 }
4400
4401 player->RemoveActiveQuest(quest_id, false);
4402 player->RemoveRewardedQuest(quest_id);
4403
4404 sScriptMgr->OnQuestStatusChange(player, quest_id);
4405}
4406
4417
4419{
4421 return;
4422
4423 if (!unitTarget)
4424 return;
4425
4427
4428 // This is a blizzlike mistake: this should be 2D distance according to projectile motion formulas, but Blizzard erroneously used 3D distance.
4429 float distXY = unitTarget->GetExactDist(pos);
4430
4431 // Avoid division by 0
4432 if (distXY < 0.001)
4433 return;
4434
4435 float distZ = pos.GetPositionZ() - unitTarget->GetPositionZ();
4436 float speedXY = effectInfo->MiscValue ? effectInfo->MiscValue / 10.0f : 30.0f;
4437 float speedZ = (2 * speedXY * speedXY * distZ + Movement::gravity * distXY * distXY) / (2 * speedXY * distXY);
4438
4439 if (!std::isfinite(speedZ))
4440 {
4441 TC_LOG_ERROR("spells", "Spell {} with SPELL_EFFECT_PULL_TOWARDS called with invalid speedZ. {}", m_spellInfo->Id, GetDebugInfo());
4442 return;
4443 }
4444
4445 unitTarget->JumpTo(speedXY, speedZ, true, pos);
4446}
4447
4449{
4451 return;
4452
4453 if (!unitTarget)
4454 return;
4455
4456 if (!m_targets.HasDst())
4457 {
4458 TC_LOG_ERROR("spells", "Spell {} with SPELL_EFFECT_PULL_TOWARDS_DEST has no dest target", m_spellInfo->Id);
4459 return;
4460 }
4461
4462 Position const* pos = m_targets.GetDstPos();
4463 // This is a blizzlike mistake: this should be 2D distance according to projectile motion formulas, but Blizzard erroneously used 3D distance
4464 float distXY = unitTarget->GetExactDist(pos);
4465
4466 // Avoid division by 0
4467 if (distXY < 0.001)
4468 return;
4469
4470 float distZ = pos->GetPositionZ() - unitTarget->GetPositionZ();
4471
4472 float speedXY = effectInfo->MiscValue ? effectInfo->MiscValue / 10.0f : 30.0f;
4473 float speedZ = (2 * speedXY * speedXY * distZ + Movement::gravity * distXY * distXY) / (2 * speedXY * distXY);
4474
4475 if (!std::isfinite(speedZ))
4476 {
4477 TC_LOG_ERROR("spells", "Spell {} with SPELL_EFFECT_PULL_TOWARDS_DEST called with invalid speedZ. {}", m_spellInfo->Id, GetDebugInfo());
4478 return;
4479 }
4480
4481 unitTarget->JumpTo(speedXY, speedZ, true, *pos);
4482}
4483
4485{
4487 return;
4488
4489 if (!unitTarget)
4490 return;
4491
4492 uint32 mechanic = effectInfo->MiscValue;
4493 DispelList dispel_list;
4494 Unit::AuraMap const& auras = unitTarget->GetOwnedAuras();
4495 for (Unit::AuraMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
4496 {
4497 Aura* aura = itr->second;
4499 continue;
4501 if ((aura->GetSpellInfo()->GetAllEffectsMechanicMask() & (1 << mechanic)))
4502 dispel_list.emplace_back(aura->GetId(), aura->GetCasterGUID());
4503 }
4504
4505 for (auto itr = dispel_list.begin(); itr != dispel_list.end(); ++itr)
4506 unitTarget->RemoveAura(itr->first, itr->second, 0, AURA_REMOVE_BY_ENEMY_SPELL);
4507}
4508
4510{
4512 return;
4513
4514 if (damage < 0)
4515 return;
4516
4517 Player* player = m_caster->ToPlayer();
4518 if (!player)
4519 return;
4520
4521 // Maybe player dismissed dead pet or pet despawned?
4522 bool hadPet = true;
4523
4524 if (!player->GetPet())
4525 {
4526 // Position passed to SummonPet is irrelevant with current implementation,
4527 // pet will be relocated without using these coords in Pet::LoadPetFromDB
4528 player->SummonPet(0, 0.0f, 0.0f, 0.0f, 0.0f, SUMMON_PET, 0);
4529 hadPet = false;
4530 }
4531
4532 // TODO: Better to fail Hunter's "Revive Pet" at cast instead of here when casting ends
4533 Pet* pet = player->GetPet(); // Attempt to get current pet
4534 if (!pet || pet->IsAlive())
4535 return;
4536
4537 // If player did have a pet before reviving, teleport it
4538 if (hadPet)
4539 {
4540 // Reposition the pet's corpse before reviving so as not to grab aggro
4541 // We can use a different, more accurate version of GetClosePoint() since we have a pet
4542 float x, y, z; // Will be used later to reposition the pet if we have one
4543 player->GetClosePoint(x, y, z, pet->GetCombatReach(), PET_FOLLOW_DIST, pet->GetFollowAngle());
4544 pet->NearTeleportTo(x, y, z, player->GetOrientation());
4545 pet->Relocate(x, y, z, player->GetOrientation()); // This is needed so SaveStayPosition() will get the proper coords.
4546 }
4547
4550 pet->setDeathState(ALIVE);
4553
4554 // Reset things for when the AI to takes over
4555 CharmInfo *ci = pet->GetCharmInfo();
4556 if (ci)
4557 {
4558 // In case the pet was at stay, we don't want it running back
4559 ci->SaveStayPosition();
4561
4562 ci->SetIsFollowing(false);
4563 ci->SetIsCommandAttack(false);
4564 ci->SetIsCommandFollow(false);
4565 ci->SetIsReturning(false);
4566 }
4567
4569}
4570
4572{
4574 return;
4575
4576 Unit* unitCaster = GetUnitCasterForEffectHandlers();
4577 if (!unitCaster)
4578 return;
4579
4580 int32 mana = 0;
4581 for (uint8 slot = SUMMON_SLOT_TOTEM_FIRE; slot < MAX_TOTEM_SLOT; ++slot)
4582 {
4583 if (!unitCaster->m_SummonSlot[slot])
4584 continue;
4585
4586 Creature* totem = unitCaster->GetMap()->GetCreature(unitCaster->m_SummonSlot[slot]);
4587 if (totem && totem->IsTotem())
4588 {
4589 uint32 spell_id = totem->GetUInt32Value(UNIT_CREATED_BY_SPELL);
4590 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell_id);
4591 if (spellInfo)
4592 {
4593 mana += spellInfo->ManaCost;
4594 mana += int32(CalculatePct(unitCaster->GetCreateMana(), spellInfo->ManaCostPercentage));
4595 }
4596 totem->ToTotem()->UnSummon();
4597 }
4598 }
4599 ApplyPct(mana, damage);
4600 if (mana)
4601 {
4604 unitCaster->CastSpell(unitCaster, 39104, args);
4605 }
4606}
4607
4609{
4611 return;
4612
4614 return;
4615
4616 int32 slot = effectInfo->MiscValue;
4617
4618 // -1 means all player equipped items and -2 all items
4619 if (slot < 0)
4620 {
4623 return;
4624 }
4625
4626 // invalid slot value
4627 if (slot >= INVENTORY_SLOT_BAG_END)
4628 return;
4629
4631 {
4634 }
4635}
4636
4638{
4640 return;
4641
4643 return;
4644
4645 int32 slot = effectInfo->MiscValue;
4646
4647 // FIXME: some spells effects have value -1/-2
4648 // Possibly its mean -1 all player equipped items and -2 all items
4649 if (slot < 0)
4650 {
4651 unitTarget->ToPlayer()->DurabilityLossAll(float(damage) / 100.0f, (slot < -1));
4652 return;
4653 }
4654
4655 // invalid slot value
4656 if (slot >= INVENTORY_SLOT_BAG_END)
4657 return;
4658
4659 if (damage <= 0)
4660 return;
4661
4663 unitTarget->ToPlayer()->DurabilityLoss(item, float(damage) / 100.0f);
4664}
4665
4667{
4669 return;
4670
4671 Unit* unitCaster = GetUnitCasterForEffectHandlers();
4672 if (!unitCaster || !unitTarget)
4673 return;
4674
4676}
4677
4679{
4681 return;
4682
4683 Unit* unitCaster = GetUnitCasterForEffectHandlers();
4684 if (!unitCaster)
4685 return;
4686
4687 uint32 name_id = effectInfo->MiscValue;
4688 GameObjectTemplate const* goinfo = sObjectMgr->GetGameObjectTemplate(name_id);
4689 if (!goinfo)
4690 {
4691 TC_LOG_ERROR("sql.sql", "Gameobject (Entry: {}) does not exist and is not created by spell (ID: {}) cast.", name_id, m_spellInfo->Id);
4692 return;
4693 }
4694
4695 float fx, fy, fz;
4696
4697 if (m_targets.HasDst())
4698 destTarget->GetPosition(fx, fy, fz);
4699 //FIXME: this can be better check for most objects but still hack
4700 else if (effectInfo->HasRadius() && m_spellInfo->Speed == 0)
4701 {
4702 float dis = effectInfo->CalcRadius(unitCaster);
4703 unitCaster->GetClosePoint(fx, fy, fz, DEFAULT_PLAYER_BOUNDING_RADIUS, dis);
4704 }
4705 else
4706 {
4707 //GO is always friendly to it's creator, get range for friends
4708 float min_dis = m_spellInfo->GetMinRange(true);
4709 float max_dis = m_spellInfo->GetMaxRange(true);
4710 float dis = (float)rand_norm() * (max_dis - min_dis) + min_dis;
4711
4712 unitCaster->GetClosePoint(fx, fy, fz, DEFAULT_PLAYER_BOUNDING_RADIUS, dis);
4713 }
4714
4715 Map* cMap = unitCaster->GetMap();
4716 // if gameobject is summoning object, it should be spawned right on caster's position
4717 if (goinfo->type == GAMEOBJECT_TYPE_RITUAL)
4718 unitCaster->GetPosition(fx, fy, fz);
4719
4720 GameObject* pGameObj = new GameObject;
4721
4722 Position pos = { fx, fy, fz, unitCaster->GetOrientation() };
4724 if (!pGameObj->Create(cMap->GenerateLowGuid<HighGuid::GameObject>(), name_id, cMap, unitCaster->GetPhaseMask(), pos, rot, 255, GO_STATE_READY))
4725 {
4726 delete pGameObj;
4727 return;
4728 }
4729
4730 int32 duration = m_spellInfo->GetDuration();
4731 switch (goinfo->type)
4732 {
4734 {
4735 unitCaster->SetChannelObjectGuid(pGameObj->GetGUID());
4736 unitCaster->AddGameObject(pGameObj); // will removed at spell cancel
4737
4738 // end time of range when possible catch fish (FISHING_BOBBER_READY_TIME..GetDuration(m_spellInfo))
4739 // start time == fish-FISHING_BOBBER_READY_TIME (0..GetDuration(m_spellInfo)-FISHING_BOBBER_READY_TIME)
4740 int32 lastSec = 0;
4741 switch (urand(0, 2))
4742 {
4743 case 0: lastSec = 3; break;
4744 case 1: lastSec = 7; break;
4745 case 2: lastSec = 13; break;
4746 }
4747
4748 // Duration of the fishing bobber can't be higher than the Fishing channeling duration
4749 duration = std::min(duration, duration - lastSec*IN_MILLISECONDS + FISHING_BOBBER_READY_TIME*IN_MILLISECONDS);
4750 break;
4751 }
4753 {
4754 if (unitCaster->GetTypeId() == TYPEID_PLAYER)
4755 {
4756 pGameObj->AddUniqueUse(unitCaster->ToPlayer());
4757 unitCaster->AddGameObject(pGameObj); // will be removed at spell cancel
4758 }
4759 break;
4760 }
4761 case GAMEOBJECT_TYPE_DUEL_ARBITER: // 52991
4762 unitCaster->AddGameObject(pGameObj);
4763 break;
4766 default:
4767 break;
4768 }
4769
4770 pGameObj->SetRespawnTime(duration > 0 ? duration/IN_MILLISECONDS : 0);
4771
4772 pGameObj->SetOwnerGUID(unitCaster->GetGUID());
4773
4774 //pGameObj->SetUInt32Value(GAMEOBJECT_LEVEL, unitCaster->GetLevel());
4775 pGameObj->SetSpellId(m_spellInfo->Id);
4776
4778
4779 TC_LOG_DEBUG("spells", "AddObject at SpellEfects.cpp EffectTransmitted");
4780 //unitCaster->AddGameObject(pGameObj);
4781 //m_ObjToDel.push_back(pGameObj);
4782
4783 cMap->AddToMap(pGameObj);
4784
4785 if (GameObject* linkedTrap = pGameObj->GetLinkedTrap())
4786 {
4787 linkedTrap->SetRespawnTime(duration > 0 ? duration/IN_MILLISECONDS : 0);
4788 //linkedTrap->SetUInt32Value(GAMEOBJECT_LEVEL, unitCaster->GetLevel());
4789 linkedTrap->SetSpellId(m_spellInfo->Id);
4790 linkedTrap->SetOwnerGUID(unitCaster->GetGUID());
4791
4793 }
4794}
4795
4797{
4799 return;
4800
4801 Player* player = m_caster->ToPlayer();
4802 if (!player)
4803 return;
4804
4806 return;
4807
4808 if (itemTarget->GetCount() < 5)
4809 return;
4810
4811 if (sWorld->getBoolConfig(CONFIG_SKILL_PROSPECTING))
4812 {
4813 uint32 SkillValue = player->GetPureSkillValue(SKILL_JEWELCRAFTING);
4814 uint32 reqSkillValue = itemTarget->GetTemplate()->RequiredSkillRank;
4815 player->UpdateGatherSkill(SKILL_JEWELCRAFTING, SkillValue, reqSkillValue);
4816 }
4817
4819}
4820
4822{
4824 return;
4825
4826 Player* player = m_caster->ToPlayer();
4827 if (!player)
4828 return;
4829
4831 return;
4832
4833 if (itemTarget->GetCount() < 5)
4834 return;
4835
4836 if (sWorld->getBoolConfig(CONFIG_SKILL_MILLING))
4837 {
4838 uint32 SkillValue = player->GetPureSkillValue(SKILL_INSCRIPTION);
4839 uint32 reqSkillValue = itemTarget->GetTemplate()->RequiredSkillRank;
4840 player->UpdateGatherSkill(SKILL_INSCRIPTION, SkillValue, reqSkillValue);
4841 }
4842
4844}
4845
4847{
4849 return;
4850
4851 TC_LOG_DEBUG("spells", "WORLD: SkillEFFECT");
4852}
4853
4854/* There is currently no need for this effect. We handle it in Battleground.cpp
4855 If we would handle the resurrection here, the spiritguide would instantly disappear as the
4856 player revives, and so we wouldn't see the spirit heal visual effect on the npc.
4857 This is why we use a half sec delay between the visual effect and the resurrection itself */
4859{
4861 return;
4862
4863 /*
4864 if (unitTarget->GetTypeId() != TYPEID_PLAYER)
4865 return;
4866 if (!unitTarget->IsInWorld())
4867 return;
4868
4869 //m_spellInfo->Effects[i].BasePoints; == 99 (percent?)
4870 //unitTarget->ToPlayer()->setResurrect(m_caster->GetGUID(), unitTarget->GetPositionX(), unitTarget->GetPositionY(), unitTarget->GetPositionZ(), unitTarget->GetMaxHealth(), unitTarget->GetMaxPower(POWER_MANA));
4871 unitTarget->ToPlayer()->ResurrectPlayer(1.0f);
4872 unitTarget->ToPlayer()->SpawnCorpseBones();
4873 */
4874}
4875
4876// remove insignia spell effect
4878{
4880 return;
4881
4882 TC_LOG_DEBUG("spells", "Effect: SkinPlayerCorpse");
4883
4884 Player* player = m_caster->ToPlayer();
4885
4886 Player* target = nullptr;
4887 if (unitTarget)
4888 target = unitTarget->ToPlayer();
4889 else if (m_corpseTarget)
4891
4892 if (!player || !target || target->IsAlive())
4893 return;
4894
4895 target->RemovedInsignia(player);
4896}
4897
4899{
4901 return;
4902
4903 TC_LOG_DEBUG("spells", "Effect: StealBeneficialBuff");
4904
4905 if (!unitTarget || unitTarget == m_caster) // can't steal from self
4906 return;
4907
4908 DispelChargesList stealList;
4909
4910 // Create dispel mask by dispel type
4912 Unit::AuraMap const& auras = unitTarget->GetOwnedAuras();
4913 for (Unit::AuraMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
4914 {
4915 Aura* aura = itr->second;
4916 AuraApplication const* aurApp = aura->GetApplicationOfTarget(unitTarget->GetGUID());
4917 if (!aurApp)
4918 continue;
4919
4920 if ((aura->GetSpellInfo()->GetDispelMask()) & dispelMask)
4921 {
4922 // Need check for passive? this
4923 if (!aurApp->IsPositive() || aura->IsPassive() || aura->GetSpellInfo()->HasAttribute(SPELL_ATTR4_NOT_STEALABLE))
4924 continue;
4925
4926 // 2.4.3 Patch Notes: "Dispel effects will no longer attempt to remove effects that have 100% dispel resistance."
4928 if (!chance)
4929 continue;
4930
4931 // The charges / stack amounts don't count towards the total number of auras that can be dispelled.
4932 // Ie: A dispel on a target with 5 stacks of Winters Chill and a Polymorph has 1 / (1 + 1) -> 50% chance to dispell
4933 // Polymorph instead of 1 / (5 + 1) -> 16%.
4934 bool dispelCharges = aura->GetSpellInfo()->HasAttribute(SPELL_ATTR7_DISPEL_CHARGES);
4935 uint8 charges = dispelCharges ? aura->GetCharges() : aura->GetStackAmount();
4936 if (charges > 0)
4937 stealList.emplace_back(aura, chance, charges);
4938 }
4939 }
4940
4941 if (stealList.empty())
4942 return;
4943
4944 size_t remaining = stealList.size();
4945
4946 // Ok if exist some buffs for dispel try dispel it
4947 uint32 failCount = 0;
4948 DispelList successList;
4949 successList.reserve(damage);
4950
4951 WorldPacket dataFail(SMSG_DISPEL_FAILED, 8 + 8 + 4 + 4 + damage * 4);
4952 // dispel N = damage buffs (or while exist buffs for dispel)
4953 for (int32 count = 0; count < damage && remaining > 0;)
4954 {
4955 // Random select buff for dispel
4956 DispelChargesList::iterator itr = stealList.begin();
4957 std::advance(itr, urand(0, remaining - 1));
4958
4959 if (itr->RollDispel())
4960 {
4961 successList.emplace_back(itr->GetAura()->GetId(), itr->GetAura()->GetCasterGUID());
4962 if (!itr->DecrementCharge())
4963 {
4964 --remaining;
4965 std::swap(*itr, stealList[remaining]);
4966 }
4967 }
4968 else
4969 {
4970 if (!failCount)
4971 {
4972 // Failed to dispell
4973 dataFail << m_caster->GetGUID(); // Caster GUID
4974 dataFail << unitTarget->GetGUID(); // Victim GUID
4975 dataFail << uint32(m_spellInfo->Id); // dispel spell id
4976 }
4977 ++failCount;
4978 dataFail << uint32(itr->GetAura()->GetId()); // Spell Id
4979 }
4980 ++count;
4981 }
4982
4983 if (failCount)
4984 m_caster->SendMessageToSet(&dataFail, true);
4985
4986 if (successList.empty())
4987 return;
4988
4989 WorldPacket dataSuccess(SMSG_SPELLSTEALLOG, 8 + 8 + 4 + 1 + 4 + damage * 5);
4990 dataSuccess << unitTarget->GetPackGUID(); // Victim GUID
4991 dataSuccess << m_caster->GetPackGUID(); // Caster GUID
4992 dataSuccess << uint32(m_spellInfo->Id); // dispel spell id
4993 dataSuccess << uint8(0); // not used
4994 dataSuccess << uint32(successList.size()); // count
4995 for (auto itr = successList.begin(); itr != successList.end(); ++itr)
4996 {
4997 dataSuccess << uint32(itr->first); // Spell Id
4998 dataSuccess << uint8(0); // 0 - steals !=0 transfers
4999 unitTarget->RemoveAurasDueToSpellBySteal(itr->first, itr->second, m_caster);
5000 }
5001 m_caster->SendMessageToSet(&dataSuccess, true);
5002}
5003
5014
5016{
5018 return;
5019
5021 return;
5022
5023 int32 creatureEntry = effectInfo->MiscValue;
5024 if (!creatureEntry)
5025 {
5026 if (m_spellInfo->Id == 42793) // Burn Body
5027 creatureEntry = 24008; // Fallen Combatant
5028 }
5029
5030 if (creatureEntry)
5032}
5033
5035{
5037 return;
5038
5040 return;
5041
5043}
5044
5046{
5048 return;
5049
5050 if (!unitTarget)
5051 return;
5052
5053 Player* player = unitTarget->ToPlayer();
5054 if (!player)
5055 return;
5056
5057 if (Quest const* quest = sObjectMgr->GetQuestTemplate(effectInfo->MiscValue))
5058 {
5059 if (!player->CanTakeQuest(quest, false))
5060 return;
5061
5062 if (quest->IsAutoAccept() && player->CanAddQuest(quest, false))
5063 player->AddQuestAndCheckCompletion(quest, player);
5064
5065 player->PlayerTalkClass->SendQuestGiverQuestDetails(quest, player->GetGUID(), true);
5066 }
5067}
5068
5070{
5072 return;
5073
5075 return;
5076
5077 Player* player = m_caster->ToPlayer();
5078
5079 if (player->GetClass() != CLASS_DEATH_KNIGHT)
5080 return;
5081
5082 // needed later
5084
5085 uint32 count = damage;
5086 if (count == 0)
5087 count = 1;
5088
5089 for (uint32 j = 0; j < MAX_RUNES && count > 0; ++j)
5090 {
5091 if (player->GetRuneCooldown(j) && player->GetCurrentRune(j) == RuneType(effectInfo->MiscValue))
5092 {
5093 player->SetRuneCooldown(j, 0);
5094 --count;
5095 }
5096 }
5097
5098 // Empower rune weapon
5099 if (m_spellInfo->Id == 47568)
5100 {
5101 // Need to do this just once
5103 return;
5104
5105 for (uint32 i = 0; i < MAX_RUNES; ++i)
5106 {
5107 if (player->GetRuneCooldown(i) && (player->GetBaseRune(i) == RUNE_FROST))
5108 player->SetRuneCooldown(i, 0);
5109 }
5110 }
5111}
5112
5114{
5116 return;
5117
5119 return;
5120
5121 uint32 creatureEntry = effectInfo->MiscValue;
5122 Pet* pet = unitTarget->CreateTamedPetFrom(creatureEntry, m_spellInfo->Id);
5123 if (!pet)
5124 return;
5125
5126 // relocate
5127 float px, py, pz;
5129 pet->Relocate(px, py, pz, unitTarget->GetOrientation());
5130
5131 // add to world
5132 pet->GetMap()->AddToMap(pet->ToCreature());
5133
5134 // unitTarget has pet now
5135 unitTarget->SetMinion(pet, true);
5136
5137 pet->InitTalentForLevel();
5138
5140 {
5143 }
5144}
5145
5147{
5149 return;
5150
5152 return;
5153 uint32 nodeid = effectInfo->MiscValue;
5154 if (sTaxiNodesStore.LookupEntry(nodeid))
5156}
5157
5166
5168{
5170 return;
5171
5172 Unit* unitCaster = GetUnitCasterForEffectHandlers();
5173 if (!unitCaster)
5174 return;
5175
5176 if (unitTarget)
5178}
5179
5181{
5183 return;
5184
5185 if (!gameObjTarget)
5186 return;
5187
5188 FactionTemplateEntry const* casterFaction = m_caster->GetFactionTemplateEntry();
5189 FactionTemplateEntry const* targetFaction = sFactionTemplateStore.LookupEntry(gameObjTarget->GetFaction());
5190 // Do not allow to damage GO's of friendly factions (ie: Wintergrasp Walls/Ulduar Storm Beacons)
5191 if (!targetFaction || (casterFaction && !casterFaction->IsFriendlyTo(*targetFaction)))
5193}
5194
5196{
5198 return;
5199
5200 if (!gameObjTarget)
5201 return;
5202
5204}
5205
5216
5217void Spell::SummonGuardian(SpellEffectInfo const& spellEffectInfo, uint32 entry, SummonPropertiesEntry const* properties, uint32 numGuardians)
5218{
5219 Unit* unitCaster = GetUnitCasterForEffectHandlers();
5220 if (!unitCaster)
5221 return;
5222
5223 if (unitCaster->IsTotem())
5224 unitCaster = unitCaster->ToTotem()->GetOwner();
5225
5226 // in another case summon new
5227 uint8 level = unitCaster->GetLevel();
5228
5229 // level of pet summoned using engineering item based at engineering skill level
5230 if (m_CastItem && unitCaster->GetTypeId() == TYPEID_PLAYER)
5231 if (ItemTemplate const* proto = m_CastItem->GetTemplate())
5232 if (proto->RequiredSkill == SKILL_ENGINEERING)
5233 if (uint16 skill202 = unitCaster->ToPlayer()->GetSkillValue(SKILL_ENGINEERING))
5234 level = skill202 / 5;
5235
5236 float radius = 5.0f;
5237 int32 duration = m_spellInfo->GetDuration();
5238
5239 if (Player* modOwner = unitCaster->GetSpellModOwner())
5240 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DURATION, duration);
5241
5242 //TempSummonType summonType = (duration == 0) ? TEMPSUMMON_DEAD_DESPAWN : TEMPSUMMON_TIMED_DESPAWN;
5243 Map* map = unitCaster->GetMap();
5244 for (uint32 count = 0; count < numGuardians; ++count)
5245 {
5246 Position pos;
5247 if (count == 0)
5248 pos = *destTarget;
5249 else
5250 // randomize position for multiple summons
5251 pos = unitCaster->GetRandomPoint(*destTarget, radius);
5252
5253 TempSummon* summon = map->SummonCreature(entry, pos, properties, duration, unitCaster, m_spellInfo->Id);
5254 if (!summon)
5255 return;
5256
5258 ((Guardian*)summon)->InitStatsForLevel(level);
5259
5260 if (properties && properties->Control == SUMMON_CATEGORY_ALLY)
5261 summon->SetFaction(unitCaster->GetFaction());
5262
5264 ((Minion*)summon)->SetFollowAngle(unitCaster->GetAbsoluteAngle(summon));
5265
5266 if (summon->GetEntry() == 27893)
5267 {
5268 if (uint32 weapon = unitCaster->GetUInt32Value(PLAYER_VISIBLE_ITEM_16_ENTRYID))
5269 {
5270 summon->SetDisplayId(11686); // modelid2
5271 summon->SetVirtualItem(0, weapon);
5272 }
5273 else
5274 summon->SetDisplayId(1126); // modelid1
5275 }
5276
5277 ExecuteLogEffectSummonObject(spellEffectInfo.EffectIndex, summon);
5278 }
5279}
5280
5282{
5284 return;
5285
5287 !unitTarget->IsPet() || ((Pet*)unitTarget)->getPetType() != HUNTER_PET)
5288 return;
5289
5291}
5292
5294{
5296 return;
5297
5299 return;
5300
5301 uint32 soundid = effectInfo->MiscValue;
5302
5303 if (!sSoundEntriesStore.LookupEntry(soundid))
5304 {
5305 TC_LOG_ERROR("spells", "EffectPlayMusic: Sound (Id: {}) does not exist in spell {}.", soundid, m_spellInfo->Id);
5306 return;
5307 }
5308
5310}
5311
5313{
5315 return;
5316
5318 return;
5319
5321}
5322
5324{
5326 return;
5327
5329 return;
5330
5331 unitTarget->ToPlayer()->ActivateTalentGroup(damage-1); // damage is 1 or 2, spec is 0 or 1
5332}
5333
5335{
5337 return;
5338
5339 if (!unitTarget)
5340 return;
5341
5342 Player* player = unitTarget->ToPlayer();
5343 if (!player)
5344 return;
5345
5346 switch (m_spellInfo->Id)
5347 {
5348 case 58730: // Restricted Flight Area
5349 case 58600: // Restricted Flight Area
5351 break;
5352 default:
5353 break;
5354 }
5355
5356 uint32 soundId = effectInfo->MiscValue;
5357
5358 if (!sSoundEntriesStore.LookupEntry(soundId))
5359 {
5360 TC_LOG_ERROR("spells", "EffectPlaySound: Sound (Id: {}) does not exist in spell {}.", soundId, m_spellInfo->Id);
5361 return;
5362 }
5363
5364 player->PlayDirectSound(soundId, player);
5365}
5366
5368{
5370 return;
5371
5372 if (!unitTarget)
5373 return;
5374 // there may be need of specifying casterguid of removed auras
5376}
5377
5379{
5381 return;
5382
5383 Player* player = m_caster->ToPlayer();
5384 if (!player)
5385 return;
5386
5387 uint32 button_id = effectInfo->MiscValue + 132;
5388 uint32 n_buttons = effectInfo->MiscValueB;
5389
5390 for (; n_buttons; --n_buttons, ++button_id)
5391 {
5392 ActionButton const* ab = player->GetActionButton(button_id);
5393 if (!ab || ab->GetType() != ACTION_BUTTON_SPELL)
5394 continue;
5395
5398 uint32 spell_id = ab->GetAction();
5399 if (!spell_id)
5400 continue;
5401
5402 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell_id);
5403 if (!spellInfo)
5404 continue;
5405
5406 if (!player->HasSpell(spell_id) || player->GetSpellHistory()->HasCooldown(spell_id))
5407 continue;
5408
5410 continue;
5411
5412 uint32 cost = spellInfo->CalcPowerCost(player, spellInfo->GetSchoolMask());
5413 if (player->GetPower(POWER_MANA) < cost)
5414 continue;
5415
5416 CastSpellExtraArgs args;
5418 m_caster->CastSpell(m_caster, spellInfo->Id, args);
5419 }
5420}
5421
5423{
5425 return;
5426
5428 return;
5429
5430 Player* player = m_caster->ToPlayer();
5431
5432 if (!player)
5433 return;
5434
5435 uint32 item_id = effectInfo->ItemType;
5436
5437 ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(item_id);
5438 if (!pProto)
5439 {
5440 player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, nullptr, nullptr);
5441 return;
5442 }
5443
5444 if (Item* pItem = player->GetItemByEntry(item_id))
5445 {
5446 for (int x = 0; x < MAX_ITEM_PROTO_SPELLS; ++x)
5447 pItem->SetSpellCharges(x, pProto->Effects[x].Charges);
5448 pItem->SetState(ITEM_CHANGED, player);
5449 }
5450}
5451
5453{
5455 return;
5456
5458 return;
5459
5460 Player* player = unitTarget->ToPlayer();
5461
5462 WorldLocation homeLoc;
5463 uint32 areaId = player->GetAreaId();
5464
5465 if (effectInfo->MiscValue)
5466 areaId = effectInfo->MiscValue;
5467
5468 if (m_targets.HasDst())
5469 homeLoc.WorldRelocate(*destTarget);
5470 else
5471 homeLoc = player->GetWorldLocation();
5472
5473 player->SetHomebind(homeLoc, areaId);
5474 player->SendBindPointUpdate();
5475
5476 TC_LOG_DEBUG("spells", "EffectBind: New homebind X: {}, Y: {}, Z: {}, MapId: {}, AreaId: {}",
5477 homeLoc.GetPositionX(), homeLoc.GetPositionY(), homeLoc.GetPositionZ(), homeLoc.GetMapId(), areaId);
5478
5479 // zone update
5481 player->SendDirectMessage(packet.Write());
5482}
5483
@ SPELL_WS_MARK_WINNER
@ SPELL_AV_MARK_LOSER
@ SPELL_WS_MARK_LOSER
@ SPELL_AB_MARK_LOSER
@ SPELL_AB_MARK_WINNER
@ SPELL_AV_MARK_WINNER
@ IN_MILLISECONDS
Definition Common.h:35
@ MINUTE
Definition Common.h:29
#define M_PI
Definition Common.h:72
@ ITEM_ENCHANTMENT_TYPE_PRISMATIC_SOCKET
Definition DBCEnums.h:363
#define MAX_EFFECT_MASK
Definition DBCEnums.h:389
@ SUMMON_PROP_FLAG_PERSONAL_SPAWN
Definition DBCEnums.h:418
@ AREA_FLAG_ALLOW_DUELS
Definition DBCEnums.h:253
#define MAX_SPELL_EFFECTS
Definition DBCEnums.h:388
DBCStorage< SpellItemEnchantmentEntry > sSpellItemEnchantmentStore(SpellItemEnchantmentfmt)
DBCStorage< FactionEntry > sFactionStore(FactionEntryfmt)
SkillRaceClassInfoEntry const * GetSkillRaceClassInfo(uint32 skill, uint8 race, uint8 class_)
DBCStorage< GlyphSlotEntry > sGlyphSlotStore(GlyphSlotfmt)
DBCStorage< SummonPropertiesEntry > sSummonPropertiesStore(SummonPropertiesfmt)
DBCStorage< SkillTiersEntry > sSkillTiersStore(SkillTiersfmt)
DBCStorage< SoundEntriesEntry > sSoundEntriesStore(SoundEntriesfmt)
DBCStorage< FactionTemplateEntry > sFactionTemplateStore(FactionTemplateEntryfmt)
DBCStorage< TaxiNodesEntry > sTaxiNodesStore(TaxiNodesEntryfmt)
DBCStorage< GlyphPropertiesEntry > sGlyphPropertiesStore(GlyphPropertiesfmt)
DBCStorage< AreaTableEntry > sAreaTableStore(AreaTableEntryfmt)
#define MAX_VEHICLE_SEATS
#define MAX_ITEM_ENCHANTMENT_EFFECTS
uint8_t uint8
Definition Define.h:135
int64_t int64
Definition Define.h:128
int8_t int8
Definition Define.h:131
int32_t int32
Definition Define.h:129
uint16_t uint16
Definition Define.h:134
uint32_t uint32
Definition Define.h:133
std::chrono::milliseconds Milliseconds
Milliseconds shorthand typedef.
Definition Duration.h:24
@ DYNAMIC_OBJECT_FARSIGHT_FOCUS
@ DYNAMIC_OBJECT_AREA_SPELL
#define ASSERT
Definition Errors.h:68
GameObjectActions
@ GO_JUST_DEACTIVATED
Definition GameObject.h:79
#define FISHING_BOBBER_READY_TIME
Definition GameObject.h:83
EnchantmentSlot
@ PERM_ENCHANTMENT_SLOT
@ TEMP_ENCHANTMENT_SLOT
@ PRISMATIC_ENCHANTMENT_SLOT
InventoryResult
Definition ItemDefines.h:25
@ EQUIP_ERR_CLIENT_LOCKED_OUT
Definition ItemDefines.h:65
@ EQUIP_ERR_ITEM_NOT_FOUND
Definition ItemDefines.h:49
@ EQUIP_ERR_OK
Definition ItemDefines.h:26
@ EQUIP_ERR_INV_FULL
Definition ItemDefines.h:76
@ EQUIP_ERR_ITEM_MAX_COUNT
Definition ItemDefines.h:43
int32 GenerateItemRandomPropertyId(uint32 item_id)
@ ITEM_CLASS_ARMOR
@ ITEM_CLASS_WEAPON
@ ITEM_SUBCLASS_WEAPON_DAGGER
@ ITEM_FIELD_FLAG_UNLOCKED
@ ITEM_SPELLTRIGGER_LEARN_SPELL_ID
@ ITEM_FLAG_IS_MILLABLE
@ ITEM_FLAG_NO_REAGENT_COST
@ ITEM_FLAG_IS_PROSPECTABLE
#define MAX_ITEM_PROTO_DAMAGES
#define MAX_ITEM_PROTO_SPELLS
@ ITEM_CHANGED
Definition Item.h:54
@ LANG_ZONE_NOFLYZONE
Definition Language.h:771
#define TC_LOG_WARN(filterType__,...)
Definition Log.h:162
#define TC_LOG_DEBUG(filterType__,...)
Definition Log.h:156
#define TC_LOG_ERROR(filterType__,...)
Definition Log.h:165
#define sLog
Definition Log.h:130
LootStore LootTemplates_Spell("spell_loot_template", "spell id (random item creating)", false)
LootType
Definition Loot.h:81
@ LOOT_PICKPOCKETING
Definition Loot.h:85
@ LOOT_MILLING
Definition Loot.h:91
@ LOOT_DISENCHANTING
Definition Loot.h:87
@ LOOT_SKINNING
Definition Loot.h:89
@ LOOT_PROSPECTING
Definition Loot.h:90
#define SPEED_CHARGE
TempSummonType
@ TEMPSUMMON_DEAD_DESPAWN
@ TEMPSUMMON_TIMED_DESPAWN
#define DEFAULT_PLAYER_BOUNDING_RADIUS
@ TYPEID_UNIT
Definition ObjectGuid.h:38
@ TYPEID_PLAYER
Definition ObjectGuid.h:39
ScriptMapMap sEventScripts
Definition ObjectMgr.cpp:60
#define sObjectMgr
Definition ObjectMgr.h:1721
#define sOutdoorPvPMgr
@ PET_SAVE_NOT_IN_SLOT
Definition PetDefines.h:45
@ PET_SAVE_AS_CURRENT
Definition PetDefines.h:42
#define PET_FOLLOW_DIST
Definition PetDefines.h:85
@ SUMMON_PET
Definition PetDefines.h:31
@ HUNTER_PET
Definition PetDefines.h:32
@ EQUIPMENT_SLOT_MAINHAND
Definition Player.h:567
std::vector< ItemPosCount > ItemPosCountVec
Definition Player.h:624
@ DAMAGE_FIRE
Definition Player.h:696
@ INVENTORY_SLOT_BAG_END
Definition Player.h:577
@ TELE_TO_SPELL
Definition Player.h:683
@ PLAYER_FLAGS_GHOST
Definition Player.h:348
@ CHEAT_GOD
Definition Player.h:837
@ ACTION_BUTTON_SPELL
Definition Player.h:191
RuneType
Definition Player.h:287
@ RUNE_FROST
Definition Player.h:290
#define INVENTORY_SLOT_BAG_0
Definition Player.h:547
@ REPUTATION_SOURCE_SPELL
Definition Player.h:207
#define MAPID_INVALID
Definition Position.h:165
@ QUEST_FLAGS_TRACKING
Definition QuestDef.h:143
@ QUEST_FLAGS_FLAGS_PVP
Definition QuestDef.h:146
#define MAX_QUEST_LOG_SIZE
Definition QuestDef.h:36
@ QUEST_STATUS_NONE
Definition QuestDef.h:104
int32 irand(int32 min, int32 max)
Definition Random.cpp:35
uint32 urand(uint32 min, uint32 max)
Definition Random.cpp:42
double rand_norm()
Definition Random.cpp:75
bool roll_chance_f(float chance)
Definition Random.h:53
bool roll_chance_i(int chance)
Definition Random.h:59
#define sScriptMgr
Definition ScriptMgr.h:1168
@ GAMEOBJECT_TYPE_BUTTON
@ GAMEOBJECT_TYPE_SPELL_FOCUS
@ GAMEOBJECT_TYPE_DUEL_ARBITER
@ GAMEOBJECT_TYPE_TRAP
@ GAMEOBJECT_TYPE_CHEST
@ GAMEOBJECT_TYPE_FISHINGHOLE
@ GAMEOBJECT_TYPE_FLAGDROP
@ GAMEOBJECT_TYPE_QUESTGIVER
@ GAMEOBJECT_TYPE_FLAGSTAND
@ GAMEOBJECT_TYPE_GOOBER
@ GAMEOBJECT_TYPE_FISHINGNODE
@ GAMEOBJECT_TYPE_DOOR
@ GAMEOBJECT_TYPE_RITUAL
SpellEffIndex
@ EFFECT_1
@ EFFECT_0
@ EFFECT_2
@ SPELL_ATTR7_CAN_RESTORE_SECONDARY_POWER
@ SPELL_ATTR7_DISPEL_CHARGES
@ SPELL_ATTR7_SUMMON_PLAYER_TOTEM
@ 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
#define MAX_RUNES
@ SPELL_PREVENTION_TYPE_SILENCE
@ SPELL_SCHOOL_MASK_NORMAL
@ EVENT_JUMP
@ UNIT_DYNFLAG_LOOTABLE
@ UNIT_DYNFLAG_NONE
@ SPELL_DAMAGE_CLASS_MAGIC
@ SPELL_DAMAGE_CLASS_MELEE
@ TEAM_ALLIANCE
@ TEAM_HORDE
#define MAX_GLYPH_SLOT_INDEX
@ SUMMON_TYPE_VEHICLE2
@ SUMMON_TYPE_LIGHTWELL
@ SUMMON_TYPE_MINION
@ SUMMON_TYPE_GUARDIAN
@ SUMMON_TYPE_PET
@ SUMMON_TYPE_TOTEM
@ SUMMON_TYPE_VEHICLE
@ SUMMON_TYPE_MINIPET
@ SUMMON_TYPE_GUARDIAN2
WeaponAttackType
@ OFF_ATTACK
@ BASE_ATTACK
@ RANGED_ATTACK
@ CLASS_HUNTER
@ CLASS_DEATH_KNIGHT
@ SPELLFAMILY_PRIEST
@ SPELLFAMILY_WARLOCK
@ SPELLFAMILY_GENERIC
@ SPELLFAMILY_WARRIOR
@ SPELLFAMILY_PALADIN
@ SPELLFAMILY_HUNTER
@ SPELLFAMILY_POTION
@ SPELLFAMILY_ROGUE
@ SPELLFAMILY_SHAMAN
@ SPELLFAMILY_DRUID
@ SPELLFAMILY_DEATHKNIGHT
GameObjectDestructibleState
@ ALLIANCE
Powers
@ MAX_POWERS
@ POWER_RAGE
@ POWER_RUNIC_POWER
@ POWER_HAPPINESS
@ POWER_ENERGY
@ POWER_MANA
uint32 const CREATURE_TYPEMASK_HUMANOID_OR_UNDEAD
#define MAX_TOTEM_SLOT
@ SUMMON_SLOT_TOTEM_FIRE
@ BATTLEGROUND_WS
@ BATTLEGROUND_EY
@ BATTLEGROUND_AV
@ BATTLEGROUND_AB
@ SPELL_MISS_REFLECT
@ AURA_STATE_DEADLY_POISON
@ AURA_STATE_BLEEDING
@ AURA_STATE_SWIFTMEND
@ AURA_STATE_CONFLAGRATE
DispelType
@ DISPEL_POISON
SpellCastResult
@ SPELL_FAILED_INTERRUPTED_COMBAT
@ SPELL_FAILED_GLYPH_SOCKET_LOCKED
@ SPELL_FAILED_DONT_REPORT
@ SPELL_FAILED_NO_DUELING
@ SPELL_CAST_OK
@ SPELL_FAILED_INVALID_GLYPH
@ GO_STATE_READY
@ SPELL_ATTR4_NOT_STEALABLE
@ SUMMON_CATEGORY_PET
@ SUMMON_CATEGORY_VEHICLE
@ SUMMON_CATEGORY_ALLY
@ SUMMON_CATEGORY_PUPPET
@ SUMMON_CATEGORY_WILD
@ SUMMON_CATEGORY_UNK
SkillType
@ SKILL_INSCRIPTION
@ SKILL_ENGINEERING
@ SKILL_NONE
@ SKILL_JEWELCRAFTING
@ SPELL_ATTR6_LIMIT_PCT_DAMAGE_MODS
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_PREVENT_RESURRECTION
@ SPELL_AURA_MOD_AURA_DURATION_BY_DISPEL_NOT_STACK
@ SPELL_AURA_PERIODIC_DAMAGE
@ SPELL_AURA_ADD_FLAT_MODIFIER
@ SPELL_AURA_CONTROL_VEHICLE
@ SPELL_AURA_MOD_STALKED
@ SPELL_AURA_PERIODIC_HEAL
@ SPELL_AURA_MOD_DECREASE_SPEED
@ SPELL_AURA_MOD_STUN
@ FORM_SHADOW
@ SPELL_INTERRUPT_FLAG_INTERRUPT
@ CHANNEL_INTERRUPT_FLAG_INTERRUPT
@ SPELLMOD_DAMAGE
@ SPELLMOD_DURATION
@ TARGET_FLAG_DEST_LOCATION
@ TARGET_FLAG_UNIT_MASK
@ TARGET_FLAG_GAMEOBJECT_MASK
@ TRIGGERED_FULL_MASK
Will return SPELL_FAILED_DONT_REPORT in CheckCast functions.
@ TRIGGERED_IGNORE_SPELL_AND_CATEGORY_CD
Will ignore GCD.
@ TRIGGERED_CAST_DIRECTLY
Will ignore combo point requirement.
@ TRIGGERED_IGNORE_CAST_IN_PROGRESS
Will ignore aura scaling.
@ TRIGGERED_IGNORE_GCD
Not triggered.
SpellValueMod
@ SPELLVALUE_BASE_POINT0
SpellEffectHandlerFn SpellEffectHandlers[TOTAL_SPELL_EFFECTS]
@ SPELL_ATTR0_CU_SHARE_DAMAGE
Definition SpellInfo.h:144
@ PROC_HIT_INTERRUPT
Definition SpellMgr.h:232
#define sSpellMgr
Definition SpellMgr.h:738
@ SPELLCATEGORY_DEVOUR_MAGIC
Definition SpellMgr.h:45
@ PROC_SPELL_TYPE_MASK_ALL
Definition SpellMgr.h:205
@ PROC_SPELL_PHASE_HIT
Definition SpellMgr.h:212
@ PROC_FLAG_DONE_SPELL_MELEE_DMG_CLASS
Definition SpellMgr.h:121
@ PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_NEG
Definition SpellMgr.h:140
@ PROC_FLAG_TAKEN_SPELL_MELEE_DMG_CLASS
Definition SpellMgr.h:122
@ PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG
Definition SpellMgr.h:139
std::vector< std::pair< uint32, ObjectGuid > > DispelList
Definition Spell.h:147
void(Spell::*)() SpellEffectHandlerFn
Definition Spell.h:776
@ SPELL_EFFECT_HANDLE_LAUNCH_TARGET
Definition Spell.h:142
@ SPELL_EFFECT_HANDLE_LAUNCH
Definition Spell.h:141
@ SPELL_EFFECT_HANDLE_HIT
Definition Spell.h:143
@ SPELL_EFFECT_HANDLE_HIT_TARGET
Definition Spell.h:144
@ SPELL_STATE_PREPARING
Definition Spell.h:132
@ SPELL_STATE_CASTING
Definition Spell.h:133
@ UNIT_PET_FLAG_CAN_BE_RENAMED
@ REACT_DEFENSIVE
@ REACT_AGGRESSIVE
NPCFlags
Non Player Character flags.
@ COMMAND_STAY
@ MOVE_RUN
@ UNIT_FLAG_IMMUNE
@ UNIT_FLAG_SKINNABLE
float baseMoveSpeed[MAX_MOVE_TYPE]
Definition Unit.cpp:87
float playerBaseMoveSpeed[MAX_MOVE_TYPE]
Definition Unit.cpp:100
@ UNIT_MASK_GUARDIAN
Definition Unit.h:366
@ UNIT_MASK_MINION
Definition Unit.h:365
@ MINDAMAGE
Definition Unit.h:152
@ MAXDAMAGE
Definition Unit.h:153
UnitMods
Definition Unit.h:157
@ UNIT_MOD_DAMAGE_OFFHAND
Definition Unit.h:181
@ UNIT_MOD_DAMAGE_RANGED
Definition Unit.h:182
@ UNIT_MOD_DAMAGE_MAINHAND
Definition Unit.h:180
@ ALIVE
Definition Unit.h:211
#define CURRENT_FIRST_NON_MELEE_SPELL
Definition Unit.h:612
CurrentSpellTypes
Definition Unit.h:605
@ CURRENT_CHANNELED_SPELL
Definition Unit.h:608
@ CURRENT_GENERIC_SPELL
Definition Unit.h:607
@ CURRENT_AUTOREPEAT_SPELL
Definition Unit.h:609
@ UNIT_STATE_CONFUSED
Definition Unit.h:231
@ UNIT_STATE_ROOT
Definition Unit.h:230
@ UNIT_STATE_FLEEING
Definition Unit.h:227
@ UNIT_STATE_ALL_ERASABLE
Definition Unit.h:267
@ UNIT_STATE_STUNNED
Definition Unit.h:223
std::vector< DispelableAura > DispelChargesList
Definition Unit.h:132
@ NULL_BAG
Definition Unit.h:61
@ NULL_SLOT
Definition Unit.h:62
@ NODAMAGE
Definition Unit.h:357
@ DOT
Definition Unit.h:355
@ SPELL_DIRECT_DAMAGE
Definition Unit.h:354
@ HEAL
Definition Unit.h:356
@ TOTAL_PCT
Definition Unit.h:146
@ UNIT_FIELD_LEVEL
@ PLAYER_FLAGS
@ PLAYER_VISIBLE_ITEM_16_ENTRYID
@ PLAYER_DUEL_ARBITER
@ UNIT_CREATED_BY_SPELL
@ ITEM_FIELD_DURABILITY
@ ITEM_FIELD_FLAGS
@ ITEM_FIELD_MAXDURABILITY
@ ITEM_FIELD_CREATOR
T AddPct(T &base, U pct)
Definition Util.h:77
T ApplyPct(T &base, U pct)
Definition Util.h:83
T CalculatePct(T base, U pct)
Definition Util.h:71
@ VEHICLE_SPELL_RIDE_HARDCODED
bool IsPositive() const
Definition SpellAuras.h:73
void UpdateApplyEffectMask(uint8 newEffMask, bool canHandleNewEffects)
uint8 GetEffectsToApply() const
Definition SpellAuras.h:76
SpellInfo const * GetSpellInfo() const
uint32 GetId() const
Aura * GetBase() const
ObjectGuid GetCasterGUID() const
int32 GetAmount() const
static Aura * TryCreate(AuraCreateInfo &createInfo)
AuraApplication const * GetApplicationOfTarget(ObjectGuid guid) const
Definition SpellAuras.h:209
DynamicObject * GetDynobjOwner() const
Definition SpellAuras.h:123
void _RegisterForTargets()
Definition SpellAuras.h:135
ObjectGuid GetCasterGUID() const
Definition SpellAuras.h:119
uint32 GetId() const
Definition SpellAuras.h:116
int32 CalcDispelChance(Unit const *auraTarget, bool offensive) const
int32 GetDuration() const
Definition SpellAuras.h:148
DynObjAura * ToDynObjAura()
Definition SpellAuras.h:260
uint8 GetStackAmount() const
Definition SpellAuras.h:164
void _ApplyEffectForTargets(uint8 effIndex)
uint8 GetCharges() const
Definition SpellAuras.h:155
SpellInfo const * GetSpellInfo() const
Definition SpellAuras.h:115
bool IsPassive() const
ObjectGuid GetOwnerGUID() const override
Definition Corpse.h:67
void SetDisplayId(uint32 modelId) override
void SetReactState(ReactStates st)
Definition Creature.h:119
void DespawnOrUnsummon(Milliseconds timeToDespawn=0s, Seconds forceRespawnTime=0s)
CreatureTemplate const * GetCreatureTemplate() const
Definition Creature.h:186
void SetImmuneToAll(bool apply) override
Definition Creature.h:126
void SelectLevel()
bool isElite() const
uint32 GetResist() const
Definition Unit.h:466
uint32 GetAbsorb() const
Definition Unit.h:465
void SetCasterViewpoint()
void SetDuration(int32 newDuration)
bool CreateDynamicObject(ObjectGuid::LowType guidlow, Unit *caster, SpellInfo const *spell, Position const &pos, float radius, DynamicObjectType type)
virtual bool OnGossipHello(Player *)
void UseDoorOrButton(uint32 time_to_restore=0, bool alternative=false, Unit *user=nullptr)
GameObjectTemplate const * GetGOInfo() const
Definition GameObject.h:102
uint32 GetFaction() const override
Definition GameObject.h:285
bool isSpawned() const
Definition GameObject.h:155
void SetOwnerGUID(ObjectGuid owner)
Definition GameObject.h:131
void SetDestructibleState(GameObjectDestructibleState state, WorldObject *attackerOrHealer=nullptr, bool setHealth=false)
void AddToSkillupList(ObjectGuid const &PlayerGuidLow)
Definition GameObject.h:206
void SetLootState(LootState s, Unit *unit=nullptr)
GameObjectAI * AI() const
Definition GameObject.h:275
GameObject * GetLinkedTrap()
void SetRespawnTime(int32 respawn)
bool IsInSkillupList(ObjectGuid const &playerGuid) const
Definition GameObject.h:207
void TriggeringLinkedGameObject(uint32 trapEntry, Unit *target)
GameobjectTypes GetGoType() const
Definition GameObject.h:176
ObjectGuid::LowType GetSpawnId() const
Definition GameObject.h:112
void ActivateObject(GameObjectActions action, WorldObject *spellCaster=nullptr, uint32 spellId=0, int32 effectIndex=-1)
void SetLevel(uint32 level)
Definition GameObject.h:175
void ModifyHealth(int32 change, WorldObject *attackerOrHealer=nullptr, uint32 spellId=0)
void Use(Unit *user)
void AddUniqueUse(Player *player)
bool Create(ObjectGuid::LowType guidlow, uint32 name_id, Map *map, uint32 phaseMask, Position const &pos, QuaternionData const &rotation, uint32 animprogress, GOState go_state, uint32 artKit=0, bool dynamic=false, ObjectGuid::LowType spawnid=0)
void SetSpellId(uint32 id)
Definition GameObject.h:143
void SetFaction(uint32 faction) override
Definition GameObject.h:286
Definition Item.h:62
void SetState(ItemUpdateState state, Player *forplayer=nullptr)
Definition Item.cpp:638
uint8 GetSlot() const
Definition Item.h:126
uint32 GetEnchantmentId(EnchantmentSlot slot) const
Definition Item.h:148
static Item * CreateItem(uint32 itemEntry, uint32 count, Player const *player=nullptr)
Definition Item.cpp:1044
uint32 GetEnchantmentDuration(EnchantmentSlot slot) const
Definition Item.h:149
void SetCount(uint32 value)
Definition Item.cpp:1250
ItemTemplate const * GetTemplate() const
Definition Item.cpp:535
bool IsWeaponVellum() const
Definition Item.h:180
bool IsEquipped() const
Definition Item.cpp:716
bool IsArmorVellum() const
Definition Item.h:181
Player * GetOwner() const
Definition Item.cpp:540
ObjectGuid GetOwnerGUID() const
Definition Item.h:76
uint16 GetPos() const
Definition Item.h:130
uint32 GetEnchantmentCharges(EnchantmentSlot slot) const
Definition Item.h:150
void ClearSoulboundTradeable(Player *currentOwner)
Definition Item.cpp:1225
uint32 GetCount() const
Definition Item.h:119
uint8 GetBagSlot() const
Definition Item.cpp:711
void SetEnchantment(EnchantmentSlot slot, uint32 id, uint32 duration, uint32 charges, ObjectGuid caster=ObjectGuid::Empty)
Definition Item.cpp:883
Definition Map.h:281
bool IsDungeon() const
Definition Map.cpp:4236
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:630
ObjectGuid::LowType GenerateLowGuid()
Definition Map.h:587
GameObject * GetGameObject(ObjectGuid const &guid)
Definition Map.cpp:4430
TempSummon * SummonCreature(uint32 entry, Position const &pos, SummonPropertiesEntry const *properties=nullptr, uint32 duration=0, WorldObject *summoner=nullptr, uint32 spellId=0, uint32 vehId=0, ObjectGuid privateObjectOwner=ObjectGuid::Empty)
Definition Object.cpp:1852
Creature * GetCreature(ObjectGuid const &guid)
Definition Map.cpp:4397
Unit * GetOwner() const
float GetFollowAngle() const override
void MoveJump(Position const &pos, float speedXY, float speedZ, uint32 id=EVENT_JUMP, bool hasOrientation=false)
void MoveCharge(float x, float y, float z, float speed=SPEED_CHARGE, uint32 id=EVENT_CHARGE, bool generatePath=false)
void MoveDistract(uint32 time, float orientation)
bool IsEmpty() const
Definition ObjectGuid.h:172
std::string ToString() const
void Clear()
Definition ObjectGuid.h:150
static Creature * ToCreature(Object *o)
Definition Object.h:186
PackedGuid const & GetPackGUID() const
Definition Object.h:80
static Unit * ToUnit(Object *o)
Definition Object.h:192
uint32 GetUInt32Value(uint16 index) const
Definition Object.cpp:249
static GameObject * ToGameObject(Object *o)
Definition Object.h:198
bool IsInWorld() const
Definition Object.h:73
TypeID GetTypeId() const
Definition Object.h:93
void SetFlag(uint16 index, uint32 newFlag)
Definition Object.cpp:760
virtual void SetDynamicFlag(uint32 flag)
Definition Object.h:89
void SetGuidValue(uint16 index, ObjectGuid value)
Definition Object.cpp:699
uint32 GetEntry() const
Definition Object.h:81
bool HasFlag(uint16 index, uint32 flag) const
Definition Object.cpp:799
static ObjectGuid GetGUID(Object const *o)
Definition Object.h:78
void SetUInt32Value(uint16 index, uint32 value)
Definition Object.cpp:585
static Player * ToPlayer(Object *o)
Definition Object.h:180
std::size_t size() const
Definition ObjectGuid.h:278
Definition Pet.h:40
Player * GetOwner() const
Definition Pet.cpp:2000
void InitTalentForLevel()
Definition Pet.cpp:1788
void SavePetToDB(PetSaveMode mode)
Definition Pet.cpp:437
PetType getPetType() const
Definition Pet.h:51
bool isControlled() const
Definition Pet.h:53
void setDeathState(DeathState s) override
Definition Pet.cpp:582
void Remove(PetSaveMode mode, bool returnreagent=false)
Definition Pet.cpp:732
uint32 GetCurrentFoodBenefitLevel(uint32 itemlevel) const
Definition Pet.cpp:1150
bool learnSpell(uint32 spell_id)
Definition Pet.cpp:1500
void SendQuestGiverQuestDetails(Quest const *quest, ObjectGuid npcGUID, bool activateAccept) const
void ClearMenus()
bool HasIgnore(ObjectGuid const &ignoreGuid)
void SetRuneCooldown(uint8 index, uint32 cooldown, bool casted=false)
Definition Player.cpp:24354
void KilledMonsterCredit(uint32 entry, ObjectGuid guid=ObjectGuid::Empty)
Definition Player.cpp:16140
uint32 GetArmorProficiency() const
Definition Player.h:1198
static bool IsEquipmentPos(uint16 pos)
Definition Player.h:1117
void LearnSpell(uint32 spell_id, bool dependent, uint32 fromSkill=0)
Definition Player.cpp:3353
void SendTalentsInfoData(bool pet)
Definition Player.cpp:25366
bool HasPvPForcingQuest() const
Definition Player.cpp:16695
Item * StoreNewItem(ItemPosCountVec const &pos, uint32 item, bool update, int32 randomPropertyId=0, GuidSet const &allowedLooters=GuidSet())
Definition Player.cpp:11621
InventoryResult CanEquipItem(uint8 slot, uint16 &dest, Item *pItem, bool swap, bool not_loading=true) const
Definition Player.cpp:10982
void SetCanTitanGrip(bool value, uint32 penaltySpellId=0, int32 allowedItemClass=0, int32 allowedItemSubClassMask=0)
Definition Player.cpp:13170
void SendTalentWipeConfirm(ObjectGuid trainerGuid) const
Definition Player.cpp:9158
uint32 EnvironmentalDamage(EnviromentalDamage type, uint32 damage)
Definition Player.cpp:634
uint8 GetDrunkValue() const
Definition Player.h:1883
void SendDirectMessage(WorldPacket const *data) const
Definition Player.cpp:6161
uint16 GetSkillValue(uint32 skill) const
Definition Player.cpp:5892
Item * BankItem(ItemPosCountVec const &dest, Item *pItem, bool update)
Definition Player.cpp:11978
Item * GetItemByEntry(uint32 entry) const
Definition Player.cpp:12461
uint16 FindQuestSlot(uint32 quest_id) const
Definition Player.cpp:15935
void SetCanParry(bool value)
Definition Player.cpp:24083
InventoryResult CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec &dest, Item *pItem, bool swap=false) const
Definition Player.cpp:9994
void SendProficiency(ItemClass itemClass, uint32 itemSubclassMask) const
Definition Player.cpp:20946
void UpdatePvPState(bool onlyFFA=false)
Definition Player.cpp:21644
void DurabilityLossAll(double percent, bool inventory)
Definition Player.cpp:4554
bool UpdateCraftSkill(uint32 spellid)
Definition Player.cpp:5449
void SetResurrectRequestData(WorldObject const *caster, uint32 health, uint32 mana, uint32 appliedAura)
Definition Player.cpp:21729
void SpawnCorpseBones(bool triggerSave=true)
Definition Player.cpp:4536
void SetDrunkValue(uint8 newDrunkValue, uint32 itemId=0)
Definition Player.cpp:872
void SendPreparedGossip(WorldObject *source)
Definition Player.cpp:14052
void UpdateTalentGroupCount(uint8 count)
Definition Player.cpp:25661
void ActivateTalentGroup(uint8 group)
Definition Player.cpp:25708
uint32 GetGlyphSlot(uint8 slot) const
Definition Player.h:1522
void PetSpellInitialize()
Definition Player.cpp:20596
void SetFallInformation(uint32 time, float z)
Definition Player.cpp:24853
void ApplyEnchantment(Item *item, EnchantmentSlot slot, bool apply, bool apply_dur=true, bool ignore_condition=false)
Definition Player.cpp:13431
bool CanAddQuest(Quest const *quest, bool msg) const
Definition Player.cpp:14467
void SetSkill(uint32 id, uint16 step, uint16 newVal, uint16 maxVal)
Definition Player.cpp:5759
Pet * GetPet() const
Definition Player.cpp:20286
uint16 GetPureSkillValue(uint32 skill) const
Definition Player.cpp:5948
uint8 GetRunesState() const
Definition Player.h:2203
void RemoveTradeableItem(Item *item)
Definition Player.cpp:13269
void SetCanBlock(bool value)
Definition Player.cpp:24092
bool GetCommandStatus(uint32 command) const
Definition Player.h:1028
Item * StoreItem(ItemPosCountVec const &pos, Item *pItem, bool update)
Definition Player.cpp:11661
WorldSession * GetSession() const
Definition Player.h:1719
Item * GetItemByPos(uint16 pos) const
Definition Player.cpp:9552
void RepopAtGraveyard()
Definition Player.cpp:4773
void SendBindPointUpdate()
Definition Player.cpp:16861
uint32 GetQuestSlotQuestId(uint16 slot) const
Definition Player.cpp:15944
void DestroyItem(uint8 bag, uint8 slot, bool update)
Definition Player.cpp:12113
bool IsResurrectRequested() const
Definition Player.h:1565
static bool IsInventoryPos(uint16 pos)
Definition Player.h:1115
uint32 DestroyItemCount(uint32 item, uint32 count, bool update, bool unequip_check=false)
Definition Player.cpp:12209
void RemovePet(Pet *pet, PetSaveMode mode, bool returnreagent=false)
Definition Player.cpp:20310
int32 CalculateReputationGain(ReputationSource source, uint32 creatureOrQuestLevel, int32 rep, int32 faction, bool noQuestBonus=false)
Definition Player.cpp:6310
uint32 GetRuneCooldown(uint8 index) const
Definition Player.h:2206
void SendLoot(ObjectGuid guid, LootType loot_type)
Definition Player.cpp:8079
bool ActivateTaxiPathTo(std::vector< uint32 > const &nodes, Creature *npc=nullptr, uint32 spellid=0)
Definition Player.cpp:21008
ActionButton const * GetActionButton(uint8 button)
Definition Player.cpp:6094
void DurabilityLoss(Item *item, double percent)
Definition Player.cpp:4580
uint32 GetWeaponProficiency() const
Definition Player.h:1197
Battleground * GetBattleground() const
Definition Player.cpp:23049
void SetQuestSlot(uint16 slot, uint32 quest_id, uint32 timer=0)
Definition Player.cpp:15964
void RemoveSpell(uint32 spell_id, bool disabled=false, bool learn_low_rank=true)
Definition Player.cpp:3391
void SetRewardedQuest(uint32 quest_id)
Definition Player.cpp:15034
void SendNewItem(Item *item, uint32 count, bool received, bool created, bool broadcast=false, bool sendChatMessage=true)
Definition Player.cpp:13856
void AutoUnequipOffhandIfNeed(bool force=false)
Definition Player.cpp:23378
void AutoStoreLoot(uint8 bag, uint8 slot, uint32 loot_id, LootStore const &store, bool broadcast=false, bool createdByPlayer=false)
Definition Player.cpp:24529
RuneType GetCurrentRune(uint8 index) const
Definition Player.h:2205
bool IsGameMaster() const
Definition Player.h:998
Item * EquipItem(uint16 pos, Item *pItem, bool update)
Definition Player.cpp:11804
PvPInfo pvpInfo
Definition Player.h:1582
void SetGlyph(uint8 slot, uint32 glyph)
Definition Player.cpp:24281
void AddQuestAndCheckCompletion(Quest const *quest, Object *questGiver)
Definition Player.cpp:14624
bool TeleportTo(uint32 mapid, float x, float y, float z, float orientation, uint32 options=0)
Definition Player.cpp:1524
void DurabilityPointsLossAll(int32 points, bool inventory)
Definition Player.cpp:4598
Pet * SummonPet(uint32 entry, float x, float y, float z, float ang, PetType petType, uint32 despwtime)
Definition Player.cpp:26269
bool CanTakeQuest(Quest const *quest, bool msg) const
Definition Player.cpp:14455
uint8 GetActiveTalentGroup() const
Definition Player.h:1496
void SendSummonRequestFrom(Unit *summoner)
Definition Player.cpp:23307
void AreaExploredOrEventHappens(uint32 questId)
Definition Player.cpp:16008
void SendEquipError(InventoryResult msg, Item *pItem, Item *pItem2=nullptr, uint32 itemid=0) const
Definition Player.cpp:13075
bool TakeQuestSourceItem(uint32 questId, bool msg)
Definition Player.cpp:15592
void RemoveActiveQuest(uint32 questId, bool update=true)
Definition Player.cpp:15693
QuestStatus GetQuestStatus(uint32 quest_id) const
Definition Player.cpp:15642
uint32 GetGlyph(uint8 group, uint8 slot) const
Definition Player.h:1524
PlayerSocial * GetSocial()
Definition Player.h:982
void AddArmorProficiency(uint32 newflag)
Definition Player.h:1196
InventoryResult CanBankItem(uint8 bag, uint8 slot, ItemPosCountVec &dest, Item *pItem, bool swap, bool not_loading=true) const
Definition Player.cpp:11183
void SetHomebind(WorldLocation const &loc, uint32 areaId)
Definition Player.cpp:16844
void FailQuest(uint32 quest_id)
Definition Player.cpp:15040
void ItemAddedQuestCheck(uint32 entry, uint32 count)
Definition Player.cpp:16049
Item * GetWeaponForAttack(WeaponAttackType attackType, bool useable=false) const
Definition Player.cpp:9607
static bool IsBankPos(uint16 pos)
Definition Player.h:1120
bool RewardHonor(Unit *victim, uint32 groupsize, int32 honor=-1, bool pvptoken=false)
Definition Player.cpp:6524
void RemoveItem(uint8 bag, uint8 slot, bool update)
Definition Player.cpp:11983
bool HasSpell(uint32 spell) const override
Definition Player.cpp:3853
void BuildPlayerRepop()
Definition Player.cpp:4292
std::unique_ptr< DuelInfo > duel
Definition Player.h:1602
void RemoveRewardedQuest(uint32 questId, bool update=true)
Definition Player.cpp:15706
void DurabilityPointsLoss(Item *item, int32 points)
Definition Player.cpp:4624
void RemovedInsignia(Player *looterPlr)
Definition Player.cpp:8040
void AddWeaponProficiency(uint32 newflag)
Definition Player.h:1195
void PrepareGossipMenu(WorldObject *source, uint32 menuId=0, bool showQuests=false)
Definition Player.cpp:13886
InventoryResult CanStoreNewItem(uint8 bag, uint8 slot, ItemPosCountVec &dest, uint32 item, uint32 count, uint32 *no_space_count=nullptr) const
Definition Player.cpp:9989
RuneType GetBaseRune(uint8 index) const
Definition Player.h:2204
ReputationMgr & GetReputationMgr()
Definition Player.h:1848
PlayerMenu * PlayerTalkClass
Definition Player.h:1969
void AddPetAura(PetAura const *petSpell)
Definition Player.cpp:20400
void RewardPlayerAndGroupAtEvent(uint32 creature_id, WorldObject *pRewardSource)
Definition Player.cpp:23636
void ResurrectPlayer(float restore_percent, bool applySickness=false)
Definition Player.cpp:4346
bool UpdateGatherSkill(uint32 SkillId, uint32 SkillValue, uint32 RedLevel, uint32 Multiplicator=1)
Definition Player.cpp:5482
bool HasFlag(uint32 flag) const
Definition QuestDef.h:219
bool ModifyReputation(FactionEntry const *factionEntry, int32 standing, bool spillOverOnly=false)
void SetItemTarget(Item *item)
Definition Spell.cpp:306
void SetDst(float x, float y, float z, float orientation, uint32 mapId=MAPID_INVALID)
Definition Spell.cpp:384
void SetGOTarget(GameObject *target)
Definition Spell.cpp:263
ObjectGuid GetObjectTargetGUID() const
Definition Spell.cpp:294
void SetUnitTarget(Unit *target)
Definition Spell.cpp:237
bool HasDst() const
Definition Spell.cpp:436
Item * GetItemTarget() const
Unit * GetUnitTarget() const
Definition Spell.cpp:229
WorldLocation const * GetDstPos() const
Definition Spell.cpp:379
float CalcRadius(WorldObject *caster=nullptr, Spell *=nullptr) const
float CalcValueMultiplier(WorldObject *caster, Spell *spell=nullptr) const
uint32 TriggerSpell
Definition SpellInfo.h:228
SpellEffects Effect
Definition SpellInfo.h:210
bool HasRadius() const
bool IsEffect() const
int32 CalcValue(WorldObject const *caster=nullptr, int32 const *basePoints=nullptr) const
float ChainAmplitude
Definition SpellInfo.h:218
SpellEffIndex EffectIndex
Definition SpellInfo.h:209
uint32 GetProvidedTargetMask() const
void ResetAllCooldowns()
bool HasCooldown(SpellInfo const *spellInfo, uint32 itemId=0, bool ignoreCategoryCooldown=false) const
void LockSpellSchool(SpellSchoolMask schoolMask, uint32 lockoutTime)
uint32 ChannelInterruptFlags
Definition SpellInfo.h:323
uint32 TargetAuraState
Definition SpellInfo.h:309
uint32 GetMaxTicks() const
uint32 PreventionType
Definition SpellInfo.h:359
float GetMaxRange(bool positive=false, WorldObject *caster=nullptr, Spell *spell=nullptr) const
uint32 GetCategory() const
flag96 SpellFamilyFlags
Definition SpellInfo.h:357
uint32 StackAmount
Definition SpellInfo.h:340
uint32 Id
Definition SpellInfo.h:289
bool IsLootCrafting() const
uint32 GetDispelMask() const
bool NeedsToBeTriggeredByCaster(SpellInfo const *triggeringSpell) const
float Speed
Definition SpellInfo.h:339
float GetMinRange(bool positive=false) const
int32 EquippedItemClass
Definition SpellInfo.h:344
std::array< uint32, 2 > SpellVisual
Definition SpellInfo.h:348
SpellSchoolMask GetSchoolMask() const
bool HasAttribute(SpellAttr0 attribute) const
Definition SpellInfo.h:375
uint32 InterruptFlags
Definition SpellInfo.h:321
int32 CalcPowerCost(WorldObject const *caster, SpellSchoolMask schoolMask, Spell *spell=nullptr) const
int32 GetDuration() const
SpellEffectInfo const & GetEffect(SpellEffIndex index) const
Definition SpellInfo.h:483
uint32 ManaCostPercentage
Definition SpellInfo.h:336
int32 EquippedItemSubClassMask
Definition SpellInfo.h:345
uint32 GetExplicitTargetMask() const
uint32 GetAllEffectsMechanicMask() const
uint32 SpellIconID
Definition SpellInfo.h:349
bool IsPositive() const
uint32 DmgClass
Definition SpellInfo.h:358
bool HasAura(AuraType aura) const
std::array< SpellEffectInfo, MAX_SPELL_EFFECTS > const & GetEffects() const
Definition SpellInfo.h:482
uint32 SpellFamilyName
Definition SpellInfo.h:356
uint32 ManaCost
Definition SpellInfo.h:332
Definition Spell.h:152
void EffectSummonRaFFriend()
SpellInfo const * GetSpellInfo() const
Definition Spell.h:452
void EffectSendEvent()
void EffectTransmitted()
void EffectSpiritHeal()
void EffectBlock()
void EffectPlayMusic()
GameObject * gameObjTarget
Definition Spell.h:525
SpellMissInfo targetMissInfo
Definition Spell.h:529
void EffectCreateItem2()
void EffectEnchantHeldItem()
void EffectActivateRune()
Unit * m_originalCaster
Definition Spell.h:488
void EffectHealMaxHealth()
void EffectProspecting()
DynObjAura * _dynObjAura
Definition Spell.h:535
void EffectCharge()
void EffectSummonObject()
void EffectSendTaxi()
void EffectCreateItem()
void EffectTameCreature()
void EffectGameObjectDamage()
SpellCastTargets m_targets
Definition Spell.h:402
void EffectSummonChangeItem()
void EffectDummy()
std::unique_ptr< PathGenerator > m_preGeneratedPath
Definition Spell.h:709
void EffectHealthLeech()
void EffectStealBeneficialBuff()
void EffectStuck()
void EffectInterruptCast()
void EffectSummonPlayer()
void EffectWeaponDmg()
int32 damage
Definition Spell.h:528
void EffectEnchantItemPrismatic()
void EffectSummonType()
void EffectSkinPlayerCorpse()
void ExecuteLogEffectSummonObject(uint8 effIndex, WorldObject *obj)
Definition Spell.cpp:4641
SpellEffectHandleMode effectHandleMode
Definition Spell.h:530
void EffectHealMechanical()
void EffectGameObjectRepair()
void EffectSummonObjectWild()
void EffectActivateObject()
void EffectSkill()
void EffectLeap()
void EffectTradeSkill()
void EffectPersistentAA()
void EffectQuestClear()
void EffectModifyThreatPercent()
void EffectForceDeselect()
void EffectPull()
void EffectParry()
void EffectRenamePet()
void AddComboPointGain(Unit *target, int8 amount)
Definition Spell.h:404
void EffectResurrect()
void EffectDestroyAllTotems()
WeaponAttackType m_attackType
Definition Spell.h:492
void EffectResurrectPet()
void EffectTriggerSpell()
void EffectPullTowards()
ObjectGuid m_originalCasterGUID
Definition Spell.h:486
WorldObject *const m_caster
Definition Spell.h:482
void EffectPowerBurn()
std::string GetDebugInfo() const
Definition Spell.cpp:8320
void EffectDurabilityDamage()
void EffectSanctuary()
void ExecuteLogEffectOpenLock(uint8 effIndex, Object *obj)
Definition Spell.cpp:4623
void EffectCastButtons()
Item * itemTarget
Definition Spell.h:524
int32 m_damage
Definition Spell.h:542
void ExecuteLogEffectTakeTargetPower(uint8 effIndex, Unit *target, uint32 powerType, uint32 powerTaken, float gainMultiplier)
Definition Spell.cpp:4592
void EffectKnockBack()
void EffectReputation()
void DoCreateItem(uint32 itemId)
void EffectDistract()
void EffectKillCredit()
void EffectSummonPet()
void EffectEnergizePct()
void EffectDispelMechanic()
void EffectSelfResurrect()
void EffectDispel()
void EffectBind()
void EffectFeedPet()
void EffectNULL()
void EffectRechargeManaGem()
void EffectApplyAura()
void EffectAddHonor()
void EffectTriggerRitualOfSummoning()
void EffectInstaKill()
void CalculateJumpSpeeds(SpellEffectInfo const &spellEffectInfo, float dist, float &speedXY, float &speedZ)
void EffectInebriate()
void EffectOpenLock()
void EffectEnvironmentalDMG()
void EffectRedirectThreat()
void EffectRemoveAura()
void EffectDualWield()
void EffectAddComboPoints()
int32 m_healing
Definition Spell.h:543
void EffectPickPocket()
void EffectProficiency()
SpellEffectInfo const * effectInfo
Definition Spell.h:531
void EffectDisEnchant()
uint32 m_glyphIndex
Definition Spell.h:401
Unit * GetUnitCasterForEffectHandlers() const
Definition Spell.cpp:7568
void EffectAddExtraAttacks()
void EffectTriggerMissileSpell()
UnitAura * _spellAura
Definition Spell.h:534
Unit * unitTarget
Definition Spell.h:523
void EffectEnchantItemTmp()
SpellSchoolMask m_spellSchoolMask
Definition Spell.h:491
void EffectCreateRandomItem()
void EffectTeleUnitsFaceCaster()
void ExecuteLogEffectUnsummonObject(uint8 effIndex, WorldObject *obj)
Definition Spell.cpp:4647
void EffectPullTowardsDest()
void EffectKillCreditPersonal()
void ExecuteLogEffectInterruptCast(uint8 effIndex, Unit *victim, uint32 spellId)
Definition Spell.cpp:4608
SpellCastResult prepare(SpellCastTargets const &targets, AuraEffect const *triggeredByAura=nullptr)
Definition Spell.cpp:3070
void ExecuteLogEffectResurrect(uint8 effIndex, Unit *target)
Definition Spell.cpp:4653
void EffectSchoolDMG()
void SendLoot(ObjectGuid guid, LootType loottype)
void EffectThreat()
Corpse * m_corpseTarget
Definition Spell.h:526
void SummonGuardian(SpellEffectInfo const &spellEffectInfo, uint32 entry, SummonPropertiesEntry const *properties, uint32 numSummons)
void EffectResurrectNew()
void EffectChargeDest()
void EffectUntrainTalents()
void EffectLearnSpell()
void EffectMilling()
void EffectHealPct()
void ExecuteLogEffectCreateItem(uint8 effIndex, uint32 entry)
Definition Spell.cpp:4629
void EffectJumpDest()
void EffectScriptEffect()
void EffectAddFarsight()
void EffectEnergize()
WorldLocation * destTarget
Definition Spell.h:527
void EffectGameObjectSetDestructionState()
void EffectApplyGlyph()
SpellCastResult CanOpenLock(SpellEffectInfo const &spellEffectInfo, uint32 lockid, SkillType &skillid, int32 &reqSkillValue, int32 &skillValue)
Definition Spell.cpp:7828
void EffectQuestComplete()
void ExecuteLogEffectDestroyItem(uint8 effIndex, uint32 entry)
Definition Spell.cpp:4635
void EffectDiscoverTaxi()
void EffectTeleportUnits()
void EffectPlaySound()
void EffectLearnPetSpell()
void EffectPowerDrain()
Item * m_CastItem
Definition Spell.h:396
uint32 m_castItemEntry
Definition Spell.h:398
void EffectTaunt()
void EffectLeapBack()
void EffectDurabilityDamagePCT()
SpellValue *const m_spellValue
Definition Spell.h:484
void EffectLearnSkill()
void SendResurrectRequest(Player *target)
Definition Spell.cpp:4728
void EffectActivateSpec()
void EffectForceCast()
void EffectDismissPet()
void EffectEnchantItemPerm()
void EffectQuestFail()
void EffectCreateTamedPet()
void EffectJump()
void ExecuteLogEffectDurabilityDamage(uint8 effIndex, Unit *victim, int32 itemId, int32 slot)
Definition Spell.cpp:4615
ObjectGuid m_castItemGUID
Definition Spell.h:397
int64 GetUnitTargetCountForEffect(SpellEffIndex effect) const
Definition Spell.cpp:2365
GameObject * focusObject
Definition Spell.h:539
void EffectTitanGrip()
void ExecuteLogEffectExtraAttacks(uint8 effIndex, Unit *victim, uint32 attCount)
Definition Spell.cpp:4601
void finish(bool ok=true)
Definition Spell.cpp:3912
void EffectSpecCount()
static void SendCastResult(Player *caster, SpellInfo const *spellInfo, uint8 castCount, SpellCastResult result, SpellCustomErrors customError=SPELL_CUSTOM_ERROR_NONE, uint32 *param1=nullptr, uint32 *param2=nullptr)
Definition Spell.cpp:4177
SpellInfo const *const m_spellInfo
Definition Spell.h:395
void EffectUnlearnSpecialization()
uint8 m_runesState
Definition Spell.h:498
void EffectQuestStart()
void EffectDuel()
void EffectUnused()
int32 CalculateDamage(SpellEffectInfo const &spellEffectInfo) const
Definition Spell.cpp:6428
void EffectSkinning()
void EffectHeal()
virtual void UnSummon(uint32 msTime=0)
void ModifyThreatByPercent(Unit *target, int32 percent)
Unit * GetCurrentVictim()
auto const & GetThreatenedByMeList() const
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 RegisterRedirectThreat(uint32 spellId, ObjectGuid const &victim, uint32 pct)
== REDIRECT SYSTEM ==
void MatchUnitThreatToHighestThreat(Unit *target)
void UnSummon(uint32 msTime=0) override
Definition Totem.cpp:103
Definition Unit.h:769
static uint32 DealDamage(Unit *attacker, Unit *victim, uint32 damage, CleanDamage const *cleanDamage=nullptr, DamageEffectType damagetype=DIRECT_DAMAGE, SpellSchoolMask damageSchoolMask=SPELL_SCHOOL_MASK_NORMAL, SpellInfo const *spellProto=nullptr, bool durabilityLoss=true)
Definition Unit.cpp:716
float GetPctModifierValue(UnitMods unitMod, UnitModifierPctType modifierType) const
Definition Unit.cpp:9095
void ClearUnitState(uint32 f)
Definition Unit.h:877
bool IsVehicle() const
Definition Unit.h:887
void ReplaceAllDynamicFlags(uint32 flag) override
Definition Unit.h:819
void SetMinion(Minion *minion, bool apply)
Definition Unit.cpp:5910
uint32 SpellHealingBonusTaken(Unit *caster, SpellInfo const *spellProto, uint32 healamount, DamageEffectType damagetype) const
Definition Unit.cpp:7558
int32 ModifyPower(Powers power, int32 val, bool withPowerUpdate=true)
Definition Unit.cpp:8439
void RemoveAurasByType(AuraType auraType, std::function< bool(AuraApplication const *)> const &check, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition Unit.cpp:3765
void JumpTo(float speedXY, float speedZ, bool forward=true, Optional< Position > dest={})
Definition Unit.cpp:12454
void RemoveGameObject(GameObject *gameObj, bool del)
Definition Unit.cpp:5111
AuraEffectList const & GetAuraEffectsByType(AuraType type) const
Definition Unit.h:1384
uint32 m_lastSanctuaryTime
Definition Unit.h:1569
void SetChannelObjectGuid(ObjectGuid guid)
Definition Unit.h:1461
Aura * GetAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint8 reqEffMask=0) const
Definition Unit.cpp:4439
Pet * ToPet()
Definition Unit.h:1788
bool CanHaveThreatList() const
====================== THREAT & COMBAT ====================
Definition Unit.h:1122
float GetSpeed(UnitMoveType mtype) const
Definition Unit.cpp:8668
void RemoveAura(AuraApplicationMap::iterator &i, AuraRemoveMode mode=AURA_REMOVE_BY_DEFAULT)
Definition Unit.cpp:3638
ThreatManager & GetThreatManager()
Definition Unit.h:1155
virtual void SetCanDualWield(bool value)
Definition Unit.h:838
uint8 GetClass() const
Definition Unit.h:895
Totem * ToTotem()
Definition Unit.h:1791
uint32 MeleeDamageBonusTaken(Unit *attacker, uint32 pdamage, WeaponAttackType attType, SpellInfo const *spellProto=nullptr, SpellSchoolMask damageSchoolMask=SPELL_SCHOOL_MASK_NORMAL)
Definition Unit.cpp:8033
std::multimap< uint32, AuraApplication * > AuraApplicationMap
Definition Unit.h:780
ShapeshiftForm GetShapeshiftForm() const
Definition Unit.h:1490
void SetFaction(uint32 faction) override
Definition Unit.h:974
void RemoveAurasDueToSpellByDispel(uint32 spellId, uint32 dispellerSpellId, ObjectGuid casterGUID, WorldObject *dispeller, uint8 chargesRemoved=1)
Definition Unit.cpp:3817
uint32 SpellHealingBonusDone(Unit *victim, SpellInfo const *spellProto, uint32 healamount, DamageEffectType damagetype, SpellEffectInfo const &spellEffectInfo, Optional< float > const &donePctTotal, uint32 stack=1) const
Definition Unit.cpp:7334
Pet * CreateTamedPetFrom(Creature *creatureTarget, uint32 spell_id=0)
Definition Unit.cpp:10856
static void CalcAbsorbResist(DamageInfo &damageInfo, Spell *spell=nullptr)
Definition Unit.cpp:1769
Unit * GetVehicleBase() const
Definition Unit.cpp:11826
MotionMaster * GetMotionMaster()
Definition Unit.h:1667
bool IsPet() const
Definition Unit.h:884
Powers GetPowerType() const
Definition Unit.h:931
bool HasUnitFlag(UnitFlags flags) const
Definition Unit.h:953
void SetCreatedBySpell(int32 spellId)
Definition Unit.h:964
uint32 GetMaxHealth() const
Definition Unit.h:914
AuraEffect * GetAuraEffect(uint32 spellId, uint8 effIndex, ObjectGuid casterGUID=ObjectGuid::Empty) const
Definition Unit.cpp:4359
ObjectGuid m_ObjectSlot[MAX_GAMEOBJECT_SLOT]
Definition Unit.h:1488
uint32 GetSpellCritDamageReduction(uint32 damage) const
Definition Unit.h:1060
bool IsAlive() const
Definition Unit.h:1234
AuraEffect * IsScriptOverriden(SpellInfo const *spell, int32 script) const
Definition Unit.cpp:4639
float GetCombatReach() const override
Definition Unit.h:839
int32 HealBySpell(HealInfo &healInfo, bool critical=false)
Definition Unit.cpp:6420
void SetHealth(uint32 val)
Definition Unit.cpp:9361
void SendSpellNonMeleeDamageLog(SpellNonMeleeDamage const *log)
Definition Unit.cpp:5185
void SetPetFlag(UnitPetFlag flags)
Definition Unit.h:994
TempSummon * ToTempSummon()
Definition Unit.h:1794
CharmInfo * GetCharmInfo()
Definition Unit.h:1287
bool HasAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint8 reqEffMask=0) const
Definition Unit.cpp:4535
uint32 CalculateDamage(WeaponAttackType attType, bool normalized, bool addTotalPct, uint8 itemDamagesMask=0) const
Definition Unit.cpp:2274
void SetVirtualItem(uint32 slot, uint32 itemId)
Definition Unit.cpp:13868
uint32 SpellDamageBonusDone(Unit *victim, SpellInfo const *spellProto, uint32 pdamage, DamageEffectType damagetype, SpellEffectInfo const &spellEffectInfo, Optional< float > const &donePctTotal, uint32 stack=1) const
Definition Unit.cpp:6453
uint32 GetDiseasesByCaster(ObjectGuid casterGUID, bool remove=false)
Definition Unit.cpp:4651
void AddGameObject(GameObject *gameObj)
Definition Unit.cpp:5093
virtual bool IsImmunedToSpellEffect(SpellInfo const *spellInfo, SpellEffectInfo const &spellEffectInfo, WorldObject const *caster, bool requireImmunityPurgesEffectAttribute=false) const
Definition Unit.cpp:7811
int32 GetHealthGain(int32 dVal)
Definition Unit.cpp:8413
bool IsInFlight() const
Definition Unit.h:1119
bool Attack(Unit *victim, bool meleeAttack)
Definition Unit.cpp:5535
static void ProcSkillsAndAuras(Unit *actor, Unit *actionTarget, uint32 typeMaskActor, uint32 typeMaskActionTarget, uint32 spellTypeMask, uint32 spellPhaseMask, uint32 hitMask, Spell *spell, DamageInfo *damageInfo, HealInfo *healInfo)
Definition Unit.cpp:5240
AuraApplication * _CreateAuraApplication(Aura *aura, uint8 effMask)
Definition Unit.cpp:3314
uint32 GetMaxPower(Powers power) const
Definition Unit.h:936
void InterruptSpell(CurrentSpellTypes spellType, bool withDelayed=true, bool withInstant=true, SpellCastResult result=SPELL_FAILED_INTERRUPTED, Optional< SpellCastResult > resultOther={})
Definition Unit.cpp:3021
bool IsSummon() const
Definition Unit.h:882
uint32 GetHealth() const
Definition Unit.h:913
uint32 GetFaction() const override
Definition Unit.h:973
void SetPower(Powers power, uint32 val, bool withPowerUpdate=true, bool force=false)
Definition Unit.cpp:9421
bool HasAuraState(AuraStateType flag, SpellInfo const *spellProto=nullptr, Unit const *Caster=nullptr) const
Definition Unit.cpp:5815
void GetDispellableAuraList(WorldObject const *caster, uint32 dispelMask, DispelChargesList &dispelList, bool isReflect=false) const
Definition Unit.cpp:4463
AttackerSet const & getAttackers() const
Definition Unit.h:857
std::multimap< uint32, Aura * > AuraMap
Definition Unit.h:776
virtual uint32 GetShieldBlockValue() const =0
void RemoveAuraFromStack(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition Unit.cpp:3800
bool HasAuraType(AuraType auraType) const
Definition Unit.cpp:4542
void NearTeleportTo(Position const &pos, bool casting=false)
Definition Unit.cpp:12832
uint32 GetAttackTime(WeaponAttackType att) const
Definition Unit.cpp:8471
void RemoveAurasDueToSpellBySteal(uint32 spellId, ObjectGuid casterGUID, WorldObject *stealer)
Definition Unit.cpp:3845
std::set< Unit * > AttackerSet
Definition Unit.h:772
void RemoveAurasDueToSpell(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, uint8 reqEffMask=0, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition Unit.cpp:3784
void AddExtraAttacks(uint32 count)
Definition Unit.cpp:2131
void EnergizeBySpell(Unit *victim, uint32 spellId, int32 damage, Powers powerType)
Definition Unit.cpp:6440
void SetOwnerGUID(ObjectGuid owner)
Definition Unit.cpp:5840
bool HasUnitState(const uint32 f) const
Definition Unit.h:876
uint32 HasUnitTypeMask(uint32 mask) const
Definition Unit.h:880
uint8 GetComboPoints(Unit const *who=nullptr) const
--------—Combo point system----------------—
Definition Unit.h:1695
uint32 CountPctFromMaxHealth(int32 pct) const
Definition Unit.h:922
virtual void CalculateMinMaxDamage(WeaponAttackType attType, bool normalized, bool addTotalPct, float &minDamage, float &maxDamage, uint8 damageIndex) const =0
SpellHistory * GetSpellHistory()
Definition Unit.h:1484
bool IsControlledByPlayer() const
Definition Unit.h:1258
AuraEffect * GetDummyAuraEffect(SpellFamilyNames name, uint32 iconId, uint8 effIndex) const
Definition Unit.cpp:4415
void SetMaxHealth(uint32 val)
Definition Unit.cpp:9393
void SetCreatorGUID(ObjectGuid creator)
Definition Unit.h:1244
uint32 GetPower(Powers power) const
Definition Unit.h:934
void CombatStop(bool includingCast=false, bool mutualPvP=true)
Definition Unit.cpp:5691
uint32 GetCreatureTypeMask() const
Definition Unit.cpp:8958
AuraApplicationMap & GetAppliedAuras()
Definition Unit.h:1338
std::list< AuraEffect * > AuraEffectList
Definition Unit.h:787
void RemoveMovementImpairingAuras(bool withRoot)
Definition Unit.cpp:4069
uint32 GetCreateMana() const
Definition Unit.h:1452
bool IsTotem() const
Definition Unit.h:886
virtual bool IsEngaged() const
Definition Unit.h:1126
uint32 MeleeDamageBonusDone(Unit *pVictim, uint32 damage, WeaponAttackType attType, SpellInfo const *spellProto=nullptr, SpellSchoolMask damageSchoolMask=SPELL_SCHOOL_MASK_NORMAL)
Definition Unit.cpp:7871
void ReplaceAllNpcFlags(NPCFlags flags)
Definition Unit.h:1099
AuraMap & GetOwnedAuras()
Definition Unit.h:1328
int32 SpellBaseDamageBonusDone(SpellSchoolMask schoolMask) const
Definition Unit.cpp:6987
void KnockbackFrom(float x, float y, float speedXY, float speedZ)
Definition Unit.cpp:12204
ObjectGuid m_SummonSlot[MAX_SUMMON_SLOT]
Definition Unit.h:1487
ObjectGuid GetTarget() const
Definition Unit.h:1797
uint8 GetLevel() const
Definition Unit.h:889
uint8 GetRace() const
Definition Unit.h:892
float GetTotalAttackPowerValue(WeaponAttackType attType) const
Definition Unit.cpp:9312
void RemoveUnitFlag(UnitFlags flags)
Definition Unit.h:955
ObjectGuid GetPetGUID() const
Definition Unit.h:1247
uint32 SpellDamageBonusTaken(Unit *caster, SpellInfo const *spellProto, uint32 pdamage, DamageEffectType damagetype) const
Definition Unit.cpp:6910
bool isDead() const
Definition Unit.h:1236
Spell * GetCurrentSpell(CurrentSpellTypes spellType) const
Definition Unit.h:1476
void WorldRelocate(WorldLocation const &loc)
Definition Position.h:179
uint32 GetMapId() const
Definition Position.h:193
WorldLocation GetWorldLocation() const
Definition Position.h:188
uint32 m_mapId
Definition Position.h:195
uint32 GetPhaseMask() const
Definition Object.h:368
virtual void SendMessageToSet(WorldPacket const *data, bool self) const
Definition Object.cpp:1783
Map * GetMap() const
Definition Object.h:449
InstanceScript * GetInstanceScript() const
Definition Object.cpp:1087
bool IsWithinLOS(float x, float y, float z, LineOfSightChecks checks=LINEOFSIGHT_ALL_CHECKS, VMAP::ModelIgnoreFlags ignoreFlags=VMAP::ModelIgnoreFlags::Nothing) const
Definition Object.cpp:1206
ObjectGuid GetPrivateObjectOwner() const
Definition Object.h:595
void GetClosePoint(float &x, float &y, float &z, float size, float distance2d=0, float relAngle=0) const
Definition Object.cpp:3244
SpellCastResult CastSpell(CastSpellTargetArg const &targets, uint32 spellId, CastSpellExtraArgs const &args={ })
Definition Object.cpp:2832
void MovePositionToFirstCollision(Position &pos, float dist, float angle)
Definition Object.cpp:3323
TempSummon * SummonCreature(uint32 entry, Position const &pos, TempSummonType despawnType=TEMPSUMMON_MANUAL_DESPAWN, Milliseconds despawnTime=0s, uint32 vehId=0, uint32 spellId=0, ObjectGuid privateObjectOwner=ObjectGuid::Empty)
Definition Object.cpp:1992
Unit * GetOwner() const
Definition Object.cpp:2180
ZoneScript * GetZoneScript() const
Definition Object.h:455
bool IsPrivateObject() const
Definition Object.h:594
int32 ModSpellDuration(SpellInfo const *spellInfo, WorldObject const *target, int32 duration, bool positive, uint32 effectMask) const
Definition Object.cpp:2320
std::string const & GetName() const
Definition Object.h:382
float ApplyEffectModifiers(SpellInfo const *spellInfo, uint8 effIndex, float value) const
Definition Object.cpp:2281
Player * GetSpellModOwner() const
Definition Object.cpp:2223
Player * GetCharmerOrOwnerPlayerOrPlayerItself() const
Definition Object.cpp:2203
void SetName(std::string newname)
Definition Object.h:383
float GetVisibilityRange() const
Definition Object.cpp:1492
void PlayDirectSound(uint32 soundId, Player *target=nullptr)
Definition Object.cpp:3433
virtual uint32 GetFaction() const =0
float GetDistance(WorldObject const *obj) const
Definition Object.cpp:1123
uint32 GetAreaId() const
Definition Object.h:374
Position GetFirstCollisionPosition(float dist, float angle)
Definition Object.cpp:3257
bool IsFriendlyTo(WorldObject const *target) const
Definition Object.cpp:2801
virtual float GetCombatReach() const
Definition Object.h:358
Player * GetAffectingPlayer() const
Definition Object.cpp:2212
void GetRandomPoint(Position const &srcPos, float distance, float &rand_x, float &rand_y, float &rand_z) const
Definition Object.cpp:1376
FactionTemplateEntry const * GetFactionTemplateEntry() const
Definition Object.cpp:2634
int32 CalculateSpellDamage(SpellEffectInfo const &spellEffectInfo, int32 const *basePoints=nullptr) const
Definition Object.cpp:2248
void Initialize(uint16 opcode, size_t newres=200)
Definition WorldPacket.h:73
WorldPacket const * Write() override
void SendNotification(const char *format,...) ATTR_PRINTF(2
bool HasPermission(uint32 permissionId)
uint32 GetAccountId() const
void SendDiscoverNewTaxiNode(uint32 nodeid)
@ SMSG_BREAK_TARGET
Definition Opcodes.h:367
@ SMSG_CLEAR_TARGET
Definition Opcodes.h:988
@ SMSG_DISPEL_FAILED
Definition Opcodes.h:639
@ SMSG_SPELLSTEALLOG
Definition Opcodes.h:848
@ SMSG_SPELLINSTAKILLLOG
Definition Opcodes.h:844
@ SMSG_SPELLDISPELLOG
Definition Opcodes.h:664
@ SMSG_DUEL_REQUESTED
Definition Opcodes.h:388
#define sWorld
Definition World.h:900
@ CONFIG_SKILL_MILLING
Definition World.h:110
@ CONFIG_SKILL_PROSPECTING
Definition World.h:109
@ CONFIG_CAST_UNSTUCK
Definition World.h:106
uint32 GetGameTimeMS()
Definition GameTime.cpp:47
TC_GAME_API float gravity
TC_GAME_API Player * FindPlayer(ObjectGuid const &)
uint32 hk_honor_at_level(uint8 level, float multiplier=1.0f)
Definition Formulas.h:41
@ RBAC_PERM_LOG_GM_TRADE
Definition RBAC.h:64
uint32 GetAction() const
Definition Player.h:223
ActionButtonType GetType() const
Definition Player.h:222
AuraCreateInfo & SetBaseAmount(int32 const *bp)
AuraCreateInfo & SetCaster(Unit *caster)
TriggerCastFlags TriggerFlags
CastSpellExtraArgs & AddSpellMod(SpellValueMod mod, int32 val)
static void VisitWorldObjects(WorldObject const *obj, T &visitor, float radius, bool dont_load=true)
Definition CellImpl.h:180
void SaveStayPosition()
Definition Unit.cpp:13193
void SetIsCommandFollow(bool val)
Definition Unit.cpp:13183
void SetIsAtStay(bool val)
Definition Unit.cpp:13214
void SetIsFollowing(bool val)
Definition Unit.cpp:13224
void SetIsReturning(bool val)
Definition Unit.cpp:13234
bool HasCommandState(CommandStates state) const
Definition Unit.h:683
void SetIsCommandAttack(bool val)
Definition Unit.cpp:13173
SkillType GetRequiredLootSkill() const
bool IsFriendlyTo(FactionTemplateEntry const &entry) const
bool CannotBeUsedUnderImmunity() const
struct GameObjectTemplate::@191::@200 spellFocus
struct GameObjectTemplate::@191::@202 goober
struct GameObjectTemplate::@191::@196 chest
struct GameObjectTemplate::@191::@195 questgiver
struct GameObjectTemplate::@191::@194 button
uint32 GetLockId() const
std::array< ItemEffect, MAX_ITEM_PROTO_SPELLS > Effects
uint32 DisenchantID
uint32 RequiredSkillRank
uint32 GetMaxStackSize() const
bool HasSignature() const
std::string Name1
bool HasFlag(ItemFlags flag) const
float m_positionZ
Definition Position.h:58
float GetExactDist2d(const float x, const float y) const
Definition Position.h:109
float GetRelativeAngle(float x, float y) const
Definition Position.h:139
float GetExactDist(float x, float y, float z) const
Definition Position.h:121
float m_positionX
Definition Position.h:56
float GetPositionZ() const
Definition Position.h:81
float m_positionY
Definition Position.h:57
float GetOrientation() const
Definition Position.h:82
float GetAbsoluteAngle(float x, float y) const
Definition Position.h:128
void SetOrientation(float orientation)
Definition Position.h:74
float GetPositionX() const
Definition Position.h:79
void GetPosition(float &x, float &y) const
Definition Position.h:84
float GetPositionY() const
Definition Position.h:80
void Relocate(float x, float y)
Definition Position.h:66
bool IsHostile
Definition Player.h:244
bool IsInHostileArea
Definition Player.h:245
static QuaternionData fromEulerAnglesZYX(float Z, float Y, float X)
uint32 Value[MAX_SKILL_STEP]
uint32 Effect[MAX_ITEM_ENCHANTMENT_EFFECTS]
int32 EffectBasePoints[MAX_SPELL_EFFECTS]
Definition Spell.h:122