TrinityCore
Loading...
Searching...
No Matches
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 "DBCStores.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
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
122#define SPELL_GASEOUS_BLOAT_HELPER RAID_MODE<uint32>(70672, 72455, 72832, 72833)
123
125{
126 // Festergut
129
130 // Rotface
133
134 // Professor Putricide
135 EVENT_BERSERK = 6, // all phases
136 EVENT_SLIME_PUDDLE = 7, // all phases
138 EVENT_TEAR_GAS = 9, // phase transition not heroic
146
156
158{
161 POINT_TABLE = 366780
163
164Position const festergutWatchPos = {4324.820f, 3166.03f, 389.3831f, 3.316126f}; //emote 432 (release gas)
165Position const rotfaceWatchPos = {4390.371f, 3164.50f, 389.3890f, 5.497787f}; //emote 432 (release ooze)
166Position const tablePos = {4356.190f, 3262.90f, 389.4820f, 1.483530f};
167
168// used in Rotface encounter
169uint32 const oozeFloodSpells[4] = {69782, 69796, 69798, 69801};
170
177
178#define EXPERIMENT_STATE_OOZE false
179#define EXPERIMENT_STATE_GAS true
180
182{
183 public:
184 explicit AbominationDespawner(Unit* owner) : _owner(owner) { }
185
187 {
188 if (Unit* summon = ObjectAccessor::GetUnit(*_owner, guid))
189 {
190 if (summon->GetEntry() == NPC_MUTATED_ABOMINATION_10 || summon->GetEntry() == NPC_MUTATED_ABOMINATION_25)
191 {
192 if (Vehicle* veh = summon->GetVehicleKit())
193 veh->RemoveAllPassengers(); // also despawns the vehicle
194
195 // Found unit is Mutated Abomination, remove it
196 return true;
197 }
198
199 // Found unit is not Mutated Abomintaion, leave it
200 return false;
201 }
202
203 // No unit found, remove from SummonList
204 return true;
205 }
206
207 private:
209};
210
212{
213 RotfaceHeightCheck(Creature* rotface) : _rotface(rotface) { }
214
215 bool operator()(Creature* stalker) const
216 {
217 return stalker->GetPositionZ() > _rotface->GetPositionZ() + 5.0f;
218 }
219
220private:
222};
223
224// 36678 - Professor Putricide
226{
233
253
281
289
290 void KilledUnit(Unit* victim) override
291 {
292 if (victim->GetTypeId() == TYPEID_PLAYER)
293 Talk(SAY_KILL);
294 }
295
296 void JustDied(Unit* /*killer*/) override
297 {
298 _JustDied();
300
303
305 }
306
307 void JustSummoned(Creature* summon) override
308 {
309 summons.Summon(summon);
310 switch (summon->GetEntry())
311 {
314 return;
316 summon->CastSpell(summon, SPELL_GROW_STACKER, true);
317 summon->CastSpell(summon, SPELL_SLIME_PUDDLE_AURA, true);
318 // blizzard casts this spell 7 times initially (confirmed in sniff)
319 for (uint8 i = 0; i < 7; ++i)
320 summon->CastSpell(summon, SPELL_GROW, true);
321 break;
322 case NPC_GAS_CLOUD:
323 // no possible aura seen in sniff adding the aurastate
326 break;
328 // no possible aura seen in sniff adding the aurastate
331 break;
333 summon->CastSpell(summon, SPELL_CHOKING_GAS_BOMB_PERIODIC, true);
334 summon->CastSpell(summon, SPELL_CHOKING_GAS_EXPLOSION_TRIGGER, true);
335 return;
338 return;
339 default:
340 break;
341 }
342
343 if (me->IsInCombat())
344 DoZoneInCombat(summon);
345 }
346
347 void DamageTaken(Unit* /*attacker*/, uint32& /*damage*/, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
348 {
350 return;
351
352 switch (_phase)
353 {
354 case PHASE_COMBAT_1:
355 if (HealthAbovePct(80))
356 return;
359 break;
360 case PHASE_COMBAT_2:
361 if (HealthAbovePct(35))
362 return;
365 break;
366 default:
367 break;
368 }
369 }
370
371 void MovementInform(uint32 type, uint32 id) override
372 {
373 if (type != POINT_MOTION_TYPE)
374 return;
375 switch (id)
376 {
377 case POINT_FESTERGUT:
378 instance->SetBossState(DATA_FESTERGUT, IN_PROGRESS); // needed here for delayed gate close
382 festergut->CastSpell(festergut, SPELL_GASEOUS_BLIGHT_LARGE, CastSpellExtraArgs().SetOriginalCaster(festergut->GetGUID()));
383 break;
384 case POINT_ROTFACE:
385 instance->SetBossState(DATA_ROTFACE, IN_PROGRESS); // needed here for delayed gate close
389 break;
390 case POINT_TABLE:
391 // stop attack
395 me->SetFacingToObject(table);
396 // operating on new phase already
397 switch (_phase)
398 {
399 case PHASE_COMBAT_2:
400 {
401 SpellInfo const* spell = sSpellMgr->GetSpellInfo(SPELL_CREATE_CONCOCTION);
403 events.ScheduleEvent(EVENT_PHASE_TRANSITION, Milliseconds(sSpellMgr->GetSpellForDifficultyFromSpell(spell, me)->CalcCastTime()) + 100ms);
404 break;
405 }
406 case PHASE_COMBAT_3:
407 {
408 SpellInfo const* spell = sSpellMgr->GetSpellInfo(SPELL_GUZZLE_POTIONS);
410 events.ScheduleEvent(EVENT_PHASE_TRANSITION, Milliseconds(sSpellMgr->GetSpellForDifficultyFromSpell(spell, me)->CalcCastTime()) + 100ms);
411 break;
412 }
413 default:
414 break;
415 }
416 break;
417 default:
418 break;
419 }
420 }
421
422 void DoAction(int32 action) override
423 {
424 switch (action)
425 {
431 EngagementStart(nullptr);
432 if (IsHeroic())
434 break;
438 break;
441 break;
447 EngagementStart(nullptr);
448 _oozeFloodStage = 0;
449 // init random sequence of floods
451 {
452 std::list<Creature*> list;
454 list.remove_if(RotfaceHeightCheck(rotface));
455 if (list.size() > 4)
456 {
457 list.sort(Trinity::ObjectDistanceOrderPred(rotface));
458 do
459 {
460 list.pop_back();
461 } while (list.size() > 4);
462 }
463
464 uint8 i = 0;
465 while (!list.empty())
466 {
467 std::list<Creature*>::iterator itr = list.begin();
468 std::advance(itr, urand(0, list.size()-1));
469 _oozeFloodDummyGUIDs[i++] = (*itr)->GetGUID();
470 list.erase(itr);
471 }
472 }
473 break;
477 dummy->CastSpell(dummy, oozeFloodSpells[_oozeFloodStage], me->GetGUID()); // cast from self for LoS (with prof's GUID for logs)
478 if (++_oozeFloodStage == 4)
479 _oozeFloodStage = 0;
480 break;
483 break;
486 events.DelayEvents(30s);
487 me->AttackStop();
488 if (!IsHeroic())
489 {
492 }
493 else
494 {
498 // cast variables
499 if (Is25ManRaid())
500 {
501 std::list<Unit*> targetList;
502 {
504 if (Player* target = ref->GetVictim()->ToPlayer())
505 targetList.push_back(target);
506 }
507
508 size_t half = targetList.size()/2;
509 // half gets ooze variable
510 while (half < targetList.size())
511 {
512 std::list<Unit*>::iterator itr = targetList.begin();
513 advance(itr, urand(0, targetList.size() - 1));
514 (*itr)->CastSpell(*itr, SPELL_OOZE_VARIABLE, true);
515 targetList.erase(itr);
516 }
517 // and half gets gas
518 for (std::list<Unit*>::iterator itr = targetList.begin(); itr != targetList.end(); ++itr)
519 (*itr)->CastSpell(*itr, SPELL_GAS_VARIABLE, true);
520 }
522 }
523 switch (_phase)
524 {
525 case PHASE_COMBAT_1:
529 break;
530 case PHASE_COMBAT_2:
534 break;
535 default:
536 break;
537 }
538 break;
539 default:
540 break;
541 }
542 }
543
544 uint32 GetData(uint32 type) const override
545 {
546 switch (type)
547 {
549 return _experimentState;
550 case DATA_PHASE:
551 return _phase;
552 case DATA_ABOMINATION:
554 default:
555 break;
556 }
557
558 return 0;
559 }
560
561 void SetData(uint32 id, uint32 data) override
562 {
563 if (id == DATA_EXPERIMENT_STAGE)
564 _experimentState = data != 0;
565 }
566
567 void UpdateAI(uint32 diff) override
568 {
570 return;
571
572 events.Update(diff);
573
575 return;
576
577 while (uint32 eventId = events.ExecuteEvent())
578 {
579 switch (eventId)
580 {
584 break;
587 if (Is25ManRaid())
589 else
591 break;
595 break;
599 break;
600 case EVENT_BERSERK:
603 break;
605 {
606 std::list<Unit*> targets;
607 SelectTargetList(targets, 2, SelectTargetMethod::Random, 0, 0.0f, true);
608 if (!targets.empty())
609 for (std::list<Unit*>::iterator itr = targets.begin(); itr != targets.end(); ++itr)
612 break;
613 }
618 break;
619 case EVENT_TEAR_GAS:
622 break;
626 // remove Tear Gas
631 break;
633 if (Is25ManRaid())
634 {
635 std::list<Unit*> targets;
636 SelectTargetList(targets, 2, SelectTargetMethod::Random, 0, -7.0f, true);
637 if (!targets.empty())
638 {
640 for (std::list<Unit*>::iterator itr = targets.begin(); itr != targets.end(); ++itr)
642 }
643 }
644 else
645 {
646 if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1, -7.0f, true))
647 {
650 }
651 }
653 break;
658 break;
661 {
664 }
666 break;
670 break;
672 {
673 switch (_phase)
674 {
675 case PHASE_COMBAT_2:
677 me->SetFacingToObject(face);
681 break;
682 case PHASE_COMBAT_3:
684 me->SetFacingToObject(face);
689 break;
690 default:
691 break;
692 }
693 break;
694 }
695 default:
696 break;
697 }
698
700 return;
701 }
702
704 }
705
706private:
708 {
709 _phase = newPhase;
710 events.SetPhase(newPhase);
711 }
712
714 PutricidePhases _phase; // external of EventMap because event phase gets reset on evade
715 float const _baseSpeed;
718};
719
721{
722 public:
723 npc_putricide_oozeAI(Creature* creature, uint32 auraSpellId, uint32 hitTargetSpellId) : ScriptedAI(creature),
724 _auraSpellId(auraSpellId), _hitTargetSpellId(hitTargetSpellId), _newTargetSelectTimer(0), _instance(creature->GetInstanceScript()) { }
725
726 void SpellHitTarget(WorldObject* /*target*/, SpellInfo const* spellInfo) override
727 {
728 if (!_newTargetSelectTimer && spellInfo->Id == sSpellMgr->GetSpellIdForDifficulty(_hitTargetSpellId, me))
729 {
731 // go passive until next target selection
733 }
734 }
735
736 void Reset() override
737 {
740
742 DoCastAOE(_auraSpellId, true);
743 }
744
745 void SpellHit(WorldObject* /*caster*/, SpellInfo const* spellInfo) override
746 {
747 if (spellInfo->Id == SPELL_TEAR_GAS_CREATURE)
749 }
750
751 void UpdateAI(uint32 diff) override
752 {
754 return;
755
756 if (!_newTargetSelectTimer && !me->IsNonMeleeSpellCast(false, false, true, false, true))
758
760
762 return;
763
765 return;
766
767 if (_newTargetSelectTimer <= diff)
768 {
771 }
772 else
773 _newTargetSelectTimer -= diff;
774 }
775
776 virtual void CastMainSpell() = 0;
777
778 private:
783};
784
785// 37697 - Volatile Ooze
795
796// 37562 - Gas Cloud
814
815// 70672, 72455, 72832, 72833 - Gaseous Bloat
817{
819
820 void HandleExtraEffect(AuraEffect const* /*aurEff*/)
821 {
822 Unit* target = GetTarget();
823 if (Unit* caster = GetCaster())
824 {
826 if (!target->HasAura(GetId()))
827 {
830 caster->CastSpell(caster, SPELL_GASEOUS_BLOAT, args);
831 }
832 }
833 }
834
835 void HandleProc(ProcEventInfo& eventInfo)
836 {
837 uint32 stack = GetStackAmount();
838 Unit* caster = eventInfo.GetActor();
839
840 int32 const mod = caster->GetMap()->Is25ManRaid() ? 1500 : 1250;
841 int32 dmg = 0;
842 for (uint8 i = 1; i <= stack; ++i)
843 dmg += mod * i;
844
846 args.AddSpellBP0(dmg);
847 caster->CastSpell(nullptr, SPELL_EXPUNGED_GAS, args);
848 }
849
855};
856
857// 70447, 72836, 72837, 72838 - Volatile Ooze Adhesive
858// 70672, 72455, 72832, 72833 - Gaseous Bloat
860{
862
863 bool Validate(SpellInfo const* spell) override
864 {
865 return ValidateSpellInfo({ spell->ExcludeTargetAuraSpell });
866 }
867
868 // set up initial variables and check if caster is creature
869 // this will let use safely use ToCreature() casts in entire script
870 bool Load() override
871 {
872 return GetCaster()->GetTypeId() == TYPEID_UNIT;
873 }
874
875 void SelectTarget(std::list<WorldObject*>& targets)
876 {
877 if (targets.empty())
878 {
880 GetCaster()->ToCreature()->DespawnOrUnsummon(1ms); // despawn next update
881 return;
882 }
883
885 targets.clear();
886 targets.push_back(target);
887 _target = target;
888 }
889
890 void SetTarget(std::list<WorldObject*>& targets)
891 {
892 targets.clear();
893 if (_target)
894 targets.push_back(_target);
895 }
896
906
914
916};
917
919{
920 public:
921 ExactDistanceCheck(Unit* source, float dist) : _source(source), _dist(dist) { }
922
923 bool operator()(WorldObject* unit) const
924 {
925 return _source->GetExactDist2d(unit) > _dist;
926 }
927
928 private:
930 float _dist;
931};
932
933// 70346, 72456, 72868, 72869 - Slime Puddle
949
950// this is here only because on retail you dont actually enter HEROIC mode for ICC
951// 72868, 72869 - Slime Puddle
953{
955
957 {
958 if (Unit* target = GetHitUnit())
959 GetCaster()->AddAura((GetCaster()->GetMap()->GetSpawnMode() & 1) ? 72456 : 70346, target);
960 }
961
966};
967
968// 70351, 71966, 71967, 71968 - Unstable Experiment
970{
972
974 {
975 PreventHitDefaultEffect(effIndex);
976 if (GetCaster()->GetTypeId() != TYPEID_UNIT)
977 return;
978
979 Creature* creature = GetCaster()->ToCreature();
980
981 uint32 stage = creature->AI()->GetData(DATA_EXPERIMENT_STAGE);
982 creature->AI()->SetData(DATA_EXPERIMENT_STAGE, stage ^ true);
983
984 Creature* target = nullptr;
985 std::list<Creature*> creList;
987 // 2 of them are spawned at green place - weird trick blizz
988 for (std::list<Creature*>::iterator itr = creList.begin(); itr != creList.end(); ++itr)
989 {
990 target = *itr;
991 std::list<Creature*> tmp;
993 if ((!stage && tmp.size() > 1) || (stage && tmp.size() == 1))
994 break;
995 }
996
997 GetCaster()->CastSpell(target, uint32(GetEffectInfo(SpellEffIndex(stage)).CalcValue()), true);
998 }
999
1004};
1005
1006// 70459 - Ooze Eruption Search Effect
1008{
1010
1011 void HandleDummy(SpellEffIndex /*effIndex*/)
1012 {
1013 uint32 adhesiveId = sSpellMgr->GetSpellIdForDifficulty(SPELL_VOLATILE_OOZE_ADHESIVE, GetCaster());
1014 if (GetHitUnit()->HasAura(adhesiveId))
1015 {
1018 }
1019 }
1020
1025};
1026
1027// 71770 - Ooze Spell Tank Protection
1029{
1031
1032 bool Validate(SpellInfo const* spellInfo) override
1033 {
1034 return ValidateSpellInfo({ spellInfo->GetEffect(EFFECT_0).TriggerSpell, spellInfo->GetEffect(EFFECT_1).TriggerSpell });
1035 }
1036
1037 void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo)
1038 {
1040
1041 Unit* actionTarget = eventInfo.GetActionTarget();
1042 actionTarget->CastSpell(nullptr, aurEff->GetSpellEffectInfo().TriggerSpell, aurEff);
1043 }
1044
1050};
1051
1052// 71255 - Choking Gas Bomb
1054{
1056
1057 void HandleScript(SpellEffIndex /*effIndex*/)
1058 {
1059 uint32 skipIndex = urand(0, 2);
1060 for (SpellEffectInfo const& spellEffectInfo : GetSpellInfo()->GetEffects())
1061 {
1062 if (spellEffectInfo.EffectIndex == skipIndex)
1063 continue;
1064
1065 uint32 spellId = uint32(spellEffectInfo.CalcValue());
1066 GetCaster()->CastSpell(GetCaster(), spellId, GetCaster()->GetGUID());
1067 }
1068 }
1069
1074};
1075
1076// 70920 - Unbound Plague Search Effect
1078{
1080
1081 bool Validate(SpellInfo const* /*spell*/) override
1082 {
1084 }
1085
1086 void FilterTargets(std::list<WorldObject*>& targets)
1087 {
1088 if (AuraEffect const* eff = GetCaster()->GetAuraEffect(SPELL_UNBOUND_PLAGUE_SEARCHER, EFFECT_0))
1089 {
1090 if (eff->GetTickNumber() < 2)
1091 {
1092 targets.clear();
1093 return;
1094 }
1095 }
1096
1097 targets.remove_if(Trinity::UnitAuraCheck(true, sSpellMgr->GetSpellIdForDifficulty(SPELL_UNBOUND_PLAGUE, GetCaster())));
1099 }
1100
1101 void HandleScript(SpellEffIndex /*effIndex*/)
1102 {
1103 if (!GetHitUnit())
1104 return;
1105
1107 if (!instance)
1108 return;
1109
1110 uint32 plagueId = sSpellMgr->GetSpellIdForDifficulty(SPELL_UNBOUND_PLAGUE, GetCaster());
1111
1112 if (!GetHitUnit()->HasAura(plagueId))
1113 {
1115 {
1116 if (Aura* oldPlague = GetCaster()->GetAura(plagueId, professor->GetGUID()))
1117 {
1118 if (Aura* newPlague = professor->AddAura(plagueId, GetHitUnit()))
1119 {
1120 newPlague->SetMaxDuration(oldPlague->GetMaxDuration());
1121 newPlague->SetDuration(oldPlague->GetDuration());
1122 oldPlague->Remove();
1126 professor->CastSpell(GetHitUnit(), SPELL_UNBOUND_PLAGUE_SEARCHER, true);
1127 }
1128 }
1129 }
1130 }
1131 }
1132
1138};
1139
1140// 70360, 72527 - Eat Ooze
1142{
1144
1145 void SelectTarget(std::list<WorldObject*>& targets)
1146 {
1147 if (targets.empty())
1148 return;
1149
1151 WorldObject* target = targets.front();
1152 targets.clear();
1153 targets.push_back(target);
1154 }
1155
1156 void HandleScript(SpellEffIndex /*effIndex*/)
1157 {
1158 Creature* target = GetHitCreature();
1159 if (!target)
1160 return;
1161
1162 if (Aura* grow = target->GetAura(uint32(GetEffectValue())))
1163 {
1164 if (grow->GetStackAmount() < 3)
1165 {
1167 target->RemoveAura(grow);
1168 target->DespawnOrUnsummon(1ms);
1169 }
1170 else
1171 grow->ModStackAmount(-3);
1172 }
1173 }
1174
1180};
1181
1182// 72451, 72463, 72671, 72672 - Mutated Plague
1184{
1186
1187 void HandleTriggerSpell(AuraEffect const* aurEff)
1188 {
1190 Unit* caster = GetCaster();
1191 if (!caster)
1192 return;
1193
1194 uint32 triggerSpell = aurEff->GetSpellEffectInfo().TriggerSpell;
1195 SpellInfo const* spell = sSpellMgr->AssertSpellInfo(triggerSpell);
1196 spell = sSpellMgr->GetSpellForDifficultyFromSpell(spell, caster);
1197
1198 int32 damage = spell->GetEffect(EFFECT_0).CalcValue(caster);
1199 float multiplier = 2.0f;
1200 if (GetTarget()->GetMap()->GetSpawnMode() & 1)
1201 multiplier = 3.0f;
1202
1203 damage *= int32(pow(multiplier, GetStackAmount()));
1204 damage = int32(damage * 1.5f);
1205
1206 CastSpellExtraArgs args(aurEff);
1208 args.AddSpellBP0(damage);
1209 GetTarget()->CastSpell(GetTarget(), triggerSpell, args);
1210 }
1211
1212 void OnRemove(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
1213 {
1214 uint32 healSpell = uint32(aurEff->GetSpellEffectInfo().CalcValue());
1215 SpellInfo const* healSpellInfo = sSpellMgr->GetSpellInfo(healSpell);
1216
1217 if (!healSpellInfo)
1218 return;
1219
1220 int32 heal = healSpellInfo->GetEffect(EFFECT_0).CalcValue() * GetStackAmount();
1222 args.AddSpellBP0(heal);
1223 GetTarget()->CastSpell(GetTarget(), healSpell, args);
1224 }
1225
1231};
1232
1233// 70308 - Mutated Transformation (Init)
1235{
1237
1239 {
1241 if (!instance)
1243
1245 if (!professor)
1247
1248 if (professor->AI()->GetData(DATA_PHASE) == PHASE_COMBAT_3 || !professor->IsAlive())
1249 {
1252 }
1253
1254 if (professor->AI()->GetData(DATA_ABOMINATION))
1255 {
1258 }
1259
1260 return SPELL_CAST_OK;
1261 }
1262
1264 {
1265 if (!GetExplTargetUnit())
1267
1268 if (GetExplTargetUnit()->GetTypeId() != TYPEID_PLAYER)
1270
1272 SpellCastResult result = CheckRequirementInternal(extension);
1273 if (result != SPELL_CAST_OK)
1274 {
1275 Spell::SendCastResult(GetExplTargetUnit()->ToPlayer(), GetSpellInfo(), 0, result, extension);
1276 return result;
1277 }
1278
1279 return SPELL_CAST_OK;
1280 }
1281
1286};
1287
1289{
1291
1292 void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
1293 {
1294 uint32 spellId = 70311;
1295 if (GetTarget()->GetMap()->GetSpawnMode() & 1)
1296 spellId = 71503;
1297
1298 GetTarget()->CastSpell(GetTarget(), spellId, true);
1299 }
1300
1305};
1306
1307// 70405, 72508, 72509, 72510 - Mutated Transformation (Dismiss)
1323
1324// 70311, 71503 - Mutated Transformation
1326{
1328
1330 {
1331 PreventHitDefaultEffect(effIndex);
1332 Unit* caster = GetOriginalCaster();
1333 if (!caster)
1334 return;
1335
1336 InstanceScript* instance = caster->GetInstanceScript();
1337 if (!instance)
1338 return;
1339
1341 if (!putricide)
1342 return;
1343
1344 if (putricide->AI()->GetData(DATA_ABOMINATION))
1345 {
1346 if (Player* player = caster->ToPlayer())
1348 return;
1349 }
1350
1351 uint32 entry = uint32(GetEffectInfo().MiscValue);
1352 SummonPropertiesEntry const* properties = sSummonPropertiesStore.LookupEntry(uint32(GetEffectInfo().MiscValueB));
1353 uint32 duration = uint32(GetSpellInfo()->GetDuration());
1354
1355 Position pos = caster->GetPosition();
1356 TempSummon* summon = caster->GetMap()->SummonCreature(entry, pos, properties, duration, caster, GetSpellInfo()->Id);
1357 if (!summon || !summon->IsVehicle())
1358 return;
1359
1360 summon->CastSpell(summon, SPELL_ABOMINATION_VEHICLE_POWER_DRAIN, true);
1361 summon->CastSpell(summon, SPELL_MUTATED_TRANSFORMATION_DAMAGE, true);
1362 caster->CastSpell(summon, SPELL_MUTATED_TRANSFORMATION_NAME, true);
1363
1364 caster->EnterVehicle(summon, 0); // VEHICLE_SPELL_RIDE_HARDCODED is used according to sniff, this is ok
1365 summon->SetCreatorGUID(caster->GetGUID());
1366 putricide->AI()->JustSummoned(summon);
1367 }
1368
1373};
1374
1375// 70402, 72511, 72512, 72513 - Mutated Transformation (Damage)
1391
1392// 70539, 72457, 72875, 72876 - Regurgitated Ooze
1394{
1396
1397 // the only purpose of this hook is to fail the achievement
1398 void ExtraEffect(SpellEffIndex /*effIndex*/)
1399 {
1400 if (InstanceScript* instance = GetCaster()->GetInstanceScript())
1401 instance->SetData(DATA_NAUSEA_ACHIEVEMENT, uint32(false));
1402 }
1403
1408};
1409
1410// Removes aura with id stored in effect value
1411// 71620 - Tear Gas Cancel
1412// 72618 - Mutated Plague Clear
1432
1433// Stinky and Precious spell, it's here because its used for both (Festergut and Rotface "pets")
1434// 71123 - Decimate
1436{
1438
1439 void HandleScript(SpellEffIndex /*effIndex*/)
1440 {
1441 if (GetHitUnit()->GetHealthPct() > float(GetEffectValue()))
1442 {
1443 uint32 newHealth = GetHitUnit()->GetMaxHealth() * uint32(GetEffectValue()) / 100;
1444 GetHitUnit()->SetHealth(newHealth);
1445 }
1446 }
1447
1452};
1453
1454// 70402, 72511, 72512, 72513 - Mutated Transformation
1456{
1458
1459 void HandleResistance(DamageInfo const& damageInfo, uint32& resistAmount, int32& /*absorbAmount*/)
1460 {
1461 Unit* caster = damageInfo.GetAttacker();;
1462 Unit* target = damageInfo.GetVictim();
1463 uint32 damage = damageInfo.GetDamage();
1464 uint32 resistedDamage = Unit::CalcSpellResistedDamage(caster, target, damage, SPELL_SCHOOL_MASK_SHADOW, nullptr);
1465 resistedDamage += Unit::CalcSpellResistedDamage(caster, target, damage, SPELL_SCHOOL_MASK_NATURE, nullptr);
1466 resistAmount = resistedDamage;
1467 }
1468
1473};
1474
1475// 71278, 72460, 72619, 72620 - Choking Gas
1476// 71279, 72459, 72621, 72622 - Choking Gas Explosion
1478{
1480
1481 bool Validate(SpellInfo const* /*spell*/) override
1482 {
1484 }
1485
1486 void FilterTargets(std::list<WorldObject*>& targets)
1487 {
1488 targets.remove_if([](WorldObject* obj)
1489 {
1490 return obj->ToUnit() && obj->ToUnit()->GetVehicle();
1491 });
1492 }
1493
1494 void HandleDispel(SpellEffIndex /*effIndex*/)
1495 {
1496 Unit* target = GetHitUnit();
1499 }
1500
1506};
1507
1509{
1510 // Creatures
1514
1515 // Spells
1536}
DBCStorage< SummonPropertiesEntry > sSummonPropertiesStore(SummonPropertiesfmt)
uint8_t uint8
Definition Define.h:135
int32_t int32
Definition Define.h:129
uint32_t uint32
Definition Define.h:133
std::chrono::milliseconds Milliseconds
Milliseconds shorthand typedef.
Definition Duration.h:24
@ IN_PROGRESS
@ FAIL
@ DONE
@ NOT_STARTED
@ POINT_MOTION_TYPE
@ TYPEID_UNIT
Definition ObjectGuid.h:38
@ TYPEID_PLAYER
Definition ObjectGuid.h:39
uint32 urand(uint32 min, uint32 max)
Definition Random.cpp:42
#define RegisterSpellAndAuraScriptPair(script_1, script_2)
Definition ScriptMgr.h:1130
#define RegisterSpellScript(spell_script)
Definition ScriptMgr.h:1128
void GetCreatureListWithEntryInGrid(Container &container, WorldObject *source, uint32 entry, float maxSearchRange)
SpellEffIndex
@ EFFECT_1
@ EFFECT_0
@ EFFECT_2
@ SPELL_EFFECT_DUMMY
@ SPELL_EFFECT_SCRIPT_EFFECT
@ SPELL_EFFECT_SUMMON
@ SPELL_EFFECT_APPLY_AURA
@ 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
SpellCustomErrors
@ SPELL_CUSTOM_ERROR_NONE
@ SPELL_CUSTOM_ERROR_TOO_MANY_ABOMINATIONS
@ SPELL_CUSTOM_ERROR_ALL_POTIONS_USED
@ AURA_STATE_UNKNOWN19
@ AURA_STATE_UNKNOWN22
#define EFFECT_ALL
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_REMOVE_BY_ENEMY_SPELL
AuraEffectHandleModes
@ AURA_EFFECT_HANDLE_REAL
@ SPELL_AURA_PERIODIC_DAMAGE
@ SPELL_AURA_PROC_TRIGGER_SPELL
@ SPELL_AURA_DUMMY
@ SPELL_AURA_PERIODIC_TRIGGER_SPELL
@ SPELLVALUE_AURA_STACK
@ SPELLVALUE_MAX_TARGETS
#define sSpellMgr
Definition SpellMgr.h:738
#define AuraProcFn(F)
#define SpellCheckCastFn(F)
#define AuraEffectProcFn(F, I, N)
#define SpellOnResistAbsorbCalculateFn(F)
#define SpellEffectFn(F, I, N)
#define SpellObjectAreaTargetSelectFn(F, I, N)
#define AuraEffectPeriodicFn(F, I, N)
#define SpellHitFn(F)
#define AuraEffectRemoveFn(F, I, N, M)
@ REACT_DEFENSIVE
@ REACT_PASSIVE
@ REACT_AGGRESSIVE
@ MOVE_RUN
@ UNIT_FLAG_UNINTERACTIBLE
@ UNIT_STATE_CASTING
Definition Unit.h:235
DamageEffectType
Definition Unit.h:352
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_UNSTABLE_EXPERIMENT
@ SPELL_GASEOUS_BLOAT_PROC
@ SPELL_UNHOLY_INFUSION_CREDIT
@ SPELL_OOZE_TANK_PROTECTION
@ SPELL_ABOMINATION_VEHICLE_POWER_DRAIN
@ SPELL_VOLATILE_OOZE_PROTECTION
@ SPELL_CREATE_CONCOCTION
@ SPELL_MUTATED_TRANSFORMATION_NAME
@ SPELL_TEAR_GAS_TRIGGER_MISSILE
@ SPELL_RELEASE_GAS_VISUAL
@ SPELL_GASEOUS_BLIGHT_LARGE
@ SPELL_GASEOUS_BLIGHT_MEDIUM
@ SPELL_GASEOUS_BLIGHT_SMALL
@ SPELL_MALLEABLE_GOO_SUMMON
@ SPELL_CHOKING_GAS_EXPLOSION_TRIGGER
@ SPELL_MUTATED_PLAGUE_CLEAR
@ EVENT_UNSTABLE_EXPERIMENT
Position const rotfaceWatchPos
@ SAY_PHASE_TRANSITION_HEROIC
@ SAY_FESTERGUT_GASEOUS_BLIGHT
@ EMOTE_UNSTABLE_EXPERIMENT
Position const tablePos
uint32 const oozeFloodSpells[4]
void AddSC_boss_professor_putricide()
#define EXPERIMENT_STATE_OOZE
bool operator()(ObjectGuid guid)
SpellEffectInfo const & GetSpellEffectInfo() const
void PreventDefaultAction()
HookList< EffectApplyHandler > AfterEffectRemove
HookList< EffectPeriodicHandler > OnEffectPeriodic
SpellInfo const * GetSpellInfo() const
Unit * GetCaster() const
Unit * GetTarget() const
ObjectGuid GetCasterGUID() const
HookList< EffectProcHandler > OnEffectProc
HookList< AuraProcHandler > OnProc
uint8 GetStackAmount() const
uint32 GetId() const
InstanceScript *const instance
void _JustReachedHome()
SummonList summons
EventMap events
virtual void JustSummoned(Creature *)
Definition CreatureAI.h:136
void DoZoneInCombat(Creature *creature=nullptr)
bool UpdateVictim()
void EngagementStart(Unit *who)
Creature *const me
Definition CreatureAI.h:82
virtual void EnterEvadeMode(EvadeReason why=EVADE_REASON_OTHER)
void SetCombatPulseDelay(uint32 delay)
Definition Creature.h:269
void SetImmuneToPC(bool apply) override
Definition Creature.h:129
void SetReactState(ReactStates st)
Definition Creature.h:119
void DespawnOrUnsummon(Milliseconds timeToDespawn=0s, Seconds forceRespawnTime=0s)
CreatureAI * AI() const
Definition Creature.h:154
Unit * GetVictim() const
Definition Unit.h:459
Unit * GetAttacker() const
Definition Unit.h:458
uint32 GetDamage() const
Definition Unit.h:464
void Update(uint32 time)
Definition EventMap.h:67
void DelayEvents(Milliseconds delay)
Definition EventMap.cpp:95
EventId ExecuteEvent()
Definition EventMap.cpp:73
bool IsInPhase(PhaseIndex phase) const
Definition EventMap.h:236
void CancelEvent(EventId eventId)
Definition EventMap.cpp:151
void SetPhase(PhaseIndex phase)
Definition EventMap.cpp:28
void ScheduleEvent(EventId eventId, Milliseconds time, GroupIndex group=0u, PhaseIndex phase=0u)
Definition EventMap.cpp:36
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
bool Is25ManRaid() const
Definition Map.cpp:4261
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
void MovePoint(uint32 id, Position const &pos, bool generatePath=true, Optional< float > finalOrient={})
static Creature * ToCreature(Object *o)
Definition Object.h:186
static Unit * ToUnit(Object *o)
Definition Object.h:192
TypeID GetTypeId() const
Definition Object.h:93
uint32 GetEntry() const
Definition Object.h:81
static ObjectGuid GetGUID(Object const *o)
Definition Object.h:78
static Player * ToPlayer(Object *o)
Definition Object.h:180
Unit * GetActionTarget() const
Definition Unit.h:509
Unit * GetActor()
Definition Unit.h:508
uint32 TriggerSpell
Definition SpellInfo.h:228
int32 CalcValue(WorldObject const *caster=nullptr, int32 const *basePoints=nullptr) const
uint32 ExcludeTargetAuraSpell
Definition SpellInfo.h:315
uint32 Id
Definition SpellInfo.h:289
SpellEffectInfo const & GetEffect(SpellEffIndex index) const
Definition SpellInfo.h:483
std::array< SpellEffectInfo, MAX_SPELL_EFFECTS > const & GetEffects() const
Definition SpellInfo.h:482
HookList< CheckCastHandler > OnCheckCast
Creature * GetHitCreature() const
Unit * GetCaster() const
HookList< HitHandler > AfterHit
HookList< HitHandler > OnHit
HookList< EffectHandler > OnEffectHit
void PreventHitDefaultEffect(SpellEffIndex effIndex)
Unit * GetHitUnit() const
int32 GetEffectValue() const
SpellEffectInfo const & GetEffectInfo() const
HookList< EffectHandler > OnEffectHitTarget
HookList< OnCalculateResistAbsorbHandler > OnCalculateResistAbsorb
Unit * GetExplTargetUnit() const
SpellInfo const * GetSpellInfo() const
void FinishCast(SpellCastResult result, uint32 *param1=nullptr, uint32 *param2=nullptr)
HookList< ObjectAreaTargetSelectHandler > OnObjectAreaTargetSelect
Unit * GetOriginalCaster() const
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
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:156
void DoMeleeAttackIfReady()
Definition UnitAI.cpp:54
virtual uint32 GetData(uint32) const
Definition UnitAI.h:155
SpellCastResult DoCastVictim(uint32 spellId, CastSpellExtraArgs const &args={})
Definition UnitAI.cpp:166
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:101
Unit * SelectTarget(SelectTargetMethod targetType, uint32 offset=0, float dist=0.0f, bool playerOnly=false, bool withTank=true, int32 aura=0)
Definition UnitAI.cpp:96
virtual void AttackStart(Unit *)
Definition UnitAI.cpp:30
SpellCastResult DoCastAOE(uint32 spellId, CastSpellExtraArgs const &args={})
Definition UnitAI.h:243
SpellCastResult DoCast(uint32 spellId)
Definition UnitAI.cpp:106
Definition Unit.h:769
void EnterVehicle(Unit *base, int8 seatId=-1)
Definition Unit.cpp:12569
void ClearUnitState(uint32 f)
Definition Unit.h:877
bool IsVehicle() const
Definition Unit.h:887
Vehicle * GetVehicle() const
Definition Unit.h:1737
Aura * GetAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint8 reqEffMask=0) const
Definition Unit.cpp:4439
void RemoveAura(AuraApplicationMap::iterator &i, AuraRemoveMode mode=AURA_REMOVE_BY_DEFAULT)
Definition Unit.cpp:3638
ThreatManager & GetThreatManager()
Definition Unit.h:1155
MotionMaster * GetMotionMaster()
Definition Unit.h:1667
bool IsNonMeleeSpellCast(bool withDelayed, bool skipChanneled=false, bool skipAutorepeat=false, bool isAutoshoot=false, bool skipInstant=true) const
Definition Unit.cpp:3063
uint32 GetMaxHealth() const
Definition Unit.h:914
Aura * AddAura(uint32 spellId, Unit *target)
Definition Unit.cpp:11964
bool IsAlive() const
Definition Unit.h:1234
static uint32 CalcSpellResistedDamage(Unit const *attacker, Unit *victim, uint32 damage, SpellSchoolMask schoolMask, SpellInfo const *spellInfo)
Definition Unit.cpp:1653
void SetHealth(uint32 val)
Definition Unit.cpp:9361
bool HasAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint8 reqEffMask=0) const
Definition Unit.cpp:4535
void SetFacingToObject(WorldObject const *object, bool force=true, uint32 movementId=EVENT_FACE)
Definition Unit.cpp:13259
void ModifyAuraState(AuraStateType flag, bool apply)
Definition Unit.cpp:5749
void RemoveAuraFromStack(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition Unit.cpp:3800
bool SetWalk(bool enable)
Definition Unit.cpp:13268
void RemoveAurasDueToSpell(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, uint8 reqEffMask=0, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition Unit.cpp:3784
Unit * GetVictim() const
Definition Unit.h:859
void SetSpeedRate(UnitMoveType mtype, float rate)
Definition Unit.cpp:8678
bool HasUnitState(const uint32 f) const
Definition Unit.h:876
void HandleEmoteCommand(Emote emoteId)
Definition Unit.cpp:1568
void SetCreatorGUID(ObjectGuid creator)
Definition Unit.h:1244
bool AttackStop()
Definition Unit.cpp:5645
bool IsInCombat() const
Definition Unit.h:1144
void RemoveUnitFlag(UnitFlags flags)
Definition Unit.h:955
Map * GetMap() const
Definition Object.h:449
InstanceScript * GetInstanceScript() const
Definition Object.cpp:1087
SpellCastResult CastSpell(CastSpellTargetArg const &targets, uint32 spellId, CastSpellExtraArgs const &args={ })
Definition Object.cpp:2832
void setActive(bool isActiveObject)
Definition Object.cpp:991
Creature * FindNearestCreature(uint32 entry, float range, bool alive=true) const
Definition Object.cpp:2099
virtual void SetData(uint32, uint32)
Definition ZoneScript.h:56
static bool ValidateSpellInfo(std::initializer_list< uint32 > spellIds)
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
PrepareSpellScript(spell_abomination_mutated_transformation)
void HandleResistance(DamageInfo const &damageInfo, uint32 &resistAmount, int32 &)
PrepareSpellScript(spell_putricide_choking_gas_bomb)
PrepareSpellScript(spell_putricide_choking_gas_filter)
void FilterTargets(std::list< WorldObject * > &targets)
bool Validate(SpellInfo const *) override
PrepareSpellScript(spell_putricide_clear_aura_effect_value)
PrepareSpellScript(spell_putricide_eat_ooze)
void SelectTarget(std::list< WorldObject * > &targets)
PrepareAuraScript(spell_putricide_gaseous_bloat)
void HandleProc(ProcEventInfo &eventInfo)
void OnRemove(AuraEffect const *aurEff, AuraEffectHandleModes)
PrepareAuraScript(spell_putricide_mutated_plague)
void HandleTriggerSpell(AuraEffect const *aurEff)
void OnRemove(AuraEffect const *, AuraEffectHandleModes)
PrepareAuraScript(spell_putricide_mutated_transformation_dismiss)
void FilterTargetsInitial(std::list< WorldObject * > &targets)
PrepareSpellScript(spell_putricide_mutated_transformation_dmg)
PrepareSpellScript(spell_putricide_mutated_transformation)
PrepareAuraScript(spell_putricide_mutation_init_aura)
void OnRemove(AuraEffect const *, AuraEffectHandleModes)
PrepareSpellScript(spell_putricide_mutation_init)
SpellCastResult CheckRequirementInternal(SpellCustomErrors &extendedError)
void SetTarget(std::list< WorldObject * > &targets)
void SelectTarget(std::list< WorldObject * > &targets)
bool Validate(SpellInfo const *spell) override
PrepareSpellScript(spell_putricide_ooze_channel)
PrepareSpellScript(spell_putricide_ooze_eruption_searcher)
PrepareAuraScript(spell_putricide_ooze_tank_protection)
void HandleProc(AuraEffect const *aurEff, ProcEventInfo &eventInfo)
bool Validate(SpellInfo const *spellInfo) override
PrepareSpellScript(spell_putricide_regurgitated_ooze)
PrepareSpellScript(spell_putricide_slime_puddle_aura)
PrepareSpellScript(spell_putricide_slime_puddle)
void ScaleRange(std::list< WorldObject * > &targets)
void FilterTargets(std::list< WorldObject * > &targets)
bool Validate(SpellInfo const *) override
PrepareSpellScript(spell_putricide_unbound_plague)
PrepareSpellScript(spell_putricide_unstable_experiment)
PrepareSpellScript(spell_stinky_precious_decimate)
@ 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:108
void RandomResize(C &container, std::size_t requestedSize)
Definition Containers.h:66
CastSpellExtraArgs & AddSpellBP0(int32 val)
CastSpellExtraArgs & AddSpellMod(SpellValueMod mod, int32 val)
ObjectGuid OriginalCaster
float GetExactDist2d(const float x, const float y) const
Definition Position.h:109
float GetPositionZ() const
Definition Position.h:81
void GetPosition(float &x, float &y) const
Definition Position.h:84
bool operator()(Creature *stalker) const
RotfaceHeightCheck(Creature *rotface)
bool IsHeroic() const
void AttackStart(Unit *) override
bool HealthAbovePct(uint32 pct) const
bool Is25ManRaid() const
void SetPhase(PutricidePhases newPhase)
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)