/* Use the force ani and repair this fucking instance for players Copyright by Bloodworld Dev Team 2008 */ #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 "wez gleboki wdech." #define MOBID_COILFANG_GUARDIAN 21873 #define MOBID_COILFANG_AMBUSHER 21865 // Obroty.... #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 //Spell przy obracaniu #define SPELL_MULTISHOT 30990 //Guardian spells #define SPELL_ARCINGSMASH 38761 #define SPELL_HAMSTRING 26211 #define PI 3.1415 struct 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(); 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_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; 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; if(WhirlTimer < diff || OrientationUpdated == 15) { if (OrientationUpdated == 15) 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; 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; }