void UpdateAI(const uint32 uiDiff) { //Return since we have no target if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; if(m_bCanShatter) if(m_uiShatterTimer < uiDiff) { ShatterGolem(); m_bCanShatter = false; }else m_uiShatterTimer -= uiDiff; for(uint8 i=0; i<3; ++i) { Unit* pGolem = Unit::GetUnit(*m_creature, m_uiGolemsGUID[i][0]); if(pGolem && pGolem->isAlive()) if(pGolem->GetHealth()*100 / pGolem->GetMaxHealth() < 1) m_uiGolemsGUID[i][1] = 1; } if(!m_bCanShatter && m_uiGolemsGUID[0][1] == 1 && m_uiGolemsGUID[1][1] == 1 && m_uiGolemsGUID[2][1] == 1) { DoCastSpellIfCan(m_creature, m_bIsRegularMode ? SPELL_SHATTERING_STOMP_N : SPELL_SHATTERING_STOMP_H); m_uiShatterTimer = 3000; m_bCanShatter = true; } // Health check if (m_creature->GetHealth()*100 / m_creature->GetMaxHealth() < (100-(20*m_uiHealthAmountModifier))) { SummonGolems(); ++m_uiHealthAmountModifier; DoScriptText(urand(0, 1) ? SAY_FORGE_1 : SAY_FORGE_2, m_creature); } DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 uiDiff) { //Return since we have no target if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; if (m_bIsStriking) { if (m_uiPause_Timer < uiDiff) { if (m_creature->GetMotionMaster()->GetCurrentMovementGeneratorType() != TARGETED_MOTION_TYPE) { if (m_creature->getVictim()) m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim()); } m_bHasTemper = false; m_bIsStriking = false; m_uiPause_Timer = 3500; } else m_uiPause_Timer -= uiDiff; return; } // When to start shatter? After 60, 40 or 20% hp? if (!m_bHasTemper && m_uiHealthAmountModifier >= 3) { if (m_uiShatteringStomp_Timer < uiDiff) { //should he stomp even if he has no brittle golem to shatter? DoScriptText(urand(0, 1) ? SAY_STOMP_1 : SAY_STOMP_2, m_creature); DoCast(m_creature, m_bIsHeroic ? SPELL_SHATTERING_STOMP_H : SPELL_SHATTERING_STOMP_N); DoScriptText(EMOTE_SHATTER, m_creature); m_uiShatteringStomp_Timer = 30000; m_bCanShatterGolem = true; } else m_uiShatteringStomp_Timer -= uiDiff; } // Shatter Golems 3 seconds after Shattering Stomp if (m_bCanShatterGolem) { if (m_uiShatter_Timer < uiDiff) { ShatterGolem(); m_uiShatter_Timer = 3000; m_bCanShatterGolem = false; } else m_uiShatter_Timer -= uiDiff; } // Health check if (!m_bCanShatterGolem && (m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) < (100-(20*m_uiHealthAmountModifier))) { ++m_uiHealthAmountModifier; if (m_creature->IsNonMeleeSpellCasted(false)) m_creature->InterruptNonMeleeSpells(false); DoScriptText(urand(0, 1) ? SAY_FORGE_1 : SAY_FORGE_2, m_creature); m_bHasTemper = true; m_creature->CastSpell(m_creature, SPELL_TEMPER, false); } DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 uiDiff) { if (!UpdateVictim()) return; if (m_bIsStriking) { if (m_uiPause_Timer <= uiDiff) { if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() != CHASE_MOTION_TYPE) if (me->getVictim()) me->GetMotionMaster()->MoveChase(me->getVictim()); m_bHasTemper = false; m_bIsStriking = false; m_uiPause_Timer = 3500; } else m_uiPause_Timer -= uiDiff; return; } // When to start shatter? After 60, 40 or 20% hp? if (!m_bHasTemper && m_uiHealthAmountModifier >= 3) { if (m_uiShatteringStomp_Timer <= uiDiff) { // Should he stomp even if he has no brittle golem to shatter? Talk(SAY_STOMP); DoCast(me, SPELL_SHATTERING_STOMP_N); Talk(EMOTE_SHATTER); m_uiShatteringStomp_Timer = 30000; m_bCanShatterGolem = true; } else m_uiShatteringStomp_Timer -= uiDiff; } // Shatter Golems 3 seconds after Shattering Stomp if (m_bCanShatterGolem) { if (m_uiShatter_Timer <= uiDiff) { ShatterGolem(); m_uiShatter_Timer = 3000; m_bCanShatterGolem = false; } else m_uiShatter_Timer -= uiDiff; } // Health check if (!m_bCanShatterGolem && me->HealthBelowPct(100 - 20 * m_uiHealthAmountModifier)) { ++m_uiHealthAmountModifier; if (me->IsNonMeleeSpellCasted(false)) me->InterruptNonMeleeSpells(false); Talk(SAY_FORGE); m_bHasTemper = true; m_uiSummonPhase = 1; } switch (m_uiSummonPhase) { case 1: // 1 - Start run to Anvil Talk(EMOTE_TO_ANVIL); me->GetMotionMaster()->MoveTargetedHome(); m_uiSummonPhase = 2; // Set Next Phase break; case 2: // 2 - Check if reached Anvil // This is handled in: void JustReachedHome() break; case 3: // 3 - Cast Temper on the Anvil if (Unit* target = GetClosestCreatureWithEntry(me, NPC_VOLKHAN_ANVIL, 1000.0f, true)) { me->SetOrientation(2.29f); DoCast(target, SPELL_TEMPER, false); DoCast(target, SPELL_TEMPER_DUMMY, false); } m_uiDelay_Timer = 1000; // Delay 2 seconds before next phase can begin m_uiSummonPhase = 4; // Set Next Phase break; case 4: // 4 - Wait for delay to expire if (m_uiDelay_Timer <= uiDiff) { if (Unit* target = SelectTarget(SELECT_TARGET_TOPAGGRO, 0)) { me->SetReactState(REACT_AGGRESSIVE); me->SetInCombatWith(target); me->GetMotionMaster()->MoveFollow(target, 0.0f, 0.0f); } m_uiSummonPhase = 5; } else m_uiDelay_Timer -= uiDiff; break; case 5: // 5 - Spawn the Golems if (Creature* creatureTarget = GetClosestCreatureWithEntry(me, NPC_VOLKHAN_ANVIL, 1000.0f, true)) for (uint8 i = 0; i < MAX_GOLEM; ++i) me->CastSpell(creatureTarget, SPELL_SUMMON_MOLTEN_GOLEM, true); m_bIsStriking = true; m_uiSummonPhase = 0; // Reset back to Phase 0 for next time break; } DoMeleeAttackIfReady(); }
void UpdateAI(uint32 diff) override { // Return since we have no target and are in CombatPhase if (events.IsInPhase(PHASE_NORMAL) && !UpdateVictim()) return; events.Update(diff); if (me->HasUnitState(UNIT_STATE_CASTING)) return; while (uint32 eventId = events.ExecuteEvent()) { switch (eventId) { case EVENT_PAUSE: if (m_bIsStriking) { if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() != CHASE_MOTION_TYPE) if (me->GetVictim()) me->GetMotionMaster()->MoveChase(me->GetVictim()); m_bHasTemper = false; m_bIsStriking = false; events.ScheduleEvent(EVENT_PAUSE, 3.5 * IN_MILLISECONDS, 0, PHASE_NORMAL); } break; case EVENT_SHATTERING_STOMP: if (!m_bHasTemper && m_uiHealthAmountModifier >= 3) { // Should he stomp even if he has no brittle golem to shatter? Talk(SAY_STOMP); DoCast(me, SPELL_SHATTERING_STOMP); Talk(EMOTE_SHATTER); events.ScheduleEvent(EVENT_SHATTERING_STOMP, 30 * IN_MILLISECONDS, 0, PHASE_NORMAL); m_bCanShatterGolem = true; } break; case EVENT_SHATTER: if (m_bCanShatterGolem) { ShatterGolem(); events.ScheduleEvent(EVENT_SHATTER, 3 * IN_MILLISECONDS, 0, PHASE_NORMAL); m_bCanShatterGolem = false; } break; case EVENT_FORGE_CAST: DoCast(me, SPELL_FORGE_VISUAL); events.ScheduleEvent(EVENT_FORGE_CAST, 15 * IN_MILLISECONDS, 0, PHASE_INTRO); break; default: break; } } // Health check if (!m_bCanShatterGolem && me->HealthBelowPct(100 - 20 * m_uiHealthAmountModifier)) { ++m_uiHealthAmountModifier; if (me->IsNonMeleeSpellCast(false)) me->InterruptNonMeleeSpells(false); Talk(SAY_FORGE); m_bHasTemper = true; m_uiSummonPhase = 1; } switch (m_uiSummonPhase) { case 1: // 1 - Start run to Anvil Talk(EMOTE_TO_ANVIL); me->GetMotionMaster()->MoveTargetedHome(); m_uiSummonPhase = 2; // Set Next Phase break; case 2: // 2 - Check if reached Anvil // This is handled in: void JustReachedHome() override break; case 3: // 3 - Cast Temper on the Anvil if (Unit* target = GetClosestCreatureWithEntry(me, NPC_VOLKHAN_ANVIL, 1000.0f, true)) { me->SetOrientation(2.29f); DoCast(target, SPELL_TEMPER, false); DoCast(target, SPELL_TEMPER_DUMMY, false); } m_uiDelay_Timer = 1000; // Delay 2 seconds before next phase can begin m_uiSummonPhase = 4; // Set Next Phase break; case 4: // 4 - Wait for delay to expire if (m_uiDelay_Timer <= diff) { if (Unit* target = SelectTarget(SELECT_TARGET_TOPAGGRO, 0)) { me->SetReactState(REACT_AGGRESSIVE); me->SetInCombatWith(target); me->GetMotionMaster()->MoveFollow(target, 0.0f, 0.0f); } m_uiSummonPhase = 5; } else m_uiDelay_Timer -= diff; break; case 5: // 5 - Spawn the Golems if (Creature* creatureTarget = GetClosestCreatureWithEntry(me, NPC_VOLKHAN_ANVIL, 1000.0f, true)) for (uint8 i = 0; i < MAX_GOLEM; ++i) me->CastSpell(creatureTarget, SPELL_SUMMON_MOLTEN_GOLEM, true); m_bIsStriking = true; m_uiSummonPhase = 0; // Reset back to Phase 0 for next time break; } DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 uiDiff) { //Return since we have no target if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; if (m_bIsStriking) { if (m_uiPause_Timer < uiDiff) { if (m_creature->GetMotionMaster()->GetCurrentMovementGeneratorType() != CHASE_MOTION_TYPE) { if (m_creature->getVictim()) m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim()); } m_bHasTemper = false; m_bIsStriking = false; m_uiPause_Timer = 3500; } else m_uiPause_Timer -= uiDiff; return; } // he shatters only one time, at 20% if (m_creature->GetHealthPercent() <= 20.0f && !m_bHasShattered) { // should he stomp even if he has no brittle golem to shatter? <-yes! if (DoCastSpellIfCan(m_creature, m_bIsRegularMode ? SPELL_SHATTERING_STOMP_N : SPELL_SHATTERING_STOMP_H) == CAST_OK) { DoScriptText(urand(0, 1) ? SAY_STOMP_1 : SAY_STOMP_2, m_creature); DoScriptText(EMOTE_SHATTER, m_creature); m_bCanShatterGolem = true; m_bHasShattered = true; } } // Shatter Golems 3 seconds after Shattering Stomp if (m_bCanShatterGolem) { if (m_uiShatter_Timer < uiDiff) { ShatterGolem(); m_uiShatter_Timer = 3000; m_bCanShatterGolem = false; } else m_uiShatter_Timer -= uiDiff; } // Health check if (!m_bCanShatterGolem && m_creature->GetHealthPercent() < float(100 - 20*m_uiHealthAmountModifier)) { ++m_uiHealthAmountModifier; if (m_creature->IsNonMeleeSpellCasted(false)) m_creature->InterruptNonMeleeSpells(false); DoScriptText(urand(0, 1) ? SAY_FORGE_1 : SAY_FORGE_2, m_creature); m_bHasTemper = true; m_creature->CastSpell(m_creature, SPELL_TEMPER, false); } DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 uiDiff) { //Return since we have no target if (!UpdateVictim()) return; //exploit fix, remove later if (m_uiCheckZ <= uiDiff) { if (me->GetPositionZ() < 50.0f) { EnterEvadeMode(); return; } m_uiCheckZ = 1000; } else m_uiCheckZ -= uiDiff; if (m_bIsStriking && !m_bMove) { if (m_uiPause_Timer <= uiDiff) { if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() != TARGETED_MOTION_TYPE) { if (me->getVictim()) me->GetMotionMaster()->MoveChase(me->getVictim()); } m_bHasTemper = false; m_bIsStriking = false; m_uiPause_Timer = 1500; } else m_uiPause_Timer -= uiDiff; return; } // ShatteringStomp all the Time, if (!m_bHasTemper && !m_bMove) { if (m_uiShatteringStomp_Timer <= uiDiff) { DoScriptText(RAND(SAY_STOMP_1,SAY_STOMP_2), me); DoCast(me, DUNGEON_MODE(SPELL_SHATTERING_STOMP_N,SPELL_SHATTERING_STOMP_H)); if (Creature* temp = me->FindNearestCreature(NPC_BRITTLE_GOLEM,99)) { DoScriptText(EMOTE_SHATTER, me); m_bCanShatterGolem = true; } m_uiShatteringStomp_Timer = 30000; } else m_uiShatteringStomp_Timer -= uiDiff; } // Shatter Golems 3 seconds after Shattering Stomp if (m_bCanShatterGolem) { if (m_uiShatter_Timer <= uiDiff) { ShatterGolem(); m_uiShatter_Timer = 3000; m_bCanShatterGolem = false; } else m_uiShatter_Timer -= uiDiff; } Creature* pAnvil = m_pInstance->instance->GetCreature(m_pInstance->GetData64(DATA_VOLKHAN_ANVIL)); float fX, fY, fZ; me->GetContactPoint(pAnvil, fX, fY, fZ, INTERACTION_DISTANCE); // Health check if (!m_bCanShatterGolem && me->HealthBelowPct(100 - 20 * m_uiHealthAmountModifier) && !m_bMove) { ++m_uiHealthAmountModifier; if (me->IsNonMeleeSpellCasted(false)) me->InterruptNonMeleeSpells(false); DoScriptText(RAND(SAY_FORGE_1,SAY_FORGE_2), me); if (me->GetDistance(pAnvil) > 5) { me->GetMotionMaster()->Clear(); me->SetReactState(REACT_PASSIVE); me->GetMotionMaster()->MovePoint(5,fX,fY,fZ); } DoScriptText(EMOTE_TO_ANVIL, me); m_bMove=true; } if (me->IsWithinMeleeRange(pAnvil,5) && m_bMove) { me->GetMotionMaster()->Clear(); me->SetReactState(REACT_AGGRESSIVE); m_bHasTemper = true; m_bMove=false; for (uint8 i = 0; i < MAX_GOLEM; ++i) { DoCast(SPELL_SUMMON_MOLTEN_GOLEM); } DoCast(SPELL_TEMPER); m_bIsStriking = true; } if (me->GetMotionMaster()->GetCurrentMovementGeneratorType()!=POINT_MOTION_TYPE && m_bMove) //if (m_uiCheckTimer<=uiDiff) { me->GetMotionMaster()->MovePoint(5,fX,fY,fZ); m_uiCheckTimer=1100; } //else //m_uiCheckTimer-=uiDiff; DoMeleeAttackIfReady(); }