TrinityCore
boss_professor_putricide.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 "icecrown_citadel.h"
19#include "Containers.h"
20#include "DB2Stores.h"
21#include "GridNotifiers.h"
22#include "Group.h"
23#include "InstanceScript.h"
24#include "Map.h"
25#include "MotionMaster.h"
26#include "ObjectAccessor.h"
27#include "ScriptedCreature.h"
28#include "ScriptMgr.h"
29#include "Spell.h"
30#include "SpellAuraEffects.h"
31#include "SpellMgr.h"
32#include "SpellScript.h"
33#include "TemporarySummon.h"
34#include "Vehicle.h"
35
36enum Say
37{
38 // Festergut
41
42 // Rotface
45
46 // Professor Putricide
51 SAY_TRANSFORM_2 = 8, // always used for phase2 change, DO NOT GROUP WITH SAY_TRANSFORM_1
56 SAY_DEATH = 13
57};
58
60{
61 // Festergut
68
69 // Professor Putricide
73 SPELL_TEAR_GAS = 71617, // phase transition
80 SPELL_OOZE_TANK_PROTECTION = 71770, // protects the tank
90
91 // Slime Puddle
93 SPELL_GROW = 70347,
95
96 // Gas Cloud
101
102 // Volatile Ooze
107
108 // Choking Gas Bomb
111
112 // Mutated Abomination vehicle
117
118 // Unholy Infusion
121
123{
124 // Festergut
127
128 // Rotface
131
132 // Professor Putricide
133 EVENT_BERSERK = 6, // all phases
134 EVENT_SLIME_PUDDLE = 7, // all phases
136 EVENT_TEAR_GAS = 9, // phase transition not heroic
144
146{
154
156{
159 POINT_TABLE = 366780
161
162Position const festergutWatchPos = {4324.820f, 3166.03f, 389.3831f, 3.316126f}; //emote 432 (release gas)
163Position const rotfaceWatchPos = {4390.371f, 3164.50f, 389.3890f, 5.497787f}; //emote 432 (release ooze)
164Position const tablePos = {4356.190f, 3262.90f, 389.4820f, 1.483530f};
165
166// used in Rotface encounter
167uint32 const oozeFloodSpells[4] = {69782, 69796, 69798, 69801};
168
170{
175
176#define EXPERIMENT_STATE_OOZE false
177#define EXPERIMENT_STATE_GAS true
178
180{
181 public:
182 explicit AbominationDespawner(Unit* owner) : _owner(owner) { }
183
185 {
186 if (Unit* summon = ObjectAccessor::GetUnit(*_owner, guid))
187 {
188 if (summon->GetEntry() == NPC_MUTATED_ABOMINATION_10 || summon->GetEntry() == NPC_MUTATED_ABOMINATION_25)
189 {
190 if (Vehicle* veh = summon->GetVehicleKit())
191 veh->RemoveAllPassengers(); // also despawns the vehicle
192
193 // Found unit is Mutated Abomination, remove it
194 return true;
195 }
196
197 // Found unit is not Mutated Abomintaion, leave it
198 return false;
199 }
200
201 // No unit found, remove from SummonList
202 return true;
203 }
204
205 private:
207};
208
210{
211 RotfaceHeightCheck(Creature* rotface) : _rotface(rotface) { }
212
213 bool operator()(Creature* stalker) const
214 {
215 return stalker->GetPositionZ() < _rotface->GetPositionZ() + 5.0f;
216 }
217
218private:
220};
221
223{
226 {
228 _oozeFloodStage = 0;
229 }
230
231 void Reset() override
232 {
236
237 events.Reset();
242 me->SetWalk(false);
243
245 {
246 me->SetUninteractible(false);
247 me->SetImmuneToPC(false);
248 }
249 }
250
251 void JustEngagedWith(Unit* who) override
252 {
254 return;
255
257 {
260 return;
261 }
262
263 me->setActive(true);
264 events.Reset();
268 if (IsHeroic())
270
277 }
278
279 void JustReachedHome() override
280 {
282 me->SetWalk(false);
285 }
286
287 void KilledUnit(Unit* victim) override
288 {
289 if (victim->GetTypeId() == TYPEID_PLAYER)
290 Talk(SAY_KILL);
291 }
292
293 void JustDied(Unit* /*killer*/) override
294 {
295 _JustDied();
297
300
302 }
303
304 void JustSummoned(Creature* summon) override
305 {
306 summons.Summon(summon);
307 switch (summon->GetEntry())
308 {
311 return;
313 summon->CastSpell(summon, SPELL_GROW_STACKER, true);
314 summon->CastSpell(summon, SPELL_SLIME_PUDDLE_AURA, true);
315 // blizzard casts this spell 7 times initially (confirmed in sniff)
316 for (uint8 i = 0; i < 7; ++i)
317 summon->CastSpell(summon, SPELL_GROW, true);
318 break;
319 case NPC_GAS_CLOUD:
320 // no possible aura seen in sniff adding the aurastate
323 break;
325 // no possible aura seen in sniff adding the aurastate
328 break;
330 summon->CastSpell(summon, SPELL_CHOKING_GAS_BOMB_PERIODIC, true);
331 summon->CastSpell(summon, SPELL_CHOKING_GAS_EXPLOSION_TRIGGER, true);
332 return;
335 return;
336 default:
337 break;
338 }
339
340 if (me->IsInCombat())
341 DoZoneInCombat(summon);
342 }
343
344 void DamageTaken(Unit* /*attacker*/, uint32& /*damage*/, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
345 {
347 return;
348
349 switch (_phase)
350 {
351 case PHASE_COMBAT_1:
352 if (HealthAbovePct(80))
353 return;
356 break;
357 case PHASE_COMBAT_2:
358 if (HealthAbovePct(35))
359 return;
362 break;
363 default:
364 break;
365 }
366 }
367
368 void MovementInform(uint32 type, uint32 id) override
369 {
370 if (type != POINT_MOTION_TYPE)
371 return;
372 switch (id)
373 {
374 case POINT_FESTERGUT:
375 instance->SetBossState(DATA_FESTERGUT, IN_PROGRESS); // needed here for delayed gate close
379 festergut->CastSpell(festergut, SPELL_GASEOUS_BLIGHT_LARGE, CastSpellExtraArgs().SetOriginalCaster(festergut->GetGUID()));
380 break;
381 case POINT_ROTFACE:
382 instance->SetBossState(DATA_ROTFACE, IN_PROGRESS); // needed here for delayed gate close
386 break;
387 case POINT_TABLE:
388 // stop attack
392 me->SetFacingToObject(table);
393 // operating on new phase already
394 switch (_phase)
395 {
396 case PHASE_COMBAT_2:
397 {
398 SpellInfo const* spell = sSpellMgr->GetSpellInfo(SPELL_CREATE_CONCOCTION, GetDifficulty());
401 break;
402 }
403 case PHASE_COMBAT_3:
404 {
405 SpellInfo const* spell = sSpellMgr->GetSpellInfo(SPELL_GUZZLE_POTIONS, GetDifficulty());
408 break;
409 }
410 default:
411 break;
412 }
413 break;
414 default:
415 break;
416 }
417 }
418
419 void DoAction(int32 action) override
420 {
421 switch (action)
422 {
428 EngagementStart(nullptr);
429 if (IsHeroic())
431 break;
435 break;
438 break;
444 EngagementStart(nullptr);
445 _oozeFloodStage = 0;
446 // init random sequence of floods
448 {
449 std::list<Creature*> list;
451 list.remove_if(RotfaceHeightCheck(rotface));
452 if (list.size() > 4)
453 {
454 list.sort(Trinity::ObjectDistanceOrderPred(rotface));
455 do
456 {
457 list.pop_back();
458 } while (list.size() > 4);
459 }
460
461 uint8 i = 0;
462 while (!list.empty())
463 {
464 std::list<Creature*>::iterator itr = list.begin();
465 std::advance(itr, urand(0, list.size()-1));
466 _oozeFloodDummyGUIDs[i++] = (*itr)->GetGUID();
467 list.erase(itr);
468 }
469 }
470 break;
475 .SetOriginalCaster(me->GetGUID())); // cast from self for LoS (with prof's GUID for logs)
476 if (++_oozeFloodStage == 4)
477 _oozeFloodStage = 0;
478 break;
481 break;
484 events.DelayEvents(30s);
485 me->AttackStop();
486 if (!IsHeroic())
487 {
490 }
491 else
492 {
496 // cast variables
497 if (Is25ManRaid())
498 {
499 std::list<Unit*> targetList;
500 {
502 if (Player* target = ref->GetVictim()->ToPlayer())
503 targetList.push_back(target);
504 }
505
506 size_t half = targetList.size()/2;
507 // half gets ooze variable
508 while (half < targetList.size())
509 {
510 std::list<Unit*>::iterator itr = targetList.begin();
511 advance(itr, urand(0, targetList.size() - 1));
512 (*itr)->CastSpell(*itr, SPELL_OOZE_VARIABLE, true);
513 targetList.erase(itr);
514 }
515 // and half gets gas
516 for (std::list<Unit*>::iterator itr = targetList.begin(); itr != targetList.end(); ++itr)
517 (*itr)->CastSpell(*itr, SPELL_GAS_VARIABLE, true);
518 }
520 }
521 switch (_phase)
522 {
523 case PHASE_COMBAT_1:
527 break;
528 case PHASE_COMBAT_2:
532 break;
533 default:
534 break;
535 }
536 break;
537 default:
538 break;
539 }
540 }
541
542 uint32 GetData(uint32 type) const override
543 {
544 switch (type)
545 {
547 return _experimentState;
548 case DATA_PHASE:
549 return _phase;
550 case DATA_ABOMINATION:
552 default:
553 break;
554 }
555
556 return 0;
557 }
558
559 void SetData(uint32 id, uint32 data) override
560 {
561 if (id == DATA_EXPERIMENT_STAGE)
562 _experimentState = data != 0;
563 }
564
565 void UpdateAI(uint32 diff) override
566 {
568 return;
569
570 events.Update(diff);
571
573 return;
574
575 while (uint32 eventId = events.ExecuteEvent())
576 {
577 switch (eventId)
578 {
582 break;
585 if (Is25ManRaid())
587 else
589 break;
593 break;
597 break;
598 case EVENT_BERSERK:
601 break;
603 {
604 std::list<Unit*> targets;
605 SelectTargetList(targets, 2, SelectTargetMethod::Random, 0, 0.0f, true);
606 if (!targets.empty())
607 for (std::list<Unit*>::iterator itr = targets.begin(); itr != targets.end(); ++itr)
610 break;
611 }
616 break;
617 case EVENT_TEAR_GAS:
620 break;
624 // remove Tear Gas
629 break;
631 if (Is25ManRaid())
632 {
633 std::list<Unit*> targets;
634 SelectTargetList(targets, 2, SelectTargetMethod::Random, 0, -7.0f, true);
635 if (!targets.empty())
636 {
638 for (std::list<Unit*>::iterator itr = targets.begin(); itr != targets.end(); ++itr)
640 }
641 }
642 else
643 {
644 if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1, -7.0f, true))
645 {
648 }
649 }
651 break;
656 break;
659 {
662 }
664 break;
668 break;
670 {
671 switch (_phase)
672 {
673 case PHASE_COMBAT_2:
675 me->SetFacingToObject(face);
679 break;
680 case PHASE_COMBAT_3:
682 me->SetFacingToObject(face);
687 break;
688 default:
689 break;
690 }
691 break;
692 }
693 default:
694 break;
695 }
696
698 return;
699 }
700 }
701
702private:
703 void SetPhase(Phases newPhase)
704 {
705 _phase = newPhase;
706 events.SetPhase(newPhase);
707 }
708
710 Phases _phase; // external of EventMap because event phase gets reset on evade
711 float const _baseSpeed;
714};
715
717{
718 public:
719 npc_putricide_oozeAI(Creature* creature, uint32 auraSpellId, uint32 hitTargetSpellId) : ScriptedAI(creature),
720 _auraSpellId(auraSpellId), _hitTargetSpellId(hitTargetSpellId), _newTargetSelectTimer(0), _instance(creature->GetInstanceScript()) { }
721
722 void SpellHitTarget(WorldObject* /*target*/, SpellInfo const* spellInfo) override
723 {
724 if (!_newTargetSelectTimer && spellInfo->Id == _hitTargetSpellId)
725 {
727 // go passive until next target selection
729 }
730 }
731
732 void Reset() override
733 {
736
738 DoCastAOE(_auraSpellId, true);
739 }
740
741 void SpellHit(WorldObject* /*caster*/, SpellInfo const* spellInfo) override
742 {
743 if (spellInfo->Id == SPELL_TEAR_GAS_CREATURE)
745 }
746
747 void UpdateAI(uint32 diff) override
748 {
750 return;
751
752 if (!_newTargetSelectTimer && !me->IsNonMeleeSpellCast(false, false, true, false, true))
754
756 return;
757
759 return;
760
761 if (_newTargetSelectTimer <= diff)
762 {
765 }
766 else
767 _newTargetSelectTimer -= diff;
768 }
769
770 virtual void CastMainSpell() = 0;
771
772 private:
777};
778
780{
782
783 void CastMainSpell() override
784 {
786 }
787};
788
790{
792 {
794 }
795
796 void CastMainSpell() override
797 {
801 }
802
803private:
805};
806
807// 70672, 72455, 72832, 72833 - Gaseous Bloat
809{
810 void HandleExtraEffect(AuraEffect const* /*aurEff*/)
811 {
812 Unit* target = GetTarget();
813 if (Unit* caster = GetCaster())
814 {
816 if (!target->HasAura(GetId()))
817 {
820 caster->CastSpell(caster, SPELL_GASEOUS_BLOAT, args);
821 }
822 }
823 }
824
825 void HandleProc(ProcEventInfo& eventInfo)
826 {
827 uint32 stack = GetStackAmount();
828 Unit* caster = eventInfo.GetActor();
829
830 int32 const mod = caster->GetMap()->Is25ManRaid() ? 1500 : 1250;
831 int32 dmg = 0;
832 for (uint8 i = 1; i <= stack; ++i)
833 dmg += mod * i;
834
836 args.AddSpellBP0(dmg);
837 caster->CastSpell(nullptr, SPELL_EXPUNGED_GAS, args);
838 }
839
840 void Register() override
841 {
844 }
845};
846
847// 70447, 72836, 72837, 72838 - Volatile Ooze Adhesive
848// 70672, 72455, 72832, 72833 - Gaseous Bloat
850{
851 bool Validate(SpellInfo const* spell) override
852 {
853 return ValidateSpellInfo({ spell->ExcludeTargetAuraSpell });
854 }
855
856 // set up initial variables and check if caster is creature
857 // this will let use safely use ToCreature() casts in entire script
858 bool Load() override
859 {
860 return GetCaster()->GetTypeId() == TYPEID_UNIT;
861 }
862
863 void SelectTarget(std::list<WorldObject*>& targets)
864 {
865 if (targets.empty())
866 {
868 GetCaster()->ToCreature()->DespawnOrUnsummon(1ms); // despawn next update
869 return;
870 }
871
873 targets.clear();
874 targets.push_back(target);
875 _target = target;
876 }
877
878 void SetTarget(std::list<WorldObject*>& targets)
879 {
880 targets.clear();
881 if (_target)
882 targets.push_back(_target);
883 }
884
886 {
890 GetCaster()->GetThreatManager().AddThreat(GetHitUnit(), 500000000.0f, nullptr, true, true); // value seen in sniff
893 }
894
895 void Register() override
896 {
901 }
902
904};
905
907{
908 public:
909 ExactDistanceCheck(Unit* source, float dist) : _source(source), _dist(dist) { }
910
911 bool operator()(WorldObject* unit) const
912 {
913 return _source->GetExactDist2d(unit) > _dist;
914 }
915
916 private:
918 float _dist;
919};
920
921// 70346, 72456, 72868, 72869 - Slime Puddle
923{
924 void ScaleRange(std::list<WorldObject*>& targets)
925 {
926 targets.remove_if(ExactDistanceCheck(GetCaster(), 2.5f * GetCaster()->GetObjectScale()));
927 }
928
929 void Register() override
930 {
933 }
934};
935
936// this is here only because on retail you dont actually enter HEROIC mode for ICC
937// 72868, 72869 - Slime Puddle
939{
941 {
942 if (Unit* target = GetHitUnit())
943 GetCaster()->AddAura(GetCaster()->GetMap()->Is25ManRaid() ? 72456 : 70346, target);
944 }
945
946 void Register() override
947 {
949 }
950};
951
952// 70351, 71966, 71967, 71968 - Unstable Experiment
954{
956 {
957 PreventHitDefaultEffect(effIndex);
958 if (GetCaster()->GetTypeId() != TYPEID_UNIT)
959 return;
960
961 Creature* creature = GetCaster()->ToCreature();
962
963 uint32 stage = creature->AI()->GetData(DATA_EXPERIMENT_STAGE);
964 creature->AI()->SetData(DATA_EXPERIMENT_STAGE, stage ^ true);
965
966 Creature* target = nullptr;
967 std::list<Creature*> creList;
969 // 2 of them are spawned at green place - weird trick blizz
970 for (std::list<Creature*>::iterator itr = creList.begin(); itr != creList.end(); ++itr)
971 {
972 target = *itr;
973 std::list<Creature*> tmp;
975 if ((!stage && tmp.size() > 1) || (stage && tmp.size() == 1))
976 break;
977 }
978
979 GetCaster()->CastSpell(target, uint32(GetEffectInfo(SpellEffIndex(stage)).CalcValue()), true);
980 }
981
982 void Register() override
983 {
985 }
986};
987
988// 70459 - Ooze Eruption Search Effect
990{
991 void HandleDummy(SpellEffIndex /*effIndex*/)
992 {
994 {
997 }
998 }
999
1000 void Register() override
1001 {
1003 }
1004};
1005
1006// 71770 - Ooze Spell Tank Protection
1008{
1009 bool Validate(SpellInfo const* spellInfo) override
1010 {
1011 return ValidateSpellEffect({ { spellInfo->Id, EFFECT_1 } })
1012 && ValidateSpellInfo({ spellInfo->GetEffect(EFFECT_0).TriggerSpell, spellInfo->GetEffect(EFFECT_1).TriggerSpell });
1013 }
1014
1015 void HandleProc(AuraEffect* aurEff, ProcEventInfo& eventInfo)
1016 {
1018
1019 Unit* actionTarget = eventInfo.GetActionTarget();
1020 actionTarget->CastSpell(nullptr, aurEff->GetSpellEffectInfo().TriggerSpell, aurEff);
1021 }
1022
1023 void Register() override
1024 {
1027 }
1028};
1029
1030// 71255 - Choking Gas Bomb
1032{
1033 void HandleScript(SpellEffIndex /*effIndex*/)
1034 {
1035 uint32 skipIndex = urand(0, 2);
1036 for (SpellEffectInfo const& spellEffectInfo : GetSpellInfo()->GetEffects())
1037 {
1038 if (spellEffectInfo.EffectIndex == skipIndex)
1039 continue;
1040
1041 uint32 spellId = uint32(spellEffectInfo.CalcValue());
1043 .SetOriginalCaster(GetCaster()->GetGUID()));
1044 }
1045 }
1046
1047 void Register() override
1048 {
1050 }
1051};
1052
1053// 70920 - Unbound Plague Search Effect
1055{
1056 bool Validate(SpellInfo const* /*spell*/) override
1057 {
1059 }
1060
1061 void FilterTargets(std::list<WorldObject*>& targets)
1062 {
1063 if (AuraEffect const* eff = GetCaster()->GetAuraEffect(SPELL_UNBOUND_PLAGUE_SEARCHER, EFFECT_0))
1064 {
1065 if (eff->GetTickNumber() < 2)
1066 {
1067 targets.clear();
1068 return;
1069 }
1070 }
1071
1072 targets.remove_if(Trinity::UnitAuraCheck(true, SPELL_UNBOUND_PLAGUE));
1074 }
1075
1076 void HandleScript(SpellEffIndex /*effIndex*/)
1077 {
1078 if (!GetHitUnit())
1079 return;
1080
1082 if (!instance)
1083 return;
1084
1086 {
1088 {
1089 if (Aura* oldPlague = GetCaster()->GetAura(SPELL_UNBOUND_PLAGUE, professor->GetGUID()))
1090 {
1091 if (Aura* newPlague = professor->AddAura(SPELL_UNBOUND_PLAGUE, GetHitUnit()))
1092 {
1093 newPlague->SetMaxDuration(oldPlague->GetMaxDuration());
1094 newPlague->SetDuration(oldPlague->GetDuration());
1095 oldPlague->Remove();
1099 professor->CastSpell(GetHitUnit(), SPELL_UNBOUND_PLAGUE_SEARCHER, true);
1100 }
1101 }
1102 }
1103 }
1104 }
1105
1106 void Register() override
1107 {
1110 }
1111};
1112
1113// 70360, 72527 - Eat Ooze
1115{
1116 void SelectTarget(std::list<WorldObject*>& targets)
1117 {
1118 if (targets.empty())
1119 return;
1120
1122 WorldObject* target = targets.front();
1123 targets.clear();
1124 targets.push_back(target);
1125 }
1126
1127 void HandleScript(SpellEffIndex /*effIndex*/)
1128 {
1129 Creature* target = GetHitCreature();
1130 if (!target)
1131 return;
1132
1133 if (Aura* grow = target->GetAura(uint32(GetEffectValue())))
1134 {
1135 if (grow->GetStackAmount() < 3)
1136 {
1138 target->RemoveAura(grow);
1139 target->DespawnOrUnsummon(1ms);
1140 }
1141 else
1142 grow->ModStackAmount(-3);
1143 }
1144 }
1145
1146 void Register() override
1147 {
1150 }
1151};
1152
1153// 72451, 72463, 72671, 72672 - Mutated Plague
1155{
1156 void HandleTriggerSpell(AuraEffect const* aurEff)
1157 {
1159 Unit* caster = GetCaster();
1160 if (!caster)
1161 return;
1162
1163 uint32 triggerSpell = aurEff->GetSpellEffectInfo().TriggerSpell;
1164 SpellInfo const* spell = sSpellMgr->AssertSpellInfo(triggerSpell, GetCastDifficulty());
1165
1166 int32 damage = spell->GetEffect(EFFECT_0).CalcValue(caster);
1167 float multiplier = 2.0f;
1168 if (GetTarget()->GetMap()->Is25ManRaid())
1169 multiplier = 3.0f;
1170
1171 damage *= int32(pow(multiplier, GetStackAmount()));
1172 damage = int32(damage * 1.5f);
1173
1174 CastSpellExtraArgs args(aurEff);
1176 args.AddSpellBP0(damage);
1177 GetTarget()->CastSpell(GetTarget(), triggerSpell, args);
1178 }
1179
1180 void OnRemove(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
1181 {
1182 uint32 healSpell = uint32(aurEff->GetSpellEffectInfo().CalcValue());
1183 SpellInfo const* healSpellInfo = sSpellMgr->GetSpellInfo(healSpell, GetCastDifficulty());
1184
1185 if (!healSpellInfo)
1186 return;
1187
1188 int32 heal = healSpellInfo->GetEffect(EFFECT_0).CalcValue() * GetStackAmount();
1191 args.AddSpellBP0(heal);
1192 GetTarget()->CastSpell(GetTarget(), healSpell, args);
1193 }
1194
1195 void Register() override
1196 {
1199 }
1200};
1201
1202// 70308 - Mutated Transformation (Init)
1204{
1206 {
1208 if (!instance)
1210
1212 if (!professor)
1214
1215 if (professor->AI()->GetData(DATA_PHASE) == PHASE_COMBAT_3 || !professor->IsAlive())
1216 {
1219 }
1220
1221 if (professor->AI()->GetData(DATA_ABOMINATION))
1222 {
1225 }
1226
1227 return SPELL_CAST_OK;
1228 }
1229
1231 {
1232 if (!GetExplTargetUnit())
1234
1235 if (GetExplTargetUnit()->GetTypeId() != TYPEID_PLAYER)
1237
1239 SpellCastResult result = CheckRequirementInternal(extension);
1240 if (result != SPELL_CAST_OK)
1241 {
1242 Spell::SendCastResult(GetExplTargetUnit()->ToPlayer(), GetSpellInfo(), GetSpell()->m_SpellVisual, GetSpell()->m_castId, result, extension);
1243 return result;
1244 }
1245
1246 return SPELL_CAST_OK;
1247 }
1248
1249 void Register() override
1250 {
1252 }
1253};
1254
1256{
1257 void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
1258 {
1259 uint32 spellId = 70311;
1260 if (GetTarget()->GetMap()->Is25ManRaid())
1261 spellId = 71503;
1262
1263 GetTarget()->CastSpell(GetTarget(), spellId, true);
1264 }
1265
1266 void Register() override
1267 {
1269 }
1270};
1271
1272// 70405, 72508, 72509, 72510 - Mutated Transformation (Dismiss)
1274{
1275 void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
1276 {
1277 if (Vehicle* veh = GetTarget()->GetVehicleKit())
1278 veh->RemoveAllPassengers();
1279 }
1280
1281 void Register() override
1282 {
1284 }
1285};
1286
1287// 70311, 71503 - Mutated Transformation
1289{
1291 {
1292 PreventHitDefaultEffect(effIndex);
1293 Unit* caster = GetOriginalCaster();
1294 if (!caster)
1295 return;
1296
1297 InstanceScript* instance = caster->GetInstanceScript();
1298 if (!instance)
1299 return;
1300
1302 if (!putricide)
1303 return;
1304
1305 if (putricide->AI()->GetData(DATA_ABOMINATION))
1306 {
1307 if (Player* player = caster->ToPlayer())
1309 return;
1310 }
1311
1312 uint32 entry = uint32(GetEffectInfo().MiscValue);
1313 SummonPropertiesEntry const* properties = sSummonPropertiesStore.LookupEntry(uint32(GetEffectInfo().MiscValueB));
1314 Milliseconds duration = Milliseconds(GetSpellInfo()->GetDuration());
1315
1316 Position pos = caster->GetPosition();
1317 TempSummon* summon = caster->GetMap()->SummonCreature(entry, pos, properties, duration, caster, GetSpellInfo()->Id);
1318 if (!summon || !summon->IsVehicle())
1319 return;
1320
1321 summon->CastSpell(summon, SPELL_ABOMINATION_VEHICLE_POWER_DRAIN, true);
1322 summon->CastSpell(summon, SPELL_MUTATED_TRANSFORMATION_DAMAGE, true);
1323 caster->CastSpell(summon, SPELL_MUTATED_TRANSFORMATION_NAME, true);
1324
1325 caster->EnterVehicle(summon, 0); // VEHICLE_SPELL_RIDE_HARDCODED is used according to sniff, this is ok
1326 summon->SetCreatorGUID(caster->GetGUID());
1327 putricide->AI()->JustSummoned(summon);
1328 }
1329
1330 void Register() override
1331 {
1333 }
1334};
1335
1336// 70402, 72511, 72512, 72513 - Mutated Transformation (Damage)
1338{
1339 void FilterTargetsInitial(std::list<WorldObject*>& targets)
1340 {
1341 if (Unit* owner = ObjectAccessor::GetUnit(*GetCaster(), GetCaster()->GetCreatorGUID()))
1342 targets.remove(owner);
1343 }
1344
1345 void Register() override
1346 {
1348 }
1349};
1350
1351// 70539, 72457, 72875, 72876 - Regurgitated Ooze
1353{
1354 // the only purpose of this hook is to fail the achievement
1355 void ExtraEffect(SpellEffIndex /*effIndex*/)
1356 {
1357 if (InstanceScript* instance = GetCaster()->GetInstanceScript())
1358 instance->SetData(DATA_NAUSEA_ACHIEVEMENT, uint32(false));
1359 }
1360
1361 void Register() override
1362 {
1364 }
1365};
1366
1367// Removes aura with id stored in effect value
1368// 71620 - Tear Gas Cancel
1369// 72618 - Mutated Plague Clear
1371{
1373 {
1374 PreventHitDefaultEffect(effIndex);
1375 Unit* target = GetHitUnit();
1376 uint32 auraId = GetEffectValue();
1377 target->RemoveAurasDueToSpell(auraId);
1378 if (m_scriptSpellId == SPELL_TEAR_GAS_CANCEL && GetSpellInfo()->GetEffects().size() >= EFFECT_1)
1379 {
1381 target->RemoveAurasDueToSpell(auraId2);
1382 }
1383 }
1384
1385 void Register() override
1386 {
1388 }
1389};
1390
1391// Stinky and Precious spell, it's here because its used for both (Festergut and Rotface "pets")
1392// 71123 - Decimate
1394{
1395 void HandleScript(SpellEffIndex /*effIndex*/)
1396 {
1397 if (GetHitUnit()->GetHealthPct() > float(GetEffectValue()))
1398 {
1399 uint32 newHealth = GetHitUnit()->GetMaxHealth() * uint32(GetEffectValue()) / 100;
1400 GetHitUnit()->SetHealth(newHealth);
1401 }
1402 }
1403
1404 void Register() override
1405 {
1407 }
1408};
1409
1410// 70402, 72511, 72512, 72513 - Mutated Transformation
1412{
1413 void HandleResistance(DamageInfo const& damageInfo, uint32& resistAmount, int32& /*absorbAmount*/)
1414 {
1415 Unit* caster = damageInfo.GetAttacker();;
1416 Unit* target = damageInfo.GetVictim();
1417 uint32 damage = damageInfo.GetDamage();
1418 uint32 resistedDamage = Unit::CalcSpellResistedDamage(caster, target, damage, SPELL_SCHOOL_MASK_SHADOW, nullptr);
1419 resistedDamage += Unit::CalcSpellResistedDamage(caster, target, damage, SPELL_SCHOOL_MASK_NATURE, nullptr);
1420 resistAmount = resistedDamage;
1421 }
1422
1423 void Register() override
1424 {
1426 }
1427};
1428
1429// 71278, 72460, 72619, 72620 - Choking Gas
1430// 71279, 72459, 72621, 72622 - Choking Gas Explosion
1432{
1433 bool Validate(SpellInfo const* /*spell*/) override
1434 {
1436 }
1437
1438 void FilterTargets(std::list<WorldObject*>& targets)
1439 {
1440 targets.remove_if([](WorldObject* obj)
1441 {
1442 return obj->ToUnit() && obj->ToUnit()->GetVehicle();
1443 });
1444 }
1445
1446 void HandleDispel(SpellEffIndex /*effIndex*/)
1447 {
1448 Unit* target = GetHitUnit();
1451 }
1452
1453 void Register() override
1454 {
1457 }
1458};
1459
1461{
1462 // Creatures
1466
1467 // Spells
1488}
DB2Storage< SummonPropertiesEntry > sSummonPropertiesStore("SummonProperties.db2", &SummonPropertiesLoadInfo::Instance)
uint8_t uint8
Definition: Define.h:144
int32_t int32
Definition: Define.h:138
uint32_t uint32
Definition: Define.h:142
std::chrono::milliseconds Milliseconds
Milliseconds shorthand typedef.
Definition: Duration.h:29
@ IN_PROGRESS
@ FAIL
@ DONE
@ NOT_STARTED
@ POINT_MOTION_TYPE
@ TYPEID_UNIT
Definition: ObjectGuid.h:40
@ TYPEID_PLAYER
Definition: ObjectGuid.h:41
Spells
Definition: PlayerAI.cpp:32
uint32 urand(uint32 min, uint32 max)
Definition: Random.cpp:42
#define RegisterSpellAndAuraScriptPair(script_1, script_2)
Definition: ScriptMgr.h:1371
#define RegisterSpellScript(spell_script)
Definition: ScriptMgr.h:1369
void GetCreatureListWithEntryInGrid(Container &container, WorldObject *source, uint32 entry, float maxSearchRange)
SpellEffIndex
Definition: SharedDefines.h:29
@ EFFECT_1
Definition: SharedDefines.h:31
@ EFFECT_0
Definition: SharedDefines.h:30
@ EFFECT_2
Definition: SharedDefines.h:32
@ TARGET_UNIT_SRC_AREA_ENTRY
@ TARGET_UNIT_DEST_AREA_ENEMY
@ TARGET_UNIT_SRC_AREA_ALLY
@ TARGET_UNIT_SRC_AREA_ENEMY
@ TARGET_UNIT_DEST_AREA_ENTRY
@ EMOTE_ONESHOT_KNEEL
@ SPELL_SCHOOL_MASK_SHADOW
@ SPELL_SCHOOL_MASK_NATURE
@ SPELL_EFFECT_DUMMY
@ SPELL_EFFECT_SCRIPT_EFFECT
@ SPELL_EFFECT_SUMMON
@ SPELL_EFFECT_APPLY_AURA
SpellCustomErrors
@ SPELL_CUSTOM_ERROR_NONE
@ SPELL_CUSTOM_ERROR_TOO_MANY_ABOMINATIONS
@ SPELL_CUSTOM_ERROR_ALL_POTIONS_USED
SpellCastResult
@ SPELL_FAILED_TARGET_NOT_PLAYER
@ SPELL_FAILED_CUSTOM_ERROR
@ SPELL_FAILED_CANT_DO_THAT_RIGHT_NOW
@ SPELL_FAILED_BAD_TARGETS
@ SPELL_CAST_OK
@ SPELL_FAILED_NO_VALID_TARGETS
@ AURA_STATE_VULNERABLE
@ AURA_STATE_RAID_ENCOUNTER
#define EFFECT_ALL
Definition: SharedDefines.h:72
AuraEffectHandleModes
@ AURA_EFFECT_HANDLE_REAL
@ AURA_REMOVE_BY_ENEMY_SPELL
@ SPELL_AURA_PERIODIC_DAMAGE
@ SPELL_AURA_PROC_TRIGGER_SPELL
@ SPELL_AURA_DUMMY
@ SPELL_AURA_PERIODIC_TRIGGER_SPELL
@ TRIGGERED_FULL_MASK
Used when doing CastSpell with triggered == true.
Definition: SpellDefines.h:266
@ SPELLVALUE_AURA_STACK
Definition: SpellDefines.h:231
@ SPELLVALUE_MAX_TARGETS
Definition: SpellDefines.h:230
#define sSpellMgr
Definition: SpellMgr.h:849
#define AuraProcFn(F)
Definition: SpellScript.h:2150
#define SpellCheckCastFn(F)
Definition: SpellScript.h:830
#define AuraEffectProcFn(F, I, N)
Definition: SpellScript.h:2160
#define SpellOnResistAbsorbCalculateFn(F)
Definition: SpellScript.h:889
#define SpellEffectFn(F, I, N)
Definition: SpellScript.h:842
#define SpellObjectAreaTargetSelectFn(F, I, N)
Definition: SpellScript.h:864
#define AuraEffectPeriodicFn(F, I, N)
Definition: SpellScript.h:2046
#define SpellHitFn(F)
Definition: SpellScript.h:854
#define AuraEffectRemoveFn(F, I, N, M)
Definition: SpellScript.h:2040
@ MOVE_RUN
Definition: UnitDefines.h:118
@ REACT_DEFENSIVE
Definition: UnitDefines.h:507
@ REACT_PASSIVE
Definition: UnitDefines.h:506
@ REACT_AGGRESSIVE
Definition: UnitDefines.h:508
DamageEffectType
Definition: UnitDefines.h:131
@ UNIT_STATE_CASTING
Definition: Unit.h:270
Position const festergutWatchPos
@ SPELL_UNBOUND_PLAGUE_PROTECTION
@ SPELL_UNBOUND_PLAGUE_SEARCHER
@ SPELL_OOZE_ERUPTION_SEARCH_PERIODIC
@ SPELL_CHOKING_GAS_BOMB_PERIODIC
@ SPELL_VOLATILE_OOZE_ADHESIVE
@ SPELL_SLIME_PUDDLE_AURA
@ SPELL_SLIME_PUDDLE_TRIGGER
@ SPELL_MUTATED_TRANSFORMATION
@ SPELL_GASEOUS_BLOAT_PROTECTION
@ SPELL_MUTATED_TRANSFORMATION_DAMAGE
@ SPELL_TEAR_GAS_CREATURE
@ SPELL_TEAR_GAS_PERIODIC_TRIGGER
@ SPELL_PLAGUE_SICKNESS
@ SPELL_UNSTABLE_EXPERIMENT
@ SPELL_MUTATED_PLAGUE
@ SPELL_GASEOUS_BLOAT_PROC
@ SPELL_UNBOUND_PLAGUE
@ SPELL_UNHOLY_INFUSION_CREDIT
@ SPELL_OOZE_TANK_PROTECTION
@ SPELL_ABOMINATION_VEHICLE_POWER_DRAIN
@ SPELL_VOLATILE_OOZE_PROTECTION
@ SPELL_TEAR_GAS_CANCEL
@ SPELL_CREATE_CONCOCTION
@ SPELL_MUTATED_TRANSFORMATION_NAME
@ SPELL_TEAR_GAS_TRIGGER_MISSILE
@ SPELL_RELEASE_GAS_VISUAL
@ SPELL_CHOKING_GAS_BOMB
@ SPELL_GASEOUS_BLIGHT_LARGE
@ SPELL_GASEOUS_BLIGHT_MEDIUM
@ SPELL_GASEOUS_BLIGHT_SMALL
@ SPELL_MALLEABLE_GOO_SUMMON
@ SPELL_MALLEABLE_GOO_H
@ SPELL_GUZZLE_POTIONS
@ SPELL_CHOKING_GAS_EXPLOSION_TRIGGER
@ SPELL_MUTATED_PLAGUE_CLEAR
Position const rotfaceWatchPos
Position const tablePos
@ EMOTE_CHOKING_GAS_BOMB
@ SAY_PHASE_TRANSITION_HEROIC
@ SAY_FESTERGUT_GASEOUS_BLIGHT
@ SAY_ROTFACE_OOZE_FLOOD
@ EMOTE_UNSTABLE_EXPERIMENT
uint32 const oozeFloodSpells[4]
void AddSC_boss_professor_putricide()
#define EXPERIMENT_STATE_OOZE
@ EVENT_ROTFACE_OOZE_FLOOD
@ EVENT_CHOKING_GAS_BOMB
@ EVENT_PHASE_TRANSITION
@ EVENT_UNSTABLE_EXPERIMENT
bool operator()(ObjectGuid guid)
SpellEffectInfo const & GetSpellEffectInfo() const
void PreventDefaultAction()
HookList< EffectApplyHandler > AfterEffectRemove
Definition: SpellScript.h:2039
HookList< EffectPeriodicHandler > OnEffectPeriodic
Definition: SpellScript.h:2045
SpellInfo const * GetSpellInfo() const
Unit * GetCaster() const
Unit * GetTarget() const
ObjectGuid GetCasterGUID() const
Difficulty GetCastDifficulty() const
HookList< EffectProcHandler > OnEffectProc
Definition: SpellScript.h:2155
HookList< AuraProcHandler > OnProc
Definition: SpellScript.h:2145
uint8 GetStackAmount() const
uint32 GetId() const
InstanceScript *const instance
void _JustReachedHome()
SummonList summons
EventMap events
void _JustDied()
void DoZoneInCombat()
Definition: CreatureAI.h:161
virtual void JustSummoned(Creature *)
Definition: CreatureAI.h:111
virtual void EnterEvadeMode(EvadeReason why=EvadeReason::Other)
Definition: CreatureAI.cpp:219
void Talk(uint8 id, WorldObject const *whisperTarget=nullptr)
Definition: CreatureAI.cpp:56
bool UpdateVictim()
Definition: CreatureAI.cpp:245
void AttackStart(Unit *victim) override
== Triggered Actions Requested ==================
Definition: CreatureAI.cpp:328
void EngagementStart(Unit *who)
Definition: CreatureAI.cpp:275
Creature *const me
Definition: CreatureAI.h:61
void SetCombatPulseDelay(uint32 delay)
Definition: Creature.h:345
void SetImmuneToPC(bool apply) override
Definition: Creature.h:170
void SetReactState(ReactStates st)
Definition: Creature.h:160
void DespawnOrUnsummon(Milliseconds timeToDespawn=0s, Seconds forceRespawnTime=0s)
Definition: Creature.cpp:2415
CreatureAI * AI() const
Definition: Creature.h:214
Unit * GetVictim() const
Definition: Unit.h:441
Unit * GetAttacker() const
Definition: Unit.h:440
uint32 GetDamage() const
Definition: Unit.h:446
uint32 ExecuteEvent()
Definition: EventMap.cpp:73
void Update(uint32 time)
Definition: EventMap.h:56
void DelayEvents(Milliseconds delay)
Definition: EventMap.cpp:96
void ScheduleEvent(uint32 eventId, Milliseconds time, uint32 group=0, uint8 phase=0)
Definition: EventMap.cpp:36
bool IsInPhase(uint8 phase) const
Definition: EventMap.h:217
void CancelEvent(uint32 eventId)
Definition: EventMap.cpp:131
void SetPhase(uint8 phase)
Definition: EventMap.cpp:28
void Reset()
Definition: EventMap.cpp:21
ExactDistanceCheck(Unit *source, float dist)
bool operator()(WorldObject *unit) const
virtual bool SetBossState(uint32 id, EncounterState state)
void DoRemoveAurasDueToSpellOnPlayers(uint32 spell, bool includePets=false, bool includeControlled=false)
void DoCastSpellOnPlayers(uint32 spell, bool includePets=false, bool includeControlled=false)
virtual ObjectGuid GetGuidData(uint32 type) const override
EncounterState GetBossState(uint32 id) const
virtual bool CheckRequiredBosses(uint32, Player const *=nullptr) const
TempSummon * SummonCreature(uint32 entry, Position const &pos, SummonPropertiesEntry const *properties=nullptr, Milliseconds duration=0ms, WorldObject *summoner=nullptr, uint32 spellId=0, uint32 vehId=0, ObjectGuid privateObjectOwner=ObjectGuid::Empty, SmoothPhasingInfo const *smoothPhasingInfo=nullptr)
Definition: Object.cpp:1836
bool Is25ManRaid() const
Definition: Map.cpp:3320
void MovePoint(uint32 id, Position const &pos, bool generatePath=true, Optional< float > finalOrient={}, Optional< float > speed={}, MovementWalkRunSpeedSelectionMode speedSelectionMode=MovementWalkRunSpeedSelectionMode::Default, Optional< float > closeEnoughDistance={})
static Creature * ToCreature(Object *o)
Definition: Object.h:219
static Unit * ToUnit(Object *o)
Definition: Object.h:225
TypeID GetTypeId() const
Definition: Object.h:173
uint32 GetEntry() const
Definition: Object.h:161
static ObjectGuid GetGUID(Object const *o)
Definition: Object.h:159
static Player * ToPlayer(Object *o)
Definition: Object.h:213
Unit * GetActionTarget() const
Definition: Unit.h:494
Unit * GetActor() const
Definition: Unit.h:493
int32 CalcValue(WorldObject const *caster=nullptr, int32 const *basePoints=nullptr, Unit const *target=nullptr, float *variance=nullptr, uint32 castItemId=0, int32 itemLevel=-1) const
Definition: SpellInfo.cpp:495
uint32 TriggerSpell
Definition: SpellInfo.h:237
uint32 ExcludeTargetAuraSpell
Definition: SpellInfo.h:360
uint32 const Id
Definition: SpellInfo.h:325
uint32 CalcCastTime(Spell *spell=nullptr) const
Definition: SpellInfo.cpp:3805
SpellEffectInfo const & GetEffect(SpellEffIndex index) const
Definition: SpellInfo.h:577
uint32 m_scriptSpellId
Definition: SpellScript.h:134
static bool ValidateSpellInfo(std::initializer_list< uint32 > spellIds)
Definition: SpellScript.h:162
static bool ValidateSpellEffect(std::initializer_list< std::pair< uint32, SpellEffIndex > > effects)
Definition: SpellScript.h:173
HookList< CheckCastHandler > OnCheckCast
Definition: SpellScript.h:829
Creature * GetHitCreature() const
Unit * GetCaster() const
HookList< HitHandler > AfterHit
Definition: SpellScript.h:852
HookList< HitHandler > OnHit
Definition: SpellScript.h:850
HookList< EffectHandler > OnEffectHit
Definition: SpellScript.h:839
void PreventHitDefaultEffect(SpellEffIndex effIndex)
Unit * GetHitUnit() const
int32 GetEffectValue() const
SpellEffectInfo const & GetEffectInfo() const
HookList< EffectHandler > OnEffectHitTarget
Definition: SpellScript.h:840
HookList< OnCalculateResistAbsorbHandler > OnCalculateResistAbsorb
Definition: SpellScript.h:888
Spell * GetSpell() const
Definition: SpellScript.h:987
void FinishCast(SpellCastResult result, int32 *param1=nullptr, int32 *param2=nullptr)
Unit * GetExplTargetUnit() const
SpellInfo const * GetSpellInfo() const
HookList< ObjectAreaTargetSelectHandler > OnObjectAreaTargetSelect
Definition: SpellScript.h:863
Unit * GetOriginalCaster() const
static void SendCastResult(Player *caster, SpellInfo const *spellInfo, SpellCastVisual spellVisual, ObjectGuid cast_count, SpellCastResult result, SpellCustomErrors customError=SPELL_CUSTOM_ERROR_NONE, int32 *param1=nullptr, int32 *param2=nullptr)
Definition: Spell.cpp:4643
bool HasEntry(uint32 entry) const
void DespawnIf(T const &predicate)
void Summon(Creature const *summon)
Trinity::IteratorPair< ThreatListIterator, std::nullptr_t > GetUnsortedThreatList() const
void FixateTarget(Unit *target)
void AddThreat(Unit *target, float amount, SpellInfo const *spell=nullptr, bool ignoreModifiers=false, bool ignoreRedirects=false)
== AFFECT MY THREAT LIST ==
virtual void SetData(uint32, uint32)
Definition: UnitAI.h:74
virtual uint32 GetData(uint32) const
Definition: UnitAI.h:73
SpellCastResult DoCastVictim(uint32 spellId, CastSpellExtraArgs const &args={})
Definition: UnitAI.cpp:180
void SelectTargetList(std::list< Unit * > &targetList, uint32 num, SelectTargetMethod targetType, uint32 offset=0, float dist=0.0f, bool playerOnly=false, bool withTank=true, int32 aura=0)
Definition: UnitAI.cpp:84
Unit * SelectTarget(SelectTargetMethod targetType, uint32 offset=0, float dist=0.0f, bool playerOnly=false, bool withTank=true, int32 aura=0)
Definition: UnitAI.cpp:79
SpellCastResult DoCastAOE(uint32 spellId, CastSpellExtraArgs const &args={})
Definition: UnitAI.h:161
SpellCastResult DoCast(uint32 spellId)
Definition: UnitAI.cpp:89
Definition: Unit.h:627
void EnterVehicle(Unit *base, int8 seatId=-1)
Definition: Unit.cpp:12118
void ClearUnitState(uint32 f)
Definition: Unit.h:733
bool IsVehicle() const
Definition: Unit.h:743
Vehicle * GetVehicle() const
Definition: Unit.h:1713
void SetHealth(uint64 val)
Definition: Unit.cpp:9346
void RemoveAura(AuraApplicationMap::iterator &i, AuraRemoveMode mode=AURA_REMOVE_BY_DEFAULT)
Definition: Unit.cpp:3685
ThreatManager & GetThreatManager()
Definition: Unit.h:1063
MotionMaster * GetMotionMaster()
Definition: Unit.h:1652
bool IsNonMeleeSpellCast(bool withDelayed, bool skipChanneled=false, bool skipAutorepeat=false, bool isAutoshoot=false, bool skipInstant=true) const
Definition: Unit.cpp:3059
void SetFacingToObject(WorldObject const *object, bool force=true)
Definition: Unit.cpp:12671
Aura * AddAura(uint32 spellId, Unit *target)
Definition: Unit.cpp:11618
bool IsAlive() const
Definition: Unit.h:1164
static uint32 CalcSpellResistedDamage(Unit const *attacker, Unit *victim, uint32 damage, SpellSchoolMask schoolMask, SpellInfo const *spellInfo)
Definition: Unit.cpp:1696
void SetUninteractible(bool apply)
Definition: Unit.cpp:8147
void ModifyAuraState(AuraStateType flag, bool apply)
Definition: Unit.cpp:5894
uint64 GetMaxHealth() const
Definition: Unit.h:777
Aura * GetAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint32 reqEffMask=0) const
Definition: Unit.cpp:4560
bool SetWalk(bool enable)
Definition: Unit.cpp:12707
void RemoveAuraFromStack(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT, uint16 num=1)
Definition: Unit.cpp:3847
Unit * GetVictim() const
Definition: Unit.h:715
void SetSpeedRate(UnitMoveType mtype, float rate)
Definition: Unit.cpp:8525
bool HasUnitState(const uint32 f) const
Definition: Unit.h:732
bool HasAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint32 reqEffMask=0) const
Definition: Unit.cpp:4664
void HandleEmoteCommand(Emote emoteId, Player *target=nullptr, Trinity::IteratorPair< int32 const * > spellVisualKitIds={}, int32 sequenceVariation=0)
Definition: Unit.cpp:1598
void SetCreatorGUID(ObjectGuid creator)
Definition: Unit.h:1173
bool AttackStop()
Definition: Unit.cpp:5781
void RemoveAurasDueToSpell(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, uint32 reqEffMask=0, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition: Unit.cpp:3831
bool IsInCombat() const
Definition: Unit.h:1043
Map * GetMap() const
Definition: Object.h:624
InstanceScript * GetInstanceScript() const
Definition: Object.cpp:1042
SpellCastResult CastSpell(CastSpellTargetArg const &targets, uint32 spellId, CastSpellExtraArgs const &args={ })
Definition: Object.cpp:2896
void setActive(bool isActiveObject)
Definition: Object.cpp:922
Creature * FindNearestCreature(uint32 entry, float range, bool alive=true) const
Definition: Object.cpp:2148
virtual void SetData(uint32, uint32)
Definition: ZoneScript.h:92
npc_putricide_oozeAI(Creature *creature, uint32 auraSpellId, uint32 hitTargetSpellId)
void UpdateAI(uint32 diff) override
void SpellHitTarget(WorldObject *, SpellInfo const *spellInfo) override
virtual void CastMainSpell()=0
void SpellHit(WorldObject *, SpellInfo const *spellInfo) override
void HandleResistance(DamageInfo const &damageInfo, uint32 &resistAmount, int32 &)
void FilterTargets(std::list< WorldObject * > &targets)
bool Validate(SpellInfo const *) override
void SelectTarget(std::list< WorldObject * > &targets)
void HandleExtraEffect(AuraEffect const *)
void HandleProc(ProcEventInfo &eventInfo)
void OnRemove(AuraEffect const *aurEff, AuraEffectHandleModes)
void HandleTriggerSpell(AuraEffect const *aurEff)
void OnRemove(AuraEffect const *, AuraEffectHandleModes)
void FilterTargetsInitial(std::list< WorldObject * > &targets)
void OnRemove(AuraEffect const *, AuraEffectHandleModes)
SpellCastResult CheckRequirementInternal(SpellCustomErrors &extendedError)
void SetTarget(std::list< WorldObject * > &targets)
void SelectTarget(std::list< WorldObject * > &targets)
bool Validate(SpellInfo const *spell) override
void HandleProc(AuraEffect *aurEff, ProcEventInfo &eventInfo)
bool Validate(SpellInfo const *spellInfo) override
void ScaleRange(std::list< WorldObject * > &targets)
void FilterTargets(std::list< WorldObject * > &targets)
bool Validate(SpellInfo const *) override
@ SPELL_SHADOWS_FATE
@ SPELL_BERSERK2
@ LIGHT_S_HAMMER_TELEPORT
#define RegisterIcecrownCitadelCreatureAI(ai_name)
@ ACTION_CHANGE_PHASE
@ ACTION_ROTFACE_COMBAT
@ ACTION_FESTERGUT_DEATH
@ ACTION_ROTFACE_DEATH
@ ACTION_ROTFACE_OOZE
@ ACTION_FESTERGUT_GAS
@ ACTION_FESTERGUT_COMBAT
@ DATA_NAUSEA_ACHIEVEMENT
@ DATA_ROTFACE
@ DATA_PROFESSOR_PUTRICIDE
@ DATA_PUTRICIDE_TABLE
@ DATA_FESTERGUT
@ NPC_TEAR_GAS_TARGET_STALKER
@ NPC_ABOMINATION_WING_MAD_SCIENTIST_STALKER
@ NPC_MUTATED_ABOMINATION_25
@ NPC_CHOKING_GAS_BOMB
@ NPC_MALLEABLE_OOZE_STALKER
@ NPC_VOLATILE_OOZE
@ NPC_PUDDLE_STALKER
@ NPC_GAS_CLOUD
@ NPC_MUTATED_ABOMINATION_10
@ NPC_GROWING_OOZE_PUDDLE
TC_GAME_API Unit * GetUnit(WorldObject const &, ObjectGuid const &guid)
TC_GAME_API GameObject * GetGameObject(WorldObject const &u, ObjectGuid const &guid)
TC_GAME_API Creature * GetCreature(WorldObject const &u, ObjectGuid const &guid)
auto SelectRandomContainerElement(C const &container) -> typename std::add_const< decltype(*std::begin(container))>::type &
Definition: Containers.h:109
void RandomResize(C &container, std::size_t requestedSize)
Definition: Containers.h:67
constexpr std::size_t size()
Definition: UpdateField.h:796
CastSpellExtraArgs & SetOriginalCaster(ObjectGuid const &guid)
Definition: SpellDefines.h:471
CastSpellExtraArgs & AddSpellBP0(int32 val)
Definition: SpellDefines.h:475
CastSpellExtraArgs & AddSpellMod(SpellValueMod mod, int32 val)
Definition: SpellDefines.h:474
ObjectGuid OriginalCaster
Definition: SpellDefines.h:482
float GetExactDist2d(const float x, const float y) const
Definition: Position.h:106
constexpr void GetPosition(float &x, float &y) const
Definition: Position.h:81
constexpr float GetPositionZ() const
Definition: Position.h:78
bool operator()(Creature *stalker) const
RotfaceHeightCheck(Creature *rotface)
bool IsHeroic() const
void AttackStart(Unit *) override
== Triggered Actions Requested ==================
bool HealthAbovePct(uint32 pct) const
Difficulty GetDifficulty() const
bool Is25ManRaid() const
void DamageTaken(Unit *, uint32 &, DamageEffectType, SpellInfo const *) override
uint32 GetData(uint32 type) const override
void DoAction(int32 action) override
boss_professor_putricide(Creature *creature)
void JustSummoned(Creature *summon) override
void KilledUnit(Unit *victim) override
void MovementInform(uint32 type, uint32 id) override
void SetData(uint32 id, uint32 data) override
void UpdateAI(uint32 diff) override
void JustEngagedWith(Unit *who) override
void CastMainSpell() override
npc_gas_cloud(Creature *creature)
npc_volatile_ooze(Creature *creature)