#include "StdAfx.h" #include "Setup.h" /************************************************************************/ /* Instance_Arcatraz.cpp Script */ /************************************************************************/ // Arcatraz DefenderAI #define CN_ARCATRAZ_DEFENDER 20857 #define PROTEAN_SUBDUAL 36288 #define FLAMING_WEAPON 36601 #define IMMOLATE 36638 class ArcatrazDefenderAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(ArcatrazDefenderAI); SP_AI_Spell spells[3]; bool m_spellcheck[3]; ArcatrazDefenderAI(Creature* pCreature) : CreatureAIScript(pCreature) { nrspells = 3; for(int i=0;iGetUInt32Value(UNIT_FIELD_BASEATTACKTIME)); } void CastTime() { for(int i=0;iGetAIInterface()->setCurrentAgent(AGENT_NULL); _unit->GetAIInterface()->SetAIState(STATE_IDLE); RemoveAIUpdateEvent(); } void OnDied(Unit * mKiller) { CastTime(); RemoveAIUpdateEvent(); } void AIUpdate() { float val = sRand.rand(100.0f); SpellCast(val); } void SpellCast(float val) { if(_unit->GetCurrentSpell() == NULL && _unit->GetAIInterface()->GetNextTarget()) { float comulativeperc = 0; Unit *target = NULL; for(int i=0;iGetAIInterface()->GetNextTarget(); switch(spells[i].targettype) { case TARGET_SELF: case TARGET_VARIOUS: _unit->CastSpell(_unit, spells[i].info, spells[i].instant); break; case TARGET_ATTACKING: _unit->CastSpell(target, spells[i].info, spells[i].instant); break; case TARGET_DESTINATION: _unit->CastSpellAoF(target->GetPositionX(),target->GetPositionY(),target->GetPositionZ(), spells[i].info, spells[i].instant); break; } if (spells[i].speech != "") { _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, spells[i].speech.c_str()); _unit->PlaySoundToSet(spells[i].soundid); } m_spellcheck[i] = false; return; } if ((val > comulativeperc && val <= (comulativeperc + spells[i].perctrigger)) || !spells[i].casttime) { _unit->setAttackTimer(spells[i].attackstoptimer, false); m_spellcheck[i] = true; } comulativeperc += spells[i].perctrigger; } } } protected: int nrspells; }; // Arcatraz SentinelAI #define CN_ARCATRAZ_SENTINEL 20869 #define ENERGY_DISCHARGE 36717 #define EXPLODE 36719 // DBC: 36722, 36719 //Permanent Feign Death (Root) 31261 ? class ArcatrazSentinelAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(ArcatrazSentinelAI); SP_AI_Spell spells[2]; bool m_spellcheck[2]; ArcatrazSentinelAI(Creature* pCreature) : CreatureAIScript(pCreature) { nrspells = 2; for(int i=0;iGetUInt32Value(UNIT_FIELD_BASEATTACKTIME)); } void CastTime() { for(int i=0;iGetAIInterface()->setCurrentAgent(AGENT_NULL); _unit->GetAIInterface()->SetAIState(STATE_IDLE); RemoveAIUpdateEvent(); } void OnDied(Unit * mKiller) { CastTime(); RemoveAIUpdateEvent(); } void AIUpdate() { if (_unit->GetHealthPct() <= 5) _unit->CastSpell(_unit, spells[1].info, spells[1].instant); float val = sRand.rand(100.0f); SpellCast(val); } void SpellCast(float val) { if(_unit->GetCurrentSpell() == NULL && _unit->GetAIInterface()->GetNextTarget()) { float comulativeperc = 0; Unit *target = NULL; for(int i=0;iGetAIInterface()->GetNextTarget(); switch(spells[i].targettype) { case TARGET_SELF: case TARGET_VARIOUS: _unit->CastSpell(_unit, spells[i].info, spells[i].instant); break; case TARGET_ATTACKING: _unit->CastSpell(target, spells[i].info, spells[i].instant); break; case TARGET_DESTINATION: _unit->CastSpellAoF(target->GetPositionX(),target->GetPositionY(),target->GetPositionZ(), spells[i].info, spells[i].instant); break; } if (spells[i].speech != "") { _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, spells[i].speech.c_str()); _unit->PlaySoundToSet(spells[i].soundid); } m_spellcheck[i] = false; return; } if ((val > comulativeperc && val <= (comulativeperc + spells[i].perctrigger)) || !spells[i].casttime) { _unit->setAttackTimer(spells[i].attackstoptimer, false); m_spellcheck[i] = true; } comulativeperc += spells[i].perctrigger; } } } protected: int nrspells; }; // Arcatraz WarderAI #define CN_ARCATRAZ_WARDER 20859 #define ARCANE_SHOT 36609 #define SHOT 15620 #define IMPROVED_WING_CLIP 35963 #define CHARGED_ARCANE_SHOT 36608 //Shoot Arcane Explosion Arrow 36327 ? class ArcatrazWarderAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(ArcatrazWarderAI); SP_AI_Spell spells[4]; bool m_spellcheck[4]; ArcatrazWarderAI(Creature* pCreature) : CreatureAIScript(pCreature) { nrspells = 4; for(int i=0;iGetUInt32Value(UNIT_FIELD_BASEATTACKTIME)); } void CastTime() { for(int i=0;iGetAIInterface()->setCurrentAgent(AGENT_NULL); _unit->GetAIInterface()->SetAIState(STATE_IDLE); RemoveAIUpdateEvent(); } void OnDied(Unit * mKiller) { CastTime(); RemoveAIUpdateEvent(); } void AIUpdate() { if (_unit->GetAIInterface()->GetNextTarget()) { Unit *target = NULL; target = _unit->GetAIInterface()->GetNextTarget(); if (_unit->GetDistance2dSq(target) >= 100.0f && _unit->GetDistanceSq(target) <= 900.0f) { _unit->GetAIInterface()->m_canMove = false; int RangedSpell; sRand.randInt(1000); RangedSpell=rand()%100; if (RangedSpell >= 0 && RangedSpell <= 20) { _unit->CastSpell(target, spells[3].info, spells[3].instant); _unit->setAttackTimer(spells[3].attackstoptimer, false); } if (RangedSpell > 20 && RangedSpell <= 40) { _unit->CastSpell(target, spells[0].info, spells[0].instant); _unit->setAttackTimer(spells[0].attackstoptimer, false); } else { _unit->CastSpell(target, spells[1].info, spells[1].instant); _unit->setAttackTimer(spells[1].attackstoptimer, false); } } else { _unit->GetAIInterface()->m_canMove = true; if (_unit->GetDistance2dSq(target) < 100.0f) { float val = sRand.rand(100.0f); SpellCast(val); } } } } void SpellCast(float val) { if(_unit->GetCurrentSpell() == NULL && _unit->GetAIInterface()->GetNextTarget()) // I was too lazy to rewrite it =S { float comulativeperc = 0; Unit *target = NULL; for(int i=0;iGetAIInterface()->GetNextTarget(); switch(spells[i].targettype) { case TARGET_SELF: case TARGET_VARIOUS: _unit->CastSpell(_unit, spells[i].info, spells[i].instant); break; case TARGET_ATTACKING: _unit->CastSpell(target, spells[i].info, spells[i].instant); break; case TARGET_DESTINATION: _unit->CastSpellAoF(target->GetPositionX(),target->GetPositionY(),target->GetPositionZ(), spells[i].info, spells[i].instant); break; } if (spells[i].speech != "") { _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, spells[i].speech.c_str()); _unit->PlaySoundToSet(spells[i].soundid); } m_spellcheck[i] = false; return; } if ((val > comulativeperc && val <= (comulativeperc + spells[i].perctrigger)) || !spells[i].casttime) { _unit->setAttackTimer(spells[i].attackstoptimer, false); m_spellcheck[i] = true; } comulativeperc += spells[i].perctrigger; } } } protected: int nrspells; }; // Blackwing DrakonaarAI #define CN_BLACKWING_DRAKONAAR 20911 #define SIMPLE_TELEPORT 12980 #define BROOD_POWER_BLACK 39033 #define MORTAL_STRIKE 13737 #define BLAST_WAVE 39038 class BlackwingDrakonaarAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(BlackwingDrakonaarAI); SP_AI_Spell spells[4]; bool m_spellcheck[4]; BlackwingDrakonaarAI(Creature* pCreature) : CreatureAIScript(pCreature) { nrspells = 4; for(int i=0;iCastSpell(_unit, spells[0].info, spells[0].instant); CastTime(); RegisterAIUpdateEvent(_unit->GetUInt32Value(UNIT_FIELD_BASEATTACKTIME)); } void CastTime() { for(int i=0;iGetAIInterface()->setCurrentAgent(AGENT_NULL); _unit->GetAIInterface()->SetAIState(STATE_IDLE); RemoveAIUpdateEvent(); } void OnDied(Unit * mKiller) { CastTime(); RemoveAIUpdateEvent(); } void AIUpdate() { float val = sRand.rand(100.0f); SpellCast(val); } void SpellCast(float val) { if(_unit->GetCurrentSpell() == NULL && _unit->GetAIInterface()->GetNextTarget()) { float comulativeperc = 0; Unit *target = NULL; for(int i=0;iGetAIInterface()->GetNextTarget(); switch(spells[i].targettype) { case TARGET_SELF: case TARGET_VARIOUS: _unit->CastSpell(_unit, spells[i].info, spells[i].instant); break; case TARGET_ATTACKING: _unit->CastSpell(target, spells[i].info, spells[i].instant); break; case TARGET_DESTINATION: _unit->CastSpellAoF(target->GetPositionX(),target->GetPositionY(),target->GetPositionZ(), spells[i].info, spells[i].instant); break; } if (spells[i].speech != "") { _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, spells[i].speech.c_str()); _unit->PlaySoundToSet(spells[i].soundid); } m_spellcheck[i] = false; return; } if ((val > comulativeperc && val <= (comulativeperc + spells[i].perctrigger)) || !spells[i].casttime) { _unit->setAttackTimer(spells[i].attackstoptimer, false); m_spellcheck[i] = true; } comulativeperc += spells[i].perctrigger; } } } protected: int nrspells; }; // Blazing TricksterAI #define CN_BLACKWING_TRICKSTER 20905 #define FIREBOLT 36906 #define FIRE_SHIELD 36907 class BlackwingTricksterAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(BlackwingTricksterAI); SP_AI_Spell spells[2]; bool m_spellcheck[2]; BlackwingTricksterAI(Creature* pCreature) : CreatureAIScript(pCreature) { nrspells = 2; for(int i=0;iGetUInt32Value(UNIT_FIELD_BASEATTACKTIME)); } void CastTime() { for(int i=0;iGetAIInterface()->setCurrentAgent(AGENT_NULL); _unit->GetAIInterface()->SetAIState(STATE_IDLE); RemoveAIUpdateEvent(); } void OnDied(Unit * mKiller) { CastTime(); RemoveAIUpdateEvent(); } void AIUpdate() { float val = sRand.rand(100.0f); SpellCast(val); } void SpellCast(float val) { if(_unit->GetCurrentSpell() == NULL && _unit->GetAIInterface()->GetNextTarget()) { float comulativeperc = 0; Unit *target = NULL; for(int i=0;iGetAIInterface()->GetNextTarget(); switch(spells[i].targettype) { case TARGET_SELF: case TARGET_VARIOUS: _unit->CastSpell(_unit, spells[i].info, spells[i].instant); break; case TARGET_ATTACKING: _unit->CastSpell(target, spells[i].info, spells[i].instant); break; case TARGET_DESTINATION: _unit->CastSpellAoF(target->GetPositionX(),target->GetPositionY(),target->GetPositionZ(), spells[i].info, spells[i].instant); break; } if (spells[i].speech != "") { _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, spells[i].speech.c_str()); _unit->PlaySoundToSet(spells[i].soundid); } m_spellcheck[i] = false; return; } if ((val > comulativeperc && val <= (comulativeperc + spells[i].perctrigger)) || !spells[i].casttime) { _unit->setAttackTimer(spells[i].attackstoptimer, false); m_spellcheck[i] = true; } comulativeperc += spells[i].perctrigger; } } } protected: int nrspells; }; // Death WatcherAI #define CN_DEATH_WATCHER 20867 #define TENTACLE_CLEAVE 36664 #define DRAIN_LIFE 36655 #define DEATH_COUNT 36657 // DBC: 36657, 36660 class DeathWatcherAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(DeathWatcherAI); SP_AI_Spell spells[3]; bool m_spellcheck[3]; DeathWatcherAI(Creature* pCreature) : CreatureAIScript(pCreature) { nrspells = 3; for(int i=0;iGetUInt32Value(UNIT_FIELD_BASEATTACKTIME)); } void CastTime() { for(int i=0;iGetAIInterface()->setCurrentAgent(AGENT_NULL); _unit->GetAIInterface()->SetAIState(STATE_IDLE); RemoveAIUpdateEvent(); } void OnDied(Unit * mKiller) { MarkApplied = 0; CastTime(); RemoveAIUpdateEvent(); } void AIUpdate() { if (_unit->GetHealthPct() <= 50 && !MarkApplied) { _unit->CastSpell(_unit, spells[2].info, spells[2].instant); MarkApplied = 1; } else { float val = sRand.rand(100.0f); SpellCast(val); } } void SpellCast(float val) { if(_unit->GetCurrentSpell() == NULL && _unit->GetAIInterface()->GetNextTarget()) { float comulativeperc = 0; Unit *target = NULL; for(int i=0;iGetAIInterface()->GetNextTarget(); switch(spells[i].targettype) { case TARGET_SELF: case TARGET_VARIOUS: _unit->CastSpell(_unit, spells[i].info, spells[i].instant); break; case TARGET_ATTACKING: _unit->CastSpell(target, spells[i].info, spells[i].instant); break; case TARGET_DESTINATION: _unit->CastSpellAoF(target->GetPositionX(),target->GetPositionY(),target->GetPositionZ(), spells[i].info, spells[i].instant); break; } if (spells[i].speech != "") { _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, spells[i].speech.c_str()); _unit->PlaySoundToSet(spells[i].soundid); } m_spellcheck[i] = false; return; } if ((val > comulativeperc && val <= (comulativeperc + spells[i].perctrigger)) || !spells[i].casttime) { _unit->setAttackTimer(spells[i].attackstoptimer, false); m_spellcheck[i] = true; } comulativeperc += spells[i].perctrigger; } } } protected: uint32 MarkApplied; int nrspells; }; // Defender CorpseAI #define CN_DEFENDER_CORPSE 21303 #define CORPSE_BURST 36593 #define BLOODY_EXPLOSION 36599 //#define PERMANENT_FEIGN_DEATH_ROOT 31261 // I don't have much infos and I am not sure about how it should work // I presume this is just corpse which should cast spell when player is close or attk it class DefenderCorpseAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(DefenderCorpseAI); SP_AI_Spell spells[2]; bool m_spellcheck[2]; DefenderCorpseAI(Creature* pCreature) : CreatureAIScript(pCreature) { nrspells = 2; for(int i=0;iCastSpell(_unit, spells[1].info, spells[1].instant); _unit->CastSpell(_unit, spells[0].info, spells[0].instant); CastTime(); RegisterAIUpdateEvent(_unit->GetUInt32Value(UNIT_FIELD_BASEATTACKTIME)); } void CastTime() { for(int i=0;iGetAIInterface()->setCurrentAgent(AGENT_NULL); _unit->GetAIInterface()->SetAIState(STATE_IDLE); RemoveAIUpdateEvent(); } void OnDied(Unit * mKiller) { CastTime(); RemoveAIUpdateEvent(); } void AIUpdate() { float val = sRand.rand(100.0f); SpellCast(val); } void SpellCast(float val) { if(_unit->GetCurrentSpell() == NULL && _unit->GetAIInterface()->GetNextTarget()) { float comulativeperc = 0; Unit *target = NULL; for(int i=0;iGetAIInterface()->GetNextTarget(); switch(spells[i].targettype) { case TARGET_SELF: case TARGET_VARIOUS: _unit->CastSpell(_unit, spells[i].info, spells[i].instant); break; case TARGET_ATTACKING: _unit->CastSpell(target, spells[i].info, spells[i].instant); break; case TARGET_DESTINATION: _unit->CastSpellAoF(target->GetPositionX(),target->GetPositionY(),target->GetPositionZ(), spells[i].info, spells[i].instant); break; } if (spells[i].speech != "") { _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, spells[i].speech.c_str()); _unit->PlaySoundToSet(spells[i].soundid); } m_spellcheck[i] = false; return; } if ((val > comulativeperc && val <= (comulativeperc + spells[i].perctrigger)) || !spells[i].casttime) { _unit->setAttackTimer(spells[i].attackstoptimer, false); m_spellcheck[i] = true; } comulativeperc += spells[i].perctrigger; } } } protected: int nrspells; }; // Protean SpawnAI #define CN_PROTEAN_SPAWN 21395 // it's sth that spawns from Defender Corpse #define ACIDIC_BITE 36796 //#define BLOODY_EXPLOSION 36588 class ProteanSpawnAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(ProteanSpawnAI); SP_AI_Spell spells[1]; bool m_spellcheck[1]; ProteanSpawnAI(Creature* pCreature) : CreatureAIScript(pCreature) { nrspells = 1; for(int i=0;iGetUInt32Value(UNIT_FIELD_BASEATTACKTIME)); } void CastTime() { for(int i=0;iGetAIInterface()->setCurrentAgent(AGENT_NULL); _unit->GetAIInterface()->SetAIState(STATE_IDLE); RemoveAIUpdateEvent(); } void OnDied(Unit * mKiller) { CastTime(); RemoveAIUpdateEvent(); } void AIUpdate() { float val = sRand.rand(100.0f); SpellCast(val); } void SpellCast(float val) { if(_unit->GetCurrentSpell() == NULL && _unit->GetAIInterface()->GetNextTarget()) { float comulativeperc = 0; Unit *target = NULL; for(int i=0;iGetAIInterface()->GetNextTarget(); switch(spells[i].targettype) { case TARGET_SELF: case TARGET_VARIOUS: _unit->CastSpell(_unit, spells[i].info, spells[i].instant); break; case TARGET_ATTACKING: _unit->CastSpell(target, spells[i].info, spells[i].instant); break; case TARGET_DESTINATION: _unit->CastSpellAoF(target->GetPositionX(),target->GetPositionY(),target->GetPositionZ(), spells[i].info, spells[i].instant); break; } if (spells[i].speech != "") { _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, spells[i].speech.c_str()); _unit->PlaySoundToSet(spells[i].soundid); } m_spellcheck[i] = false; return; } if ((val > comulativeperc && val <= (comulativeperc + spells[i].perctrigger)) || !spells[i].casttime) { _unit->setAttackTimer(spells[i].attackstoptimer, false); m_spellcheck[i] = true; } comulativeperc += spells[i].perctrigger; } } } protected: int nrspells; }; // Entropic EyeAI #define CN_ENTROPIC_EYE 20868 #define WAVERING_WILL 36699 // not sure if this is right one (I mean spell, not ID) #define PIERCING_SHADOW 36698 // this "smaller" list must be rechecked =S #define HEX 36700 #define TANTACLE_CLEAVE_EYE 36664 /* #define TANTACLE_CLEAVE_EYE 36664 #define FIREBALL_EYE 36711 #define FROSTBOLT_EYE 36710 #define WITHERED_TOUCH_EYE 36696 #define HEX_EYE 36700 #define PIERCING_SHADOW_EYE 36698 #define CHAOS_BREATH_EYE 36677 // SSS #define POISON_BOLT_EYE 36713 // DBC List :O #define NECROTIC_POISON_EYE 36693 #define SHRINK_EYE 36697 #define SHADOW_BOLT_EYE 36714 #define FEVERED_FATIGUE_EYE 36695 #define WAVERING_WILL_EYE 36699 #define CORROSIVE_POISON_EYE 36694 #define ARCANE_BOLT_EYE 36712 */ class EntropicEyeAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(EntropicEyeAI); SP_AI_Spell spells[4]; bool m_spellcheck[4]; EntropicEyeAI(Creature* pCreature) : CreatureAIScript(pCreature) { nrspells = 4; for(int i=0;iGetUInt32Value(UNIT_FIELD_BASEATTACKTIME)); } void CastTime() { for(int i=0;iGetAIInterface()->setCurrentAgent(AGENT_NULL); _unit->GetAIInterface()->SetAIState(STATE_IDLE); RemoveAIUpdateEvent(); } void OnDied(Unit * mKiller) { CastTime(); RemoveAIUpdateEvent(); } void AIUpdate() { float val = sRand.rand(100.0f); SpellCast(val); } void SpellCast(float val) { if(_unit->GetCurrentSpell() == NULL && _unit->GetAIInterface()->GetNextTarget()) { float comulativeperc = 0; Unit *target = NULL; for(int i=0;iGetAIInterface()->GetNextTarget(); switch(spells[i].targettype) { case TARGET_SELF: case TARGET_VARIOUS: _unit->CastSpell(_unit, spells[i].info, spells[i].instant); break; case TARGET_ATTACKING: _unit->CastSpell(target, spells[i].info, spells[i].instant); break; case TARGET_DESTINATION: _unit->CastSpellAoF(target->GetPositionX(),target->GetPositionY(),target->GetPositionZ(), spells[i].info, spells[i].instant); break; } if (spells[i].speech != "") { _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, spells[i].speech.c_str()); _unit->PlaySoundToSet(spells[i].soundid); } m_spellcheck[i] = false; return; } if ((val > comulativeperc && val <= (comulativeperc + spells[i].perctrigger)) || !spells[i].casttime) { _unit->setAttackTimer(spells[i].attackstoptimer, false); m_spellcheck[i] = true; } comulativeperc += spells[i].perctrigger; } } } protected: int nrspells; }; // Eredar DeathbringerAI #define CN_EREDAR_DEATHBRINGER 20880 #define UNHOLY_AURA 27987 // DBC: 27988, 27987 #define DIMINISH_SOUL 36789 // DBC: 36789, 36791 (SSS) #define FORCEFUL_CLEAVE 36787 class EredarDeathbringerAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(EredarDeathbringerAI); SP_AI_Spell spells[3]; bool m_spellcheck[3]; EredarDeathbringerAI(Creature* pCreature) : CreatureAIScript(pCreature) { nrspells = 3; for(int i=0;iCastSpell(_unit, spells[0].info, spells[0].instant); } void OnCombatStart(Unit* mTarget) { CastTime(); RegisterAIUpdateEvent(_unit->GetUInt32Value(UNIT_FIELD_BASEATTACKTIME)); } void CastTime() { for(int i=0;iGetAIInterface()->setCurrentAgent(AGENT_NULL); _unit->GetAIInterface()->SetAIState(STATE_IDLE); RemoveAIUpdateEvent(); } void OnDied(Unit * mKiller) { CastTime(); RemoveAIUpdateEvent(); } void AIUpdate() { float val = sRand.rand(100.0f); SpellCast(val); } void SpellCast(float val) { if(_unit->GetCurrentSpell() == NULL && _unit->GetAIInterface()->GetNextTarget()) { float comulativeperc = 0; Unit *target = NULL; for(int i=0;iGetAIInterface()->GetNextTarget(); switch(spells[i].targettype) { case TARGET_SELF: case TARGET_VARIOUS: _unit->CastSpell(_unit, spells[i].info, spells[i].instant); break; case TARGET_ATTACKING: _unit->CastSpell(target, spells[i].info, spells[i].instant); break; case TARGET_DESTINATION: _unit->CastSpellAoF(target->GetPositionX(),target->GetPositionY(),target->GetPositionZ(), spells[i].info, spells[i].instant); break; } if (spells[i].speech != "") { _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, spells[i].speech.c_str()); _unit->PlaySoundToSet(spells[i].soundid); } m_spellcheck[i] = false; return; } if ((val > comulativeperc && val <= (comulativeperc + spells[i].perctrigger)) || !spells[i].casttime) { _unit->setAttackTimer(spells[i].attackstoptimer, false); m_spellcheck[i] = true; } comulativeperc += spells[i].perctrigger; } } } protected: int nrspells; }; // Eredar Soul-EaterAI #define CN_EREDAR_SOUL_EATER 20879 #define SOUL_CHILL 36786 #define SOUL_STEAL1 36778 // this on target, another on self #define SOUL_STEAL2 36782 // DBC: 36782, 36778 class EredarSoulEaterAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(EredarSoulEaterAI); SP_AI_Spell spells[3]; bool m_spellcheck[3]; EredarSoulEaterAI(Creature* pCreature) : CreatureAIScript(pCreature) { nrspells = 3; for(int i=0;iGetUInt32Value(UNIT_FIELD_BASEATTACKTIME)); } void CastTime() { for(int i=0;iGetAIInterface()->setCurrentAgent(AGENT_NULL); _unit->GetAIInterface()->SetAIState(STATE_IDLE); RemoveAIUpdateEvent(); } void OnDied(Unit * mKiller) { CastTime(); RemoveAIUpdateEvent(); } void AIUpdate() { float val = sRand.rand(100.0f); SpellCast(val); } void SpellCast(float val) { if(_unit->GetCurrentSpell() == NULL && _unit->GetAIInterface()->GetNextTarget()) { float comulativeperc = 0; Unit *target = NULL; for(int i=0;iGetAIInterface()->GetNextTarget(); switch(spells[i].targettype) { case TARGET_SELF: case TARGET_VARIOUS: _unit->CastSpell(_unit, spells[i].info, spells[i].instant); break; case TARGET_ATTACKING: _unit->CastSpell(target, spells[i].info, spells[i].instant); break; case TARGET_DESTINATION: _unit->CastSpellAoF(target->GetPositionX(),target->GetPositionY(),target->GetPositionZ(), spells[i].info, spells[i].instant); break; } if (m_spellcheck[1] == true) _unit->CastSpell(_unit, spells[2].info, spells[2].instant); if (spells[i].speech != "") { _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, spells[i].speech.c_str()); _unit->PlaySoundToSet(spells[i].soundid); } m_spellcheck[i] = false; return; } if ((val > comulativeperc && val <= (comulativeperc + spells[i].perctrigger)) || !spells[i].casttime) { _unit->setAttackTimer(spells[i].attackstoptimer, false); m_spellcheck[i] = true; } comulativeperc += spells[i].perctrigger; } } } protected: int nrspells; }; // Ethereum Life-BinderAI #define CN_ETHEREUM_LIFE_BINDER 21702 #define BIND 37480 #define SHADOW_WORD_PAIN 15654 class EthereumLifeBinderAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(EthereumLifeBinderAI); SP_AI_Spell spells[2]; bool m_spellcheck[2]; EthereumLifeBinderAI(Creature* pCreature) : CreatureAIScript(pCreature) { nrspells = 2; for(int i=0;iGetUInt32Value(UNIT_FIELD_BASEATTACKTIME)); } void CastTime() { for(int i=0;iGetAIInterface()->setCurrentAgent(AGENT_NULL); _unit->GetAIInterface()->SetAIState(STATE_IDLE); RemoveAIUpdateEvent(); } void OnDied(Unit * mKiller) { CastTime(); RemoveAIUpdateEvent(); } void AIUpdate() { float val = sRand.rand(100.0f); SpellCast(val); } void SpellCast(float val) { if(_unit->GetCurrentSpell() == NULL && _unit->GetAIInterface()->GetNextTarget()) { float comulativeperc = 0; Unit *target = NULL; for(int i=0;iGetAIInterface()->GetNextTarget(); switch(spells[i].targettype) { case TARGET_SELF: case TARGET_VARIOUS: _unit->CastSpell(_unit, spells[i].info, spells[i].instant); break; case TARGET_ATTACKING: _unit->CastSpell(target, spells[i].info, spells[i].instant); break; case TARGET_DESTINATION: _unit->CastSpellAoF(target->GetPositionX(),target->GetPositionY(),target->GetPositionZ(), spells[i].info, spells[i].instant); break; } if (spells[i].speech != "") { _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, spells[i].speech.c_str()); _unit->PlaySoundToSet(spells[i].soundid); } m_spellcheck[i] = false; return; } if ((val > comulativeperc && val <= (comulativeperc + spells[i].perctrigger)) || !spells[i].casttime) { _unit->setAttackTimer(spells[i].attackstoptimer, false); m_spellcheck[i] = true; } comulativeperc += spells[i].perctrigger; } } } protected: int nrspells; }; // Ethereum SlayerAI #define CN_ETHEREUM_SLAYER 20896 #define IMPARING_POISON 36839 #define SLAYER_STRIKE 36838 #define EVASION 15087 class EthereumSlayerAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(EthereumSlayerAI); SP_AI_Spell spells[3]; bool m_spellcheck[3]; EthereumSlayerAI(Creature* pCreature) : CreatureAIScript(pCreature) { nrspells = 3; for(int i=0;iGetUInt32Value(UNIT_FIELD_BASEATTACKTIME)); } void CastTime() { for(int i=0;iGetAIInterface()->setCurrentAgent(AGENT_NULL); _unit->GetAIInterface()->SetAIState(STATE_IDLE); RemoveAIUpdateEvent(); } void OnDied(Unit * mKiller) { CastTime(); RemoveAIUpdateEvent(); } void AIUpdate() { float val = sRand.rand(100.0f); SpellCast(val); } void SpellCast(float val) { if(_unit->GetCurrentSpell() == NULL && _unit->GetAIInterface()->GetNextTarget()) { float comulativeperc = 0; Unit *target = NULL; for(int i=0;iGetAIInterface()->GetNextTarget(); switch(spells[i].targettype) { case TARGET_SELF: case TARGET_VARIOUS: _unit->CastSpell(_unit, spells[i].info, spells[i].instant); break; case TARGET_ATTACKING: _unit->CastSpell(target, spells[i].info, spells[i].instant); break; case TARGET_DESTINATION: _unit->CastSpellAoF(target->GetPositionX(),target->GetPositionY(),target->GetPositionZ(), spells[i].info, spells[i].instant); break; } if (spells[i].speech != "") { _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, spells[i].speech.c_str()); _unit->PlaySoundToSet(spells[i].soundid); } m_spellcheck[i] = false; return; } if ((val > comulativeperc && val <= (comulativeperc + spells[i].perctrigger)) || !spells[i].casttime) { _unit->setAttackTimer(spells[i].attackstoptimer, false); m_spellcheck[i] = true; } comulativeperc += spells[i].perctrigger; } } } protected: int nrspells; }; // Ethereum Wave-CasterAI #define CN_ETHEREUM_WAVE_CASTER 20897 #define POLYMORPH 36840 #define ARCANE_HASTE 32693 #define SONIC_BOMB 36841 // should counter spell so I must code it a bit more // KNOCKBACK ? class EthereumWaveCasterAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(EthereumWaveCasterAI); SP_AI_Spell spells[3]; bool m_spellcheck[3]; EthereumWaveCasterAI(Creature* pCreature) : CreatureAIScript(pCreature) { nrspells = 3; for(int i=0;iGetUInt32Value(UNIT_FIELD_BASEATTACKTIME)); } void CastTime() { for(int i=0;iGetAIInterface()->setCurrentAgent(AGENT_NULL); _unit->GetAIInterface()->SetAIState(STATE_IDLE); RemoveAIUpdateEvent(); } void OnDied(Unit * mKiller) { CastTime(); RemoveAIUpdateEvent(); } void AIUpdate() { float val = sRand.rand(100.0f); SpellCast(val); } void SpellCast(float val) { if(_unit->GetCurrentSpell() == NULL && _unit->GetAIInterface()->GetNextTarget()) { float comulativeperc = 0; Unit *target = NULL; for(int i=0;iGetAIInterface()->GetNextTarget(); switch(spells[i].targettype) { case TARGET_SELF: case TARGET_VARIOUS: _unit->CastSpell(_unit, spells[i].info, spells[i].instant); break; case TARGET_ATTACKING: _unit->CastSpell(target, spells[i].info, spells[i].instant); break; case TARGET_DESTINATION: _unit->CastSpellAoF(target->GetPositionX(),target->GetPositionY(),target->GetPositionZ(), spells[i].info, spells[i].instant); break; } if (spells[i].speech != "") { _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, spells[i].speech.c_str()); _unit->PlaySoundToSet(spells[i].soundid); } m_spellcheck[i] = false; return; } if ((val > comulativeperc && val <= (comulativeperc + spells[i].perctrigger)) || !spells[i].casttime) { _unit->setAttackTimer(spells[i].attackstoptimer, false); m_spellcheck[i] = true; } comulativeperc += spells[i].perctrigger; } } } protected: int nrspells; }; // Gargantuan AbyssalAI #define CN_GARGANTUAN_ABYSSAL 20898 #define FIRE_SHIELD_ABY 38855 // DBC: 38855, 38893 #define METEOR 36837 class GargantuanAbyssalAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(GargantuanAbyssalAI); SP_AI_Spell spells[2]; bool m_spellcheck[2]; GargantuanAbyssalAI(Creature* pCreature) : CreatureAIScript(pCreature) { nrspells = 2; for(int i=0;iGetUInt32Value(UNIT_FIELD_BASEATTACKTIME)); } void CastTime() { for(int i=0;iGetAIInterface()->setCurrentAgent(AGENT_NULL); _unit->GetAIInterface()->SetAIState(STATE_IDLE); RemoveAIUpdateEvent(); } void OnDied(Unit * mKiller) { CastTime(); RemoveAIUpdateEvent(); } void AIUpdate() { float val = sRand.rand(100.0f); SpellCast(val); } void SpellCast(float val) { if(_unit->GetCurrentSpell() == NULL && _unit->GetAIInterface()->GetNextTarget()) { float comulativeperc = 0; Unit *target = NULL; for(int i=0;iGetAIInterface()->GetNextTarget(); switch(spells[i].targettype) { case TARGET_SELF: case TARGET_VARIOUS: _unit->CastSpell(_unit, spells[i].info, spells[i].instant); break; case TARGET_ATTACKING: _unit->CastSpell(target, spells[i].info, spells[i].instant); break; case TARGET_DESTINATION: _unit->CastSpellAoF(target->GetPositionX(),target->GetPositionY(),target->GetPositionZ(), spells[i].info, spells[i].instant); break; } if (spells[i].speech != "") { _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, spells[i].speech.c_str()); _unit->PlaySoundToSet(spells[i].soundid); } m_spellcheck[i] = false; return; } if ((val > comulativeperc && val <= (comulativeperc + spells[i].perctrigger)) || !spells[i].casttime) { _unit->setAttackTimer(spells[i].attackstoptimer, false); m_spellcheck[i] = true; } comulativeperc += spells[i].perctrigger; } } } protected: int nrspells; }; // Greater Fire ElementalAI #define CN_GREATER_FIRE_ELEMENTAL 15438 #define FIRE_SHIELD_GFE 13376 #define FIRE_NOVA 12470 #define FIRE_BLAST 13339 #define MARK_OF_DEATH 37128 // SSS // should be applied on target class GreaterFireElementalAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(GreaterFireElementalAI); SP_AI_Spell spells[4]; bool m_spellcheck[4]; GreaterFireElementalAI(Creature* pCreature) : CreatureAIScript(pCreature) { nrspells = 4; for(int i=0;iCastSpell(_unit, spells[0].info, spells[0].instant); } void OnCombatStart(Unit* mTarget) { CastTime(); RegisterAIUpdateEvent(_unit->GetUInt32Value(UNIT_FIELD_BASEATTACKTIME)); } void CastTime() { for(int i=0;iGetAIInterface()->setCurrentAgent(AGENT_NULL); _unit->GetAIInterface()->SetAIState(STATE_IDLE); RemoveAIUpdateEvent(); } void OnDied(Unit * mKiller) { CastTime(); RemoveAIUpdateEvent(); } void AIUpdate() { float val = sRand.rand(100.0f); SpellCast(val); } void SpellCast(float val) { if(_unit->GetCurrentSpell() == NULL && _unit->GetAIInterface()->GetNextTarget()) { float comulativeperc = 0; Unit *target = NULL; for(int i=0;iGetAIInterface()->GetNextTarget(); switch(spells[i].targettype) { case TARGET_SELF: case TARGET_VARIOUS: _unit->CastSpell(_unit, spells[i].info, spells[i].instant); break; case TARGET_ATTACKING: _unit->CastSpell(target, spells[i].info, spells[i].instant); break; case TARGET_DESTINATION: _unit->CastSpellAoF(target->GetPositionX(),target->GetPositionY(),target->GetPositionZ(), spells[i].info, spells[i].instant); break; } if (spells[i].speech != "") { _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, spells[i].speech.c_str()); _unit->PlaySoundToSet(spells[i].soundid); } m_spellcheck[i] = false; return; } if ((val > comulativeperc && val <= (comulativeperc + spells[i].perctrigger)) || !spells[i].casttime) { _unit->setAttackTimer(spells[i].attackstoptimer, false); m_spellcheck[i] = true; } comulativeperc += spells[i].perctrigger; } } } protected: int nrspells; }; // IronjawAI // spells verification, coz some of those are for sure pet spells? :| :| :| #define CN_IRONJAW 18670 // I couldn't force Ironjaw to cast spells with "?" #define FURIOUS_HOWL 24597 // ? #define DASH 23110 #define BITE 27050 #define GROWL 14921 // ? #define FEROCIOUS_INSPIRATION 34456 // ? #define FRENZY_EFFECT 19615 #define KILL_COMMAND 34027 #define BESTIAL_WRATH 24395 // DBC: 24395, 24396, 24397, 26592 (all are diffrent) // ? #define SNARL 32919 #define CHILLING_HOWL 32918 class IronjawAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(IronjawAI); SP_AI_Spell spells[10]; bool m_spellcheck[10]; IronjawAI(Creature* pCreature) : CreatureAIScript(pCreature) { nrspells = 10; for(int i=0;iGetUInt32Value(UNIT_FIELD_BASEATTACKTIME)); } void CastTime() { for(int i=0;iGetAIInterface()->setCurrentAgent(AGENT_NULL); _unit->GetAIInterface()->SetAIState(STATE_IDLE); RemoveAIUpdateEvent(); } void OnDied(Unit * mKiller) { CastTime(); RemoveAIUpdateEvent(); } void AIUpdate() { float val = sRand.rand(100.0f); SpellCast(val); } void SpellCast(float val) { if(_unit->GetCurrentSpell() == NULL && _unit->GetAIInterface()->GetNextTarget()) { float comulativeperc = 0; Unit *target = NULL; for(int i=0;iGetAIInterface()->GetNextTarget(); switch(spells[i].targettype) { case TARGET_SELF: case TARGET_VARIOUS: _unit->CastSpell(_unit, spells[i].info, spells[i].instant); break; case TARGET_ATTACKING: _unit->CastSpell(target, spells[i].info, spells[i].instant); break; case TARGET_DESTINATION: _unit->CastSpellAoF(target->GetPositionX(),target->GetPositionY(),target->GetPositionZ(), spells[i].info, spells[i].instant); break; } if (spells[i].speech != "") { _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, spells[i].speech.c_str()); _unit->PlaySoundToSet(spells[i].soundid); } m_spellcheck[i] = false; return; } if ((val > comulativeperc && val <= (comulativeperc + spells[i].perctrigger)) || !spells[i].casttime) { _unit->setAttackTimer(spells[i].attackstoptimer, false); m_spellcheck[i] = true; } comulativeperc += spells[i].perctrigger; } } } protected: int nrspells; }; // Millhouse ManastormAI #define CN_MILLHOUSE_MANASTORM 20977 #define SIMPLE_TELEPORT_MM 12980 #define CONJURE_WATER 36879 // SSS =/ #define ARCANE_INTELLECT 36880 #define ICE_ARMOR 36881 #define DRINK 30024 #define FIREBALL_MM 14034 #define FROSTBOLT_MM 15497 #define FIRE_BLAST_MM 13341 #define CONE_OF_COLD 12611 #define ARCANE_MISSILES 33832 // DBC: 33832, 33833 #define PYROBLAST 33975 //#define CHILLED 7321 effect of ICE_ARMOR 36881 class MillhouseManastormAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(MillhouseManastormAI); SP_AI_Spell spells[11]; bool m_spellcheck[11]; MillhouseManastormAI(Creature* pCreature) : CreatureAIScript(pCreature) { nrspells = 11; for(int i=0;iCastSpell(_unit, spells[0].info, spells[0].instant); } void OnCombatStart(Unit* mTarget) { CastTime(); RegisterAIUpdateEvent(_unit->GetUInt32Value(UNIT_FIELD_BASEATTACKTIME)); } void CastTime() { for(int i=0;iGetUInt32Value(UNIT_FIELD_POWER1) < _unit->GetUInt32Value(UNIT_FIELD_BASE_MANA)) { _unit->CastSpell(_unit, spells[1].info, spells[1].instant); _unit->CastSpell(_unit, spells[4].info, spells[4].instant); }*/ _unit->CastSpell(_unit, spells[1].info, spells[1].instant); _unit->CastSpell(_unit, spells[4].info, spells[4].instant); _unit->GetAIInterface()->setCurrentAgent(AGENT_NULL); _unit->GetAIInterface()->SetAIState(STATE_IDLE); RemoveAIUpdateEvent(); } void OnDied(Unit * mKiller) { CastTime(); RemoveAIUpdateEvent(); } void AIUpdate() { float val = sRand.rand(100.0f); SpellCast(val); } void SpellCast(float val) { if(_unit->GetCurrentSpell() == NULL && _unit->GetAIInterface()->GetNextTarget()) { float comulativeperc = 0; Unit *target = NULL; for(int i=0;iGetAIInterface()->GetNextTarget(); switch(spells[i].targettype) { case TARGET_SELF: case TARGET_VARIOUS: _unit->CastSpell(_unit, spells[i].info, spells[i].instant); break; case TARGET_ATTACKING: _unit->CastSpell(target, spells[i].info, spells[i].instant); break; case TARGET_DESTINATION: _unit->CastSpellAoF(target->GetPositionX(),target->GetPositionY(),target->GetPositionZ(), spells[i].info, spells[i].instant); break; } if (spells[i].speech != "") { _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, spells[i].speech.c_str()); _unit->PlaySoundToSet(spells[i].soundid); } m_spellcheck[i] = false; return; } if ((val > comulativeperc && val <= (comulativeperc + spells[i].perctrigger)) || !spells[i].casttime) { _unit->setAttackTimer(spells[i].attackstoptimer, false); m_spellcheck[i] = true; } comulativeperc += spells[i].perctrigger; } } } protected: int nrspells; }; // Negaton ScreamerAI // this one needs some more work for dmg taken dmg type, but I don't have time for it... #define CN_NEGATON_SCREAMER 20875 // I need to add missing about 15 mobs (w00t? More? =() and to this script // OnDamageTaken function with check of spell dmg type and correc spell casts in diff cases #define PSYCHIC_SCREAM 13704 #define DAMAGE_REDUCTION_SHADOW 34338 #define DAMAGE_REDUCTION_FROST 34334 #define DAMAGE_REDUCTION_ARCANE 34331 #define DAMAGE_REDUCTION_FIRE 34333 #define DAMAGE_REDUCTION_HOLY 34336 #define DAMAGE_REDUCTION_NATURE 34335 //#define DAMAGE_REDUCTION_PHYSICAL 34337 #define SHADOW_ENERGY 34399 // Energy SSS-s (I am sure only to spells shadow-frost-arcane-fire) #define FROST_ENERGY 34404 #define ARCANE_ENERGY 34401 #define FIRE_ENERGY 34398 #define HOLY_ENERGY 34403 #define NATURE_ENERGY 34402 //#define PHYSICAL_ENERGY #define SHADOW_BOLT_VOLLEY 36736 #define FROSTBOLT_VOLLEY 36741 #define ARCANE_VOLLEY 36738 #define FIREBALL_VOLLEY 36742 #define HOLY_VOLLEY 36743 #define LIGHTNING_BOLT_VOLLEY 36740 //#define _VOLLEY class NegatonScreamerAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(NegatonScreamerAI); SP_AI_Spell spells[19]; bool m_spellcheck[19]; NegatonScreamerAI(Creature* pCreature) : CreatureAIScript(pCreature) { nrspells = 19; for(int i=0;iGetUInt32Value(UNIT_FIELD_BASEATTACKTIME)); } void CastTime() { for(int i=0;iGetAIInterface()->setCurrentAgent(AGENT_NULL); _unit->GetAIInterface()->SetAIState(STATE_IDLE); RemoveAIUpdateEvent(); } void OnDied(Unit * mKiller) { CastTime(); RemoveAIUpdateEvent(); } void AIUpdate() { float val = sRand.rand(100.0f); SpellCast(val); } void SpellCast(float val) { if(_unit->GetCurrentSpell() == NULL && _unit->GetAIInterface()->GetNextTarget()) { float comulativeperc = 0; Unit *target = NULL; for(int i=0;iGetAIInterface()->GetNextTarget(); switch(spells[i].targettype) { case TARGET_SELF: case TARGET_VARIOUS: _unit->CastSpell(_unit, spells[i].info, spells[i].instant); break; case TARGET_ATTACKING: _unit->CastSpell(target, spells[i].info, spells[i].instant); break; case TARGET_DESTINATION: _unit->CastSpellAoF(target->GetPositionX(),target->GetPositionY(),target->GetPositionZ(), spells[i].info, spells[i].instant); break; } if (spells[i].speech != "") { _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, spells[i].speech.c_str()); _unit->PlaySoundToSet(spells[i].soundid); } m_spellcheck[i] = false; return; } if ((val > comulativeperc && val <= (comulativeperc + spells[i].perctrigger)) || !spells[i].casttime) { _unit->setAttackTimer(spells[i].attackstoptimer, false); m_spellcheck[i] = true; } comulativeperc += spells[i].perctrigger; } } } protected: int nrspells; }; // Negaton Warp-MasterAI #define CN_NEGATON_WARP_MASTER 20873 #define SUMMON_NEGATION_FIELD 36813 class NegatonWarpMasterAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(NegatonWarpMasterAI); SP_AI_Spell spells[1]; bool m_spellcheck[1]; NegatonWarpMasterAI(Creature* pCreature) : CreatureAIScript(pCreature) { nrspells = 1; for(int i=0;iGetUInt32Value(UNIT_FIELD_BASEATTACKTIME)); } void CastTime() { for(int i=0;iGetAIInterface()->setCurrentAgent(AGENT_NULL); _unit->GetAIInterface()->SetAIState(STATE_IDLE); RemoveAIUpdateEvent(); } void OnDied(Unit * mKiller) { CastTime(); RemoveAIUpdateEvent(); } void AIUpdate() { float val = sRand.rand(100.0f); SpellCast(val); } void SpellCast(float val) { if(_unit->GetCurrentSpell() == NULL && _unit->GetAIInterface()->GetNextTarget()) { float comulativeperc = 0; Unit *target = NULL; for(int i=0;iGetAIInterface()->GetNextTarget(); switch(spells[i].targettype) { case TARGET_SELF: case TARGET_VARIOUS: _unit->CastSpell(_unit, spells[i].info, spells[i].instant); break; case TARGET_ATTACKING: _unit->CastSpell(target, spells[i].info, spells[i].instant); break; case TARGET_DESTINATION: _unit->CastSpellAoF(target->GetPositionX(),target->GetPositionY(),target->GetPositionZ(), spells[i].info, spells[i].instant); break; } if (spells[i].speech != "") { _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, spells[i].speech.c_str()); _unit->PlaySoundToSet(spells[i].soundid); } m_spellcheck[i] = false; return; } if ((val > comulativeperc && val <= (comulativeperc + spells[i].perctrigger)) || !spells[i].casttime) { _unit->setAttackTimer(spells[i].attackstoptimer, false); m_spellcheck[i] = true; } comulativeperc += spells[i].perctrigger; } } } protected: int nrspells; }; // Negaton FieldAI #define CN_NEGATON_FIELD 21414 #define NEGATION_FIELD 36728 // DBC: 36728, 36729; class NegatonFieldAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(NegatonFieldAI); SP_AI_Spell spells[1]; bool m_spellcheck[1]; NegatonFieldAI(Creature* pCreature) : CreatureAIScript(pCreature) { nrspells = 1; for(int i=0;iCastSpell(_unit, spells[0].info, spells[0].instant); } void OnCombatStart(Unit* mTarget) { CastTime(); RegisterAIUpdateEvent(_unit->GetUInt32Value(UNIT_FIELD_BASEATTACKTIME)); } void CastTime() { for(int i=0;iGetAIInterface()->setCurrentAgent(AGENT_NULL); _unit->GetAIInterface()->SetAIState(STATE_IDLE); RemoveAIUpdateEvent(); } void OnDied(Unit * mKiller) { CastTime(); RemoveAIUpdateEvent(); } void AIUpdate() { float val = sRand.rand(100.0f); SpellCast(val); } void SpellCast(float val) { if(_unit->GetCurrentSpell() == NULL && _unit->GetAIInterface()->GetNextTarget()) { float comulativeperc = 0; Unit *target = NULL; for(int i=0;iGetAIInterface()->GetNextTarget(); switch(spells[i].targettype) { case TARGET_SELF: case TARGET_VARIOUS: _unit->CastSpell(_unit, spells[i].info, spells[i].instant); break; case TARGET_ATTACKING: _unit->CastSpell(target, spells[i].info, spells[i].instant); break; case TARGET_DESTINATION: _unit->CastSpellAoF(target->GetPositionX(),target->GetPositionY(),target->GetPositionZ(), spells[i].info, spells[i].instant); break; } if (spells[i].speech != "") { _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, spells[i].speech.c_str()); _unit->PlaySoundToSet(spells[i].soundid); } m_spellcheck[i] = false; return; } if ((val > comulativeperc && val <= (comulativeperc + spells[i].perctrigger)) || !spells[i].casttime) { _unit->setAttackTimer(spells[i].attackstoptimer, false); m_spellcheck[i] = true; } comulativeperc += spells[i].perctrigger; } } } protected: int nrspells; }; // Phase-HunterAI #define CN_PHASE_HUNTER 20906 #define SIMPLE_TELEPORT_PH 12980 #define BACK_ATTACK 36909 #define WARP 36908 // lack of core support? #define PHASE_BURST 36910 class PhaseHunterAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(PhaseHunterAI); SP_AI_Spell spells[4]; bool m_spellcheck[4]; PhaseHunterAI(Creature* pCreature) : CreatureAIScript(pCreature) { nrspells = 4; for(int i=0;iCastSpell(_unit, spells[0].info, spells[0].instant); CastTime(); RegisterAIUpdateEvent(_unit->GetUInt32Value(UNIT_FIELD_BASEATTACKTIME)); } void CastTime() { for(int i=0;iGetAIInterface()->setCurrentAgent(AGENT_NULL); _unit->GetAIInterface()->SetAIState(STATE_IDLE); RemoveAIUpdateEvent(); } void OnDied(Unit * mKiller) { CastTime(); RemoveAIUpdateEvent(); } void AIUpdate() { float val = sRand.rand(100.0f); SpellCast(val); } void SpellCast(float val) { if(_unit->GetCurrentSpell() == NULL && _unit->GetAIInterface()->GetNextTarget()) { float comulativeperc = 0; Unit *target = NULL; for(int i=0;iGetAIInterface()->GetNextTarget(); switch(spells[i].targettype) { case TARGET_SELF: case TARGET_VARIOUS: _unit->CastSpell(_unit, spells[i].info, spells[i].instant); break; case TARGET_ATTACKING: _unit->CastSpell(target, spells[i].info, spells[i].instant); break; case TARGET_DESTINATION: _unit->CastSpellAoF(target->GetPositionX(),target->GetPositionY(),target->GetPositionZ(), spells[i].info, spells[i].instant); break; } if (m_spellcheck[2] == true) { uint32 chance = sRand.randInt(100); if (chance > 0 && chance <= 30) _unit->CastSpell(_unit, spells[1].info, spells[1].instant); else return; } if (spells[i].speech != "") { _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, spells[i].speech.c_str()); _unit->PlaySoundToSet(spells[i].soundid); } m_spellcheck[i] = false; return; } if ((val > comulativeperc && val <= (comulativeperc + spells[i].perctrigger)) || !spells[i].casttime) { _unit->setAttackTimer(spells[i].attackstoptimer, false); m_spellcheck[i] = true; } comulativeperc += spells[i].perctrigger; } } } protected: int nrspells; }; // Protean HorrorAI #define CN_PROTEAN_HORROR 20865 #define TOOTHY_BITE 36612 //#define BLOODY_EXPLOSION 36588 class ProteanHorrorAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(ProteanHorrorAI); SP_AI_Spell spells[1]; bool m_spellcheck[1]; ProteanHorrorAI(Creature* pCreature) : CreatureAIScript(pCreature) { nrspells = 1; for(int i=0;iGetUInt32Value(UNIT_FIELD_BASEATTACKTIME)); } void CastTime() { for(int i=0;iGetAIInterface()->setCurrentAgent(AGENT_NULL); _unit->GetAIInterface()->SetAIState(STATE_IDLE); RemoveAIUpdateEvent(); } void OnDied(Unit * mKiller) { CastTime(); RemoveAIUpdateEvent(); } void AIUpdate() { float val = sRand.rand(100.0f); SpellCast(val); } void SpellCast(float val) { if(_unit->GetCurrentSpell() == NULL && _unit->GetAIInterface()->GetNextTarget()) { float comulativeperc = 0; Unit *target = NULL; for(int i=0;iGetAIInterface()->GetNextTarget(); switch(spells[i].targettype) { case TARGET_SELF: case TARGET_VARIOUS: _unit->CastSpell(_unit, spells[i].info, spells[i].instant); break; case TARGET_ATTACKING: _unit->CastSpell(target, spells[i].info, spells[i].instant); break; case TARGET_DESTINATION: _unit->CastSpellAoF(target->GetPositionX(),target->GetPositionY(),target->GetPositionZ(), spells[i].info, spells[i].instant); break; } if (spells[i].speech != "") { _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, spells[i].speech.c_str()); _unit->PlaySoundToSet(spells[i].soundid); } m_spellcheck[i] = false; return; } if ((val > comulativeperc && val <= (comulativeperc + spells[i].perctrigger)) || !spells[i].casttime) { _unit->setAttackTimer(spells[i].attackstoptimer, false); m_spellcheck[i] = true; } comulativeperc += spells[i].perctrigger; } } } protected: int nrspells; }; // Protean NightmareAI #define CN_PROTEAN_NIGHTMARE 20864 #define INCUBATION 36622 #define INFECTIOUS_POISON 36619 #define GAPIND_MAW 36617 class ProteanNightmareAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(ProteanNightmareAI); SP_AI_Spell spells[3]; bool m_spellcheck[3]; ProteanNightmareAI(Creature* pCreature) : CreatureAIScript(pCreature) { nrspells = 3; for(int i=0;iGetUInt32Value(UNIT_FIELD_BASEATTACKTIME)); } void CastTime() { for(int i=0;iGetAIInterface()->setCurrentAgent(AGENT_NULL); _unit->GetAIInterface()->SetAIState(STATE_IDLE); RemoveAIUpdateEvent(); } void OnDied(Unit * mKiller) { CastTime(); RemoveAIUpdateEvent(); } void AIUpdate() { float val = sRand.rand(100.0f); SpellCast(val); } void SpellCast(float val) { if(_unit->GetCurrentSpell() == NULL && _unit->GetAIInterface()->GetNextTarget()) { float comulativeperc = 0; Unit *target = NULL; for(int i=0;iGetAIInterface()->GetNextTarget(); switch(spells[i].targettype) { case TARGET_SELF: case TARGET_VARIOUS: _unit->CastSpell(_unit, spells[i].info, spells[i].instant); break; case TARGET_ATTACKING: _unit->CastSpell(target, spells[i].info, spells[i].instant); break; case TARGET_DESTINATION: _unit->CastSpellAoF(target->GetPositionX(),target->GetPositionY(),target->GetPositionZ(), spells[i].info, spells[i].instant); break; } if (spells[i].speech != "") { _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, spells[i].speech.c_str()); _unit->PlaySoundToSet(spells[i].soundid); } m_spellcheck[i] = false; return; } if ((val > comulativeperc && val <= (comulativeperc + spells[i].perctrigger)) || !spells[i].casttime) { _unit->setAttackTimer(spells[i].attackstoptimer, false); m_spellcheck[i] = true; } comulativeperc += spells[i].perctrigger; } } } protected: int nrspells; }; // Sulfuron Magma-ThrowerAI #define CN_SULFURON_MAGMA_THROWER 20909 #define SIMPLE_TELEPORT_SMT 12980 #define SHADOW_BOLT_SMT 36986 // DBC: 36987, 36986; #define MAGMA_THROWERS_CURSE 36917 #define RAIN_OF_FIRE 19717 class SulfuronMagmaThrowerAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(SulfuronMagmaThrowerAI); SP_AI_Spell spells[4]; bool m_spellcheck[4]; SulfuronMagmaThrowerAI(Creature* pCreature) : CreatureAIScript(pCreature) { nrspells = 4; for(int i=0;iCastSpell(_unit, spells[0].info, spells[0].instant); CastTime(); RegisterAIUpdateEvent(_unit->GetUInt32Value(UNIT_FIELD_BASEATTACKTIME)); } void CastTime() { for(int i=0;iGetAIInterface()->setCurrentAgent(AGENT_NULL); _unit->GetAIInterface()->SetAIState(STATE_IDLE); RemoveAIUpdateEvent(); } void OnDied(Unit * mKiller) { CastTime(); RemoveAIUpdateEvent(); } void AIUpdate() { float val = sRand.rand(100.0f); SpellCast(val); } void SpellCast(float val) { if(_unit->GetCurrentSpell() == NULL && _unit->GetAIInterface()->GetNextTarget()) { float comulativeperc = 0; Unit *target = NULL; for(int i=0;iGetAIInterface()->GetNextTarget(); switch(spells[i].targettype) { case TARGET_SELF: case TARGET_VARIOUS: _unit->CastSpell(_unit, spells[i].info, spells[i].instant); break; case TARGET_ATTACKING: _unit->CastSpell(target, spells[i].info, spells[i].instant); break; case TARGET_DESTINATION: _unit->CastSpellAoF(target->GetPositionX(),target->GetPositionY(),target->GetPositionZ(), spells[i].info, spells[i].instant); break; } if (spells[i].speech != "") { _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, spells[i].speech.c_str()); _unit->PlaySoundToSet(spells[i].soundid); } m_spellcheck[i] = false; return; } if ((val > comulativeperc && val <= (comulativeperc + spells[i].perctrigger)) || !spells[i].casttime) { _unit->setAttackTimer(spells[i].attackstoptimer, false); m_spellcheck[i] = true; } comulativeperc += spells[i].perctrigger; } } } protected: int nrspells; }; // Spiteful TemptressAI #define CN_SPITEFUL_TEMPTRESS 20883 #define SHADOW_BOLT_ST 36868 #define DOMINATION_ST 36866 #define SPITEFUL_FURY 36886 #define PRAYER_OF_MENDING 33280 // DBC: 33280, 33110; SSS class SpitefulTemptressAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(SpitefulTemptressAI); SP_AI_Spell spells[4]; bool m_spellcheck[4]; SpitefulTemptressAI(Creature* pCreature) : CreatureAIScript(pCreature) { nrspells = 4; for(int i=0;iGetUInt32Value(UNIT_FIELD_BASEATTACKTIME)); } void CastTime() { for(int i=0;iGetAIInterface()->setCurrentAgent(AGENT_NULL); _unit->GetAIInterface()->SetAIState(STATE_IDLE); RemoveAIUpdateEvent(); } void OnDied(Unit * mKiller) { CastTime(); RemoveAIUpdateEvent(); } void AIUpdate() { float val = sRand.rand(100.0f); SpellCast(val); } void SpellCast(float val) { if(_unit->GetCurrentSpell() == NULL && _unit->GetAIInterface()->GetNextTarget()) { float comulativeperc = 0; Unit *target = NULL; for(int i=0;iGetAIInterface()->GetNextTarget(); switch(spells[i].targettype) { case TARGET_SELF: case TARGET_VARIOUS: _unit->CastSpell(_unit, spells[i].info, spells[i].instant); break; case TARGET_ATTACKING: _unit->CastSpell(target, spells[i].info, spells[i].instant); break; case TARGET_DESTINATION: _unit->CastSpellAoF(target->GetPositionX(),target->GetPositionY(),target->GetPositionZ(), spells[i].info, spells[i].instant); break; } if (spells[i].speech != "") { _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, spells[i].speech.c_str()); _unit->PlaySoundToSet(spells[i].soundid); } m_spellcheck[i] = false; return; } if ((val > comulativeperc && val <= (comulativeperc + spells[i].perctrigger)) || !spells[i].casttime) { _unit->setAttackTimer(spells[i].attackstoptimer, false); m_spellcheck[i] = true; } comulativeperc += spells[i].perctrigger; } } } protected: int nrspells; }; // Soul DevourerAI #define CN_SOUL_DEVOURER 20866 #define SIGHTLESS_EYE 36644 #define LAVA_BREATH 21333 // doesn't have animation? #define FEL_BREATH 36654 #define FRENZY 33958 class SoulDevourerAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(SoulDevourerAI); SP_AI_Spell spells[4]; bool m_spellcheck[4]; SoulDevourerAI(Creature* pCreature) : CreatureAIScript(pCreature) { nrspells = 4; for(int i=0;iCastSpell(_unit, spells[0].info, spells[0].instant); CastTime(); RegisterAIUpdateEvent(_unit->GetUInt32Value(UNIT_FIELD_BASEATTACKTIME)); } void CastTime() { for(int i=0;iGetAIInterface()->setCurrentAgent(AGENT_NULL); _unit->GetAIInterface()->SetAIState(STATE_IDLE); RemoveAIUpdateEvent(); } void OnDied(Unit * mKiller) { CastTime(); RemoveAIUpdateEvent(); } void AIUpdate() { float val = sRand.rand(100.0f); SpellCast(val); } void SpellCast(float val) { if(_unit->GetCurrentSpell() == NULL && _unit->GetAIInterface()->GetNextTarget()) { float comulativeperc = 0; Unit *target = NULL; for(int i=0;iGetAIInterface()->GetNextTarget(); switch(spells[i].targettype) { case TARGET_SELF: case TARGET_VARIOUS: _unit->CastSpell(_unit, spells[i].info, spells[i].instant); break; case TARGET_ATTACKING: _unit->CastSpell(target, spells[i].info, spells[i].instant); break; case TARGET_DESTINATION: _unit->CastSpellAoF(target->GetPositionX(),target->GetPositionY(),target->GetPositionZ(), spells[i].info, spells[i].instant); break; } if (spells[i].speech != "") { _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, spells[i].speech.c_str()); _unit->PlaySoundToSet(spells[i].soundid); } m_spellcheck[i] = false; return; } if ((val > comulativeperc && val <= (comulativeperc + spells[i].perctrigger)) || !spells[i].casttime) { _unit->setAttackTimer(spells[i].attackstoptimer, false); m_spellcheck[i] = true; } comulativeperc += spells[i].perctrigger; } } } protected: int nrspells; }; // SolomonAI #define CN_SOLOMON 798 // not sure if this boy should be scripted, but he was in DBC and had spells, so I couldn't // stop myself to not give little boy deadly skills muhahah =) #define SLIME_SPRAY 36486 #define SAW_BLADE 32735 #define CRUSADER_STRIKE 35509 // SE (script effect) class SolomonAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(SolomonAI); SP_AI_Spell spells[3]; bool m_spellcheck[3]; SolomonAI(Creature* pCreature) : CreatureAIScript(pCreature) { nrspells = 3; for(int i=0;iGetUInt32Value(UNIT_FIELD_BASEATTACKTIME)); } void CastTime() { for(int i=0;iGetAIInterface()->setCurrentAgent(AGENT_NULL); _unit->GetAIInterface()->SetAIState(STATE_IDLE); RemoveAIUpdateEvent(); } void OnDied(Unit * mKiller) { CastTime(); RemoveAIUpdateEvent(); } void AIUpdate() { float val = sRand.rand(100.0f); SpellCast(val); } void SpellCast(float val) { if(_unit->GetCurrentSpell() == NULL && _unit->GetAIInterface()->GetNextTarget()) { float comulativeperc = 0; Unit *target = NULL; for(int i=0;iGetAIInterface()->GetNextTarget(); switch(spells[i].targettype) { case TARGET_SELF: case TARGET_VARIOUS: _unit->CastSpell(_unit, spells[i].info, spells[i].instant); break; case TARGET_ATTACKING: _unit->CastSpell(target, spells[i].info, spells[i].instant); break; case TARGET_DESTINATION: _unit->CastSpellAoF(target->GetPositionX(),target->GetPositionY(),target->GetPositionZ(), spells[i].info, spells[i].instant); break; } if (spells[i].speech != "") { _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, spells[i].speech.c_str()); _unit->PlaySoundToSet(spells[i].soundid); } m_spellcheck[i] = false; return; } if ((val > comulativeperc && val <= (comulativeperc + spells[i].perctrigger)) || !spells[i].casttime) { _unit->setAttackTimer(spells[i].attackstoptimer, false); m_spellcheck[i] = true; } comulativeperc += spells[i].perctrigger; } } } protected: int nrspells; }; // Skulking WitchAI #define CN_SKULKING_WITCH 20882 // works really cool as assassin :) #define CHASTISE 36863 #define GOUGE 36862 #define LASH_OF_PAIN 36864 #define GREAT_INVISIBILITY 16380 class SkulkingWitchAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(SkulkingWitchAI); SP_AI_Spell spells[4]; bool m_spellcheck[4]; SkulkingWitchAI(Creature* pCreature) : CreatureAIScript(pCreature) { nrspells = 4; for(int i=0;iCastSpell(_unit, spells[3].info, spells[3].instant); FIRST_ATTACK = 1; } void OnCombatStart(Unit* mTarget) { FIRST_ATTACK = 1; CastTime(); RegisterAIUpdateEvent(_unit->GetUInt32Value(UNIT_FIELD_BASEATTACKTIME)); } void CastTime() { for(int i=0;iCastSpell(_unit, spells[3].info, spells[3].instant); CastTime(); _unit->GetAIInterface()->setCurrentAgent(AGENT_NULL); _unit->GetAIInterface()->SetAIState(STATE_IDLE); RemoveAIUpdateEvent(); } void OnDied(Unit * mKiller) { FIRST_ATTACK = 1; _unit->CastSpell(_unit, spells[3].info, spells[3].instant); CastTime(); RemoveAIUpdateEvent(); } void AIUpdate() { if (FIRST_ATTACK && _unit->GetAIInterface()->GetNextTarget()) { FIRST_ATTACK = 0; Unit * target = NULL; target = _unit->GetAIInterface()->GetNextTarget(); _unit->CastSpell(target, spells[1].info, spells[1].instant); } else { float val = sRand.rand(100.0f); SpellCast(val); } } void SpellCast(float val) { if(_unit->GetCurrentSpell() == NULL && _unit->GetAIInterface()->GetNextTarget()) { float comulativeperc = 0; Unit *target = NULL; for(int i=0;iGetAIInterface()->GetNextTarget(); switch(spells[i].targettype) { case TARGET_SELF: case TARGET_VARIOUS: _unit->CastSpell(_unit, spells[i].info, spells[i].instant); break; case TARGET_ATTACKING: _unit->CastSpell(target, spells[i].info, spells[i].instant); break; case TARGET_DESTINATION: _unit->CastSpellAoF(target->GetPositionX(),target->GetPositionY(),target->GetPositionZ(), spells[i].info, spells[i].instant); break; } if (spells[i].speech != "") { _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, spells[i].speech.c_str()); _unit->PlaySoundToSet(spells[i].soundid); } m_spellcheck[i] = false; return; } if ((val > comulativeperc && val <= (comulativeperc + spells[i].perctrigger)) || !spells[i].casttime) { _unit->setAttackTimer(spells[i].attackstoptimer, false); m_spellcheck[i] = true; } comulativeperc += spells[i].perctrigger; } } } protected: uint32 FIRST_ATTACK; int nrspells; }; // Sightless EyeAI #define CN_SIGHTLESS_EYE 21346 #define SIGHTLESS_TOUCH 36646 class SightlessEyeAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(SightlessEyeAI); SP_AI_Spell spells[1]; bool m_spellcheck[1]; SightlessEyeAI(Creature* pCreature) : CreatureAIScript(pCreature) { nrspells = 1; for(int i=0;iGetUInt32Value(UNIT_FIELD_BASEATTACKTIME)); } void CastTime() { for(int i=0;iGetAIInterface()->setCurrentAgent(AGENT_NULL); _unit->GetAIInterface()->SetAIState(STATE_IDLE); RemoveAIUpdateEvent(); } void OnDied(Unit * mKiller) { CastTime(); RemoveAIUpdateEvent(); } void AIUpdate() { float val = sRand.rand(100.0f); SpellCast(val); } void SpellCast(float val) { if(_unit->GetCurrentSpell() == NULL && _unit->GetAIInterface()->GetNextTarget()) { float comulativeperc = 0; Unit *target = NULL; for(int i=0;iGetAIInterface()->GetNextTarget(); switch(spells[i].targettype) { case TARGET_SELF: case TARGET_VARIOUS: _unit->CastSpell(_unit, spells[i].info, spells[i].instant); break; case TARGET_ATTACKING: _unit->CastSpell(target, spells[i].info, spells[i].instant); break; case TARGET_DESTINATION: _unit->CastSpellAoF(target->GetPositionX(),target->GetPositionY(),target->GetPositionZ(), spells[i].info, spells[i].instant); break; } if (spells[i].speech != "") { _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, spells[i].speech.c_str()); _unit->PlaySoundToSet(spells[i].soundid); } m_spellcheck[i] = false; return; } if ((val > comulativeperc && val <= (comulativeperc + spells[i].perctrigger)) || !spells[i].casttime) { _unit->setAttackTimer(spells[i].attackstoptimer, false); m_spellcheck[i] = true; } comulativeperc += spells[i].perctrigger; } } } protected: int nrspells; }; // Sargeron HellcallerAI #define CN_SARGERON_HELLCALLER 20902 #define HELL_RAIN 36829 #define CURSE_OF_THE_ELEMENTS 36831 #define INCINERATE 36832 class SargeronHellcallerAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(SargeronHellcallerAI); SP_AI_Spell spells[3]; bool m_spellcheck[3]; SargeronHellcallerAI(Creature* pCreature) : CreatureAIScript(pCreature) { nrspells = 3; for(int i=0;iGetUInt32Value(UNIT_FIELD_BASEATTACKTIME)); } void CastTime() { for(int i=0;iGetAIInterface()->setCurrentAgent(AGENT_NULL); _unit->GetAIInterface()->SetAIState(STATE_IDLE); RemoveAIUpdateEvent(); } void OnDied(Unit * mKiller) { CastTime(); RemoveAIUpdateEvent(); } void AIUpdate() { float val = sRand.rand(100.0f); SpellCast(val); } void SpellCast(float val) { if(_unit->GetCurrentSpell() == NULL && _unit->GetAIInterface()->GetNextTarget()) { float comulativeperc = 0; Unit *target = NULL; for(int i=0;iGetAIInterface()->GetNextTarget(); switch(spells[i].targettype) { case TARGET_SELF: case TARGET_VARIOUS: _unit->CastSpell(_unit, spells[i].info, spells[i].instant); break; case TARGET_ATTACKING: _unit->CastSpell(target, spells[i].info, spells[i].instant); break; case TARGET_DESTINATION: _unit->CastSpellAoF(target->GetPositionX(),target->GetPositionY(),target->GetPositionZ(), spells[i].info, spells[i].instant); break; } if (spells[i].speech != "") { _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, spells[i].speech.c_str()); _unit->PlaySoundToSet(spells[i].soundid); } m_spellcheck[i] = false; return; } if ((val > comulativeperc && val <= (comulativeperc + spells[i].perctrigger)) || !spells[i].casttime) { _unit->setAttackTimer(spells[i].attackstoptimer, false); m_spellcheck[i] = true; } comulativeperc += spells[i].perctrigger; } } } protected: int nrspells; }; // Unbound DevastatorAI #define CN_UNBOUND_DEVASTATOR 20881 #define DEAFENING_ROAR 36887 #define DEVASTATE 36894 // DBC: 36891, 36894; class UnboundDevastatorAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(UnboundDevastatorAI); SP_AI_Spell spells[2]; bool m_spellcheck[2]; UnboundDevastatorAI(Creature* pCreature) : CreatureAIScript(pCreature) { nrspells = 2; for(int i=0;iGetUInt32Value(UNIT_FIELD_BASEATTACKTIME)); } void CastTime() { for(int i=0;iGetAIInterface()->setCurrentAgent(AGENT_NULL); _unit->GetAIInterface()->SetAIState(STATE_IDLE); RemoveAIUpdateEvent(); } void OnDied(Unit * mKiller) { CastTime(); RemoveAIUpdateEvent(); } void AIUpdate() { float val = sRand.rand(100.0f); SpellCast(val); } void SpellCast(float val) { if(_unit->GetCurrentSpell() == NULL && _unit->GetAIInterface()->GetNextTarget()) { float comulativeperc = 0; Unit *target = NULL; for(int i=0;iGetAIInterface()->GetNextTarget(); switch(spells[i].targettype) { case TARGET_SELF: case TARGET_VARIOUS: _unit->CastSpell(_unit, spells[i].info, spells[i].instant); break; case TARGET_ATTACKING: _unit->CastSpell(target, spells[i].info, spells[i].instant); break; case TARGET_DESTINATION: _unit->CastSpellAoF(target->GetPositionX(),target->GetPositionY(),target->GetPositionZ(), spells[i].info, spells[i].instant); break; } if (spells[i].speech != "") { _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, spells[i].speech.c_str()); _unit->PlaySoundToSet(spells[i].soundid); } m_spellcheck[i] = false; return; } if ((val > comulativeperc && val <= (comulativeperc + spells[i].perctrigger)) || !spells[i].casttime) { _unit->setAttackTimer(spells[i].attackstoptimer, false); m_spellcheck[i] = true; } comulativeperc += spells[i].perctrigger; } } } protected: int nrspells; }; // Unchained DoombringerAI #define CN_UNCHAINED_DOOMBRINGER 20900 #define AGONIZING_ARMOR 36836 #define WAR_STOMP 36835 #define BERSEKER_CHARGE 36833 // should charge the farthest enemy class UnchainedDoombringerAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(UnchainedDoombringerAI); SP_AI_Spell spells[3]; bool m_spellcheck[3]; UnchainedDoombringerAI(Creature* pCreature) : CreatureAIScript(pCreature) { nrspells = 3; for(int i=0;iGetUInt32Value(UNIT_FIELD_BASEATTACKTIME)); } void CastTime() { for(int i=0;iGetAIInterface()->setCurrentAgent(AGENT_NULL); _unit->GetAIInterface()->SetAIState(STATE_IDLE); RemoveAIUpdateEvent(); } void OnDied(Unit * mKiller) { CastTime(); RemoveAIUpdateEvent(); } void AIUpdate() { float val = sRand.rand(100.0f); SpellCast(val); } void SpellCast(float val) { if(_unit->GetCurrentSpell() == NULL && _unit->GetAIInterface()->GetNextTarget()) { float comulativeperc = 0; Unit *target = NULL; for(int i=0;iGetAIInterface()->GetNextTarget(); switch(spells[i].targettype) { case TARGET_SELF: case TARGET_VARIOUS: _unit->CastSpell(_unit, spells[i].info, spells[i].instant); break; case TARGET_ATTACKING: _unit->CastSpell(target, spells[i].info, spells[i].instant); break; case TARGET_DESTINATION: _unit->CastSpellAoF(target->GetPositionX(),target->GetPositionY(),target->GetPositionZ(), spells[i].info, spells[i].instant); break; } if (spells[i].speech != "") { _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, spells[i].speech.c_str()); _unit->PlaySoundToSet(spells[i].soundid); } m_spellcheck[i] = false; return; } if ((val > comulativeperc && val <= (comulativeperc + spells[i].perctrigger)) || !spells[i].casttime) { _unit->setAttackTimer(spells[i].attackstoptimer, false); m_spellcheck[i] = true; } comulativeperc += spells[i].perctrigger; } } } protected: int nrspells; }; // Warder CorpseAI #define CN_WARDER_CORPSE 21303 #define CORPSE_BURST_WC 36593 #define BLOODY_EXPLOSION_WC 36599 //#define PERMANENT_FEIGN_DEATH_ROOT_WC 31261 // I don't have much infos and I am not sure about how it should work // I presume this is just corpse which should cast spell when player is close or attk it // so same situation like in Defender Corpse class WarderCorpseAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(WarderCorpseAI); SP_AI_Spell spells[2]; bool m_spellcheck[2]; WarderCorpseAI(Creature* pCreature) : CreatureAIScript(pCreature) { nrspells = 2; for(int i=0;iCastSpell(_unit, spells[1].info, spells[1].instant); _unit->CastSpell(_unit, spells[0].info, spells[0].instant); CastTime(); RegisterAIUpdateEvent(_unit->GetUInt32Value(UNIT_FIELD_BASEATTACKTIME)); } void CastTime() { for(int i=0;iGetAIInterface()->setCurrentAgent(AGENT_NULL); _unit->GetAIInterface()->SetAIState(STATE_IDLE); RemoveAIUpdateEvent(); } void OnDied(Unit * mKiller) { CastTime(); RemoveAIUpdateEvent(); } void AIUpdate() { float val = sRand.rand(100.0f); SpellCast(val); } void SpellCast(float val) { if(_unit->GetCurrentSpell() == NULL && _unit->GetAIInterface()->GetNextTarget()) { float comulativeperc = 0; Unit *target = NULL; for(int i=0;iGetAIInterface()->GetNextTarget(); switch(spells[i].targettype) { case TARGET_SELF: case TARGET_VARIOUS: _unit->CastSpell(_unit, spells[i].info, spells[i].instant); break; case TARGET_ATTACKING: _unit->CastSpell(target, spells[i].info, spells[i].instant); break; case TARGET_DESTINATION: _unit->CastSpellAoF(target->GetPositionX(),target->GetPositionY(),target->GetPositionZ(), spells[i].info, spells[i].instant); break; } if (spells[i].speech != "") { _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, spells[i].speech.c_str()); _unit->PlaySoundToSet(spells[i].soundid); } m_spellcheck[i] = false; return; } if ((val > comulativeperc && val <= (comulativeperc + spells[i].perctrigger)) || !spells[i].casttime) { _unit->setAttackTimer(spells[i].attackstoptimer, false); m_spellcheck[i] = true; } comulativeperc += spells[i].perctrigger; } } } protected: int nrspells; }; // Sargeron ArcherAI #define CN_SARGERON_ARCHER 20901 #define FROST_ARROW 35964 //DBC: 35965, 35964; #define SHOT_SA 22907 #define RAPID_FIRE 36828 #define SCATTER_SHOT 23601 #define HOOKED_NET 36827 #define IMMOLATION_ARROW 35932 // DBC: 35932, 35935 class SargeronArcherAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(SargeronArcherAI); SP_AI_Spell spells[6]; bool m_spellcheck[6]; SargeronArcherAI(Creature* pCreature) : CreatureAIScript(pCreature) { nrspells = 6; for(int i=0;iGetUInt32Value(UNIT_FIELD_BASEATTACKTIME)); } void CastTime() { for(int i=0;iGetAIInterface()->setCurrentAgent(AGENT_NULL); _unit->GetAIInterface()->SetAIState(STATE_IDLE); RemoveAIUpdateEvent(); } void OnDied(Unit * mKiller) { CastTime(); RemoveAIUpdateEvent(); } void AIUpdate() { if (_unit->GetAIInterface()->GetNextTarget()) { Unit *target = NULL; target = _unit->GetAIInterface()->GetNextTarget(); if (_unit->GetDistance2dSq(target) >= 100.0f && _unit->GetDistanceSq(target) <= 900.0f) { _unit->GetAIInterface()->m_canMove = false; int RangedSpell; sRand.randInt(1000); RangedSpell=rand()%100; if (RangedSpell >= 0 && RangedSpell <= 13) { _unit->CastSpell(target, spells[0].info, spells[0].instant); _unit->setAttackTimer(spells[0].attackstoptimer, false); } if (RangedSpell > 12 && RangedSpell <= 25) { _unit->CastSpell(target, spells[3].info, spells[3].instant); _unit->setAttackTimer(spells[3].attackstoptimer, false); } if (RangedSpell > 25 && RangedSpell <= 38) { _unit->CastSpell(target, spells[5].info, spells[5].instant); _unit->setAttackTimer(spells[5].attackstoptimer, false); } if (RangedSpell > 38 && RangedSpell <= 44) { _unit->CastSpell(target, spells[2].info, spells[2].instant); _unit->setAttackTimer(spells[2].attackstoptimer, false); } if (RangedSpell > 44 && RangedSpell <= 50) { _unit->CastSpell(target, spells[4].info, spells[4].instant); _unit->setAttackTimer(spells[4].attackstoptimer, false); } else { _unit->CastSpell(target, spells[1].info, spells[1].instant); _unit->setAttackTimer(spells[1].attackstoptimer, false); } } else { _unit->GetAIInterface()->m_canMove = true; if (_unit->GetDistance2dSq(target) < 100.0f) { float val = sRand.rand(100.0f); SpellCast(val); } } } } void SpellCast(float val) { if(_unit->GetCurrentSpell() == NULL && _unit->GetAIInterface()->GetNextTarget()) // I was too lazy to rewrite it =S { float comulativeperc = 0; Unit *target = NULL; for(int i=0;iGetAIInterface()->GetNextTarget(); switch(spells[i].targettype) { case TARGET_SELF: case TARGET_VARIOUS: _unit->CastSpell(_unit, spells[i].info, spells[i].instant); break; case TARGET_ATTACKING: _unit->CastSpell(target, spells[i].info, spells[i].instant); break; case TARGET_DESTINATION: _unit->CastSpellAoF(target->GetPositionX(),target->GetPositionY(),target->GetPositionZ(), spells[i].info, spells[i].instant); break; } if (spells[i].speech != "") { _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, spells[i].speech.c_str()); _unit->PlaySoundToSet(spells[i].soundid); } m_spellcheck[i] = false; return; } if ((val > comulativeperc && val <= (comulativeperc + spells[i].perctrigger)) || !spells[i].casttime) { _unit->setAttackTimer(spells[i].attackstoptimer, false); m_spellcheck[i] = true; } comulativeperc += spells[i].perctrigger; } } } protected: int nrspells; }; /*****************************/ /* */ /* Boss AIs */ /* */ /*****************************/ // Zereketh the UnboundAI #define CN_ZEREKETH_THE_UNBOUND 20870 #define SEED_OF_CORRUPTION 36123 //32865, 36123 #define SHADOW_NOVA 36127 // 30533, 39005, 36127 (normal mode), 39005 (heroic mode?) #define VOID_ZONE 36119 // DBC: 36119; it's not fully functionl without additional core support (for dmg and random place targeting). class ZerekethTheUnboundAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(ZerekethTheUnboundAI); SP_AI_Spell spells[3]; bool m_spellcheck[3]; ZerekethTheUnboundAI(Creature* pCreature) : CreatureAIScript(pCreature) { nrspells = 3; for(int i=0;iGetUInt32Value(UNIT_FIELD_BASEATTACKTIME)); _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, "Life energy to... consume."); _unit->PlaySoundToSet(11250); } void CastTime() { for(int i=0;iGetAIInterface()->setCurrentAgent(AGENT_NULL); _unit->GetAIInterface()->SetAIState(STATE_IDLE); RemoveAIUpdateEvent(); } void OnTargetDied(Unit* mTarget) { if (_unit->GetHealthPct() > 0) // Hack to prevent double yelling (OnDied and OnTargetDied when creature is dying) { int RandomSpeach; sRand.randInt(1000); RandomSpeach=rand()%2; switch (RandomSpeach) { case 0: _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, "This vessel...is empty."); _unit->PlaySoundToSet(11251); break; case 1: _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, "No... more... life."); // not sure _unit->PlaySoundToSet(11252); break; } } } void OnDied(Unit * mKiller) { CastTime(); RemoveAIUpdateEvent(); _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, "The Void... beckons."); _unit->PlaySoundToSet(11255); } void AIUpdate() { int RandomSpeach; RandomSpeach=rand()%100; // 2% chance to say sth (no idea if this is right as names "TEMPEST_Zerek_ShadowHell01/02" tell me nothing =/ switch (RandomSpeach) { case 0: _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, "The shadow... will you."); // missing word! =( _unit->PlaySoundToSet(11253); break; case 1: _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, "Darkness... consumes all."); // verification needed _unit->PlaySoundToSet(11254); break; } float val = sRand.rand(100.0f); SpellCast(val); } void SpellCast(float val) { if(_unit->GetCurrentSpell() == NULL && _unit->GetAIInterface()->GetNextTarget()) { float comulativeperc = 0; Unit *target = NULL; for(int i=0;iGetAIInterface()->GetNextTarget(); switch(spells[i].targettype) { case TARGET_SELF: case TARGET_VARIOUS: _unit->CastSpell(_unit, spells[i].info, spells[i].instant); break; case TARGET_ATTACKING: _unit->CastSpell(target, spells[i].info, spells[i].instant); break; case TARGET_DESTINATION: _unit->CastSpellAoF(target->GetPositionX(),target->GetPositionY(),target->GetPositionZ(), spells[i].info, spells[i].instant); break; } if (spells[i].speech != "") { _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, spells[i].speech.c_str()); _unit->PlaySoundToSet(spells[i].soundid); } m_spellcheck[i] = false; return; } if ((val > comulativeperc && val <= (comulativeperc + spells[i].perctrigger)) || !spells[i].casttime) { _unit->setAttackTimer(spells[i].attackstoptimer, false); m_spellcheck[i] = true; } comulativeperc += spells[i].perctrigger; } } } protected: int nrspells; }; // Dalliah the DoomsayerAI #define CN_DALLIAH_THE_DOOMSAYER 20885 #define GIFT_OF_THE_DOOMSAYER 36173 // DBC: 36173 #define WHIRLWIND 36175 // DBC: 36142, 36175 #define HEAL 36144 #define SHADOW_WAVE 39016 // Heroic mode spell // sounds missing related to Wrath... (look on script below this one) class DalliahTheDoomsayerAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(DalliahTheDoomsayerAI); SP_AI_Spell spells[4]; bool m_spellcheck[4]; DalliahTheDoomsayerAI(Creature* pCreature) : CreatureAIScript(pCreature) { nrspells = 4; for(int i=0;iGetUInt32Value(UNIT_FIELD_BASEATTACKTIME)); _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, "It is unwise to anger me."); // verification needed _unit->PlaySoundToSet(11086); } void CastTime() { for(int i=0;iGetHealthPct() > 0) { int RandomSpeach; RandomSpeach=rand()%2; switch (RandomSpeach) { case 0: _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, "Completely ineffective! Just like someone else I know!"); // need verif. _unit->PlaySoundToSet(11087); break; case 1: _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, "You choosed the wrong opponenet!"); // verification needed _unit->PlaySoundToSet(11088); break; } } } void OnCombatStop(Unit *mTarget) { CastTime(); _unit->GetAIInterface()->setCurrentAgent(AGENT_NULL); _unit->GetAIInterface()->SetAIState(STATE_IDLE); RemoveAIUpdateEvent(); } void OnDied(Unit * mKiller) { CastTime(); RemoveAIUpdateEvent(); _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, "Now I'm really angry..."); // verification needed _unit->PlaySoundToSet(11093); } void AIUpdate() { float val = sRand.rand(100.0f); SpellCast(val); } void HealSound() { int RandomSpeach; RandomSpeach=rand()%20; switch (RandomSpeach) { case 0: _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, "That is much better."); _unit->PlaySoundToSet(11091); break; case 1: _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, "Ah, just what I needed."); // both need verif. _unit->PlaySoundToSet(11092); break; } } void WhirlwindSound() { int RandomWhirlwind; RandomWhirlwind=rand()%20; switch (RandomWhirlwind) { case 0: _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, "Rip the Whirlwind!"); _unit->PlaySoundToSet(11089); break; case 1: _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, "I'll cut you to pices!"); // all to verification _unit->PlaySoundToSet(11090); break; } } void SpellCast(float val) { if(_unit->GetCurrentSpell() == NULL && _unit->GetAIInterface()->GetNextTarget()) { float comulativeperc = 0; Unit *target = NULL; for(int i=0;iGetAIInterface()->GetNextTarget(); switch(spells[i].targettype) { case TARGET_SELF: case TARGET_VARIOUS: _unit->CastSpell(_unit, spells[i].info, spells[i].instant); break; case TARGET_ATTACKING: _unit->CastSpell(target, spells[i].info, spells[i].instant); break; case TARGET_DESTINATION: _unit->CastSpellAoF(target->GetPositionX(),target->GetPositionY(),target->GetPositionZ(), spells[i].info, spells[i].instant); break; } if (m_spellcheck[1] == true) { WhirlwindSound(); int NextAttack; NextAttack=rand()%100+1; if (NextAttack <= 25 && NextAttack > 0) { m_spellcheck[2] = true; } } if (spells[i].speech != "") { _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, spells[i].speech.c_str()); _unit->PlaySoundToSet(spells[i].soundid); } m_spellcheck[i] = false; return; } if ((val > comulativeperc && val <= (comulativeperc + spells[i].perctrigger)) || !spells[i].casttime) { _unit->setAttackTimer(spells[i].attackstoptimer, false); m_spellcheck[i] = true; } comulativeperc += spells[i].perctrigger; } } } protected: int nrspells; }; // Wrath-Scryer SoccothratesAI #define CN_WRATH_SCRYER_SOCCOTHRATES 20886 #define IMMOLATION 35959 // DBC: 36051, 35959 #define FELFIRE_SHOCK 35759 #define FELFIRE_LINE_UP 35770 // ? #define KNOCK_AWAY 20686 // DBC: 36512; but it uses it on himself too so changed to other #define CHARGE 35754 // DBC: 36058, 35754 =( =( // CHARGE_TARGETING 36038 ? // There are more sounds connected with Dalliah and some spells, but I don't know situation in which they are used // so haven't added them. class WrathScryerSoccothratesAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(WrathScryerSoccothratesAI); SP_AI_Spell spells[5]; bool m_spellcheck[5]; WrathScryerSoccothratesAI(Creature* pCreature) : CreatureAIScript(pCreature) { nrspells = 5; for(int i=0;iGetUInt32Value(UNIT_FIELD_BASEATTACKTIME)); _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, "At least target for my frustration!"); // verification needed _unit->PlaySoundToSet(11238); } void CastTime() { for(int i=0;iGetHealthPct() > 0) { int RandomSpeach; RandomSpeach=rand()%2; switch (RandomSpeach) { case 0: _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, "Yes, that was quiet... satisfied."); // need verif. _unit->PlaySoundToSet(11239); break; case 1: _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, "Ha! Much better!"); // verification needed _unit->PlaySoundToSet(11240); break; } } } void OnCombatStop(Unit *mTarget) { CastTime(); _unit->GetAIInterface()->setCurrentAgent(AGENT_NULL); _unit->GetAIInterface()->SetAIState(STATE_IDLE); RemoveAIUpdateEvent(); } void OnDied(Unit * mKiller) { CastTime(); RemoveAIUpdateEvent(); _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, ""); // verification needed _unit->PlaySoundToSet(11243); } void AIUpdate() { float val = sRand.rand(100.0f); SpellCast(val); } void SpellCast(float val) { if(_unit->GetCurrentSpell() == NULL && _unit->GetAIInterface()->GetNextTarget()) { float comulativeperc = 0; Unit *target = NULL; for(int i=0;iGetAIInterface()->GetNextTarget(); switch(spells[i].targettype) { case TARGET_SELF: case TARGET_VARIOUS: _unit->CastSpell(_unit, spells[i].info, spells[i].instant); break; case TARGET_ATTACKING: _unit->CastSpell(target, spells[i].info, spells[i].instant); break; case TARGET_DESTINATION: _unit->CastSpellAoF(target->GetPositionX(),target->GetPositionY(),target->GetPositionZ(), spells[i].info, spells[i].instant); break; } if (spells[i].speech != "") { _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, spells[i].speech.c_str()); _unit->PlaySoundToSet(spells[i].soundid); } m_spellcheck[i] = false; return; } if ((val > comulativeperc && val <= (comulativeperc + spells[i].perctrigger)) || !spells[i].casttime) { _unit->setAttackTimer(spells[i].attackstoptimer, false); m_spellcheck[i] = true; } comulativeperc += spells[i].perctrigger; } } } protected: int nrspells; }; // Harbinger SkyrissAI #define CN_HARBRINGER_SKYRISS 20912 #define MIND_REND 36924 // DBC: 36859, 36924; #define FEAR 39415 #define DOMINATION 37162 #define SUMMON_ILLUSION_66 36931 // those 2 don't work #define SUMMON_ILLUSION_33 36932 // BLINK_VISUAL 36937 ? // SIMPLE_TELEPORT 12980 ? // Add sounds related to his dialog with mind controlled guy class HarbringerSkyrissAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(HarbringerSkyrissAI); SP_AI_Spell spells[5]; bool m_spellcheck[5]; HarbringerSkyrissAI(Creature* pCreature) : CreatureAIScript(pCreature) { IllusionCount = 0; nrspells = 5; for(int i=0;iGetUInt32Value(UNIT_FIELD_BASEATTACKTIME)); _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, "Bear witness to the agent of your demise!"); // used when he kills Warden Mellichar _unit->PlaySoundToSet(11123); } void CastTime() { for(int i=0;iGetHealthPct() > 0) { int RandomSpeach; RandomSpeach=rand()%2; switch (RandomSpeach) { case 0: _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, "Your fate is written!"); // this one needs verification _unit->PlaySoundToSet(11124); break; case 1: _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, "The chaos I have sown here is but a taste...."); _unit->PlaySoundToSet(11125); break; } } } void OnCombatStop(Unit *mTarget) { IllusionCount = 0; CastTime(); _unit->GetAIInterface()->setCurrentAgent(AGENT_NULL); _unit->GetAIInterface()->SetAIState(STATE_IDLE); RemoveAIUpdateEvent(); } void OnDied(Unit * mKiller) { IllusionCount = 0; CastTime(); RemoveAIUpdateEvent(); _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, "I am merely one of... infinite multitudes."); _unit->PlaySoundToSet(11126); } void AIUpdate() { if (_unit->GetHealthPct() <= 66 && !IllusionCount) { IllusionCount = 1; _unit->CastSpell(_unit, spells[3].info, spells[3].instant); //_unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, "We span the universe, as countless as the stars!"); _unit->PlaySoundToSet(11131); // Idk if those texts shouldn't be told by clones and by org. so disabled MSG to make it harder to detect =P } if (_unit->GetHealthPct() <= 33 && IllusionCount == 1) { IllusionCount = 2; _unit->CastSpell(_unit, spells[4].info, spells[4].instant); //_unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, "We span the universe, as countless as the stars!"); _unit->PlaySoundToSet(11131); } else { float val = sRand.rand(100.0f); SpellCast(val); } } void FearSound() { int RandomFear; RandomFear=rand()%4; switch (RandomFear) { case 0: _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, "Flee in terror."); _unit->PlaySoundToSet(11129); break; case 1: _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, "I will show you horrors undreamed of."); _unit->PlaySoundToSet(11130); break; } } void DominationSound() { int RandomDomination; RandomDomination=rand()%4; switch (RandomDomination) { case 0: _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, "You will do my bidding, weakling."); _unit->PlaySoundToSet(11127); break; case 1: _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, "Your will is no longer your own."); _unit->PlaySoundToSet(11128); break; } } void SpellCast(float val) { if(_unit->GetCurrentSpell() == NULL && _unit->GetAIInterface()->GetNextTarget()) { float comulativeperc = 0; Unit *target = NULL; for(int i=0;iGetAIInterface()->GetNextTarget(); switch(spells[i].targettype) { case TARGET_SELF: case TARGET_VARIOUS: _unit->CastSpell(_unit, spells[i].info, spells[i].instant); break; case TARGET_ATTACKING: _unit->CastSpell(target, spells[i].info, spells[i].instant); break; case TARGET_DESTINATION: _unit->CastSpellAoF(target->GetPositionX(),target->GetPositionY(),target->GetPositionZ(), spells[i].info, spells[i].instant); break; } if (spells[i].speech != "") { _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, spells[i].speech.c_str()); _unit->PlaySoundToSet(spells[i].soundid); } if (m_spellcheck[1] == true) { FearSound(); } if (m_spellcheck[2] == true) { DominationSound(); } m_spellcheck[i] = false; return; } if ((val > comulativeperc && val <= (comulativeperc + spells[i].perctrigger)) || !spells[i].casttime) { _unit->setAttackTimer(spells[i].attackstoptimer, false); m_spellcheck[i] = true; } comulativeperc += spells[i].perctrigger; } } } protected: uint32 IllusionCount; int nrspells; }; /* // Warden MellicharAI // he is EVENT STARTER and needs some more time I don't have atm =( #define CN_WARDEN_MELLICHAR 20904 #define class WardenMellicharAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(WardenMellicharAI); SP_AI_Spell spells[1]; bool m_spellcheck[1]; WardenMellicharAI(Creature* pCreature) : CreatureAIScript(pCreature) { nrspells = 1; for(int i=0;iGetUInt32Value(UNIT_FIELD_BASEATTACKTIME)); _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, ""); _unit->PlaySoundToSet(); } void CastTime() { for(int i=0;iSendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, ""); _unit->PlaySoundToSet(); break; case 1: _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, ""); _unit->PlaySoundToSet(); break; } } } void OnCombatStop(Unit *mTarget) { CastTime(); _unit->GetAIInterface()->setCurrentAgent(AGENT_NULL); _unit->GetAIInterface()->SetAIState(STATE_IDLE); RemoveAIUpdateEvent(); } void OnDied(Unit * mKiller) { CastTime(); RemoveAIUpdateEvent(); _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, ""); _unit->PlaySoundToSet(); } void AIUpdate() { float val = sRand.rand(100.0f); SpellCast(val); } void SpellCast(float val) { if(_unit->GetCurrentSpell() == NULL && _unit->GetAIInterface()->GetNextTarget()) { float comulativeperc = 0; Unit *target = NULL; for(int i=0;iGetAIInterface()->GetNextTarget(); switch(spells[i].targettype) { case TARGET_SELF: case TARGET_VARIOUS: _unit->CastSpell(_unit, spells[i].info, spells[i].instant); break; case TARGET_ATTACKING: _unit->CastSpell(target, spells[i].info, spells[i].instant); break; case TARGET_DESTINATION: _unit->CastSpellAoF(target->GetPositionX(),target->GetPositionY(),target->GetPositionZ(), spells[i].info, spells[i].instant); break; } if (spells[i].speech != "") { _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, spells[i].speech.c_str()); _unit->PlaySoundToSet(spells[i].soundid); } m_spellcheck[i] = false; return; } if ((val > comulativeperc && val <= (comulativeperc + spells[i].perctrigger)) || !spells[i].casttime) { _unit->setAttackTimer(spells[i].attackstoptimer, false); m_spellcheck[i] = true; } comulativeperc += spells[i].perctrigger; } } } protected: int nrspells; }; */ void SetupArcatraz(ScriptMgr * mgr) { mgr->register_creature_script(CN_ARCATRAZ_DEFENDER, &ArcatrazDefenderAI::Create); mgr->register_creature_script(CN_ARCATRAZ_SENTINEL, &ArcatrazSentinelAI::Create); mgr->register_creature_script(CN_ARCATRAZ_WARDER, &ArcatrazWarderAI::Create); mgr->register_creature_script(CN_BLACKWING_DRAKONAAR, &BlackwingDrakonaarAI::Create); mgr->register_creature_script(CN_BLACKWING_TRICKSTER, &BlackwingTricksterAI::Create); mgr->register_creature_script(CN_DEATH_WATCHER, &DeathWatcherAI::Create); mgr->register_creature_script(CN_DEFENDER_CORPSE, &DefenderCorpseAI::Create); mgr->register_creature_script(CN_PROTEAN_SPAWN, &ProteanSpawnAI::Create); mgr->register_creature_script(CN_ENTROPIC_EYE, &EntropicEyeAI::Create); mgr->register_creature_script(CN_EREDAR_DEATHBRINGER, &EredarDeathbringerAI::Create); mgr->register_creature_script(CN_EREDAR_SOUL_EATER, &EredarSoulEaterAI::Create); mgr->register_creature_script(CN_ETHEREUM_LIFE_BINDER, &EthereumLifeBinderAI::Create); mgr->register_creature_script(CN_ETHEREUM_SLAYER, &EthereumSlayerAI::Create); mgr->register_creature_script(CN_ETHEREUM_WAVE_CASTER, &EthereumWaveCasterAI::Create); mgr->register_creature_script(CN_GARGANTUAN_ABYSSAL, &GargantuanAbyssalAI::Create); mgr->register_creature_script(CN_GREATER_FIRE_ELEMENTAL, &GreaterFireElementalAI::Create); mgr->register_creature_script(CN_IRONJAW, &IronjawAI::Create); mgr->register_creature_script(CN_MILLHOUSE_MANASTORM, &MillhouseManastormAI::Create); mgr->register_creature_script(CN_NEGATON_SCREAMER, &NegatonScreamerAI::Create); mgr->register_creature_script(CN_NEGATON_WARP_MASTER, &NegatonWarpMasterAI::Create); mgr->register_creature_script(CN_NEGATON_FIELD, &NegatonFieldAI::Create); mgr->register_creature_script(CN_PHASE_HUNTER, &PhaseHunterAI::Create); mgr->register_creature_script(CN_PROTEAN_HORROR, &ProteanHorrorAI::Create); mgr->register_creature_script(CN_PROTEAN_NIGHTMARE, &ProteanNightmareAI::Create); mgr->register_creature_script(CN_SULFURON_MAGMA_THROWER, &SulfuronMagmaThrowerAI::Create); mgr->register_creature_script(CN_SPITEFUL_TEMPTRESS, &SpitefulTemptressAI::Create); mgr->register_creature_script(CN_SOUL_DEVOURER, &SoulDevourerAI::Create); mgr->register_creature_script(CN_SOLOMON, &SolomonAI::Create); mgr->register_creature_script(CN_SKULKING_WITCH, &SkulkingWitchAI::Create); mgr->register_creature_script(CN_SIGHTLESS_EYE, &SightlessEyeAI::Create); mgr->register_creature_script(CN_SARGERON_HELLCALLER, &SargeronHellcallerAI::Create); mgr->register_creature_script(CN_UNBOUND_DEVASTATOR, &UnboundDevastatorAI::Create); mgr->register_creature_script(CN_UNCHAINED_DOOMBRINGER, &UnchainedDoombringerAI::Create); mgr->register_creature_script(CN_WARDER_CORPSE, &WarderCorpseAI::Create); mgr->register_creature_script(CN_SARGERON_ARCHER, &SargeronArcherAI::Create); mgr->register_creature_script(CN_ZEREKETH_THE_UNBOUND, &ZerekethTheUnboundAI::Create); mgr->register_creature_script(CN_DALLIAH_THE_DOOMSAYER, &DalliahTheDoomsayerAI::Create); mgr->register_creature_script(CN_WRATH_SCRYER_SOCCOTHRATES, &WrathScryerSoccothratesAI::Create); mgr->register_creature_script(CN_HARBRINGER_SKYRISS, &HarbringerSkyrissAI::Create); //mgr->register_creature_script(CN_WARDEN_MELLICHAR, &WardenMellicharAI::Create); } // Note: Don't have infos about: Akkiris Lightning-Waker, Nathan, Third Fragment Guardian, Udalo, Whisper and // Twilight Drakonaar; some of those mobs aren't aggresive. //