void UpdateAI(const uint32 diff) { //Return since we have no target if (!UpdateVictim()) return; //ArcaneExplosion_Timer if (ArcaneExplosion_Timer <= diff) { DoCast(me->getVictim(), SPELL_ARCANE_EXPLOSION); ArcaneExplosion_Timer = 8000 + rand()%10000; } else ArcaneExplosion_Timer -= diff; //If we are within range melee the target if (me->IsWithinMeleeRange(me->getVictim())) { //Make sure our attack is ready and we arn't currently casting if (me->isAttackReady() && !me->IsNonMeleeSpellCasted(false)) { me->AttackerStateUpdate(me->getVictim()); me->resetAttackTimer(); } }else { //EarthShock_Timer if (EarthShock_Timer <= diff) { DoCast(me->getVictim(), SPELL_EARTH_SHOCK); EarthShock_Timer = 1000; } else EarthShock_Timer -= diff; } //Blink_Timer if (Blink_Timer <= diff) { //DoCast(me, SPELL_BLINK); switch (urand(0,2)) { case 0: me->GetMap()->CreatureRelocation(me, -8340.782227f,2083.814453f,125.648788f,0.0f); DoResetThreat(); break; case 1: me->GetMap()->CreatureRelocation(me, -8341.546875f,2118.504639f,133.058151f,0.0f); DoResetThreat(); break; case 2: me->GetMap()->CreatureRelocation(me, -8318.822266f,2058.231201f,133.058151f,0.0f); DoResetThreat(); break; } DoStopAttack(); Blink_Timer= 20000 + rand()%20000; } else Blink_Timer -= diff; int procent = (int) (me->GetHealthPct() + 0.5f); //Summoning 2 Images and teleporting to a random position on 75% health if ((!Images75 && !IsImage) && (procent <= 75 && procent > 70)) DoSplit(75); //Summoning 2 Images and teleporting to a random position on 50% health if ((!Images50 && !IsImage) && (procent <= 50 && procent > 45)) DoSplit(50); //Summoning 2 Images and teleporting to a random position on 25% health if ((!Images25 && !IsImage) && (procent <= 25 && procent > 20)) DoSplit(25); //Invisible_Timer if (Invisible) { if (Invisible_Timer <= diff) { //Making Skeram visible after telporting me->SetVisible(true); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); Invisible_Timer = 2500; Invisible = false; } else Invisible_Timer -= diff; } DoMeleeAttackIfReady(); }
void DoSplit(int atPercent /* 75 50 25 */) { DoScriptText(SAY_SPLIT, me); ov_mycoordinates *place1 = new ov_mycoordinates(-8340.782227f, 2083.814453f, 125.648788f, 0); ov_mycoordinates *place2 = new ov_mycoordinates(-8341.546875f, 2118.504639f, 133.058151f, 0); ov_mycoordinates *place3 = new ov_mycoordinates(-8318.822266f, 2058.231201f, 133.058151f, 0); ov_mycoordinates *bossc=place1, *i1=place2, *i2=place3; switch(urand(0, 2)) { case 0: bossc=place1; i1=place2; i2=place3; break; case 1: bossc=place2; i1=place1; i2=place3; break; case 2: bossc=place3; i1=place1; i2=place2; break; } for(uint16 i = 0; i < 41; ++i) { if(Player* target = CAST_PLR(SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))) { if(Group *pGrp = target->GetGroup()) for(uint8 ico = 0; ico < TARGETICONCOUNT; ++ico) { //if(grp->m_targetIcons[ico] == me->GetGUID()) -- private member :( pGrp->SetTargetIcon(ico, 0, 0); } break; } } me->RemoveAllAuras(); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); me->SetVisible(false); me->GetMap()->CreatureRelocation(me, bossc->x, bossc->y, bossc->z, bossc->r); Invisible = true; DoResetThreat(); DoStopAttack(); switch(atPercent) { case 75: Images75 = true; break; case 50: Images50 = true; break; case 25: Images25 = true; break; } Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0); Creature* Image1 = me->SummonCreature(15263, i1->x, i1->y, i1->z, i1->r, TEMPSUMMON_CORPSE_DESPAWN, 30000); if(Image1) { Image1->SetMaxHealth(me->GetMaxHealth() / 5); Image1->SetHealth(me->GetHealth() / 5); if(target) Image1->AI()->AttackStart(target); CAST_AI(boss_skeram::boss_skeramAI, Image1->AI())->IsImage = true; } Creature* Image2 = me->SummonCreature(15263, i2->x, i2->y, i2->z, i2->r, TEMPSUMMON_CORPSE_DESPAWN, 30000); if(Image2) { Image2->SetMaxHealth(me->GetMaxHealth() / 5); Image2->SetHealth(me->GetHealth() / 5); if(target) Image2->AI()->AttackStart(target); CAST_AI(boss_skeram::boss_skeramAI, Image2->AI())->IsImage = true; } Invisible = true; delete place1; delete place2; delete place3; }
void UpdateAI(uint32 const diff) { if (!UpdateVictim() || !CheckInRoom()) return; events.Update(diff); if (me->HasUnitState(UNIT_STAT_CASTING)) return; while (uint32 eventId = events.ExecuteEvent()) { switch (eventId) { case EVENT_BERSERK: DoScriptText(EMOTE_GENERIC_BERSERK_RAID, me); Talk(SAY_BERSERK); DoCast(me, SPELL_BERSERK); break; case EVENT_VAMPIRIC_BITE: { std::list<Player*> targets; SelectRandomTarget(false, &targets); if (!targets.empty()) { Unit* target = targets.front(); DoCast(target, SPELL_VAMPIRIC_BITE); Talk(SAY_VAMPIRIC_BITE); _vampires.insert(target->GetGUID()); } break; } case EVENT_BLOOD_MIRROR: { // victim can be NULL when this is processed in the same update tick as EVENT_AIR_PHASE if (me->getVictim()) { Player* newOfftank = SelectRandomTarget(true); if (_offtank != newOfftank) { _offtank = newOfftank; if (_offtank) { // both spells have SPELL_ATTR5_SINGLE_TARGET_SPELL, no manual removal needed _offtank->CastSpell(me->getVictim(), SPELL_BLOOD_MIRROR_DAMAGE, true); me->getVictim()->CastSpell(_offtank, SPELL_BLOOD_MIRROR_DUMMY, true); DoCastVictim(SPELL_BLOOD_MIRROR_VISUAL); if (Item* shadowsEdge = _offtank->GetWeaponForAttack(BASE_ATTACK, true)) if (!_offtank->HasAura(SPELL_THIRST_QUENCHED) && shadowsEdge->GetEntry() == ITEM_SHADOW_S_EDGE && !_offtank->HasAura(SPELL_GUSHING_WOUND)) _offtank->CastSpell(_offtank, SPELL_GUSHING_WOUND, true); } } } events.ScheduleEvent(EVENT_BLOOD_MIRROR, 2500, EVENT_GROUP_CANCELLABLE); break; } case EVENT_DELIRIOUS_SLASH: if (_offtank && !me->HasByteFlag(UNIT_FIELD_BYTES_1, 3, 0x03)) DoCast(_offtank, SPELL_DELIRIOUS_SLASH); events.ScheduleEvent(EVENT_DELIRIOUS_SLASH, urand(20000, 24000), EVENT_GROUP_NORMAL); break; case EVENT_PACT_OF_THE_DARKFALLEN: { std::list<Player*> targets; SelectRandomTarget(false, &targets); uint32 targetCount = 2; // do not combine these checks! we want it incremented TWICE when both conditions are met if (IsHeroic()) ++targetCount; if (Is25ManRaid()) ++targetCount; Arkcore::RandomResizeList<Player*>(targets, targetCount); if (targets.size() > 1) { Talk(SAY_PACT_OF_THE_DARKFALLEN); for (std::list<Player*>::iterator itr = targets.begin(); itr != targets.end(); ++itr) DoCast(*itr, SPELL_PACT_OF_THE_DARKFALLEN); } events.ScheduleEvent(EVENT_PACT_OF_THE_DARKFALLEN, 30500, EVENT_GROUP_NORMAL); break; } case EVENT_SWARMING_SHADOWS: if (Player* target = SelectRandomTarget(false)) { Talk(EMOTE_SWARMING_SHADOWS, target->GetGUID()); Talk(SAY_SWARMING_SHADOWS); DoCast(target, SPELL_SWARMING_SHADOWS); } events.ScheduleEvent(EVENT_SWARMING_SHADOWS, 30500, EVENT_GROUP_NORMAL); break; case EVENT_TWILIGHT_BLOODBOLT: { std::list<Player*> targets; SelectRandomTarget(false, &targets); Arkcore::RandomResizeList<Player*>(targets, uint32(Is25ManRaid() ? 4 : 2)); for (std::list<Player*>::iterator itr = targets.begin(); itr != targets.end(); ++itr) DoCast(*itr, SPELL_TWILIGHT_BLOODBOLT); DoCast(me, SPELL_TWILIGHT_BLOODBOLT_TARGET); events.ScheduleEvent(EVENT_TWILIGHT_BLOODBOLT, urand(10000, 15000), EVENT_GROUP_NORMAL); break; } case EVENT_AIR_PHASE: DoStopAttack(); me->SetReactState(REACT_PASSIVE); events.DelayEvents(10000, EVENT_GROUP_NORMAL); events.CancelEventGroup(EVENT_GROUP_CANCELLABLE); me->GetMotionMaster()->MovePoint(POINT_CENTER, centerPos); break; case EVENT_AIR_START_FLYING: me->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING); me->SetByteFlag(UNIT_FIELD_BYTES_1, 3, 0x01); me->SetFlying(true); me->SendMovementFlagUpdate(); me->GetMotionMaster()->MovePoint(POINT_AIR, airPos); break; case EVENT_AIR_FLY_DOWN: me->GetMotionMaster()->MovePoint(POINT_GROUND, centerPos); break; default: break; } } DoMeleeAttackIfReady(); }
void DoSplit(int atPercent /* 75 50 25 */) { DoScriptText(SAY_SPLIT, m_creature); ov_mycoordinates *place1 = new ov_mycoordinates(-8340.782227f, 2083.814453f, 125.648788f, 0.0f); ov_mycoordinates *place2 = new ov_mycoordinates(-8341.546875f, 2118.504639f, 133.058151f, 0.0f); ov_mycoordinates *place3 = new ov_mycoordinates(-8318.822266f, 2058.231201f, 133.058151f, 0.0f); ov_mycoordinates *bossc=place1, *i1=place2, *i2=place3; switch(urand(0, 2)) { case 0: bossc = place1; i1 = place2; i2 = place3; break; case 1: bossc = place2; i1 = place1; i2 = place3; break; case 2: bossc = place3; i1 = place1; i2 = place2; break; } m_creature->RemoveAllAuras(); m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); m_creature->SetVisibility(VISIBILITY_OFF); m_creature->GetMap()->CreatureRelocation(m_creature, bossc->x, bossc->y, bossc->z, bossc->r); Invisible = true; DoResetThreat(); DoStopAttack(); switch (atPercent) { case 75: Images75 = true; break; case 50: Images50 = true; break; case 25: Images25 = true; break; } Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0); Image1 = m_creature->SummonCreature(15263, i1->x, i1->y, i1->z, i1->r, TEMPSUMMON_CORPSE_DESPAWN, 30000); if (Image1) { Image1->SetMaxHealth(m_creature->GetMaxHealth() / 5); Image1->SetHealth(m_creature->GetHealth() / 5); if (boss_skeramAI* pImageAI = dynamic_cast<boss_skeramAI*>(Image1->AI())) pImageAI->IsImage = true; if (target) Image1->AI()->AttackStart(target); } Image2 = m_creature->SummonCreature(15263,i2->x, i2->y, i2->z, i2->r, TEMPSUMMON_CORPSE_DESPAWN, 30000); if (Image2) { Image2->SetMaxHealth(m_creature->GetMaxHealth() / 5); Image2->SetHealth(m_creature->GetHealth() / 5); if (boss_skeramAI* pImageAI = dynamic_cast<boss_skeramAI*>(Image2->AI())) pImageAI->IsImage = true; if (target) Image2->AI()->AttackStart(target); } Invisible = true; delete place1; delete place2; delete place3; }
void UpdateAI(uint32 diff) override { if (!UpdateVictim() || !CheckInRoom()) return; events.Update(diff); if (me->HasUnitState(UNIT_STATE_CASTING)) return; while (uint32 eventId = events.ExecuteEvent()) { switch (eventId) { case EVENT_BERSERK: Talk(EMOTE_BERSERK_RAID); Talk(SAY_BERSERK); DoCast(me, SPELL_BERSERK); break; case EVENT_VAMPIRIC_BITE: { std::list<Player*> targets; SelectRandomTarget(false, &targets); if (!targets.empty()) { Unit* target = targets.front(); DoCast(target, SPELL_VAMPIRIC_BITE); DoCastAOE(SPELL_VAMPIRIC_BITE_DUMMY, true); Talk(SAY_VAMPIRIC_BITE); _vampires.insert(target->GetGUID()); target->CastSpell(target, SPELL_PRESENCE_OF_THE_DARKFALLEN, TRIGGERED_FULL_MASK); target->CastSpell(target, SPELL_PRESENCE_OF_THE_DARKFALLEN_2, TRIGGERED_FULL_MASK); } break; } case EVENT_BLOOD_MIRROR: { // victim can be NULL when this is processed in the same update tick as EVENT_AIR_PHASE if (me->GetVictim()) { Player* newOfftank = SelectRandomTarget(true); if (newOfftank) { if (_offtankGUID != newOfftank->GetGUID()) { _offtankGUID = newOfftank->GetGUID(); // both spells have SPELL_ATTR5_SINGLE_TARGET_SPELL, no manual removal needed newOfftank->CastSpell(me->GetVictim(), SPELL_BLOOD_MIRROR_DAMAGE, true); me->EnsureVictim()->CastSpell(newOfftank, SPELL_BLOOD_MIRROR_DUMMY, true); DoCastVictim(SPELL_BLOOD_MIRROR_VISUAL); if (Is25ManRaid() && newOfftank->GetQuestStatus(QUEST_BLOOD_INFUSION) == QUEST_STATUS_INCOMPLETE && newOfftank->HasAura(SPELL_UNSATED_CRAVING) && !newOfftank->HasAura(SPELL_THIRST_QUENCHED) && !newOfftank->HasAura(SPELL_GUSHING_WOUND)) newOfftank->CastSpell(newOfftank, SPELL_GUSHING_WOUND, TRIGGERED_FULL_MASK); } } else _offtankGUID.Clear(); } events.ScheduleEvent(EVENT_BLOOD_MIRROR, 2500, EVENT_GROUP_CANCELLABLE); break; } case EVENT_DELIRIOUS_SLASH: if (_offtankGUID && !me->HasByteFlag(UNIT_FIELD_BYTES_1, 3, UNIT_BYTE1_FLAG_ALWAYS_STAND | UNIT_BYTE1_FLAG_HOVER)) if (Player* _offtank = ObjectAccessor::GetPlayer(*me, _offtankGUID)) DoCast(_offtank, SPELL_DELIRIOUS_SLASH); events.ScheduleEvent(EVENT_DELIRIOUS_SLASH, urand(20000, 24000), EVENT_GROUP_NORMAL); break; case EVENT_PACT_OF_THE_DARKFALLEN: { std::list<Player*> targets; SelectRandomTarget(false, &targets); Trinity::Containers::RandomResizeList(targets, Is25ManRaid() ? 3 : 2); if (targets.size() > 1) { Talk(SAY_PACT_OF_THE_DARKFALLEN); for (std::list<Player*>::iterator itr = targets.begin(); itr != targets.end(); ++itr) DoCast(*itr, SPELL_PACT_OF_THE_DARKFALLEN); } events.ScheduleEvent(EVENT_PACT_OF_THE_DARKFALLEN, 30500, EVENT_GROUP_NORMAL); break; } case EVENT_SWARMING_SHADOWS: if (Player* target = SelectRandomTarget(false)) { Talk(EMOTE_SWARMING_SHADOWS, target); Talk(SAY_SWARMING_SHADOWS); DoCast(target, SPELL_SWARMING_SHADOWS); } events.ScheduleEvent(EVENT_SWARMING_SHADOWS, 30500, EVENT_GROUP_NORMAL); break; case EVENT_TWILIGHT_BLOODBOLT: { std::list<Player*> targets; SelectRandomTarget(false, &targets); Trinity::Containers::RandomResizeList<Player*>(targets, uint32(Is25ManRaid() ? 4 : 2)); for (std::list<Player*>::iterator itr = targets.begin(); itr != targets.end(); ++itr) DoCast(*itr, SPELL_TWILIGHT_BLOODBOLT); DoCast(me, SPELL_TWILIGHT_BLOODBOLT_TARGET); events.ScheduleEvent(EVENT_TWILIGHT_BLOODBOLT, urand(10000, 15000), EVENT_GROUP_NORMAL); break; } case EVENT_AIR_PHASE: DoStopAttack(); me->SetReactState(REACT_PASSIVE); events.DelayEvents(10000, EVENT_GROUP_NORMAL); events.CancelEventGroup(EVENT_GROUP_CANCELLABLE); me->GetMotionMaster()->MovePoint(POINT_CENTER, centerPos); break; case EVENT_AIR_START_FLYING: me->SetDisableGravity(true); me->SetByteFlag(UNIT_FIELD_BYTES_1, 3, UNIT_BYTE1_FLAG_ALWAYS_STAND); me->GetMotionMaster()->MovePoint(POINT_AIR, airPos); break; case EVENT_AIR_FLY_DOWN: me->GetMotionMaster()->MovePoint(POINT_GROUND, centerPos); break; default: break; } } DoMeleeAttackIfReady(); }
void DoSplit(int atPercent /* 75 50 25 */) { DoScriptText(SAY_SPLIT, m_creature); ov_mycoordinates *place1 = new ov_mycoordinates(-8340.782227,2083.814453,125.648788,0); ov_mycoordinates *place2 = new ov_mycoordinates(-8341.546875,2118.504639,133.058151,0); ov_mycoordinates *place3 = new ov_mycoordinates(-8318.822266,2058.231201,133.058151,0); ov_mycoordinates *bossc=place1, *i1=place2, *i2=place3; switch(rand()%3) { case 0: bossc=place1; i1=place2; i2=place3; break; case 1: bossc=place2; i1=place1; i2=place3; break; case 2: bossc=place3; i1=place1; i2=place2; break; } for (int tryi = 0; tryi < 41; tryi ++) { Unit *targetpl = SelectUnit(SELECT_TARGET_RANDOM, 0); if (targetpl->GetTypeId() == TYPEID_PLAYER) { Group *grp = CAST_PLR(targetpl)->GetGroup(); if (grp) { for (int ici = 0; ici < TARGETICONCOUNT; ici++) { //if (grp ->m_targetIcons[ici] == m_creature->GetGUID()) -- private member:( grp->SetTargetIcon(ici, 0); } } break; } } m_creature->RemoveAllAuras(); m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); m_creature->SetVisibility(VISIBILITY_OFF); m_creature->Relocate(bossc->x, bossc->y, bossc->z, bossc->r); Invisible = true; delete place1; delete place2; delete place3; DoResetThreat(); DoStopAttack(); switch (atPercent) { case 75: Images75 = true; break; case 50: Images50 = true; break; case 25: Images25 = true; break; } Unit* target = SelectUnit(SELECT_TARGET_RANDOM,0); Image1 = m_creature->SummonCreature(15263, i1->x, i1->y, i1->z, i1->r, TEMPSUMMON_CORPSE_DESPAWN, 30000); if (Image1) { Image1->SetMaxHealth(m_creature->GetMaxHealth() / 5); Image1->SetHealth(m_creature->GetHealth() / 5); if (target) Image1->AI()->AttackStart(target); CAST_AI(boss_skeramAI, Image1->AI())->IsImage = true; } Image2 = m_creature->SummonCreature(15263,i2->x, i2->y, i2->z, i2->r, TEMPSUMMON_CORPSE_DESPAWN, 30000); if (Image2) { Image2->SetMaxHealth(m_creature->GetMaxHealth() / 5); Image2->SetHealth(m_creature->GetHealth() / 5); if (target) Image2->AI()->AttackStart(target); CAST_AI(boss_skeramAI, Image2->AI())->IsImage = true; } Invisible = true; }
void DoSplit(int atPercent /* 75 50 25 */) { DoScriptText(SAY_SPLIT, me); ov_mycoordinates *place1 = new ov_mycoordinates(-8340.782227f,2083.814453f,125.648788f,0); ov_mycoordinates *place2 = new ov_mycoordinates(-8341.546875f,2118.504639f,133.058151f,0); ov_mycoordinates *place3 = new ov_mycoordinates(-8318.822266f,2058.231201f,133.058151f,0); ov_mycoordinates *bossc=place1, *i1=place2, *i2=place3; switch(rand()%3) { case 0: bossc=place1; i1=place2; i2=place3; break; case 1: bossc=place2; i1=place1; i2=place3; break; case 2: bossc=place3; i1=place1; i2=place2; break; } for (int tryi = 0; tryi < 41; tryi ++) { Unit* targetpl = SelectUnit(SELECT_TARGET_RANDOM, 0); if (targetpl->GetTypeId() == TYPEID_PLAYER) { Group *grp = ((Player* )targetpl)->GetGroup(); if (grp) { for (int ici = 0; ici < TARGETICONCOUNT; ici++) { //if (grp ->m_targetIcons[ici] == me->GetGUID()) -- private member:( grp->SetTargetIcon(ici, 0); } } break; } } me->RemoveAllAuras(); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); me->SetVisibility(VISIBILITY_OFF); me->GetMap()->CreatureRelocation(me, bossc->x, bossc->y, bossc->z, bossc->r); Invisible = true; DoResetThreat(); DoStopAttack(); switch (atPercent) { case 75: Images75 = true; break; case 50: Images50 = true; break; case 25: Images25 = true; break; } Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM,0); Image1 = me->SummonCreature(15263, i1->x, i1->y, i1->z, i1->r, TEMPSUMMON_CORPSE_DESPAWN, 30000); if (!Image1) { PLACES_CLEANUP return; }
void UpdateAI(const uint32 diff) { if (instance->GetData(DATA_LURKER_FISHING_EVENT) != DONE) return; //boss is invisible, don't attack if (!CanStartEvent) { if (m_submerged) { m_submerged = false; WaitTimer2 = 500; } //wait 500ms before emerge anim if (!m_submerged && WaitTimer2 <= diff) { me->SetVisibility(VISIBILITY_ON); me->RemoveAllAuras(); me->SetUInt32Value(UNIT_NPC_EMOTESTATE, 0); DoCast(me, SPELL_EMERGE, false); WaitTimer2 = 60000;//never reached WaitTimer = 3000; } else WaitTimer2 -= diff; //wait 3secs for emerge anim, then attack if (WaitTimer <= diff) { //fresh fished from pool WaitTimer = 3000; CanStartEvent = true; me->RemoveAurasDueToSpell(SPELL_SUBMERGE); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_ATTACKABLE_2); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); DoZoneInCombat(); if (ConsecutiveSubmerge) { events.RescheduleEvent(LURKER_EVENT_WHIRL, 2000); events.RescheduleEvent(LURKER_EVENT_GEYSER, urand(5000, 15000)); events.RescheduleEvent(LURKER_EVENT_SUBMERGE, 90000); } } else WaitTimer -= diff; return; } if (!UpdateVictim()) return; DoSpecialThings(diff, DO_PULSE_COMBAT); Rotate(diff);//always check rotate things events.Update(diff); if(!m_submerged && RotType == NOROTATE)//is not spouting and not submerged { if(SpoutTimer < diff) { if(me->getVictim() && RotType == NOROTATE) StartRotate(me->getVictim());//start spout and random rotate SpoutTimer= 35000; return; } else SpoutTimer -= diff; } while (uint32 eventId = events.ExecuteEvent()) { switch (eventId) { case LURKER_EVENT_WHIRL: { if (m_submerged == false) { AddSpellToCast(me, SPELL_WHIRL); } events.RescheduleEvent(LURKER_EVENT_WHIRL, 18000); break; } case LURKER_EVENT_GEYSER: { AddSpellToCast(SPELL_GEYSER, CAST_RANDOM); events.ScheduleEvent(LURKER_EVENT_GEYSER, urand(15000, 20000)); break; } case LURKER_EVENT_SUBMERGE: { ForceSpellCast(me, SPELL_SUBMERGE, INTERRUPT_AND_CAST_INSTANTLY); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_ATTACKABLE_2); me->SetVisibility(VISIBILITY_OFF); SummonAdds(); m_submerged = true; // directly cast Spout after emerging! SpoutTimer = 4000; events.CancelEvent(LURKER_EVENT_WHIRL); events.CancelEvent(LURKER_EVENT_GEYSER); events.ScheduleEvent(LURKER_EVENT_REEMERGE, 60000); break; } case LURKER_EVENT_REEMERGE: { me->SetVisibility(VISIBILITY_OFF); DoStopAttack(); //Time values here is irrelevant, they just need to be set WaitTimer = 60000; WaitTimer2 = 60000; CanStartEvent = false; m_submerged = true; ConsecutiveSubmerge = true; break; } } } CastNextSpellIfAnyAndReady(); DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 diff) { //Return since we have no target if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; //ArcaneExplosion_Timer if (ArcaneExplosion_Timer < diff) { DoCastSpellIfCan(m_creature->getVictim(), SPELL_ARCANE_EXPLOSION); ArcaneExplosion_Timer = urand(8000, 18000); }else ArcaneExplosion_Timer -= diff; //If we are within range melee the target if (m_creature->IsWithinDistInMap(m_creature->getVictim(), ATTACK_DISTANCE)) { //Make sure our attack is ready and we arn't currently casting if (m_creature->isAttackReady() && !m_creature->IsNonMeleeSpellCasted(false)) { m_creature->AttackerStateUpdate(m_creature->getVictim()); m_creature->resetAttackTimer(); } }else { //EarthShock_Timer if (EarthShock_Timer < diff) { DoCastSpellIfCan(m_creature->getVictim(),SPELL_EARTH_SHOCK); EarthShock_Timer = 1000; }else EarthShock_Timer -= diff; } //Blink_Timer if (Blink_Timer < diff) { //DoCastSpellIfCan(m_creature, SPELL_BLINK); switch (urand(0, 2)) { case 0: m_creature->GetMap()->CreatureRelocation(m_creature, -8340.782227f, 2083.814453f, 125.648788f, 0.0f); DoResetThreat(); break; case 1: m_creature->GetMap()->CreatureRelocation(m_creature, -8341.546875f, 2118.504639f, 133.058151f, 0.0f); DoResetThreat(); break; case 2: m_creature->GetMap()->CreatureRelocation(m_creature, -8318.822266f, 2058.231201f, 133.058151f, 0.0f); DoResetThreat(); break; } DoStopAttack(); Blink_Timer = urand(20000, 40000); }else Blink_Timer -= diff; float procent = m_creature->GetHealthPercent(); //Summoning 2 Images and teleporting to a random position on 75% health if (!Images75 && !IsImage && procent <= 75.0f && procent > 70.0f) DoSplit(75); //Summoning 2 Images and teleporting to a random position on 50% health if (!Images50 && !IsImage && procent <= 50.0f && procent > 45.0f) DoSplit(50); //Summoning 2 Images and teleporting to a random position on 25% health if (!Images25 && !IsImage && procent <= 25.0f && procent > 20.0f) DoSplit(25); //Invisible_Timer if (Invisible) { if (Invisible_Timer < diff) { //Making Skeram visible after telporting m_creature->SetVisibility(VISIBILITY_ON); m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); Invisible_Timer = 2500; Invisible = false; }else Invisible_Timer -= diff; } DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 diff) { if (!UpdateVictim()) return; if (me->HasUnitState(UNIT_STATE_CASTING)) return; if (ArcaneExplosionTimer <= diff) { DoCastAOE(SPELL_ARCANE_EXPLOSION); ArcaneExplosionTimer = urand(8000, 18000); } else ArcaneExplosionTimer -= diff; if (FullFillmentTimer <= diff) { if (Unit* target = SelectTarget(TARGET_RANDOM, 1, 45, true)) { DoCast(target, SPELL_TRUE_FULFILLMENT); FullFillmentTimer = urand(20000, 22000); } } else FullFillmentTimer -= diff; if (me->IsWithinMeleeRange(me->GetVictim())) { if (me->IsAttackReady() && !me->IsNonMeleeSpellCasted(false)) { me->AttackerStateUpdate(me->GetVictim()); me->ResetAttackTimer(); } } else { if (EarthShockTimer <= diff) { DoCastVictim(SPELL_EARTH_SHOCK); EarthShockTimer = 1000; } else EarthShockTimer -= diff; } if (BlinkTimer <= diff) { //DoCast(me, SPELL_BLINK); switch (urand(0, 2)) { case 0: me->SetPosition(-8340.782227f, 2083.814453f, 125.648788f, 0.0f); DoResetThreat(); break; case 1: me->SetPosition(-8341.546875f, 2118.504639f, 133.058151f, 0.0f); DoResetThreat(); break; case 2: me->SetPosition(-8318.822266f, 2058.231201f, 133.058151f, 0.0f); DoResetThreat(); break; } DoStopAttack(); BlinkTimer= urand(20000, 40000); } else BlinkTimer -= diff; int procent = (int) (me->GetHealthPct() + 0.5f); if ((!Images75 && !IsImage) && (procent <= 75 && procent > 70)) DoSplit(75); if ((!Images50 && !IsImage) && (procent <= 50 && procent > 45)) DoSplit(50); if ((!Images25 && !IsImage) && (procent <= 25 && procent > 20)) DoSplit(25); if (Invisible) { if (InvisibleTimer <= diff) { me->SetVisible(true); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); InvisibleTimer = 2500; Invisible = false; } else InvisibleTimer -= diff; } DoMeleeAttackIfReady(); }