Unit* instance_naxxramas::SelectRandomTargetOnSide(bool bRight, const WorldObject & object) { Map::PlayerList const& lPlayers = instance->GetPlayers(); std::list<uint64> lTargets; if (lPlayers.isEmpty() ) return NULL; for (Map::PlayerList::const_iterator itr = lPlayers.begin(); itr != lPlayers.end(); ++itr) if (Player* pPlayer = itr->getSource() ) if ( (IsInRightSideGothArea(pPlayer) && bRight) || (!IsInRightSideGothArea(pPlayer) && !bRight) ) lTargets.push_back(pPlayer->GetGUID() ); // choose random player from those on the Gothik's right side if (lTargets.empty() ) return NULL; std::list<uint64>::iterator itrGUID = lTargets.begin(); advance(itrGUID, (rand()%lTargets.size()) ); if (Unit* pTarget = Unit::GetUnit(object, *itrGUID)) return pTarget; return NULL; }
bool HasPlayersInLeftSide() { Map::PlayerList const& lPlayers = m_pInstance->instance->GetPlayers(); if (lPlayers.isEmpty()) return false; for (Map::PlayerList::const_iterator itr = lPlayers.begin(); itr != lPlayers.end(); ++itr) { if (Player* pPlayer = itr->getSource()) { if (!IsInRightSideGothArea(pPlayer) && pPlayer->IsAlive()) return true; } } return false; }
void instance_naxxramas::SetGothTriggers() { Creature* pGoth = instance->GetCreature(m_uiGothikGUID); if (!pGoth) return; for(std::list<uint64>::iterator itr = m_lGothTriggerList.begin(); itr != m_lGothTriggerList.end(); ++itr) { if (Creature* pTrigger = instance->GetCreature(*itr)) { GothTrigger pGt; pGt.bIsAnchorHigh = (pTrigger->GetPositionZ() >= (pGoth->GetPositionZ() - 5.0f)); pGt.bIsRightSide = IsInRightSideGothArea(pTrigger); m_mGothTriggerMap[pTrigger->GetGUID()] = pGt; } } }
void instance_naxxramas::SetGothTriggers() { Creature* pGoth = GetSingleCreatureFromStorage(NPC_GOTHIK); if (!pGoth) return; for(GUIDList::const_iterator itr = m_lGothTriggerList.begin(); itr != m_lGothTriggerList.end(); ++itr) { if (Creature* pTrigger = instance->GetCreature(*itr)) { GothTrigger pGt; pGt.bIsAnchorHigh = (pTrigger->GetPositionZ() >= (pGoth->GetPositionZ() - 5.0f)); pGt.bIsRightSide = IsInRightSideGothArea(pTrigger); m_mGothTriggerMap[pTrigger->GetObjectGuid()] = pGt; } } }
void UpdateAI(const uint32 uiDiff) override { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; switch (m_uiPhase) { case PHASE_SPEECH: if (m_uiSpeechTimer < uiDiff) { switch (m_uiSpeech) { case 1: DoScriptText(SAY_SPEECH_1, m_creature); m_uiSpeechTimer = 4 * IN_MILLISECONDS; break; case 2: DoScriptText(SAY_SPEECH_2, m_creature); m_uiSpeechTimer = 6 * IN_MILLISECONDS; break; case 3: DoScriptText(SAY_SPEECH_3, m_creature); m_uiSpeechTimer = 5 * IN_MILLISECONDS; break; case 4: DoScriptText(SAY_SPEECH_4, m_creature); m_uiPhase = PHASE_BALCONY; break; } m_uiSpeech++; } else m_uiSpeechTimer -= uiDiff; // No break here case PHASE_BALCONY: // Do summoning if (m_uiTraineeTimer < uiDiff) { if (m_pInstance) m_pInstance->SetData(TYPE_DO_GOTH_SUMMON, NPC_UNREL_TRAINEE); m_uiTraineeTimer = 20 * IN_MILLISECONDS; } else m_uiTraineeTimer -= uiDiff; if (m_uiDeathKnightTimer < uiDiff) { if (m_pInstance) m_pInstance->SetData(TYPE_DO_GOTH_SUMMON, NPC_UNREL_DEATH_KNIGHT); m_uiDeathKnightTimer = 25 * IN_MILLISECONDS; } else m_uiDeathKnightTimer -= uiDiff; if (m_uiRiderTimer < uiDiff) { if (m_pInstance) m_pInstance->SetData(TYPE_DO_GOTH_SUMMON, NPC_UNREL_RIDER); m_uiRiderTimer = 30 * IN_MILLISECONDS; } else m_uiRiderTimer -= uiDiff; if (m_uiPhaseTimer < uiDiff) { m_uiPhase = PHASE_STOP_SUMMONING; m_uiPhaseTimer = 27 * IN_MILLISECONDS; } else m_uiPhaseTimer -= uiDiff; break; case PHASE_STOP_SUMMONING: if (m_uiPhaseTimer < uiDiff) { if (DoCastSpellIfCan(m_creature, SPELL_TELEPORT_RIGHT, CAST_TRIGGERED) == CAST_OK) { m_uiPhase = m_pInstance ? PHASE_TELEPORTING : PHASE_STOP_TELEPORTING; DoScriptText(SAY_TELEPORT, m_creature); DoScriptText(EMOTE_TO_FRAY, m_creature); // Remove Immunity m_creature->ApplySpellImmune(0, IMMUNITY_DAMAGE, SPELL_SCHOOL_MASK_ALL, false); DoResetThreat(); m_creature->SetInCombatWithZone(); } } else m_uiPhaseTimer -= uiDiff; break; case PHASE_TELEPORTING: // Phase is only reached if m_pInstance is valid if (m_uiTeleportTimer < uiDiff) { uint32 uiTeleportSpell = IsInRightSideGothArea(m_creature) ? SPELL_TELEPORT_LEFT : SPELL_TELEPORT_RIGHT; if (DoCastSpellIfCan(m_creature, uiTeleportSpell) == CAST_OK) { m_uiTeleportTimer = 20 * IN_MILLISECONDS; m_uiShadowboltTimer = 2 * IN_MILLISECONDS; } } else m_uiTeleportTimer -= uiDiff; if (m_creature->GetHealthPercent() <= 30.0f) { m_uiPhase = PHASE_STOP_TELEPORTING; ProcessCentralDoor(); // as the doors now open, recheck whether mobs are standing around m_uiControlZoneTimer = 1; } // no break here case PHASE_STOP_TELEPORTING: if (m_uiHarvestSoulTimer < uiDiff) { if (DoCastSpellIfCan(m_creature, SPELL_HARVESTSOUL) == CAST_OK) m_uiHarvestSoulTimer = 15 * IN_MILLISECONDS; } else m_uiHarvestSoulTimer -= uiDiff; if (m_uiShadowboltTimer) { if (m_uiShadowboltTimer <= uiDiff) m_uiShadowboltTimer = 0; else m_uiShadowboltTimer -= uiDiff; } // Shadowbold cooldown finished, cast when ready else if (!m_creature->IsNonMeleeSpellCasted(true)) { // Select valid target if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_TOPAGGRO, 0, SPELL_SHADOWBOLT, SELECT_FLAG_IN_LOS)) DoCastSpellIfCan(pTarget, m_bIsRegularMode ? SPELL_SHADOWBOLT : SPELL_SHADOWBOLT_H); } break; } // Control Check, if Death zone empty if (m_uiControlZoneTimer) { if (m_uiControlZoneTimer <= uiDiff) { m_uiControlZoneTimer = 0; if (m_pInstance && !HasPlayersInLeftSide()) { ProcessCentralDoor(); for (GuidList::const_iterator itr = m_lSummonedAddGuids.begin(); itr != m_lSummonedAddGuids.end(); itr++) { if (Creature* pCreature = m_pInstance->instance->GetCreature(*itr)) { if (!pCreature->IsInCombat()) pCreature->SetInCombatWithZone(); } } } } else m_uiControlZoneTimer -= uiDiff; } }