diff options
author | ForesterDev <11771800+ForesterDev@users.noreply.github.com> | 2020-09-04 18:59:46 +0400 |
---|---|---|
committer | Shauren <shauren.trinity@gmail.com> | 2022-02-05 11:10:39 +0100 |
commit | ceec4ecf3527cf96c52df8b6b0e64a79819e4f14 (patch) | |
tree | 0dba93c2c44f3a25a120cacfe6897b796f7a5cb9 | |
parent | 1c22cd7d089eeeab93be4ee013bcd8739528433f (diff) |
Scripts/ICC: update Professor Putricide scripts to new model (#25394)
* Scripts/ICC: update Professor Putricide scripts to new model
* fix build
(cherry picked from commit 0b0d5e9beaf0cc2b7c94e0884a4269899c55691c)
-rw-r--r-- | src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp | 2091 |
1 files changed, 929 insertions, 1162 deletions
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp index 8b043947186..e472906fc73 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp @@ -217,511 +217,500 @@ private: Creature* _rotface; }; -class boss_professor_putricide : public CreatureScript +struct boss_professor_putricide : public BossAI { - public: - boss_professor_putricide() : CreatureScript("boss_professor_putricide") { } + boss_professor_putricide(Creature* creature) : BossAI(creature, DATA_PROFESSOR_PUTRICIDE), + _baseSpeed(creature->GetSpeedRate(MOVE_RUN)), _experimentState(EXPERIMENT_STATE_OOZE) + { + _phase = PHASE_NONE; + _oozeFloodStage = 0; + } - struct boss_professor_putricideAI : public BossAI + void Reset() override + { + if (!(events.IsInPhase(PHASE_ROTFACE) || events.IsInPhase(PHASE_FESTERGUT))) + instance->SetBossState(DATA_PROFESSOR_PUTRICIDE, NOT_STARTED); + instance->SetData(DATA_NAUSEA_ACHIEVEMENT, uint32(true)); + + events.Reset(); + summons.DespawnAll(); + SetPhase(PHASE_COMBAT_1); + _experimentState = EXPERIMENT_STATE_OOZE; + me->SetReactState(REACT_DEFENSIVE); + me->SetWalk(false); + + if (instance->GetBossState(DATA_ROTFACE) == DONE && instance->GetBossState(DATA_FESTERGUT) == DONE) { - boss_professor_putricideAI(Creature* creature) : BossAI(creature, DATA_PROFESSOR_PUTRICIDE), - _baseSpeed(creature->GetSpeedRate(MOVE_RUN)), _experimentState(EXPERIMENT_STATE_OOZE) - { - _phase = PHASE_NONE; - _oozeFloodStage = 0; - } + me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE); + me->SetImmuneToPC(false); + } + } - void Reset() override - { - if (!(events.IsInPhase(PHASE_ROTFACE) || events.IsInPhase(PHASE_FESTERGUT))) - instance->SetBossState(DATA_PROFESSOR_PUTRICIDE, NOT_STARTED); - instance->SetData(DATA_NAUSEA_ACHIEVEMENT, uint32(true)); - - events.Reset(); - summons.DespawnAll(); - SetPhase(PHASE_COMBAT_1); - _experimentState = EXPERIMENT_STATE_OOZE; - me->SetReactState(REACT_DEFENSIVE); - me->SetWalk(false); - - if (instance->GetBossState(DATA_ROTFACE) == DONE && instance->GetBossState(DATA_FESTERGUT) == DONE) - { - me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE); - me->SetImmuneToPC(false); - } - } + void JustEngagedWith(Unit* who) override + { + if (events.IsInPhase(PHASE_ROTFACE) || events.IsInPhase(PHASE_FESTERGUT)) + return; - void JustEngagedWith(Unit* who) override - { - if (events.IsInPhase(PHASE_ROTFACE) || events.IsInPhase(PHASE_FESTERGUT)) - return; + if (!instance->CheckRequiredBosses(DATA_PROFESSOR_PUTRICIDE, who->ToPlayer())) + { + EnterEvadeMode(); + instance->DoCastSpellOnPlayers(LIGHT_S_HAMMER_TELEPORT); + return; + } - if (!instance->CheckRequiredBosses(DATA_PROFESSOR_PUTRICIDE, who->ToPlayer())) - { - EnterEvadeMode(); - instance->DoCastSpellOnPlayers(LIGHT_S_HAMMER_TELEPORT); - return; - } + me->setActive(true); + events.Reset(); + events.ScheduleEvent(EVENT_BERSERK, 10min); + events.ScheduleEvent(EVENT_SLIME_PUDDLE, 10s); + events.ScheduleEvent(EVENT_UNSTABLE_EXPERIMENT, 30s, 35s); + if (IsHeroic()) + events.ScheduleEvent(EVENT_UNBOUND_PLAGUE, 20s); + + SetPhase(PHASE_COMBAT_1); + Talk(SAY_AGGRO); + DoCast(me, SPELL_OOZE_TANK_PROTECTION, true); + DoZoneInCombat(me); + me->SetCombatPulseDelay(5); + instance->SetBossState(DATA_PROFESSOR_PUTRICIDE, IN_PROGRESS); + } - me->setActive(true); - events.Reset(); - events.ScheduleEvent(EVENT_BERSERK, 10min); - events.ScheduleEvent(EVENT_SLIME_PUDDLE, 10s); - events.ScheduleEvent(EVENT_UNSTABLE_EXPERIMENT, 30s, 35s); - if (IsHeroic()) - events.ScheduleEvent(EVENT_UNBOUND_PLAGUE, 20s); - - SetPhase(PHASE_COMBAT_1); - Talk(SAY_AGGRO); - DoCast(me, SPELL_OOZE_TANK_PROTECTION, true); - DoZoneInCombat(me); - me->SetCombatPulseDelay(5); - instance->SetBossState(DATA_PROFESSOR_PUTRICIDE, IN_PROGRESS); - } + void JustReachedHome() override + { + _JustReachedHome(); + me->SetWalk(false); + if (events.IsInPhase(PHASE_COMBAT_1) || events.IsInPhase(PHASE_COMBAT_2) || events.IsInPhase(PHASE_COMBAT_3)) + instance->SetBossState(DATA_PROFESSOR_PUTRICIDE, FAIL); + } - void JustReachedHome() override - { - _JustReachedHome(); - me->SetWalk(false); - if (events.IsInPhase(PHASE_COMBAT_1) || events.IsInPhase(PHASE_COMBAT_2) || events.IsInPhase(PHASE_COMBAT_3)) - instance->SetBossState(DATA_PROFESSOR_PUTRICIDE, FAIL); - } + void KilledUnit(Unit* victim) override + { + if (victim->GetTypeId() == TYPEID_PLAYER) + Talk(SAY_KILL); + } - void KilledUnit(Unit* victim) override - { - if (victim->GetTypeId() == TYPEID_PLAYER) - Talk(SAY_KILL); - } + void JustDied(Unit* /*killer*/) override + { + _JustDied(); + Talk(SAY_DEATH); - void JustDied(Unit* /*killer*/) override - { - _JustDied(); - Talk(SAY_DEATH); + if (Is25ManRaid() && me->HasAura(SPELL_SHADOWS_FATE)) + DoCastAOE(SPELL_UNHOLY_INFUSION_CREDIT, true); - if (Is25ManRaid() && me->HasAura(SPELL_SHADOWS_FATE)) - DoCastAOE(SPELL_UNHOLY_INFUSION_CREDIT, true); + DoCast(SPELL_MUTATED_PLAGUE_CLEAR); + } - DoCast(SPELL_MUTATED_PLAGUE_CLEAR); - } + void JustSummoned(Creature* summon) override + { + summons.Summon(summon); + switch (summon->GetEntry()) + { + case NPC_MALLEABLE_OOZE_STALKER: + DoCast(summon, SPELL_MALLEABLE_GOO_H); + return; + case NPC_GROWING_OOZE_PUDDLE: + summon->CastSpell(summon, SPELL_GROW_STACKER, true); + summon->CastSpell(summon, SPELL_SLIME_PUDDLE_AURA, true); + // blizzard casts this spell 7 times initially (confirmed in sniff) + for (uint8 i = 0; i < 7; ++i) + summon->CastSpell(summon, SPELL_GROW, true); + break; + case NPC_GAS_CLOUD: + // no possible aura seen in sniff adding the aurastate + summon->ModifyAuraState(AURA_STATE_RAID_ENCOUNTER, true); + summon->SetReactState(REACT_PASSIVE); + break; + case NPC_VOLATILE_OOZE: + // no possible aura seen in sniff adding the aurastate + summon->ModifyAuraState(AURA_STATE_VULNERABLE, true); + summon->SetReactState(REACT_PASSIVE); + break; + case NPC_CHOKING_GAS_BOMB: + summon->CastSpell(summon, SPELL_CHOKING_GAS_BOMB_PERIODIC, true); + summon->CastSpell(summon, SPELL_CHOKING_GAS_EXPLOSION_TRIGGER, true); + return; + case NPC_MUTATED_ABOMINATION_10: + case NPC_MUTATED_ABOMINATION_25: + return; + default: + break; + } - void JustSummoned(Creature* summon) override - { - summons.Summon(summon); - switch (summon->GetEntry()) - { - case NPC_MALLEABLE_OOZE_STALKER: - DoCast(summon, SPELL_MALLEABLE_GOO_H); - return; - case NPC_GROWING_OOZE_PUDDLE: - summon->CastSpell(summon, SPELL_GROW_STACKER, true); - summon->CastSpell(summon, SPELL_SLIME_PUDDLE_AURA, true); - // blizzard casts this spell 7 times initially (confirmed in sniff) - for (uint8 i = 0; i < 7; ++i) - summon->CastSpell(summon, SPELL_GROW, true); - break; - case NPC_GAS_CLOUD: - // no possible aura seen in sniff adding the aurastate - summon->ModifyAuraState(AURA_STATE_RAID_ENCOUNTER, true); - summon->SetReactState(REACT_PASSIVE); - break; - case NPC_VOLATILE_OOZE: - // no possible aura seen in sniff adding the aurastate - summon->ModifyAuraState(AURA_STATE_VULNERABLE, true); - summon->SetReactState(REACT_PASSIVE); - break; - case NPC_CHOKING_GAS_BOMB: - summon->CastSpell(summon, SPELL_CHOKING_GAS_BOMB_PERIODIC, true); - summon->CastSpell(summon, SPELL_CHOKING_GAS_EXPLOSION_TRIGGER, true); - return; - case NPC_MUTATED_ABOMINATION_10: - case NPC_MUTATED_ABOMINATION_25: - return; - default: - break; - } + if (me->IsInCombat()) + DoZoneInCombat(summon); + } - if (me->IsInCombat()) - DoZoneInCombat(summon); - } + void DamageTaken(Unit* /*attacker*/, uint32& /*damage*/) override + { + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; - void DamageTaken(Unit* /*attacker*/, uint32& /*damage*/) override - { - if (me->HasUnitState(UNIT_STATE_CASTING)) + switch (_phase) + { + case PHASE_COMBAT_1: + if (HealthAbovePct(80)) + return; + me->SetReactState(REACT_PASSIVE); + DoAction(ACTION_CHANGE_PHASE); + break; + case PHASE_COMBAT_2: + if (HealthAbovePct(35)) return; + me->SetReactState(REACT_PASSIVE); + DoAction(ACTION_CHANGE_PHASE); + break; + default: + break; + } + } + void MovementInform(uint32 type, uint32 id) override + { + if (type != POINT_MOTION_TYPE) + return; + switch (id) + { + case POINT_FESTERGUT: + instance->SetBossState(DATA_FESTERGUT, IN_PROGRESS); // needed here for delayed gate close + me->SetSpeedRate(MOVE_RUN, _baseSpeed); + DoAction(ACTION_FESTERGUT_GAS); + if (Creature* festergut = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_FESTERGUT))) + festergut->CastSpell(festergut, SPELL_GASEOUS_BLIGHT_LARGE, CastSpellExtraArgs().SetOriginalCaster(festergut->GetGUID())); + break; + case POINT_ROTFACE: + instance->SetBossState(DATA_ROTFACE, IN_PROGRESS); // needed here for delayed gate close + me->SetSpeedRate(MOVE_RUN, _baseSpeed); + DoAction(ACTION_ROTFACE_OOZE); + events.ScheduleEvent(EVENT_ROTFACE_OOZE_FLOOD, 25s, 0, PHASE_ROTFACE); + break; + case POINT_TABLE: + // stop attack + me->GetMotionMaster()->MoveIdle(); + me->SetSpeedRate(MOVE_RUN, _baseSpeed); + if (GameObject* table = ObjectAccessor::GetGameObject(*me, instance->GetGuidData(DATA_PUTRICIDE_TABLE))) + me->SetFacingToObject(table); + // operating on new phase already switch (_phase) { - case PHASE_COMBAT_1: - if (HealthAbovePct(80)) - return; - me->SetReactState(REACT_PASSIVE); - DoAction(ACTION_CHANGE_PHASE); - break; case PHASE_COMBAT_2: - if (HealthAbovePct(35)) - return; - me->SetReactState(REACT_PASSIVE); - DoAction(ACTION_CHANGE_PHASE); + { + SpellInfo const* spell = sSpellMgr->GetSpellInfo(SPELL_CREATE_CONCOCTION, GetDifficulty()); + DoCast(me, SPELL_CREATE_CONCOCTION); + events.ScheduleEvent(EVENT_PHASE_TRANSITION, Milliseconds(spell->CalcCastTime()) + 100ms); break; + } + case PHASE_COMBAT_3: + { + SpellInfo const* spell = sSpellMgr->GetSpellInfo(SPELL_GUZZLE_POTIONS, GetDifficulty()); + DoCast(me, SPELL_GUZZLE_POTIONS); + events.ScheduleEvent(EVENT_PHASE_TRANSITION, Milliseconds(spell->CalcCastTime()) + 100ms); + break; + } default: break; } - } + break; + default: + break; + } + } - void MovementInform(uint32 type, uint32 id) override - { - if (type != POINT_MOTION_TYPE) - return; - switch (id) + void DoAction(int32 action) override + { + switch (action) + { + case ACTION_FESTERGUT_COMBAT: + SetPhase(PHASE_FESTERGUT); + me->SetSpeedRate(MOVE_RUN, _baseSpeed*2.0f); + me->GetMotionMaster()->MovePoint(POINT_FESTERGUT, festergutWatchPos); + me->SetReactState(REACT_PASSIVE); + EngagementStart(nullptr); + if (IsHeroic()) + events.ScheduleEvent(EVENT_FESTERGUT_GOO, 13s, 18s, 0, PHASE_FESTERGUT); + break; + case ACTION_FESTERGUT_GAS: + Talk(SAY_FESTERGUT_GASEOUS_BLIGHT); + DoCast(me, SPELL_RELEASE_GAS_VISUAL, true); + break; + case ACTION_FESTERGUT_DEATH: + events.ScheduleEvent(EVENT_FESTERGUT_DIES, 4s, 0, PHASE_FESTERGUT); + break; + case ACTION_ROTFACE_COMBAT: + SetPhase(PHASE_ROTFACE); + me->SetSpeedRate(MOVE_RUN, _baseSpeed*2.0f); + me->GetMotionMaster()->MovePoint(POINT_ROTFACE, rotfaceWatchPos); + me->SetReactState(REACT_PASSIVE); + EngagementStart(nullptr); + _oozeFloodStage = 0; + // init random sequence of floods + if (Creature* rotface = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_ROTFACE))) { - case POINT_FESTERGUT: - instance->SetBossState(DATA_FESTERGUT, IN_PROGRESS); // needed here for delayed gate close - me->SetSpeedRate(MOVE_RUN, _baseSpeed); - DoAction(ACTION_FESTERGUT_GAS); - if (Creature* festergut = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_FESTERGUT))) - festergut->CastSpell(festergut, SPELL_GASEOUS_BLIGHT_LARGE, CastSpellExtraArgs().SetOriginalCaster(festergut->GetGUID())); - break; - case POINT_ROTFACE: - instance->SetBossState(DATA_ROTFACE, IN_PROGRESS); // needed here for delayed gate close - me->SetSpeedRate(MOVE_RUN, _baseSpeed); - DoAction(ACTION_ROTFACE_OOZE); - events.ScheduleEvent(EVENT_ROTFACE_OOZE_FLOOD, 25s, 0, PHASE_ROTFACE); - break; - case POINT_TABLE: - // stop attack - me->GetMotionMaster()->MoveIdle(); - me->SetSpeedRate(MOVE_RUN, _baseSpeed); - if (GameObject* table = ObjectAccessor::GetGameObject(*me, instance->GetGuidData(DATA_PUTRICIDE_TABLE))) - me->SetFacingToObject(table); - // operating on new phase already - switch (_phase) + std::list<Creature*> list; + GetCreatureListWithEntryInGrid(list, rotface, NPC_PUDDLE_STALKER, 50.0f); + list.remove_if(RotfaceHeightCheck(rotface)); + if (list.size() > 4) + { + list.sort(Trinity::ObjectDistanceOrderPred(rotface)); + do { - case PHASE_COMBAT_2: - { - SpellInfo const* spell = sSpellMgr->GetSpellInfo(SPELL_CREATE_CONCOCTION, GetDifficulty()); - DoCast(me, SPELL_CREATE_CONCOCTION); - events.ScheduleEvent(EVENT_PHASE_TRANSITION, Milliseconds(spell->CalcCastTime()) + 100ms); - break; - } - case PHASE_COMBAT_3: - { - SpellInfo const* spell = sSpellMgr->GetSpellInfo(SPELL_GUZZLE_POTIONS, GetDifficulty()); - DoCast(me, SPELL_GUZZLE_POTIONS); - events.ScheduleEvent(EVENT_PHASE_TRANSITION, Milliseconds(spell->CalcCastTime()) + 100ms); - break; - } - default: - break; - } - break; - default: - break; - } - } + list.pop_back(); + } while (list.size() > 4); + } - void DoAction(int32 action) override - { - switch (action) + uint8 i = 0; + while (!list.empty()) + { + std::list<Creature*>::iterator itr = list.begin(); + std::advance(itr, urand(0, list.size()-1)); + _oozeFloodDummyGUIDs[i++] = (*itr)->GetGUID(); + list.erase(itr); + } + } + break; + case ACTION_ROTFACE_OOZE: + Talk(SAY_ROTFACE_OOZE_FLOOD); + if (Creature* dummy = ObjectAccessor::GetCreature(*me, _oozeFloodDummyGUIDs[_oozeFloodStage])) + dummy->CastSpell(dummy, oozeFloodSpells[_oozeFloodStage], CastSpellExtraArgs(TRIGGERED_FULL_MASK) + .SetOriginalCaster(me->GetGUID())); // cast from self for LoS (with prof's GUID for logs) + if (++_oozeFloodStage == 4) + _oozeFloodStage = 0; + break; + case ACTION_ROTFACE_DEATH: + events.ScheduleEvent(EVENT_ROTFACE_DIES, 4500ms, 0, PHASE_ROTFACE); + break; + case ACTION_CHANGE_PHASE: + me->SetSpeedRate(MOVE_RUN, _baseSpeed*2.0f); + events.DelayEvents(30s); + me->AttackStop(); + if (!IsHeroic()) { - case ACTION_FESTERGUT_COMBAT: - SetPhase(PHASE_FESTERGUT); - me->SetSpeedRate(MOVE_RUN, _baseSpeed*2.0f); - me->GetMotionMaster()->MovePoint(POINT_FESTERGUT, festergutWatchPos); - me->SetReactState(REACT_PASSIVE); - EngagementStart(nullptr); - if (IsHeroic()) - events.ScheduleEvent(EVENT_FESTERGUT_GOO, 13s, 18s, 0, PHASE_FESTERGUT); - break; - case ACTION_FESTERGUT_GAS: - Talk(SAY_FESTERGUT_GASEOUS_BLIGHT); - DoCast(me, SPELL_RELEASE_GAS_VISUAL, true); - break; - case ACTION_FESTERGUT_DEATH: - events.ScheduleEvent(EVENT_FESTERGUT_DIES, 4s, 0, PHASE_FESTERGUT); - break; - case ACTION_ROTFACE_COMBAT: - SetPhase(PHASE_ROTFACE); - me->SetSpeedRate(MOVE_RUN, _baseSpeed*2.0f); - me->GetMotionMaster()->MovePoint(POINT_ROTFACE, rotfaceWatchPos); - me->SetReactState(REACT_PASSIVE); - EngagementStart(nullptr); - _oozeFloodStage = 0; - // init random sequence of floods - if (Creature* rotface = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_ROTFACE))) - { - std::list<Creature*> list; - GetCreatureListWithEntryInGrid(list, rotface, NPC_PUDDLE_STALKER, 50.0f); - list.remove_if(RotfaceHeightCheck(rotface)); - if (list.size() > 4) - { - list.sort(Trinity::ObjectDistanceOrderPred(rotface)); - do - { - list.pop_back(); - } while (list.size() > 4); - } - - uint8 i = 0; - while (!list.empty()) - { - std::list<Creature*>::iterator itr = list.begin(); - std::advance(itr, urand(0, list.size()-1)); - _oozeFloodDummyGUIDs[i++] = (*itr)->GetGUID(); - list.erase(itr); - } - } - break; - case ACTION_ROTFACE_OOZE: - Talk(SAY_ROTFACE_OOZE_FLOOD); - if (Creature* dummy = ObjectAccessor::GetCreature(*me, _oozeFloodDummyGUIDs[_oozeFloodStage])) - dummy->CastSpell(dummy, oozeFloodSpells[_oozeFloodStage], CastSpellExtraArgs(TRIGGERED_FULL_MASK) - .SetOriginalCaster(me->GetGUID())); // cast from self for LoS (with prof's GUID for logs) - if (++_oozeFloodStage == 4) - _oozeFloodStage = 0; - break; - case ACTION_ROTFACE_DEATH: - events.ScheduleEvent(EVENT_ROTFACE_DIES, 4500ms, 0, PHASE_ROTFACE); - break; - case ACTION_CHANGE_PHASE: - me->SetSpeedRate(MOVE_RUN, _baseSpeed*2.0f); - events.DelayEvents(30s); - me->AttackStop(); - if (!IsHeroic()) - { - DoCast(me, SPELL_TEAR_GAS); - events.ScheduleEvent(EVENT_TEAR_GAS, 2500ms); - } - else + DoCast(me, SPELL_TEAR_GAS); + events.ScheduleEvent(EVENT_TEAR_GAS, 2500ms); + } + else + { + Talk(SAY_PHASE_TRANSITION_HEROIC); + DoCast(me, SPELL_UNSTABLE_EXPERIMENT, true); + DoCast(me, SPELL_UNSTABLE_EXPERIMENT, true); + // cast variables + if (Is25ManRaid()) + { + std::list<Unit*> targetList; { - Talk(SAY_PHASE_TRANSITION_HEROIC); - DoCast(me, SPELL_UNSTABLE_EXPERIMENT, true); - DoCast(me, SPELL_UNSTABLE_EXPERIMENT, true); - // cast variables - if (Is25ManRaid()) - { - std::list<Unit*> targetList; - { - for (ThreatReference const* ref : me->GetThreatManager().GetUnsortedThreatList()) - if (Player* target = ref->GetVictim()->ToPlayer()) - targetList.push_back(target); - } - - size_t half = targetList.size()/2; - // half gets ooze variable - while (half < targetList.size()) - { - std::list<Unit*>::iterator itr = targetList.begin(); - advance(itr, urand(0, targetList.size() - 1)); - (*itr)->CastSpell(*itr, SPELL_OOZE_VARIABLE, true); - targetList.erase(itr); - } - // and half gets gas - for (std::list<Unit*>::iterator itr = targetList.begin(); itr != targetList.end(); ++itr) - (*itr)->CastSpell(*itr, SPELL_GAS_VARIABLE, true); - } - me->GetMotionMaster()->MovePoint(POINT_TABLE, tablePos); + for (ThreatReference const* ref : me->GetThreatManager().GetUnsortedThreatList()) + if (Player* target = ref->GetVictim()->ToPlayer()) + targetList.push_back(target); } - switch (_phase) + + size_t half = targetList.size()/2; + // half gets ooze variable + while (half < targetList.size()) { - case PHASE_COMBAT_1: - SetPhase(PHASE_COMBAT_2); - events.ScheduleEvent(EVENT_MALLEABLE_GOO, 21s, 26s); - events.ScheduleEvent(EVENT_CHOKING_GAS_BOMB, 35s, 40s); - break; - case PHASE_COMBAT_2: - SetPhase(PHASE_COMBAT_3); - events.ScheduleEvent(EVENT_MUTATED_PLAGUE, 25s); - events.CancelEvent(EVENT_UNSTABLE_EXPERIMENT); - break; - default: - break; + std::list<Unit*>::iterator itr = targetList.begin(); + advance(itr, urand(0, targetList.size() - 1)); + (*itr)->CastSpell(*itr, SPELL_OOZE_VARIABLE, true); + targetList.erase(itr); } - break; - default: - break; + // and half gets gas + for (std::list<Unit*>::iterator itr = targetList.begin(); itr != targetList.end(); ++itr) + (*itr)->CastSpell(*itr, SPELL_GAS_VARIABLE, true); + } + me->GetMotionMaster()->MovePoint(POINT_TABLE, tablePos); } - } - - uint32 GetData(uint32 type) const override - { - switch (type) + switch (_phase) { - case DATA_EXPERIMENT_STAGE: - return _experimentState; - case DATA_PHASE: - return _phase; - case DATA_ABOMINATION: - return uint32(summons.HasEntry(NPC_MUTATED_ABOMINATION_10) || summons.HasEntry(NPC_MUTATED_ABOMINATION_25)); + case PHASE_COMBAT_1: + SetPhase(PHASE_COMBAT_2); + events.ScheduleEvent(EVENT_MALLEABLE_GOO, 21s, 26s); + events.ScheduleEvent(EVENT_CHOKING_GAS_BOMB, 35s, 40s); + break; + case PHASE_COMBAT_2: + SetPhase(PHASE_COMBAT_3); + events.ScheduleEvent(EVENT_MUTATED_PLAGUE, 25s); + events.CancelEvent(EVENT_UNSTABLE_EXPERIMENT); + break; default: break; } + break; + default: + break; + } + } - return 0; - } + uint32 GetData(uint32 type) const override + { + switch (type) + { + case DATA_EXPERIMENT_STAGE: + return _experimentState; + case DATA_PHASE: + return _phase; + case DATA_ABOMINATION: + return uint32(summons.HasEntry(NPC_MUTATED_ABOMINATION_10) || summons.HasEntry(NPC_MUTATED_ABOMINATION_25)); + default: + break; + } - void SetData(uint32 id, uint32 data) override - { - if (id == DATA_EXPERIMENT_STAGE) - _experimentState = data != 0; - } + return 0; + } - void UpdateAI(uint32 diff) override - { - if (!(events.IsInPhase(PHASE_ROTFACE) || events.IsInPhase(PHASE_FESTERGUT)) && !UpdateVictim()) - return; + void SetData(uint32 id, uint32 data) override + { + if (id == DATA_EXPERIMENT_STAGE) + _experimentState = data != 0; + } - events.Update(diff); + void UpdateAI(uint32 diff) override + { + if (!(events.IsInPhase(PHASE_ROTFACE) || events.IsInPhase(PHASE_FESTERGUT)) && !UpdateVictim()) + return; - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; + events.Update(diff); + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; - while (uint32 eventId = events.ExecuteEvent()) + while (uint32 eventId = events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_FESTERGUT_DIES: + Talk(SAY_FESTERGUT_DEATH); + EnterEvadeMode(); + break; + case EVENT_FESTERGUT_GOO: + DoCastAOE(SPELL_MALLEABLE_GOO_SUMMON, CastSpellExtraArgs(true).AddSpellMod(SPELLVALUE_MAX_TARGETS, 1)); + if (Is25ManRaid()) + events.ScheduleEvent(EVENT_FESTERGUT_GOO, 10s, 15s, 0, PHASE_FESTERGUT); + else + events.ScheduleEvent(EVENT_FESTERGUT_GOO, 30s, 35s, 0, PHASE_FESTERGUT); + break; + case EVENT_ROTFACE_DIES: + Talk(SAY_ROTFACE_DEATH); + EnterEvadeMode(); + break; + case EVENT_ROTFACE_OOZE_FLOOD: + DoAction(ACTION_ROTFACE_OOZE); + events.ScheduleEvent(EVENT_ROTFACE_OOZE_FLOOD, 25s, 0, PHASE_ROTFACE); + break; + case EVENT_BERSERK: + Talk(SAY_BERSERK); + DoCast(me, SPELL_BERSERK2); + break; + case EVENT_SLIME_PUDDLE: { - switch (eventId) + std::list<Unit*> targets; + SelectTargetList(targets, 2, SelectTargetMethod::Random, 0, 0.0f, true); + if (!targets.empty()) + for (std::list<Unit*>::iterator itr = targets.begin(); itr != targets.end(); ++itr) + DoCast(*itr, SPELL_SLIME_PUDDLE_TRIGGER); + events.ScheduleEvent(EVENT_SLIME_PUDDLE, 35s); + break; + } + case EVENT_UNSTABLE_EXPERIMENT: + Talk(EMOTE_UNSTABLE_EXPERIMENT); + DoCast(me, SPELL_UNSTABLE_EXPERIMENT); + events.ScheduleEvent(EVENT_UNSTABLE_EXPERIMENT, 35s, 40s); + break; + case EVENT_TEAR_GAS: + me->GetMotionMaster()->MovePoint(POINT_TABLE, tablePos); + DoCast(me, SPELL_TEAR_GAS_PERIODIC_TRIGGER, true); + break; + case EVENT_RESUME_ATTACK: + me->SetReactState(REACT_AGGRESSIVE); + AttackStart(me->GetVictim()); + // remove Tear Gas + me->RemoveAurasDueToSpell(SPELL_TEAR_GAS_PERIODIC_TRIGGER); + DoCastAOE(SPELL_TEAR_GAS_CANCEL); + instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_GAS_VARIABLE); + instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_OOZE_VARIABLE); + break; + case EVENT_MALLEABLE_GOO: + if (Is25ManRaid()) { - case EVENT_FESTERGUT_DIES: - Talk(SAY_FESTERGUT_DEATH); - EnterEvadeMode(); - break; - case EVENT_FESTERGUT_GOO: - DoCastAOE(SPELL_MALLEABLE_GOO_SUMMON, CastSpellExtraArgs(true).AddSpellMod(SPELLVALUE_MAX_TARGETS, 1)); - if (Is25ManRaid()) - events.ScheduleEvent(EVENT_FESTERGUT_GOO, 10s, 15s, 0, PHASE_FESTERGUT); - else - events.ScheduleEvent(EVENT_FESTERGUT_GOO, 30s, 35s, 0, PHASE_FESTERGUT); - break; - case EVENT_ROTFACE_DIES: - Talk(SAY_ROTFACE_DEATH); - EnterEvadeMode(); - break; - case EVENT_ROTFACE_OOZE_FLOOD: - DoAction(ACTION_ROTFACE_OOZE); - events.ScheduleEvent(EVENT_ROTFACE_OOZE_FLOOD, 25s, 0, PHASE_ROTFACE); - break; - case EVENT_BERSERK: - Talk(SAY_BERSERK); - DoCast(me, SPELL_BERSERK2); - break; - case EVENT_SLIME_PUDDLE: + std::list<Unit*> targets; + SelectTargetList(targets, 2, SelectTargetMethod::Random, 0, -7.0f, true); + if (!targets.empty()) { - std::list<Unit*> targets; - SelectTargetList(targets, 2, SelectTargetMethod::Random, 0, 0.0f, true); - if (!targets.empty()) - for (std::list<Unit*>::iterator itr = targets.begin(); itr != targets.end(); ++itr) - DoCast(*itr, SPELL_SLIME_PUDDLE_TRIGGER); - events.ScheduleEvent(EVENT_SLIME_PUDDLE, 35s); - break; + Talk(EMOTE_MALLEABLE_GOO); + for (std::list<Unit*>::iterator itr = targets.begin(); itr != targets.end(); ++itr) + DoCast(*itr, SPELL_MALLEABLE_GOO); } - case EVENT_UNSTABLE_EXPERIMENT: - Talk(EMOTE_UNSTABLE_EXPERIMENT); - DoCast(me, SPELL_UNSTABLE_EXPERIMENT); - events.ScheduleEvent(EVENT_UNSTABLE_EXPERIMENT, 35s, 40s); - break; - case EVENT_TEAR_GAS: - me->GetMotionMaster()->MovePoint(POINT_TABLE, tablePos); - DoCast(me, SPELL_TEAR_GAS_PERIODIC_TRIGGER, true); - break; - case EVENT_RESUME_ATTACK: - me->SetReactState(REACT_AGGRESSIVE); - AttackStart(me->GetVictim()); - // remove Tear Gas - me->RemoveAurasDueToSpell(SPELL_TEAR_GAS_PERIODIC_TRIGGER); - DoCastAOE(SPELL_TEAR_GAS_CANCEL); - instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_GAS_VARIABLE); - instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_OOZE_VARIABLE); - break; - case EVENT_MALLEABLE_GOO: - if (Is25ManRaid()) - { - std::list<Unit*> targets; - SelectTargetList(targets, 2, SelectTargetMethod::Random, 0, -7.0f, true); - if (!targets.empty()) - { - Talk(EMOTE_MALLEABLE_GOO); - for (std::list<Unit*>::iterator itr = targets.begin(); itr != targets.end(); ++itr) - DoCast(*itr, SPELL_MALLEABLE_GOO); - } - } - else - { - if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1, -7.0f, true)) - { - Talk(EMOTE_MALLEABLE_GOO); - DoCast(target, SPELL_MALLEABLE_GOO); - } - } - events.ScheduleEvent(EVENT_MALLEABLE_GOO, 25s, 30s); - break; - case EVENT_CHOKING_GAS_BOMB: - Talk(EMOTE_CHOKING_GAS_BOMB); - DoCast(me, SPELL_CHOKING_GAS_BOMB); - events.ScheduleEvent(EVENT_CHOKING_GAS_BOMB, 35s, 40s); - break; - case EVENT_UNBOUND_PLAGUE: - if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, NonTankTargetSelector(me))) - { - DoCast(target, SPELL_UNBOUND_PLAGUE); - DoCast(target, SPELL_UNBOUND_PLAGUE_SEARCHER); - } - events.ScheduleEvent(EVENT_UNBOUND_PLAGUE, 90s); - break; - case EVENT_MUTATED_PLAGUE: - DoCastVictim(SPELL_MUTATED_PLAGUE); - events.ScheduleEvent(EVENT_MUTATED_PLAGUE, 10s); - break; - case EVENT_PHASE_TRANSITION: + } + else + { + if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1, -7.0f, true)) { - switch (_phase) - { - case PHASE_COMBAT_2: - if (Creature* face = me->FindNearestCreature(NPC_TEAR_GAS_TARGET_STALKER, 50.0f)) - me->SetFacingToObject(face); - me->HandleEmoteCommand(EMOTE_ONESHOT_KNEEL); - Talk(SAY_TRANSFORM_1); - events.ScheduleEvent(EVENT_RESUME_ATTACK, 5500ms, 0, PHASE_COMBAT_2); - break; - case PHASE_COMBAT_3: - if (Creature* face = me->FindNearestCreature(NPC_TEAR_GAS_TARGET_STALKER, 50.0f)) - me->SetFacingToObject(face); - me->HandleEmoteCommand(EMOTE_ONESHOT_KNEEL); - Talk(SAY_TRANSFORM_2); - summons.DespawnIf(AbominationDespawner(me)); - events.ScheduleEvent(EVENT_RESUME_ATTACK, 8500ms, 0, PHASE_COMBAT_3); - break; - default: - break; - } - break; + Talk(EMOTE_MALLEABLE_GOO); + DoCast(target, SPELL_MALLEABLE_GOO); } + } + events.ScheduleEvent(EVENT_MALLEABLE_GOO, 25s, 30s); + break; + case EVENT_CHOKING_GAS_BOMB: + Talk(EMOTE_CHOKING_GAS_BOMB); + DoCast(me, SPELL_CHOKING_GAS_BOMB); + events.ScheduleEvent(EVENT_CHOKING_GAS_BOMB, 35s, 40s); + break; + case EVENT_UNBOUND_PLAGUE: + if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, NonTankTargetSelector(me))) + { + DoCast(target, SPELL_UNBOUND_PLAGUE); + DoCast(target, SPELL_UNBOUND_PLAGUE_SEARCHER); + } + events.ScheduleEvent(EVENT_UNBOUND_PLAGUE, 90s); + break; + case EVENT_MUTATED_PLAGUE: + DoCastVictim(SPELL_MUTATED_PLAGUE); + events.ScheduleEvent(EVENT_MUTATED_PLAGUE, 10s); + break; + case EVENT_PHASE_TRANSITION: + { + switch (_phase) + { + case PHASE_COMBAT_2: + if (Creature* face = me->FindNearestCreature(NPC_TEAR_GAS_TARGET_STALKER, 50.0f)) + me->SetFacingToObject(face); + me->HandleEmoteCommand(EMOTE_ONESHOT_KNEEL); + Talk(SAY_TRANSFORM_1); + events.ScheduleEvent(EVENT_RESUME_ATTACK, 5500ms, 0, PHASE_COMBAT_2); + break; + case PHASE_COMBAT_3: + if (Creature* face = me->FindNearestCreature(NPC_TEAR_GAS_TARGET_STALKER, 50.0f)) + me->SetFacingToObject(face); + me->HandleEmoteCommand(EMOTE_ONESHOT_KNEEL); + Talk(SAY_TRANSFORM_2); + summons.DespawnIf(AbominationDespawner(me)); + events.ScheduleEvent(EVENT_RESUME_ATTACK, 8500ms, 0, PHASE_COMBAT_3); + break; default: break; } - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; + break; } - - DoMeleeAttackIfReady(); + default: + break; } - private: - void SetPhase(Phases newPhase) - { - _phase = newPhase; - events.SetPhase(newPhase); - } + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + } - ObjectGuid _oozeFloodDummyGUIDs[4]; - Phases _phase; // external of EventMap because event phase gets reset on evade - float const _baseSpeed; - uint8 _oozeFloodStage; - bool _experimentState; - }; + DoMeleeAttackIfReady(); + } - CreatureAI* GetAI(Creature* creature) const override - { - return GetIcecrownCitadelAI<boss_professor_putricideAI>(creature); - } +private: + void SetPhase(Phases newPhase) + { + _phase = newPhase; + events.SetPhase(newPhase); + } + + ObjectGuid _oozeFloodDummyGUIDs[4]; + Phases _phase; // external of EventMap because event phase gets reset on evade + float const _baseSpeed; + uint8 _oozeFloodStage; + bool _experimentState; }; class npc_putricide_oozeAI : public ScriptedAI @@ -789,176 +778,132 @@ class npc_putricide_oozeAI : public ScriptedAI InstanceScript* _instance; }; -class npc_volatile_ooze : public CreatureScript +struct npc_volatile_ooze : public npc_putricide_oozeAI { - public: - npc_volatile_ooze() : CreatureScript("npc_volatile_ooze") { } + npc_volatile_ooze(Creature* creature) : npc_putricide_oozeAI(creature, SPELL_OOZE_ERUPTION_SEARCH_PERIODIC, SPELL_OOZE_ERUPTION) { } - struct npc_volatile_oozeAI : public npc_putricide_oozeAI - { - npc_volatile_oozeAI(Creature* creature) : npc_putricide_oozeAI(creature, SPELL_OOZE_ERUPTION_SEARCH_PERIODIC, SPELL_OOZE_ERUPTION) { } - - void CastMainSpell() override - { - me->CastSpell(me, SPELL_VOLATILE_OOZE_ADHESIVE, false); - } - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return GetIcecrownCitadelAI<npc_volatile_oozeAI>(creature); - } + void CastMainSpell() override + { + me->CastSpell(me, SPELL_VOLATILE_OOZE_ADHESIVE, false); + } }; -class npc_gas_cloud : public CreatureScript +struct npc_gas_cloud : public npc_putricide_oozeAI { - public: - npc_gas_cloud() : CreatureScript("npc_gas_cloud") { } - - struct npc_gas_cloudAI : public npc_putricide_oozeAI - { - npc_gas_cloudAI(Creature* creature) : npc_putricide_oozeAI(creature, SPELL_GASEOUS_BLOAT_PROC, SPELL_EXPUNGED_GAS) - { - _newTargetSelectTimer = 0; - } - - void CastMainSpell() override - { - CastSpellExtraArgs args; - args.AddSpellMod(SPELLVALUE_AURA_STACK, 10); - me->CastSpell(me, SPELL_GASEOUS_BLOAT, args); - } + npc_gas_cloud(Creature* creature) : npc_putricide_oozeAI(creature, SPELL_GASEOUS_BLOAT_PROC, SPELL_EXPUNGED_GAS) + { + _newTargetSelectTimer = 0; + } - private: - uint32 _newTargetSelectTimer; - }; + void CastMainSpell() override + { + CastSpellExtraArgs args; + args.AddSpellMod(SPELLVALUE_AURA_STACK, 10); + me->CastSpell(me, SPELL_GASEOUS_BLOAT, args); + } - CreatureAI* GetAI(Creature* creature) const override - { - return GetIcecrownCitadelAI<npc_gas_cloudAI>(creature); - } +private: + uint32 _newTargetSelectTimer; }; -class spell_putricide_gaseous_bloat : public SpellScriptLoader +class spell_putricide_gaseous_bloat : public AuraScript { - public: - spell_putricide_gaseous_bloat() : SpellScriptLoader("spell_putricide_gaseous_bloat") { } + PrepareAuraScript(spell_putricide_gaseous_bloat); - class spell_putricide_gaseous_bloat_AuraScript : public AuraScript + void HandleExtraEffect(AuraEffect const* /*aurEff*/) + { + Unit* target = GetTarget(); + if (Unit* caster = GetCaster()) { - PrepareAuraScript(spell_putricide_gaseous_bloat_AuraScript); - - void HandleExtraEffect(AuraEffect const* /*aurEff*/) + target->RemoveAuraFromStack(GetSpellInfo()->Id, GetCasterGUID()); + if (!target->HasAura(GetId())) { - Unit* target = GetTarget(); - if (Unit* caster = GetCaster()) - { - target->RemoveAuraFromStack(GetSpellInfo()->Id, GetCasterGUID()); - if (!target->HasAura(GetId())) - { - CastSpellExtraArgs args; - args.AddSpellMod(SPELLVALUE_AURA_STACK, 10); - caster->CastSpell(caster, SPELL_GASEOUS_BLOAT, args); - } - } + CastSpellExtraArgs args; + args.AddSpellMod(SPELLVALUE_AURA_STACK, 10); + caster->CastSpell(caster, SPELL_GASEOUS_BLOAT, args); } + } + } - void HandleProc(ProcEventInfo& eventInfo) - { - uint32 stack = GetStackAmount(); - Unit* caster = eventInfo.GetActor(); - - int32 const mod = caster->GetMap()->Is25ManRaid() ? 1500 : 1250; - int32 dmg = 0; - for (uint8 i = 1; i <= stack; ++i) - dmg += mod * i; + void HandleProc(ProcEventInfo& eventInfo) + { + uint32 stack = GetStackAmount(); + Unit* caster = eventInfo.GetActor(); - CastSpellExtraArgs args; - args.AddSpellBP0(dmg); - caster->CastSpell(nullptr, SPELL_EXPUNGED_GAS, args); - } + int32 const mod = caster->GetMap()->Is25ManRaid() ? 1500 : 1250; + int32 dmg = 0; + for (uint8 i = 1; i <= stack; ++i) + dmg += mod * i; - void Register() override - { - OnEffectPeriodic += AuraEffectPeriodicFn(spell_putricide_gaseous_bloat_AuraScript::HandleExtraEffect, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE); - OnProc += AuraProcFn(spell_putricide_gaseous_bloat_AuraScript::HandleProc); - } - }; + CastSpellExtraArgs args; + args.AddSpellBP0(dmg); + caster->CastSpell(nullptr, SPELL_EXPUNGED_GAS, args); + } - AuraScript* GetAuraScript() const override - { - return new spell_putricide_gaseous_bloat_AuraScript(); - } + void Register() override + { + OnEffectPeriodic += AuraEffectPeriodicFn(spell_putricide_gaseous_bloat::HandleExtraEffect, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE); + OnProc += AuraProcFn(spell_putricide_gaseous_bloat::HandleProc); + } }; -class spell_putricide_ooze_channel : public SpellScriptLoader +class spell_putricide_ooze_channel : public SpellScript { - public: - spell_putricide_ooze_channel() : SpellScriptLoader("spell_putricide_ooze_channel") { } - - class spell_putricide_ooze_channel_SpellScript : public SpellScript - { - PrepareSpellScript(spell_putricide_ooze_channel_SpellScript); + PrepareSpellScript(spell_putricide_ooze_channel); - bool Validate(SpellInfo const* spell) override - { - return ValidateSpellInfo({ spell->ExcludeTargetAuraSpell }); - } - - // set up initial variables and check if caster is creature - // this will let use safely use ToCreature() casts in entire script - bool Load() override - { - return GetCaster()->GetTypeId() == TYPEID_UNIT; - } + bool Validate(SpellInfo const* spell) override + { + return ValidateSpellInfo({ spell->ExcludeTargetAuraSpell }); + } - void SelectTarget(std::list<WorldObject*>& targets) - { - if (targets.empty()) - { - FinishCast(SPELL_FAILED_NO_VALID_TARGETS); - GetCaster()->ToCreature()->DespawnOrUnsummon(1ms); // despawn next update - return; - } + // set up initial variables and check if caster is creature + // this will let use safely use ToCreature() casts in entire script + bool Load() override + { + return GetCaster()->GetTypeId() == TYPEID_UNIT; + } - WorldObject* target = Trinity::Containers::SelectRandomContainerElement(targets); - targets.clear(); - targets.push_back(target); - _target = target; - } + void SelectTarget(std::list<WorldObject*>& targets) + { + if (targets.empty()) + { + FinishCast(SPELL_FAILED_NO_VALID_TARGETS); + GetCaster()->ToCreature()->DespawnOrUnsummon(1ms); // despawn next update + return; + } - void SetTarget(std::list<WorldObject*>& targets) - { - targets.clear(); - if (_target) - targets.push_back(_target); - } + WorldObject* target = Trinity::Containers::SelectRandomContainerElement(targets); + targets.clear(); + targets.push_back(target); + _target = target; + } - void StartAttack() - { - GetCaster()->ClearUnitState(UNIT_STATE_CASTING); - GetCaster()->GetThreatManager().ResetAllThreat(); - GetCaster()->ToCreature()->AI()->AttackStart(GetHitUnit()); - GetCaster()->GetThreatManager().AddThreat(GetHitUnit(), 500000000.0f, nullptr, true, true); // value seen in sniff - GetCaster()->GetThreatManager().FixateTarget(GetHitUnit()); - GetCaster()->ToCreature()->SetReactState(REACT_AGGRESSIVE); - } + void SetTarget(std::list<WorldObject*>& targets) + { + targets.clear(); + if (_target) + targets.push_back(_target); + } - void Register() override - { - OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_putricide_ooze_channel_SpellScript::SelectTarget, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); - OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_putricide_ooze_channel_SpellScript::SetTarget, EFFECT_1, TARGET_UNIT_SRC_AREA_ENEMY); - OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_putricide_ooze_channel_SpellScript::SetTarget, EFFECT_2, TARGET_UNIT_SRC_AREA_ENEMY); - AfterHit += SpellHitFn(spell_putricide_ooze_channel_SpellScript::StartAttack); - } + void StartAttack() + { + GetCaster()->ClearUnitState(UNIT_STATE_CASTING); + GetCaster()->GetThreatManager().ResetAllThreat(); + GetCaster()->ToCreature()->AI()->AttackStart(GetHitUnit()); + GetCaster()->GetThreatManager().AddThreat(GetHitUnit(), 500000000.0f, nullptr, true, true); // value seen in sniff + GetCaster()->GetThreatManager().FixateTarget(GetHitUnit()); + GetCaster()->ToCreature()->SetReactState(REACT_AGGRESSIVE); + } - WorldObject* _target = nullptr; - }; + void Register() override + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_putricide_ooze_channel::SelectTarget, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_putricide_ooze_channel::SetTarget, EFFECT_1, TARGET_UNIT_SRC_AREA_ENEMY); + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_putricide_ooze_channel::SetTarget, EFFECT_2, TARGET_UNIT_SRC_AREA_ENEMY); + AfterHit += SpellHitFn(spell_putricide_ooze_channel::StartAttack); + } - SpellScript* GetSpellScript() const override - { - return new spell_putricide_ooze_channel_SpellScript(); - } + WorldObject* _target = nullptr; }; class ExactDistanceCheck @@ -976,692 +921,511 @@ class ExactDistanceCheck float _dist; }; -class spell_putricide_slime_puddle : public SpellScriptLoader +class spell_putricide_slime_puddle : public SpellScript { - public: - spell_putricide_slime_puddle() : SpellScriptLoader("spell_putricide_slime_puddle") { } - - class spell_putricide_slime_puddle_SpellScript : public SpellScript - { - PrepareSpellScript(spell_putricide_slime_puddle_SpellScript); + PrepareSpellScript(spell_putricide_slime_puddle); - void ScaleRange(std::list<WorldObject*>& targets) - { - targets.remove_if(ExactDistanceCheck(GetCaster(), 2.5f * GetCaster()->GetObjectScale())); - } - - void Register() override - { - OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_putricide_slime_puddle_SpellScript::ScaleRange, EFFECT_0, TARGET_UNIT_DEST_AREA_ENEMY); - OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_putricide_slime_puddle_SpellScript::ScaleRange, EFFECT_1, TARGET_UNIT_DEST_AREA_ENTRY); - } - }; + void ScaleRange(std::list<WorldObject*>& targets) + { + targets.remove_if(ExactDistanceCheck(GetCaster(), 2.5f * GetCaster()->GetObjectScale())); + } - SpellScript* GetSpellScript() const override - { - return new spell_putricide_slime_puddle_SpellScript(); - } + void Register() override + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_putricide_slime_puddle::ScaleRange, EFFECT_0, TARGET_UNIT_DEST_AREA_ENEMY); + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_putricide_slime_puddle::ScaleRange, EFFECT_1, TARGET_UNIT_DEST_AREA_ENTRY); + } }; // this is here only because on retail you dont actually enter HEROIC mode for ICC -class spell_putricide_slime_puddle_aura : public SpellScriptLoader +class spell_putricide_slime_puddle_aura : public SpellScript { - public: - spell_putricide_slime_puddle_aura() : SpellScriptLoader("spell_putricide_slime_puddle_aura") { } + PrepareSpellScript(spell_putricide_slime_puddle_aura); - class spell_putricide_slime_puddle_aura_SpellScript : public SpellScript - { - PrepareSpellScript(spell_putricide_slime_puddle_aura_SpellScript); - - void ReplaceAura() - { - if (Unit* target = GetHitUnit()) - GetCaster()->AddAura(GetCaster()->GetMap()->Is25ManRaid() ? 72456 : 70346, target); - } - - void Register() override - { - OnHit += SpellHitFn(spell_putricide_slime_puddle_aura_SpellScript::ReplaceAura); - } - }; + void ReplaceAura() + { + if (Unit* target = GetHitUnit()) + GetCaster()->AddAura(GetCaster()->GetMap()->Is25ManRaid() ? 72456 : 70346, target); + } - SpellScript* GetSpellScript() const override - { - return new spell_putricide_slime_puddle_aura_SpellScript(); - } + void Register() override + { + OnHit += SpellHitFn(spell_putricide_slime_puddle_aura::ReplaceAura); + } }; -class spell_putricide_unstable_experiment : public SpellScriptLoader +class spell_putricide_unstable_experiment : public SpellScript { - public: - spell_putricide_unstable_experiment() : SpellScriptLoader("spell_putricide_unstable_experiment") { } + PrepareSpellScript(spell_putricide_unstable_experiment); - class spell_putricide_unstable_experiment_SpellScript : public SpellScript - { - PrepareSpellScript(spell_putricide_unstable_experiment_SpellScript); - - void HandleScript(SpellEffIndex effIndex) - { - PreventHitDefaultEffect(effIndex); - if (GetCaster()->GetTypeId() != TYPEID_UNIT) - return; - - Creature* creature = GetCaster()->ToCreature(); - - uint32 stage = creature->AI()->GetData(DATA_EXPERIMENT_STAGE); - creature->AI()->SetData(DATA_EXPERIMENT_STAGE, stage ^ true); - - Creature* target = nullptr; - std::list<Creature*> creList; - GetCreatureListWithEntryInGrid(creList, GetCaster(), NPC_ABOMINATION_WING_MAD_SCIENTIST_STALKER, 200.0f); - // 2 of them are spawned at green place - weird trick blizz - for (std::list<Creature*>::iterator itr = creList.begin(); itr != creList.end(); ++itr) - { - target = *itr; - std::list<Creature*> tmp; - GetCreatureListWithEntryInGrid(tmp, target, NPC_ABOMINATION_WING_MAD_SCIENTIST_STALKER, 10.0f); - if ((!stage && tmp.size() > 1) || (stage && tmp.size() == 1)) - break; - } + void HandleScript(SpellEffIndex effIndex) + { + PreventHitDefaultEffect(effIndex); + if (GetCaster()->GetTypeId() != TYPEID_UNIT) + return; - GetCaster()->CastSpell(target, uint32(GetEffectInfo(SpellEffIndex(stage)).CalcValue()), true); - } + Creature* creature = GetCaster()->ToCreature(); - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_putricide_unstable_experiment_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); - } - }; + uint32 stage = creature->AI()->GetData(DATA_EXPERIMENT_STAGE); + creature->AI()->SetData(DATA_EXPERIMENT_STAGE, stage ^ true); - SpellScript* GetSpellScript() const override + Creature* target = nullptr; + std::list<Creature*> creList; + GetCreatureListWithEntryInGrid(creList, GetCaster(), NPC_ABOMINATION_WING_MAD_SCIENTIST_STALKER, 200.0f); + // 2 of them are spawned at green place - weird trick blizz + for (std::list<Creature*>::iterator itr = creList.begin(); itr != creList.end(); ++itr) { - return new spell_putricide_unstable_experiment_SpellScript(); + target = *itr; + std::list<Creature*> tmp; + GetCreatureListWithEntryInGrid(tmp, target, NPC_ABOMINATION_WING_MAD_SCIENTIST_STALKER, 10.0f); + if ((!stage && tmp.size() > 1) || (stage && tmp.size() == 1)) + break; } -}; -class spell_putricide_ooze_eruption_searcher : public SpellScriptLoader -{ - public: - spell_putricide_ooze_eruption_searcher() : SpellScriptLoader("spell_putricide_ooze_eruption_searcher") { } - - class spell_putricide_ooze_eruption_searcher_SpellScript : public SpellScript - { - PrepareSpellScript(spell_putricide_ooze_eruption_searcher_SpellScript); + GetCaster()->CastSpell(target, uint32(GetEffectInfo(SpellEffIndex(stage)).CalcValue()), true); + } - void HandleDummy(SpellEffIndex /*effIndex*/) - { - if (GetHitUnit()->HasAura(SPELL_VOLATILE_OOZE_ADHESIVE)) - { - GetHitUnit()->RemoveAurasDueToSpell(SPELL_VOLATILE_OOZE_ADHESIVE, GetCaster()->GetGUID(), 0, AURA_REMOVE_BY_ENEMY_SPELL); - GetCaster()->CastSpell(GetHitUnit(), SPELL_OOZE_ERUPTION, true); - } - } + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_putricide_unstable_experiment::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } +}; - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_putricide_ooze_eruption_searcher_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); - } - }; +class spell_putricide_ooze_eruption_searcher : public SpellScript +{ + PrepareSpellScript(spell_putricide_ooze_eruption_searcher); - SpellScript* GetSpellScript() const override + void HandleDummy(SpellEffIndex /*effIndex*/) + { + if (GetHitUnit()->HasAura(SPELL_VOLATILE_OOZE_ADHESIVE)) { - return new spell_putricide_ooze_eruption_searcher_SpellScript(); + GetHitUnit()->RemoveAurasDueToSpell(SPELL_VOLATILE_OOZE_ADHESIVE, GetCaster()->GetGUID(), 0, AURA_REMOVE_BY_ENEMY_SPELL); + GetCaster()->CastSpell(GetHitUnit(), SPELL_OOZE_ERUPTION, true); } + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_putricide_ooze_eruption_searcher::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } }; // 71770 - Ooze Spell Tank Protection -class spell_putricide_ooze_tank_protection : public SpellScriptLoader +class spell_putricide_ooze_tank_protection : public AuraScript { - public: - spell_putricide_ooze_tank_protection() : SpellScriptLoader("spell_putricide_ooze_tank_protection") { } - - class spell_putricide_ooze_tank_protection_AuraScript : public AuraScript - { - PrepareAuraScript(spell_putricide_ooze_tank_protection_AuraScript); - - bool Validate(SpellInfo const* spellInfo) override - { - return spellInfo->GetEffects().size() > EFFECT_1 - && ValidateSpellInfo({ spellInfo->GetEffect(EFFECT_0).TriggerSpell, spellInfo->GetEffect(EFFECT_1).TriggerSpell }); - } + PrepareAuraScript(spell_putricide_ooze_tank_protection); - void HandleProc(AuraEffect* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); + bool Validate(SpellInfo const* spellInfo) override + { + return spellInfo->GetEffects().size() > EFFECT_1 + && ValidateSpellInfo({ spellInfo->GetEffect(EFFECT_0).TriggerSpell, spellInfo->GetEffect(EFFECT_1).TriggerSpell }); + } - Unit* actionTarget = eventInfo.GetActionTarget(); - actionTarget->CastSpell(nullptr, aurEff->GetSpellEffectInfo().TriggerSpell, aurEff); - } + void HandleProc(AuraEffect* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_putricide_ooze_tank_protection_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); - OnEffectProc += AuraEffectProcFn(spell_putricide_ooze_tank_protection_AuraScript::HandleProc, EFFECT_1, SPELL_AURA_PROC_TRIGGER_SPELL); - } - }; + Unit* actionTarget = eventInfo.GetActionTarget(); + actionTarget->CastSpell(nullptr, aurEff->GetSpellEffectInfo().TriggerSpell, aurEff); + } - AuraScript* GetAuraScript() const override - { - return new spell_putricide_ooze_tank_protection_AuraScript(); - } + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_putricide_ooze_tank_protection::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); + OnEffectProc += AuraEffectProcFn(spell_putricide_ooze_tank_protection::HandleProc, EFFECT_1, SPELL_AURA_PROC_TRIGGER_SPELL); + } }; -class spell_putricide_choking_gas_bomb : public SpellScriptLoader +class spell_putricide_choking_gas_bomb : public SpellScript { - public: - spell_putricide_choking_gas_bomb() : SpellScriptLoader("spell_putricide_choking_gas_bomb") { } + PrepareSpellScript(spell_putricide_choking_gas_bomb); - class spell_putricide_choking_gas_bomb_SpellScript : public SpellScript + void HandleScript(SpellEffIndex /*effIndex*/) + { + uint32 skipIndex = urand(0, 2); + for (SpellEffectInfo const& spellEffectInfo : GetSpellInfo()->GetEffects()) { - PrepareSpellScript(spell_putricide_choking_gas_bomb_SpellScript); - - void HandleScript(SpellEffIndex /*effIndex*/) - { - uint32 skipIndex = urand(0, 2); - for (SpellEffectInfo const& spellEffectInfo : GetSpellInfo()->GetEffects()) - { - if (spellEffectInfo.EffectIndex == skipIndex) - continue; + if (spellEffectInfo.EffectIndex == skipIndex) + continue; - uint32 spellId = uint32(spellEffectInfo.CalcValue()); - GetCaster()->CastSpell(GetCaster(), spellId, CastSpellExtraArgs(TRIGGERED_FULL_MASK) - .SetOriginalCaster(GetCaster()->GetGUID())); - } - } - - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_putricide_choking_gas_bomb_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); - } - }; - - SpellScript* GetSpellScript() const override - { - return new spell_putricide_choking_gas_bomb_SpellScript(); + uint32 spellId = uint32(spellEffectInfo.CalcValue()); + GetCaster()->CastSpell(GetCaster(), spellId, CastSpellExtraArgs(TRIGGERED_FULL_MASK) + .SetOriginalCaster(GetCaster()->GetGUID())); } + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_putricide_choking_gas_bomb::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } }; -class spell_putricide_unbound_plague : public SpellScriptLoader +class spell_putricide_unbound_plague : public SpellScript { - public: - spell_putricide_unbound_plague() : SpellScriptLoader("spell_putricide_unbound_plague") { } - - class spell_putricide_unbound_plague_SpellScript : public SpellScript - { - PrepareSpellScript(spell_putricide_unbound_plague_SpellScript); - - bool Validate(SpellInfo const* /*spell*/) override - { - return ValidateSpellInfo({ SPELL_UNBOUND_PLAGUE, SPELL_UNBOUND_PLAGUE_SEARCHER }); - } - - void FilterTargets(std::list<WorldObject*>& targets) - { - if (AuraEffect const* eff = GetCaster()->GetAuraEffect(SPELL_UNBOUND_PLAGUE_SEARCHER, EFFECT_0)) - { - if (eff->GetTickNumber() < 2) - { - targets.clear(); - return; - } - } - - targets.remove_if(Trinity::UnitAuraCheck(true, SPELL_UNBOUND_PLAGUE)); - Trinity::Containers::RandomResize(targets, 1); - } - - void HandleScript(SpellEffIndex /*effIndex*/) - { - if (!GetHitUnit()) - return; + PrepareSpellScript(spell_putricide_unbound_plague); - InstanceScript* instance = GetCaster()->GetInstanceScript(); - if (!instance) - return; - - if (!GetHitUnit()->HasAura(SPELL_UNBOUND_PLAGUE)) - { - if (Creature* professor = ObjectAccessor::GetCreature(*GetCaster(), instance->GetGuidData(DATA_PROFESSOR_PUTRICIDE))) - { - if (Aura* oldPlague = GetCaster()->GetAura(SPELL_UNBOUND_PLAGUE, professor->GetGUID())) - { - if (Aura* newPlague = professor->AddAura(SPELL_UNBOUND_PLAGUE, GetHitUnit())) - { - newPlague->SetMaxDuration(oldPlague->GetMaxDuration()); - newPlague->SetDuration(oldPlague->GetDuration()); - oldPlague->Remove(); - GetCaster()->RemoveAurasDueToSpell(SPELL_UNBOUND_PLAGUE_SEARCHER); - GetCaster()->CastSpell(GetCaster(), SPELL_PLAGUE_SICKNESS, true); - GetCaster()->CastSpell(GetCaster(), SPELL_UNBOUND_PLAGUE_PROTECTION, true); - professor->CastSpell(GetHitUnit(), SPELL_UNBOUND_PLAGUE_SEARCHER, true); - } - } - } - } - } + bool Validate(SpellInfo const* /*spell*/) override + { + return ValidateSpellInfo({ SPELL_UNBOUND_PLAGUE, SPELL_UNBOUND_PLAGUE_SEARCHER }); + } - void Register() override + void FilterTargets(std::list<WorldObject*>& targets) + { + if (AuraEffect const* eff = GetCaster()->GetAuraEffect(SPELL_UNBOUND_PLAGUE_SEARCHER, EFFECT_0)) + { + if (eff->GetTickNumber() < 2) { - OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_putricide_unbound_plague_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ALLY); - OnEffectHitTarget += SpellEffectFn(spell_putricide_unbound_plague_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + targets.clear(); + return; } - }; - - SpellScript* GetSpellScript() const override - { - return new spell_putricide_unbound_plague_SpellScript(); } -}; -class spell_putricide_eat_ooze : public SpellScriptLoader -{ - public: - spell_putricide_eat_ooze() : SpellScriptLoader("spell_putricide_eat_ooze") { } - - class spell_putricide_eat_ooze_SpellScript : public SpellScript - { - PrepareSpellScript(spell_putricide_eat_ooze_SpellScript); + targets.remove_if(Trinity::UnitAuraCheck(true, SPELL_UNBOUND_PLAGUE)); + Trinity::Containers::RandomResize(targets, 1); + } - void SelectTarget(std::list<WorldObject*>& targets) - { - if (targets.empty()) - return; + void HandleScript(SpellEffIndex /*effIndex*/) + { + if (!GetHitUnit()) + return; - targets.sort(Trinity::ObjectDistanceOrderPred(GetCaster())); - WorldObject* target = targets.front(); - targets.clear(); - targets.push_back(target); - } + InstanceScript* instance = GetCaster()->GetInstanceScript(); + if (!instance) + return; - void HandleScript(SpellEffIndex /*effIndex*/) + if (!GetHitUnit()->HasAura(SPELL_UNBOUND_PLAGUE)) + { + if (Creature* professor = ObjectAccessor::GetCreature(*GetCaster(), instance->GetGuidData(DATA_PROFESSOR_PUTRICIDE))) { - Creature* target = GetHitCreature(); - if (!target) - return; - - if (Aura* grow = target->GetAura(uint32(GetEffectValue()))) + if (Aura* oldPlague = GetCaster()->GetAura(SPELL_UNBOUND_PLAGUE, professor->GetGUID())) { - if (grow->GetStackAmount() < 3) + if (Aura* newPlague = professor->AddAura(SPELL_UNBOUND_PLAGUE, GetHitUnit())) { - target->RemoveAurasDueToSpell(SPELL_GROW_STACKER); - target->RemoveAura(grow); - target->DespawnOrUnsummon(1ms); + newPlague->SetMaxDuration(oldPlague->GetMaxDuration()); + newPlague->SetDuration(oldPlague->GetDuration()); + oldPlague->Remove(); + GetCaster()->RemoveAurasDueToSpell(SPELL_UNBOUND_PLAGUE_SEARCHER); + GetCaster()->CastSpell(GetCaster(), SPELL_PLAGUE_SICKNESS, true); + GetCaster()->CastSpell(GetCaster(), SPELL_UNBOUND_PLAGUE_PROTECTION, true); + professor->CastSpell(GetHitUnit(), SPELL_UNBOUND_PLAGUE_SEARCHER, true); } - else - grow->ModStackAmount(-3); } } - - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_putricide_eat_ooze_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); - OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_putricide_eat_ooze_SpellScript::SelectTarget, EFFECT_0, TARGET_UNIT_DEST_AREA_ENTRY); - } - }; - - SpellScript* GetSpellScript() const override - { - return new spell_putricide_eat_ooze_SpellScript(); } + } + + void Register() override + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_putricide_unbound_plague::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ALLY); + OnEffectHitTarget += SpellEffectFn(spell_putricide_unbound_plague::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } }; -class spell_putricide_mutated_plague : public SpellScriptLoader +class spell_putricide_eat_ooze : public SpellScript { - public: - spell_putricide_mutated_plague() : SpellScriptLoader("spell_putricide_mutated_plague") { } - - class spell_putricide_mutated_plague_AuraScript : public AuraScript - { - PrepareAuraScript(spell_putricide_mutated_plague_AuraScript); - - void HandleTriggerSpell(AuraEffect const* aurEff) - { - PreventDefaultAction(); - Unit* caster = GetCaster(); - if (!caster) - return; - - uint32 triggerSpell = aurEff->GetSpellEffectInfo().TriggerSpell; - SpellInfo const* spell = sSpellMgr->AssertSpellInfo(triggerSpell, GetCastDifficulty()); - - int32 damage = spell->GetEffect(EFFECT_0).CalcValue(caster); - float multiplier = 2.0f; - if (GetTarget()->GetMap()->Is25ManRaid()) - multiplier = 3.0f; - - damage *= int32(pow(multiplier, GetStackAmount())); - damage = int32(damage * 1.5f); - - CastSpellExtraArgs args(aurEff); - args.OriginalCaster = GetCasterGUID(); - args.AddSpellBP0(damage); - GetTarget()->CastSpell(GetTarget(), triggerSpell, args); - } + PrepareSpellScript(spell_putricide_eat_ooze); - void OnRemove(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/) - { - uint32 healSpell = uint32(aurEff->GetSpellEffectInfo().CalcValue()); - SpellInfo const* healSpellInfo = sSpellMgr->GetSpellInfo(healSpell, GetCastDifficulty()); + void SelectTarget(std::list<WorldObject*>& targets) + { + if (targets.empty()) + return; - if (!healSpellInfo) - return; + targets.sort(Trinity::ObjectDistanceOrderPred(GetCaster())); + WorldObject* target = targets.front(); + targets.clear(); + targets.push_back(target); + } - int32 heal = healSpellInfo->GetEffect(EFFECT_0).CalcValue() * GetStackAmount(); - CastSpellExtraArgs args(TRIGGERED_FULL_MASK); - args.SetOriginalCaster(GetCasterGUID()); - args.AddSpellBP0(heal); - GetTarget()->CastSpell(GetTarget(), healSpell, args); - } + void HandleScript(SpellEffIndex /*effIndex*/) + { + Creature* target = GetHitCreature(); + if (!target) + return; - void Register() override + if (Aura* grow = target->GetAura(uint32(GetEffectValue()))) + { + if (grow->GetStackAmount() < 3) { - OnEffectPeriodic += AuraEffectPeriodicFn(spell_putricide_mutated_plague_AuraScript::HandleTriggerSpell, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL); - AfterEffectRemove += AuraEffectRemoveFn(spell_putricide_mutated_plague_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL, AURA_EFFECT_HANDLE_REAL); + target->RemoveAurasDueToSpell(SPELL_GROW_STACKER); + target->RemoveAura(grow); + target->DespawnOrUnsummon(1ms); } - }; - - AuraScript* GetAuraScript() const override - { - return new spell_putricide_mutated_plague_AuraScript(); + else + grow->ModStackAmount(-3); } + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_putricide_eat_ooze::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_putricide_eat_ooze::SelectTarget, EFFECT_0, TARGET_UNIT_DEST_AREA_ENTRY); + } }; -class spell_putricide_mutation_init : public SpellScriptLoader +class spell_putricide_mutated_plague : public AuraScript { - public: - spell_putricide_mutation_init() : SpellScriptLoader("spell_putricide_mutation_init") { } - - class spell_putricide_mutation_init_SpellScript : public SpellScript - { - PrepareSpellScript(spell_putricide_mutation_init_SpellScript); + PrepareAuraScript(spell_putricide_mutated_plague); - SpellCastResult CheckRequirementInternal(SpellCustomErrors& extendedError) - { - InstanceScript* instance = GetExplTargetUnit()->GetInstanceScript(); - if (!instance) - return SPELL_FAILED_CANT_DO_THAT_RIGHT_NOW; - - Creature* professor = ObjectAccessor::GetCreature(*GetExplTargetUnit(), instance->GetGuidData(DATA_PROFESSOR_PUTRICIDE)); - if (!professor) - return SPELL_FAILED_CANT_DO_THAT_RIGHT_NOW; - - if (professor->AI()->GetData(DATA_PHASE) == PHASE_COMBAT_3 || !professor->IsAlive()) - { - extendedError = SPELL_CUSTOM_ERROR_ALL_POTIONS_USED; - return SPELL_FAILED_CUSTOM_ERROR; - } - - if (professor->AI()->GetData(DATA_ABOMINATION)) - { - extendedError = SPELL_CUSTOM_ERROR_TOO_MANY_ABOMINATIONS; - return SPELL_FAILED_CUSTOM_ERROR; - } - - return SPELL_CAST_OK; - } - - SpellCastResult CheckRequirement() - { - if (!GetExplTargetUnit()) - return SPELL_FAILED_BAD_TARGETS; - - if (GetExplTargetUnit()->GetTypeId() != TYPEID_PLAYER) - return SPELL_FAILED_TARGET_NOT_PLAYER; + void HandleTriggerSpell(AuraEffect const* aurEff) + { + PreventDefaultAction(); + Unit* caster = GetCaster(); + if (!caster) + return; + + uint32 triggerSpell = aurEff->GetSpellEffectInfo().TriggerSpell; + SpellInfo const* spell = sSpellMgr->AssertSpellInfo(triggerSpell, GetCastDifficulty()); + + int32 damage = spell->GetEffect(EFFECT_0).CalcValue(caster); + float multiplier = 2.0f; + if (GetTarget()->GetMap()->Is25ManRaid()) + multiplier = 3.0f; + + damage *= int32(pow(multiplier, GetStackAmount())); + damage = int32(damage * 1.5f); + + CastSpellExtraArgs args(aurEff); + args.OriginalCaster = GetCasterGUID(); + args.AddSpellBP0(damage); + GetTarget()->CastSpell(GetTarget(), triggerSpell, args); + } - SpellCustomErrors extension = SPELL_CUSTOM_ERROR_NONE; - SpellCastResult result = CheckRequirementInternal(extension); - if (result != SPELL_CAST_OK) - { - Spell::SendCastResult(GetExplTargetUnit()->ToPlayer(), GetSpellInfo(), GetSpell()->m_SpellVisual, GetSpell()->m_castId, result, extension); - return result; - } + void OnRemove(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/) + { + uint32 healSpell = uint32(aurEff->GetSpellEffectInfo().CalcValue()); + SpellInfo const* healSpellInfo = sSpellMgr->GetSpellInfo(healSpell, GetCastDifficulty()); - return SPELL_CAST_OK; - } + if (!healSpellInfo) + return; - void Register() override - { - OnCheckCast += SpellCheckCastFn(spell_putricide_mutation_init_SpellScript::CheckRequirement); - } - }; + int32 heal = healSpellInfo->GetEffect(EFFECT_0).CalcValue() * GetStackAmount(); + CastSpellExtraArgs args(TRIGGERED_FULL_MASK); + args.SetOriginalCaster(GetCasterGUID()); + args.AddSpellBP0(heal); + GetTarget()->CastSpell(GetTarget(), healSpell, args); + } - class spell_putricide_mutation_init_AuraScript : public AuraScript - { - PrepareAuraScript(spell_putricide_mutation_init_AuraScript); + void Register() override + { + OnEffectPeriodic += AuraEffectPeriodicFn(spell_putricide_mutated_plague::HandleTriggerSpell, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL); + AfterEffectRemove += AuraEffectRemoveFn(spell_putricide_mutated_plague::OnRemove, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL, AURA_EFFECT_HANDLE_REAL); + } +}; - void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - uint32 spellId = 70311; - if (GetTarget()->GetMap()->Is25ManRaid()) - spellId = 71503; +class spell_putricide_mutation_init : public SpellScript +{ + PrepareSpellScript(spell_putricide_mutation_init); - GetTarget()->CastSpell(GetTarget(), spellId, true); - } + SpellCastResult CheckRequirementInternal(SpellCustomErrors& extendedError) + { + InstanceScript* instance = GetExplTargetUnit()->GetInstanceScript(); + if (!instance) + return SPELL_FAILED_CANT_DO_THAT_RIGHT_NOW; - void Register() override - { - AfterEffectRemove += AuraEffectRemoveFn(spell_putricide_mutation_init_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); - } - }; + Creature* professor = ObjectAccessor::GetCreature(*GetExplTargetUnit(), instance->GetGuidData(DATA_PROFESSOR_PUTRICIDE)); + if (!professor) + return SPELL_FAILED_CANT_DO_THAT_RIGHT_NOW; - SpellScript* GetSpellScript() const override + if (professor->AI()->GetData(DATA_PHASE) == PHASE_COMBAT_3 || !professor->IsAlive()) { - return new spell_putricide_mutation_init_SpellScript(); + extendedError = SPELL_CUSTOM_ERROR_ALL_POTIONS_USED; + return SPELL_FAILED_CUSTOM_ERROR; } - AuraScript* GetAuraScript() const override + if (professor->AI()->GetData(DATA_ABOMINATION)) { - return new spell_putricide_mutation_init_AuraScript(); + extendedError = SPELL_CUSTOM_ERROR_TOO_MANY_ABOMINATIONS; + return SPELL_FAILED_CUSTOM_ERROR; } -}; -class spell_putricide_mutated_transformation_dismiss : public SpellScriptLoader -{ - public: - spell_putricide_mutated_transformation_dismiss() : SpellScriptLoader("spell_putricide_mutated_transformation_dismiss") { } + return SPELL_CAST_OK; + } - class spell_putricide_mutated_transformation_dismiss_AuraScript : public AuraScript - { - PrepareAuraScript(spell_putricide_mutated_transformation_dismiss_AuraScript); + SpellCastResult CheckRequirement() + { + if (!GetExplTargetUnit()) + return SPELL_FAILED_BAD_TARGETS; - void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - if (Vehicle* veh = GetTarget()->GetVehicleKit()) - veh->RemoveAllPassengers(); - } + if (GetExplTargetUnit()->GetTypeId() != TYPEID_PLAYER) + return SPELL_FAILED_TARGET_NOT_PLAYER; - void Register() override - { - AfterEffectRemove += AuraEffectRemoveFn(spell_putricide_mutated_transformation_dismiss_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL, AURA_EFFECT_HANDLE_REAL); - } - }; - - AuraScript* GetAuraScript() const override + SpellCustomErrors extension = SPELL_CUSTOM_ERROR_NONE; + SpellCastResult result = CheckRequirementInternal(extension); + if (result != SPELL_CAST_OK) { - return new spell_putricide_mutated_transformation_dismiss_AuraScript(); + Spell::SendCastResult(GetExplTargetUnit()->ToPlayer(), GetSpellInfo(), GetSpell()->m_SpellVisual, GetSpell()->m_castId, result, extension); + return result; } + + return SPELL_CAST_OK; + } + + void Register() override + { + OnCheckCast += SpellCheckCastFn(spell_putricide_mutation_init::CheckRequirement); + } }; -class spell_putricide_mutated_transformation : public SpellScriptLoader +class spell_putricide_mutation_init_aura : public AuraScript { - public: - spell_putricide_mutated_transformation() : SpellScriptLoader("spell_putricide_mutated_transformation") { } + PrepareAuraScript(spell_putricide_mutation_init_aura); - class spell_putricide_mutated_transformation_SpellScript : public SpellScript - { - PrepareSpellScript(spell_putricide_mutated_transformation_SpellScript); + void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + uint32 spellId = 70311; + if (GetTarget()->GetMap()->Is25ManRaid()) + spellId = 71503; - void HandleSummon(SpellEffIndex effIndex) - { - PreventHitDefaultEffect(effIndex); - Unit* caster = GetOriginalCaster(); - if (!caster) - return; + GetTarget()->CastSpell(GetTarget(), spellId, true); + } - InstanceScript* instance = caster->GetInstanceScript(); - if (!instance) - return; + void Register() override + { + AfterEffectRemove += AuraEffectRemoveFn(spell_putricide_mutation_init_aura::OnRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); + } +}; - Creature* putricide = ObjectAccessor::GetCreature(*caster, instance->GetGuidData(DATA_PROFESSOR_PUTRICIDE)); - if (!putricide) - return; +class spell_putricide_mutated_transformation_dismiss : public AuraScript +{ + PrepareAuraScript(spell_putricide_mutated_transformation_dismiss); - if (putricide->AI()->GetData(DATA_ABOMINATION)) - { - if (Player* player = caster->ToPlayer()) - Spell::SendCastResult(player, GetSpellInfo(), GetSpell()->m_SpellVisual, GetSpell()->m_castId, SPELL_FAILED_CUSTOM_ERROR, SPELL_CUSTOM_ERROR_TOO_MANY_ABOMINATIONS); - return; - } + void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + if (Vehicle* veh = GetTarget()->GetVehicleKit()) + veh->RemoveAllPassengers(); + } - uint32 entry = uint32(GetEffectInfo().MiscValue); - SummonPropertiesEntry const* properties = sSummonPropertiesStore.LookupEntry(uint32(GetEffectInfo().MiscValueB)); - uint32 duration = uint32(GetSpellInfo()->GetDuration()); + void Register() override + { + AfterEffectRemove += AuraEffectRemoveFn(spell_putricide_mutated_transformation_dismiss::OnRemove, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL, AURA_EFFECT_HANDLE_REAL); + } +}; - Position pos = caster->GetPosition(); - TempSummon* summon = caster->GetMap()->SummonCreature(entry, pos, properties, duration, caster, GetSpellInfo()->Id); - if (!summon || !summon->IsVehicle()) - return; +class spell_putricide_mutated_transformation : public SpellScript +{ + PrepareSpellScript(spell_putricide_mutated_transformation); - summon->CastSpell(summon, SPELL_ABOMINATION_VEHICLE_POWER_DRAIN, true); - summon->CastSpell(summon, SPELL_MUTATED_TRANSFORMATION_DAMAGE, true); - caster->CastSpell(summon, SPELL_MUTATED_TRANSFORMATION_NAME, true); + void HandleSummon(SpellEffIndex effIndex) + { + PreventHitDefaultEffect(effIndex); + Unit* caster = GetOriginalCaster(); + if (!caster) + return; - caster->EnterVehicle(summon, 0); // VEHICLE_SPELL_RIDE_HARDCODED is used according to sniff, this is ok - summon->SetCreatorGUID(caster->GetGUID()); - putricide->AI()->JustSummoned(summon); - } + InstanceScript* instance = caster->GetInstanceScript(); + if (!instance) + return; - void Register() override - { - OnEffectHit += SpellEffectFn(spell_putricide_mutated_transformation_SpellScript::HandleSummon, EFFECT_0, SPELL_EFFECT_SUMMON); - } - }; + Creature* putricide = ObjectAccessor::GetCreature(*caster, instance->GetGuidData(DATA_PROFESSOR_PUTRICIDE)); + if (!putricide) + return; - SpellScript* GetSpellScript() const override + if (putricide->AI()->GetData(DATA_ABOMINATION)) { - return new spell_putricide_mutated_transformation_SpellScript(); + if (Player* player = caster->ToPlayer()) + Spell::SendCastResult(player, GetSpellInfo(), GetSpell()->m_SpellVisual, GetSpell()->m_castId, SPELL_FAILED_CUSTOM_ERROR, SPELL_CUSTOM_ERROR_TOO_MANY_ABOMINATIONS); + return; } -}; -class spell_putricide_mutated_transformation_dmg : public SpellScriptLoader -{ - public: - spell_putricide_mutated_transformation_dmg() : SpellScriptLoader("spell_putricide_mutated_transformation_dmg") { } + uint32 entry = uint32(GetEffectInfo().MiscValue); + SummonPropertiesEntry const* properties = sSummonPropertiesStore.LookupEntry(uint32(GetEffectInfo().MiscValueB)); + uint32 duration = uint32(GetSpellInfo()->GetDuration()); - class spell_putricide_mutated_transformation_dmg_SpellScript : public SpellScript - { - PrepareSpellScript(spell_putricide_mutated_transformation_dmg_SpellScript); + Position pos = caster->GetPosition(); + TempSummon* summon = caster->GetMap()->SummonCreature(entry, pos, properties, duration, caster, GetSpellInfo()->Id); + if (!summon || !summon->IsVehicle()) + return; - void FilterTargetsInitial(std::list<WorldObject*>& targets) - { - if (Unit* owner = ObjectAccessor::GetUnit(*GetCaster(), GetCaster()->GetCreatorGUID())) - targets.remove(owner); - } + summon->CastSpell(summon, SPELL_ABOMINATION_VEHICLE_POWER_DRAIN, true); + summon->CastSpell(summon, SPELL_MUTATED_TRANSFORMATION_DAMAGE, true); + caster->CastSpell(summon, SPELL_MUTATED_TRANSFORMATION_NAME, true); - void Register() override - { - OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_putricide_mutated_transformation_dmg_SpellScript::FilterTargetsInitial, EFFECT_0, TARGET_UNIT_SRC_AREA_ALLY); - } - }; + caster->EnterVehicle(summon, 0); // VEHICLE_SPELL_RIDE_HARDCODED is used according to sniff, this is ok + summon->SetCreatorGUID(caster->GetGUID()); + putricide->AI()->JustSummoned(summon); + } - SpellScript* GetSpellScript() const override - { - return new spell_putricide_mutated_transformation_dmg_SpellScript(); - } + void Register() override + { + OnEffectHit += SpellEffectFn(spell_putricide_mutated_transformation::HandleSummon, EFFECT_0, SPELL_EFFECT_SUMMON); + } }; -class spell_putricide_regurgitated_ooze : public SpellScriptLoader +class spell_putricide_mutated_transformation_dmg : public SpellScript { - public: - spell_putricide_regurgitated_ooze() : SpellScriptLoader("spell_putricide_regurgitated_ooze") { } - - class spell_putricide_regurgitated_ooze_SpellScript : public SpellScript - { - PrepareSpellScript(spell_putricide_regurgitated_ooze_SpellScript); + PrepareSpellScript(spell_putricide_mutated_transformation_dmg); - // the only purpose of this hook is to fail the achievement - void ExtraEffect(SpellEffIndex /*effIndex*/) - { - if (InstanceScript* instance = GetCaster()->GetInstanceScript()) - instance->SetData(DATA_NAUSEA_ACHIEVEMENT, uint32(false)); - } - - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_putricide_regurgitated_ooze_SpellScript::ExtraEffect, EFFECT_0, SPELL_EFFECT_APPLY_AURA); - } - }; + void FilterTargetsInitial(std::list<WorldObject*>& targets) + { + if (Unit* owner = ObjectAccessor::GetUnit(*GetCaster(), GetCaster()->GetCreatorGUID())) + targets.remove(owner); + } - SpellScript* GetSpellScript() const override - { - return new spell_putricide_regurgitated_ooze_SpellScript(); - } + void Register() override + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_putricide_mutated_transformation_dmg::FilterTargetsInitial, EFFECT_0, TARGET_UNIT_SRC_AREA_ALLY); + } }; -// Removes aura with id stored in effect value -class spell_putricide_clear_aura_effect_value : public SpellScriptLoader +class spell_putricide_regurgitated_ooze : public SpellScript { - public: - spell_putricide_clear_aura_effect_value() : SpellScriptLoader("spell_putricide_clear_aura_effect_value") { } + PrepareSpellScript(spell_putricide_regurgitated_ooze); - class spell_putricide_clear_aura_effect_value_SpellScript : public SpellScript - { - PrepareSpellScript(spell_putricide_clear_aura_effect_value_SpellScript); + // the only purpose of this hook is to fail the achievement + void ExtraEffect(SpellEffIndex /*effIndex*/) + { + if (InstanceScript* instance = GetCaster()->GetInstanceScript()) + instance->SetData(DATA_NAUSEA_ACHIEVEMENT, uint32(false)); + } - void HandleScript(SpellEffIndex effIndex) - { - PreventHitDefaultEffect(effIndex); - Unit* target = GetHitUnit(); - uint32 auraId = GetEffectValue(); - target->RemoveAurasDueToSpell(auraId); - if (m_scriptSpellId == SPELL_TEAR_GAS_CANCEL && GetSpellInfo()->GetEffects().size() >= EFFECT_1) - { - uint32 auraId2 = GetSpellInfo()->GetEffect(EFFECT_1).CalcValue(); - target->RemoveAurasDueToSpell(auraId2); - } - } + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_putricide_regurgitated_ooze::ExtraEffect, EFFECT_0, SPELL_EFFECT_APPLY_AURA); + } +}; - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_putricide_clear_aura_effect_value_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); - } - }; +// Removes aura with id stored in effect value +class spell_putricide_clear_aura_effect_value : public SpellScript +{ + PrepareSpellScript(spell_putricide_clear_aura_effect_value); - SpellScript* GetSpellScript() const override + void HandleScript(SpellEffIndex effIndex) + { + PreventHitDefaultEffect(effIndex); + Unit* target = GetHitUnit(); + uint32 auraId = GetEffectValue(); + target->RemoveAurasDueToSpell(auraId); + if (m_scriptSpellId == SPELL_TEAR_GAS_CANCEL && GetSpellInfo()->GetEffects().size() >= EFFECT_1) { - return new spell_putricide_clear_aura_effect_value_SpellScript(); + uint32 auraId2 = GetSpellInfo()->GetEffect(EFFECT_1).CalcValue(); + target->RemoveAurasDueToSpell(auraId2); } + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_putricide_clear_aura_effect_value::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } }; // Stinky and Precious spell, it's here because its used for both (Festergut and Rotface "pets") -class spell_stinky_precious_decimate : public SpellScriptLoader +class spell_stinky_precious_decimate : public SpellScript { - public: - spell_stinky_precious_decimate() : SpellScriptLoader("spell_stinky_precious_decimate") { } - - class spell_stinky_precious_decimate_SpellScript : public SpellScript - { - PrepareSpellScript(spell_stinky_precious_decimate_SpellScript); - - void HandleScript(SpellEffIndex /*effIndex*/) - { - if (GetHitUnit()->GetHealthPct() > float(GetEffectValue())) - { - uint32 newHealth = GetHitUnit()->GetMaxHealth() * uint32(GetEffectValue()) / 100; - GetHitUnit()->SetHealth(newHealth); - } - } + PrepareSpellScript(spell_stinky_precious_decimate); - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_stinky_precious_decimate_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); - } - }; - - SpellScript* GetSpellScript() const override + void HandleScript(SpellEffIndex /*effIndex*/) + { + if (GetHitUnit()->GetHealthPct() > float(GetEffectValue())) { - return new spell_stinky_precious_decimate_SpellScript(); + uint32 newHealth = GetHitUnit()->GetMaxHealth() * uint32(GetEffectValue()) / 100; + GetHitUnit()->SetHealth(newHealth); } + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_stinky_precious_decimate::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } }; // 70402, 72511, 72512, 72513 - Mutated Transformation @@ -1687,26 +1451,29 @@ class spell_abomination_mutated_transformation : public SpellScript void AddSC_boss_professor_putricide() { - new boss_professor_putricide(); - new npc_volatile_ooze(); - new npc_gas_cloud(); - new spell_putricide_gaseous_bloat(); - new spell_putricide_ooze_channel(); - new spell_putricide_slime_puddle(); - new spell_putricide_slime_puddle_aura(); - new spell_putricide_unstable_experiment(); - new spell_putricide_ooze_eruption_searcher(); - new spell_putricide_ooze_tank_protection(); - new spell_putricide_choking_gas_bomb(); - new spell_putricide_unbound_plague(); - new spell_putricide_eat_ooze(); - new spell_putricide_mutated_plague(); - new spell_putricide_mutation_init(); - new spell_putricide_mutated_transformation_dismiss(); - new spell_putricide_mutated_transformation(); - new spell_putricide_mutated_transformation_dmg(); - new spell_putricide_regurgitated_ooze(); - new spell_putricide_clear_aura_effect_value(); - new spell_stinky_precious_decimate(); + // Creatures + RegisterIcecrownCitadelCreatureAI(boss_professor_putricide); + RegisterIcecrownCitadelCreatureAI(npc_volatile_ooze); + RegisterIcecrownCitadelCreatureAI(npc_gas_cloud); + + // Spells + RegisterSpellScript(spell_putricide_gaseous_bloat); + RegisterSpellScript(spell_putricide_ooze_channel); + RegisterSpellScript(spell_putricide_slime_puddle); + RegisterSpellScript(spell_putricide_slime_puddle_aura); + RegisterSpellScript(spell_putricide_unstable_experiment); + RegisterSpellScript(spell_putricide_ooze_eruption_searcher); + RegisterSpellScript(spell_putricide_ooze_tank_protection); + RegisterSpellScript(spell_putricide_choking_gas_bomb); + RegisterSpellScript(spell_putricide_unbound_plague); + RegisterSpellScript(spell_putricide_eat_ooze); + RegisterSpellScript(spell_putricide_mutated_plague); + RegisterSpellAndAuraScriptPair(spell_putricide_mutation_init, spell_putricide_mutation_init_aura); + RegisterSpellScript(spell_putricide_mutated_transformation_dismiss); + RegisterSpellScript(spell_putricide_mutated_transformation); + RegisterSpellScript(spell_putricide_mutated_transformation_dmg); + RegisterSpellScript(spell_putricide_regurgitated_ooze); + RegisterSpellScript(spell_putricide_clear_aura_effect_value); + RegisterSpellScript(spell_stinky_precious_decimate); RegisterSpellScript(spell_abomination_mutated_transformation); } |