#include "StdAfx.h" #include "Setup.h" /************************************************************************/ /* Instance_ManaTombs.cpp Script */ /************************************************************************/ // Ethereal Darkcaster AI #define CN_ETHEREAL_DARKCASTER 18331 #define MANA_BURN 29310 // can be wrong #define SHADOW_WORD_PAIN 41355 class ETHEREALDARKCASTERAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(ETHEREALDARKCASTERAI); SP_AI_Spell spells[2]; bool m_spellcheck[2]; ETHEREALDARKCASTERAI(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; }; // Ethereal Priest AI #define CN_ETHEREAL_PRIEST 18317 #define HEAL 39378 #define POWER_WORD_SHIELD 29408 // no idea if this is correct one [also can be: 41373 or other] class ETHEREALPRIESTAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(ETHEREALPRIESTAI); SP_AI_Spell spells[2]; bool m_spellcheck[2]; ETHEREALPRIESTAI(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; }; // Ethereal Theurgist AI #define CN_ETHEREAL_THEURGIST 18315 #define POLYMORPH 36840 // so many poly to choose from #define BLAST_WAVE 30092 // not sure, also can be: 39001 (maybe too powerful?), 36278, 30600, 25049 (eventually) class ETHEREALTHEURGISTAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(ETHEREALTHEURGISTAI); SP_AI_Spell spells[2]; bool m_spellcheck[2]; ETHEREALTHEURGISTAI(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; }; // Ethereal Sorcerer AI #define CN_ETHEREAL_SORCERER 18313 #define ARCANE_MISSILES 29956 //29955 can be also: 39414 (too much dmg?), 29956 (just arcane missiles without add. effects) // doesnt'w work for now class ETHEREALSORCERERAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(ETHEREALSORCERERAI); SP_AI_Spell spells[1]; bool m_spellcheck[1]; ETHEREALSORCERERAI(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; }; // Nexus Stalker AI #define CN_NEXUS_STALKER 18314 #define GOUGE 29425 // not sure, maybe should be : 36862, #define POISON 34969 // no idea if this is correct one #define STEALTH 32615 // Can be also: 31621, 31526, 30991 and others // maybe I should set it's proc chance to 0.0 and add spell casting OnCombatStart... class NEXUSSTALKERAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(NEXUSSTALKERAI); SP_AI_Spell spells[3]; bool m_spellcheck[3]; NEXUSSTALKERAI(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; }; // Nexus Terror AI #define CN_NEXUS_TERROR 19307 #define PSYCHIC_SCREAM 34322 class NEXUSTERRORAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(NEXUSTERRORAI); SP_AI_Spell spells[1]; bool m_spellcheck[1]; NEXUSTERRORAI(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; }; // Mana Leech AI #define CN_MANA_LEECH 19306 #define ARCANE_EXPLOSION 39348 // not sure about id class MANALEECHAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(MANALEECHAI); SP_AI_Spell spells[1]; bool m_spellcheck[1]; MANALEECHAI(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) { _unit->CastSpell(_unit, spells[0].info, spells[0].instant); 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; }; // Ethereal Spellbinder AI #define CN_ETHEREAL_SPELLBINDER 18312 // couldn't find accurate source of it's spells #define CORRUPTION 30938 #define IMMOLATE 38806 // Not sure to any id/spell, because of lack of information source #define UNSTABLE_AFFLICTION 35183 // if it casts this spell it can also be: 34439, 30938 #define SUMMON_ETHEREAL_WRAITH 32316 // added, but still more core support needed // On WoWWiki is description that Spellbinder summons are Mana Wraiths, but there is no // spell connected with such creature. class ETHEREALSPELLBINDERAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(ETHEREALSPELLBINDERAI); SP_AI_Spell spells[4]; bool m_spellcheck[4]; ETHEREALSPELLBINDERAI(Creature* pCreature) : CreatureAIScript(pCreature) { nrspells = 4; 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; }; // Ethereal Wraith AI #define CN_ETHEREAL_WRAITH 18394 #define SHADOW_BOLT_VOLLEY 36736 // no idea if this is correct spell, but description seems to match with this what should be used // maybe normal shadow bolt like those: 29927, 30055 should be used class ETHEREALWRAITHAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(ETHEREALWRAITHAI); SP_AI_Spell spells[1]; bool m_spellcheck[1]; ETHEREALWRAITHAI(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; }; /*****************************/ /* */ /* Boss AIs */ /* */ /*****************************/ // Needs to add Yor in a future // PandemoniusAI #define CN_PANDEMONIUS 18341 #define VOID_BLAST 32325 //38760 #define DARK_SHELL 32358 //38759 class PANDEMONIUSAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(PANDEMONIUSAI); SP_AI_Spell spells[2]; bool m_spellcheck[2]; PANDEMONIUSAI(Creature* pCreature) : CreatureAIScript(pCreature) { nrspells = 2; for(int i=0;iSendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, "All will feed all your soul!"); _unit->PlaySoundToSet(10561); break; case 1: _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, "You fool life!"); _unit->PlaySoundToSet(10562); break; case 2: _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, "Do not resist!"); _unit->PlaySoundToSet(10563); 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, I am powered!"); // powered, emopowered? _unit->PlaySoundToSet(10564); break; case 1: _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, "More, I must have more!"); _unit->PlaySoundToSet(10565); 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, "Do the void... once... more."); _unit->PlaySoundToSet(10566); 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(spells[i].soundid) { _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, spells[i].speech.c_str()); _unit->PlaySoundToSet(spells[i].soundid); } } 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; }; // TavarokAI #define CN_TAVAROK 18343 #define EARTHQUAKE 33919 // affects also caster if it is close enough (and does it really works?) #define CRYSTAL_PRISON 32361 // deals 10 dmg instead of 10% player hp - core problem #define ARCING_SMASH 39144 // probably wrong id (maybe: 40457 ?) // Strange... I couldn't find any sounds for this boss in DBC and in extracted // from client sounds O_O class TAVAROKAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(TAVAROKAI); SP_AI_Spell spells[3]; bool m_spellcheck[3]; TAVAROKAI(Creature* pCreature) : CreatureAIScript(pCreature) { nrspells = 3; for(int i=0;iGetUInt32Value(UNIT_FIELD_BASEATTACKTIME)); } void OnTargetDied(Unit* mTarget) // left to keep it easy to add needed data. { } 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; } 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; }; // Nexus-Prince ShaffarAI #define CN_NEXUS_PRINCE_SHAFFAR 18344 #define FIREBALL 37329 #define FROSTBOLT 40429 // Also can be: 40430 or 32370 #define FROST_NOVA 29849 // Also worth to try: 30094 #define BLINK 36109 // 36109 - forward 20yard, 36718 - 5yard, behind target, 29883 - random target // still doesn't tp boss #define SUMMON_ETEREAL_BECON 32371 // probably lack of core support for this, but I will add it anyway // TO DO: Becons must spawn after each 10 sec support units (find way to add // them to friend list too). Still don't know how they exactly work. class NEXUSPRINCESHAFFARAI : public CreatureAIScript { public: ADD_CREATURE_FACTORY_FUNCTION(NEXUSPRINCESHAFFARAI); SP_AI_Spell spells[5]; bool m_spellcheck[5]; NEXUSPRINCESHAFFARAI(Creature* pCreature) : CreatureAIScript(pCreature) { SUMMON_ETEREAL_BECON_Cooldown = 10; nrspells = 5; for(int i=0;iSendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, "Ah, we have not been properly introduced!"); _unit->PlaySoundToSet(10541); break; case 1: _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, "An epic battle! How exciting."); _unit->PlaySoundToSet(10542); break; case 2: _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, "I have longed for a good adventure!"); _unit->PlaySoundToSet(10543); 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, "And now, we part company."); // part company? _unit->PlaySoundToSet(10544); break; case 1: _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, "It has been... entertaining."); _unit->PlaySoundToSet(10545); break; } } } void OnCombatStop(Unit *mTarget) { SUMMON_ETEREAL_BECON_Cooldown = 10; _unit->GetAIInterface()->setCurrentAgent(AGENT_NULL); _unit->GetAIInterface()->SetAIState(STATE_IDLE); RemoveAIUpdateEvent(); } void OnDied(Unit * mKiller) { SUMMON_ETEREAL_BECON_Cooldown = 10; _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, "I must bid you... Farewell."); // I don't think it's correct. _unit->PlaySoundToSet(10546); RemoveAIUpdateEvent(); } void AIUpdate() { SUMMON_ETEREAL_BECON_Cooldown--; if (!SUMMON_ETEREAL_BECON_Cooldown) { _unit->CastSpell(_unit, spells[4].info, spells[4].instant); // I will add it as a loop someday ;) _unit->CastSpell(_unit, spells[4].info, spells[4].instant); _unit->CastSpell(_unit, spells[4].info, spells[4].instant); SUMMON_ETEREAL_BECON_Cooldown = 10; } 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 SUMMON_ETEREAL_BECON_Cooldown; int nrspells; }; void SetupManaTombs(ScriptMgr * mgr) { mgr->register_creature_script(CN_ETHEREAL_DARKCASTER, ÐEREALDARKCASTERAI::Create); mgr->register_creature_script(CN_ETHEREAL_PRIEST, ÐEREALPRIESTAI::Create); mgr->register_creature_script(CN_ETHEREAL_SPELLBINDER, ÐEREALSPELLBINDERAI::Create); mgr->register_creature_script(CN_ETHEREAL_THEURGIST, ÐEREALTHEURGISTAI::Create); mgr->register_creature_script(CN_ETHEREAL_SORCERER, ÐEREALSORCERERAI::Create); mgr->register_creature_script(CN_ETHEREAL_WRAITH, ÐEREALWRAITHAI::Create); mgr->register_creature_script(CN_NEXUS_STALKER, &NEXUSSTALKERAI::Create); mgr->register_creature_script(CN_NEXUS_TERROR, &NEXUSTERRORAI::Create); mgr->register_creature_script(CN_MANA_LEECH, &MANALEECHAI::Create); mgr->register_creature_script(CN_PANDEMONIUS, &PANDEMONIUSAI::Create); mgr->register_creature_script(CN_TAVAROK, &TAVAROKAI::Create); mgr->register_creature_script(CN_NEXUS_PRINCE_SHAFFAR, &NEXUSPRINCESHAFFARAI::Create); }