void AddJustAggroed(Unit* pWho) { // Let all adds attack for (GuidVector::const_iterator itr = m_vAddGuids.begin(); itr != m_vAddGuids.end(); ++itr) { Creature* pAdd = m_creature->GetMap()->GetCreature(*itr); if (pAdd && !pAdd->getVictim()) pAdd->AI()->AttackStart(pWho); } }
// Note: this should be done by creature linkin in core void DoDespawnAdds() { for (GuidVector::const_iterator itr = m_vAddGuids.begin(); itr != m_vAddGuids.end(); ++itr) { if (Creature* pTemp = m_creature->GetMap()->GetCreature(*itr)) { pTemp->ForcedDespawn(); } } m_vAddGuids.clear(); for (GuidVector::const_iterator itr = m_vAssassinGuids.begin(); itr != m_vAssassinGuids.end(); ++itr) { if (Creature* pTemp = m_creature->GetMap()->GetCreature(*itr)) { pTemp->ForcedDespawn(); } } m_vAssassinGuids.clear(); }
void CastBunnySpell(Creature* pTarget, uint32 uSpell) { if (!uSpell) return; std::list<Creature*> creatureList; GetCreatureListWithEntryInGrid(creatureList, m_creature, NPC_VIMGOL_VISUAL_BUNNY, 200.0f); for (auto& bunny : creatureList) for (auto it = m_uiBunnyGuids.begin(); it != m_uiBunnyGuids.end(); ++it) if ((*it) == bunny->GetObjectGuid()) if (m_uiActiveCircles[std::distance(m_uiBunnyGuids.begin(), it)]) bunny->CastSpell(pTarget ? pTarget : bunny, uSpell, TRIGGERED_OLD_TRIGGERED); }
void Cleanup(Creature* infernal, InfernalPoint *point) { for (GuidVector::iterator itr = infernals.begin(); itr!= infernals.end(); ++itr) { if (*itr == infernal->GetGUID()) { infernals.erase(itr); break; } } positions.push_back(point); }
void InfernalCleanup() { //Infernal Cleanup for (GuidVector::const_iterator itr = infernals.begin(); itr != infernals.end(); ++itr) if (Unit* pInfernal = ObjectAccessor::GetUnit(*me, *itr)) if (pInfernal->IsAlive()) { pInfernal->SetVisible(false); pInfernal->setDeathState(JUST_DIED); } infernals.clear(); }
void JustDied(Unit* /*pKiller*/) override { for (GuidVector::const_iterator itr = m_vSnoboldGuidsVector.begin(); itr != m_vSnoboldGuidsVector.end(); ++itr) { if (Creature* pSnobold = m_creature->GetMap()->GetCreature(*itr)) { if (!pSnobold->isAlive()) continue; // ToDo: check if there is any player vehicle mounting involved SendAIEvent(AI_EVENT_CUSTOM_EVENTAI_A, m_creature, pSnobold); } } }
void DoSetupAdds() { m_uiSetupAddsTimer = 0; if (!m_pInstance) return; GuidList lAddGuids; m_pInstance->GetKelidanAddList(lAddGuids); // Sort Adds to vector if not already done if (!lAddGuids.empty()) { m_vAddGuids.reserve(lAddGuids.size()); std::list<Creature*> lAdds; for (GuidList::const_iterator itr = lAddGuids.begin(); itr != lAddGuids.end(); ++itr) { if (Creature* pAdd = m_pInstance->instance->GetCreature(*itr)) lAdds.push_back(pAdd); } // Sort them by angle lAdds.sort(SortByAngle(m_creature)); for (std::list<Creature*>::const_iterator itr = lAdds.begin(); itr != lAdds.end(); ++itr) m_vAddGuids.push_back((*itr)->GetObjectGuid()); } // Respawn killed adds and reset counter m_uiKilledAdds = 0; for (GuidVector::const_iterator itr = m_vAddGuids.begin(); itr != m_vAddGuids.end(); ++itr) { Creature* pAdd = m_pInstance->instance->GetCreature(*itr); if (pAdd && !pAdd->isAlive()) pAdd->Respawn(); } // Cast pentagram uint8 s = m_vAddGuids.size(); for (uint8 i = 0; i < s; ++i) { Creature* pCaster = m_pInstance->instance->GetCreature(m_vAddGuids[i]); Creature* pTarget = m_pInstance->instance->GetCreature(m_vAddGuids[(i + 2) % s]); if (pCaster && pTarget) pCaster->CastSpell(pTarget, SPELL_CHANNELING, TRIGGERED_NONE); } m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_NPC); }
// Wrapper to remove Gravity Lapse - this should be removed on aura 44251 expires void RemoveGravityLapse() { GuidVector vGuids; m_creature->FillGuidsListFromThreatList(vGuids); for (GuidVector::const_iterator itr = vGuids.begin(); itr != vGuids.end(); ++itr) { Unit* pUnit = m_creature->GetMap()->GetUnit(*itr); if (pUnit && pUnit->GetTypeId() == TYPEID_PLAYER) { pUnit->RemoveAurasDueToSpell(SPELL_GRAVITY_LAPSE_FLY); pUnit->RemoveAurasDueToSpell(SPELL_GRAVITY_LAPSE_DOT); } } }
npc_vimgol_visual_bunnyAI(Creature* pCreature) : ScriptedAI(pCreature) { m_pMap = (ScriptedMap*)pCreature->GetInstanceData(); GuidVector bunnyGuids; if (m_pMap) { m_pMap->GetCreatureGuidVectorFromStorage(m_creature->GetEntry(), bunnyGuids); for (auto it = bunnyGuids.begin(); it != bunnyGuids.end(); ++it) if ((*it) == m_creature->GetObjectGuid()) m_uiBunnyId = std::distance(bunnyGuids.begin(), it); } Reset(); }
uint8 playersInsideCircles() { uint32 tmpAuras[5] = { SPELL_VIMGOL_POP_TEST_A, SPELL_VIMGOL_POP_TEST_B, SPELL_VIMGOL_POP_TEST_C, SPELL_VIMGOL_POP_TEST_D, SPELL_VIMGOL_POP_TEST_E }; uint8 tmpCounter = 0; if (m_uiBunnyGuids.size() < 5 && m_pMap) { m_uiBunnyGuids.clear(); m_pMap->GetCreatureGuidVectorFromStorage(NPC_VIMGOL_VISUAL_BUNNY, m_uiBunnyGuids); } for (int i = 0; i < 5; i++) m_uiActiveCircles[i] = false; std::list<Player*> playerList; GetPlayerListWithEntryInWorld(playerList, m_creature, 30); for (auto itr = playerList.begin(); itr != playerList.end(); ++itr) { if (!(*itr)->HasAura(SPELL_VIMGOL_POP_TEST_A) && !(*itr)->HasAura(SPELL_VIMGOL_POP_TEST_B) && !(*itr)->HasAura(SPELL_VIMGOL_POP_TEST_C) && !(*itr)->HasAura(SPELL_VIMGOL_POP_TEST_D) && !(*itr)->HasAura(SPELL_VIMGOL_POP_TEST_E)) continue; for (auto it = m_uiBunnyGuids.begin(); it != m_uiBunnyGuids.end(); ++it) { for (int i = 0; i < 5; ++i) { if (!(*itr)->GetAura(tmpAuras[i], SpellEffectIndex(0))) continue; if ((*it) != (*itr)->GetAura(tmpAuras[i], SpellEffectIndex(0))->GetCasterGuid()) continue; m_uiActiveCircles[std::distance(m_uiBunnyGuids.begin(), it)] = true; } } } for (int i = 0; i < 5; i++) if (m_uiActiveCircles[i]) ++tmpCounter; return tmpCounter; }
// Wrapper to teleport all players to the platform - Workaround for missing spell void DoTeleportToPlatform() { m_creature->NearTeleportTo(aVorpilTeleportLoc[0], aVorpilTeleportLoc[1], aVorpilTeleportLoc[2], 0.0f); float fX, fY, fZ; GuidVector vGuids; m_creature->FillGuidsListFromThreatList(vGuids); for (GuidVector::const_iterator itr = vGuids.begin(); itr != vGuids.end(); ++itr) { Unit* pTarget = m_creature->GetMap()->GetUnit(*itr); if (pTarget && pTarget->GetTypeId() == TYPEID_PLAYER) { pTarget->GetRandomPoint(aVorpilTeleportLoc[0], aVorpilTeleportLoc[1], aVorpilTeleportLoc[2], 4.0f, fX, fY, fZ); DoTeleportPlayer(pTarget, fX, fY, fZ, m_creature->GetAngle(fX, fY)); } } }
void UpdateAI(const uint32 uiDiff) override { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; // Shimmer Timer Timer if (m_uiShimmerTimer < uiDiff) { // Remove old vulnerability spell if (m_uiCurrentVulnerabilitySpell) m_creature->RemoveAurasDueToSpell(m_uiCurrentVulnerabilitySpell); // Cast new random vurlnabilty on self uint32 aSpellId[] = {SPELL_FIRE_VULNERABILITY, SPELL_FROST_VULNERABILITY, SPELL_SHADOW_VULNERABILITY, SPELL_NATURE_VULNERABILITY, SPELL_ARCANE_VULNERABILITY}; uint32 uiSpell = aSpellId[urand(0, 4)]; if (DoCastSpellIfCan(m_creature, uiSpell) == CAST_OK) { m_uiCurrentVulnerabilitySpell = uiSpell; DoScriptText(EMOTE_SHIMMER, m_creature); m_uiShimmerTimer = 45000; } } else m_uiShimmerTimer -= uiDiff; // Breath One Timer if (m_uiBreathOneTimer < uiDiff) { if (DoCastSpellIfCan(m_creature, m_uiBreathOneSpell) == CAST_OK) m_uiBreathOneTimer = 60000; } else m_uiBreathOneTimer -= uiDiff; // Breath Two Timer if (m_uiBreathTwoTimer < uiDiff) { if (DoCastSpellIfCan(m_creature, m_uiBreathTwoSpell) == CAST_OK) m_uiBreathTwoTimer = 60000; } else m_uiBreathTwoTimer -= uiDiff; // Affliction Timer if (m_uiAfflictionTimer < uiDiff) { uint32 m_uiSpellAfflict = 0; switch (urand(0, 4)) { case 0: m_uiSpellAfflict = SPELL_BROODAF_BLUE; break; case 1: m_uiSpellAfflict = SPELL_BROODAF_BLACK; break; case 2: m_uiSpellAfflict = SPELL_BROODAF_RED; break; case 3: m_uiSpellAfflict = SPELL_BROODAF_BRONZE; break; case 4: m_uiSpellAfflict = SPELL_BROODAF_GREEN; break; } GuidVector vGuids; m_creature->FillGuidsListFromThreatList(vGuids); for (GuidVector::const_iterator i = vGuids.begin(); i != vGuids.end(); ++i) { Unit* pUnit = m_creature->GetMap()->GetUnit(*i); if (pUnit) { // Cast affliction DoCastSpellIfCan(pUnit, m_uiSpellAfflict, CAST_TRIGGERED); // Chromatic mutation if target is effected by all afflictions if (pUnit->HasAura(SPELL_BROODAF_BLUE, EFFECT_INDEX_0) && pUnit->HasAura(SPELL_BROODAF_BLACK, EFFECT_INDEX_0) && pUnit->HasAura(SPELL_BROODAF_RED, EFFECT_INDEX_0) && pUnit->HasAura(SPELL_BROODAF_BRONZE, EFFECT_INDEX_0) && pUnit->HasAura(SPELL_BROODAF_GREEN, EFFECT_INDEX_0)) { // target->RemoveAllAuras(); // DoCastSpellIfCan(target,SPELL_CHROMATIC_MUT_1); // Chromatic mutation is causing issues // Assuming it is caused by a lack of core support for Charm // So instead we instant kill our target // WORKAROUND if (pUnit->GetTypeId() == TYPEID_PLAYER) m_creature->CastSpell(pUnit, 5, false); } } } m_uiAfflictionTimer = 10000; } else m_uiAfflictionTimer -= uiDiff; // Frenzy Timer if (m_uiFrenzyTimer < uiDiff) { if (DoCastSpellIfCan(m_creature, SPELL_FRENZY) == CAST_OK) { DoScriptText(EMOTE_GENERIC_FRENZY_KILL, m_creature); m_uiFrenzyTimer = urand(10000, 15000); } } else m_uiFrenzyTimer -= uiDiff; // Enrage if not already enraged and below 20% if (!m_bEnraged && m_creature->GetHealthPercent() < 20.0f) { DoCastSpellIfCan(m_creature, SPELL_ENRAGE); m_bEnraged = true; } DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 uiDiff) override { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; // When Solarian reaches 20% she will transform into a huge void walker. if (m_Phase != PHASE_VOID && m_creature->GetHealthPercent() < 20.0f) { if (DoCastSpellIfCan(m_creature, SPELL_SOLARIAN_TRANSFORM) == CAST_OK) { DoScriptText(SAY_VOIDA, m_creature); m_uiDelayTimer = 2000; m_creature->SetArmor(WV_ARMOR); m_Phase = PHASE_VOID; if (m_creature->GetVisibility() != VISIBILITY_ON) m_creature->SetVisibility(VISIBILITY_ON); // Stop the combat for a small delay SetCombatMovement(false); m_creature->GetMotionMaster()->MoveIdle(); } } // Handle delays between combat phases if (m_uiDelayTimer) { if (m_uiDelayTimer <= uiDiff) { if (m_Phase == PHASE_SPLIT) { // select two different numbers between 0 and 7 so we will get different spawn points for the spotlights uint8 uiPos1 = urand(0, 7); uint8 uiPos2 = (uiPos1 + urand(1, 7)) % 8; // summon 3 spotlights m_vSpotLightsGuidVector.clear(); DoSummonSpotlight(fSpotlightRadius[0], M_PI_F / 2, urand(0, 3)); DoSummonSpotlight(fSpotlightRadius[1], M_PI_F / 4, uiPos1); DoSummonSpotlight(fSpotlightRadius[1], M_PI_F / 4, uiPos2); m_creature->SetVisibility(VISIBILITY_OFF); DoScriptText(urand(0, 1) ? SAY_SUMMON1 : SAY_SUMMON2, m_creature); m_uiSummonAgentsTimer = 5000; } else if (m_Phase == PHASE_VOID) { DoScriptText(SAY_VOIDB, m_creature); SetCombatMovement(true); m_creature->GetMotionMaster()->Clear(); m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim()); } m_uiDelayTimer = 0; } else m_uiDelayTimer -= uiDiff; // Combat is still on hold return; } switch (m_Phase) { case PHASE_NORMAL: // Phase 1 Timer if (m_uiSplitTimer <= uiDiff) { m_Phase = PHASE_SPLIT; // After these 50 seconds she portals to the middle of the room and disappears, leaving 3 light portals behind. // ToDo: check if there are some spells involved in this event! m_creature->GetMotionMaster()->MoveIdle(); SetCombatMovement(false); m_creature->NearTeleportTo(fRoomCenter[0], fRoomCenter[1], fRoomCenter[2], fRoomCenter[3], true); m_uiDelayTimer = 1000; m_uiSplitTimer = 75000; // Do nothing more, if phase switched return; } else m_uiSplitTimer -= uiDiff; // Wrath of the Astromancer targets a random player which will explode after 6 secondes if (m_uiWrathOfTheAstromancerTimer <= uiDiff) { // Target the tank ? if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 1, SPELL_WRATH_OF_THE_ASTROMANCER, SELECT_FLAG_PLAYER)) { if (DoCastSpellIfCan(pTarget, SPELL_WRATH_OF_THE_ASTROMANCER) == CAST_OK) m_uiWrathOfTheAstromancerTimer = urand(12000, 18000); } else m_uiWrathOfTheAstromancerTimer = 10000; } else m_uiWrathOfTheAstromancerTimer -= uiDiff; // Blinding Light Timer if (m_uiBlindingLightTimer <= uiDiff) { // She casts this spell every 45 seconds. It is a kind of Moonfire spell, which she strikes down on the whole raid simultaneously. It hits everyone in the raid for 2280 to 2520 arcane damage. if (DoCastSpellIfCan(m_creature, SPELL_BLINDING_LIGHT) == CAST_OK && DoCastSpellIfCan(m_creature, SPELL_MARK_OF_SOLARIAN) == CAST_OK) m_uiBlindingLightTimer = 20000; } else m_uiBlindingLightTimer -= uiDiff; // Arcane Missiles Timer if (m_uiArcaneMissilesTimer <= uiDiff) { // Solarian casts Arcane Missiles on on random targets in the raid. if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0, SPELL_ARCANE_MISSILES, SELECT_FLAG_PLAYER)) { DoCastSpellIfCan(pTarget, SPELL_ARCANE_MISSILES); m_uiArcaneMissilesTimer = urand(3000, 3500); return; } } else m_uiArcaneMissilesTimer -= uiDiff; DoMeleeAttackIfReady(); break; case PHASE_SPLIT: // Summon 4 Agents on each portal if (m_uiSummonAgentsTimer) { if (m_uiSummonAgentsTimer <= uiDiff) { for (uint8 i = 0; i < MAX_SPOTLIGHTS; ++i) { if (Creature* pSpotlight = m_creature->GetMap()->GetCreature(m_vSpotLightsGuidVector[i])) { for (uint8 j = 0; j < MAX_AGENTS; ++j) m_creature->SummonCreature(NPC_SOLARIUM_AGENT, pSpotlight->GetPositionX(), pSpotlight->GetPositionY(), pSpotlight->GetPositionZ(), 0, TEMPSPAWN_DEAD_DESPAWN, 0); } } m_uiSummonAgentsTimer = 0; m_uiSummonPriestsTimer = 16000; } else m_uiSummonAgentsTimer -= uiDiff; } if (m_uiSummonPriestsTimer) { if (m_uiSummonPriestsTimer <= uiDiff) { m_Phase = PHASE_NORMAL; // Randomize the portals std::random_shuffle(m_vSpotLightsGuidVector.begin(), m_vSpotLightsGuidVector.end()); // Summon 2 priests for (uint8 i = 0; i < 2; ++i) { if (Creature* pSpotlight = m_creature->GetMap()->GetCreature(m_vSpotLightsGuidVector[i])) m_creature->SummonCreature(NPC_SOLARIUM_PRIEST, pSpotlight->GetPositionX(), pSpotlight->GetPositionY(), pSpotlight->GetPositionZ(), 0, TEMPSPAWN_DEAD_DESPAWN, 0); } // Teleport the boss at the last portal if (Creature* pSpotlight = m_creature->GetMap()->GetCreature(m_vSpotLightsGuidVector[2])) m_creature->NearTeleportTo(pSpotlight->GetPositionX(), pSpotlight->GetPositionY(), pSpotlight->GetPositionZ(), pSpotlight->GetOrientation(), true); SetCombatMovement(true); m_creature->GetMotionMaster()->Clear(); m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim()); // Set as visible and reset spells timers m_creature->SetVisibility(VISIBILITY_ON); m_uiArcaneMissilesTimer = 0; m_uiSummonPriestsTimer = 0; m_uiBlindingLightTimer = 20000; m_uiWrathOfTheAstromancerTimer = urand(20000, 25000); } else m_uiSummonPriestsTimer -= uiDiff; } break; case PHASE_VOID: // Fear Timer if (m_uiFearTimer <= uiDiff) { if (DoCastSpellIfCan(m_creature, SPELL_PSYHIC_SCREAM) == CAST_OK) m_uiFearTimer = 20000; } else m_uiFearTimer -= uiDiff; // Void Bolt Timer if (m_uiVoidBoltTimer <= uiDiff) { if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_VOID_BOLT) == CAST_OK) m_uiVoidBoltTimer = 10000; } else m_uiVoidBoltTimer -= uiDiff; DoMeleeAttackIfReady(); break; } }
void SummonedCreatureJustDied(Creature* summoned) override { m_skeletons.erase(std::remove(m_skeletons.begin(), m_skeletons.end(), summoned->GetObjectGuid()), m_skeletons.end()); }
void UpdateAI(const uint32 uiDiff) override { if (m_uiInciteChaosWaitTimer) { if (m_uiInciteChaosWaitTimer <= uiDiff) { // Restart attack on all targets for (GuidVector::const_iterator itr = m_vTargetsGuids.begin(); itr != m_vTargetsGuids.end(); ++itr) { if (Unit* pTarget = m_creature->GetMap()->GetUnit(*itr)) AttackStart(pTarget); } m_creature->HandleEmote(EMOTE_STATE_NONE); m_uiInciteChaosWaitTimer = 0; } else m_uiInciteChaosWaitTimer -= uiDiff; } // Return since we have no pTarget if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; if (m_uiInciteChaosTimer < uiDiff) { // Store the threat list m_vTargetsGuids.clear(); m_creature->FillGuidsListFromThreatList(m_vTargetsGuids); if (DoCastSpellIfCan(m_creature, SPELL_INCITE_CHAOS) == CAST_OK) { m_creature->HandleEmote(EMOTE_STATE_LAUGH); m_uiInciteChaosTimer = 55000; m_uiInciteChaosWaitTimer = 16000; return; } } else m_uiInciteChaosTimer -= uiDiff; // Charge Timer if (m_uiChargeTimer < uiDiff) { if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 1, SPELL_CHARGE, SELECT_FLAG_NOT_IN_MELEE_RANGE)) { if (DoCastSpellIfCan(pTarget, SPELL_CHARGE) == CAST_OK) m_uiChargeTimer = urand(30000, 43000); } } else m_uiChargeTimer -= uiDiff; // Knockback Timer if (m_uiKnockbackTimer < uiDiff) { if (DoCastSpellIfCan(m_creature, SPELL_WAR_STOMP) == CAST_OK) m_uiKnockbackTimer = urand(15000, 30000); } else m_uiKnockbackTimer -= uiDiff; DoMeleeAttackIfReady(); }