#include "StdAfx.h" #include "Setup.h" /************************************************************************/ /* Instance_TheMechanar.cpp Script */ /************************************************************************/ // Arcane ServantAI #define CN_ARCANE_SERVANT 20478 #define ARCANE_VOLLEY 35255 #define ARCANE_EXPLOSION 22271 //#define SPOTLIGHT 35259 // SSS class ArcaneServantAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(ArcaneServantAI); SP_AI_Spell spells[2]; bool m_spellcheck[2]; ArcaneServantAI(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; }; // Bloodwarder CenturionAI #define CN_BLOODWARDER_CENTURION 19510 #define SHIELD_BASH 35178 #define UNSTABLE_AFFLICTION 35183 #define MELT_ARMOR 35185 #define CHILLING_TOUCH 12531 #define ETHEREAL_TELEPORT 34427 // SSS //#define SEED_OF_CORRUPTION 37826 // SSS class BloodwarderCenturionAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(BloodwarderCenturionAI); SP_AI_Spell spells[5]; bool m_spellcheck[5]; BloodwarderCenturionAI(Creature* pCreature) : CreatureAIScript(pCreature) { nrspells = 5; for(int i=0;iCastSpell(_unit, spells[4].info, spells[4].instant); CastTime(); RegisterAIUpdateEvent(_unit->GetUInt32Value(UNIT_FIELD_BASEATTACKTIME)); } void CastTime() { for(int i=0;iGetAIInterface()->setCurrentAgent(AGENT_NULL); _unit->GetAIInterface()->SetAIState(STATE_IDLE); RemoveAIUpdateEvent(); } void OnDied(Unit * mKiller) { CastTime(); RemoveAIUpdateEvent(); } void AIUpdate() { float val = sRand.rand(100.0f); SpellCast(val); } void SpellCast(float val) { if(_unit->GetCurrentSpell() == NULL && _unit->GetAIInterface()->GetNextTarget()) { float comulativeperc = 0; Unit *target = NULL; for(int i=0;iGetAIInterface()->GetNextTarget(); switch(spells[i].targettype) { case TARGET_SELF: case TARGET_VARIOUS: _unit->CastSpell(_unit, spells[i].info, spells[i].instant); break; case TARGET_ATTACKING: _unit->CastSpell(target, spells[i].info, spells[i].instant); break; case TARGET_DESTINATION: _unit->CastSpellAoF(target->GetPositionX(),target->GetPositionY(),target->GetPositionZ(), spells[i].info, spells[i].instant); break; } if (spells[i].speech != "") { _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, spells[i].speech.c_str()); _unit->PlaySoundToSet(spells[i].soundid); } m_spellcheck[i] = false; return; } if ((val > comulativeperc && val <= (comulativeperc + spells[i].perctrigger)) || !spells[i].casttime) { _unit->setAttackTimer(spells[i].attackstoptimer, false); m_spellcheck[i] = true; } comulativeperc += spells[i].perctrigger; } } } protected: int nrspells; }; // Bloodwarder PhysicianAI #define CN_BLOODWARDER_PHYSICIAN 20990 #define HOLY_SHOCK 36340 #define ANESTHETIC 36333 #define BANDAGE 36348 // DBC: 36348; mine choice 38919 #define ETHEREAL_TELEPORT_PHYS 34427 // SSS //#define SEED_OF_CORRUPTION 37826 // SSS class BloodwarderPhysicianAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(BloodwarderPhysicianAI); SP_AI_Spell spells[4]; bool m_spellcheck[4]; BloodwarderPhysicianAI(Creature* pCreature) : CreatureAIScript(pCreature) { nrspells = 4; for(int i=0;iCastSpell(_unit, spells[3].info, spells[3].instant); CastTime(); RegisterAIUpdateEvent(_unit->GetUInt32Value(UNIT_FIELD_BASEATTACKTIME)); } void CastTime() { for(int i=0;iGetAIInterface()->setCurrentAgent(AGENT_NULL); _unit->GetAIInterface()->SetAIState(STATE_IDLE); RemoveAIUpdateEvent(); } void OnDied(Unit * mKiller) { CastTime(); RemoveAIUpdateEvent(); } void AIUpdate() { float val = sRand.rand(100.0f); SpellCast(val); } void SpellCast(float val) { if(_unit->GetCurrentSpell() == NULL && _unit->GetAIInterface()->GetNextTarget()) { float comulativeperc = 0; Unit *target = NULL; for(int i=0;iGetAIInterface()->GetNextTarget(); switch(spells[i].targettype) { case TARGET_SELF: case TARGET_VARIOUS: _unit->CastSpell(_unit, spells[i].info, spells[i].instant); break; case TARGET_ATTACKING: _unit->CastSpell(target, spells[i].info, spells[i].instant); break; case TARGET_DESTINATION: _unit->CastSpellAoF(target->GetPositionX(),target->GetPositionY(),target->GetPositionZ(), spells[i].info, spells[i].instant); break; } if (spells[i].speech != "") { _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, spells[i].speech.c_str()); _unit->PlaySoundToSet(spells[i].soundid); } m_spellcheck[i] = false; return; } if ((val > comulativeperc && val <= (comulativeperc + spells[i].perctrigger)) || !spells[i].casttime) { _unit->setAttackTimer(spells[i].attackstoptimer, false); m_spellcheck[i] = true; } comulativeperc += spells[i].perctrigger; } } } protected: int nrspells; }; // Bloodwarder SlayerAI #define CN_BLOODWARDER_SLAYER 19167 #define WHIRLWIND 13736 // DBC: 13736, 15589; #define SOLAR_STRIKE 35189 #define MELT_ARMOR_SLAYER 35231 #define CHILLING_TOUCH_SLAYER 12531 #define MORTAL_STRIKE 15708 class BloodwarderSlayerAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(BloodwarderSlayerAI); SP_AI_Spell spells[5]; bool m_spellcheck[5]; BloodwarderSlayerAI(Creature* pCreature) : CreatureAIScript(pCreature) { nrspells = 5; 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; }; // Mechanar CrusherAI #define CN_MECHANAR_CRUSHER 19231 #define DISARM 31955 // is that all? and not sure to this one :) class MechanarCrusherAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(MechanarCrusherAI); SP_AI_Spell spells[1]; bool m_spellcheck[1]; MechanarCrusherAI(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; }; // Mechanar DrillerAI #define CN_MECHANAR_DRILLER 19712 #define GLOB_OF_MACHINE_FLUID 35056 #define DRILL_ARMOR 35047 #define CRIPPLING_POISON 30981 // not sure if crippling poison and glob should be here (I mean if both should be) #define POUND 35049 class MechanarDrillerAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(MechanarDrillerAI); SP_AI_Spell spells[4]; bool m_spellcheck[4]; MechanarDrillerAI(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; }; // Mechanar TinkererAI #define CN_MECHANAR_TINKERER 19716 // recheck and add some stuff #define NETHERBOMB 35057 #define PRAYER_OF_MENDING 35092 // DBC: 35092, 33110, 35094 // SSS #define MANIACAL_CHARGE 35062 // those two are connected with each other and Idk if those shouldn't be scripted separately #define NETHER_EXPLOSION 35058 // additional coding to add health percent check, chance to cast and killing caster =/ class MechanarTinkererAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(MechanarTinkererAI); SP_AI_Spell spells[4]; bool m_spellcheck[4]; MechanarTinkererAI(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) { _unit->CastSpell(_unit, spells[3].info, spells[3].instant); CastTime(); RemoveAIUpdateEvent(); } void AIUpdate() {/* // not working yet, I must found out why you can't loot after death (hmm, sth is wrong? :P) if (_unit->GetHealthPct() < 15 && _unit->GetAIInterface()->GetNextTarget()) { uint32 val = sRand.rand(100); if (val > 0 && val < 20) { _unit->SetUInt32Value(UNIT_FIELD_HEALTH, 0); _unit->setDeathState(JUST_DIED); _unit->GetAIInterface()->HandleEvent(EVENT_UNITDIED, _unit, 0); //_unit->setDeathState(DEATH); //CALL_SCRIPT_EVENT(m_Unit, OnDied)(_unit); //_unit->GetAIInterface()->HandleEvent(EVENT_UNITDIED, _unit, misc1); //, uint32 misc1 //CastTime(); //RemoveAIUpdateEvent(); } } */ 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; }; // Mechanar WreckerAI #define CN_MECHANAR_WRECKER 19713 #define POUND_WRECKER 35049 #define GLOB_OF_MACHINE_FLUID_WRECKER 35056 #define PRAYER_OF_MENDING_WRECKER 33280 // DBC: 33280, 33110, 35093; SSS (hmm... not sure if it uses it =S) should also affect allies, not enemies class MechanarWreckerAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(MechanarWreckerAI); SP_AI_Spell spells[3]; bool m_spellcheck[3]; MechanarWreckerAI(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; }; // Raging FlamesAI #define CN_RAGING_FLAMES 20481 #define RAGING_FLAMES 35278 // DBC: 35278; #define INFERNO 35268 // DBC: 35268, 35283; // his skills needs additional core support I think class RagingFlamesAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(RagingFlamesAI); SP_AI_Spell spells[2]; bool m_spellcheck[2]; RagingFlamesAI(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; }; // Sunseeker AstromageAI #define CN_SUNSEEKER_ASTROMAGE 19168 #define SCORCH 17195 #define SOLARBURN 35267 #define FIRE_SHIELD 35265 // DBC: 35266, 35265 #define ETHEREAL_TELEPORT_ASTROMAGE 34427 class SunseekerAstromageAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(SunseekerAstromageAI); SP_AI_Spell spells[4]; bool m_spellcheck[4]; SunseekerAstromageAI(Creature* pCreature) : CreatureAIScript(pCreature) { nrspells = 4; for(int i=0;iCastSpell(_unit, spells[3].info, spells[3].instant); CastTime(); RegisterAIUpdateEvent(_unit->GetUInt32Value(UNIT_FIELD_BASEATTACKTIME)); } void CastTime() { for(int i=0;iGetAIInterface()->setCurrentAgent(AGENT_NULL); _unit->GetAIInterface()->SetAIState(STATE_IDLE); RemoveAIUpdateEvent(); } void OnDied(Unit * mKiller) { CastTime(); RemoveAIUpdateEvent(); } void AIUpdate() { float val = sRand.rand(100.0f); SpellCast(val); } void SpellCast(float val) { if(_unit->GetCurrentSpell() == NULL && _unit->GetAIInterface()->GetNextTarget()) { float comulativeperc = 0; Unit *target = NULL; for(int i=0;iGetAIInterface()->GetNextTarget(); switch(spells[i].targettype) { case TARGET_SELF: case TARGET_VARIOUS: _unit->CastSpell(_unit, spells[i].info, spells[i].instant); break; case TARGET_ATTACKING: _unit->CastSpell(target, spells[i].info, spells[i].instant); break; case TARGET_DESTINATION: _unit->CastSpellAoF(target->GetPositionX(),target->GetPositionY(),target->GetPositionZ(), spells[i].info, spells[i].instant); break; } if (spells[i].speech != "") { _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, spells[i].speech.c_str()); _unit->PlaySoundToSet(spells[i].soundid); } m_spellcheck[i] = false; return; } if ((val > comulativeperc && val <= (comulativeperc + spells[i].perctrigger)) || !spells[i].casttime) { _unit->setAttackTimer(spells[i].attackstoptimer, false); m_spellcheck[i] = true; } comulativeperc += spells[i].perctrigger; } } } protected: int nrspells; }; // Sunseeker EngineerAI #define CN_SUNSEEKER_ENGINEER 20988 #define SUPER_SHRINK_RAY 36341 #define DEATH_RAY 36345 #define GROWTH_RAY 36346 // doesn't work, even when used by player =( #define ETHEREAL_TELEPORT_ENGINEER 34427 class SunseekerEngineerAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(SunseekerEngineerAI); SP_AI_Spell spells[4]; bool m_spellcheck[4]; SunseekerEngineerAI(Creature* pCreature) : CreatureAIScript(pCreature) { nrspells = 4; for(int i=0;iCastSpell(_unit, spells[3].info, spells[3].instant); CastTime(); RegisterAIUpdateEvent(_unit->GetUInt32Value(UNIT_FIELD_BASEATTACKTIME)); } void CastTime() { for(int i=0;iGetAIInterface()->setCurrentAgent(AGENT_NULL); _unit->GetAIInterface()->SetAIState(STATE_IDLE); RemoveAIUpdateEvent(); } void OnDied(Unit * mKiller) { CastTime(); RemoveAIUpdateEvent(); } void AIUpdate() { float val = sRand.rand(100.0f); SpellCast(val); } void SpellCast(float val) { if(_unit->GetCurrentSpell() == NULL && _unit->GetAIInterface()->GetNextTarget()) { float comulativeperc = 0; Unit *target = NULL; for(int i=0;iGetAIInterface()->GetNextTarget(); switch(spells[i].targettype) { case TARGET_SELF: case TARGET_VARIOUS: _unit->CastSpell(_unit, spells[i].info, spells[i].instant); break; case TARGET_ATTACKING: _unit->CastSpell(target, spells[i].info, spells[i].instant); break; case TARGET_DESTINATION: _unit->CastSpellAoF(target->GetPositionX(),target->GetPositionY(),target->GetPositionZ(), spells[i].info, spells[i].instant); break; } if (spells[i].speech != "") { _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, spells[i].speech.c_str()); _unit->PlaySoundToSet(spells[i].soundid); } m_spellcheck[i] = false; return; } if ((val > comulativeperc && val <= (comulativeperc + spells[i].perctrigger)) || !spells[i].casttime) { _unit->setAttackTimer(spells[i].attackstoptimer, false); m_spellcheck[i] = true; } comulativeperc += spells[i].perctrigger; } } } protected: int nrspells; }; // Sunseeker NetherbinderAI #define CN_SUNSEEKER_NETHERBINDER 20059 #define ARCANE_NOVA 35261 #define STARFIRE 35243 #define SUMMON_ARCANE_GOLEM1 35251 // DBC: 35251, 35260; Guardian, so won't work now #define SUMMON_ARCANE_GOLEM2 35260 #define DISPEL_MAGIC 23859 // no idea about this one //#define SEED_OF_CORRUPTION 37826 class SunseekerNetherbinderAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(SunseekerNetherbinderAI); SP_AI_Spell spells[5]; bool m_spellcheck[5]; SunseekerNetherbinderAI(Creature* pCreature) : CreatureAIScript(pCreature) { nrspells = 5; 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; }; // Tempest-Forge DestroyerAI #define CN_TEMPEST_FORGE_DESTROYER 19735 #define KNOCKDOWN 35783 #define CHARGED_FIST 36582 // DBC: 36582, 36583; doesn't work anyway at all (lack of core support?) class TempestForgeDestroyerAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(TempestForgeDestroyerAI); SP_AI_Spell spells[2]; bool m_spellcheck[2]; TempestForgeDestroyerAI(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; }; // Tempest-Forge PatrollerAI #define CN_TEMPEST_FORGE_PATROLLER 19166 #define CHARGED_ARCANE_MISSILE 35012 #define KNOCKDOWN_PATROLLER 35011 class TempestForgePatrollerAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(TempestForgePatrollerAI); SP_AI_Spell spells[2]; bool m_spellcheck[2]; TempestForgePatrollerAI(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; }; /**************************/ /* */ /* Boss AIs */ /* */ /**************************/ // Gatewatcher Gyro-Kill AI #define CN_GATEWATCHER_GYRO_KILL 19218 #define SAW_BLADE 35318 #define SHADOW_POWER_GKILL 35322 #define STEAM_OF_MACHINE_FLUID_GKILL 35311 class GatewatcherGyroKillAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(GatewatcherGyroKillAI); SP_AI_Spell spells[3]; bool m_spellcheck[3]; GatewatcherGyroKillAI(Creature* pCreature) : CreatureAIScript(pCreature) { nrspells = 3; for(int i=0;iGetUInt32Value(UNIT_FIELD_BASEATTACKTIME)); _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, "I predict a painful death."); _unit->PlaySoundToSet(11101); } void CastTime() { for(int i=0;iGetAIInterface()->setCurrentAgent(AGENT_NULL); _unit->GetAIInterface()->SetAIState(STATE_IDLE); RemoveAIUpdateEvent(); } void OnTargetDied(Unit* mTarget) { if (_unit->GetHealthPct() > 0) // Hack to prevent double yelling (OnDied and OnTargetDied when creature is dying) { int RandomSpeach; sRand.randInt(1000); RandomSpeach=rand()%2; switch (RandomSpeach) { case 0: _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, "Your strategy was flat!"); // flat? _unit->PlaySoundToSet(11102); break; case 1: _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, "Yes, the only magical outcome!"); // magical outcome? _unit->PlaySoundToSet(11103); break; } } } void OnDied(Unit * mKiller) { CastTime(); RemoveAIUpdateEvent(); _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, "An unforseen... contingency."); _unit->PlaySoundToSet(11106); } void AIUpdate() { float val = sRand.rand(100.0f); SpellCast(val); } void SawBladesSound() { int RandomSawBlades; RandomSawBlades=rand()%30; switch (RandomSawBlades) { case 0: _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, "Measure twice; cut once."); _unit->PlaySoundToSet(11104); break; case 1: _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, "If my devision is correct, you should be quiet dead!"); // needs checks _unit->PlaySoundToSet(11105); break; } } void SpellCast(float val) { if(_unit->GetCurrentSpell() == NULL && _unit->GetAIInterface()->GetNextTarget()) { float comulativeperc = 0; Unit *target = NULL; for(int i=0;iGetAIInterface()->GetNextTarget(); switch(spells[i].targettype) { case TARGET_SELF: case TARGET_VARIOUS: _unit->CastSpell(_unit, spells[i].info, spells[i].instant); break; case TARGET_ATTACKING: _unit->CastSpell(target, spells[i].info, spells[i].instant); break; case TARGET_DESTINATION: _unit->CastSpellAoF(target->GetPositionX(),target->GetPositionY(),target->GetPositionZ(), spells[i].info, spells[i].instant); break; } if (m_spellcheck[0] == true) SawBladesSound(); 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; }; // Gatewatcher Iron-Hand AI #define CN_GATEWATCHER_IRON_HAND 19710 #define JACK_HAMMER 35327 // DBC: 35327, 35330 #define HAMMER_PUNCH 35326 #define STREAM_OF_MACHINE_FLUID_IHAND 35311 #define SHADOW_POWER_IHAND 35322 class GatewatcherIronHandAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(GatewatcherIronHandAI); SP_AI_Spell spells[4]; bool m_spellcheck[4]; GatewatcherIronHandAI(Creature* pCreature) : CreatureAIScript(pCreature) { nrspells = 4; for(int i=0;iGetUInt32Value(UNIT_FIELD_BASEATTACKTIME)); _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, "You have approximately 5 seconds to live!"); // needs checks! _unit->PlaySoundToSet(11109); } void CastTime() { for(int i=0;iGetAIInterface()->setCurrentAgent(AGENT_NULL); _unit->GetAIInterface()->SetAIState(STATE_IDLE); RemoveAIUpdateEvent(); } void OnTargetDied(Unit* mTarget) { if (_unit->GetHealthPct() > 0) // Hack to prevent double yelling (OnDied and OnTargetDied when creature is dying) { int RandomSpeach; sRand.randInt(1000); RandomSpeach=rand()%2; switch (RandomSpeach) { case 0: _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, "Afford gun conclusion!"); _unit->PlaySoundToSet(11110); break; case 1: _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, "The processing will continue a schedule!"); _unit->PlaySoundToSet(11111); break; } } } void OnDied(Unit * mKiller) { CastTime(); RemoveAIUpdateEvent(); _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, "My calculations... did not..."); // ?? _unit->PlaySoundToSet(11114); } void AIUpdate() { float val = sRand.rand(100.0f); SpellCast(val); } void HammerSound() { uint32 RandomHammer; RandomHammer=rand()%10; switch (RandomHammer) { case 0: { _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, "With the precise "); // !! _unit->PlaySoundToSet(11112); }break; case 1: { _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, "Low tech yet quiet effective!"); // this one too =/ _unit->PlaySoundToSet(11113); }break; } } void SpellCast(float val) { if(_unit->GetCurrentSpell() == NULL && _unit->GetAIInterface()->GetNextTarget()) { float comulativeperc = 0; Unit *target = NULL; for(int i=0;iGetAIInterface()->GetNextTarget(); switch(spells[i].targettype) { case TARGET_SELF: case TARGET_VARIOUS: _unit->CastSpell(_unit, spells[i].info, spells[i].instant); break; case TARGET_ATTACKING: _unit->CastSpell(target, spells[i].info, spells[i].instant); break; case TARGET_DESTINATION: _unit->CastSpellAoF(target->GetPositionX(),target->GetPositionY(),target->GetPositionZ(), spells[i].info, spells[i].instant); break; } if (m_spellcheck[1] == true) { HammerSound(); } 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; }; // Mechano-Lord Capacitus AI #define CN_MECHANO_LORD_CAPACITUS 19219 #define HEAD_CRACK 35161 #define REFLECTIVE_DAMAGE_SHIELD 35159 #define REFLECTIVE_MAGIC_SHIELD 35158 #define SEED_OF_CORRUPTION 37826 // SSS (server side script) (is it really used?) /*#define NETHER_CHARGE 34303 #define NETHER_CHARGE_PASSIVE 35150 // SSS #define NETHER_CHARGE_PULSE 35151 // SSS #define NETHER_CHARGE_TIMER 37670 #define NETHER_DETONATION 35152 // Spell from Timer // Note: All for bombs :O*/ class MechanoLordCapacitusAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(MechanoLordCapacitusAI); SP_AI_Spell spells[4]; bool m_spellcheck[4]; MechanoLordCapacitusAI(Creature* pCreature) : CreatureAIScript(pCreature) { nrspells = 4; for(int i=0;iGetUInt32Value(UNIT_FIELD_BASEATTACKTIME)); _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, "You should split while you can."); _unit->PlaySoundToSet(11162); } void CastTime() { for(int i=0;iGetAIInterface()->setCurrentAgent(AGENT_NULL); _unit->GetAIInterface()->SetAIState(STATE_IDLE); RemoveAIUpdateEvent(); } void OnTargetDied(Unit* mTarget) { if (_unit->GetHealthPct() > 0) // Hack to prevent double yelling (OnDied and OnTargetDied when creature is dying) { int RandomSpeach; sRand.randInt(1000); RandomSpeach=rand()%2; switch (RandomSpeach) { case 0: _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, "Can't say I didn't warn you!"); // checks here _unit->PlaySoundToSet(11163); break; case 1: _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, "Damn, I'm good!"); _unit->PlaySoundToSet(11164); break; } } } void OnDied(Unit * mKiller) { CastTime(); RemoveAIUpdateEvent(); _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, "Bully!"); _unit->PlaySoundToSet(11167); } 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; }; // Nethermancer Sepethrea AI #define CN_NETHERMANCER_SEPETHREA 19221 #define SUMMON_RAGIN_FLAMES 35275 // must add despawning after death! #define FROST_ATTACK 35263 #define ARCANE_BLAST 35314 #define DRAGONS_BREATH 35250 //#define KNOCKBACK 37317 // not sure to this one! class NethermancerSepethreaAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(NethermancerSepethreaAI); SP_AI_Spell spells[4]; bool m_spellcheck[4]; NethermancerSepethreaAI(Creature* pCreature) : CreatureAIScript(pCreature) { SummonTimer = 4; nrspells = 4; for(int i=0;iGetUInt32Value(UNIT_FIELD_BASEATTACKTIME)); //_unit->CastSpell(_unit, spells[0].info, spells[0].instant); _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, "Don't value your life very much, do you?"); _unit->PlaySoundToSet(11186); } void CastTime() { for(int i=0;iGetAIInterface()->setCurrentAgent(AGENT_NULL); _unit->GetAIInterface()->SetAIState(STATE_IDLE); RemoveAIUpdateEvent(); } void OnTargetDied(Unit* mTarget) { if (_unit->GetHealthPct() > 0) // Hack to prevent double yelling (OnDied and OnTargetDied when creature is dying) { int RandomSpeach; sRand.randInt(1000); RandomSpeach=rand()%2; switch (RandomSpeach) { case 0: _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, "And don't come back!"); // checks here _unit->PlaySoundToSet(11187); break; case 1: _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, ""); // ? ? ! ! _unit->PlaySoundToSet(11188); break; } } } void OnDied(Unit * mKiller) { SummonTimer = 4; CastTime(); RemoveAIUpdateEvent(); _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, "Anu... bala belore...alon."); _unit->PlaySoundToSet(11192); } void AIUpdate() { SummonTimer--; if (!SummonTimer) { _unit->CastSpell(_unit, spells[0].info, spells[0].instant); _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, "I am not alone!"); // checks! _unit->PlaySoundToSet(11191); } float val = sRand.rand(100.0f); SpellCast(val); } void DragonsBreathSound() { uint32 RandomDragonsBreath; RandomDragonsBreath=rand()%10; switch (RandomDragonsBreath) { case 0: { _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, "Think you can take the heat?"); _unit->PlaySoundToSet(11189); }break; case 1: { _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, "Anar'endal dracon!"); _unit->PlaySoundToSet(11190); }break; } } void SpellCast(float val) { if(_unit->GetCurrentSpell() == NULL && _unit->GetAIInterface()->GetNextTarget()) { float comulativeperc = 0; Unit *target = NULL; for(int i=0;iGetAIInterface()->GetNextTarget(); switch(spells[i].targettype) { case TARGET_SELF: case TARGET_VARIOUS: _unit->CastSpell(_unit, spells[i].info, spells[i].instant); break; case TARGET_ATTACKING: _unit->CastSpell(target, spells[i].info, spells[i].instant); break; case TARGET_DESTINATION: _unit->CastSpellAoF(target->GetPositionX(),target->GetPositionY(),target->GetPositionZ(), spells[i].info, spells[i].instant); break; } if (m_spellcheck[3] == true) DragonsBreathSound(); 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 SummonTimer; int nrspells; }; // Pathaleon the Calculator AI #define CN_PATHALEON_THE_CALCULATOR 19220 #define MANA_TRAP 36021 // I am not sure to any of those ids =( #define DOMINATION 36866 #define SILENCE 38491 #define SUMMON_NETHER_WRAITH1 35285 // not the best way, but blizzlike :) (but they don't work for now =() #define SUMMON_NETHER_WRAITH2 35286 #define SUMMON_NETHER_WRAITH3 35287 #define SUMMON_NETHER_WRAITH4 35288 // hmm... he switches weapons and there is sound for it, but I must know when he does that, how it looks like etc. // before adding weapon switching =/ (Sound: 11199; speech: "I prefer to be hands-on...";) class PathaleonTheCalculatorAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(PathaleonTheCalculatorAI); SP_AI_Spell spells[7]; bool m_spellcheck[7]; PathaleonTheCalculatorAI(Creature* pCreature) : CreatureAIScript(pCreature) { SummonTimer=rand()%16+30; // 30 - 45 sec nrspells = 7; for(int i=0;iGetUInt32Value(UNIT_FIELD_BASEATTACKTIME)); _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, "We are on a strict timetable. You will not interfere!"); _unit->PlaySoundToSet(11193); } void CastTime() { for(int i=0;iGetAIInterface()->setCurrentAgent(AGENT_NULL); _unit->GetAIInterface()->SetAIState(STATE_IDLE); RemoveAIUpdateEvent(); } void OnTargetDied(Unit* mTarget) { if (_unit->GetHealthPct() > 0) // Hack to prevent double yelling (OnDied and OnTargetDied when creature is dying) { int RandomSpeach; sRand.randInt(1000); RandomSpeach=rand()%2; switch (RandomSpeach) { case 0: _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, "A minor inconvenience."); _unit->PlaySoundToSet(11194); break; case 1: _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, "Looks like you lose."); _unit->PlaySoundToSet(11195); break; } } } void OnDied(Unit * mKiller) { SummonTimer=rand()%16+30; CastTime(); RemoveAIUpdateEvent(); _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, "The project will... continue."); _unit->PlaySoundToSet(11200); } void AIUpdate() { SummonTimer--; if (!SummonTimer) { _unit->CastSpell(_unit, spells[3].info, spells[3].instant); _unit->CastSpell(_unit, spells[4].info, spells[4].instant); _unit->CastSpell(_unit, spells[5].info, spells[5].instant); _unit->CastSpell(_unit, spells[6].info, spells[6].instant); SummonTimer=rand()%16+30; // 30 - 45 _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, "Time to supplement my work force."); _unit->PlaySoundToSet(11196);; } float val = sRand.rand(100.0f); SpellCast(val); } void DominationSound() { int RandomDomination; RandomDomination=rand()%2; switch (RandomDomination) { case 0: _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, "I'm looking for a team player..."); _unit->PlaySoundToSet(11197); break; case 1: _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, "You work for me now!"); _unit->PlaySoundToSet(11198); break; } } void SpellCast(float val) { if(_unit->GetCurrentSpell() == NULL && _unit->GetAIInterface()->GetNextTarget()) { float comulativeperc = 0; Unit *target = NULL; for(int i=0;iGetAIInterface()->GetNextTarget(); switch(spells[i].targettype) { case TARGET_SELF: case TARGET_VARIOUS: _unit->CastSpell(_unit, spells[i].info, spells[i].instant); break; case TARGET_ATTACKING: _unit->CastSpell(target, spells[i].info, spells[i].instant); break; case TARGET_DESTINATION: _unit->CastSpellAoF(target->GetPositionX(),target->GetPositionY(),target->GetPositionZ(), spells[i].info, spells[i].instant); break; } if (m_spellcheck[1] == true) { DominationSound(); } 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 SummonTimer; int nrspells; }; void SetupTheMechanar(ScriptMgr * mgr) { mgr->register_creature_script(CN_ARCANE_SERVANT, &ArcaneServantAI::Create); mgr->register_creature_script(CN_BLOODWARDER_CENTURION, &BloodwarderCenturionAI::Create); mgr->register_creature_script(CN_BLOODWARDER_PHYSICIAN, &BloodwarderPhysicianAI::Create); mgr->register_creature_script(CN_BLOODWARDER_SLAYER, &BloodwarderSlayerAI::Create); mgr->register_creature_script(CN_MECHANAR_CRUSHER, &MechanarCrusherAI::Create); mgr->register_creature_script(CN_MECHANAR_DRILLER, &MechanarDrillerAI::Create); mgr->register_creature_script(CN_MECHANAR_TINKERER, &MechanarTinkererAI::Create); mgr->register_creature_script(CN_MECHANAR_WRECKER, &MechanarWreckerAI::Create); mgr->register_creature_script(CN_RAGING_FLAMES, &RagingFlamesAI::Create); mgr->register_creature_script(CN_SUNSEEKER_ASTROMAGE, &SunseekerAstromageAI::Create); mgr->register_creature_script(CN_SUNSEEKER_ENGINEER, &SunseekerEngineerAI::Create); mgr->register_creature_script(CN_SUNSEEKER_NETHERBINDER, &SunseekerNetherbinderAI::Create); mgr->register_creature_script(CN_TEMPEST_FORGE_DESTROYER, &TempestForgeDestroyerAI::Create); mgr->register_creature_script(CN_TEMPEST_FORGE_PATROLLER, &TempestForgePatrollerAI::Create); mgr->register_creature_script(CN_GATEWATCHER_GYRO_KILL, &GatewatcherGyroKillAI::Create); mgr->register_creature_script(CN_GATEWATCHER_IRON_HAND, &GatewatcherIronHandAI::Create); mgr->register_creature_script(CN_MECHANO_LORD_CAPACITUS, &MechanoLordCapacitusAI::Create); mgr->register_creature_script(CN_NETHERMANCER_SEPETHREA, &NethermancerSepethreaAI::Create); mgr->register_creature_script(CN_PATHALEON_THE_CALCULATOR, &PathaleonTheCalculatorAI::Create); } // Data needed for: Nether Wraith, Mechanar Crusher (maybe not enough?)