void UpdateAI(const uint32 uiDiff) { // must move teleporting of profesor after assisting to scripts of the other bosses (to their JustDied) // m_creature->NearTeleportTo(SpawnLoc[0].x, SpawnLoc[0].y, SpawnLoc[0].z, SpawnLoc[0].o); if (m_bIsAssistingOnly) return; if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; // Enrage if (m_uiEnrageTimer <= uiDiff) { if (DoCastSpellIfCan(m_creature, SPELL_BERSERK) == CAST_OK) { DoScriptText(SAY_BERSERK, m_creature); m_uiEnrageTimer = 30 * MINUTE * IN_MILLISECONDS; } } else m_uiEnrageTimer -= uiDiff; switch(m_uiPhase) { case PHASE_ONE: { // health check if (m_uiHealthCheckTimer <= uiDiff) { if (m_creature->GetHealthPercent() <= 80.0f) { if (m_bIsHeroic) { DoCastSpellIfCan(m_creature, SPELL_VOLATILE_EXPERIMENT); DoExperiment(true, true); DoScriptText(SAY_PHASE_CHANGE, m_creature); } else { DoCastSpellIfCan(m_creature, SPELL_TEAR_GAS, CAST_TRIGGERED); DoCastSpellIfCan(m_creature, SPELL_TEAR_GAS_1, CAST_TRIGGERED); } if (m_pInstance) m_pInstance->SetData(TYPE_PUTRICIDE, SPECIAL); m_creature->GetMotionMaster()->Clear(); m_creature->GetMotionMaster()->MovePoint(POINT_PUTRICIDE_SPAWN, SpawnLoc[0].x, SpawnLoc[0].y, SpawnLoc[0].z); m_uiPhase = PHASE_RUNNING_ONE; return; } m_uiHealthCheckTimer = 1000; } else m_uiHealthCheckTimer -= uiDiff; // Unbound Plague if (m_bIsHeroic) { if (m_uiUnboundPlagueTimer <= uiDiff) { if (Unit *pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0, SPELL_UNBOUND_PLAGUE, SELECT_FLAG_PLAYER)) { if (DoCastSpellIfCan(pTarget, SPELL_UNBOUND_PLAGUE) == CAST_OK) m_uiUnboundPlagueTimer = 70000; } } else m_uiUnboundPlagueTimer -= uiDiff; } // Slime Puddle if (m_uiPuddleTimer <= uiDiff) { for (int i = 0; i < 2; ++i) { if (Unit *pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0, SPELL_SLIME_PUDDLE_SUMMON, SELECT_FLAG_PLAYER)) DoCastSpellIfCan(pTarget, SPELL_SLIME_PUDDLE, CAST_TRIGGERED); } m_uiPuddleTimer = 30000; } else m_uiPuddleTimer -= uiDiff; // Unstable Experiment if (m_uiUnstableExperimentTimer <= uiDiff) { if (DoCastSpellIfCan(m_creature, SPELL_UNSTABLE_EXPERIMENT) == CAST_OK) { DoExperiment(m_bIsGreenOoze); m_uiUnstableExperimentTimer = 30000; m_bIsGreenOoze = !m_bIsGreenOoze; } } else m_uiUnstableExperimentTimer -= uiDiff; break; } case PHASE_TRANSITION_ONE: { if (m_uiTransitionTimer <= uiDiff) { m_creature->GetMotionMaster()->Clear(); m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim()); m_uiTransitionTimer = 15000; m_uiPhase = PHASE_TWO; if (m_pInstance) m_pInstance->SetData(TYPE_PUTRICIDE, IN_PROGRESS); if (m_bIsHeroic) { DoCastSpellIfCan(m_creature, SPELL_CREATE_CONCOCTION); DoScriptText(SAY_TRANSFORM_1, m_creature); } else DoCastSpellIfCan(m_creature, SPELL_TEAR_GAS_CANCEL, CAST_TRIGGERED); } else m_uiTransitionTimer -= uiDiff; return; } case PHASE_TWO: { // health check if (m_uiHealthCheckTimer <= uiDiff) { if (m_creature->GetHealthPercent() <= 35.0f) { if (m_bIsHeroic) { DoCastSpellIfCan(m_creature, SPELL_VOLATILE_EXPERIMENT); DoExperiment(true, true); DoScriptText(SAY_PHASE_CHANGE, m_creature); } else { DoCastSpellIfCan(m_creature, SPELL_TEAR_GAS, CAST_TRIGGERED); DoCastSpellIfCan(m_creature, SPELL_TEAR_GAS_1, CAST_TRIGGERED); } if (m_pInstance) m_pInstance->SetData(TYPE_PUTRICIDE, SPECIAL); m_creature->GetMotionMaster()->Clear(); m_creature->GetMotionMaster()->MovePoint(POINT_PUTRICIDE_SPAWN, SpawnLoc[0].x, SpawnLoc[0].y, SpawnLoc[0].z); m_uiPhase = PHASE_RUNNING_TWO; return; } m_uiHealthCheckTimer = 1000; } else m_uiHealthCheckTimer -= uiDiff; // Unbound Plague if (m_bIsHeroic) { if (m_uiUnboundPlagueTimer <= uiDiff) { if (Unit *pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0, SPELL_UNBOUND_PLAGUE, SELECT_FLAG_PLAYER)) { if (DoCastSpellIfCan(pTarget, SPELL_UNBOUND_PLAGUE) == CAST_OK) m_uiUnboundPlagueTimer = 70000; } } else m_uiUnboundPlagueTimer -= uiDiff; } // Slime Puddle if (m_uiPuddleTimer <= uiDiff) { for (int i = 0; i < 2; ++i) { if (Unit *pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0, SPELL_SLIME_PUDDLE_SUMMON, SELECT_FLAG_PLAYER)) DoCastSpellIfCan(pTarget, SPELL_SLIME_PUDDLE, CAST_TRIGGERED); } m_uiPuddleTimer = 30000; } else m_uiPuddleTimer -= uiDiff; // Unstable Experiment if (m_uiUnstableExperimentTimer <= uiDiff) { if (DoCastSpellIfCan(m_creature, SPELL_UNSTABLE_EXPERIMENT) == CAST_OK) { DoExperiment(m_bIsGreenOoze); m_uiUnstableExperimentTimer = 30000; m_bIsGreenOoze = !m_bIsGreenOoze; } } else m_uiUnstableExperimentTimer -= uiDiff; // Malleable Goo if (m_uiMalleableGooTimer <= uiDiff) { for (int i = 0; i < (m_bIs25Man ? 2 : 1); ++i) { if (Unit *pTarget = SelectRandomRangedTarget(m_creature)) { float x, y, z; pTarget->GetPosition(x, y, z); if (Creature *pTmp = m_creature->SummonCreature(NPC_MALLEABLE_GOO, x, y, z, 0.0f, TEMPSUMMON_TIMED_DESPAWN, 20000)) { DoCastSpellIfCan(pTmp, SPELL_MALLEABLE_GOO_MISSILE); m_uiMalleableGooTimer = 20000; } } } } else m_uiMalleableGooTimer -= uiDiff; // Choking Gas if (m_uiChokingGasBombTimer <= uiDiff) { if (DoCastSpellIfCan(m_creature, SPELL_CHOKING_GAS_BOMB) == CAST_OK) m_uiChokingGasBombTimer = urand(25000, 30000); } else m_uiChokingGasBombTimer -= uiDiff; break; } case PHASE_TRANSITION_TWO: { if (m_uiTransitionTimer <= uiDiff) { m_creature->GetMotionMaster()->Clear(); m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim()); m_uiTransitionTimer = 15000; m_uiPhase = PHASE_THREE; if (m_pInstance) m_pInstance->SetData(TYPE_PUTRICIDE, IN_PROGRESS); if (m_bIsHeroic) { DoCastSpellIfCan(m_creature, SPELL_GUZZLE_POTIONS); DoScriptText(SAY_TRANSFORM_2, m_creature); } else DoCastSpellIfCan(m_creature, SPELL_TEAR_GAS_CANCEL, CAST_TRIGGERED); } else m_uiTransitionTimer -= uiDiff; return; } case PHASE_THREE: { // Unbound Plague if (m_bIsHeroic) { if (m_uiUnboundPlagueTimer <= uiDiff) { if (Unit *pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0, SPELL_UNBOUND_PLAGUE, SELECT_FLAG_PLAYER)) { if (DoCastSpellIfCan(pTarget, SPELL_UNBOUND_PLAGUE) == CAST_OK) m_uiUnboundPlagueTimer = 70000; } } else m_uiUnboundPlagueTimer -= uiDiff; } // Mutated Plague (proc cooldown for creatures doesn't work) if (m_uiMutatedPlagueTimer <= uiDiff) { if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_MUTATED_PLAGUE) == CAST_OK) m_uiMutatedPlagueTimer = 10000; } else m_uiMutatedPlagueTimer -= uiDiff; // Slime Puddle if (m_uiPuddleTimer <= uiDiff) { for (int i = 0; i < 2; ++i) { if (Unit *pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0, SPELL_SLIME_PUDDLE_SUMMON, SELECT_FLAG_PLAYER)) DoCastSpellIfCan(pTarget, SPELL_SLIME_PUDDLE, CAST_TRIGGERED); } m_uiPuddleTimer = 30000; } else m_uiPuddleTimer -= uiDiff; // Malleable Goo if (m_uiMalleableGooTimer <= uiDiff) { for (int i = 0; i < (m_bIs25Man ? 2 : 1); ++i) { if (Unit *pTarget = SelectRandomRangedTarget(m_creature)) { float x, y, z; pTarget->GetPosition(x, y, z); if (Creature *pTmp = m_creature->SummonCreature(NPC_MALLEABLE_GOO, x, y, z, 0.0f, TEMPSUMMON_TIMED_DESPAWN, 20000)) { DoCastSpellIfCan(pTmp, SPELL_MALLEABLE_GOO_MISSILE); m_uiMalleableGooTimer = 20000; } } } } else m_uiMalleableGooTimer -= uiDiff; // Choking Gas if (m_uiChokingGasBombTimer <= uiDiff) { if (DoCastSpellIfCan(m_creature, SPELL_CHOKING_GAS_BOMB) == CAST_OK) m_uiChokingGasBombTimer = urand(25000, 30000); } else m_uiChokingGasBombTimer -= uiDiff; break; } case PHASE_RUNNING_ONE: case PHASE_RUNNING_TWO: // wait for arriving at the table (during phase transition) break; } DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 uiDiff) { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; switch (m_uiPhase) { // phase 1 case PHASE_1: if (m_uiSlimePuddleTimer < uiDiff) { DoSlimePuddle(); m_uiSlimePuddleTimer = 35000; } else m_uiSlimePuddleTimer -= uiDiff; if (m_uiUnstableExperimentTimer < uiDiff) { DoCast(m_creature, SPELL_UNSTABLE_EXPERIMENT); DoExperiment(); m_uiUnstableExperimentTimer = 37000; } else m_uiUnstableExperimentTimer -= uiDiff; if (m_creature->GetHealthPercent() < 80.0f) { m_creature->InterruptNonMeleeSpells(true); SetCombatMovement(false); if(Difficulty == RAID_DIFFICULTY_10MAN_NORMAL || Difficulty == RAID_DIFFICULTY_25MAN_NORMAL) { DoCast(m_creature, SPELL_TEAR_GAS); m_uiMovementTimer = 2500; } else m_uiMovementTimer = 100; m_uiSwitchTimer = 17500; m_uiDrinkPotionTimer = 10000; m_uiPhase = PHASE_TRANSFORM_1; } break; // break -> tear gas case PHASE_TRANSFORM_1: if(m_uiMovementTimer < uiDiff) { m_creature->GetMotionMaster()->MovePoint(0, homeX, homeY, homeZ); m_uiMovementTimer = 30000; } else m_uiMovementTimer -= uiDiff; if (m_uiDrinkPotionTimer < uiDiff) { DoScriptText(SAY_TRANSFORM1, m_creature); DoCast(m_creature, SPELL_CREATE_CONCOCTION); m_uiDrinkPotionTimer = 60000; } else m_uiDrinkPotionTimer -= uiDiff; if(m_uiSwitchTimer < uiDiff) { SetCombatMovement(true); m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim()); m_uiPhase = PHASE_2; } else m_uiSwitchTimer -= uiDiff; break; // phase 2 case PHASE_2: if (m_uiSlimePuddleTimer < uiDiff) { DoSlimePuddle(); m_uiSlimePuddleTimer = 35000; } else m_uiSlimePuddleTimer -= uiDiff; if (m_uiUnstableExperimentTimer < uiDiff) { DoCast(m_creature, SPELL_UNSTABLE_EXPERIMENT); DoExperiment(); m_uiUnstableExperimentTimer = 37000; } else m_uiUnstableExperimentTimer -= uiDiff; if (m_uiChockinGasTimer < uiDiff) { for(uint8 i = 0; i < m_uiMaxTargets; ++i) { if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) m_creature->SummonCreature(NPC_GAS_BOMB, pTarget->GetPositionX(), pTarget->GetPositionY(), pTarget->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 25000); } m_uiChockinGasTimer = urand(15000, 20000); } else m_uiChockinGasTimer -= uiDiff; if (m_uiMalleableGooTimer < uiDiff) { if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) DoCast(pTarget, SPELL_MALLEABLE_GOO); m_uiMalleableGooTimer = urand(10000, 15000); } else m_uiMalleableGooTimer -= uiDiff; if (m_creature->GetHealthPercent() < 35.0f) { m_creature->InterruptNonMeleeSpells(true); SetCombatMovement(false); if(Difficulty == RAID_DIFFICULTY_10MAN_NORMAL || Difficulty == RAID_DIFFICULTY_25MAN_NORMAL) { DoCast(m_creature, SPELL_TEAR_GAS); m_uiMovementTimer = 2500; } else m_uiMovementTimer = 100; m_uiSwitchTimer = 17500; m_uiDrinkPotionTimer = 10000; m_uiPhase = PHASE_TRANSFORM_2; } break; // break -> tear gas case PHASE_TRANSFORM_2: if(m_uiMovementTimer < uiDiff) { m_creature->GetMotionMaster()->MovePoint(0, homeX, homeY, homeZ); m_uiMovementTimer = 30000; } else m_uiMovementTimer -= uiDiff; if (m_uiDrinkPotionTimer < uiDiff) { DoScriptText(SAY_TRANSFORM2, m_creature); DoCast(m_creature, SPELL_GUZZLE_POTIONS); m_uiDrinkPotionTimer = 60000; } else m_uiDrinkPotionTimer -= uiDiff; if(m_uiSwitchTimer < uiDiff) { if(m_pInstance) m_pInstance->DoRemoveAurasDueToSpellOnPlayers(SPELL_MUTATED_TRANSFORMATION); SetCombatMovement(true); m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim()); m_uiPhase = PHASE_3; } else m_uiSwitchTimer -= uiDiff; break; // phase 3 case PHASE_3: if (m_uiMutatedPlagueTimer < uiDiff) { if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_TOPAGGRO, 0)) DoCast(pTarget, SPELL_MUTATED_PLAGUE); m_uiMutatedPlagueTimer = 10000; } else m_uiMutatedPlagueTimer -= uiDiff; break; } // berserk if (m_uiBerserkTimer < uiDiff) { DoCast(m_creature, SPELL_BERSERK); DoScriptText(SAY_BERSERK, m_creature); m_uiBerserkTimer = 60000; } else m_uiBerserkTimer -= uiDiff; DoMeleeAttackIfReady(); }