rendered paste body#include "../../../sc_defines.h"#include "../../../creature/simple_ai.h"#define SPELL_SPOUT 37433#define SPELL_SPOUT_VISUAL 37431#define SPELL_GEYSER 37478#define SPELL_WHIRL 37660#define SPELL_WATERBOLT 37138#define SPELL_SUBMERGE 37550#define EMOTE_SPOUT "takes a deep breath."#define MOBID_COILFANG_GUARDIAN 21873#define MOBID_COILFANG_AMBUSHER 21865#define AMBUSHER_X1 -18#define AMBUSHER_Y1 -459.823914#define AMBUSHER_Z1 -21#define AMBUSHER_X2 -17#define AMBUSHER_Y2 -465#define AMBUSHER_Z2 -21#define AMBUSHER_X3 55.366653#define AMBUSHER_Y3 -486.836060#define AMBUSHER_Z3 -22#define AMBUSHER_X4 69.597980#define AMBUSHER_Y4 -486.433044#define AMBUSHER_Z4 -21#define AMBUSHER_X5 90#define AMBUSHER_Y5 -364#define AMBUSHER_Z5 -21#define AMBUSHER_X6 86#define AMBUSHER_Y6 -360#define AMBUSHER_Z6 -21#define GUARDIAN_X1 25.4#define GUARDIAN_Y1 -373.88#define GUARDIAN_Z1 -21#define GUARDIAN_X2 -5#define GUARDIAN_Y2 -427#define GUARDIAN_Z2 -22#define GUARDIAN_X3 39#define GUARDIAN_Y3 -463#define GUARDIAN_Z3 -21#define MOVE_AMBUSHER_X1 2.855381#define MOVE_AMBUSHER_Y1 -459.823914#define MOVE_AMBUSHER_Z1 -19.182686#define MOVE_AMBUSHER_X2 12.4#define MOVE_AMBUSHER_Y2 -466.042267#define MOVE_AMBUSHER_Z2 -19.182686#define MOVE_AMBUSHER_X3 51.366653#define MOVE_AMBUSHER_Y3 -460.836060#define MOVE_AMBUSHER_Z3 -19.182686#define MOVE_AMBUSHER_X4 62.597980#define MOVE_AMBUSHER_Y4 -457.433044#define MOVE_AMBUSHER_Z4 -19.182686#define MOVE_AMBUSHER_X5 77.607452#define MOVE_AMBUSHER_Y5 -384.302765#define MOVE_AMBUSHER_Z5 -19.182686#define MOVE_AMBUSHER_X6 63.897900#define MOVE_AMBUSHER_Y6 -378.984924#define MOVE_AMBUSHER_Z6 -19.182686#define MOVE_GUARDIAN_X1 34.447250#define MOVE_GUARDIAN_Y1 -387.333618#define MOVE_GUARDIAN_Z1 -19.182686#define MOVE_GUARDIAN_X2 14.388216#define MOVE_GUARDIAN_Y2 -423.468018#define MOVE_GUARDIAN_Z2 -19.625271#define MOVE_GUARDIAN_X3 42.471519#define MOVE_GUARDIAN_Y3 -445.115295#define MOVE_GUARDIAN_Z3 -19.769423//Ambusher spells#define SPELL_MULTISHOT 30990//Guardian spells#define SPELL_ARCINGSMASH 38761 // Wrong SpellId. Can't find the right one.#define SPELL_HAMSTRING 26211#define PI 3.1415struct MANGOS_DLL_DECL boss_the_lurker_belowAI : public ScriptedAI{ boss_the_lurker_belowAI(Creature *c) : ScriptedAI(c) {EnterEvadeMode();} int SpoutTimer; int PhaseTimer; int GeyserTimer; int WaterboltTimer; int WhirlTimer; int OrientationUpdated; float SpoutAngle; bool Spawned; bool Submerged; bool Clockwise; Creature* Summoned; void EnterEvadeMode() { m_creature->RemoveAllAuras(); m_creature->DeleteThreatList(); m_creature->CombatStop(true); DoGoHome(); m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE); WhirlTimer = rand()%5000 + 15000; PhaseTimer = 120000; SpoutTimer = 45000; OrientationUpdated = -1; GeyserTimer = rand()%5000 + 15000; WaterboltTimer = 3000; Submerged = false; Spawned = false; Clockwise = true; SpoutAngle = 0; m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_DISARM, true); m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_FEAR, true); m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_POLYMORPH, true); m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_INTERRUPTED, true); m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_SILENCE, true); } void MoveInLineOfSight(Unit *who) { if (!who) return; if (who->isTargetableForAttack() && who->isInAccessablePlaceFor(m_creature) && m_creature->IsHostileTo(who)) { float attackRadius = m_creature->GetAttackDistance(who); if (m_creature->IsWithinDistInMap(who, attackRadius) && m_creature->GetDistanceZ(who) <= CREATURE_Z_ATTACK_RANGE && m_creature->IsWithinLOSInMap(who)) { if(who->HasStealthAura()) who->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH); m_creature->AddThreat(who,1.0f); DoStartRangedAttack(who); } } } void AttackStart(Unit *who) { if (!who || m_creature->getVictim()) return; if (who->isTargetableForAttack() && who->isInAccessablePlaceFor(m_creature) && m_creature->IsHostileTo(who)) { float attackRadius = m_creature->GetAttackDistance(who); if (m_creature->IsWithinDistInMap(who, attackRadius) && m_creature->GetDistanceZ(who) <= CREATURE_Z_ATTACK_RANGE && m_creature->IsWithinLOSInMap(who)) { if(who->HasStealthAura()) who->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH); DoStartRangedAttack(who); } } } void UpdateAI(const uint32 diff) { if( m_creature->getVictim() && m_creature->isAlive()) { if(!Submerged) { if(SpoutTimer < diff) { if (OrientationUpdated == -1) { OrientationUpdated = 0; Unit* target = NULL; target = SelectUnit(SELECT_TARGET_TOPAGGRO,0); m_creature->SetUInt64Value(UNIT_FIELD_TARGET, 0); DoCast(m_creature,SPELL_SPOUT_VISUAL); DoTextEmote(EMOTE_SPOUT,NULL); if(target) SpoutAngle = target->GetAngle(target); else SpoutAngle = 0; SpoutTimer = 3000; switch(rand()%2) { case 0: Clockwise = true; SpoutAngle += 0.5; // We want him to start at the main tank but not hit him! break; case 1: Clockwise = false; SpoutAngle -= 0.5; // We want him to start at the main tank but not hit him! break; } return; } else { if(Clockwise) SpoutAngle += PI/7.5; else SpoutAngle -= PI/7.5; if(SpoutAngle > 2*PI) SpoutAngle -= 2*PI; if(SpoutAngle < 0) SpoutAngle += 2*PI; m_creature->SetOrientation(SpoutAngle); DoCast(m_creature, SPELL_SPOUT); OrientationUpdated++; SpoutTimer = 1000; } }else SpoutTimer -= diff; if(OrientationUpdated != -1) return; //Whirl directly after a Spout and at random times if(WhirlTimer < diff || OrientationUpdated == 15) { if (OrientationUpdated == 15) // A spout takes about 15 secs SpoutTimer = 45000; OrientationUpdated = -1; WhirlTimer = rand()%5000 + 15000; DoCast(m_creature,SPELL_WHIRL); }else WhirlTimer -= diff; if(PhaseTimer < diff) { DoCast(m_creature,SPELL_SUBMERGE); PhaseTimer = 60000; Submerged = true; }else PhaseTimer -= diff; if(GeyserTimer < diff) { Unit* target = NULL; target = SelectUnit(SELECT_TARGET_RANDOM,0); if(target == SelectUnit(SELECT_TARGET_TOPAGGRO,0)) target = SelectUnit(SELECT_TARGET_TOPAGGRO,1); GeyserTimer = rand()%5000 + 15000; if(target) DoCast(target,SPELL_GEYSER); else DoCast(m_creature->getVictim(),SPELL_GEYSER); }else GeyserTimer -= diff; if(WaterboltTimer < diff) { Unit* target = NULL; int i = 0; bool meleeTarget = false; target = SelectUnit(SELECT_TARGET_TOPAGGRO,0); if (!target) target = m_creature->getVictim(); while (target) { if( m_creature->IsWithinDistInMap(target, 14)) { meleeTarget = true; break; } target = SelectUnit(SELECT_TARGET_TOPAGGRO,i); i++; } if(!meleeTarget) { target = SelectUnit(SELECT_TARGET_RANDOM,0); if(target) DoCast(target,SPELL_WATERBOLT); else DoCast(m_creature->getVictim(),SPELL_WATERBOLT); WaterboltTimer = 3000; } else DoMeleeAttackIfReady(); }else WaterboltTimer -= diff; DoMeleeAttackIfReady(); } else { if(PhaseTimer < diff) { Submerged = false; m_creature->RemoveAllAuras(); m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); m_creature->RemoveFlag(UNIT_NPC_EMOTESTATE,EMOTE_STATE_SUBMERGED); m_creature->RemoveFlag(UNIT_FIELD_BYTES_1,9); DoCast(m_creature,20568); Spawned = false; SpoutTimer = 1500; // directly cast Spout after emerging! PhaseTimer = 120000; return; }else PhaseTimer -= diff; if(!Spawned) { m_creature->SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); Summoned = m_creature->SummonCreature(MOBID_COILFANG_GUARDIAN,GUARDIAN_X1,GUARDIAN_Y1,GUARDIAN_Z1,0,TEMPSUMMON_CORPSE_DESPAWN,0); Summoned->SendMoveToPacket(MOVE_GUARDIAN_X1,MOVE_GUARDIAN_Y1,MOVE_GUARDIAN_Z1,false,2000); Summoned = m_creature->SummonCreature(MOBID_COILFANG_GUARDIAN,GUARDIAN_X2,GUARDIAN_Y2,GUARDIAN_Z2,0,TEMPSUMMON_CORPSE_DESPAWN,0); Summoned->SendMoveToPacket(MOVE_GUARDIAN_X2,MOVE_GUARDIAN_Y2,MOVE_GUARDIAN_Z2,false,2000); Summoned = m_creature->SummonCreature(MOBID_COILFANG_GUARDIAN,GUARDIAN_X3,GUARDIAN_Y3,GUARDIAN_Z3,0,TEMPSUMMON_CORPSE_DESPAWN,0); Summoned->SendMoveToPacket(MOVE_GUARDIAN_X3,MOVE_GUARDIAN_Y3,MOVE_GUARDIAN_Z3,false,2000); Summoned = m_creature->SummonCreature(MOBID_COILFANG_AMBUSHER,AMBUSHER_X1,AMBUSHER_Y1,AMBUSHER_Z1,0,TEMPSUMMON_CORPSE_DESPAWN,0); Summoned->SendMoveToPacket(MOVE_AMBUSHER_X1,MOVE_AMBUSHER_Y1,MOVE_AMBUSHER_Z1,false,2000); Summoned = m_creature->SummonCreature(MOBID_COILFANG_AMBUSHER,AMBUSHER_X2,AMBUSHER_Y2,AMBUSHER_Z2,0,TEMPSUMMON_CORPSE_DESPAWN,0); Summoned->SendMoveToPacket(MOVE_AMBUSHER_X2,MOVE_AMBUSHER_Y2,MOVE_AMBUSHER_Z2,false,2000); Summoned = m_creature->SummonCreature(MOBID_COILFANG_AMBUSHER,AMBUSHER_X3,AMBUSHER_Y3,AMBUSHER_Z3,0,TEMPSUMMON_CORPSE_DESPAWN,0); Summoned->SendMoveToPacket(MOVE_AMBUSHER_X3,MOVE_AMBUSHER_Y3,MOVE_AMBUSHER_Z3,false,2000); Summoned = m_creature->SummonCreature(MOBID_COILFANG_AMBUSHER,AMBUSHER_X4,AMBUSHER_Y4,AMBUSHER_Z4,0,TEMPSUMMON_CORPSE_DESPAWN,0); Summoned->SendMoveToPacket(MOVE_AMBUSHER_X4,MOVE_AMBUSHER_Y4,MOVE_AMBUSHER_Z4,false,2000); Summoned = m_creature->SummonCreature(MOBID_COILFANG_AMBUSHER,AMBUSHER_X5,AMBUSHER_Y5,AMBUSHER_Z5,0,TEMPSUMMON_CORPSE_DESPAWN,0); Summoned->SendMoveToPacket(MOVE_AMBUSHER_X5,MOVE_AMBUSHER_Y5,MOVE_AMBUSHER_Z5,false,2000); Summoned = m_creature->SummonCreature(MOBID_COILFANG_AMBUSHER,AMBUSHER_X6,AMBUSHER_Y6,AMBUSHER_Z6,0,TEMPSUMMON_CORPSE_DESPAWN,0); Summoned->SendMoveToPacket(MOVE_AMBUSHER_X6,MOVE_AMBUSHER_Y6,MOVE_AMBUSHER_Z6,false,2000); Spawned = true; } } } }};CreatureAI* GetAI_boss_the_lurker_below(Creature *_Creature){ return new boss_the_lurker_belowAI (_Creature);}void AddSC_boss_the_lurker_below(){ Script *newscript; newscript = new Script; newscript->Name="boss_the_lurker_below"; newscript->GetAI = GetAI_boss_the_lurker_below; m_scripts[nrscripts++] = newscript;}CreatureAI* GetAI_mob_coilfang_guardian(Creature *_Creature){ SimpleAI* ai = new SimpleAI (_Creature); ai->Spell[0].Enabled = true; ai->Spell[0].Spell_Id = SPELL_ARCINGSMASH; ai->Spell[0].Cooldown = 15000; ai->Spell[0].First_Cast = 5000; ai->Spell[0].Cast_Target_Type = CAST_HOSTILE_TARGET; ai->Spell[1].Enabled = true; ai->Spell[1].Spell_Id = SPELL_HAMSTRING; ai->Spell[1].Cooldown = 10000; ai->Spell[1].First_Cast = 2000; ai->Spell[1].Cast_Target_Type = CAST_HOSTILE_TARGET; return ai;}void AddSC_mob_coilfang_guardian(){ Script *newscript; newscript = new Script; newscript->Name="mob_coilfang_guardian"; newscript->GetAI = GetAI_mob_coilfang_guardian; m_scripts[nrscripts++] = newscript;}struct MANGOS_DLL_DECL mob_coilfang_ambusherAI : public ScriptedAI{ mob_coilfang_ambusherAI(Creature *c) : ScriptedAI(c) {EnterEvadeMode();} int MultiShotTimer; int ShootBowTimer; int GlobalCooldown; void EnterEvadeMode() { m_creature->RemoveAllAuras(); m_creature->DeleteThreatList(); m_creature->CombatStop(); m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE); MultiShotTimer = 10000; ShootBowTimer = 4000; GlobalCooldown = 1500; DoGoHome(); } void AttackStart(Unit *who) { if (!who || m_creature->getVictim()) return; if (who->isTargetableForAttack() && who->isInAccessablePlaceFor(m_creature) && m_creature->IsHostileTo(who)) { DoStartRangedAttack(who); } } void MoveInLineOfSight(Unit *who) { if (!who || m_creature->getVictim()) return; if (who->isTargetableForAttack() && who->isInAccessablePlaceFor(m_creature) && m_creature->IsHostileTo(who)) { DoStartRangedAttack(who); } } void UpdateAI(const uint32 diff) { if(MultiShotTimer < diff && GlobalCooldown < diff) { Unit* target = NULL; target = m_creature->getVictim(); if(target) DoCast(target,SPELL_MULTISHOT); MultiShotTimer = 10000; GlobalCooldown = 1500; }else MultiShotTimer -= diff; if(ShootBowTimer < diff && GlobalCooldown < diff) { Unit* target = NULL; target = m_creature->getVictim(); if(target) DoCast(target,30493); ShootBowTimer = 5000; GlobalCooldown = 1500; }else ShootBowTimer -= diff; GlobalCooldown -= diff; }};CreatureAI* GetAI_mob_coilfang_ambusher(Creature *_Creature){ return new mob_coilfang_ambusherAI (_Creature);}void AddSC_mob_coilfang_ambusher(){ Script *newscript; newscript = new Script; newscript->Name="mob_coilfang_ambusher"; newscript->GetAI = GetAI_mob_coilfang_ambusher; m_scripts[nrscripts++] = newscript;}