#include "StdAfx.h" #include "Setup.h" /************************************************************************/ /* Instance_TheSteamvault.cpp Script */ /************************************************************************/ // Coilfang Engineer AI #define CN_COILFANG_ENGINEER 17721 #define BOMB 22334 //40332 // AOE #define NET 6533 //38338 // Should stay for 5 or 8 sec? // DAZED? class COILFANGENGINEERAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(COILFANGENGINEERAI); SP_AI_Spell spells[2]; bool m_spellcheck[2]; COILFANGENGINEERAI(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; }; // Coilfang Oracle AI #define CN_COILFANG_ORACLE 17803 #define FROST_SHOCK 22582 //34353 #define SONIC_BURST 8281 //39052 // Should make dmg? or maybe it shouldn't be added here? #define HEAL 31730 //39378 // Hmm... no idea if this is correct id (and how much should heal) // Also it should heal other naga like etc. // DAZED? class COILFANGORACLEAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(COILFANGORACLEAI); SP_AI_Spell spells[3]; bool m_spellcheck[3]; COILFANGORACLEAI(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; }; // Coilfang Warrior AI #define CN_COILFANG_WARRIOR 17802 // at least, couldn't find any data to compare it with blizz //#define MORTAL_STRIKE 29572 // should it really be here? #define MORTAL_BLOW 35105 #define BATTLE_SHOUT 31403 // Defensive Stance 7164 ? // DAZED? class COILFANGWARRIORAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(COILFANGWARRIORAI); SP_AI_Spell spells[2]; bool m_spellcheck[2]; COILFANGWARRIORAI(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; }; // Coilfang Siren AI #define CN_COILFANG_SIREN 17801 //#define MOONFIRE 20690 // not sure to id // not used ? #define AOE_FEAR 29321 //30584 // Maybe should be: 33547 or 29321 #define LIGHTNING_BOLT 15234 //36152 // 1 target #define ARCANE_FLARE 35106 // DAZED? class COILFANGSIRENAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(COILFANGSIRENAI); SP_AI_Spell spells[3]; bool m_spellcheck[3]; COILFANGSIRENAI(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; }; // Bog OverlordAI #define CN_BOG_OVERLORD 21694 #define FUNGAL_DECAY 32065 #define TRAMPLE 15550 //40340 // Should be used when enraged #define ENRAGE_BOG_OVERLORD 8599 //40683 // No idea if this is good spell id (used ENRAGE_B [B = Bog], because of redefining) #define DISEASE_CLOUD 37266 //DBC: 37266, 37267 || Heroic: 37863, 37864 ? // Should be immunite on CC's and slowing down effects. // Also should detect players in stealth mode. (Invisibility and Stealth Detection 18950 ?) class BOGOVERLORDAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(BOGOVERLORDAI); SP_AI_Spell spells[4]; bool m_spellcheck[4]; BOGOVERLORDAI(Creature* pCreature) : CreatureAIScript(pCreature) { nrspells = 4; for(int i=0;iCastSpell(_unit, spells[3].info, spells[3].instant); // ...and this } 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; }; // Coilfang Sorceress #define CN_COILFANG_SORCERESS 17722 #define FROSTBOLT 12675 //39064 #define BLIZZARD 39416 //38646 // or maybe: 37263 #define FROST_NOVA 15063 //29849 // also can be: 30094 or 32365 class COILFANGSORCERESSAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(COILFANGSORCERESSAI); SP_AI_Spell spells[3]; bool m_spellcheck[3]; COILFANGSORCERESSAI(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; }; // Coilfang Leper #define CN_COILFANG_LEPER 21338 // Couldn't find source to compare it's spells #define SHADOW_BOLT 9613 //39025 #define FIRE_BLAST_LEPER 13339 // not sure to those #define STRIKE 13446 #define FROST_NOVA_LEPER 11831 #define CLEAVE_LEPER 5532 // THOSE SPELLS MUST BE VERIFIED! #define HEAL_LEPER 11642 #define SUNDER_ARMOR_LEPER 13444 #define SHOOT 15547 //DAZED class COILFANGLEPERAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(COILFANGLEPERAI); SP_AI_Spell spells[8]; bool m_spellcheck[8]; COILFANGLEPERAI(Creature* pCreature) : CreatureAIScript(pCreature) { nrspells = 8; 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; }; // Coilfang Slavemaster #define CN_COILFANG_SLAVEMASTER 17805 #define GEYSER 10987 //40089 // It don't have to be good spell id [can be: 10987, 37478, 40089, 37427] - no idea why it doesn't knock you out #define ENRAGE_SlAVEMASTER 8269 // Slaves should run after killing slavemaster class COILFANGSLAVEMASTERAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(COILFANGSLAVEMASTERAI); SP_AI_Spell spells[2]; bool m_spellcheck[2]; COILFANGSLAVEMASTERAI(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; }; // Coilfang water elemental #define CN_COILFANG_WATER_ELEMENTAL 17917 //#define FROSTBOLT_VOLLEY 36741 #define WATER_BOLT_WOLLEY 34449 // DAZED? class COILFANGWATERELEMENTALAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(COILFANGWATERELEMENTALAI); SP_AI_Spell spells[1]; bool m_spellcheck[1]; COILFANGWATERELEMENTALAI(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; }; // Coilfang MyrmidonAI #define CN_COILFANG_MYRMIDON 17800 #define SWEEPING_STRIKES 18765 // DBC: 18765, 12723 //35429 #define CLEAVE 15622 //38260 // no idea about it's id #define EXECUTE 7160 //38959 // should activate only on target with <= 25% hp // not sure about it class COILFANGMYRMIDONAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(COILFANGMYRMIDONAI); SP_AI_Spell spells[3]; bool m_spellcheck[3]; COILFANGMYRMIDONAI(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; }; // Tidal SurgerAI #define CN_TIDAL_SURGER 21695 //#define KNOCKBACK 30056 #define WATER_SPOUT 37250 #define FROST_NOVA_SURGER 15531 // Should has immunite to frost spells (as adds) + should has // 3-4 minons (Idk if they should be spawned by script) class TIDALSURGERAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(TIDALSURGERAI); SP_AI_Spell spells[2]; bool m_spellcheck[2]; TIDALSURGERAI(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; }; // Steamrigger MechanicAI #define CN_STEAMRIGGER_MECHANIC 17951 #define REPAIR 31532 // DAZED? class STEAMRIGGERMECHANICAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(STEAMRIGGERMECHANICAI); SP_AI_Spell spells[1]; bool m_spellcheck[1]; STEAMRIGGERMECHANICAI(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; }; // Steam SurgerAI #define CN_STEAM_SURGER 21696 #define WATER_BOLT 37252 // DAZED? class STEAMSURGERAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(STEAMSURGERAI); SP_AI_Spell spells[1]; bool m_spellcheck[1]; STEAMSURGERAI(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 */ /* */ /*****************************/ struct Coords { float x; float y; float z; float o; }; //Mekgineer Steamrigger static Coords spawnCoords[] = { { -300.037842, -115.296227, -7.865229, 4.197916 }, { -330.083008, -121.505997, -7.985120, 5.061450 }, { -346.530273, -147.167892, -6.703687, 0.010135 } }; #define CN_MEKGINEER_STEAMRIGGER 17796 #define CN_STEAMRIGGER_MECHANIC 17951 #define SUPER_SHRINK_RAY 31485 #define SAW_BLADE 31486 // Or this: 35318 #define ELECTRIFIED_NET 35107 #define ENRAGE 41447 // No idea if these are good ids // still not sue // Must spawn 3 Steamrigger Mechanics when his health is on 75%, 50% and 25% class MEKGINEERSTEAMRIGGERAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(MEKGINEERSTEAMRIGGERAI); SP_AI_Spell spells[4]; bool m_spellcheck[4]; MEKGINEERSTEAMRIGGERAI(Creature* pCreature) : CreatureAIScript(pCreature) { nrspells = 4; for(int i=0;iSendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, "Your in for a World-O-Hurt !"); _unit->PlaySoundToSet(10368); break; case 1: _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, "Eat hot metal! Scumbag!"); _unit->PlaySoundToSet(10369); break; case 2: _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, "I'll come over there!"); // really? _unit->PlaySoundToSet(10370); break; case 3: _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, "I'm bringin' the pain!"); // really2? _unit->PlaySoundToSet(10371); 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()%3; switch (RandomSpeach) { case 0: _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, "You just got served, Punk!"); _unit->PlaySoundToSet(10372); break; case 1: _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, "I own you!"); _unit->PlaySoundToSet(10373); break; case 2: _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, "Have fun dying, capcake!"); // capcake? _unit->PlaySoundToSet(10374); break; } } } void OnCombatStop(Unit *mTarget) { Timer = 0; CastTime(); _unit->GetAIInterface()->setCurrentAgent(AGENT_NULL); _unit->GetAIInterface()->SetAIState(STATE_IDLE); RemoveAIUpdateEvent(); } void OnDied(Unit * mKiller) { Timer = 0; CastTime(); _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, "Mommy"); _unit->PlaySoundToSet(10375); RemoveAIUpdateEvent(); } void AIUpdate() { Timer++; if (Timer == 100) { _unit->CastSpell(_unit, spells[3].info, spells[3].instant); } if(_unit->GetHealthPct() == 25 || _unit->GetHealthPct() == 50 || _unit->GetHealthPct() == 75) { Creature *cre = NULL; for(int i = 0; i < 3; i++) { cre = _unit->GetMapMgr()->GetInterface()->SpawnCreature(CN_STEAMRIGGER_MECHANIC, spawnCoords[i].x, spawnCoords[i].y, spawnCoords[i].z, spawnCoords[i].o, true, false, _unit->GetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE), 50); //63 if(cre) { //cre->GetAIInterface()->MoveTo(14.161, -177.874, -85.649, 0.23); cre->GetAIInterface()->setOutOfCombatRange(100000); } cre = _unit->GetMapMgr()->GetInterface()->SpawnCreature(CN_STEAMRIGGER_MECHANIC, spawnCoords[2-i].x, spawnCoords[2-i].y, spawnCoords[2-i].z, spawnCoords[2-i].o, true, false, _unit->GetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE), 63); if(cre) { //cre->GetAIInterface()->MoveTo(27.133, -232.030, -84.188, 0.44); cre->GetAIInterface()->setOutOfCombatRange(100000); } } } 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 Timer; int nrspells; }; // Hydromancer ThespiaAI #define CN_HYDROMANCER_THESPIA 17797 #define ENVELOPING_WINDS 31718 #define LIGHTNING_CLOUD 25033 #define LUNG_BURST 31481 class HYDROMANCERTHESPIAAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(HYDROMANCERTHESPIAAI); SP_AI_Spell spells[3]; bool m_spellcheck[3]; HYDROMANCERTHESPIAAI(Creature* pCreature) : CreatureAIScript(pCreature) { nrspells = 3; for(int i=0;iSendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, "The depths will consume you!"); _unit->PlaySoundToSet(10361); break; case 1: _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, "Meet your doom, surface dwellers!"); _unit->PlaySoundToSet(10362); break; case 2: _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, "You will drown in blood!"); _unit->PlaySoundToSet(10363); 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, "To the depths of oblivion with you!"); _unit->PlaySoundToSet(10364); break; case 1: _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, "For my Lady and Master."); _unit->PlaySoundToSet(10365); break; } } } void OnCombatStop(Unit *mTarget) { CastTime(); _unit->GetAIInterface()->setCurrentAgent(AGENT_NULL); _unit->GetAIInterface()->SetAIState(STATE_IDLE); RemoveAIUpdateEvent(); } void OnDied(Unit * mKiller) { CastTime(); _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, "Our matron will be ... The end of you"); _unit->PlaySoundToSet(10366); 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; }; // Warlord Kalitresh AI #define CN_WARLORD_KALITRESH 17798 #define IMPALE 34451 //24049 // 1 target Correct spell id? Maybe 34451 or ... correct #define HEAD_CRACK 16172 #define WARLORDS_RAGE 36453 // DBC: 37081, 36453 // still he must be forced by Driller to cast it #define SPELL_REFLECTION 31534 //33961 class WARLORDKALITRESHAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(WARLORDKALITRESHAI); SP_AI_Spell spells[4]; bool m_spellcheck[4]; WARLORDKALITRESHAI(Creature* pCreature) : CreatureAIScript(pCreature) { nrspells = 4; for(int i=0;iSendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, "Your head will roll!"); _unit->PlaySoundToSet(10392); break; case 1: _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, "I despise all of your kind!"); _unit->PlaySoundToSet(10393); break; case 2: /* Maybe an emote for "strange words"? */ _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, "No freaking idea :P"); _unit->PlaySoundToSet(10394); 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, "Squirm , Surface filth!"); _unit->PlaySoundToSet(10395); break; case 1: _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, "Hahahahah"); _unit->PlaySoundToSet(10366); break; } } } void OnCombatStop(Unit *mTarget) { CastTime(); _unit->GetAIInterface()->setCurrentAgent(AGENT_NULL); _unit->GetAIInterface()->SetAIState(STATE_IDLE); RemoveAIUpdateEvent(); } void OnDied(Unit * mKiller) { CastTime(); _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, "For her exelency , For Vash..."); _unit->PlaySoundToSet(10397); 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 SetupTheSteamvault(ScriptMgr * mgr) { mgr->register_creature_script(CN_COILFANG_ORACLE, &COILFANGORACLEAI::Create); mgr->register_creature_script(CN_COILFANG_ENGINEER, &COILFANGENGINEERAI::Create); mgr->register_creature_script(CN_COILFANG_WARRIOR, &COILFANGWARRIORAI::Create); mgr->register_creature_script(CN_COILFANG_SIREN, &COILFANGSIRENAI::Create); mgr->register_creature_script(CN_COILFANG_SORCERESS, &COILFANGSORCERESSAI::Create); mgr->register_creature_script(CN_COILFANG_LEPER, &COILFANGLEPERAI::Create); mgr->register_creature_script(CN_COILFANG_SLAVEMASTER, &COILFANGSLAVEMASTERAI::Create); mgr->register_creature_script(CN_COILFANG_MYRMIDON, &COILFANGMYRMIDONAI::Create); mgr->register_creature_script(CN_COILFANG_WATER_ELEMENTAL, &COILFANGWATERELEMENTALAI::Create); mgr->register_creature_script(CN_BOG_OVERLORD, &BOGOVERLORDAI::Create); mgr->register_creature_script(CN_TIDAL_SURGER, &TIDALSURGERAI::Create); mgr->register_creature_script(CN_STEAM_SURGER, &STEAMSURGERAI::Create); mgr->register_creature_script(CN_STEAMRIGGER_MECHANIC, &STEAMRIGGERMECHANICAI::Create); mgr->register_creature_script(CN_HYDROMANCER_THESPIA, &HYDROMANCERTHESPIAAI::Create); mgr->register_creature_script(CN_MEKGINEER_STEAMRIGGER, &MEKGINEERSTEAMRIGGERAI::Create); mgr->register_creature_script(CN_WARLORD_KALITRESH, &WARLORDKALITRESHAI::Create); } /* TO DO: Check all spells/creatures and evenatually balance them (if needed!) also add spawns correctly (no core support for now and hacky Onyxia way does not work (in Onyxia also). Change target type when there will be more core support. Also very imporant thing is to force spawns to heal random or target you choosed. When that will work, I will add AI for mechanics who should heal one of instance bosses.*/ // Don't have infos about: Second Fragment Guardian (22891) | Dreghood Slave (17799 - // should they really have enrage ? [8269]), Driller should use Warlord's Rage spell // (31543) to force Warlord to enrage, but I need more infos about targeting target // you want to.