void UpdateAI(const uint32 uiDiff) { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; if (m_uiMorphTimer) { if (m_uiMorphTimer <= uiDiff) { if (DoCastSpellIfCan(m_creature, SPELL_POLYMORPH_BACKFIRE, CAST_TRIGGERED) == CAST_OK) { m_uiMorphTimer = 0; m_creature->ForcedDespawn(); } } else m_uiMorphTimer -= uiDiff; } for (UNORDERED_MAP<uint8, uint32>::iterator itr = m_mSpellTimers.begin(); itr != m_mSpellTimers.end(); ++itr) { if (itr->second < uiDiff) { if (CanUseSpecialAbility(itr->first)) { itr->second = m_aSpitelashAbility[itr->first].m_uiCooldown; break; } } else itr->second -= uiDiff; } DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 uiDiff) override { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; if (m_uiMorphTimer) { if (m_uiMorphTimer <= uiDiff) { if (DoCastSpellIfCan(m_creature, SPELL_POLYMORPH_BACKFIRE, CAST_TRIGGERED) == CAST_OK) { m_uiMorphTimer = 0; m_creature->ForcedDespawn(); } } else m_uiMorphTimer -= uiDiff; } for (auto& m_mSpellTimer : m_mSpellTimers) { if (m_mSpellTimer.second < uiDiff) { if (CanUseSpecialAbility(m_mSpellTimer.first)) { m_mSpellTimer.second = m_aSpitelashAbility[m_mSpellTimer.first].m_uiCooldown; break; } } else m_mSpellTimer.second -= uiDiff; } DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 uiDiff) { //Return since we have no target if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; for (UNORDERED_MAP<uint8, uint32>::iterator itr = m_mSpellTimers.begin(); itr != m_mSpellTimers.end(); ++itr) { if (itr->second < uiDiff) { if (CanUseSpecialAbility(itr->first)) { itr->second = m_aSilverHandAbility[itr->first].m_uiCooldown; break; } } else itr->second -= uiDiff; } DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 uiDiff) override { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; // Call specific virtual function if (!UpdateCrusaderAI(uiDiff)) return; if (m_uiAbilityTimer < uiDiff) { uint8 uiIndex = urand(0, m_uiMaxAbilities - 1); uint32 uiMinHealth = m_pAbilityArray[uiIndex].m_uiMinHealth; uint8 uiTargetType = m_pAbilityArray[uiIndex].m_uiTargetType; SelectFlags spellSelectFlag = m_pAbilityArray[uiIndex].m_selectFlag; // check timers and health condition // only cast spells that have timers expired // also check for health percentage for self cast spells if (m_uiSpellTimer[uiIndex] || (uiTargetType == TARGET_TYPE_SELF && uiMinHealth && m_creature->GetHealthPercent() > uiMinHealth)) { m_uiAbilityTimer = 2000; return; } else { uint32 uiSpellId = m_pAbilityArray[uiIndex].m_uiSpellId; // special case for heroism / bloodlust if (uiSpellId == SPELL_HEROISM && m_pInstance && m_pInstance->GetPlayerTeam() == ALLIANCE) uiSpellId = SPELL_BLOODLUST; if (CanUseSpecialAbility(uiSpellId, uiTargetType, spellSelectFlag, uiMinHealth)) { m_uiSpellTimer[uiIndex] = m_pAbilityArray[uiIndex].m_uiCooldown; m_uiAbilityTimer = urand(2000, 6000); } else m_uiAbilityTimer = 2000; } } else m_uiAbilityTimer -= uiDiff; // spell cooldown for (uint8 i = 0; i < m_uiMaxAbilities; ++i) { if (m_uiSpellTimer[i]) { if (m_uiSpellTimer[i] <= uiDiff) m_uiSpellTimer[i] = 0; else m_uiSpellTimer[i] -= uiDiff; } } // Change target if (m_uiResetThreatTimer < uiDiff) { if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 1)) { DoResetThreat(); AttackStart(pTarget); m_uiResetThreatTimer = urand(5000, 15000); } } else m_uiResetThreatTimer -= uiDiff; // CC check for PVP trinket if (m_uiIsCCTimer < uiDiff) { if (m_creature->isFrozen() || m_creature->hasUnitState(UNIT_STAT_CAN_NOT_REACT)) { // Pvp trinket only in heroic mode if (m_pInstance && m_pInstance->IsHeroicDifficulty() && !m_uiTrinketCooldownTimer) { if (DoCastSpellIfCan(m_creature, SPELL_PVP_TRINKET, CAST_TRIGGERED) == CAST_OK) m_uiTrinketCooldownTimer = 120000; } SendAIEventAround(AI_EVENT_GOT_CCED, NULL, 0, CRUSADER_AIEVENT_THROW_RADIUS); SendAIEvent(AI_EVENT_GOT_CCED, NULL, m_creature); m_uiIsCCTimer = 5000; } else m_uiIsCCTimer = 2000; } else m_uiIsCCTimer -= uiDiff; // trinket cooldown if (m_uiTrinketCooldownTimer) { if (m_uiTrinketCooldownTimer <= uiDiff) m_uiTrinketCooldownTimer = 0; else m_uiTrinketCooldownTimer -= uiDiff; } DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 uiDiff) override { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; // Acts as an enrage timer if (m_creature->GetHealthPercent() < 80.0f) { if (m_uiDrainPowerTimer < uiDiff) { if (DoCastSpellIfCan(m_creature, SPELL_DRAIN_POWER) == CAST_OK) { DoScriptText(SAY_DRAIN_POWER, m_creature); m_uiDrainPowerTimer = 30000; } } else m_uiDrainPowerTimer -= uiDiff; } if (m_uiSpiritBoltsTimer < uiDiff) { if (DoCastSpellIfCan(m_creature, SPELL_SPIRIT_BOLTS) == CAST_OK) { DoScriptText(SAY_SPIRIT_BOLTS, m_creature); m_bCanUsePlayerSpell = false; m_uiSpiritBoltsTimer = 40000; } } else m_uiSpiritBoltsTimer -= uiDiff; if (m_uiSiphonSoulTimer < uiDiff) { if (DoCastSpellIfCan(m_creature, SPELL_SIPHON_SOUL_DUMMY) == CAST_OK) { DoScriptText(SAY_SOUL_SIPHON, m_creature); m_uiSiphonSoulTimer = 40000; } } else m_uiSiphonSoulTimer -= uiDiff; // Use abilities only during the siphon soul phases if (m_bCanUsePlayerSpell) { // Loop through all abilities for (uint8 i = 0; i < m_vPlayerSpellTimer.size(); ++i) { if (m_vPlayerSpellTimer[i] < uiDiff) { if (CanUseSpecialAbility(i)) m_vPlayerSpellTimer[i] = m_aMalacrassStolenAbility[m_uiPlayerClass][i].m_uiCooldown; } else m_vPlayerSpellTimer[i] -= uiDiff; } } DoMeleeAttackIfReady(); }