TrinityCore
Loading...
Searching...
No Matches
spell_hunter.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/*
19 * Scripts for spells with SPELLFAMILY_HUNTER, SPELLFAMILY_PET and SPELLFAMILY_GENERIC spells used by hunter players.
20 * Ordered alphabetically using scriptname.
21 * Scriptnames of files in this file should be prefixed with "spell_hun_".
22 */
23
24#include "ScriptMgr.h"
25#include "CellImpl.h"
26#include "GridNotifiersImpl.h"
27#include "Pet.h"
28#include "SpellAuraEffects.h"
29#include "SpellHistory.h"
30#include "SpellMgr.h"
31#include "SpellScript.h"
32
34{
81};
82
87
88// 13161 - Aspect of the Beast
123
124// 61669 - Aspect of the Beast
126{
128
129 bool Validate(SpellInfo const* /*spellInfo*/) override
130 {
132 }
133
134 bool Load() override
135 {
136 return GetUnitOwner()->GetSpellModOwner();
137 }
138
139 void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
140 {
143 Remove();
144 }
145
150};
151
152// 34074 - Aspect of the Viper
154{
156
167
168 void HandleProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/)
169 {
171
173 int32 mana = CalculatePct(maxMana, GetTarget()->GetAttackTime(RANGED_ATTACK) / 1000.0f);
174
175 if (AuraEffect const* glyph = GetTarget()->GetAuraEffect(SPELL_HUNTER_GLYPH_OF_ASPECT_OF_THE_VIPER, EFFECT_0))
176 AddPct(mana, glyph->GetAmount());
177
178 CastSpellExtraArgs args(aurEff);
179 args.AddSpellBP0(mana);
181 }
182
183 void OnApply(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
184 {
185 // Hunter T7 4P Bonus
188 }
189
190 void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
191 {
192 // Hunter T7 4P Bonus
195 }
196
203};
204
205// 53209 - Chimera Shot
207{
209
214
216 {
217 Unit* caster = GetCaster();
218 if (Unit* unitTarget = GetHitUnit())
219 {
220 uint32 spellId = 0;
221 int32 basePoint = 0;
222 Unit::AuraApplicationMap const& auras = unitTarget->GetAppliedAuras();
223 for (Unit::AuraApplicationMap::const_iterator i = auras.begin(); i != auras.end(); ++i)
224 {
225 Aura* aura = i->second->GetBase();
226 if (aura->GetCasterGUID() != caster->GetGUID())
227 continue;
228
229 // Search only Serpent Sting, Viper Sting, Scorpid Sting auras
230 flag96 familyFlag = aura->GetSpellInfo()->SpellFamilyFlags;
231 if (!(familyFlag[1] & 0x00000080 || familyFlag[0] & 0x0000C000))
232 continue;
233 if (AuraEffect const* aurEff = aura->GetEffect(EFFECT_0))
234 {
235 // Serpent Sting - Instantly deals 40% of the damage done by your Serpent Sting.
236 if (familyFlag[0] & 0x4000)
237 {
239
240 // calculate damage of basic tick (bonuses are already factored in AuraEffect)
241 basePoint = aurEff->GetAmount() * aurEff->GetTotalTicks();
242 ApplyPct(basePoint, 40);
243 }
244 // Viper Sting - Instantly restores mana to you equal to 60% of the total amount drained by your Viper Sting.
245 else if (familyFlag[1] & 0x00000080)
246 {
248
249 // % of mana drained in max duration
250 basePoint = aurEff->GetAmount() * aurEff->GetTotalTicks();
251
252 // max value
253 int32 maxManaReturn = CalculatePct(static_cast<int32>(caster->GetMaxPower(POWER_MANA)), basePoint * 2);
254 ApplyPct(basePoint, unitTarget->GetMaxPower(POWER_MANA));
255 if (basePoint > maxManaReturn)
256 basePoint = maxManaReturn;
257
258 ApplyPct(basePoint, 60);
259 }
260 // Scorpid Sting - Attempts to Disarm the target for 10 sec. This effect cannot occur more than once per 1 minute.
261 else if (familyFlag[0] & 0x00008000)
263
264 // Refresh aura duration
265 aura->RefreshDuration();
266 }
267 break;
268 }
269
270 if (spellId)
271 {
273 args.AddSpellBP0(basePoint);
274 caster->CastSpell(unitTarget, spellId, args);
275 }
276 }
277 }
278
283};
284
285// -53256 - Cobra Strikes
287{
289
290 bool Validate(SpellInfo const* spellInfo) override
291 {
292 return ValidateSpellInfo({ spellInfo->GetEffect(EFFECT_0).TriggerSpell });
293 }
294
295 void HandleProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/)
296 {
298
299 SpellInfo const* triggeredSpellInfo = sSpellMgr->AssertSpellInfo(aurEff->GetSpellEffectInfo().TriggerSpell);
300
302 args.AddSpellMod(SPELLVALUE_AURA_STACK, triggeredSpellInfo->StackAmount);
303 GetTarget()->CastSpell(nullptr, triggeredSpellInfo->Id, args);
304 }
305
310};
311
312// 53257 - Cobra Strikes (triggered spell)
327
328// 781 - Disengage
330{
332
334 {
335 Unit* caster = GetCaster();
336 if (caster->GetTypeId() == TYPEID_PLAYER && !caster->IsInCombat())
338
339 return SPELL_CAST_OK;
340 }
341
346};
347
348// 56841 - Glyph of Arcane Shot
350{
352
353 bool Validate(SpellInfo const* /*spellInfo*/) override
354 {
356 }
357
358 bool CheckProc(ProcEventInfo& eventInfo)
359 {
360 if (Unit* procTarget = eventInfo.GetActionTarget())
361 {
362 Unit::AuraApplicationMap const& auras = procTarget->GetAppliedAuras();
363 for (Unit::AuraApplicationMap::const_iterator i = auras.begin(); i != auras.end(); ++i)
364 {
365 Aura const* aura = i->second->GetBase();
366 if (aura->GetCasterGUID() != GetTarget()->GetGUID())
367 continue;
368 // Search only Serpent Sting, Viper Sting, Scorpid Sting, Wyvern Sting
370 && aura->GetSpellInfo()->SpellFamilyFlags & flag96(0xC000, 0x1080))
371 return true;
372 }
373 }
374 return false;
375 }
376
377 void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo)
378 {
380 SpellInfo const* procSpell = eventInfo.GetSpellInfo();
381 if (!procSpell)
382 return;
383
384 int32 mana = procSpell->CalcPowerCost(eventInfo.GetActor(), procSpell->GetSchoolMask());
385 ApplyPct(mana, aurEff->GetAmount());
386
387 // castspell refactor note: this is not triggered - is this intended?
389 args.AddSpellBP0(mana);
390 eventInfo.GetActor()->CastSpell(eventInfo.GetActor(), SPELL_HUNTER_GLYPH_OF_ARCANE_SHOT, args);
391 }
392
398};
399
400// 57870 - Glyph of Mend Pet
421
422// -53301 - Explosive Shot
424{
426
427 bool Validate(SpellInfo const* /*spellInfo*/) override
428 {
430 }
431
432 void PeriodicTick(AuraEffect const* aurEff)
433 {
434 if (Unit* caster = GetCaster())
435 {
436 CastSpellExtraArgs args(aurEff);
437 args.AddSpellBP0(aurEff->GetAmount());
438 caster->CastSpell(GetTarget(), SPELL_HUNTER_EXPLOSIVE_SHOT_DAMAGE, args);
439 }
440 }
441
446};
447
448// -53511 - Feeding Frenzy
450{
452
453 bool Validate(SpellInfo const* /*spellInfo*/) override
454 {
456 }
457
458 void PeriodicTick(AuraEffect const* aurEff)
459 {
461
462 uint8 rank = GetSpellInfo()->GetRank();
463 uint32 spellId = triggerSpells[rank - 1];
464
465 if (GetTarget()->GetVictim() && GetTarget()->EnsureVictim()->HasAuraState(AURA_STATE_HEALTHLESS_35_PERCENT))
466 GetTarget()->CastSpell(nullptr, spellId, aurEff);
467 else
469 }
470
475};
476
477// -53290 - Hunting Party
479{
481
482 bool Validate(SpellInfo const* /*spellInfo*/) override
483 {
485 }
486
487 void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo)
488 {
490 eventInfo.GetActor()->CastSpell(nullptr, SPELL_REPLENISHMENT, aurEff);
491 }
492
497};
498
499// -19572 - Improved Mend Pet
526
527// 53412 - Invigoration
529{
531
532 bool Validate(SpellInfo const* /*spellInfo*/) override
533 {
535 }
536
538 {
539 if (Unit* unitTarget = GetHitUnit())
540 if (AuraEffect* aurEff = unitTarget->GetDummyAuraEffect(SPELLFAMILY_HUNTER, 3487, 0))
541 if (roll_chance_i(aurEff->GetAmount()))
542 unitTarget->CastSpell(unitTarget, SPELL_HUNTER_INVIGORATION_TRIGGERED, true);
543 }
544
549};
550
551// 58914 - Kill Command
553{
555
556 bool Validate(SpellInfo const* /*spellInfo*/) override
557 {
559 }
560
561 void HandleProc(AuraEffect const* /*aurEff*/, ProcEventInfo& eventInfo)
562 {
563 // prevent charge drop (aura has both proc charge and stacks)
565
566 if (Unit* owner = eventInfo.GetActor()->GetOwner())
567 owner->RemoveAuraFromStack(SPELL_HUNTER_KILL_COMMAND_HUNTER);
568
569 ModStackAmount(-1);
570 }
571
576};
577
578// 53478 - Last Stand Pet
601
602// -56342 - Lock and Load
604{
606
607 bool Validate(SpellInfo const* /*spellInfo*/) override
608 {
609 return ValidateSpellInfo(
610 {
613 });
614 }
615
616 bool CheckProc(ProcEventInfo& eventInfo)
617 {
619 return false;
620 return true;
621 }
622
623 bool CheckTrapProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo)
624 {
625 if (!(eventInfo.GetTypeMask() & PROC_FLAG_DONE_TRAP_ACTIVATION))
626 return false;
627
628 // Do not proc on traps for immolation/explosive trap
629 SpellInfo const* spellInfo = eventInfo.GetSpellInfo();
630 if (!spellInfo || !(spellInfo->GetSchoolMask() & SPELL_SCHOOL_MASK_FROST))
631 return false;
632
633 return roll_chance_i(aurEff->GetAmount());
634 }
635
636 bool CheckPeriodicProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo)
637 {
638 if (!(eventInfo.GetTypeMask() & PROC_FLAG_DONE_PERIODIC))
639 return false;
640
641 return roll_chance_i(aurEff->GetAmount());
642 }
643
644 void HandleProc(ProcEventInfo& eventInfo)
645 {
647
648 Unit* caster = eventInfo.GetActor();
649 caster->CastSpell(caster, SPELL_HUNTER_LOCK_AND_LOAD_TRIGGER, true);
650 caster->CastSpell(caster, SPELL_HUNTER_LOCK_AND_LOAD_MARKER, true);
651 }
652
662};
663
664// 53271 - Masters Call
666{
668
669 bool Validate(SpellInfo const* spellInfo) override
670 {
671 return ValidateSpellInfo(
672 {
674 static_cast<uint32>(spellInfo->GetEffect(EFFECT_0).CalcValue()),
675 static_cast<uint32>(spellInfo->GetEffect(EFFECT_1).CalcValue())
676 });
677 }
678
679 bool Load() override
680 {
681 return GetCaster()->GetTypeId() == TYPEID_PLAYER;
682 }
683
685 {
687 ASSERT(pet); // checked in Spell::CheckCast
688
689 if (!pet->IsPet() || !pet->IsAlive())
690 return SPELL_FAILED_NO_PET;
691
692 // Do a mini Spell::CheckCasterAuras on the pet, no other way of doing this
694 uint32 const unitflag = pet->GetUnitFlags();
695 if (!pet->GetCharmerGUID().IsEmpty())
696 result = SPELL_FAILED_CHARMED;
697 else if (unitflag & UNIT_FLAG_STUNNED)
698 result = SPELL_FAILED_STUNNED;
699 else if (unitflag & UNIT_FLAG_FLEEING)
700 result = SPELL_FAILED_FLEEING;
701 else if (unitflag & UNIT_FLAG_CONFUSED)
702 result = SPELL_FAILED_CONFUSED;
703
704 if (result != SPELL_CAST_OK)
705 return result;
706
707 Unit* target = GetExplTargetUnit();
708 if (!target)
710
711 if (!pet->IsWithinLOSInMap(target))
713
714 return SPELL_CAST_OK;
715 }
716
717 void HandleDummy(SpellEffIndex /*effIndex*/)
718 {
720 }
721
723 {
725 }
726
734};
735
736// 34477 - Misdirection
764
765// 35079 - Misdirection (Proc)
780
781// 1742 - Pet Cower
783{
785
786 void CalculateAmount(AuraEffect const* /*aurEff*/, int32& amount, bool& /*canBeRecalculated*/)
787 {
788 if (AuraEffect const* improvedCower = GetUnitOwner()->GetDummyAuraEffect(SPELLFAMILY_PET, SPELL_ICON_HUNTER_PET_IMPROVED_COWER, EFFECT_0))
789 AddPct(amount, improvedCower->GetAmount());
790 }
791
796};
797
798// 54044 - Pet Carrion Feeder
800{
802
803 bool Load() override
804 {
805 if (!GetCaster()->IsPet())
806 return false;
807 return true;
808 }
809
810 bool Validate(SpellInfo const* /*spellInfo*/) override
811 {
813 }
814
816 {
817 Unit* caster = GetCaster();
818 float max_range = GetSpellInfo()->GetMaxRange(false);
819 WorldObject* result = nullptr;
820 // search for nearby enemy corpse in range
823 Cell::VisitWorldObjects(caster, searcher, max_range);
824 if (!result)
825 Cell::VisitGridObjects(caster, searcher, max_range);
826 if (!result)
828 return SPELL_CAST_OK;
829 }
830
831 void HandleDummy(SpellEffIndex /*effIndex*/)
832 {
833 Unit* caster = GetCaster();
835 }
836
842};
843
844// 55709 - Pet Heart of the Phoenix
846{
848
849 bool Load() override
850 {
851 if (!GetCaster()->IsPet())
852 return false;
853 return true;
854 }
855
860
861 void HandleScript(SpellEffIndex /*effIndex*/)
862 {
863 Unit* caster = GetCaster();
864 if (Unit* owner = caster->GetOwner())
865 {
867 {
869 args.AddSpellBP0(100); // @todo shouldn't this be in spellmgr if it's constant?
870 owner->CastSpell(caster, SPELL_HUNTER_PET_HEART_OF_THE_PHOENIX_TRIGGERED, args);
872 }
873 }
874 }
875
880};
881
882// -53234 - Piercing Shots
884{
886
887 bool Validate(SpellInfo const* /*spellInfo*/) override
888 {
890 }
891
892 bool CheckProc(ProcEventInfo& eventInfo)
893 {
894 if (eventInfo.GetActionTarget())
895 return true;
896 return false;
897 }
898
899 void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo)
900 {
902 Unit* caster = eventInfo.GetActor();
903 Unit* target = eventInfo.GetActionTarget();
904
905 if (DamageInfo* dmgInfo = eventInfo.GetDamageInfo())
906 {
907 SpellInfo const* piercingShots = sSpellMgr->AssertSpellInfo(SPELL_HUNTER_PIERCING_SHOTS);
908 uint32 dmg = dmgInfo->GetDamage();
909
910 int32 bp = CalculatePct(int32(dmg), aurEff->GetAmount()) / static_cast<int32>(piercingShots->GetMaxTicks());
911
912 CastSpellExtraArgs args(aurEff);
913 args.AddSpellBP0(bp);
914 caster->CastSpell(target, SPELL_HUNTER_PIERCING_SHOTS, args);
915 }
916 }
917
923};
924
925// 56654, 58882 - Rapid Recuperation
927{
929
930 bool Validate(SpellInfo const* spellInfo) override
931 {
932 return ValidateSpellInfo({ spellInfo->GetEffect(EFFECT_0).TriggerSpell });
933 }
934
935 void HandlePeriodic(AuraEffect const* aurEff)
936 {
938
939 Unit* target = GetTarget();
940 CastSpellExtraArgs args(aurEff);
941 args.AddSpellBP0(CalculatePct(target->GetMaxPower(POWER_MANA), aurEff->GetAmount()));
942 target->CastSpell(target, aurEff->GetSpellEffectInfo().TriggerSpell, args);
943 }
944
949};
950
951// -53228 - Rapid Recuperation (talent aura)
953{
955
956 bool Validate(SpellInfo const* /*spellInfo*/) override
957 {
958 return ValidateSpellInfo(
959 {
962 });
963 }
964
965 void HandleRapidFireProc(AuraEffect const* /*aurEff*/, ProcEventInfo& eventInfo)
966 {
967 // Proc only from Rapid Fire
968 SpellInfo const* spellInfo = eventInfo.GetSpellInfo();
969 if (!spellInfo || !(spellInfo->SpellFamilyFlags[0] & 0x00000020))
970 {
972 return;
973 }
974 }
975
976 void HandleRapidKillingProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo)
977 {
979
981
982 // Proc only from Rapid Killing
983 SpellInfo const* spellInfo = eventInfo.GetSpellInfo();
984 if (!spellInfo || !(spellInfo->SpellFamilyFlags[1] & 0x01000000))
985 return;
986
987 uint8 rank = GetSpellInfo()->GetRank();
988 uint32 spellId = triggerSpells[rank - 1];
989 eventInfo.GetActor()->CastSpell(nullptr, spellId, aurEff);
990 }
991
997};
998
999// 23989 - Readiness
1001{
1003
1004 bool Load() override
1005 {
1006 return GetCaster()->GetTypeId() == TYPEID_PLAYER;
1007 }
1008
1009 void HandleDummy(SpellEffIndex /*effIndex*/)
1010 {
1011 // immediately finishes the cooldown on your other Hunter abilities except Bestial Wrath
1012 GetCaster()->GetSpellHistory()->ResetCooldowns([](SpellHistory::CooldownStorageType::iterator itr) -> bool
1013 {
1014 SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(itr->first);
1015
1017 if (spellInfo->SpellFamilyName == SPELLFAMILY_HUNTER &&
1018 spellInfo->Id != SPELL_HUNTER_READINESS &&
1019 spellInfo->Id != SPELL_HUNTER_BESTIAL_WRATH &&
1020 spellInfo->Id != SPELL_DRAENEI_GIFT_OF_THE_NAARU &&
1021 spellInfo->GetRecoveryTime() > 0)
1022 return true;
1023 return false;
1024 }, true);
1025 }
1026
1031};
1032
1033// 53480 - Roar of Sacrifice
1035{
1037
1038 bool Validate(SpellInfo const* /*spellInfo*/) override
1039 {
1041 }
1042
1043 bool CheckProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo)
1044 {
1045 DamageInfo* damageInfo = eventInfo.GetDamageInfo();
1046 if (!damageInfo || !(damageInfo->GetSchoolMask() & aurEff->GetMiscValue()))
1047 return false;
1048
1049 if (!GetCaster())
1050 return false;
1051
1052 return true;
1053 }
1054
1055 void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo)
1056 {
1058
1059 CastSpellExtraArgs args(aurEff);
1060 args.AddSpellBP0(CalculatePct(eventInfo.GetDamageInfo()->GetDamage(), aurEff->GetAmount()));
1062 }
1063
1069};
1070
1071// 37506 - Scatter Shot
1073{
1075
1076 bool Load() override
1077 {
1078 return GetCaster()->GetTypeId() == TYPEID_PLAYER;
1079 }
1080
1081 void HandleDummy(SpellEffIndex /*effIndex*/)
1082 {
1083 Player* caster = GetCaster()->ToPlayer();
1084 // break Auto Shot and autohit
1086 caster->AttackStop();
1088 }
1089
1094};
1095
1096// -53302 - Sniper Training
1098{
1100
1101 bool Validate(SpellInfo const* /*spellInfo*/) override
1102 {
1104 }
1105
1106 void HandlePeriodic(AuraEffect const* aurEff)
1107 {
1109 if (aurEff->GetAmount() <= 0)
1110 {
1111 Unit* target = GetTarget();
1113 target->CastSpell(target, spellId, aurEff);
1114 if (Player* playerTarget = GetUnitOwner()->ToPlayer())
1115 {
1116 int32 baseAmount = aurEff->GetBaseAmount();
1117 int32 amount = playerTarget->CalculateSpellDamage(aurEff->GetSpellEffectInfo(), &baseAmount);
1118 GetEffect(EFFECT_0)->SetAmount(amount);
1119 }
1120 }
1121 }
1122
1124 {
1125 if (Player* playerTarget = GetUnitOwner()->ToPlayer())
1126 {
1127 int32 baseAmount = aurEff->GetBaseAmount();
1128 int32 amount = playerTarget->isMoving() ?
1129 playerTarget->CalculateSpellDamage(aurEff->GetSpellEffectInfo(), &baseAmount) :
1130 aurEff->GetAmount() - 1;
1131 aurEff->SetAmount(amount);
1132 }
1133 }
1134
1140};
1141
1142// 1515 - Tame Beast
1144{
1146
1148 {
1149 Player* caster = GetCaster()->ToPlayer();
1150 if (!caster)
1152
1153 if (!GetExplTargetUnit())
1155
1156 if (Creature* target = GetExplTargetUnit()->ToCreature())
1157 {
1158 if (target->GetLevel() > caster->GetLevel())
1160
1161 // use SMSG_PET_TAME_FAILURE?
1162 if (!target->GetCreatureTemplate()->IsTameable(caster->CanTameExoticPets()))
1164
1165 PetStable const* petStable = caster->GetPetStable();
1166 if (petStable)
1167 {
1168 if (petStable->CurrentPet)
1170
1171 if (petStable->GetUnslottedHunterPet())
1172 {
1175 }
1176 }
1177
1178 if (!caster->GetCharmedGUID().IsEmpty())
1180
1181 if (!target->GetOwnerGUID().IsEmpty())
1182 {
1185 }
1186 }
1187 else
1189
1190 return SPELL_CAST_OK;
1191 }
1192
1197};
1198
1199// -24604 - Furious Howl
1200// 53434 - Call of the Wild
1219
1220// -34497 - Thrill of the Hunt
1222{
1224
1225 bool Validate(SpellInfo const* /*spellInfo*/) override
1226 {
1228 }
1229
1230 void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo)
1231 {
1233 SpellInfo const* spellInfo = eventInfo.GetSpellInfo();
1234 if (!spellInfo)
1235 return;
1236
1237 Unit* caster = eventInfo.GetActor();
1238 int32 amount = 0;
1239
1240 // Explosive Shot
1241 if (spellInfo->SpellFamilyFlags[2] & 0x200)
1242 {
1243 if (AuraEffect const* explosiveShot = eventInfo.GetActionTarget()->GetAuraEffect(SPELL_AURA_PERIODIC_DUMMY, SPELLFAMILY_HUNTER, 0x00000000, 0x80000000, 0x00000000, caster->GetGUID()))
1244 {
1245 // due to Lock and Load SpellInfo::CalcPowerCost might return 0, so just calculate it manually
1246 amount = CalculatePct(static_cast<int32>(CalculatePct(caster->GetCreateMana(), explosiveShot->GetSpellInfo()->ManaCostPercentage)), aurEff->GetAmount());
1247
1248 ASSERT(explosiveShot->GetSpellInfo()->GetMaxTicks() > 0);
1249 amount /= explosiveShot->GetSpellInfo()->GetMaxTicks();
1250 }
1251 }
1252 else
1253 amount = CalculatePct(static_cast<int32>(spellInfo->CalcPowerCost(caster, spellInfo->GetSchoolMask())), aurEff->GetAmount());
1254
1255 if (!amount)
1256 return;
1257
1258 CastSpellExtraArgs args(aurEff);
1259 args.AddSpellBP0(amount);
1260 caster->CastSpell(nullptr, SPELL_HUNTER_THRILL_OF_THE_HUNT_MANA, args);
1261 }
1262
1267};
1268
1269// 67151 - Item - Hunter T9 4P Bonus (Steady Shot)
1271{
1273
1274 bool Validate(SpellInfo const* /*spellInfo*/) override
1275 {
1277 }
1278
1279 bool CheckProc(ProcEventInfo& eventInfo)
1280 {
1281 if (eventInfo.GetActor()->GetTypeId() == TYPEID_PLAYER && eventInfo.GetActor()->ToPlayer()->GetPet())
1282 return true;
1283 return false;
1284 }
1285
1286 void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo)
1287 {
1289 Unit* caster = eventInfo.GetActor();
1290
1291 caster->CastSpell(caster->ToPlayer()->GetPet(), SPELL_HUNTER_T9_4P_GREATNESS, aurEff);
1292 }
1293
1299};
1300
1301// 60144 - Viper Attack Speed
1333
1334// -19386 - Wyvern Sting
1336{
1338
1351
1352 void OnRemove(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
1353 {
1354 uint8 rank = sSpellMgr->GetSpellRank(GetId());
1355 uint32 spellId = sSpellMgr->GetSpellWithRank(SPELL_HUNTER_WYVERN_STING_DOT_R1, rank);
1356 if (Unit* caster = GetCaster())
1357 caster->CastSpell(GetTarget(), spellId, aurEff);
1358 }
1359
1364};
1365
1367{
1404}
uint8_t uint8
Definition Define.h:135
int32_t int32
Definition Define.h:129
uint32_t uint32
Definition Define.h:133
#define ASSERT_NOTNULL(pointer)
Definition Errors.h:84
#define ASSERT
Definition Errors.h:68
@ TYPEID_PLAYER
Definition ObjectGuid.h:39
bool roll_chance_i(int chance)
Definition Random.h:59
#define RegisterSpellScript(spell_script)
Definition ScriptMgr.h:1128
SpellEffIndex
@ EFFECT_1
@ EFFECT_0
@ SPELL_EFFECT_DUMMY
@ SPELL_EFFECT_SCRIPT_EFFECT
@ TARGET_UNIT_CASTER_AREA_PARTY
@ SPELL_SCHOOL_MASK_FROST
@ RANGED_ATTACK
@ PETTAME_CREATUREALREADYOWNED
@ PETTAME_TOOMANY
@ SPELLFAMILY_HUNTER
@ SPELLFAMILY_PET
@ POWER_MANA
@ AURA_STATE_HEALTHLESS_35_PERCENT
SpellCastResult
@ SPELL_FAILED_STUNNED
@ SPELL_FAILED_BAD_IMPLICIT_TARGETS
@ SPELL_FAILED_ALREADY_HAVE_SUMMON
@ SPELL_FAILED_ALREADY_HAVE_CHARM
@ SPELL_FAILED_HIGHLEVEL
@ SPELL_FAILED_DONT_REPORT
@ SPELL_FAILED_CANT_DO_THAT_RIGHT_NOW
@ SPELL_FAILED_BAD_TARGETS
@ SPELL_FAILED_CONFUSED
@ SPELL_CAST_OK
@ SPELL_FAILED_CHARMED
@ SPELL_FAILED_LINE_OF_SIGHT
@ SPELL_FAILED_FLEEING
@ SPELL_FAILED_NO_PET
@ SPELL_FAILED_NO_EDIBLE_CORPSES
@ AURA_REMOVE_BY_DEFAULT
AuraEffectHandleModes
@ AURA_EFFECT_HANDLE_REAL
@ SPELL_AURA_UNTRACKABLE
@ SPELL_AURA_PROC_TRIGGER_SPELL
@ SPELL_AURA_OBS_MOD_POWER
@ SPELL_AURA_ADD_FLAT_MODIFIER
@ SPELL_AURA_DUMMY
@ SPELL_AURA_MOD_DECREASE_SPEED
@ SPELL_AURA_PERIODIC_DUMMY
@ SPELL_AURA_PERIODIC_TRIGGER_SPELL
@ SPELL_AURA_MOD_STUN
@ TRIGGERED_FULL_MASK
Will return SPELL_FAILED_DONT_REPORT in CheckCast functions.
@ TRIGGERED_IGNORE_SPELL_AND_CATEGORY_CD
Will ignore GCD.
@ SPELLVALUE_AURA_STACK
@ TARGET_CHECK_ENEMY
Definition SpellInfo.h:81
#define sSpellMgr
Definition SpellMgr.h:738
@ PROC_FLAG_DONE_PERIODIC
Definition SpellMgr.h:142
@ PROC_FLAG_DONE_TRAP_ACTIVATION
Definition SpellMgr.h:146
#define AuraProcFn(F)
#define SpellCheckCastFn(F)
#define AuraEffectProcFn(F, I, N)
#define SpellEffectFn(F, I, N)
#define AuraEffectCalcAmountFn(F, I, N)
#define SpellObjectAreaTargetSelectFn(F, I, N)
#define AuraEffectPeriodicFn(F, I, N)
#define AuraCheckEffectProcFn(F, I, N)
#define AuraEffectUpdatePeriodicFn(F, I, N)
#define AuraEffectApplyFn(F, I, N, M)
#define AuraCheckProcFn(F)
#define AuraEffectRemoveFn(F, I, N, M)
@ UNIT_FLAG_STUNNED
@ UNIT_FLAG_CONFUSED
@ UNIT_FLAG_FLEEING
@ CURRENT_AUTOREPEAT_SPELL
Definition Unit.h:609
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
SpellEffectInfo const & GetSpellEffectInfo() const
void SetAmount(int32 amount)
int32 GetMiscValue() const
int32 GetBaseAmount() const
int32 GetAmount() const
void PreventDefaultAction()
AuraApplication const * GetTargetApplication() const
HookList< EffectApplyHandler > AfterEffectRemove
HookList< CheckEffectProcHandler > DoCheckEffectProc
HookList< EffectPeriodicHandler > OnEffectPeriodic
SpellInfo const * GetSpellInfo() const
WorldObject * GetOwner() const
HookList< EffectApplyHandler > AfterEffectApply
HookList< EffectCalcAmountHandler > DoEffectCalcAmount
Unit * GetCaster() const
HookList< EffectUpdatePeriodicHandler > OnEffectUpdatePeriodic
AuraEffect * GetEffect(uint8 effIndex) const
Unit * GetTarget() const
HookList< CheckProcHandler > DoCheckProc
void Remove(AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
HookList< EffectProcHandler > OnEffectProc
Unit * GetUnitOwner() const
HookList< AuraProcHandler > OnProc
HookList< EffectApplyHandler > OnEffectApply
uint32 GetId() const
bool ModStackAmount(int32 num, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
void RefreshDuration(bool withMods=false)
ObjectGuid GetCasterGUID() const
Definition SpellAuras.h:119
AuraEffect * GetEffect(uint8 effIndex) const
Definition SpellAuras.h:201
SpellInfo const * GetSpellInfo() const
Definition SpellAuras.h:115
SpellSchoolMask GetSchoolMask() const
Definition Unit.h:461
uint32 GetDamage() const
Definition Unit.h:464
bool IsEmpty() const
Definition ObjectGuid.h:172
TypeID GetTypeId() const
Definition Object.h:93
static ObjectGuid GetGUID(Object const *o)
Definition Object.h:78
static Player * ToPlayer(Object *o)
Definition Object.h:180
PetInfo const * GetUnslottedHunterPet() const
Definition PetDefines.h:117
Optional< PetInfo > CurrentPet
Definition PetDefines.h:112
Definition Pet.h:40
void SendAttackSwingCancelAttack() const
Definition Player.cpp:20067
bool CanTameExoticPets() const
Definition Player.h:1902
PetStable * GetPetStable()
Definition Player.h:1067
Pet * GetPet() const
Definition Player.cpp:20286
void SendTameFailure(uint8 result)
Definition Player.cpp:2781
Unit * GetActionTarget() const
Definition Unit.h:509
uint32 GetTypeMask() const
Definition Unit.h:511
SpellInfo const * GetSpellInfo() const
Definition Unit.cpp:268
Unit * GetActor()
Definition Unit.h:508
DamageInfo * GetDamageInfo() const
Definition Unit.h:519
uint32 TriggerSpell
Definition SpellInfo.h:228
int32 CalcValue(WorldObject const *caster=nullptr, int32 const *basePoints=nullptr) const
void ResetCooldowns(Predicate predicate, bool update=false)
uint32 GetMaxTicks() const
float GetMaxRange(bool positive=false, WorldObject *caster=nullptr, Spell *spell=nullptr) const
flag96 SpellFamilyFlags
Definition SpellInfo.h:357
uint32 StackAmount
Definition SpellInfo.h:340
uint32 Id
Definition SpellInfo.h:289
uint8 GetRank() const
uint32 GetRecoveryTime() const
SpellSchoolMask GetSchoolMask() const
int32 CalcPowerCost(WorldObject const *caster, SpellSchoolMask schoolMask, Spell *spell=nullptr) const
SpellEffectInfo const & GetEffect(SpellEffIndex index) const
Definition SpellInfo.h:483
uint32 SpellFamilyName
Definition SpellInfo.h:356
HookList< CheckCastHandler > OnCheckCast
Unit * GetCaster() const
HookList< EffectHandler > OnEffectHit
Unit * GetHitUnit() const
int32 GetEffectValue() const
HookList< EffectHandler > OnEffectHitTarget
Unit * GetExplTargetUnit() const
SpellInfo const * GetSpellInfo() const
HookList< ObjectAreaTargetSelectHandler > OnObjectAreaTargetSelect
void UnregisterRedirectThreat(uint32 spellId)
Definition Unit.h:769
ThreatManager & GetThreatManager()
Definition Unit.h:1155
std::multimap< uint32, AuraApplication * > AuraApplicationMap
Definition Unit.h:780
bool IsPet() const
Definition Unit.h:884
ObjectGuid GetCharmedGUID() const
Definition Unit.h:1255
AuraEffect * GetAuraEffect(uint32 spellId, uint8 effIndex, ObjectGuid casterGUID=ObjectGuid::Empty) const
Definition Unit.cpp:4359
bool IsAlive() const
Definition Unit.h:1234
UnitFlags GetUnitFlags() const
Definition Unit.h:952
bool HasAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint8 reqEffMask=0) const
Definition Unit.cpp:4535
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
void RemoveAurasDueToSpell(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, uint8 reqEffMask=0, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition Unit.cpp:3784
uint32 CountPctFromMaxHealth(int32 pct) const
Definition Unit.h:922
SpellHistory * GetSpellHistory()
Definition Unit.h:1484
ObjectGuid GetCharmerGUID() const
Definition Unit.h:1252
uint32 GetCreateMana() const
Definition Unit.h:1452
Guardian * GetGuardianPet() const
Definition Unit.cpp:5894
bool AttackStop()
Definition Unit.cpp:5645
uint8 GetLevel() const
Definition Unit.h:889
bool IsInCombat() const
Definition Unit.h:1144
SpellCastResult CastSpell(CastSpellTargetArg const &targets, uint32 spellId, CastSpellExtraArgs const &args={ })
Definition Object.cpp:2832
Unit * GetOwner() const
Definition Object.cpp:2180
bool IsWithinLOSInMap(WorldObject const *obj, LineOfSightChecks checks=LINEOFSIGHT_ALL_CHECKS, VMAP::ModelIgnoreFlags ignoreFlags=VMAP::ModelIgnoreFlags::Nothing) const
Definition Object.cpp:1226
Player * GetSpellModOwner() const
Definition Object.cpp:2223
static bool ValidateSpellInfo(std::initializer_list< uint32 > spellIds)
Definition Util.h:412
void OnRemove(AuraEffect const *, AuraEffectHandleModes)
PrepareAuraScript(spell_hun_ascpect_of_the_viper)
void HandleProc(AuraEffect const *aurEff, ProcEventInfo &)
bool Validate(SpellInfo const *) override
void OnApply(AuraEffect const *aurEff, AuraEffectHandleModes)
PrepareAuraScript(spell_hun_aspect_of_the_beast_pet)
void OnApply(AuraEffect const *, AuraEffectHandleModes)
bool Validate(SpellInfo const *) override
PrepareAuraScript(spell_hun_aspect_of_the_beast)
void OnApply(AuraEffect const *, AuraEffectHandleModes)
void OnRemove(AuraEffect const *, AuraEffectHandleModes)
bool Validate(SpellInfo const *) override
void Register() override
bool Validate(SpellInfo const *) override
void HandleScriptEffect(SpellEffIndex)
PrepareSpellScript(spell_hun_chimera_shot)
void HandleStackDrop(AuraEffect const *, ProcEventInfo &)
PrepareAuraScript(spell_hun_cobra_strikes_triggered)
PrepareAuraScript(spell_hun_cobra_strikes)
void HandleProc(AuraEffect const *aurEff, ProcEventInfo &)
bool Validate(SpellInfo const *spellInfo) override
void Register() override
SpellCastResult CheckCast()
PrepareSpellScript(spell_hun_disengage)
bool Validate(SpellInfo const *) override
void PeriodicTick(AuraEffect const *aurEff)
PrepareAuraScript(spell_hun_explosive_shot)
void PeriodicTick(AuraEffect const *aurEff)
PrepareAuraScript(spell_hun_feeding_frenzy)
bool Validate(SpellInfo const *) override
bool Validate(SpellInfo const *) override
void HandleProc(AuraEffect const *aurEff, ProcEventInfo &eventInfo)
bool CheckProc(ProcEventInfo &eventInfo)
PrepareAuraScript(spell_hun_glyph_of_arcane_shot)
PrepareAuraScript(spell_hun_glyph_of_mend_pet)
void HandleProc(AuraEffect const *aurEff, ProcEventInfo &eventInfo)
bool Validate(SpellInfo const *) override
PrepareAuraScript(spell_hun_hunting_party)
void HandleProc(AuraEffect const *aurEff, ProcEventInfo &eventInfo)
bool Validate(SpellInfo const *) override
PrepareAuraScript(spell_hun_improved_mend_pet)
bool CheckProc(ProcEventInfo &)
bool Validate(SpellInfo const *) override
void HandleProc(AuraEffect const *aurEff, ProcEventInfo &)
PrepareSpellScript(spell_hun_invigoration)
void Register() override
bool Validate(SpellInfo const *) override
void HandleScriptEffect(SpellEffIndex)
void HandleProc(AuraEffect const *, ProcEventInfo &eventInfo)
PrepareAuraScript(spell_hun_kill_command_pet)
bool Validate(SpellInfo const *) override
bool Validate(SpellInfo const *) override
void HandleDummy(SpellEffIndex)
PrepareSpellScript(spell_hun_last_stand_pet)
bool CheckTrapProc(AuraEffect const *aurEff, ProcEventInfo &eventInfo)
bool CheckProc(ProcEventInfo &eventInfo)
bool Validate(SpellInfo const *) override
PrepareAuraScript(spell_hun_lock_and_load)
void HandleProc(ProcEventInfo &eventInfo)
bool CheckPeriodicProc(AuraEffect const *aurEff, ProcEventInfo &eventInfo)
SpellCastResult DoCheckCast()
void HandleDummy(SpellEffIndex)
void HandleScriptEffect(SpellEffIndex)
bool Validate(SpellInfo const *spellInfo) override
void Register() override
PrepareSpellScript(spell_hun_masters_call)
PrepareAuraScript(spell_hun_misdirection_proc)
void OnRemove(AuraEffect const *, AuraEffectHandleModes)
bool Validate(SpellInfo const *) override
void OnRemove(AuraEffect const *, AuraEffectHandleModes)
PrepareAuraScript(spell_hun_misdirection)
void HandleProc(AuraEffect const *aurEff, ProcEventInfo &)
void Register() override
bool Validate(SpellInfo const *) override
void HandleDummy(SpellEffIndex)
SpellCastResult CheckIfCorpseNear()
PrepareSpellScript(spell_hun_pet_carrion_feeder)
void CalculateAmount(AuraEffect const *, int32 &amount, bool &)
PrepareAuraScript(spell_hun_pet_cower)
void Register() override
PrepareSpellScript(spell_hun_pet_heart_of_the_phoenix)
bool Validate(SpellInfo const *) override
bool Validate(SpellInfo const *) override
void HandleProc(AuraEffect const *aurEff, ProcEventInfo &eventInfo)
bool CheckProc(ProcEventInfo &eventInfo)
PrepareAuraScript(spell_hun_piercing_shots)
bool Validate(SpellInfo const *) override
void HandleRapidKillingProc(AuraEffect const *aurEff, ProcEventInfo &eventInfo)
void HandleRapidFireProc(AuraEffect const *, ProcEventInfo &eventInfo)
PrepareAuraScript(spell_hun_rapid_recuperation_trigger)
PrepareAuraScript(spell_hun_rapid_recuperation)
bool Validate(SpellInfo const *spellInfo) override
void HandlePeriodic(AuraEffect const *aurEff)
void Register() override
void HandleDummy(SpellEffIndex)
bool Load() override
PrepareSpellScript(spell_hun_readiness)
void HandleProc(AuraEffect const *aurEff, ProcEventInfo &eventInfo)
bool CheckProc(AuraEffect const *aurEff, ProcEventInfo &eventInfo)
bool Validate(SpellInfo const *) override
PrepareAuraScript(spell_hun_roar_of_sacrifice)
PrepareSpellScript(spell_hun_scatter_shot)
void HandleDummy(SpellEffIndex)
PrepareAuraScript(spell_hun_sniper_training)
bool Validate(SpellInfo const *) override
void HandlePeriodic(AuraEffect const *aurEff)
void HandleUpdatePeriodic(AuraEffect *aurEff)
bool Validate(SpellInfo const *) override
void Register() override
void HandleProc(AuraEffect const *aurEff, ProcEventInfo &eventInfo)
PrepareAuraScript(spell_hun_t9_4p_bonus)
bool CheckProc(ProcEventInfo &eventInfo)
void Register() override
SpellCastResult CheckCast()
PrepareSpellScript(spell_hun_tame_beast)
void FilterTargets(std::list< WorldObject * > &targets)
PrepareSpellScript(spell_hun_target_only_pet_and_owner)
void HandleProc(AuraEffect const *aurEff, ProcEventInfo &eventInfo)
bool Validate(SpellInfo const *) override
PrepareAuraScript(spell_hun_thrill_of_the_hunt)
void OnRemove(AuraEffect const *, AuraEffectHandleModes)
bool Validate(SpellInfo const *) override
PrepareAuraScript(spell_hun_viper_attack_speed)
void OnApply(AuraEffect const *aurEff, AuraEffectHandleModes)
PrepareAuraScript(spell_hun_wyvern_sting)
bool Validate(SpellInfo const *) override
void OnRemove(AuraEffect const *aurEff, AuraEffectHandleModes)
@ SPELL_HUNTER_CHIMERA_SHOT_SCORPID
@ SPELL_HUNTER_VIPER_ATTACK_SPEED
@ SPELL_HUNTER_INVIGORATION_TRIGGERED
@ SPELL_HUNTER_PET_HEART_OF_THE_PHOENIX
@ SPELL_HUNTER_WYVERN_STING_DOT_R4
@ SPELL_HUNTER_THRILL_OF_THE_HUNT_MANA
@ SPELL_HUNTER_GLYPH_OF_ARCANE_SHOT
@ SPELL_HUNTER_CHIMERA_SHOT_VIPER
@ SPELL_HUNTER_SNIPER_TRAINING_R1
@ SPELL_HUNTER_ASPECT_OF_THE_VIPER_ENERGIZE
@ SPELL_HUNTER_LOCK_AND_LOAD_MARKER
@ SPELL_HUNTER_KILL_COMMAND_HUNTER
@ SPELL_HUNTER_FEEDING_FRENZY_BUFF_R2
@ SPELL_HUNTER_WYVERN_STING_DOT_R1
@ SPELL_HUNTER_SNIPER_TRAINING_BUFF_R1
@ SPELL_HUNTER_MISDIRECTION_PROC
@ SPELL_HUNTER_GLYPH_OF_MEND_PET_HAPPINESS
@ SPELL_HUNTER_FEEDING_FRENZY_BUFF_R1
@ SPELL_HUNTER_MISDIRECTION
@ SPELL_HUNTER_WYVERN_STING_DOT_R6
@ SPELL_HUNTER_READINESS
@ SPELL_HUNTER_MASTERS_CALL_TRIGGERED
@ SPELL_HUNTER_GLYPH_OF_ASPECT_OF_THE_VIPER
@ SPELL_HUNTER_RAPID_RECUPERATION_MANA_R2
@ SPELL_HUNTER_WYVERN_STING_DOT_R3
@ SPELL_HUNTER_LOCK_AND_LOAD_TRIGGER
@ SPELL_HUNTER_PET_HEART_OF_THE_PHOENIX_DEBUFF
@ SPELL_HUNTER_WYVERN_STING_DOT_R2
@ SPELL_HUNTER_PET_HEART_OF_THE_PHOENIX_TRIGGERED
@ SPELL_DRAENEI_GIFT_OF_THE_NAARU
@ SPELL_HUNTER_WYVERN_STING_DOT_R5
@ SPELL_HUNTER_VICIOUS_VIPER
@ SPELL_HUNTER_ASPECT_OF_THE_BEAST
@ SPELL_HUNTER_RAPID_RECUPERATION_MANA_R1
@ SPELL_ROAR_OF_SACRIFICE_TRIGGERED
@ SPELL_HUNTER_ASPECT_OF_THE_BEAST_PET
@ SPELL_HUNTER_PET_CARRION_FEEDER_TRIGGERED
@ SPELL_REPLENISHMENT
@ SPELL_HUNTER_ASPECT_OF_THE_VIPER
@ SPELL_HUNTER_PET_LAST_STAND_TRIGGERED
@ SPELL_HUNTER_BESTIAL_WRATH
@ SPELL_HUNTER_IMPROVED_MEND_PET
@ SPELL_HUNTER_EXPLOSIVE_SHOT_DAMAGE
@ SPELL_HUNTER_CHIMERA_SHOT_SERPENT
@ SPELL_HUNTER_T9_4P_GREATNESS
@ SPELL_HUNTER_PIERCING_SHOTS
HunterSpellIcons
@ SPELL_ICON_HUNTER_PET_IMPROVED_COWER
void AddSC_hunter_spell_scripts()
CastSpellExtraArgs & AddSpellBP0(int32 val)
CastSpellExtraArgs & AddSpellMod(SpellValueMod mod, int32 val)
static void VisitGridObjects(WorldObject const *obj, T &visitor, float radius, bool dont_load=true)
Definition CellImpl.h:168
static void VisitWorldObjects(WorldObject const *obj, T &visitor, float radius, bool dont_load=true)
Definition CellImpl.h:180