#include "StdAfx.h" #include "Setup.h" /************************************************************************/ /* Instance_TheUnderbog.cpp Script */ /************************************************************************/ // Bog Giant AI #define CN_BOG_GIANT 17723 #define FUNGAL_DECAY_GIANT 32065 #define TRAMPLE 15550 // not sure to those spells #define ENRAGE_GIANT 8599 class BOGGIANTAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(BOGGIANTAI); SP_AI_Spell spells[3]; bool m_spellcheck[3]; BOGGIANTAI(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; }; // Claw AI #define CN_CLAW 17827 #define ENRAGE_CLAW 34971 #define ECHOING_ROAR 31429 #define MAUL 34298 //DAZED? class CLAWAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(CLAWAI); SP_AI_Spell spells[3]; bool m_spellcheck[3]; CLAWAI(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; }; // Underbat AI #define CN_UNDERBAT 17724 #define KNOCKDOWN 20276 // can't find correct aoe knockdown for now =/ does it use it for sure? #define TENTACLE_LASH 34171 // not sure to this //DAZED class UNDERBATAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(UNDERBATAI); SP_AI_Spell spells[2]; bool m_spellcheck[2]; UNDERBATAI(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; }; // Fen Ray AI #define CN_FEN_RAY 17731 #define PSYCHIC_HORROR 34984 //DAZED class FENRAYAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(FENRAYAI); SP_AI_Spell spells[1]; bool m_spellcheck[1]; FENRAYAI(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; }; /* Lykul Stinger/Wasp - Bee-type mobs which inflict a poison which deals minor nature damage. However, targets which are inflicted with poison from both a Wasp and Stinger take sharply increased damage. Cannot be polymorphed, but can be frost nova'd. Can both be trapped by hunters, and Wasps should be killed first in a mixed mob group due to their relative weakness and poisons. The poison can be interrupted or spellreflected. */ // Lykul Stinger AI #define CN_LYKUL_STINGER 19632 #define POISON 36694 // Maybe be: 36694 (armor - 5000 :O), 13526, 3396 (both very old spells), 24111 #define STINGER_FRENZY 34392 // not sure // From description this poison is Corrosive Poison, but Idk for sure class LYKULSTINGERAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(LYKULSTINGERAI); SP_AI_Spell spells[2]; bool m_spellcheck[2]; LYKULSTINGERAI(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; }; // Lykul Wasp AI #define CN_LYKUL_WASP 17732 #define POISON 36694 // Maybe be: 36694 (armor - 5000 :O), 13526, 3396 (both very old spells), 24111 #define POISON_SPIT 32330 #define ENRAGE_WASP 8599 // From description this poison is Corrosive Poison, but Idk for sure class LYKULWASPAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(LYKULWASPAI); SP_AI_Spell spells[3]; bool m_spellcheck[3]; LYKULWASPAI(Creature* pCreature) : CreatureAIScript(pCreature) { nrspells = 3; for(int i=0;iGetUInt32Value(UNIT_FIELD_BASEATTACKTIME)); _unit->CastSpell(_unit, spells[2].info, spells[2].instant); } 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; }; // Wrathfin Warrior AI #define CN_WRATHFIN_WARRIOR 17735 #define REND 36991 // It is only bleed like spell I remember well (if it isn't bleed, but other spell // report it then. Can be: 36991, 37662, 29574, 29578, 36965 (big dmg) // not sure if it's even casted =( // Also can be Carnivorous Bite, but no idea :P #define STRIKE 11976 #define SHIELD_BASH 11972 // ofc not sure to those #define ENRAGE_WARTHFIN_WARRIOR 8599 //DAZED class WRATHFINWARRIORAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(WRATHFINWARRIORAI); SP_AI_Spell spells[4]; bool m_spellcheck[4]; WRATHFINWARRIORAI(Creature* pCreature) : CreatureAIScript(pCreature) { nrspells = 4; for(int i=0;iGetUInt32Value(UNIT_FIELD_BASEATTACKTIME)); _unit->CastSpell(_unit, spells[3].info, spells[3].instant); } 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; }; // Wrathfin Sentry AI #define CN_WRATHFIN_SENTRY 17727 #define STRIKE_WRATHFIN_SENTRY 11976 #define SHIELD_BASH_WRATHFIN_SENTRY 11972 //Invisibility and Stealth Detection 18950 ? class WRATHFINSENTRYAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(WRATHFINSENTRYAI); SP_AI_Spell spells[2]; bool m_spellcheck[2]; WRATHFINSENTRYAI(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; }; // Wrathfin Myrmidon AI #define CN_WRATHFIN_MYRMIDON 17726 #define CORAL_CUT 31410 //DAZED class WRATHFINMYRMIDONAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(WRATHFINMYRMIDONAI); SP_AI_Spell spells[1]; bool m_spellcheck[1]; WRATHFINMYRMIDONAI(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; }; // Underbog Lord AI #define CN_UNDERBOG_LORD 17734 /*#define KNOCKBACK 28405 // this is wrong id for sure. On Wiki there was sth about kickback, but there is no such spell in DBC -.-' // or maybe it's Boglord Bash: 32077 ?*/ #define ENRAGE_LORD 8599 //33653 // This spell was added, but still I don't have infos abou it :| // Can be: 37023, 33653 and others... #define KNOCK_AWAY 25778 // not sure to those #define FUNGAL_DECAY 32065 //DAZED class UNDERBOGLORDAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(UNDERBOGLORDAI); SP_AI_Spell spells[3]; bool m_spellcheck[3]; UNDERBOGLORDAI(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; }; /* Murkblood Lost Ones - Humanoid mobs Spearmen (flings spears and cast Viper Sting), Tribesmen, Oracles (casts Fireball) and Healers (casts Holy Light, Heal and Prayer of Healing}. Come in groups together. Healers will cast Prayer of Healing if left alone which will completely heal all nearby Murkbloods and Wrathfins and so should be killed first or crowd-controlled until last. The heal is interruptible. */ // Murkblood Spearman AI #define CN_MURKBLOOD_SPEARMAN 17729 //#define SPEAR_THROW 31758 // not sure if that spell is casted (maybe other, but similar), also can be: 31758, 40083, 32248 #define THROW 22887 #define VIPER_STRING 31407 class MURKBLOODSPEARMANAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(MURKBLOODSPEARMANAI); SP_AI_Spell spells[2]; bool m_spellcheck[2]; MURKBLOODSPEARMANAI(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; }; // Murkblood Oracle AI #define CN_MURKBLOOD_ORACLE 17771 #define FIREBALL 14034 //32369 // can be: 32369, 37329, 32363, 31262, 40877, 38641, 37111 #define SHADOW_BOLT_ORACLE 12471 #define CORRUPTION 31405 #define SCORCH 15241 #define AMPLIFY_DAMAGE 12248 #define FROSTBOLT 15497 #define ELEMENTAL_ARMOR 34880 class MURKBLOODORACLEAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(MURKBLOODORACLEAI); SP_AI_Spell spells[7]; bool m_spellcheck[7]; MURKBLOODORACLEAI(Creature* pCreature) : CreatureAIScript(pCreature) { nrspells = 7; for(int i=0;iGetUInt32Value(UNIT_FIELD_BASEATTACKTIME)); _unit->CastSpell(_unit, spells[6].info, spells[6].instant); } 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; }; // Murkblood Healer AI #define CN_MURKBLOOD_HEALER 17730 //#define HEAL 32130 // also can be: 32130, 31730, 34945, 38209, 39378, 31739 NOT CASTED!? #define HOLY_LIGHT 29427 //32769 // can be: 37979, 32769, 31713 #define RENEW 34423 #define PRAYER_OF_HEALING 15585 //30604 // can be: 35943, 30604 causes crashes =/ class MURKBLOODHEALERAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(MURKBLOODHEALERAI); SP_AI_Spell spells[3]; bool m_spellcheck[3]; MURKBLOODHEALERAI(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; }; // Murkblood Tribesman AI #define CN_MURKBLOOD_TRIBESMAN 17728 #define STRIKE_TRIBESMAN 12057 #define ENRAGE_TRIBESMAN 8599 //DAZED? class MURKBLOODTRIBESMANAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(MURKBLOODTRIBESMANAI); SP_AI_Spell spells[2]; bool m_spellcheck[2]; MURKBLOODTRIBESMANAI(Creature* pCreature) : CreatureAIScript(pCreature) { nrspells = 2; for(int i=0;iGetUInt32Value(UNIT_FIELD_BASEATTACKTIME)); _unit->CastSpell(_unit, spells[1].info, spells[1].instant); } 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; }; /* Underbog Shambler/Frenzy - Nature elementals which can afflict their target with a disease which inflicts nature damage the next 5 times that target takes damage. Also a Frenzy variety which enrage and deal increased damage. Can be banished and trapped. Shamblers heal themselves and others. */ // Underbog Shambler AI #define CN_UNDERBOG_SHAMBLER 17871 //#define HEAL 32130 // 38209 | no idea if he is using heal (using healing spell yes (nearly sure), but if heal Idk) //#define SPORE_EXPLOSION 37966 //38419 //32327 #define ITCHY_SPORES 32329 #define ALLERGIES 31427 #define FUNGAL_REGROWTH 34163 //DAZED class UNDERBOGSHAMBLERAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(UNDERBOGSHAMBLERAI); SP_AI_Spell spells[3]; bool m_spellcheck[3]; UNDERBOGSHAMBLERAI(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; }; // Underbog Frenzy AI #define CN_UNDERBOG_FRENZY 20465 #define ENRAGE_FRENZY 34971 // no idea if this is good spell id / still don't know if it's good // Invisibility and Stealth Detection 18950 ? // Permanent Feign Death (Root) 31261 ? class UNDERBOGFRENZYAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(UNDERBOGFRENZYAI); SP_AI_Spell spells[1]; bool m_spellcheck[1]; UNDERBOGFRENZYAI(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; }; // Underbog Lurker AI #define CN_UNDERBOG_LURKER 17725 #define WILD_GROWTH 34161 //DAZED? class UNDERBOGLURKERAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(UNDERBOGLURKERAI); SP_AI_Spell spells[1]; bool m_spellcheck[1]; UNDERBOGLURKERAI(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; }; /*****************************/ /* */ /* Boss AIs */ /* */ /*****************************/ // HungarfenAI #define CN_HUNGARFEN 17770 #define UNDERBOG_MUSHROOM 31693 // still not idea *confused* //34588 // No idea if this is right spell, but should be correct (also aditional core support needed!) #define FOUL_SPORES 31673 //DBC: 31673, 31697 // this one needs additional core support too // Putrid Mushroom Primer 31693 ? // Despawn Underbog Mushrooms 34874 ? class HUNGARFENAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(HUNGARFENAI); SP_AI_Spell spells[2]; bool m_spellcheck[2]; HUNGARFENAI(Creature* pCreature) : CreatureAIScript(pCreature) { FOUL_SPORES_LIMITER = 0; 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) { FOUL_SPORES_LIMITER = 0;; CastTime(); RemoveAIUpdateEvent(); } void AIUpdate() { if(_unit->GetHealthPct() <= 20 && !FOUL_SPORES_LIMITER) { _unit->CastSpell(_unit, spells[1].info, spells[1].instant); FOUL_SPORES_LIMITER = 1; } else { float val = sRand.rand(100.f); 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 FOUL_SPORES_LIMITER; int nrspells; }; // Ghaz'anAI #define CN_GHAZAN 18105 #define ACID_SPIT 34290 #define TAIL_SWEEP 34267 #define ACID_BREATH 34268 //24839 //34268 <-- not sure #define ENRAGE 15716 // Not sure to id as always in Enrage case: 34409, 34970 //#define TRASH 3391 //DAZED? class GHAZANAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(GHAZANAI); SP_AI_Spell spells[4]; bool m_spellcheck[4]; GHAZANAI(Creature* pCreature) : CreatureAIScript(pCreature) { ENRAGE_LIMITER = 0; 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(); ENRAGE_LIMITER = 0; } void AIUpdate() { if(_unit->GetHealthPct() <= 20 && ENRAGE_LIMITER == 0) { ENRAGE_LIMITER = 1; // Added to prevent situation when health jumps from 21 to 19 % and enrage is never activated _unit->CastSpell(_unit, spells[3].info, spells[3].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: int ENRAGE_LIMITER; int nrspells; }; // Swamplord Musel'ekAI // Needs additional core support and more work =/ #define CN_SWAMPLORD_MUSELEK 17826 //#define AUTO_SHOT //#define FREEZING_TRAP 41086 // <-- Ice trap/ couldn't find better spell for now (we can use: 31933, but it has to affect players on xx radius) #define MULTI_SHOT 34974 //34879 // 38383, 38383, #define AIMED_SHOT 31623 //38370 #define THROW_FREEZING_TRAP 31946 // needs more core support #define ECHOING_ROAR 31429 // Special Claw Attk, need to find better id if needed // is this used for sure? #define RAPTOR_STRIKE 31566 #define HUNTERS_MARK 31615 #define KNOCK_AWAY_MUSELEK 18813 #define DETERRENCE 31567 #define SHOT 22907 // No idea for now how to force him to keep the distance and use his abilities // (Multi, Aimed should be used only when he is quiet far from party) // BEAR_COMMAND 34662 ? // NOTIFY_OF_DEATH 31547 ? class SWAMPLORDMUSELEKAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(SWAMPLORDMUSELEKAI); SP_AI_Spell spells[9]; bool m_spellcheck[9]; SWAMPLORDMUSELEKAI(Creature* pCreature) : CreatureAIScript(pCreature) { nrspells = 9; for(int i=0;iSendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, "We fight to the death!"); _unit->PlaySoundToSet(10384); break; case 1: _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, "I will end this quickly!"); _unit->PlaySoundToSet(10385); break; case 2: _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, "!"); _unit->PlaySoundToSet(10386); break; } RegisterAIUpdateEvent(_unit->GetUInt32Value(UNIT_FIELD_BASEATTACKTIME)); } void CastTime() { for(int i=0;iGetHealthPct() > 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, "!"); _unit->PlaySoundToSet(10387); break; case 1: _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, "It is finished!"); _unit->PlaySoundToSet(10388); break; } } } void OnCombatStop(Unit *mTarget) { //SHOTTimer = 0; CastTime(); _unit->GetAIInterface()->setCurrentAgent(AGENT_NULL); _unit->GetAIInterface()->SetAIState(STATE_IDLE); RemoveAIUpdateEvent(); } void OnDied(Unit * mKiller) { //SHOTTimer = 0; CastTime(); _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, "Well... done..."); // not sure _unit->PlaySoundToSet(10389); RemoveAIUpdateEvent(); } void AIUpdate() { if (/*_unit->GetCurrentSpell() == NULL &&*/ _unit->GetAIInterface()->GetNextTarget()) { //SHOTTimer++; Unit *target = NULL; target = _unit->GetAIInterface()->GetNextTarget(); if (_unit->GetDistance2dSq(target) >= 100.0f /*225.0f*/ && _unit->GetDistanceSq(target) <= 900.0f && ShotCount/*SHOTTimer < 12*/) { ShotCount--; _unit->GetAIInterface()->m_canMove = false; int RangedSpell; sRand.randInt(1000); RangedSpell=rand()%100; if (RangedSpell >= 0 && RangedSpell <= 20) { _unit->CastSpell(target, spells[0].info, spells[0].instant); _unit->setAttackTimer(spells[0].attackstoptimer, false); } if (RangedSpell > 20 && RangedSpell <= 40) { _unit->CastSpell(target, spells[1].info, spells[1].instant); _unit->setAttackTimer(spells[1].attackstoptimer, false); } else { _unit->CastSpell(target, spells[8].info, spells[8].instant); _unit->setAttackTimer(spells[8].attackstoptimer, false); } } else { ShotCount=rand()%2+1; _unit->GetAIInterface()->m_canMove = true; if (_unit->GetDistance2dSq(target) < 100.0f /*225.0f*/) { float val = sRand.rand(100.0f); SpellCast(val); } } /*if (SHOTTimer == 32) SHOTTimer = 0;*/ } else return; } /* void AIUpdate() { sRand.randInt(1000); if (_unit->GetAIInterface()->GetNextTarget()) { Unit *target = NULL; target = _unit->GetAIInterface()->GetNextTarget(); if (_unit->GetDistanceSq(target) >= 10.0f && _unit->GetDistanceSq(target) <= 40.0f) { //_unit->GetAIInterface()->m_canMove = false; int RangedSpell; RangedSpell=rand()%100; if (RangedSpell >= 0 && RangedSpell <= 15) { _unit->CastSpell(target, spells[0].info, spells[0].instant); //_unit->setAttackTimer(spells[0].attackstoptimer, false); } if (RangedSpell > 15 && RangedSpell <= 25) { _unit->CastSpell(target, spells[1].info, spells[1].instant); //_unit->setAttackTimer(spells[1].attackstoptimer, false); } else { _unit->CastSpell(target, spells[8].info, spells[8].instant); //_unit->setAttackTimer(spells[8].attackstoptimer, false); } } if (_unit->GetDistanceSq(target) < 10.0f) { //_unit->GetAIInterface()->m_canMove = true; float val = sRand.rand(100.0f); SpellCast(val); } else return; } } */ 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 SHOTTimer; int ShotCount; int nrspells; }; // The Black StalkerAI #define CN_THE_BLACK_STALKER 17882 #define CHAIN_LIGHTNING 31717 //39066 // 28167, 39066 #define LEVITATE 31704 // Not sure to id #define STATIC_CHARGE 31715 #define SUMMON_SPORE_STRIDER 38755 // spawning adds only on Heroic! lack of core support =/ class THEBLACKSTALKERAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(THEBLACKSTALKERAI); SP_AI_Spell spells[4]; bool m_spellcheck[4]; THEBLACKSTALKERAI(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; }; void SetupTheUnderbog(ScriptMgr * mgr) { mgr->register_creature_script(CN_BOG_GIANT, &BOGGIANTAI::Create); mgr->register_creature_script(CN_CLAW, &CLAWAI::Create); mgr->register_creature_script(CN_FEN_RAY, &FENRAYAI::Create); mgr->register_creature_script(CN_LYKUL_STINGER, &LYKULSTINGERAI::Create); mgr->register_creature_script(CN_UNDERBAT, &UNDERBATAI::Create); mgr->register_creature_script(CN_FEN_RAY, &FENRAYAI::Create); mgr->register_creature_script(CN_LYKUL_STINGER, &LYKULSTINGERAI::Create); mgr->register_creature_script(CN_LYKUL_WASP, &LYKULWASPAI::Create); mgr->register_creature_script(CN_WRATHFIN_WARRIOR, &WRATHFINWARRIORAI::Create); mgr->register_creature_script(CN_WRATHFIN_MYRMIDON, &WRATHFINMYRMIDONAI::Create); mgr->register_creature_script(CN_WRATHFIN_SENTRY, &WRATHFINSENTRYAI::Create); mgr->register_creature_script(CN_MURKBLOOD_SPEARMAN, &MURKBLOODSPEARMANAI::Create); mgr->register_creature_script(CN_MURKBLOOD_ORACLE, &MURKBLOODORACLEAI::Create); mgr->register_creature_script(CN_MURKBLOOD_HEALER, &MURKBLOODHEALERAI::Create); mgr->register_creature_script(CN_MURKBLOOD_TRIBESMAN, &MURKBLOODTRIBESMANAI::Create); mgr->register_creature_script(CN_UNDERBOG_SHAMBLER, &UNDERBOGSHAMBLERAI::Create); mgr->register_creature_script(CN_UNDERBOG_FRENZY, &UNDERBOGFRENZYAI::Create); mgr->register_creature_script(CN_UNDERBOG_LORD, &UNDERBOGLORDAI::Create); mgr->register_creature_script(CN_UNDERBOG_LURKER, &UNDERBOGLURKERAI::Create); mgr->register_creature_script(CN_HUNGARFEN, &HUNGARFENAI::Create); mgr->register_creature_script(CN_GHAZAN, &GHAZANAI::Create); mgr->register_creature_script(CN_SWAMPLORD_MUSELEK, &SWAMPLORDMUSELEKAI::Create); mgr->register_creature_script(CN_THE_BLACK_STALKER, &THEBLACKSTALKERAI::Create); } // Notes: Wasp/Stinger must be checked. Please check it (because for sure // many spells/creatures with spells are missing and also you will find some dupes. // No spells found for: Windcaller Claw, Spore Spider, Earthbinder Rayge // Left Underbog Mushroom.