void OPvPWintergrasp::PromotePlayer(Player *killer) const { Aura *aur; if (aur = killer->GetAura(SPELL_RECRUIT)) { if (aur->GetStackAmount() >= 5) { killer->RemoveAura(SPELL_RECRUIT); killer->CastSpell(killer, SPELL_CORPORAL, true); } else killer->CastSpell(killer, SPELL_RECRUIT, true); } else if (aur = killer->GetAura(SPELL_CORPORAL)) { if (aur->GetStackAmount() >= 5) { killer->RemoveAura(SPELL_CORPORAL); killer->CastSpell(killer, SPELL_LIEUTENANT, true); } else killer->CastSpell(killer, SPELL_CORPORAL, true); } else if (killer->HasAura(SPELL_LIEUTENANT)) killer->CastSpell(killer, SPELL_LIEUTENANT, true); }
void OPvPWintergrasp::HandleKill(Player *killer, Unit *victim) { if(victim->GetTypeId() == TYPEID_PLAYER) { // We handle promotion here because player should not get promotion if he has buff but do the kill outside the zone if(victim->getLevel() >= 70) { Aura *aur; if(aur = killer->GetAura(SPELL_RECRUIT)) { if(aur->GetStackAmount() >= 5) { killer->RemoveAura(SPELL_RECRUIT); killer->CastSpell(killer, SPELL_CORPORAL, true); } else killer->CastSpell(killer, SPELL_RECRUIT, true); } else if(aur = killer->GetAura(SPELL_CORPORAL)) { if(aur->GetStackAmount() >= 5) { killer->RemoveAura(SPELL_CORPORAL); killer->CastSpell(killer, SPELL_LIEUTENANT, true); } else killer->CastSpell(killer, SPELL_CORPORAL, true); } else if(killer->HasAura(SPELL_LIEUTENANT)) killer->CastSpell(killer, SPELL_LIEUTENANT, true); } } }
void HandleScript(SpellEffIndex /*effIndex*/) { if (!(GetHitCreature() && GetHitCreature()->IsAlive())) return; Aura *unstable = GetCaster()->GetAura(SPELL_UNSTABLE_OOZE); if (unstable != NULL) { uint8 newStack = uint8(unstable->GetStackAmount()+1); unstable->SetStackAmount(newStack); // explode! if (newStack >= 5) { GetCaster()->RemoveAurasDueToSpell(SPELL_LARGE_OOZE_BUFF_COMBINE); GetCaster()->RemoveAurasDueToSpell(SPELL_LARGE_OOZE_COMBINE); if (InstanceScript* instance = GetCaster()->GetInstanceScript()) if (Creature* rotface = Unit::GetCreature(*GetCaster(), instance->GetData64(DATA_ROTFACE))) if (rotface->IsAlive()) { rotface->AI()->Talk(EMOTE_UNSTABLE_EXPLOSION); rotface->AI()->Talk(SAY_UNSTABLE_EXPLOSION); } if (Creature* cre = GetCaster()->ToCreature()) cre->AI()->DoAction(EVENT_STICKY_OOZE); GetCaster()->CastSpell(GetCaster(), SPELL_UNSTABLE_OOZE_EXPLOSION, false, NULL, NULL, GetCaster()->GetGUID()); if (InstanceScript* instance = GetCaster()->GetInstanceScript()) instance->SetData(DATA_OOZE_DANCE_ACHIEVEMENT, uint32(false)); } } GetHitCreature()->DespawnOrUnsummon(); }
void UpdateAI(uint32 diff) override { if (!UpdateVictim()) return; if (uiGripOfSladRanTimer <= diff) { Unit* target = me->GetVictim(); DoCast(target, SPELL_GRIP_OF_SLAD_RAN); uiGripOfSladRanTimer = urand(3, 6)*IN_MILLISECONDS; Aura* grip = target->GetAura(SPELL_GRIP_OF_SLAD_RAN, me->GetGUID()); if (grip && grip->GetStackAmount() == 5) { target->RemoveAurasDueToSpell(SPELL_GRIP_OF_SLAD_RAN, me->GetGUID()); target->CastSpell(target, SPELL_SNAKE_WRAP, true); if (TempSummon* _me = me->ToTempSummon()) if (Unit* summoner = _me->GetSummoner()) if (Creature* sladran = summoner->ToCreature()) sladran->AI()->SetGUID(target->GetGUID(), DATA_SNAKES_WHYD_IT_HAVE_TO_BE_SNAKES); me->DespawnOrUnsummon(); } } else uiGripOfSladRanTimer -= diff; }
void HandleRemove(AuraEffect const* aurEff, AuraEffectHandleModes mode) { PreventDefaultAction(); Aura* aura = aurEff->GetBase(); if (aura->GetStackAmount() == 1) aura->Remove(AURA_REMOVE_BY_DEFAULT); else aura->SetStackAmount(GetStackAmount() - 1); }
void UpdateAI(const uint32 diff) { if (!UpdateVictim()) return; if (CheckIntenseColdTimer < diff && !MoreThanTwoIntenseCold) { std::list<HostilReference*> ThreatList = m_creature->getThreatManager().getThreatList(); for(std::list<HostilReference*>::const_iterator itr = ThreatList.begin(); itr != ThreatList.end(); itr++) { Unit *target = Unit::GetUnit(*m_creature, (*itr)->getUnitGuid()); if (!target || target->GetTypeId() != TYPEID_PLAYER) continue; Aura *AuraIntenseCold = target->GetAura(SPELL_INTENSE_COLD_TRIGGERED); if (AuraIntenseCold && AuraIntenseCold->GetStackAmount() > 2) { MoreThanTwoIntenseCold = true; break; } } CheckIntenseColdTimer = 2000; }else CheckIntenseColdTimer -= diff; if (!Enrage && (m_creature->GetHealth() < m_creature->GetMaxHealth() * 0.25)) { DoScriptText(SAY_ENRAGE , m_creature); DoCast(m_creature, SPELL_ENRAGE); Enrage = true; } if (CRYSTALFIRE_BREATH_Timer < diff) { DoCast(m_creature->getVictim(), HeroicMode ? SPELL_CRYSTALFIRE_BREATH_H : SPELL_CRYSTALFIRE_BREATH_N); CRYSTALFIRE_BREATH_Timer = 14000; }else CRYSTALFIRE_BREATH_Timer -=diff; if (TAIL_SWEEP_Timer < diff) { DoCast(m_creature, SPELL_TAIL_SWEEP); TAIL_SWEEP_Timer = 5000; }else TAIL_SWEEP_Timer -=diff; if (CRYSTAL_CHAINS_CRYSTALIZE_Timer < diff) { DoScriptText(SAY_CRYSTAL_NOVA , m_creature); if (HeroicMode) DoCast(m_creature, SPELL_CRYSTALIZE); else if (Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0)) DoCast(target, SPELL_CRYSTAL_CHAINS); CRYSTAL_CHAINS_CRYSTALIZE_Timer = HeroicMode ? 30000 : 11000; }else CRYSTAL_CHAINS_CRYSTALIZE_Timer -= diff; DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 diff) { if (!UpdateVictim()) return; if (uiCheckIntenseColdTimer < diff && !bMoreThanTwoIntenseCold) { std::list<HostileReference*> ThreatList = me->getThreatManager().getThreatList(); for (std::list<HostileReference*>::const_iterator itr = ThreatList.begin(); itr != ThreatList.end(); ++itr) { Unit *pTarget = Unit::GetUnit(*me, (*itr)->getUnitGuid()); if (!pTarget || pTarget->GetTypeId() != TYPEID_PLAYER) continue; Aura *AuraIntenseCold = pTarget->GetAura( SPELL_INTENSE_COLD_TRIGGERED); if (AuraIntenseCold && AuraIntenseCold->GetStackAmount() > 2) { bMoreThanTwoIntenseCold = true; break; } } uiCheckIntenseColdTimer = 2 * IN_MILLISECONDS; } else uiCheckIntenseColdTimer -= diff; if (!bEnrage && HealthBelowPct(25)) { DoScriptText(SAY_ENRAGE, me); DoCast(me, SPELL_ENRAGE); bEnrage = true; } if (uiCrystalfireBreathTimer <= diff) { DoCast(me->getVictim(), SPELL_CRYSTALFIRE_BREATH); uiCrystalfireBreathTimer = 14 * IN_MILLISECONDS; } else uiCrystalfireBreathTimer -= diff; if (uiTailSweepTimer <= diff) { DoCast(me, SPELL_TAIL_SWEEP); uiTailSweepTimer = 5 * IN_MILLISECONDS; } else uiTailSweepTimer -= diff; if (uiCrystalChainsCrystalizeTimer <= diff) { DoScriptText(SAY_CRYSTAL_NOVA, me); if (IsHeroic()) DoCast(me, SPELL_CRYSTALIZE); else if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)) DoCast(pTarget, SPELL_CRYSTAL_CHAINS); uiCrystalChainsCrystalizeTimer = DUNGEON_MODE( 30 * IN_MILLISECONDS, 11 * IN_MILLISECONDS); } else uiCrystalChainsCrystalizeTimer -= diff; DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 diff) { //Return since we have no target if (!UpdateVictim()) return; if (uiSpawnTimer <= diff) { uint32 spawnNumber = urand(2, DUNGEON_MODE(3, 5)); for (uint8 i = 0; i < spawnNumber; ++i) DoSummon( RAND(NPC_DRAKKARI_INVADER_1, NPC_DRAKKARI_INVADER_2), AddSpawnPoint, 0, TEMPSUMMON_DEAD_DESPAWN); uiSpawnTimer = urand(30 * IN_MILLISECONDS, 40 * IN_MILLISECONDS); } else uiSpawnTimer -= diff; if (uiConsumeTimer <= diff) { DoScriptText(SAY_CONSUME, me); DoCast(SPELL_CONSUME); uiConsumeTimer = 15 * IN_MILLISECONDS; } else uiConsumeTimer -= diff; if (bAchiev) { Aura *pConsumeAura = me->GetAura( DUNGEON_MODE(SPELL_CONSUME_AURA, H_SPELL_CONSUME_AURA)); if (pConsumeAura && pConsumeAura->GetStackAmount() > 9) bAchiev = false; } if (uiCrushTimer <= diff) { DoCastVictim(SPELL_CRUSH); uiCrushTimer = urand(10 * IN_MILLISECONDS, 15 * IN_MILLISECONDS); } else uiCrushTimer -= diff; if (uiInfectedWoundTimer <= diff) { DoCastVictim(SPELL_INFECTED_WOUND); uiInfectedWoundTimer = urand(25 * IN_MILLISECONDS, 35 * IN_MILLISECONDS); } else uiInfectedWoundTimer -= diff; if (uiExplodeCorpseTimer <= diff) { DoCast(SPELL_CORPSE_EXPLODE); DoScriptText(SAY_EXPLODE, me); uiExplodeCorpseTimer = urand(15 * IN_MILLISECONDS, 19 * IN_MILLISECONDS); } else uiExplodeCorpseTimer -= diff; DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 diff) { //Return since we have no target if (!UpdateVictim()) return; if (uiSpawnTimer <= diff) { for (uint8 i = 0; i < urand(2,HEROIC(3,5)); ++i) DoSpawnCreature(RAND(NPC_DRAKKARI_INVADER_1,NPC_DRAKKARI_INVADER_2), AddSpawnPoint.GetPositionX(), AddSpawnPoint.GetPositionY(), AddSpawnPoint.GetPositionZ(), AddSpawnPoint.GetOrientation(), TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 90000); uiSpawnTimer = urand(30000,40000); } else uiSpawnTimer -= diff; if (uiConsumeTimer <= diff) { DoScriptText(SAY_CONSUME, m_creature); DoCast(HEROIC(SPELL_CONSUME, H_SPELL_CONSUME)); uiConsumeTimer = 15000; } else uiConsumeTimer -= diff; if (bAchiev) { if (uiAuraCountTimer <= diff) { if (m_creature->HasAura(HEROIC(SPELL_CONSUME,H_SPELL_CONSUME))) { Aura *pConsumeAura = m_creature->GetAura(HEROIC(SPELL_CONSUME,H_SPELL_CONSUME)); if (pConsumeAura && pConsumeAura->GetStackAmount() > 9) bAchiev = false; } uiAuraCountTimer = 16000; } else uiAuraCountTimer -= diff; } if (uiCrushTimer <= diff) { DoCastVictim(SPELL_CRUSH); uiCrushTimer = urand(10000,15000); } else uiCrushTimer -= diff; if (uiInfectedWoundTimer <= diff) { DoCastVictim(SPELL_INFECTED_WOUND); uiInfectedWoundTimer = urand(25000,35000); } else uiInfectedWoundTimer -= diff; if (uiExplodeCorpseTimer <= diff) { DoCast(HEROIC(SPELL_CORPSE_EXPLODE, H_SPELL_CORPSE_EXPLODE)); DoScriptText(SAY_EXPLODE, m_creature); uiExplodeCorpseTimer = urand(15000,19000); } else uiExplodeCorpseTimer -= diff; DoMeleeAttackIfReady(); }
void UpdateAI(uint32 diff) override { if (!UpdateVictim()) return; events.Update(diff); if (me->HasUnitState(UNIT_STATE_CASTING)) return; while (uint32 eventId = events.ExecuteEvent()) { switch (eventId) { case EVENT_CONSUME: Talk(SAY_CONSUME); DoCastAOE(SPELL_CONSUME); events.ScheduleEvent(EVENT_CONSUME, 15000); break; case EVENT_CRUSH: DoCastVictim(SPELL_CRUSH); events.ScheduleEvent(EVENT_CRUSH, urand(10000, 15000)); break; case EVENT_INFECTED_WOUND: DoCastVictim(SPELL_INFECTED_WOUND); events.ScheduleEvent(EVENT_INFECTED_WOUND, urand(25000, 35000)); break; case EVENT_CORPSE_EXPLODE: Talk(SAY_EXPLODE); DoCastAOE(SPELL_CORPSE_EXPLODE); events.ScheduleEvent(EVENT_CORPSE_EXPLODE, urand(15000, 19000)); break; case EVENT_SPAWN: for (uint8 i = 0; i < 3; ++i) if (Creature* trigger = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_TROLLGORE_INVADER_SUMMONER_1 + i))) trigger->CastSpell(trigger, RAND(SPELL_SUMMON_INVADER_A, SPELL_SUMMON_INVADER_B, SPELL_SUMMON_INVADER_C), true, NULL, NULL, me->GetGUID()); events.ScheduleEvent(EVENT_SPAWN, urand(30000, 40000)); break; default: break; } } if (_consumptionJunction) { Aura* ConsumeAura = me->GetAura(SPELL_CONSUME_BUFF_HELPER); if (ConsumeAura && ConsumeAura->GetStackAmount() > 9) _consumptionJunction = false; } DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 diff) { if (!UpdateVictim()) return; if (SpawnTimer <= diff) { uint32 spawnNumber = urand(2, DUNGEON_MODE(3, 5)); for (uint8 i = 0; i < spawnNumber; ++i) DoSummon(RAND(NPC_DRAKKARI_INVADER_1, NPC_DRAKKARI_INVADER_2), AddSpawnPoint, 0, TEMPSUMMON_DEAD_DESPAWN); SpawnTimer = urand(30*IN_MILLISECONDS, 40*IN_MILLISECONDS); } else SpawnTimer -= diff; if (ConsumeTimer <= diff) { DoSendQuantumText(SAY_CONSUME, me); DoCastAOE(DUNGEON_MODE(SPELL_CONSUME_5N, SPELL_CONSUME_5H)); ConsumeTimer = 15*IN_MILLISECONDS; } else ConsumeTimer -= diff; if (bAchiev) { Aura* ConsumeAura = me->GetAura(DUNGEON_MODE(SPELL_CONSUME_AURA_5N, SPELL_CONSUME_AURA_5H)); if (ConsumeAura && ConsumeAura->GetStackAmount() > 9) bAchiev = false; } if (CrushTimer <= diff) { DoCastVictim(SPELL_CRUSH); CrushTimer = urand(10*IN_MILLISECONDS, 15*IN_MILLISECONDS); } else CrushTimer -= diff; if (InfectedWoundTimer <= diff) { DoCastVictim(SPELL_INFECTED_WOUND); InfectedWoundTimer = urand(25*IN_MILLISECONDS, 35*IN_MILLISECONDS); } else InfectedWoundTimer -= diff; if (ExplodeCorpseTimer <= diff) { DoCast(DUNGEON_MODE(SPELL_CORPSE_EXPLODE_5N, SPELL_CORPSE_EXPLODE_5H)); DoSendQuantumText(SAY_EXPLODE, me); ExplodeCorpseTimer = urand(15*IN_MILLISECONDS, 19*IN_MILLISECONDS); } else ExplodeCorpseTimer -= diff; DoMeleeAttackIfReady(); }
bool Spell_arcane_torrent(Unit* caster, std::list<Unit*> &, SpellCastTargets const&, SpellEntry const *spellInfo, uint32 effectIndex) { if (effectIndex != 0) return true; switch (spellInfo->Id) { case 28730: // Arcane Torrent (Mana) case 33390: // Arcane Torrent (mana Wretched Devourer) { Aura* dummy = caster->GetDummyAura(28734); if (dummy) { int32 bp = (2.17*caster->getLevel() + 9.136) * dummy->GetStackAmount(); caster->CastCustomSpell(caster, 28733, &bp, NULL, NULL, true); caster->RemoveAurasDueToSpell(28734); } break; } // Arcane Torrent (Energy) case 25046: { // Search Mana Tap auras on caster Aura* dummy = caster->GetDummyAura(28734); if (dummy) { int32 bp = dummy->GetStackAmount() * 10; caster->CastCustomSpell(caster, 25048, &bp, NULL, NULL, true); caster->RemoveAurasDueToSpell(28734); } break; } } return true; }
void MountedChampionAI::executeEvent(uint32 eventID) { uint32 timer = 0; switch (eventID) { case EVENT_SPELL_CHARGE: { if (Unit* pUnit = SelectTarget(SELECT_TARGET_FARTHEST)) { DoResetThreat(); me->AddThreat(pUnit, 5.0f); DoCast(pUnit, SPELL_CHARGE, true); } timer = 5000; }break; case EVENT_SPELL_SHIELD_BREAKER: { if (Unit* pUnit = SelectTarget(SELECT_TARGET_FARTHEST)) DoCast(pUnit, SPELL_SHIELD_BREAKER, true); timer = 7 * IN_MILLISECONDS; }break; case EVENT_SPELL_SHIELD: { Aura* pAura = me->GetAura(SPELL_SHIELD); if (!pAura || pAura->GetStackAmount() < 3) { DoCast(SPELL_SHIELD); timer = urand(4 * IN_MILLISECONDS, 5 * IN_MILLISECONDS); } else timer = urand(1 * IN_MILLISECONDS, 2 * IN_MILLISECONDS); }break; } if (eventID && timer) eventMap.ScheduleEvent(eventID, timer); }
void UpdateAI(uint32 const diff) { events.Update(diff); switch (events.ExecuteEvent()) { case EVENT_DUMMY_RECAST_DEFEND: switch (me->GetEntry()) { case NPC_CHARGE_TARGET: { if (!me->HasAura(SPELL_CHARGE_DEFEND)) DoCast(SPELL_CHARGE_DEFEND); break; } case NPC_RANGED_TARGET: { Aura* defend = me->GetAura(SPELL_RANGED_DEFEND); if (!defend || defend->GetStackAmount() < 3 || defend->GetDuration() <= 8000) DoCast(SPELL_RANGED_DEFEND); break; } } isVulnerable = false; events.ScheduleEvent(EVENT_DUMMY_RECAST_DEFEND, 5000); break; case EVENT_DUMMY_RESET: if (UpdateVictim()) { EnterEvadeMode(); events.ScheduleEvent(EVENT_DUMMY_RESET, 10000); } break; } if (!UpdateVictim()) return; if (!me->HasUnitState(UNIT_STATE_STUNNED)) me->SetControlled(true, UNIT_STATE_STUNNED); }
void HandleScript(SpellEffIndex /*effIndex*/) { if (!(GetHitCreature() && GetHitCreature()->IsAlive())) return; Aura *unstable = GetCaster()->GetAura(SPELL_UNSTABLE_OOZE); if (unstable != NULL) { Aura *targetAura = GetHitCreature()->GetAura(SPELL_UNSTABLE_OOZE); if (targetAura != NULL) unstable->ModStackAmount(targetAura->GetStackAmount()); else unstable->ModStackAmount(1); // no idea why, but this does not trigger explosion on retail (only small+large do) } // just for safety GetHitCreature()->RemoveAurasDueToSpell(SPELL_LARGE_OOZE_BUFF_COMBINE); GetHitCreature()->RemoveAurasDueToSpell(SPELL_LARGE_OOZE_COMBINE); GetHitCreature()->DespawnOrUnsummon(); }
void HandleScriptEffect(SpellEffIndex /*effIndex*/) { Unit* caster = GetCaster(); if (Unit* unitTarget = GetHitUnit()) { uint32 spellId = 0; int32 basePoint = 0; Unit::AuraApplicationMap& Auras = unitTarget->GetAppliedAuras(); for (Unit::AuraApplicationMap::iterator i = Auras.begin(); i != Auras.end(); ++i) { Aura* aura = i->second->GetBase(); if (aura->GetCasterGUID() != caster->GetGUID()) continue; // Search only Serpent Sting, Viper Sting, Scorpid Sting auras flag96 familyFlag = aura->GetSpellInfo()->SpellFamilyFlags; if (!(familyFlag[1] & 0x00000080 || familyFlag[0] & 0x0000C000)) continue; if (AuraEffect* aurEff = aura->GetEffect(0)) { // Serpent Sting - Instantly deals 40% of the damage done by your Serpent Sting. if (familyFlag[0] & 0x4000) { int32 TickCount = aurEff->GetTotalTicks(); spellId = SPELL_HUNTER_CHIMERA_SHOT_SERPENT; basePoint = (aurEff->GetAmount() + aurEff->GetBonusAmount()) * aurEff->GetDonePct(); ApplyPct(basePoint, TickCount * 40); basePoint = unitTarget->SpellDamageBonusTaken(caster, aura->GetSpellInfo(), basePoint, DOT, aura->GetStackAmount()); if (Player* modOwner = caster->GetSpellModOwner()) modOwner->ApplySpellMod(aura->GetSpellInfo()->Id, SPELLMOD_DOT, basePoint); aurEff->SetBonusAmount(caster->SpellDamageBonusDone(unitTarget, aurEff->GetSpellInfo(), 0, DOT)); } // Viper Sting - Instantly restores mana to you equal to 60% of the total amount drained by your Viper Sting. else if (familyFlag[1] & 0x00000080) { int32 TickCount = aura->GetEffect(0)->GetTotalTicks(); spellId = SPELL_HUNTER_CHIMERA_SHOT_VIPER; // Amount of one aura tick basePoint = int32(CalculatePct(unitTarget->GetMaxPower(POWER_MANA), aurEff->GetAmount())); int32 casterBasePoint = aurEff->GetAmount() * unitTarget->GetMaxPower(POWER_MANA) / 50; /// @todo WTF? caster uses unitTarget? if (basePoint > casterBasePoint) basePoint = casterBasePoint; ApplyPct(basePoint, TickCount * 60); } // Scorpid Sting - Attempts to Disarm the target for 10 sec. This effect cannot occur more than once per 1 minute. else if (familyFlag[0] & 0x00008000) spellId = SPELL_HUNTER_CHIMERA_SHOT_SCORPID; // ?? nothing say in spell desc (possibly need addition check) //if (familyFlag & 0x0000010000000000LL || // dot // familyFlag & 0x0000100000000000LL) // stun //{ // spellId = 53366; // 53366 Chimera Shot - Wyvern //} // Refresh aura duration aura->RefreshDuration(); } break; } if (spellId) caster->CastCustomSpell(unitTarget, spellId, &basePoint, 0, 0, true); if (spellId == SPELL_HUNTER_CHIMERA_SHOT_SCORPID && caster->ToPlayer()) // Scorpid Sting - Add 1 minute cooldown caster->GetSpellHistory()->AddCooldown(spellId, 0, std::chrono::minutes(1)); } }
void UpdateAI(const uint32 uiDiff) override { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; // This needs to be checked only on heroic if (!m_bIsRegularMode && m_uiCheckPermafrostTimer) { if (m_uiCheckPermafrostTimer <= uiDiff) { ThreatList playerList = m_creature->getThreatManager().getThreatList(); for (ThreatList::const_iterator itr = playerList.begin(); itr != playerList.end(); ++itr) { if (Player* pTarget = m_creature->GetMap()->GetPlayer((*itr)->getUnitGuid())) { Aura* pAuraIntenseCold = pTarget->GetAura(SPELL_PERMAFROST_AURA_H, EFFECT_INDEX_2); if (pAuraIntenseCold) { if (pAuraIntenseCold->GetStackAmount() > MAX_PERMAFROST_STACK) { if (m_pInstance) m_pInstance->SetSpecialAchievementCriteria(TYPE_ACHIEV_DOESNT_GO_ELEVEN, false); m_uiCheckPermafrostTimer = 0; return; } } } } m_uiCheckPermafrostTimer = 1000; } else m_uiCheckPermafrostTimer -= uiDiff; } // Do nothing more while moving if (m_uiPhase == PHASE_MOVEMENT) return; // Casted in every phase if (m_uiThrowSaroniteTimer < uiDiff) { // TODO - only target players? if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) { if (DoCastSpellIfCan(pTarget, SPELL_THROW_SARONITE) == CAST_OK) { DoScriptText(EMOTE_THROW_SARONITE, m_creature, pTarget); m_uiThrowSaroniteTimer = 16000; } } } else m_uiThrowSaroniteTimer -= uiDiff; switch (m_uiPhase) { case PHASE_NO_ENCHANTMENT: { if (m_creature->GetHealthPercent() < 66.0f) { DoCastSpellIfCan(m_creature, SPELL_THUNDERING_STOMP, CAST_INTERRUPT_PREVIOUS); SetCombatMovement(false); m_creature->GetMotionMaster()->MoveJump(aGarfrostMoveLocs[0][0], aGarfrostMoveLocs[0][1], aGarfrostMoveLocs[0][2], 3 * m_creature->GetSpeed(MOVE_RUN), 10.0f, PHASE_BLADE_ENCHANTMENT); m_uiPhase = PHASE_MOVEMENT; // Stop further action return; } break; } case PHASE_BLADE_ENCHANTMENT: { if (m_creature->GetHealthPercent() < 33.0f) { DoCastSpellIfCan(m_creature, SPELL_THUNDERING_STOMP, CAST_INTERRUPT_PREVIOUS); SetCombatMovement(false); m_creature->GetMotionMaster()->MoveJump(aGarfrostMoveLocs[1][0], aGarfrostMoveLocs[1][1], aGarfrostMoveLocs[1][2], 3 * m_creature->GetSpeed(MOVE_RUN), 10.0f, PHASE_MACE_ENCHANTMENT); m_uiPhase = PHASE_MOVEMENT; // Stop further action return; } if (m_uiChillingWaveTimer < uiDiff) { if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_CHILLING_WAVE) == CAST_OK) m_uiChillingWaveTimer = 14000; } else m_uiChillingWaveTimer -= uiDiff; break; } case PHASE_MACE_ENCHANTMENT: { if (m_uiDeepFreezeTimer < uiDiff) { if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) { if (DoCastSpellIfCan(pTarget, SPELL_DEEP_FREEZE) == CAST_OK) { DoScriptText(EMOTE_DEEP_FREEZE, m_creature, pTarget); m_uiDeepFreezeTimer = 20000; } } } else m_uiDeepFreezeTimer -= uiDiff; break; } } DoMeleeAttackIfReady(); }
void PlayerbotMageAI::DoNextCombatManeuver(Unit *pTarget) { if (!pTarget || pTarget->isDead()) return; PlayerbotAI *ai = GetAI(); if (!ai) return; Player *m_bot = GetPlayerBot(); if (!m_bot || m_bot->isDead()) return; Unit *pVictim = pTarget->getVictim(); Unit *m_tank = FindMainTankInRaid(GetMaster()); if (!m_tank && m_bot->GetGroup() && GetMaster()->GetGroup() != m_bot->GetGroup()) { FindMainTankInRaid(m_bot); } if (!m_tank) { m_tank = m_bot; } uint32 masterHP = GetMaster()->GetHealth()*100 / GetMaster()->GetMaxHealth(); float pDist = m_bot->GetDistance(pTarget); uint8 pThreat = GetThreatPercent(pTarget); #pragma region Choose Actions // Choose actions accoring to talents (MAGE is always ranged dps) m_role = BOT_ROLE_DPS_RANGED; // if i am under attack and if i am not tank or offtank: change target if needed if (isUnderAttack()) { // Keep hitting but reduce threat //else if (m_bot->getRace() == (uint8) RACE_NIGHTELF && CastSpell(R_SHADOWMELD,m_bot)) { return; } if (pVictim && pVictim->GetGUID() == m_bot->GetGUID() && pDist <= 2) { } // My target is almost up to me, no need to search else //Have to select nearest target { Unit *curAtt = GetNearestAttackerOf(m_bot); if (curAtt && curAtt->GetGUID() != pTarget->GetGUID()) { m_bot->SetSelection(curAtt->GetGUID()); DoNextCombatManeuver(curAtt); //Restart new update to get variables fixed.. return; } } //my target is attacking me } #pragma endregion TakePosition(pTarget); // If there's a cast stop if (m_bot->HasUnitState(UNIT_STAT_CASTING)) { return; } if (DoSupportRaid(m_bot,30,0,0,0,1,1)) { return; } if (m_tank->GetGUID() != m_bot->GetGUID() && pVictim && pVictim->GetGUID() == m_bot->GetGUID() ) { //if (CastSpell(INVISIBILITY, m_bot)) { return; } if (ai->GetHealthPercent(*pTarget) > 50 && CastSpell(POLYMORPH)) { return; } //if (m_bot->getRace() == (uint8) RACE_NIGHTELF && isUnderAttack() && CastSpell(R_SHADOWMELD, m_bot)) { return; } } if (isUnderAttack() && pDist > 5 && CastSpell(FROST_NOVA, pTarget)) { return; } if (DEEP_FREEZE && pTarget->isFrozen() && CastSpell(DEEP_FREEZE,pTarget)) { return; } if (isUnderAttack() && CastSpell(DRAGONS_BREATH, pTarget)) { return; } if ((isUnderAttack() || ai->GetHealthPercent() < 75 && !HasAuraName(m_bot, MANA_SHIELD)) && ai->GetManaPercent() > 40 && CastSpell(MANA_SHIELD,m_bot)) { return; } if (m_bot->getRace() == (uint8) RACE_DWARF && ai->GetHealthPercent() < 75 && CastSpell(R_STONEFORM,m_bot)) { } //no gcd if (m_bot->getRace() == (uint8) RACE_DRAENEI && ai->GetHealthPercent() < 55 && CastSpell(R_GIFT_OF_NAARU,m_bot)) { return; } //no Gcd, but has cast if (m_bot->getRace() == (uint8) RACE_TAUREN && pDist < 8 && CastSpell(R_WAR_STOMP, pTarget)) { return; } //no gcd but is cast if ((ai->GetHealthPercent() < 65 || ai->GetManaPercent() < 5) && CastSpell(ICE_BLOCK,m_bot)) { return; } if (isUnderAttack() && CastSpell(ICE_BARRIER, pTarget)) { return; } if (ai->GetManaPercent() < 30 && CastSpell (EVOCATION, m_bot)) { return; } //Break spells if (m_bot->getRace() == (uint8) RACE_BLOODELF && pDist < 8 && (pTarget->IsNonMeleeSpellCasted(true) || ai->GetManaPercent() < 40) && CastSpell(R_ARCANE_TORRENT, pTarget)) { } //no gcd else if (pThreat < threatThreshold && pTarget->IsNonMeleeSpellCasted(true) && CastSpell(COUNTER_SPELL, pTarget)) { return; } //High threat if (!m_bot->HasAura(MOLTEN_ARMOR) && CastSpell(MOLTEN_ARMOR,m_bot)) { return; } if (ai->GetHealthPercent(*pTarget) > 96) { return; } // dont dps too early //Catch if (pTarget->HasUnitMovementFlag(UNIT_FLAG_FLEEING)) { if (CastSpell(FROST_NOVA,pTarget)) return; if (CastSpell(FROSTBOLT,pTarget)) return; } // If at threat limit, try to reduce threat if (pThreat > threatThreshold && m_tank->GetGUID() != m_bot->GetGUID() && !isUnderAttack()) { if (m_tank->getVictim() && m_tank->getVictim()->GetGUID() != pTarget->GetGUID()) // I am attacking wrong target!! { m_bot->SetSelection(m_tank->getVictim()->GetGUID()); return; } else { if (CastSpell(INVISIBILITY,m_bot)) { return; } //Lets see if we can manage else if (m_bot->FindCurrentSpellBySpellId(SHOOT)) { m_bot->InterruptNonMeleeSpells( true, SHOOT ); return; } //Disable wand else { return; } //use no spells and wait threat to be reduced } } // buff up if (CastSpell(ICY_VEINS,m_bot)) {} //nogcd if (m_bot->getRace() == (uint8) RACE_TROLL && CastSpell(R_BERSERKING,m_bot)) {} //no GCD if (m_bot->getRace() == (uint8) RACE_ORC && CastSpell(R_BLOOD_FURY,m_bot)) {} //no GCD if (CastSpell(POM,m_bot)) {} //nogcd if (TALENT_ARCANE) { if (CastSpell(ARCANE_POWER,m_bot)) {} //nogcd if (CastSpell(MIRROR_IMAGE,m_bot)) { return; } //AOE if (isUnderAttack(m_tank,5)) { if (CastSpell(BLIZZARD,pTarget)) { return; } } //DPS if (ARCANE_BLAST) { Aura *abaura = m_bot->GetAura(P_ARCANE_BLAST); if (abaura && abaura->GetStackAmount() >= 3) { if (m_bot->HasAura(P_MISSILE_BARRAGE) && CastSpell(ARCANE_MISSILES,pTarget)) { return; } else if (CastSpell(ARCANE_BARRAGE,pTarget)) { return; } } } if (CastSpell(ARCANE_BARRAGE,pTarget) ) { return; } } if (TALENT_FIRE) { if (CastSpell(COMBUSTION,m_bot)) { } //nogcd if (CastSpell(MIRROR_IMAGE,m_bot)) { return; } //AOE if (isUnderAttack(m_tank,5)) { if (CastSpell(FLAMESTRIKE,pTarget)) { return; } if (CastSpell(BLAST_WAVE,pTarget)) { return; } if (CastSpell(LIVING_BOMB,pTarget)) { return; } if (CastSpell(DRAGONS_BREATH,pTarget)) { return; } } //DPS if (m_bot->HasAura(P_HOT_STREAK) && CastSpell(PYROBLAST,pTarget)) { return; } if (!pTarget->HasAura(LIVING_BOMB,m_bot->GetGUID()) && CastSpell(LIVING_BOMB,pTarget)) { return; } //if (!pTarget->HasAura(IMP_SCORCH) && CastSpell(SCORCH,pTarget)) { return; } if (CastSpell(FIREBALL,pTarget)) { return; } } if (TALENT_FROST) { if (CastSpell(MIRROR_IMAGE,m_bot)) { return; } if (CastSpell(WATER_ELEMENTAL,m_bot)) { return; } uint64 pet_guid = m_bot->GetPetGUID(); if (pet_guid>0){ Pet* pet = ObjectAccessor::GetPet(*m_bot, pet_guid); Unit *unit = ObjectAccessor::GetUnit(*m_bot, pet_guid); if (unit!=NULL){ if (!unit->isInCombat()) { m_bot->GetSession()->HandlePetActionHelper(unit, pet_guid, COMMAND_ATTACK, ACT_COMMAND, pTarget->GetGUID()); } } } //if (CastSpell(33395, pTarget)) // pet freeze spell // sLog.outError ("successfully casted freeze"); //AOE if (isUnderAttack(m_tank,5)) { if (CastSpell(BLIZZARD,pTarget)) { return; } } //DPS if (m_bot->HasAura(P_FINGERS_OF_FROST) && CastSpell(DEEP_FREEZE,pTarget)) { return; } if (m_bot->HasAura(P_BRAIN_FREEZE) && CastSpell(FROSTFIRE_BOLT,pTarget)) { return; } if (CastSpell(FROSTBOLT,pTarget,true,true)) { return; } } // Defaults especialy for lower levels if (m_bot->HasAura(P_BRAIN_FREEZE) && CastSpell(FIREBALL,pTarget,1,1)) { return; } if (m_bot->HasAura(P_FIRESTARTER) && CastSpell(FLAMESTRIKE,pTarget,1,1)) { return; } if (m_bot->HasAura(P_HOT_STREAK) && CastSpell(PYROBLAST,pTarget,1,1)) { return; } if (m_bot->HasAura(POM) && (CastSpell(PYROBLAST,pTarget,1,1) || CastSpell(FIREBALL,pTarget,1,1) || CastSpell(FROSTBOLT,pTarget,1,1))) { return; } if (pTarget->isFrozen() && CastSpell(ICE_LANCE,pTarget)) { return; } if (m_bot->isMoving() && (CastSpell(FIRE_BLAST,pTarget,1,1) || CastSpell(ARCANE_BARRAGE,pTarget) || CastSpell(ICE_LANCE,pTarget))) { return; } if (CastSpell(FIREBALL,pTarget)) { return; } if (CastSpell(FROSTBOLT,pTarget)) { return; } if (CastSpell(ARCANE_MISSILES,pTarget)) { return; } // drink potion if(ai->GetManaPercent() < 5 ) { Item *pItem = ai->FindPotion(); if(pItem != NULL) { if (pItem->GetSpell() && m_bot->HasSpellCooldown(pItem->GetSpell()) ) { return; } //pot is in cooldown ai->UseItem(*pItem); } } // if we get down here, it means we are out of mana, so use wand CastSpell(SHOOT, pTarget); } //end DoNextCombatManeuver
void HandleScriptEffect(SpellEffIndex /*effIndex*/) { Unit* caster = GetCaster(); Unit* unitTarget = GetHitUnit(); if (!unitTarget) return; uint32 spellId = 0; int32 basePoint = 0; Unit::AuraApplicationMap& Auras = unitTarget->GetAppliedAuras(); for (Unit::AuraApplicationMap::iterator i = Auras.begin(); i != Auras.end(); ++i) { Aura* aura = i->second->GetBase(); if (aura->GetCasterGUID() != caster->GetGUID()) continue; // Search only Serpent Sting, Viper Sting, Scorpid Sting auras flag96 familyFlag = aura->GetSpellProto()->SpellFamilyFlags; if (!(familyFlag[1] & 0x00000080 || familyFlag[0] & 0x0000C000)) continue; if (AuraEffect const * aurEff = aura->GetEffect(0)) { // Serpent Sting - Instantly deals 40% of the damage done by your Serpent Sting. if (familyFlag[0] & 0x4000) { int32 TickCount = aurEff->GetTotalTicks(); spellId = HUNTER_SPELL_CHIMERA_SHOT_SERPENT; basePoint = caster->SpellDamageBonus(unitTarget, aura->GetSpellProto(), aurEff->GetAmount(), DOT, aura->GetStackAmount()); basePoint = basePoint * TickCount * 40 / 100; } // Viper Sting - Instantly restores mana to you equal to 60% of the total amount drained by your Viper Sting. else if (familyFlag[1] & 0x00000080) { int32 TickCount = aura->GetEffect(0)->GetTotalTicks(); spellId = HUNTER_SPELL_CHIMERA_SHOT_VIPER; // Amount of one aura tick basePoint = aurEff->GetAmount() * unitTarget->GetMaxPower(POWER_MANA) / 100 ; int32 casterBasePoint = aurEff->GetAmount() * unitTarget->GetMaxPower(POWER_MANA) / 50 ; if (basePoint > casterBasePoint) basePoint = casterBasePoint; basePoint = basePoint * TickCount * 60 / 100; } // Scorpid Sting - Attempts to Disarm the target for 10 sec. This effect cannot occur more than once per 1 minute. else if (familyFlag[0] & 0x00008000) spellId = HUNTER_SPELL_CHIMERA_SHOT_SCORPID; // ?? nothing say in spell desc (possibly need addition check) //if (familyFlag & 0x0000010000000000LL || // dot // familyFlag & 0x0000100000000000LL) // stun //{ // spellId = 53366; // 53366 Chimera Shot - Wyvern //} // Refresh aura duration aura->RefreshDuration(); } break; } if (spellId) caster->CastCustomSpell(unitTarget, spellId, &basePoint, 0, 0, true); if (spellId == HUNTER_SPELL_CHIMERA_SHOT_SCORPID && caster->ToPlayer()) // Scorpid Sting - Add 1 minute cooldown caster->ToPlayer()->AddSpellCooldown(spellId,0,uint32(time(NULL) + 60)); }
void UpdateAI(const uint32 uiDiff) { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; if (m_bTimeToDie) { FakeDeath(); return; } if (m_bDead) { if (m_uiRespawnTimer < uiDiff) { m_creature->SetHealth(m_creature->GetMaxHealth()); m_creature->SetVisibility(VISIBILITY_OFF); Init(); m_creature->MonsterTextEmote("%s appears to defend Emalon!", 0, true); if (m_pInstance) { Creature* pEmalon = (Creature*)Unit::GetUnit((*m_creature), m_pInstance->GetData64(DATA_EMALON)); if (pEmalon) { Unit* pTarget = pEmalon->getVictim(); if (pTarget) m_creature->GetMotionMaster()->MoveChase(pTarget); } } return; } else { m_uiRespawnTimer -= uiDiff; return; } } Aura* pAuraOvercharged = m_creature->GetAura(SPELL_OVERCHARGED, 0); if(pAuraOvercharged && pAuraOvercharged->GetStackAmount() >= 10) { DoCast(m_creature, SPELL_OVERCHARGED_BLAST); m_bTimeToDie = true; return; } if(m_uiShockTimer < uiDiff) { DoCast(m_creature->getVictim(), SPELL_SHOCK); m_uiShockTimer = 8000+rand()%4000; } else m_uiShockTimer -= uiDiff; if(m_uiEvadeCheckTimer < uiDiff) { if(m_creature->GetDistance2d(-229.11f, -289.03f) > 70.0f) EnterEvadeMode(); m_uiEvadeCheckTimer = 2000; } else m_uiEvadeCheckTimer -= uiDiff; DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 uiDiff) { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; if (m_uiEvadeCheckCooldown < uiDiff) { Creature* pEmalon = m_pInstance->GetSingleCreatureFromStorage(NPC_EMALON); if ((pEmalon && pEmalon->IsInEvadeMode()) || (m_creature->GetDistance2d(-219.119f, -289.037f) > 80.0f)) { EnterEvadeMode(); return; } m_uiEvadeCheckCooldown = 2000; } else m_uiEvadeCheckCooldown -= uiDiff; if (m_bTimeToDie) { FakeDeath(); return; } if (m_bDead) { if (m_uiRespawnTimer < uiDiff) { m_creature->SetHealth(m_creature->GetMaxHealth()); m_creature->SetVisibility(VISIBILITY_OFF); Init(); m_creature->MonsterTextEmote("%s appears to defend Emalon!", NULL, true); m_creature->SetInCombatWithZone(); DoResetThreat(); if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) m_creature->GetMotionMaster()->MoveChase(pTarget); } else m_uiRespawnTimer -= uiDiff; return; } if (m_uiOverchargedStacksCheckTimer < uiDiff) { m_uiOverchargedStacksCheckTimer = 2000; Aura* pAuraOvercharged = m_creature->GetAura(SPELL_OVERCHARGED, EFFECT_INDEX_0); if(pAuraOvercharged && pAuraOvercharged->GetStackAmount() >= 10) { DoCastSpellIfCan(m_creature, SPELL_OVERCHARGED_BLAST); m_bTimeToDie = true; return; } } else m_uiOverchargedStacksCheckTimer -= uiDiff; if (m_uiShockTimer < uiDiff) { DoCastSpellIfCan(m_creature->getVictim(), SPELL_SHOCK); m_uiShockTimer = 8000+rand()%4000; } else m_uiShockTimer -= uiDiff; DoMeleeAttackIfReady(); }
void PlayerbotShamanAI::DoNextCombatManeuver(Unit *pTarget) { if (!pTarget || pTarget->isDead()) return; PlayerbotAI *ai = GetAI(); if (!ai) return; Player *m_bot = GetPlayerBot(); if (!m_bot || m_bot->isDead()) return; Unit *pVictim = pTarget->getVictim(); Unit *m_tank = FindMainTankInRaid(GetMaster()); if (!m_tank && m_bot->GetGroup() && GetMaster()->GetGroup() != m_bot->GetGroup()) { FindMainTankInRaid(m_bot); } if (!m_tank) { m_tank = m_bot; } uint32 masterHP = GetMaster()->GetHealth()*100 / GetMaster()->GetMaxHealth(); float pDist = m_bot->GetDistance(pTarget); uint8 pThreat = GetThreatPercent(pTarget); uint8 reqHeal = 0; uint8 OwnPartyHP = GetHealthPercentRaid(m_bot, reqHeal); switch(ai->GetScenarioType()) { case SCENARIO_DUEL: ((ai->GetHealthPercent() < 80 && CastSpell(LESSER_HEAL)) || CastSpell(LIGHTNING_BOLT, pTarget)); return; } // Cast CC breakers if any match found (include any dispels first) does not work yet //uint32 ccSpells[4] = { R_ESCAPE_ARTIST, R_EVERY_MAN_FOR_HIMSELF, R_WILL_OF_FORSAKEN, R_STONEFORM }; //if (ai->GetManaPercent() < 35) { ccSpells[0] = 0; ccSpells[1] = 0; } //We dont have any mana to waste... //if (castSelfCCBreakers(ccSpells)) { } // Most of them don't trigger gcd #pragma region Choose Actions // Choose actions accoring to talents if (m_tank->GetGUID() == m_bot->GetGUID()) { m_role=BOT_ROLE_TANK; } // Hey! I am Main Tank else if (TALENT_ENHANCEMENT) { m_role = BOT_ROLE_DPS_MELEE; } else if (TALENT_ELEMENTAL) { m_role = BOT_ROLE_DPS_RANGED; } else if (TALENT_RESTO) { m_role = BOT_ROLE_SUPPORT; } else { m_role = BOT_ROLE_DPS_MELEE; } //Unknown build or low level.. Mainly attack // if i am under attack and if i am not tank or offtank: change target if needed if (m_tank->GetGUID() != m_bot->GetGUID() && isUnderAttack() ) { if (pVictim && pVictim->GetGUID() == m_bot->GetGUID() && pDist <= 2) { } // My target is almost up to me, no need to search else //Have to select nearest target { Unit *curAtt = GetNearestAttackerOf(m_bot); if (curAtt && curAtt->GetGUID() != pTarget->GetGUID()) { m_bot->SetSelection(curAtt->GetGUID()); //ai->AddLootGUID(curAtt->GetGUID()); DoNextCombatManeuver(curAtt); //Restart new update to get variables fixed.. return; } } //my target is attacking me } #pragma endregion // Choose Weapon Enchant if (ChangeWeaponEnchants()) return; if (TALENT_ELEMENTAL){ if (!m_bot->HasAura(WATER_SHIELD) && CastSpell(WATER_SHIELD,m_bot)) { return; }} if (TALENT_ENHANCEMENT){ if (!m_bot->HasAura(LIGHTNING_SHIELD) && CastSpell(LIGHTNING_SHIELD,m_bot)) { return; }} if (TALENT_RESTO){ if (!m_bot->HasAura(WATER_SHIELD) && CastSpell(WATER_SHIELD,m_bot)) { return; }} // Choose shield /* if (EARTH_SHIELD && ai->GetHealthPercent() < 80 && isUnderAttack()) { if (CastSpell(EARTH_SHIELD,m_bot)) { return; } } else if (WATER_SHIELD && ai->GetManaPercent() < 40) { if (CastSpell(WATER_SHIELD,m_bot)) { return; } } else if (LIGHTNING_SHIELD && ( isUnderAttack() || m_tank->GetGUID() == m_bot->GetGUID() ) && !(m_bot->HasAura(WATER_SHIELD) && ai->GetManaPercent() < 80) ) { if (CastSpell(LIGHTNING_SHIELD,m_bot)) { return; } } else if (CastSpell(WATER_SHIELD,m_bot)) { return; } */ // If there's a cast stop if(m_bot->HasUnitState(UNIT_STAT_CASTING)) return; switch(m_role) { #pragma region BOT_ROLE_TANK / BOT_ROLE_OFFTANK case BOT_ROLE_TANK: case BOT_ROLE_OFFTANK: if (!TALENT_ELEMENTAL && !TALENT_RESTO) { TakePosition(pTarget); } else { TakePosition(pTarget,BOT_ROLE_DPS_RANGED); } // mob will come to you sooner or later no need to hurry // Do support stuff if (!m_bot->isMoving() && ChangeTotems(m_role)) { return; } if (ai->GetManaPercent() > 70 && DoSupportRaid(m_bot)) { return; } break; #pragma endregion #pragma region BOT_ROLE_DPS_MELEE case BOT_ROLE_DPS_MELEE: TakePosition(pTarget); // Do support stuff if (!m_bot->isMoving() && ChangeTotems(m_role)) { return; } if (ai->GetManaPercent() > 40 && DoSupportRaid(m_bot)) { return; } break; #pragma endregion #pragma region BOT_ROLE_DPS_RANGED case BOT_ROLE_DPS_RANGED: TakePosition(pTarget); // Do support stuff if (!m_bot->isMoving() && ChangeTotems(m_role)) { return; } if (ai->GetManaPercent() > 40 && DoSupportRaid(m_bot)) { return; } break; #pragma endregion #pragma region BOT_ROLE_SUPPORT case BOT_ROLE_SUPPORT: TakePosition(pTarget); // Do support stuff if (!m_bot->isMoving() && ChangeTotems(m_role)) { return; } if (DoSupportRaid(m_bot)) { return; } //heal pets and bots Unit *target = DoSelectLowestHpFriendly(40, 1000); if(target && target->isAlive() && HealTarget(target, target->GetHealth()*100 / target->GetMaxHealth()) ) { return; } break; #pragma endregion } #pragma region ShamanCommon //Defensive Stuff if (m_tank->GetGUID() != m_bot->GetGUID() && pVictim && pVictim->GetGUID() == m_bot->GetGUID() ) { if (pDist > 5 && CastSpell(FROST_SHOCK, pTarget)) { return; } if ((pTarget->GetCreatureType() == (uint32) CREATURE_TYPE_BEAST || pTarget->GetCreatureType() == (uint32) CREATURE_TYPE_HUMANOID) && CastSpell(HEX, pTarget)) { return; } // no gcd if (CastSpell(WIND_SHEAR, pTarget)) { } // no gcd } if (m_bot->getRace() == (uint8) RACE_BLOODELF && pDist < 8 && pTarget->IsNonMeleeSpellCasted(true) && CastSpell(R_ARCANE_TORRENT, pTarget)) { } //no gcd if (pTarget->IsNonMeleeSpellCasted(true) && CastSpell(WIND_SHEAR, pTarget)) { } //no gcd if (m_bot->getRace() == (uint8) RACE_TAUREN && pVictim && pVictim->GetGUID() == m_bot->GetGUID() && pDist < 8 && CastSpell(R_WAR_STOMP, pTarget)) { return; } //Catch if (pTarget->HasUnitMovementFlag(UNIT_FLAG_FLEEING)) { if (CastSpell(FROST_SHOCK,pTarget)) return; } //Buff and restores if ( ( (ai->GetHealthPercent() < 60 && isUnderAttack()) || (ai->GetManaPercent() < 30) ) && CastSpell(SHAMANISTIC_RAGE, m_bot)) { return; } if (m_bot->getRace() == (uint8) RACE_TROLL && CastSpell(R_BERSERKING,m_bot)) {} // no GCD if (m_bot->getRace() == (uint8) RACE_ORC && CastSpell(R_BLOOD_FURY,m_bot)) {} // no GCD if (!m_bot->HasAura(HEROISM) && !m_bot->HasAura(EXHAUSTION) && !m_bot->HasAura(SATED) && CastSpell(HEROISM,m_bot)) { return; } if (m_role != BOT_ROLE_SUPPORT && CastSpell(NATURES_SWIFTNESS, m_bot)) { } //healers keep it for healing no gcd else if (CastSpell(ELEMENTAL_MASTERY, m_bot)) { } //no gcd // If at threat limit, use WIND_SHEAR to reduce threat if (pThreat > threatThreshold && m_tank->GetGUID() != m_bot->GetGUID() && !isUnderAttack()) { if (m_tank->getVictim() && m_tank->getVictim()->GetGUID() != pTarget->GetGUID()) // I am attacking wrong target!! { m_bot->SetSelection(m_tank->getVictim()->GetGUID()); return; } else { if (CastSpell(WIND_SHEAR,pTarget)) { return; } //Lets see if we can manage else { return; } //use no spells and wait threat to be reduced } } if (TALENT_ELEMENTAL) { if (CastSpell(ELEMENTAL_MASTERY, m_bot)) { } //no gcd if (!pTarget->HasAura(FLAME_SHOCK,m_bot->GetGUID()) && CastSpell(FLAME_SHOCK,pTarget)) { return; } if (CastSpell(LAVA_BURST,pTarget)) { return; } if (CastSpell(CHAIN_LIGHTNING,pTarget)) { return; } if (CastSpell(LIGHTNING_BOLT,pTarget)) { return; } } //dps if (MAELSTROM_WEAPON) { Aura *maelaura = m_bot->GetAura(MAELSTROM_WEAPON); if (maelaura && maelaura->GetStackAmount() == 5) { if ((isUnderAttack(m_tank,3) || m_tank->GetGUID() == m_bot->GetGUID()) && CastSpell(CHAIN_LIGHTNING,pTarget,true,true)) { return; } if (CastSpell(LIGHTNING_BOLT,pTarget,true,true)) { return; } } } if (CastSpell(FLAME_SHOCK,pTarget)) { return; } if (CastSpell(STORMSTRIKE,pTarget,true,true)) { return; } //if (!TALENT_ENHANCEMENT && CanCast(LAVA_BURST,pTarget,true) && pTarget->HasAura(FLAME_SHOCK,m_bot->GetGUID()) && CastSpell(LAVA_BURST,pTarget,false)) { return; } if (CastSpell(FERAL_SPIRIT,m_bot)) { return; } if (CanCast(EARTH_SHOCK,pTarget,true) && (pTarget->HasAura(STORMSTRIKE,m_bot->GetGUID()) || pTarget->HasAura(FLAME_SHOCK,m_bot->GetGUID()) ) && CastSpell(EARTH_SHOCK,pTarget)) { return; } //if (CanCast(FLAME_SHOCK,pTarget) && CastSpell(FLAME_SHOCK,pTarget)) { return; } if (CastSpell(LAVA_LASH,pTarget,true,true)) { return; } if (CastSpell(FIRE_NOVA,pTarget)) { return; } //if ((isUnderAttack(m_tank,4) || m_tank->GetGUID() == m_bot->GetGUID()) && CastSpell(FIRE_NOVA,pTarget)) { return; } if (ai->GetManaPercent() > 60 && castDispel(PURGE,pTarget)) { return; } //PURGE but dont overpurge #pragma endregion // drink potion if support / healer (Other builds simply overuse mana and waste mana pots) if(ai->GetManaPercent() < 5 && (m_role == BOT_ROLE_SUPPORT || m_role == BOT_ROLE_HEALER) ) { Item *pItem = ai->FindPotion(); if(pItem != NULL) { if (pItem->GetSpell() && m_bot->HasSpellCooldown(pItem->GetSpell()) ) { return; } //pot is in cooldown ai->UseItem(*pItem); } } } //end DoNextCombatManeuver
void UpdateAI(const uint32 diff) { //Return since we have no target if (!UpdateVictim()) return; if (uiSpawnTimer <= diff) { uint32 spawnNumber = urand(2, DUNGEON_MODE(3, 5)); for (uint8 i = 0; i < spawnNumber; ++i) if (Creature* temp = DoSummon(RAND(NPC_DRAKKARI_INVADER_1, NPC_DRAKKARI_INVADER_2), AddSpawnPoint, 0, TEMPSUMMON_DEAD_DESPAWN)) { if (temp->GetAI()) { temp->GetAI()->AttackStart(me); temp->AddThreat(me, 5000000.0f); } } uiSpawnTimer = urand(30*IN_MILLISECONDS, 40*IN_MILLISECONDS); } else uiSpawnTimer -= diff; if (uiConsumeTimer <= diff) { std::list<HostileReference *> t_list = me->getThreatManager().getThreatList(); if (!t_list.empty()) { for (std::list<HostileReference *>::const_iterator itr = t_list.begin(); itr!= t_list.end(); ++itr) { if (Unit* target = Unit::GetUnit((*me), (*itr)->getUnitGuid())) { if (me->GetDistance(target) <= 50.0f && target->isAlive() && me->IsValidAttackTarget(target)) { // Apply aura for every target in 50yards ~ 45m DoCast(me, DUNGEON_MODE(SPELL_CONSUME_AURA, H_SPELL_CONSUME), true); } } } } DoScriptText(SAY_CONSUME, me); DoCast(SPELL_CONSUME); uiConsumeTimer = 15*IN_MILLISECONDS; } else uiConsumeTimer -= diff; if (consumptionJunction) { Aura* ConsumeAura = me->GetAura(DUNGEON_MODE(SPELL_CONSUME_AURA, H_SPELL_CONSUME_AURA)); if (ConsumeAura && ConsumeAura->GetStackAmount() > 9) consumptionJunction = false; } if (uiCrushTimer <= diff) { DoCastVictim(SPELL_CRUSH); uiCrushTimer = urand(10*IN_MILLISECONDS, 15*IN_MILLISECONDS); } else uiCrushTimer -= diff; if (uiInfectedWoundTimer <= diff) { DoCastVictim(SPELL_INFECTED_WOUND); uiInfectedWoundTimer = urand(25*IN_MILLISECONDS, 35*IN_MILLISECONDS); } else uiInfectedWoundTimer -= diff; if (uiExplodeCorpseTimer <= diff) { std::list<Creature*> addList; me->GetCreatureListWithEntryInGrid(addList,NPC_DRAKKARI_INVADER_1, 10.0f); me->GetCreatureListWithEntryInGrid(addList,NPC_DRAKKARI_INVADER_2, 10.0f); if(!addList.empty()) { DoCast(SPELL_CORPSE_EXPLODE); DoScriptText(SAY_EXPLODE, me); for(std::list<Creature*>::iterator i = addList.begin(); i != addList.end(); i++) { if ((*i)) { if(!(*i)->isAlive()) { DoCast((*i), DUNGEON_MODE(SPELL_CORPSE_EXPLODE_NH, SPELL_CORPSE_EXPLODE_HC), true); (*i)->DespawnOrUnsummon(); } } } } uiExplodeCorpseTimer = urand(15*IN_MILLISECONDS, 19*IN_MILLISECONDS); } else uiExplodeCorpseTimer -= diff; DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 diff) { if (!UpdateVictim()) return; if (me->getVictim() && !me->getVictim()->GetCharmerOrOwnerPlayerOrPlayerItself()) me->Kill(me->getVictim()); events.Update(diff); if (me->hasUnitState(UNIT_STAT_CASTING)) return; if (uiCheckIntenseColdTimer < diff && !bMoreThanTwoIntenseCold) { std::list<HostileReference*> ThreatList = me->getThreatManager().getThreatList(); for (std::list<HostileReference*>::const_iterator itr = ThreatList.begin(); itr != ThreatList.end(); ++itr) { Unit *pTarget = Unit::GetUnit(*me, (*itr)->getUnitGuid()); if (!pTarget || pTarget->GetTypeId() != TYPEID_PLAYER) continue; Aura *AuraIntenseCold = pTarget->GetAura(SPELL_BITING_COLD_TRIGGERED); if (AuraIntenseCold && AuraIntenseCold->GetStackAmount() > 2) { bMoreThanTwoIntenseCold = true; break; } } uiCheckIntenseColdTimer = 2000; } else uiCheckIntenseColdTimer -= diff; while(uint32 eventId = events.ExecuteEvent()) { switch(eventId) { case EVENT_FREEZE: DoCastAOE(SPELL_FREEZE); events.ScheduleEvent(EVENT_FREEZE, urand(30000, 35000)); break; case EVENT_ICICLE: if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)) if (pTarget->isAlive()) DoCast(pTarget, SPELL_ICICLE); events.ScheduleEvent(EVENT_ICICLE, 2000); break; case EVENT_FLASH_CAST: DoScriptText(SAY_FLASH_FREEZE, me); me->MonsterTextEmote(EMOTE_FREEZE, 0, true); for (uint32 i = 0; i < RAID_MODE(2,3); ++i) if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)) if (pTarget->isAlive()) pTarget->CastSpell(pTarget, SPELL_ICICLE_SNOWDRIFT, true); DoCast(SPELL_FLASH_FREEZE); events.RescheduleEvent(EVENT_ICICLE, 15000); events.ScheduleEvent(EVENT_FLASH_CAST, 50000); events.ScheduleEvent(EVENT_FLASH_EFFECT, 9000); break; case EVENT_FLASH_EFFECT: DoCast(SPELL_FLASH_FREEZE_VISUAL); FlashFreeze(); events.CancelEvent(EVENT_FLASH_EFFECT); break; case EVENT_BLOWS: DoScriptText(SAY_STALACTITE, me); me->MonsterTextEmote(EMOTE_BLOWS, 0, true); DoCast(me, RAID_MODE(SPELL_FROZEN_BLOWS_10, SPELL_FROZEN_BLOWS_25)); events.ScheduleEvent(EVENT_BLOWS, urand(60000, 65000)); break; case EVENT_RARE_CACHE: DoScriptText(SAY_HARD_MODE_MISSED, me); RareCache = false; events.CancelEvent(EVENT_RARE_CACHE); break; case EVENT_BERSERK: DoCast(me, SPELL_BERSERK, true); DoScriptText(SAY_BERSERK, me); events.CancelEvent(EVENT_BERSERK); break; } } DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 diff) { if (!UpdateVictim()) return; if (Creature* rotface = Unit::GetCreature(*me, instance->GetData64(DATA_ROTFACE))) { if (!rotface->IsAlive()) me->Kill(me); // Meurt si Rotface meurt } else me->Kill(me); // Meurt si pas de Rotface events.Update(diff); while (uint32 eventId = events.ExecuteEvent()) { switch (eventId) { case EVENT_STICKY_OOZE: DoCastVictim(SPELL_STICKY_OOZE); events.ScheduleEvent(EVENT_STICKY_OOZE, 15000); break; case EVENT_CHECK_EXPLODE: { if (hasExploded) break; Aura *unstable = me->GetAura(SPELL_UNSTABLE_OOZE); if (unstable != NULL) { uint8 stack = uint8(unstable->GetStackAmount()); // explode! if (stack >= 5) { me->RemoveAurasDueToSpell(SPELL_LARGE_OOZE_BUFF_COMBINE); me->RemoveAurasDueToSpell(SPELL_LARGE_OOZE_COMBINE); if (InstanceScript* instance = me->GetInstanceScript()) if (Creature* rotface = Unit::GetCreature(*me, instance->GetData64(DATA_ROTFACE))) if (rotface->IsAlive()) { rotface->AI()->Talk(EMOTE_UNSTABLE_EXPLOSION); rotface->AI()->Talk(SAY_UNSTABLE_EXPLOSION); } DoAction(EVENT_STICKY_OOZE); me->CastSpell(me, SPELL_UNSTABLE_OOZE_EXPLOSION, false, NULL, NULL, me->GetGUID()); if (InstanceScript* instance = me->GetInstanceScript()) instance->SetData(DATA_OOZE_DANCE_ACHIEVEMENT, uint32(false)); hasExploded = true; } } events.ScheduleEvent(EVENT_CHECK_EXPLODE, 500); break; } default: break; } } if (me->IsVisible()) DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 diff) { if (!CanDoSomething()) return; if (m_uiEvadeCheckCooldown < diff) { Creature* pEmalon = (Creature*)Unit::GetUnit((*me), pInstance->GetData64(DATA_EMALON)); if ((pEmalon && pEmalon->IsInEvadeMode()) || (me->GetDistance2d(-219.119f, -289.037f) > 80.0f)) { EnterEvadeMode(); return; } m_uiEvadeCheckCooldown = 2000; } else m_uiEvadeCheckCooldown -= diff; if (m_bTimeToDie) { FakeDeath(); return; } if (m_bDead) { if (m_uiRespawnTimer < diff) { me->SetHealth(me->GetMaxHealth()); me->SetVisibility(VISIBILITY_OFF); Init(); Speak(CHAT_TYPE_BOSS_EMOTE,0,"Un seide de la tempete vient defendre Emalon !"); me->SetInCombatWithZone(); DoResetThreat(); if (Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0)) me->GetMotionMaster()->MoveChase(pTarget); } else m_uiRespawnTimer -= diff; return; } if (m_uiOverchargedStacksCheckTimer < diff) { m_uiOverchargedStacksCheckTimer = 2000; Aura* pAuraOvercharged = me->GetAura(SPELL_OVERCHARGED, 0); if(pAuraOvercharged && pAuraOvercharged->GetStackAmount() >= 10) { DoCast(me, SPELL_OVERCHARGED_BLAST); m_bTimeToDie = true; return; } } else m_uiOverchargedStacksCheckTimer -= diff; Tasks.UpdateEvent(diff); DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 uiDiff) { //despawn after 1 hour timer if(!IsFirstTime) { if(m_uiDespawnTimer < uiDiff) { IsFirstTime = true; DoStopAttack(); CombatStopped = true; m_creature->RemoveAllAuras(); m_creature->setFaction(35); //friendly events.Reset(); //schedule says SayEvents.Reset(); SayEvents.ScheduleEvent(SAYEVENT_END1, 0); SayEvents.ScheduleEvent(SAYEVENT_END2, (10)*IN_MILLISECONDS); SayEvents.ScheduleEvent(SAYEVENT_END3, (10+8)*IN_MILLISECONDS); } else m_uiDespawnTimer -= uiDiff; } SayEvents.Update(uiDiff); while (uint32 eventId = SayEvents.ExecuteEvent()) { switch (eventId) { case SAYEVENT_END1: DoScriptText(SAY_END_1, m_creature); break; case SAYEVENT_END2: DoScriptText(SAY_END_2, m_creature); break; case SAYEVENT_END3: DoScriptText(SAY_END_3, m_creature); m_creature->SetVisibility(VISIBILITY_OFF); EnterEvadeMode(); break; case SAYEVENT_ENTER1: DoScriptText(SAY_ENTER_1, m_creature); break; case SAYEVENT_ENTER2: DoScriptText(SAY_ENTER_2, m_creature); break; case SAYEVENT_ENTER3: DoScriptText(SAY_ENTER_3, m_creature); HasSaidBeginningStuff = true; break; case SAYEVENT_DEFEATED1: DoScriptText(SAY_DEFEATED_1, m_creature); break; case SAYEVENT_DEFEATED2: DoScriptText(SAY_DEFEATED_2, m_creature); break; case SAYEVENT_DEFEATED3: DoScriptText(SAY_DEFEATED_3, m_creature); break; case SAYEVENT_DEFEATED4: DoScriptText(SAY_DEFEATED_4, m_creature); break; case SAYEVENT_DEFEATED5: DoScriptText(SAY_DEFEATED_5, m_creature); m_creature->SetVisibility(VISIBILITY_OFF); EnterEvadeMode(); break; default: break; } } if (CombatStopped || !m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; if (IsOutOfCombatArea(m_creature)) { EnterEvadeMode(); return; } //check for phase 2 at 20% health if(!IsPhase2) { if(m_creature->GetHealthPercent() < 20.0f) { IsPhase2 = true; DoScriptText(SAY_START_PHASE_2, m_creature); events.CancelEvent(EVENT_SUMMON_STARS); events.CancelEvent(EVENT_SUMMON_CONSTELLATION); UnSummonAllCreatures(); //4 black holes in square pattern const float pos[4][2] = {{10,0}, {-10,0}, {0,10}, {0,-10}}; for (int i = 0; i < 4; i++) DoSpawnCreature(NPC_BLACK_HOLE, pos[i][0], pos[i][1], 0, 0, TEMPSUMMON_CORPSE_DESPAWN, 1000); DoScriptText(SAY_SUMMON_STARS, m_creature); events.ScheduleEvent(EVENT_SUMMON_STARS,SUMMON_STARS_TIMER); } } //switch targets to next top aggro if phase punch stacks >= 5 if (Unit *TopAggro = m_creature->SelectAttackingTarget(ATTACKING_TARGET_TOPAGGRO_PLAYER, 0)) { Aura *aur = TopAggro->GetAura(SPELL_PHASE_PUNCH, EFFECT_INDEX_0); if (aur && aur->GetStackAmount() >= 5) if (Unit *NextTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_TOPAGGRO_PLAYER, 1)) m_creature->Attack(NextTarget, true); } events.Update(uiDiff); while (uint32 eventId = events.ExecuteEvent()) { switch (eventId) { case EVENT_BERSERK: DoCast(m_creature, SPELL_BERSERK); //events.ScheduleEvent(EVENT_BERSERK, 10*IN_MILLISECONDS); DoScriptText(SAY_BERSERK, m_creature); DoScriptText(EMOTE_BERSERK, m_creature); break; case EVENT_QUANTUM_STRIKE: DoCast(m_creature->getVictim(), HEROIC(SPELL_QUANTUM_STRIKE, SPELL_QUANTUM_STRIKE_H)); events.ScheduleEvent(EVENT_QUANTUM_STRIKE, QUANTUM_STRIKE_TIMER); break; case EVENT_PHASE_PUNCH: DoCast(m_creature->getVictim(), SPELL_PHASE_PUNCH); events.ScheduleEvent(EVENT_PHASE_PUNCH, PHASE_PUNCH_TIMER); break; case EVENT_ASCEND_TO_HEAVENS: DoCast(m_creature->getVictim(), SPELL_ASCEND_TO_HEAVENS); events.ScheduleEvent(EVENT_ASCEND_TO_HEAVENS, 5*IN_MILLISECONDS); //just in case they survive... hehehe break; case EVENT_SUMMON_STARS: if(!IsPhase2) { size_t n_stars = CurrSummons.count(NPC_COLLAPSING_STAR); if (n_stars > MAX_STARS) //shouldnt happen break; for(size_t i = 0; i < MAX_STARS-n_stars; i++) //respawn missing stars { float x, y; GetRandomPointInCircle(30.0f, x, y); DoSpawnCreature(NPC_COLLAPSING_STAR, x, y, 0, 0, TEMPSUMMON_CORPSE_DESPAWN, 1000); } if (MAX_STARS-n_stars > 0) //summoned at least one DoScriptText(SAY_SUMMON_STARS, m_creature); events.ScheduleEvent(EVENT_SUMMON_STARS, SUMMON_STARS_TIMER); } break; case EVENT_SUMMON_CONSTELLATION: if (CurrSummons.count(NPC_LIVING_CONSTELLATION) > MAX_CONSTELLATIONS) //just to avoid infinite summons break; for(int i=0; i<3; i++) { float x, y; GetRandomPointInCircle(30.0f, x, y); DoSpawnCreature(NPC_LIVING_CONSTELLATION, x, y, 0, 0, TEMPSUMMON_CORPSE_DESPAWN, 1000); } events.ScheduleEvent(EVENT_SUMMON_CONSTELLATION, SUMMON_CONSTELLATION_TIMER); break; case EVENT_COSMIC_SMASH: //TODO: mark destination point (don't know the spell) DoScriptText(EMOTE_COSMIC_SMASH, m_creature); events.ScheduleEvent(EVENT_COSMIC_SMASH_EFFECT, 2*IN_MILLISECONDS); events.ScheduleEvent(EVENT_COSMIC_SMASH, COSMIC_SMASH_TIMER); break; case EVENT_COSMIC_SMASH_EFFECT: for (int i = 0; i < HEROIC(1, 3); i++) { float x, y; GetRandomPointInCircle(30.0f, x, y); m_creature->CastSpell(m_creature->GetPositionX()+x, m_creature->GetPositionY()+y, m_creature->GetPositionZ()+0.5f, HEROIC(SPELL_COSMIC_SMASH, SPELL_COSMIC_SMASH_H), true); } break; default: break; } } DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 uiDiff) override { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; // This needs to be checked only on heroic if (!m_bIsRegularMode) { if (uiCheckIntenseColdTimer < uiDiff) { ThreatList playerList = m_creature->GetThreatManager().getThreatList(); for (ThreatList::const_iterator itr = playerList.begin(); itr != playerList.end(); ++itr) { if (Player* pTarget = m_creature->GetMap()->GetPlayer((*itr)->getUnitGuid())) { Aura* pAuraIntenseCold = pTarget->GetAura(SPELL_INTENSE_COLD_AURA, EFFECT_INDEX_0); if (pAuraIntenseCold) { if (pAuraIntenseCold->GetStackAmount() > MAX_INTENSE_COLD_STACK) { if (m_pInstance) m_pInstance->SetData(TYPE_INTENSE_COLD_FAILED, pTarget->GetGUIDLow()); } } } } uiCheckIntenseColdTimer = 1000; } else uiCheckIntenseColdTimer -= uiDiff; } if (!m_bIsEnraged && m_creature->GetHealthPercent() < 25.0f) { if (!m_creature->IsNonMeleeSpellCasted(false)) { m_bIsEnraged = true; DoScriptText(SAY_ENRAGE, m_creature); DoCastSpellIfCan(m_creature, SPELL_ENRAGE); } } if (uiCrystalChainTimer < uiDiff) { if (!m_creature->IsNonMeleeSpellCasted(false)) { if (m_bIsRegularMode) { if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 1)) { if (Player* pPlayer = pTarget->GetCharmerOrOwnerPlayerOrPlayerItself()) DoCastSpellIfCan(pPlayer, SPELL_CRYSTAL_CHAINS); uiCrystalChainTimer = 30000; } } else { if (Unit* pSource = m_creature->getVictim()) { uiCrystalChainTimer = 15000; Player* pPlayer = pSource->GetCharmerOrOwnerPlayerOrPlayerItself(); if (!pPlayer) return; if (Group* pGroup = pPlayer->GetGroup()) { for (GroupReference* pRef = pGroup->GetFirstMember(); pRef != NULL; pRef = pRef->next()) { if (Player* pMember = pRef->getSource()) { if (pMember->IsAlive() && pMember->IsWithinDistInMap(m_creature, 50.0f)) m_creature->CastSpell(pMember, SPELL_CRYSTAL_CHAINS, true); } } } else m_creature->CastSpell(pPlayer, SPELL_CRYSTAL_CHAINS, false); } } } } else uiCrystalChainTimer -= uiDiff; if (uiTailSweepTimer < uiDiff) { if (DoCastSpellIfCan(m_creature, SPELL_TAIL_SWEEP) == CAST_OK) uiTailSweepTimer = urand(2500, 7500); } else uiCrystalChainTimer -= uiDiff; if (uiCrystalfireBreathTimer < uiDiff) { if (DoCastSpellIfCan(m_creature, m_bIsRegularMode ? SPELL_CRYSTALFIRE_BREATH : SPELL_CRYSTALFIRE_BREATH_H) == CAST_OK) uiCrystalfireBreathTimer = urand(15000, 20000); } else uiCrystalfireBreathTimer -= uiDiff; if (!m_bIsRegularMode) { if (uiCrystallizeTimer < uiDiff) { if (DoCastSpellIfCan(m_creature, SPELL_CRYSTALLIZE) == CAST_OK) { uiCrystallizeTimer = urand(15000, 25000); DoScriptText(SAY_CRYSTAL_NOVA, m_creature); } } else uiCrystallizeTimer -= uiDiff; } DoMeleeAttackIfReady(); }