#include "StdAfx.h" #include "Setup.h" /************************************************************************/ /* Instance_SethekkHalls.cpp Script */ /************************************************************************/ // Avian Darkhawk AI #define CN_AVIAN_DARKHAWK 20686 #define CHARGE 36509 // no idea if this is correct id class AVIANDARKHAWKAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(AVIANDARKHAWKAI); SP_AI_Spell spells[1]; bool m_spellcheck[1]; AVIANDARKHAWKAI(Creature* pCreature) : CreatureAIScript(pCreature) { nrspells = 1; for(int i=0;iGetUInt32Value(UNIT_FIELD_BASEATTACKTIME)); } void OnCombatStop(Unit *mTarget) { _unit->GetAIInterface()->setCurrentAgent(AGENT_NULL); _unit->GetAIInterface()->SetAIState(STATE_IDLE); RemoveAIUpdateEvent(); } void OnDied(Unit * mKiller) { 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; } m_spellcheck[i] = false; return; } if(val > comulativeperc && val <= (comulativeperc + spells[i].perctrigger)) { _unit->setAttackTimer(spells[i].attackstoptimer, false); m_spellcheck[i] = true; } comulativeperc += spells[i].perctrigger; } } } protected: Unit *target; int nrspells; }; // Avian Ripper AI #define CN_AVIAN_RIPPER 21891 #define FLESH_RIP 40199 class AVIANRIPPERAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(AVIANRIPPERAI); SP_AI_Spell spells[1]; bool m_spellcheck[1]; AVIANRIPPERAI(Creature* pCreature) : CreatureAIScript(pCreature) { nrspells = 1; for(int i=0;iGetUInt32Value(UNIT_FIELD_BASEATTACKTIME)); } void OnCombatStop(Unit *mTarget) { _unit->GetAIInterface()->setCurrentAgent(AGENT_NULL); _unit->GetAIInterface()->SetAIState(STATE_IDLE); RemoveAIUpdateEvent(); } void OnDied(Unit * mKiller) { 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; } m_spellcheck[i] = false; return; } if(val > comulativeperc && val <= (comulativeperc + spells[i].perctrigger)) { _unit->setAttackTimer(spells[i].attackstoptimer, false); m_spellcheck[i] = true; } comulativeperc += spells[i].perctrigger; } } } protected: int nrspells; }; // Avian Warhawk AI #define CN_AVIAN_WARHAWK 21904 // test it more@ #define CLEAVE 38474 // no idea if this is right #define CHARGE_WARHAWK 40602 // same here #define CARNIVOROUS_BITE 39382 // and here =) class AVIANWARHAWKAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(AVIANWARHAWKAI); SP_AI_Spell spells[3]; bool m_spellcheck[3]; AVIANWARHAWKAI(Creature* pCreature) : CreatureAIScript(pCreature) { nrspells = 3; for(int i=0;iGetUInt32Value(UNIT_FIELD_BASEATTACKTIME)); } void OnCombatStop(Unit *mTarget) { _unit->GetAIInterface()->setCurrentAgent(AGENT_NULL); _unit->GetAIInterface()->SetAIState(STATE_IDLE); RemoveAIUpdateEvent(); } void OnDied(Unit * mKiller) { 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; } m_spellcheck[i] = false; return; } if(val > comulativeperc && val <= (comulativeperc + spells[i].perctrigger)) { _unit->setAttackTimer(spells[i].attackstoptimer, false); m_spellcheck[i] = true; } comulativeperc += spells[i].perctrigger; } } } protected: Unit *target; int nrspells; }; // Cobalt Serpent AI #define CN_COBALT_SERPENT 19428 #define WING_BUFFET 41572 #define FROSTBOLT 40429 // no idea about if these are good ids :P #define CHAIN_LIGHTNING_SERPENT 39945 class COBALTSERPENTAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(COBALTSERPENTAI); SP_AI_Spell spells[3]; bool m_spellcheck[3]; COBALTSERPENTAI(Creature* pCreature) : CreatureAIScript(pCreature) { nrspells = 3; for(int i=0;iGetUInt32Value(UNIT_FIELD_BASEATTACKTIME)); } void OnCombatStop(Unit *mTarget) { _unit->GetAIInterface()->setCurrentAgent(AGENT_NULL); _unit->GetAIInterface()->SetAIState(STATE_IDLE); RemoveAIUpdateEvent(); } void OnDied(Unit * mKiller) { 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; } m_spellcheck[i] = false; return; } if(val > comulativeperc && val <= (comulativeperc + spells[i].perctrigger)) { _unit->setAttackTimer(spells[i].attackstoptimer, false); m_spellcheck[i] = true; } comulativeperc += spells[i].perctrigger; } } } protected: int nrspells; }; // Time-Lost Controller AI #define CN_TIME_LOST_CONTROLLER 20691 #define SHIRNK 36697 // 36697 or 35013 //#define CONTROL_TOTEM // Can't find spell for that :O class TIMELOSTCONTROLLERAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(TIMELOSTCONTROLLERAI); SP_AI_Spell spells[1]; bool m_spellcheck[1]; TIMELOSTCONTROLLERAI(Creature* pCreature) : CreatureAIScript(pCreature) { nrspells = 1; for(int i=0;iGetUInt32Value(UNIT_FIELD_BASEATTACKTIME)); } void OnCombatStop(Unit *mTarget) { _unit->GetAIInterface()->setCurrentAgent(AGENT_NULL); _unit->GetAIInterface()->SetAIState(STATE_IDLE); RemoveAIUpdateEvent(); } void OnDied(Unit * mKiller) { 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; } m_spellcheck[i] = false; return; } if(val > comulativeperc && val <= (comulativeperc + spells[i].perctrigger)) { _unit->setAttackTimer(spells[i].attackstoptimer, false); m_spellcheck[i] = true; } comulativeperc += spells[i].perctrigger; } } } protected: int nrspells; }; // Time-Lost Scryer AI #define CN_TIME_LOST_SCRYER 20697 #define FLASH_HEAL 38588 // let's try this one #define ARCANE_MISSILES 35034 // and those: 35033, 35034 // doesn't work somehow class TIMELOSTSCRYERAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(TIMELOSTSCRYERAI); SP_AI_Spell spells[2]; bool m_spellcheck[2]; TIMELOSTSCRYERAI(Creature* pCreature) : CreatureAIScript(pCreature) { nrspells = 2; for(int i=0;iGetUInt32Value(UNIT_FIELD_BASEATTACKTIME)); } void OnCombatStop(Unit *mTarget) { _unit->GetAIInterface()->setCurrentAgent(AGENT_NULL); _unit->GetAIInterface()->SetAIState(STATE_IDLE); RemoveAIUpdateEvent(); } void OnDied(Unit * mKiller) { 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; } m_spellcheck[i] = false; return; } if(val > comulativeperc && val <= (comulativeperc + spells[i].perctrigger)) { _unit->setAttackTimer(spells[i].attackstoptimer, false); m_spellcheck[i] = true; } comulativeperc += spells[i].perctrigger; } } } protected: int nrspells; }; // Time-Lost Shadowmage AI #define CN_TIME_LOST_SHADOWMAGE 20698 #define CURSE_OF_THE_DARK_TALON 32682 class TIMELOSTSHADOWMAGEAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(TIMELOSTSHADOWMAGEAI); SP_AI_Spell spells[1]; bool m_spellcheck[1]; TIMELOSTSHADOWMAGEAI(Creature* pCreature) : CreatureAIScript(pCreature) { nrspells = 1; for(int i=0;iGetUInt32Value(UNIT_FIELD_BASEATTACKTIME)); } void OnCombatStop(Unit *mTarget) { _unit->GetAIInterface()->setCurrentAgent(AGENT_NULL); _unit->GetAIInterface()->SetAIState(STATE_IDLE); RemoveAIUpdateEvent(); } void OnDied(Unit * mKiller) { 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; } m_spellcheck[i] = false; return; } if(val > comulativeperc && val <= (comulativeperc + spells[i].perctrigger)) { _unit->setAttackTimer(spells[i].attackstoptimer, false); m_spellcheck[i] = true; } comulativeperc += spells[i].perctrigger; } } } protected: int nrspells; }; // Sethekk Guard AI #define CN_SETHEKK_GUARD 18323 #define THUNDERCLAP 36214 #define SUNDER_ARMOR 30901 // 1000 arm per use (to 5 uses!) O_O class SETHEKKGUARDAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(SETHEKKGUARDAI); SP_AI_Spell spells[2]; bool m_spellcheck[2]; SETHEKKGUARDAI(Creature* pCreature) : CreatureAIScript(pCreature) { nrspells = 2; for(int i=0;iGetUInt32Value(UNIT_FIELD_BASEATTACKTIME)); } void OnCombatStop(Unit *mTarget) { _unit->GetAIInterface()->setCurrentAgent(AGENT_NULL); _unit->GetAIInterface()->SetAIState(STATE_IDLE); RemoveAIUpdateEvent(); } void OnDied(Unit * mKiller) { 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; } m_spellcheck[i] = false; return; } if(val > comulativeperc && val <= (comulativeperc + spells[i].perctrigger)) { _unit->setAttackTimer(spells[i].attackstoptimer, false); m_spellcheck[i] = true; } comulativeperc += spells[i].perctrigger; } } } protected: int nrspells; }; // Sethekk Initiate AI #define CN_SETHEKK_INITIATE 18318 #define MAGIC_REFLECTION 20223 // 20223 or 20619 class SETHEKKINITIATEAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(SETHEKKINITIATEAI); SP_AI_Spell spells[1]; bool m_spellcheck[1]; SETHEKKINITIATEAI(Creature* pCreature) : CreatureAIScript(pCreature) { nrspells = 1; for(int i=0;iGetUInt32Value(UNIT_FIELD_BASEATTACKTIME)); } void OnCombatStop(Unit *mTarget) { _unit->GetAIInterface()->setCurrentAgent(AGENT_NULL); _unit->GetAIInterface()->SetAIState(STATE_IDLE); RemoveAIUpdateEvent(); } void OnDied(Unit * mKiller) { 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; } m_spellcheck[i] = false; return; } if(val > comulativeperc && val <= (comulativeperc + spells[i].perctrigger)) { _unit->setAttackTimer(spells[i].attackstoptimer, false); m_spellcheck[i] = true; } comulativeperc += spells[i].perctrigger; } } } protected: int nrspells; }; // Sethekk Oracle AI #define CN_SETHEKK_ORACLE 18328 #define FAERIE_FIRE 21670 // 20656 or 21670 or 32129 or other #define ARCANE_LIGHTNING 38146 // 38146, 32690 or 38634 class SETHEKKORACLEAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(SETHEKKORACLEAI); SP_AI_Spell spells[2]; bool m_spellcheck[2]; SETHEKKORACLEAI(Creature* pCreature) : CreatureAIScript(pCreature) { nrspells = 2; for(int i=0;iGetUInt32Value(UNIT_FIELD_BASEATTACKTIME)); } void OnCombatStop(Unit *mTarget) { _unit->GetAIInterface()->setCurrentAgent(AGENT_NULL); _unit->GetAIInterface()->SetAIState(STATE_IDLE); RemoveAIUpdateEvent(); } void OnDied(Unit * mKiller) { 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; } m_spellcheck[i] = false; return; } if(val > comulativeperc && val <= (comulativeperc + spells[i].perctrigger)) { _unit->setAttackTimer(spells[i].attackstoptimer, false); m_spellcheck[i] = true; } comulativeperc += spells[i].perctrigger; } } } protected: int nrspells; }; // Sethekk Prophet AI #define CN_SETHEKK_PROPHET 18325 #define FEAR 32241 // Should it be aoe or normal? // damn it fears caster too //#define // Ghost spawning similar to those in Sunken Temple class SETHEKKPROPHETAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(SETHEKKPROPHETAI); SP_AI_Spell spells[1]; bool m_spellcheck[1]; SETHEKKPROPHETAI(Creature* pCreature) : CreatureAIScript(pCreature) { nrspells = 1; for(int i=0;iGetUInt32Value(UNIT_FIELD_BASEATTACKTIME)); } void OnCombatStop(Unit *mTarget) { _unit->GetAIInterface()->setCurrentAgent(AGENT_NULL); _unit->GetAIInterface()->SetAIState(STATE_IDLE); RemoveAIUpdateEvent(); } void OnDied(Unit * mKiller) { 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; } m_spellcheck[i] = false; return; } if(val > comulativeperc && val <= (comulativeperc + spells[i].perctrigger)) { _unit->setAttackTimer(spells[i].attackstoptimer, false); m_spellcheck[i] = true; } comulativeperc += spells[i].perctrigger; } } } protected: int nrspells; }; // Sethekk Ravenguard AI #define CN_SETHEKK_RAVENGUARD 18322 #define BLOODTHIRST 31996 // check also spells like this: 31996 and this: 35948 #define HOWLING_SCREECH 32651 class SETHEKKRAVENGUARDAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(SETHEKKRAVENGUARDAI); SP_AI_Spell spells[2]; bool m_spellcheck[2]; SETHEKKRAVENGUARDAI(Creature* pCreature) : CreatureAIScript(pCreature) { nrspells = 2; for(int i=0;iGetUInt32Value(UNIT_FIELD_BASEATTACKTIME)); } void OnCombatStop(Unit *mTarget) { _unit->GetAIInterface()->setCurrentAgent(AGENT_NULL); _unit->GetAIInterface()->SetAIState(STATE_IDLE); RemoveAIUpdateEvent(); } void OnDied(Unit * mKiller) { 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; } m_spellcheck[i] = false; return; } if(val > comulativeperc && val <= (comulativeperc + spells[i].perctrigger)) { _unit->setAttackTimer(spells[i].attackstoptimer, false); m_spellcheck[i] = true; } comulativeperc += spells[i].perctrigger; } } } protected: int nrspells; }; // Sethekk Shaman AI #define CN_SETHEKK_SHAMAN 18326 #define SUMMON_DARK_VORTEX 32663 //SUMMON_VOIDWALKER 30208 // Shouldn't be Dark Vortex (spell id: 32663) ? class SETHEKKSHAMANAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(SETHEKKSHAMANAI); SP_AI_Spell spells[1]; bool m_spellcheck[1]; SETHEKKSHAMANAI(Creature* pCreature) : CreatureAIScript(pCreature) { nrspells = 1; for(int i=0;iGetUInt32Value(UNIT_FIELD_BASEATTACKTIME)); } void OnCombatStop(Unit *mTarget) { _unit->GetAIInterface()->setCurrentAgent(AGENT_NULL); _unit->GetAIInterface()->SetAIState(STATE_IDLE); RemoveAIUpdateEvent(); } void OnDied(Unit * mKiller) { 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; } m_spellcheck[i] = false; return; } if(val > comulativeperc && val <= (comulativeperc + spells[i].perctrigger)) { _unit->setAttackTimer(spells[i].attackstoptimer, false); m_spellcheck[i] = true; } comulativeperc += spells[i].perctrigger; } } } protected: int nrspells; }; // Sethekk Talon Lord AI #define CN_SETHEKK_TALON_LORD 18321 #define TALON_OF_JUSTICE 32654 // 32654 or 39229 #define AVENGERS_SHIELD 32774 // On WoWWiki is Shield of Revenge, but that should be it. Also spells that can be: 32774, 32674, 37554 class SETHEKKTALONLORDAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(SETHEKKTALONLORDAI); SP_AI_Spell spells[2]; bool m_spellcheck[2]; SETHEKKTALONLORDAI(Creature* pCreature) : CreatureAIScript(pCreature) { nrspells = 2; for(int i=0;iGetUInt32Value(UNIT_FIELD_BASEATTACKTIME)); } void OnCombatStop(Unit *mTarget) { _unit->GetAIInterface()->setCurrentAgent(AGENT_NULL); _unit->GetAIInterface()->SetAIState(STATE_IDLE); RemoveAIUpdateEvent(); } void OnDied(Unit * mKiller) { 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; } m_spellcheck[i] = false; return; } if(val > comulativeperc && val <= (comulativeperc + spells[i].perctrigger)) { _unit->setAttackTimer(spells[i].attackstoptimer, false); m_spellcheck[i] = true; } comulativeperc += spells[i].perctrigger; } } } protected: Unit *target; int nrspells; }; /*****************************/ /* */ /* Boss AIs */ /* */ /*****************************/ // Darkweaver SythAI #define CN_DARKWEAVER_SYTH 18472 // Spells #define FROST_SHOCK 25464 // Workaround as this is player spell, but with proly same effect. (lower dmg - 37865, higher dmg - 37332) #define FLAME_SHOCK 34354 // To small dmg, need to find better one #define SHADOW_SHOCK 30138 // SELF IN DESCR. ?_? I think more accurate can be found (but this is quiet good) #define ARCANE_SHOCK 33175 // I think better can be found, but still it's good #define CHAIN_LIGHTNING 33643 // Couldn't find more info about this spell? // Summons #define SUMMON_SYTH_FIRE_ELEMENTAL 33537 //needs more core support, but those are correct ids! #define SUMMON_SYTH_FROST_ELEMENTAL 33539 #define SUMMON_SYTH_ARCANE_ELEMENTAL 33538 #define SUMMON_SYTH_SHADOW_ELEMENTAL 33540 class DARKWEAVERSYTHAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(DARKWEAVERSYTHAI); SP_AI_Spell spells[9]; bool m_spellcheck[9]; DARKWEAVERSYTHAI(Creature* pCreature) : CreatureAIScript(pCreature) { SUMMON_LIMITER = 1; nrspells = 9; for(int i=0;iSendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, "Time to... make my move!"); // needs corrections _unit->PlaySoundToSet(10503); break; case 1: _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, "Nice pets, yes!"); // corrections needed! _unit->PlaySoundToSet(10504); break; case 2: _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, "Nice pets have... weapons, not so... nice!"); _unit->PlaySoundToSet(10505); break; } RegisterAIUpdateEvent(_unit->GetUInt32Value(UNIT_FIELD_BASEATTACKTIME)); } 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, "Yes! Fleeting life is..."); // need to add it _unit->PlaySoundToSet(10506); break; case 1: _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, "Be free!"); // corrections needed!! _unit->PlaySoundToSet(10507); break; } } } void OnCombatStop(Unit *mTarget) { SUMMON_LIMITER = 1; _unit->GetAIInterface()->setCurrentAgent(AGENT_NULL); _unit->GetAIInterface()->SetAIState(STATE_IDLE); RemoveAIUpdateEvent(); } void OnDied(Unit * mKiller) { SUMMON_LIMITER = 1; _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, "No more life, no more pain!"); // It's talking so _unit->PlaySoundToSet(10508); RemoveAIUpdateEvent(); } void AIUpdate() { if ((_unit->GetHealthPct() <= 75 && SUMMON_LIMITER == 1) || (_unit->GetHealthPct() <= 50 && SUMMON_LIMITER == 2) || (_unit->GetHealthPct() <= 25 && SUMMON_LIMITER == 3)) { SummonElementalWave(); } else { float val = sRand.rand(100.0f); SpellCast(val); } } void SummonElementalWave() { _unit->CastSpell(_unit, spells[5].info, spells[5].instant); _unit->CastSpell(_unit, spells[6].info, spells[6].instant); _unit->CastSpell(_unit, spells[7].info, spells[7].instant); _unit->CastSpell(_unit, spells[8].info, spells[8].instant); _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, "I have pets... of my own"); // It's talking so -.-' _unit->PlaySoundToSet(10502); SUMMON_LIMITER += 1; } 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)) { _unit->setAttackTimer(spells[i].attackstoptimer, false); m_spellcheck[i] = true; } comulativeperc += spells[i].perctrigger; } } } protected: uint32 SUMMON_LIMITER; int nrspells; }; // Talon King IkissAI #define CN_TALON_KING_IKISS 18473 #define ARCANE_VOLLEY 37078 // maybe should be: 37078 or other #define ARCANE_EXPLOSION 38197 // bit too high dmg, but should work nearly in the same way #define BLINK 38642 // Should be to random character, also can be: 38642, 29883, 38932, 36718, // doesn't work, because of lack features in core #define POLYMORPH 38245 // worth to try also: 38245, 38896 #define MANA_SHIELD 38151 // also: 35064, 38151 class TALONKINGIKISSAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(TALONKINGIKISSAI); SP_AI_Spell spells[5]; bool m_spellcheck[5]; TALONKINGIKISSAI(Creature* pCreature) : CreatureAIScript(pCreature) { nrspells = 5; for(int i=0;iSendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, "You make war on Ikiss!"); // needs corrections _unit->PlaySoundToSet(10554); break; case 1: _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, "Ikiss caught you pretty... sliced you, yes!"); // corrections needed! _unit->PlaySoundToSet(10555); break; case 2: _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, "No escape for... for you!"); _unit->PlaySoundToSet(10556); break; } RegisterAIUpdateEvent(_unit->GetUInt32Value(UNIT_FIELD_BASEATTACKTIME)); } void OnTargetDied(Unit* mTarget) // left to keep it easy to add needed data. { 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, "You'll die! Stay away from trinkets!"); // needs corrections _unit->PlaySoundToSet(10558); break; case 1: _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, ""); // corrections needed! _unit->PlaySoundToSet(10559); break; } } } void OnCombatStop(Unit *mTarget) { _unit->GetAIInterface()->setCurrentAgent(AGENT_NULL); _unit->GetAIInterface()->SetAIState(STATE_IDLE); RemoveAIUpdateEvent(); } void OnDied(Unit * mKiller) { _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, "Ikiss will not... die!"); _unit->PlaySoundToSet(10560); 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)) { _unit->setAttackTimer(spells[i].attackstoptimer, false); m_spellcheck[i] = true; } comulativeperc += spells[i].perctrigger; } } } protected: int nrspells; }; // AnzuAI #define CN_ANZU 23035 // that should be real id, but it is not existing in my DB #define SUMMON_RAVEN_GOD 40098 // event just to test it! #define SPELL_BOMB 40303 #define CYCLONE_OF_FEATHERS 40321 #define PARALYZING_SCREECH 40184 #define CHARGE_ANZU 40602 // no idea, can be: 40602, 39574 and others #define BANISH 40370 // can be: 38791, 38009, 40370, 39674, 35182, 40825 // should banish for one minute //#define SPAWN_BIRDS Can't find for now =/ class ANZUAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(ANZUAI); SP_AI_Spell spells[6]; bool m_spellcheck[6]; ANZUAI(Creature* pCreature) : CreatureAIScript(pCreature) { SUMMON_LIMITER = 1; nrspells = 6; for(int i=0;iCastSpell(_unit, spells[5].info, spells[5].targettype); SUMMON_LIMITER = 1; RegisterAIUpdateEvent(_unit->GetUInt32Value(UNIT_FIELD_BASEATTACKTIME)); } void OnTargetDied(Unit* mTarget) // left to keep it easy to add needed data. { } void OnCombatStop(Unit *mTarget) { SUMMON_LIMITER = 1; _unit->GetAIInterface()->setCurrentAgent(AGENT_NULL); _unit->GetAIInterface()->SetAIState(STATE_IDLE); RemoveAIUpdateEvent(); } void OnDied(Unit * mKiller) { SUMMON_LIMITER = 1; RemoveAIUpdateEvent(); } void AIUpdate() { if((_unit->GetHealthPct() <= 66 && SUMMON_LIMITER == 1) || (_unit->GetHealthPct() <= 33 && SUMMON_LIMITER == 2) ) { SummonPhase(); } else { float val = sRand.rand(100.0f); SpellCast(val); } } void SummonPhase() { SUMMON_LIMITER += 1; _unit->CastSpell(_unit,spells[4].info, spells[4].targettype); //_unit->CastSpell(_unit,spells[6].info, spells[6].targettype); Bird summon spell } 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)) { _unit->setAttackTimer(spells[i].attackstoptimer, false); m_spellcheck[i] = true; } comulativeperc += spells[i].perctrigger; } } } protected: Unit *target; uint32 SUMMON_LIMITER; int nrspells; }; void SetupSethekkHalls(ScriptMgr * mgr) { mgr->register_creature_script(CN_AVIAN_DARKHAWK, &AVIANDARKHAWKAI::Create); mgr->register_creature_script(CN_AVIAN_RIPPER, &AVIANRIPPERAI::Create); mgr->register_creature_script(CN_AVIAN_WARHAWK, &AVIANWARHAWKAI::Create); mgr->register_creature_script(CN_COBALT_SERPENT, &COBALTSERPENTAI::Create); mgr->register_creature_script(CN_TIME_LOST_CONTROLLER, &TIMELOSTCONTROLLERAI::Create); mgr->register_creature_script(CN_TIME_LOST_SCRYER, &TIMELOSTSCRYERAI::Create); mgr->register_creature_script(CN_TIME_LOST_SHADOWMAGE, &TIMELOSTSHADOWMAGEAI::Create); mgr->register_creature_script(CN_SETHEKK_GUARD, &SETHEKKGUARDAI::Create); mgr->register_creature_script(CN_SETHEKK_INITIATE, &SETHEKKINITIATEAI::Create); mgr->register_creature_script(CN_SETHEKK_ORACLE, &SETHEKKORACLEAI::Create); mgr->register_creature_script(CN_SETHEKK_PROPHET, &SETHEKKPROPHETAI::Create); mgr->register_creature_script(CN_SETHEKK_RAVENGUARD, &SETHEKKRAVENGUARDAI::Create); mgr->register_creature_script(CN_SETHEKK_SHAMAN, &SETHEKKSHAMANAI::Create); mgr->register_creature_script(CN_SETHEKK_TALON_LORD, &SETHEKKTALONLORDAI::Create); mgr->register_creature_script(CN_DARKWEAVER_SYTH, &DARKWEAVERSYTHAI::Create); mgr->register_creature_script(CN_TALON_KING_IKISS, &TALONKINGIKISSAI::Create); mgr->register_creature_script(CN_ANZU, &ANZUAI::Create); } // Can't check Anzu, as I don't have it in DB right now. Add some spells (2?) and // change other if needed.