void UpdateAI(const uint32 uiDiff) { //Return since we have no target if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; if (m_uiPhase == PHASE_1 || m_uiPhase == PHASE_3) { //m_uiShockBlast_Timer if (m_uiShockBlast_Timer < uiDiff) { //Randomly used in m_uiPhases 1 and 3 on Vashj's target, it's a Shock spell doing 8325-9675 nature damage and stunning the target for 5 seconds, during which she will not attack her target but switch to the next person on the aggro list. DoCastSpellIfCan(m_creature->getVictim(), SPELL_SHOCK_BLAST); m_uiShockBlast_Timer = urand(1000, 15000); //random cooldown }else m_uiShockBlast_Timer -= uiDiff; //m_uiStaticCharge_Timer if (m_uiStaticCharge_Timer < uiDiff) { //Used on random people (only 1 person at any given time) in m_uiPhases 1 and 3, it's a debuff doing 2775 to 3225 Nature damage to the target and everybody in about 5 yards around it, every 1 seconds for 30 seconds. It can be removed by Cloak of Shadows, Iceblock, Divine Shield, etc, but not by Cleanse or Dispel Magic. Unit *pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0); //cast Static Charge every 2 seconds for 20 seconds if (pTarget && !pTarget->HasAura(SPELL_STATIC_CHARGE_TRIGGER)) DoCastSpellIfCan(pTarget, SPELL_STATIC_CHARGE_TRIGGER); m_uiStaticCharge_Timer = urand(10000, 30000); }else m_uiStaticCharge_Timer -= uiDiff; //m_uiEntangle_Timer if (m_uiEntangle_Timer < uiDiff) { if (!m_bEntangle) { //Used in m_uiPhases 1 and 3, it casts Entangling Roots on everybody in a 15 yard radius of Vashj, immobilzing them for 10 seconds and dealing 500 damage every 2 seconds. It's not a magic effect so it cannot be dispelled, but is removed by various buffs such as Cloak of Shadows or Blessing of Freedom. DoCastSpellIfCan(m_creature->getVictim(), SPELL_ENTANGLE); m_bEntangle = true; m_uiEntangle_Timer = 10000; } else { CastShootOrMultishot(); m_bEntangle = false; m_uiEntangle_Timer = urand(20000, 25000); } }else m_uiEntangle_Timer -= uiDiff; //m_uiPhase 1 if (m_uiPhase == PHASE_1) { //m_uiPhase 2 begins when Vashj hits 70%. She will run to the middle of her platform and surround herself in a shield making her invulerable. if (m_creature->GetHealthPercent() <= 70.0f) { DoScriptText(SAY_PHASE2, m_creature); if (m_creature->GetMotionMaster()->GetCurrentMovementGeneratorType() == CHASE_MOTION_TYPE) { //set false, so MoveChase is not triggered in AttackStart SetCombatMovement(false); m_creature->GetMotionMaster()->MovementExpired(); m_creature->GetMotionMaster()->MovePoint(POINT_MOVE_CENTER, afMiddlePos[0], afMiddlePos[1], afMiddlePos[2]); } m_uiPhase = PHASE_2; return; } } //m_uiPhase PHASE_3 else { //m_uiSummonSporebat_Timer if (m_uiSummonSporebat_Timer < uiDiff) { m_creature->SummonCreature(NPC_TOXIC_SPOREBAT, afSporebatPos[0], afSporebatPos[1], afSporebatPos[2], afSporebatPos[3], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); //summon sporebats faster and faster if (m_uiSummonSporebat_StaticTimer > 1000) m_uiSummonSporebat_StaticTimer -= 1000; m_uiSummonSporebat_Timer = m_uiSummonSporebat_StaticTimer; }else m_uiSummonSporebat_Timer -= uiDiff; } //Melee attack DoMeleeAttackIfReady(); //m_uiCheck_Timer - used to check if somebody is in melee range if (m_uiCheck_Timer < uiDiff) { bool bInMeleeRange = false; ThreatList const& tList = m_creature->getThreatManager().getThreatList(); for (ThreatList::const_iterator itr = tList.begin();itr != tList.end(); ++itr) { Unit* pTarget = Unit::GetUnit(*m_creature, (*itr)->getUnitGuid()); //if in melee range if (pTarget && pTarget->IsWithinDistInMap(m_creature, ATTACK_DISTANCE)) { bInMeleeRange = true; break; } } //if nobody is in melee range if (!bInMeleeRange) CastShootOrMultishot(); m_uiCheck_Timer = 1500; }else m_uiCheck_Timer -= uiDiff; } //m_uiPhase PHASE_2 else { //m_uiForkedLightning_Timer if (m_uiForkedLightning_Timer < uiDiff) { //Used constantly in m_uiPhase 2, it shoots out completely randomly targeted bolts of lightning which hit everybody in a roughtly 60 degree cone in front of Vashj for 2313-2687 nature damage. Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0); if (!pTarget) pTarget = m_creature->getVictim(); DoCastSpellIfCan(pTarget, SPELL_FORKED_LIGHTNING); m_uiForkedLightning_Timer = urand(3000, 9000); }else m_uiForkedLightning_Timer -= uiDiff; //NPC_ENCHANTED_ELEMENTAL if (m_uiEnchantedElemental_Timer < uiDiff) { if (Creature* pElemental = m_creature->SummonCreature(NPC_ENCHANTED_ELEMENTAL, afElementPos[m_uiEnchantedElemental_Pos][0], afElementPos[m_uiEnchantedElemental_Pos][1], afElementPos[m_uiEnchantedElemental_Pos][2], afElementPos[m_uiEnchantedElemental_Pos][3], TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 60000)) pElemental->GetMotionMaster()->MoveFollow(m_creature, 0.0f, 0.0f); if (m_uiEnchantedElemental_Pos == 7) m_uiEnchantedElemental_Pos = 0; else ++m_uiEnchantedElemental_Pos; m_uiEnchantedElemental_Timer = urand(10000, 15000); }else m_uiEnchantedElemental_Timer -= uiDiff; //NPC_TAINTED_ELEMENTAL if (m_uiTaintedElemental_Timer < uiDiff) { uint32 uiPos = urand(0,7); m_creature->SummonCreature(NPC_TAINTED_ELEMENTAL, afElementPos[uiPos][0], afElementPos[uiPos][1], afElementPos[uiPos][2], afElementPos[uiPos][3], TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 15000); m_uiTaintedElemental_Timer = 120000; }else m_uiTaintedElemental_Timer -= uiDiff; //NPC_COILFANG_ELITE if (m_uiCoilfangElite_Timer < uiDiff) { uint32 uiPos = urand(0,2); m_creature->SummonCreature(NPC_COILFANG_ELITE, afCoilfangElitePos[uiPos][0], afCoilfangElitePos[uiPos][1], afCoilfangElitePos[uiPos][2], afCoilfangElitePos[uiPos][3], TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 45000); //wowwiki says 50 seconds, bosskillers says 45 m_uiCoilfangElite_Timer = urand(45000, 50000); }else m_uiCoilfangElite_Timer -= uiDiff; //NPC_COILFANG_STRIDER if (m_uiCoilfangStrider_Timer < uiDiff) { uint32 uiPos = urand(0,2); m_creature->SummonCreature(NPC_COILFANG_STRIDER, afCoilfangStriderPos[uiPos][0], afCoilfangStriderPos[uiPos][1], afCoilfangStriderPos[uiPos][2], afCoilfangStriderPos[uiPos][3], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); //wowwiki says 60 seconds, bosskillers says 60-70 m_uiCoilfangStrider_Timer = urand(60000, 70000); }else m_uiCoilfangStrider_Timer -= uiDiff; //m_uiCheck_Timer if (m_uiCheck_Timer < uiDiff) { //Start m_uiPhase 3 if (m_pInstance && m_pInstance->GetData(TYPE_VASHJ_PHASE3_CHECK) == DONE) { DoScriptText(SAY_PHASE3, m_creature); //set life 50%, not correct. Must remove 5% for each generator switched off m_creature->SetHealth(m_creature->GetMaxHealth()/2); m_creature->RemoveAurasDueToSpell(SPELL_MAGIC_BARRIER); SetCombatMovement(true); //return to chase top aggro if (m_creature->GetMotionMaster()->GetCurrentMovementGeneratorType() != CHASE_MOTION_TYPE) m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim()); m_uiPhase = PHASE_3; } m_uiCheck_Timer = 1000; }else m_uiCheck_Timer -= uiDiff; } }
void UpdateAI(uint32 diff) override { if (!CanAttack && Intro) { if (AggroTimer <= diff) { CanAttack = true; me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); AggroTimer=19000; } else { AggroTimer-=diff; return; } } // to prevent abuses during phase 2 if (Phase == 2 && !me->GetVictim() && me->IsInCombat()) { EnterEvadeMode(); return; } // Return since we have no target if (!UpdateVictim()) return; if (Phase == 1 || Phase == 3) { // ShockBlastTimer if (ShockBlastTimer <= diff) { // Shock Burst // Randomly used in Phases 1 and 3 on Vashj's target, it's a Shock spell doing 8325-9675 nature damage and stunning the target for 5 seconds, during which she will not attack her target but switch to the next person on the aggro list. DoCastVictim(SPELL_SHOCK_BLAST); me->TauntApply(me->GetVictim()); ShockBlastTimer = 1000 + rand32() % 14000; // random cooldown } else ShockBlastTimer -= diff; // StaticChargeTimer if (StaticChargeTimer <= diff) { // Static Charge // Used on random people (only 1 person at any given time) in Phases 1 and 3, it's a debuff doing 2775 to 3225 Nature damage to the target and everybody in about 5 yards around it, every 1 seconds for 30 seconds. It can be removed by Cloak of Shadows, Iceblock, Divine Shield, etc, but not by Cleanse or Dispel Magic. Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 200, true); if (target && !target->HasAura(SPELL_STATIC_CHARGE_TRIGGER)) DoCast(target, SPELL_STATIC_CHARGE_TRIGGER); // cast Static Charge every 2 seconds for 20 seconds StaticChargeTimer = 10000 + rand32() % 20000; } else StaticChargeTimer -= diff; // EntangleTimer if (EntangleTimer <= diff) { if (!Entangle) { // Entangle // Used in Phases 1 and 3, it casts Entangling Roots on everybody in a 15 yard radius of Vashj, immobilzing them for 10 seconds and dealing 500 damage every 2 seconds. It's not a magic effect so it cannot be dispelled, but is removed by various buffs such as Cloak of Shadows or Blessing of Freedom. DoCastVictim(SPELL_ENTANGLE); Entangle = true; EntangleTimer = 10000; } else { CastShootOrMultishot(); Entangle = false; EntangleTimer = 20000 + rand32() % 5000; } } else EntangleTimer -= diff; // Phase 1 if (Phase == 1) { // Start phase 2 if (HealthBelowPct(70)) { // Phase 2 begins when Vashj hits 70%. She will run to the middle of her platform and surround herself in a shield making her invulerable. Phase = 2; me->GetMotionMaster()->Clear(); DoTeleportTo(MIDDLE_X, MIDDLE_Y, MIDDLE_Z); for (uint8 i = 0; i < 4; ++i) if (Creature* creature = me->SummonCreature(SHIED_GENERATOR_CHANNEL, ShieldGeneratorChannelPos[i][0], ShieldGeneratorChannelPos[i][1], ShieldGeneratorChannelPos[i][2], ShieldGeneratorChannelPos[i][3], TEMPSUMMON_CORPSE_DESPAWN, 0)) ShieldGeneratorChannel[i] = creature->GetGUID(); Talk(SAY_PHASE2); } } // Phase 3 else { // SummonSporebatTimer if (SummonSporebatTimer <= diff) { if (Creature* sporebat = me->SummonCreature(TOXIC_SPOREBAT, SPOREBAT_X, SPOREBAT_Y, SPOREBAT_Z, SPOREBAT_O, TEMPSUMMON_CORPSE_DESPAWN, 0)) if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) sporebat->AI()->AttackStart(target); // summon sporebats faster and faster if (SummonSporebatStaticTimer > 1000) SummonSporebatStaticTimer -= 1000; SummonSporebatTimer = SummonSporebatStaticTimer; if (SummonSporebatTimer < 5000) SummonSporebatTimer = 5000; } else SummonSporebatTimer -= diff; } // Melee attack DoMeleeAttackIfReady(); // CheckTimer - used to check if somebody is in melee range if (CheckTimer <= diff) { bool inMeleeRange = false; std::list<HostileReference*> t_list = me->getThreatManager().getThreatList(); for (std::list<HostileReference*>::const_iterator itr = t_list.begin(); itr!= t_list.end(); ++itr) { Unit* target = ObjectAccessor::GetUnit(*me, (*itr)->getUnitGuid()); if (target && target->IsWithinDistInMap(me, 5)) // if in melee range { inMeleeRange = true; break; } } // if nobody is in melee range if (!inMeleeRange) CastShootOrMultishot(); CheckTimer = 5000; } else CheckTimer -= diff; } // Phase 2 else { // ForkedLightningTimer if (ForkedLightningTimer <= diff) { // Forked Lightning // Used constantly in Phase 2, it shoots out completely randomly targeted bolts of lightning which hit everybody in a roughtly 60 degree cone in front of Vashj for 2313-2687 nature damage. Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0); if (!target) target = me->GetVictim(); DoCast(target, SPELL_FORKED_LIGHTNING); ForkedLightningTimer = 2000 + rand32() % 6000; } else ForkedLightningTimer -= diff; // EnchantedElementalTimer if (EnchantedElementalTimer <= diff) { me->SummonCreature(ENCHANTED_ELEMENTAL, ElementPos[EnchantedElementalPos][0], ElementPos[EnchantedElementalPos][1], ElementPos[EnchantedElementalPos][2], ElementPos[EnchantedElementalPos][3], TEMPSUMMON_CORPSE_DESPAWN, 0); if (EnchantedElementalPos == 7) EnchantedElementalPos = 0; else ++EnchantedElementalPos; EnchantedElementalTimer = 10000 + rand32() % 5000; } else EnchantedElementalTimer -= diff; // TaintedElementalTimer if (TaintedElementalTimer <= diff) { uint32 pos = rand32() % 8; me->SummonCreature(TAINTED_ELEMENTAL, ElementPos[pos][0], ElementPos[pos][1], ElementPos[pos][2], ElementPos[pos][3], TEMPSUMMON_DEAD_DESPAWN, 0); TaintedElementalTimer = 120000; } else TaintedElementalTimer -= diff; // CoilfangEliteTimer if (CoilfangEliteTimer <= diff) { uint32 pos = rand32() % 3; Creature* coilfangElite = me->SummonCreature(COILFANG_ELITE, CoilfangElitePos[pos][0], CoilfangElitePos[pos][1], CoilfangElitePos[pos][2], CoilfangElitePos[pos][3], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); if (coilfangElite) { if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) coilfangElite->AI()->AttackStart(target); else if (me->GetVictim()) coilfangElite->AI()->AttackStart(me->GetVictim()); } CoilfangEliteTimer = 45000 + rand32() % 5000; } else CoilfangEliteTimer -= diff; // CoilfangStriderTimer if (CoilfangStriderTimer <= diff) { uint32 pos = rand32() % 3; if (Creature* CoilfangStrider = me->SummonCreature(COILFANG_STRIDER, CoilfangStriderPos[pos][0], CoilfangStriderPos[pos][1], CoilfangStriderPos[pos][2], CoilfangStriderPos[pos][3], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000)) { if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) CoilfangStrider->AI()->AttackStart(target); else if (me->GetVictim()) CoilfangStrider->AI()->AttackStart(me->GetVictim()); } CoilfangStriderTimer = 60000 + rand32() % 10000; } else CoilfangStriderTimer -= diff; // CheckTimer if (CheckTimer <= diff) { // Start Phase 3 if (instance->GetData(DATA_CANSTARTPHASE3)) { // set life 50% me->SetHealth(me->CountPctFromMaxHealth(50)); me->RemoveAurasDueToSpell(SPELL_MAGIC_BARRIER); Talk(SAY_PHASE3); Phase = 3; // return to the tank me->GetMotionMaster()->MoveChase(me->GetVictim()); } CheckTimer = 1000; } else CheckTimer -= diff; } }
void UpdateAI(const uint32 diff) { if(!CanAttack && Intro) { if(AggroTimer < diff) { CanAttack = true; m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); AggroTimer=19000; }else { AggroTimer-=diff; return; } } //to prevent abuses during phase 2 if(Phase == 2 && !m_creature->getVictim() && InCombat) { EnterEvadeMode(); return; } //Return since we have no target if (!UpdateVictim() ) return; if(Phase == 1 || Phase == 3) { //ShockBlast_Timer if (ShockBlast_Timer < diff) { //Shock Burst //Randomly used in Phases 1 and 3 on Vashj's target, it's a Shock spell doing 8325-9675 nature damage and stunning the target for 5 seconds, during which she will not attack her target but switch to the next person on the aggro list. DoCast(m_creature->getVictim(), SPELL_SHOCK_BLAST); m_creature->TauntApply(m_creature->getVictim()); ShockBlast_Timer = 1000+rand()%14000; //random cooldown }else ShockBlast_Timer -= diff; //StaticCharge_Timer if(StaticCharge_Timer < diff) { //Static Charge //Used on random people (only 1 person at any given time) in Phases 1 and 3, it's a debuff doing 2775 to 3225 Nature damage to the target and everybody in about 5 yards around it, every 1 seconds for 30 seconds. It can be removed by Cloak of 3s, Iceblock, Divine Shield, etc, but not by Cleanse or Dispel Magic. Unit *target = NULL; target = SelectUnit(SELECT_TARGET_RANDOM, 0); if(target && !target->HasAura(SPELL_STATIC_CHARGE_TRIGGER, 0) && target->GetTypeId() == TYPEID_PLAYER && !target->isDead()) //cast Static Charge every 2 seconds for 20 seconds DoCast(target, SPELL_STATIC_CHARGE_TRIGGER); StaticCharge_Timer = 10000+rand()%20000; //blizzlike }else StaticCharge_Timer -= diff; //Entangle_Timer if (Entangle_Timer < diff) { if(!Entangle) { //Entangle //Used in Phases 1 and 3, it casts Entangling Roots on everybody in a 15 yard radius of Vashj, immobilzing them for 10 seconds and dealing 500 damage every 2 seconds. It's not a magic effect so it cannot be dispelled, but is removed by various buffs such as Cloak of Shadows or Blessing of Freedom. DoCast(m_creature->getVictim(), SPELL_ENTANGLE); Entangle = true; Entangle_Timer = 10000; } else { CastShootOrMultishot(); Entangle = false; Entangle_Timer = 20000+rand()%5000; } }else Entangle_Timer -= diff; //Phase 1 if(Phase == 1) { //Start phase 2 if ((m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) < 70) { //Phase 2 begins when Vashj hits 70%. She will run to the middle of her platform and surround herself in a shield making her invulerable. Phase = 2; m_creature->GetMotionMaster()->Clear(); DoTeleportTo(MIDDLE_X, MIDDLE_Y, MIDDLE_Z); Creature *pCreature; for(uint8 i = 0; i < 4; i++) { pCreature = m_creature->SummonCreature(SHIED_GENERATOR_CHANNEL, ShieldGeneratorChannelPos[i][0], ShieldGeneratorChannelPos[i][1], ShieldGeneratorChannelPos[i][2], ShieldGeneratorChannelPos[i][3], TEMPSUMMON_CORPSE_DESPAWN, 0); if (pCreature) ShieldGeneratorChannel[i] = pCreature->GetGUID(); } DoScriptText(SAY_PHASE2, m_creature); } } //Phase 3 else { //SummonSporebat_Timer if(SummonSporebat_Timer < diff) { Creature *Sporebat = NULL; Sporebat = m_creature->SummonCreature(TOXIC_SPOREBAT, SPOREBAT_X, SPOREBAT_Y, SPOREBAT_Z, SPOREBAT_O, TEMPSUMMON_CORPSE_DESPAWN, 0); if(Sporebat) { Unit *target = NULL; target = SelectUnit(SELECT_TARGET_RANDOM, 0); if(target) Sporebat->AI()->AttackStart(target); } //summon sporebats faster and faster if(SummonSporebat_StaticTimer > 1000) SummonSporebat_StaticTimer -= 1000; SummonSporebat_Timer = SummonSporebat_StaticTimer; if(SummonSporebat_Timer < 5000) SummonSporebat_Timer = 5000; }else SummonSporebat_Timer -= diff; } //Melee attack DoMeleeAttackIfReady(); //Check_Timer - used to check if somebody is in melee range if(Check_Timer < diff) { bool InMeleeRange = false; Unit *target; std::list<HostilReference *> t_list = m_creature->getThreatManager().getThreatList(); for(std::list<HostilReference *>::iterator itr = t_list.begin(); itr!= t_list.end(); ++itr) { target = Unit::GetUnit(*m_creature, (*itr)->getUnitGuid()); //if in melee range if(target && target->IsWithinDistInMap(m_creature, 5)) { InMeleeRange = true; break; } } //if nobody is in melee range if(!InMeleeRange) CastShootOrMultishot(); Check_Timer = 5000; }else Check_Timer -= diff; } //Phase 2 else { //ForkedLightning_Timer if(ForkedLightning_Timer < diff) { //Forked Lightning //Used constantly in Phase 2, it shoots out completely randomly targeted bolts of lightning which hit everybody in a roughtly 60 degree cone in front of Vashj for 2313-2687 nature damage. Unit *target = NULL; target = SelectUnit(SELECT_TARGET_RANDOM, 0); if(!target) target = m_creature->getVictim(); DoCast(target, SPELL_FORKED_LIGHTNING); ForkedLightning_Timer = 2000+rand()%6000; //blizzlike }else ForkedLightning_Timer -= diff; //EnchantedElemental_Timer if(EnchantedElemental_Timer < diff) { Creature *Elemental; Elemental = m_creature->SummonCreature(ENCHANTED_ELEMENTAL, ElementPos[EnchantedElemental_Pos][0], ElementPos[EnchantedElemental_Pos][1], ElementPos[EnchantedElemental_Pos][2], ElementPos[EnchantedElemental_Pos][3], TEMPSUMMON_CORPSE_DESPAWN, 0); if(EnchantedElemental_Pos == 7) EnchantedElemental_Pos = 0; else EnchantedElemental_Pos++; EnchantedElemental_Timer = 10000+rand()%5000; }else EnchantedElemental_Timer -= diff; //TaintedElemental_Timer if(TaintedElemental_Timer < diff) { Creature *Tain_Elemental; uint32 pos = rand()%8; Tain_Elemental = m_creature->SummonCreature(TAINTED_ELEMENTAL, ElementPos[pos][0], ElementPos[pos][1], ElementPos[pos][2], ElementPos[pos][3], TEMPSUMMON_DEAD_DESPAWN, 0); TaintedElemental_Timer = 120000; }else TaintedElemental_Timer -= diff; //CoilfangElite_Timer if(CoilfangElite_Timer < diff) { uint32 pos = rand()%3; Creature* CoilfangElite = NULL; CoilfangElite = m_creature->SummonCreature(COILFANG_ELITE, CoilfangElitePos[pos][0], CoilfangElitePos[pos][1], CoilfangElitePos[pos][2], CoilfangElitePos[pos][3], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); if(CoilfangElite) { Unit *target = NULL; target = SelectUnit(SELECT_TARGET_RANDOM, 0); if(target) CoilfangElite->AI()->AttackStart(target); else if(m_creature->getVictim()) CoilfangElite->AI()->AttackStart(m_creature->getVictim()); } CoilfangElite_Timer = 45000+rand()%5000; }else CoilfangElite_Timer -= diff; //CoilfangStrider_Timer if(CoilfangStrider_Timer < diff) { uint32 pos = rand()%3; Creature* CoilfangStrider = NULL; CoilfangStrider = m_creature->SummonCreature(COILFANG_STRIDER, CoilfangStriderPos[pos][0], CoilfangStriderPos[pos][1], CoilfangStriderPos[pos][2], CoilfangStriderPos[pos][3], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); if(CoilfangStrider) { Unit *target = NULL; target = SelectUnit(SELECT_TARGET_RANDOM, 0); if(target) CoilfangStrider->AI()->AttackStart(target); else if(m_creature->getVictim()) CoilfangStrider->AI()->AttackStart(m_creature->getVictim()); } CoilfangStrider_Timer = 60000+rand()%10000; }else CoilfangStrider_Timer -= diff; //Check_Timer if(Check_Timer < diff) { //Start Phase 3 if(pInstance && pInstance->GetData(DATA_CANSTARTPHASE3)) { //set life 50% m_creature->SetHealth(m_creature->GetMaxHealth()/2); m_creature->RemoveAurasDueToSpell(SPELL_MAGIC_BARRIER); DoScriptText(SAY_PHASE3, m_creature); Phase = 3; //return to the tank m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim()); } // check item tainted core. if player has item, cast root. if not has item and is rooted, remove root InstanceMap::PlayerList const &playerliste = ((InstanceMap*)m_creature->GetMap())->GetPlayers(); InstanceMap::PlayerList::const_iterator it; Map::PlayerList const &PlayerList = ((InstanceMap*)m_creature->GetMap())->GetPlayers(); for(Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) { Player* i_pl = i->getSource(); { if(i_pl->HasItemCount(31088, 1, false)) { if(i_pl->HasAura(39666,0)) i_pl->RemoveAurasDueToSpell(39666); // cloak of shadowx if(!i_pl->HasAura(38132,0)) i_pl->CastSpell(i_pl, 38132, false); // spell root } else if(i_pl->HasAura(38132,0)) i_pl->RemoveAurasDueToSpell(38132); } } Check_Timer = 1000; }else Check_Timer -= diff; } }
void UpdateAI(const uint32 uiDiff) { //Return since we have no target if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; if (m_uiPhase == PHASE_1 || m_uiPhase == PHASE_3) { //m_uiShockBlast_Timer if (m_uiShockBlast_Timer < uiDiff) { //Randomly used in m_uiPhases 1 and 3 on Vashj's target, it's a Shock spell doing 8325-9675 nature damage and stunning the target for 5 seconds, //during which she will not attack her target but switch to the next person on the aggro list. if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_SHOCK_BLAST) == CAST_OK) m_uiShockBlast_Timer = urand(8000, 15000); //random cooldown } else m_uiShockBlast_Timer -= uiDiff; //m_uiStaticCharge_Timer if (m_uiStaticCharge_Timer < uiDiff) { //Used on random people (only 1 person at any given time) in m_uiPhases 1 and 3, it's a debuff doing 2775 to 3225 Nature damage to the target and everybody in about 5 yards around it, //every 1 seconds for 30 seconds. It can be removed by Cloak of Shadows, Iceblock, Divine Shield, etc, but not by Cleanse or Dispel Magic. Unit *pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0, SPELL_STATIC_CHARGE_TRIGGER, SELECT_FLAG_PLAYER); //cast Static Charge every 2 seconds for 20 seconds if (pTarget && !pTarget->HasAura(SPELL_STATIC_CHARGE_TRIGGER) && DoCastSpellIfCan(pTarget, SPELL_STATIC_CHARGE_TRIGGER) == CAST_OK) m_uiStaticCharge_Timer = urand(10000, 30000); } else m_uiStaticCharge_Timer -= uiDiff; //m_uiEntangle_Timer if (m_uiEntangle_Timer < uiDiff) { if (!m_bEntangle) { //Used in m_uiPhases 1 and 3, it casts Entangling Roots on everybody in a 15 yard radius of Vashj, immobilzing them for 10 seconds and dealing 500 damage every 2 seconds. //It's not a magic effect so it cannot be dispelled, but is removed by various buffs such as Cloak of Shadows or Blessing of Freedom. if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_ENTANGLE) == CAST_OK) { m_bEntangle = true; m_uiEntangle_Timer = 10000; } } else { CastShootOrMultishot(m_creature->getVictim()); m_bEntangle = false; m_uiEntangle_Timer = urand(20000, 25000); } } else m_uiEntangle_Timer -= uiDiff; //m_uiPhase 1 if (m_uiPhase == PHASE_1) { //m_uiPhase 2 begins when Vashj hits 70%. She will run to the middle of her platform and surround herself in a shield making her invulerable. if (m_creature->GetHealthPercent() <= 70.0f) { DoScriptText(SAY_PHASE2, m_creature); if (m_creature->GetMotionMaster()->GetCurrentMovementGeneratorType() == CHASE_MOTION_TYPE) { //set false, so MoveChase is not triggered in AttackStart SetCombatMovement(false); m_creature->GetMotionMaster()->MovementExpired(); m_creature->GetMotionMaster()->MovePoint(POINT_MOVE_CENTER, afMiddlePos[0], afMiddlePos[1], afMiddlePos[2]); } m_uiPhase = PHASE_2; return; } } //m_uiPhase PHASE_3 else { // @Lorh : Mind Control (effect on 2 random target) if (m_uiPersuasionTimer <= uiDiff) { if (DoCastSpellIfCan(m_creature, SPELL_PERSUASION) == CAST_OK) m_uiPersuasionTimer = 45000; } else m_uiPersuasionTimer -= uiDiff; //@Lorh : Custom increase sporebat if (m_uiAddSporebat < uiDiff) { if (m_uiCountSporebat < 4) //Stop at 4 sporebat summoned. After 4mn , m_uiSummonSporebat_Timer manage soft enrage m_uiCountSporebat++; //Switch case, more easy to adapt timer if needed switch(m_uiCountSporebat) { case 2: // 2 sporebat at 1mn m_uiAddSporebat = 130000; break; case 3: // 3 sporebat at 3mn10 m_uiAddSporebat = 50000; break; default: // 4 sporebat at 4mn, go enrage m_uiAddSporebat = 80000; break; } } else m_uiAddSporebat -= uiDiff; // Summon Sporebat timer if (m_uiSummonSporebat_Timer < uiDiff) { for (uint8 summonSporebat = 0; summonSporebat < m_uiCountSporebat; summonSporebat++) m_creature->SummonCreature(NPC_TOXIC_SPOREBAT, afSporebatPos[0], afSporebatPos[1], afSporebatPos[2], frand(-6.0f, 6.0f), TEMPSUMMON_DEAD_DESPAWN, 5000); if (m_uiSummonSporebat_StaticTimer <= 4000) m_uiSummonSporebat_StaticTimer = 4000; //This case happened after 4mn, soft enrage start else m_uiSummonSporebat_StaticTimer -= 1000; m_uiSummonSporebat_Timer = m_uiSummonSporebat_StaticTimer; } else m_uiSummonSporebat_Timer -= uiDiff; } //Melee attack DoMeleeAttackIfReady(); //m_uiCheck_Timer - used to check if somebody is in melee range if (m_uiCheck_Timer < uiDiff) { //if nobody is in melee range if (!m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0, uint32(0), SELECT_FLAG_IN_MELEE_RANGE)) CastShootOrMultishot(m_creature->getVictim()); m_uiCheck_Timer = 3000; } else m_uiCheck_Timer -= uiDiff; } //m_uiPhase PHASE_2 else { //m_uiForkedLightning_Timer if (m_uiForkedLightning_Timer < uiDiff) { //Used constantly in m_uiPhase 2, it shoots out completely randomly targeted bolts of lightning which hit everybody in a roughtly 60 degree cone in front of Vashj for 2313-2687 nature damage. Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0); if (!pTarget) pTarget = m_creature->getVictim(); if (DoCastSpellIfCan(pTarget, SPELL_FORKED_LIGHTNING) == CAST_OK) m_uiForkedLightning_Timer = urand(2000, 8000); } else m_uiForkedLightning_Timer -= uiDiff; //NPC_ENCHANTED_ELEMENTAL if (m_uiEnchantedElemental_Timer < uiDiff) { uint32 uiPos = urand(0, 7); if (Creature* pElemental = m_creature->SummonCreature(NPC_ENCHANTED_ELEMENTAL, afElementPos[uiPos][0], afElementPos[uiPos][1], afElementPos[uiPos][2], afElementPos[uiPos][3], TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 60000)) pElemental->GetMotionMaster()->MoveFollow(m_creature, 0.0f, 0.0f); switch (m_uiShieldGeneratorDown) { case 1: m_uiEnchantedElemental_Timer = urand(5000, 9000); break; case 2: m_uiEnchantedElemental_Timer = urand(5000, 8000); break; case 3: m_uiEnchantedElemental_Timer = urand(5000, 7000); break; case 4: m_uiEnchantedElemental_Timer = urand(5000, 6000); break; default: m_uiEnchantedElemental_Timer = urand(5000, 10000); break; } } else m_uiEnchantedElemental_Timer -= uiDiff; //NPC_TAINTED_ELEMENTAL if (m_uiTaintedElemental_Timer < uiDiff) { uint32 uiPos = urand(0, 7); m_creature->SummonCreature(NPC_TAINTED_ELEMENTAL, afElementPos[uiPos][0], afElementPos[uiPos][1], afElementPos[uiPos][2], afElementPos[uiPos][3], TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 60000); m_uiTaintedElemental_Timer = 120000; } else m_uiTaintedElemental_Timer -= uiDiff; //NPC_COILFANG_ELITE if (m_uiCoilfangElite_Timer < uiDiff) { uint32 uiPos = urand(0, 7); if (Creature* pElite = m_creature->SummonCreature(NPC_COILFANG_ELITE, afElementPos[uiPos][0], afElementPos[uiPos][1], afElementPos[uiPos][2], afElementPos[uiPos][3], TEMPSUMMON_TIMED_OOC_OR_DEAD_DESPAWN, 15000)) // @Lorh : I change the flag to avoid that he despawn after 45sec pElite->GetMotionMaster()->MovePoint(POINT_MOVE_FLOOR, afFloorPoint[uiPos][0], afFloorPoint[uiPos][1], afFloorPoint[uiPos][2]); //wowwiki says 50 seconds, bosskillers says 45 m_uiCoilfangElite_Timer = urand(45000, 50000); } else m_uiCoilfangElite_Timer -= uiDiff; //NPC_COILFANG_STRIDER if (m_uiCoilfangStrider_Timer < uiDiff) { uint32 uiPos = urand(0, 7); if (Creature* pStrider = m_creature->SummonCreature(NPC_COILFANG_STRIDER, afElementPos[uiPos][0], afElementPos[uiPos][1], afElementPos[uiPos][2], afElementPos[uiPos][3], TEMPSUMMON_TIMED_OOC_OR_CORPSE_DESPAWN, 8000)) //@Lorh : I changed the flag, to avoid that aoe fear take effect after death pStrider->GetMotionMaster()->MovePoint(POINT_MOVE_FLOOR, afFloorPoint[uiPos][0], afFloorPoint[uiPos][1], afFloorPoint[uiPos][2]); //wowwiki says 60 seconds, bosskillers says 60-70 m_uiCoilfangStrider_Timer = urand(60000, 70000); } else m_uiCoilfangStrider_Timer -= uiDiff; //m_uiCheck_Timer if (m_uiCheck_Timer < uiDiff) { //Start m_uiPhase 3 if (m_pInstance && m_pInstance->GetData(TYPE_VASHJ_PHASE3_CHECK) == DONE) { DoScriptText(SAY_PHASE3, m_creature); SetCombatMovement(true); //@Lorh : Reset Aggro DoResetThreat(); if (m_creature->GetMotionMaster()->GetCurrentMovementGeneratorType() != CHASE_MOTION_TYPE) m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim()); m_uiPhase = PHASE_3; } m_uiCheck_Timer = 1000; } else m_uiCheck_Timer -= uiDiff; } }