void boss_mr_smiteAI::PhaseEquipStart() { // Try to get scripted instance data ScriptedInstance* pInstance = (ScriptedInstance*)m_creature->GetInstanceData(); if (!pInstance) return; // Get chest object if available GameObject* pChest = pInstance->GetSingleGameObjectFromStorage(GO_SMITE_CHEST); if (!pChest) return; // Enter equipment phase (0: Walk to chest object) m_uiPhase = PHASE_EQUIP_NULL; // Get contact point of chest object float fX, fY, fZ; pChest->GetContactPoint(m_creature, fX, fY, fZ, CONTACT_DISTANCE); // Erase all previous movements and walk towards the clostest point available near // that chest object m_creature->GetMotionMaster()->Clear(); m_creature->SetFacingToObject(pChest); m_creature->GetMotionMaster()->MovePoint(0, fX, fY, fZ); }
void WaypointReached(uint32 uiPointId) { if (!m_pInstance) return; switch(uiPointId) { case 1: DoScriptText(SAY_AT_GONG, m_creature); if (GameObject* pStrangeGong = m_pInstance->GetSingleGameObjectFromStorage(GO_STRANGE_GONG)) pStrangeGong->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NO_INTERACT); //Start bang gong for 2min m_creature->CastSpell(m_creature, SPELL_BANGING_THE_GONG, false); SetEscortPaused(true); break; case 3: DoScriptText(SAY_OPEN_ENTRANCE, m_creature); break; case 4: m_pInstance->SetData(TYPE_EVENT_RUN, IN_PROGRESS); //TODO: Spawn group of Amani'shi Savage and make them run to entrance break; } }
void PhaseEquipStart() { ScriptedInstance* pInstance = (ScriptedInstance*)m_creature->GetInstanceData(); if (!pInstance) { return; } GameObject* pChest = pInstance->GetSingleGameObjectFromStorage(GO_SMITE_CHEST); if (!pChest) { return; } m_uiPhase = PHASE_EQUIP_NULL; float fX, fY, fZ; pChest->GetContactPoint(m_creature, fX, fY, fZ, CONTACT_DISTANCE); m_creature->GetMotionMaster()->Clear(); m_creature->SetFacingToObject(pChest); m_creature->GetMotionMaster()->MovePoint(0, fX, fY, fZ); }
void SetMyForge() { std::list<GameObject *> lGOList; uint32 uiGOBellow = 0; uint32 uiGOFire = 0; for (uint8 i = 0; i < MAX_FORGE; ++i) { switch(i) { case 0: uiGOBellow = GO_BELLOW_1; break; case 1: uiGOBellow = GO_BELLOW_2; break; case 2: uiGOBellow = GO_BELLOW_3; break; } if (GameObject* pGOTemp = m_pInstance->GetSingleGameObjectFromStorage(uiGOBellow)) lGOList.push_back(pGOTemp); } if (!lGOList.empty()) { if (lGOList.size() != MAX_FORGE) error_log("SSC: mob_dragonflayer_forge_master expected %u in lGOList, but does not match.", MAX_FORGE); lGOList.sort(ObjectDistanceOrder(m_creature)); if (lGOList.front()->getLootState() == GO_READY) lGOList.front()->UseDoorOrButton(DAY); else if (lGOList.front()->getLootState() == GO_ACTIVATED) lGOList.front()->ResetDoorOrButton(); switch(lGOList.front()->GetEntry()) { case GO_BELLOW_1: uiGOFire = GO_FORGEFIRE_1; m_uiForgeEncounterId = TYPE_BELLOW_1; break; case GO_BELLOW_2: uiGOFire = GO_FORGEFIRE_2; m_uiForgeEncounterId = TYPE_BELLOW_2; break; case GO_BELLOW_3: uiGOFire = GO_FORGEFIRE_3; m_uiForgeEncounterId = TYPE_BELLOW_3; break; } if (GameObject* pGOTemp = m_pInstance->GetSingleGameObjectFromStorage(uiGOFire)) { if (pGOTemp->getLootState() == GO_READY) pGOTemp->UseDoorOrButton(DAY); else if (pGOTemp->getLootState() == GO_ACTIVATED) pGOTemp->ResetDoorOrButton(); } } }
// function that will summon spirits periodically void DoSummonSpirit(uint8 uiIndex) { if (!m_pInstance) return; if (GameObject* pRune = m_pInstance->GetSingleGameObjectFromStorage(GO_DWARFRUNE_A01 + uiIndex)) m_creature->SummonCreature(NPC_BURNING_SPIRIT, pRune->GetPositionX(), pRune->GetPositionY(), pRune->GetPositionZ(), m_creature->GetAngle(m_creature), TEMPSPAWN_TIMED_OOC_OR_DEAD_DESPAWN, 60000); }
// Right is right side from gothik (eastern) bool IsInRightSideGothArea(Unit* pUnit) { if (m_pInstance) if (GameObject* pCombatGate = m_pInstance->GetSingleGameObjectFromStorage(GO_MILI_GOTH_COMBAT_GATE)) return (pCombatGate->GetPositionY() >= pUnit->GetPositionY()); script_error_log("left/right side check, Gothik combat area failed."); return true; }
void DoSummonBroodsOfAnzu() { if (!m_pInstance) { return; } // Note: the birds should fly around the room for about 10 seconds before starting to attack the players if (GameObject* pClaw = m_pInstance->GetSingleGameObjectFromStorage(GO_RAVENS_CLAW)) { float fX, fY, fZ; for (uint8 i = 0; i < MAX_BROODS; ++i) { m_creature->GetRandomPoint(pClaw->GetPositionX(), pClaw->GetPositionY(), pClaw->GetPositionZ(), 7.0f, fX, fY, fZ); m_creature->SummonCreature(NPC_BROOD_OF_ANZU, fX, fY, fZ, 0, TEMPSUMMON_TIMED_OOC_OR_DEAD_DESPAWN, 30000); } } }
// Wrapper to activate dragon orbs void DoActivateDragonOrb(uint32 uiEntry) { if (!m_pInstance) { return; } // Set the visual around the Orb if (GameObject* pGo = m_pInstance->GetSingleGameObjectFromStorage(uiEntry)) { if (Creature* pTarget = GetClosestCreatureWithEntry(pGo, NPC_BLUE_ORB_TARGET, 5.0f)) { pTarget->CastSpell(pTarget, SPELL_RING_BLUE_FLAME, false); } } // Make the orb usable m_pInstance->DoToggleGameObjectFlags(uiEntry, GO_FLAG_NO_INTERACT, false); }
void JustDidDialogueStep(int32 iEntry) override { if (!m_pInstance) { return; } switch (iEntry) { case NPC_MADRIGOSA: if (Creature* pTrigger = m_pInstance->GetSingleCreatureFromStorage(NPC_FLIGHT_TRIGGER_LEFT)) { m_creature->SummonCreature(NPC_MADRIGOSA, pTrigger->GetPositionX(), pTrigger->GetPositionY(), pTrigger->GetPositionZ(), 0, TEMPSUMMON_DEAD_DESPAWN, 0); } m_bIsIntroInProgress = true; break; case YELL_MADR_ICE_BARRIER: if (Creature* pMadrigosa = m_pInstance->GetSingleCreatureFromStorage(NPC_MADRIGOSA)) #if defined (CLASSIC) || defined (TBC) { pMadrigosa->CastSpell(pMadrigosa, SPELL_FREEZE, true); } #endif #if defined (WOTLK) { pMadrigosa->CastSpell(pMadrigosa, SPELL_FREEZE, false); } #endif break; case YELL_MADR_INTRO: if (Creature* pMadrigosa = m_pInstance->GetSingleCreatureFromStorage(NPC_MADRIGOSA)) pMadrigosa->GetMotionMaster()->MovePoint(POINT_MOVE_GROUND, aMadrigosaLoc[0].m_fX, aMadrigosaLoc[0].m_fY, aMadrigosaLoc[0].m_fZ); break; case YELL_INTRO: if (Creature* pMadrigosa = m_pInstance->GetSingleCreatureFromStorage(NPC_MADRIGOSA)) { m_creature->AI()->AttackStart(pMadrigosa); } break; case SPELL_FROST_BREATH: if (Creature* pMadrigosa = m_pInstance->GetSingleCreatureFromStorage(NPC_MADRIGOSA)) { #if defined (CLASSIC) || defined (TBC) pMadrigosa->CastSpell(m_creature, SPELL_FROST_BREATH, true); #endif #if defined (WOTLK) { pMadrigosa->CastSpell(m_creature, SPELL_FROST_BREATH, false); } #endif pMadrigosa->GetMotionMaster()->MoveIdle(); } break; case POINT_MOVE_ICE_BLOCK: m_bCanDoMeleeAttack = false; if (Creature* pMadrigosa = m_pInstance->GetSingleCreatureFromStorage(NPC_MADRIGOSA)) { pMadrigosa->GetMotionMaster()->MovePoint(POINT_MOVE_ICE_BLOCK, aMadrigosaLoc[1].m_fX, aMadrigosaLoc[1].m_fY, aMadrigosaLoc[1].m_fZ); pMadrigosa->HandleEmote(EMOTE_ONESHOT_LIFTOFF); pMadrigosa->SetLevitate(true); } // Temporary! This will make Brutallus not follow Madrigosa through the air until mmaps are implemented m_creature->GetMotionMaster()->MoveIdle(); break; case YELL_MADR_ICE_BLOCK: if (Creature* pMadrigosa = m_pInstance->GetSingleCreatureFromStorage(NPC_MADRIGOSA)) { pMadrigosa->CastSpell(m_creature, SPELL_FROST_BLAST, true); } m_uiMadrigosaSpellTimer = 2000; break; case SPELL_FLAME_RING: DoCastSpellIfCan(m_creature, SPELL_CLEAR_DEBUFFS, CAST_TRIGGERED); DoCastSpellIfCan(m_creature, SPELL_FLAME_RING, CAST_TRIGGERED); break; case YELL_INTRO_BREAK_ICE: m_creature->RemoveAurasDueToSpell(SPELL_FLAME_RING); break; case SPELL_FEL_FIREBALL: // Spell has script target Madrigosa DoCastSpellIfCan(m_creature, SPELL_FEL_FIREBALL); break; case POINT_MOVE_GROUND: if (Creature* pMadrigosa = m_pInstance->GetSingleCreatureFromStorage(NPC_MADRIGOSA)) pMadrigosa->GetMotionMaster()->MovePoint(POINT_MOVE_GROUND, aMadrigosaLoc[0].m_fX, aMadrigosaLoc[0].m_fY, aMadrigosaLoc[0].m_fZ); m_uiMadrigosaSpellTimer = 0; break; case YELL_MADR_TRAP: if (Creature* pMadrigosa = m_pInstance->GetSingleCreatureFromStorage(NPC_MADRIGOSA)) { pMadrigosa->CastSpell(m_creature, SPELL_ENCAPSULATE, true); // Need to remove the fire aura after 4 sec so Madrigosa won't die so soon pMadrigosa->RemoveAurasDueToSpell(SPELL_FEL_FIREBALL); } break; case YELL_INTRO_CHARGE: m_bCanDoMeleeAttack = true; if (m_creature->getVictim()) { m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim()); } DoCastSpellIfCan(m_creature, SPELL_CHARGE); break; case YELL_INTRO_KILL_MADRIGOSA: // Face the players if (GameObject* pIceWall = m_pInstance->GetSingleGameObjectFromStorage(GO_ICE_BARRIER)) { m_creature->SetFacingToObject(pIceWall); } break; case YELL_INTRO_TAUNT: DoCastSpellIfCan(m_creature, SPELL_BREAK_ICE); m_bIsIntroInProgress = false; break; } }
void UpdateAI(const uint32 uiDiff) override { if (m_bEventMode) { if (!m_uiSpeechStep) return; if (m_uiSpeechTimer < uiDiff) { switch (m_uiSpeechStep) { case 1: DoScriptText(YELL_FENRUS, m_creature); m_creature->SetVisibility(VISIBILITY_ON); m_uiSpeechTimer = 2000; break; case 2: DoCastSpellIfCan(m_creature, SPELL_FIRE); m_uiSpeechTimer = 5000; break; case 3: if (m_pInstance) if (GameObject* pLightning = m_pInstance->GetSingleGameObjectFromStorage(GO_ARUGAL_FOCUS)) pLightning->Use(m_creature); m_uiSpeechTimer = 5000; break; case 4: m_creature->SetVisibility(VISIBILITY_OFF); m_uiSpeechTimer = 500; break; case 5: { Creature* pVoidwalker = NULL; Creature* pLeader = NULL; for (uint8 i = 0; i < 4; ++i) { pVoidwalker = m_creature->SummonCreature(NPC_VOIDWALKER, VWSpawns[i].fX, VWSpawns[i].fY, VWSpawns[i].fZ, VWSpawns[i].fO, TEMPSPAWN_DEAD_DESPAWN, 1); if (!pVoidwalker) continue; if (!i) pLeader = pVoidwalker; if (mob_arugal_voidwalkerAI* pVoidwalkerAI = dynamic_cast<mob_arugal_voidwalkerAI*>(pVoidwalker->AI())) pVoidwalkerAI->SetPosition(i, pLeader); pVoidwalker = NULL; } m_uiSpeechStep = 0; return; } default: m_uiSpeechStep = 0; return; } ++m_uiSpeechStep; } else m_uiSpeechTimer -= uiDiff; return; } // Check if we have a current target if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; if (GetManaPercent() < 6.0f && !m_bAttacking) { if (m_posPosition != POSITION_UPPER_LEDGE) StartAttacking(); else if (m_uiTeleportTimer > 2000) m_uiTeleportTimer = 2000; m_bAttacking = true; } else if (GetManaPercent() > 12.0f && m_bAttacking) { StopAttacking(); m_bAttacking = false; } if (m_uiYellTimer < uiDiff) { DoScriptText(YELL_COMBAT, m_creature); m_uiYellTimer = urand(34000, 68000); } else m_uiYellTimer -= uiDiff; if (m_uiCurseTimer < uiDiff) { if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 1)) DoCastSpellIfCan(pTarget, SPELL_ARUGALS_CURSE); m_uiCurseTimer = urand(20000, 35000); } else m_uiCurseTimer -= uiDiff; if (m_uiThundershockTimer < uiDiff) { if (GetVictimDistance() < 5.0f) { DoCastSpellIfCan(m_creature->getVictim(), SPELL_THUNDERSHOCK); m_uiThundershockTimer = urand(30200, 38500); } } else m_uiThundershockTimer -= uiDiff; if (m_uiVoidboltTimer < uiDiff) { if (!m_bAttacking) { DoCastSpellIfCan(m_creature->getVictim(), SPELL_VOID_BOLT); m_uiVoidboltTimer = urand(2900, 4800); } } else m_uiVoidboltTimer -= uiDiff; if (m_uiTeleportTimer < uiDiff) { ArugalPosition posNewPosition; if (m_posPosition == POSITION_SPAWN_LEDGE) posNewPosition = (ArugalPosition)urand(1, 2); else { posNewPosition = (ArugalPosition)urand(0, 1); if (m_posPosition == posNewPosition) posNewPosition = POSITION_STAIRS; } if (m_creature->IsNonMeleeSpellCasted(false)) m_creature->InterruptNonMeleeSpells(false); switch (posNewPosition) { case POSITION_SPAWN_LEDGE: DoCastSpellIfCan(m_creature, SPELL_SHADOW_PORT_SPAWN_LEDGE, true); break; case POSITION_UPPER_LEDGE: DoCastSpellIfCan(m_creature, SPELL_SHADOW_PORT_UPPER_LEDGE, true); break; case POSITION_STAIRS: DoCastSpellIfCan(m_creature, SPELL_SHADOW_PORT_STAIRS, true); break; } if (GetManaPercent() < 6.0f) { if (posNewPosition == POSITION_UPPER_LEDGE) { StopAttacking(); m_uiTeleportTimer = urand(2000, 2200); } else { StartAttacking(); m_uiTeleportTimer = urand(48000, 55000); } } else m_uiTeleportTimer = urand(48000, 55000); m_posPosition = posNewPosition; } else m_uiTeleportTimer -= uiDiff; if (m_bAttacking) DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 uiDiff) override { // Handling of his combat-end speech and Ragnaros summoning if (m_uiSpeech) { if (m_uiSpeechTimer < uiDiff) { switch (m_uiSpeech) { // Majordomo retreat event case 1: DoScriptText(SAY_DEFEAT_1, m_creature); m_uiSpeechTimer = 7500; ++m_uiSpeech; break; case 2: DoScriptText(SAY_DEFEAT_2, m_creature); m_uiSpeechTimer = 8000; ++m_uiSpeech; break; case 3: DoScriptText(SAY_DEFEAT_3, m_creature); m_uiSpeechTimer = 21500; ++m_uiSpeech; break; case 4: DoCastSpellIfCan(m_creature, SPELL_TELEPORT_SELF); // TODO - when should they be unsummoned? // TODO - also unclear how this should be handled, as of range issues m_uiSpeechTimer = 900; ++m_uiSpeech; break; case 5: // Majordomo is away now, remove his adds UnsummonMajordomoAdds(); m_uiSpeech = 0; break; // Ragnaros Summon Event case 10: DoScriptText(SAY_SUMMON_1, m_creature); ++m_uiSpeech; m_uiSpeechTimer = 1000; break; case 11: DoCastSpellIfCan(m_creature, SPELL_SUMMON_RAGNAROS); // TODO - Move along, this expects to be handled with mmaps m_creature->GetMotionMaster()->MovePoint(1, 831.079590f, -816.023193f, -229.023270f); ++m_uiSpeech; m_uiSpeechTimer = 7000; break; case 12: // Reset orientation if (GameObject* pLavaSteam = m_pInstance->GetSingleGameObjectFromStorage(GO_LAVA_STEAM)) { m_creature->SetFacingToObject(pLavaSteam); } m_uiSpeechTimer = 4500; ++m_uiSpeech; break; case 13: DoScriptText(SAY_SUMMON_MAJ, m_creature); ++m_uiSpeech; m_uiSpeechTimer = 8000; break; case 14: // Summon Ragnaros if (m_pInstance) if (GameObject* pGo = m_pInstance->GetSingleGameObjectFromStorage(GO_LAVA_STEAM)) { m_creature->SummonCreature(NPC_RAGNAROS, pGo->GetPositionX(), pGo->GetPositionY(), pGo->GetPositionZ(), fmod(m_creature->GetOrientation() + M_PI, 2 * M_PI), TEMPSUMMON_TIMED_OOC_OR_DEAD_DESPAWN, 2 * HOUR * IN_MILLISECONDS); } ++m_uiSpeech; m_uiSpeechTimer = 8700; break; case 15: if (Creature* pRagnaros = m_creature->GetMap()->GetCreature(m_ragnarosGuid)) { DoScriptText(SAY_ARRIVAL1_RAG, pRagnaros); } ++m_uiSpeech; m_uiSpeechTimer = 11700; break; case 16: DoScriptText(SAY_ARRIVAL2_MAJ, m_creature); ++m_uiSpeech; m_uiSpeechTimer = 8700; break; case 17: if (Creature* pRagnaros = m_creature->GetMap()->GetCreature(m_ragnarosGuid)) { DoScriptText(SAY_ARRIVAL3_RAG, pRagnaros); } ++m_uiSpeech; m_uiSpeechTimer = 16500; break; case 18: if (Creature* pRagnaros = m_creature->GetMap()->GetCreature(m_ragnarosGuid)) { pRagnaros->CastSpell(m_creature, SPELL_ELEMENTAL_FIRE, false); } // Rest of summoning speech is handled by Ragnaros, as Majordomo will be dead m_uiSpeech = 0; break; } } else { m_uiSpeechTimer -= uiDiff; } } // When encounter finished, no need to do anything anymore (important for moving home after victory) if (m_bHasEncounterFinished) { return; } if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) { return; } // Cast Ageis to heal self if (m_uiAegisTimer <= uiDiff) { m_uiAegisTimer = 0; } else { m_uiAegisTimer -= uiDiff; } if (m_creature->GetHealthPercent() < 90.0f && !m_uiAegisTimer) { DoCastSpellIfCan(m_creature, SPELL_AEGIS); m_uiAegisTimer = 10000; } // Magic Reflection Timer if (m_uiMagicReflectionTimer < uiDiff) { if (DoCastSpellIfCan(m_creature, SPELL_MAGIC_REFLECTION) == CAST_OK) { m_uiMagicReflectionTimer = 30000; } } else { m_uiMagicReflectionTimer -= uiDiff; } // Damage Reflection Timer if (m_uiDamageReflectionTimer < uiDiff) { if (DoCastSpellIfCan(m_creature, SPELL_DAMAGE_REFLECTION) == CAST_OK) { m_uiDamageReflectionTimer = 30000; } } else { m_uiDamageReflectionTimer -= uiDiff; } // Teleports the target to the heated rock in the center of the area if (m_uiTeleportTimer < uiDiff) { if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 1)) { if (DoCastSpellIfCan(pTarget, SPELL_TELEPORT) == CAST_OK) { m_uiTeleportTimer = 20000; } } } else { m_uiTeleportTimer -= uiDiff; } // Blastwave Timer if (m_uiBlastwaveTimer < uiDiff) { if (DoCastSpellIfCan(m_creature, SPELL_BLASTWAVE) == CAST_OK) { m_uiBlastwaveTimer = 10000; } } else { m_uiBlastwaveTimer -= uiDiff; } DoMeleeAttackIfReady(); }
void DoGo(uint32 id, uint32 state) { if (GameObject* pGo = m_pInstance->GetSingleGameObjectFromStorage(id)) pGo->SetGoState(GOState(state)); }