void UpdateAI(uint32 diff) override { if (!UpdateVictim()) return; events.Update(diff); if (me->HasUnitState(UNIT_STATE_CASTING)) return; while (uint32 eventId = events.ExecuteEvent()) { switch (eventId) { case EVENT_BRAIN_WASH_TOTEM: DoCast(me, SPELL_BRAIN_WASH_TOTEM); events.ScheduleEvent(EVENT_BRAIN_WASH_TOTEM, urand(18000, 26000)); break; case EVENT_POWERFULL_HEALING_WARD: DoCast(me, SPELL_POWERFULL_HEALING_WARD); events.ScheduleEvent(EVENT_POWERFULL_HEALING_WARD, urand(14000, 20000)); break; case EVENT_HEX: if (Unit* target = me->GetVictim()) { DoCast(target, SPELL_HEX, true); if (DoGetThreat(target)) DoModifyThreatPercent(target, -80); } events.ScheduleEvent(EVENT_HEX, urand(12000, 20000)); break; case EVENT_DELUSIONS_OF_JINDO: // Casting the delusion curse with a shade so shade will attack the same target with the curse. if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100.0f, true)) { DoCast(target, SPELL_SHADE_OF_JINDO, true); DoCast(target, SPELL_DELUSIONS_OF_JINDO); } events.ScheduleEvent(EVENT_DELUSIONS_OF_JINDO, urand(4000, 12000)); break; case EVENT_TELEPORT: // Teleports a random player and spawns 9 Sacrificed Trolls to attack player if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100.0f, true)) { DoTeleportPlayer(target, TeleportLoc.GetPositionX(), TeleportLoc.GetPositionY(), TeleportLoc.GetPositionZ(), TeleportLoc.GetOrientation()); if (DoGetThreat(me->GetVictim())) DoModifyThreatPercent(target, -100); // Summon a formation of trolls for (uint8 i = 0; i < 10; ++i) if (Creature* SacrificedTroll = me->SummonCreature(NPC_SACRIFICED_TROLL, Formation[i].GetPositionX(), Formation[i].GetPositionY(), Formation[i].GetPositionZ(), Formation[i].GetOrientation(), TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000)) SacrificedTroll->AI()->AttackStart(target); } events.ScheduleEvent(EVENT_TELEPORT, urand(15000, 23000)); break; default: break; } } DoMeleeAttackIfReady(); }
void MovementInform(uint32 type, uint32 id) { if (type == POINT_MOTION_TYPE) { switch (id) { case 8: PointData = GetMoveData(); if (PointData) { me->SetSpeed(MOVE_FLIGHT, 1.0f); me->GetMotionMaster()->MovePoint(PointData->LocId, PointData->fX, PointData->fY, PointData->fZ); } break; case 9: me->GetMotionMaster()->MoveChase(me->getVictim()); BellowingRoarTimer = 1000; break; case 10: me->SetCanFly(true); me->GetMotionMaster()->MovePoint(11, Phase2Location.GetPositionX(), Phase2Location.GetPositionY(), Phase2Location.GetPositionZ()+25); me->SetSpeed(MOVE_FLIGHT, 1.0f); Talk(SAY_PHASE_2_TRANS); if (instance) instance->SetData(DATA_ONYXIA_PHASE, Phase); WhelpTimer = 5000; LairGuardTimer = 15000; break; case 11: if (PointData) me->GetMotionMaster()->MovePoint(PointData->LocId, PointData->fX, PointData->fY, PointData->fZ); me->GetMotionMaster()->Clear(false); me->GetMotionMaster()->MoveIdle(); break; default: IsMoving = false; break; } } }
void Update(uint32 diff) { if (!instance->HavePlayers()) return; // portals should spawn if other portal is dead and doors are closed if (bActive && uiMainEventPhase == IN_PROGRESS) { if (uiActivationTimer < diff) { AddWave(); bActive = false; uiActivationTimer = 5000; } else uiActivationTimer -= diff; } // if main event is in progress and players have wiped then reset instance if ( uiMainEventPhase == IN_PROGRESS && CheckWipe()) { SetData(DATA_REMOVE_NPC, 1); StartBossEncounter(uiFirstBoss, false); StartBossEncounter(uiSecondBoss, false); SetData(DATA_MAIN_DOOR, GO_STATE_ACTIVE); SetData(DATA_WAVE_COUNT, 0); uiMainEventPhase = NOT_STARTED; if (Creature* pSinclari = instance->GetCreature(uiSinclari)) { pSinclari->SetVisible(true); std::list<Creature*> GuardList; pSinclari->GetCreatureListWithEntryInGrid(GuardList, NPC_VIOLET_HOLD_GUARD, 40.0f); if (!GuardList.empty()) { for (std::list<Creature*>::const_iterator itr = GuardList.begin(); itr != GuardList.end(); ++itr) { if (Creature* pGuard = *itr) { pGuard->SetVisible(true); pGuard->SetReactState(REACT_AGGRESSIVE); pGuard->GetMotionMaster()->MovePoint(1, pGuard->GetHomePosition()); } } } pSinclari->GetMotionMaster()->MovePoint(1, pSinclari->GetHomePosition()); pSinclari->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); } } // Cyanigosa is spawned but not tranformed, prefight event Creature* pCyanigosa = instance->GetCreature(uiCyanigosa); if (pCyanigosa && !pCyanigosa->HasAura(CYANIGOSA_SPELL_TRANSFORM)) { if (uiCyanigosaEventTimer <= diff) { switch (uiCyanigosaEventPhase) { case 1: pCyanigosa->CastSpell(pCyanigosa, CYANIGOSA_BLUE_AURA, false); DoScriptText(CYANIGOSA_SAY_SPAWN, pCyanigosa); uiCyanigosaEventTimer = 7*IN_MILLISECONDS; ++uiCyanigosaEventPhase; break; case 2: pCyanigosa->GetMotionMaster()->MoveJump(MiddleRoomLocation.GetPositionX(), MiddleRoomLocation.GetPositionY(), MiddleRoomLocation.GetPositionZ(), 10.0f, 20.0f); pCyanigosa->CastSpell(pCyanigosa, CYANIGOSA_BLUE_AURA, false); uiCyanigosaEventTimer = 7*IN_MILLISECONDS; ++uiCyanigosaEventPhase; break; case 3: pCyanigosa->RemoveAurasDueToSpell(CYANIGOSA_BLUE_AURA); pCyanigosa->CastSpell(pCyanigosa, CYANIGOSA_SPELL_TRANSFORM, 0); pCyanigosa->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC|UNIT_FLAG_NON_ATTACKABLE); pCyanigosa->SetReactState(REACT_AGGRESSIVE); uiCyanigosaEventTimer = 2*IN_MILLISECONDS; ++uiCyanigosaEventPhase; break; case 4: uiCyanigosaEventPhase = 0; break; } } else uiCyanigosaEventTimer -= diff; } // if there are NPCs in front of the prison door, which are casting the door seal spell and doors are active if (GetData(DATA_NPC_PRESENCE_AT_DOOR) && uiMainEventPhase == IN_PROGRESS) { // if door integrity is > 0 then decrase it's integrity state if (GetData(DATA_DOOR_INTEGRITY)) { if (uiDoorSpellTimer < diff) { SetData(DATA_DOOR_INTEGRITY, GetData(DATA_DOOR_INTEGRITY)-1); uiDoorSpellTimer =2000; } else uiDoorSpellTimer -= diff; } // else set door state to active (means door will open and group have failed to sustain mob invasion on the door) else { SetData(DATA_MAIN_DOOR, GO_STATE_ACTIVE); uiMainEventPhase = FAIL; } } }
void UpdateAI(const uint32 uiDiff) { //Return since we have no target if (!UpdateVictim()) return; if (!instance || instance->GetData(DATA_UROM_PLATAFORM) < 2) return; if (teleportTimer <= uiDiff) { me->InterruptNonMeleeSpells(false); DoScriptText(SAY_TELEPORT, me); me->GetMotionMaster()->MoveIdle(); DoCast(SPELL_TELEPORT); teleportTimer = urand(30000, 35000); } else teleportTimer -= uiDiff; if (canCast && !me->FindCurrentSpellBySpellId(SPELL_EMPOWERED_ARCANE_EXPLOSION)) { if (castArcaneExplosionTimer <= uiDiff) { canCast = false; canGoBack = true; DoCastAOE(SPELL_EMPOWERED_ARCANE_EXPLOSION); castArcaneExplosionTimer = 2000; }else castArcaneExplosionTimer -= uiDiff; } if (canGoBack) { if (arcaneExplosionTimer <= uiDiff) { Position pPos; me->getVictim()->GetPosition(&pPos); me->NearTeleportTo(pPos.GetPositionX(), pPos.GetPositionY(), pPos.GetPositionZ(), pPos.GetOrientation()); me->GetMotionMaster()->MoveChase(me->getVictim(), 0, 0); me->SetUnitMovementFlags(MOVEMENTFLAG_WALKING); canCast = false; canGoBack = false; arcaneExplosionTimer = 9000; } else arcaneExplosionTimer -= uiDiff; } if (!me->IsNonMeleeSpellCasted(false, true, true)) { if (frostBombTimer <= uiDiff) { DoCastVictim(SPELL_FROSTBOMB); frostBombTimer = urand(5000, 8000); } else frostBombTimer -= uiDiff; if (timeBombTimer <= uiDiff) { if (Unit* unit = SelectTarget(SELECT_TARGET_RANDOM)) DoCast(unit, SPELL_TIME_BOMB); timeBombTimer = urand(20000, 25000); } else timeBombTimer -= uiDiff; } DoMeleeAttackIfReady(); }
void UpdateAI(uint32 diff) override { if (!UpdateVictim()) return; if (platform < 3) return; events.Update(diff); if (teleportTimer <= diff) { me->InterruptNonMeleeSpells(false); me->GetMotionMaster()->MoveIdle(); DoCast(SPELL_TELEPORT); teleportTimer = urand(30000, 35000); } else teleportTimer -= diff; if (canCast && !me->FindCurrentSpellBySpellId(SPELL_EMPOWERED_ARCANE_EXPLOSION)) { if (castArcaneExplosionTimer <= diff) { canCast = false; canGoBack = true; DoCastAOE(SPELL_EMPOWERED_ARCANE_EXPLOSION); castArcaneExplosionTimer = 2000; } else castArcaneExplosionTimer -= diff; } if (canGoBack) { if (arcaneExplosionTimer <= diff) { if (me->GetVictim()) { Position pos = me->EnsureVictim()->GetPosition(); me->NearTeleportTo(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation()); me->GetMotionMaster()->MoveChase(me->GetVictim()); } me->SetWalk(true); Talk(EMOTE_ARCANE_EXPLOSION); Talk(SAY_ARCANE_EXPLOSION); canCast = false; canGoBack = false; arcaneExplosionTimer = 9000; } else arcaneExplosionTimer -= diff; } if (!me->IsNonMeleeSpellCast(false, true, true)) { if (frostBombTimer <= diff) { DoCastVictim(SPELL_FROSTBOMB); frostBombTimer = urand(5000, 8000); } else frostBombTimer -= diff; if (timeBombTimer <= diff) { if (Unit* unit = SelectTarget(SELECT_TARGET_RANDOM)) DoCast(unit, SPELL_TIME_BOMB); timeBombTimer = urand(20000, 25000); } else timeBombTimer -= diff; } DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 diff) { if (!UpdateVictim()) return; events.Update(diff); if (me->HasUnitState(UNIT_STATE_CASTING)) return; while (uint32 eventId = events.ExecuteEvent()) { switch (eventId) { case EVENT_THROW_SARONITE: if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) { Talk(SAY_THROW_SARONITE, target->GetGUID()); DoCast(target, SPELL_THROW_SARONITE); } events.ScheduleEvent(EVENT_THROW_SARONITE, urand(12500, 20000)); break; case EVENT_CHILLING_WAVE: DoCast(me, SPELL_CHILLING_WAVE); events.ScheduleEvent(EVENT_CHILLING_WAVE, 40000, 0, PHASE_TWO); break; case EVENT_DEEP_FREEZE: if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) { Talk(SAY_CAST_DEEP_FREEZE, target->GetGUID()); DoCast(target, SPELL_DEEP_FREEZE); } events.ScheduleEvent(EVENT_DEEP_FREEZE, 35000, 0, PHASE_THREE); break; case EVENT_JUMP: me->AttackStop(); if (events.IsInPhase(PHASE_TWO)) me->GetMotionMaster()->MoveJump(northForgePos.GetPositionX(), northForgePos.GetPositionY(), northForgePos.GetPositionZ(), 25.0f, 15.0f); else if (events.IsInPhase(PHASE_THREE)) me->GetMotionMaster()->MoveJump(southForgePos.GetPositionX(), southForgePos.GetPositionY(), southForgePos.GetPositionZ(), 25.0f, 15.0f); break; case EVENT_RESUME_ATTACK: if (events.IsInPhase(PHASE_THREE)) events.ScheduleEvent(EVENT_CHILLING_WAVE, 5000, 0, PHASE_TWO); else if (events.IsInPhase(PHASE_THREE)) events.ScheduleEvent(EVENT_DEEP_FREEZE, 10000, 0, PHASE_THREE); AttackStart(me->getVictim()); break; default: break; } } DoMeleeAttackIfReady(); }
void AttackStart(Unit* attacker) { if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() == POINT_MOTION_TYPE) return; // we do this checks to see if the creature is one of the creatures that sorround the boss if (Creature* colossus = Unit::GetCreature(*me, instance ? instance->GetData64(DATA_DRAKKARI_COLOSSUS) : 0)) { Position homePosition; me->GetHomePosition().GetPosition(&homePosition); Position colossusHomePosition; colossus->GetHomePosition().GetPosition(&colossusHomePosition); float distance = homePosition.GetExactDist(colossusHomePosition.GetPositionX(), colossusHomePosition.GetPositionY(), colossusHomePosition.GetPositionZ()); if (distance < 12.0f) { MoveMojos(colossus); me->SetReactState(REACT_PASSIVE); } else ScriptedAI::AttackStart(attacker); } }
void SpawnMobs() { for (uint8 i = 0; i < DUNGEON_MODE(5, 6); ++i) { switch (urand(0, 2)) { case 0: me->SummonCreature(CREATURE_YMIRJAR_WARRIOR, SpawnLoc.GetPositionX()+rand()%5, SpawnLoc.GetPositionY()+rand()%5, SpawnLoc.GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000); break; case 1: me->SummonCreature(CREATURE_YMIRJAR_WITCH_DOCTOR, SpawnLoc.GetPositionX()+rand()%5, SpawnLoc.GetPositionY()+rand()%5, SpawnLoc.GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000); break; case 2: me->SummonCreature(CREATURE_YMIRJAR_HARPOONER, SpawnLoc.GetPositionX()+rand()%5, SpawnLoc.GetPositionY()+rand()%5, SpawnLoc.GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000); break; } } }
bool CheckPlayersInDistance() { bool returnValue = false; if (me->GetMap()) { Map::PlayerList const& players = me->GetMap()->GetPlayers(); if (me->GetMap()->IsDungeon() && !players.isEmpty()) { for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) { Player* player = itr->getSource(); // Only apply to attackable, alive and in 70.0 yards players if (player && !player->isGameMaster() && player->isAlive() && me->IsValidAttackTarget(player)) { if (player->GetDistance(CenterPoint) <= 70.0f) returnValue = true; // In combat with that player, check, that player does not get too far away if (DoGetThreat(player)) { if (player->GetDistance(CenterPoint) > 40.0f) { player->NearTeleportTo(CenterPoint.GetPositionX(), CenterPoint.GetPositionY(), CenterPoint.GetPositionZ(), CenterPoint.GetOrientation()); } } } } } } return returnValue; }
int32 CreatureAI::VisualizeBoundary(uint32 duration, Unit* owner, bool fill) const { typedef std::pair<int32, int32> coordinate; if (!owner) return -1; if (!_boundary || _boundary->empty()) return LANG_CREATURE_MOVEMENT_NOT_BOUNDED; std::queue<coordinate> Q; std::unordered_set<coordinate> alreadyChecked; std::unordered_set<coordinate> outOfBounds; Position startPosition = owner->GetPosition(); if (!CheckBoundary(&startPosition)) // fall back to creature position { startPosition = me->GetPosition(); if (!CheckBoundary(&startPosition)) { startPosition = me->GetHomePosition(); if (!CheckBoundary(&startPosition)) // fall back to creature home position return LANG_CREATURE_NO_INTERIOR_POINT_FOUND; } } float spawnZ = startPosition.GetPositionZ() + BOUNDARY_VISUALIZE_SPAWN_HEIGHT; bool boundsWarning = false; Q.push({ 0,0 }); while (!Q.empty()) { coordinate front = Q.front(); bool hasOutOfBoundsNeighbor = false; for (coordinate off : std::initializer_list<coordinate>{{1,0}, {0,1}, {-1,0}, {0,-1}}) { coordinate next(front.first + off.first, front.second + off.second); if (next.first > BOUNDARY_VISUALIZE_FAILSAFE_LIMIT || next.first < -BOUNDARY_VISUALIZE_FAILSAFE_LIMIT || next.second > BOUNDARY_VISUALIZE_FAILSAFE_LIMIT || next.second < -BOUNDARY_VISUALIZE_FAILSAFE_LIMIT) { boundsWarning = true; continue; } if (alreadyChecked.find(next) == alreadyChecked.end()) // never check a coordinate twice { Position nextPos(startPosition.GetPositionX() + next.first*BOUNDARY_VISUALIZE_STEP_SIZE, startPosition.GetPositionY() + next.second*BOUNDARY_VISUALIZE_STEP_SIZE, startPosition.GetPositionZ()); if (CheckBoundary(&nextPos)) Q.push(next); else { outOfBounds.insert(next); hasOutOfBoundsNeighbor = true; } alreadyChecked.insert(next); } else if (outOfBounds.find(next) != outOfBounds.end()) hasOutOfBoundsNeighbor = true; } if (fill || hasOutOfBoundsNeighbor) if (TempSummon* point = owner->SummonCreature(BOUNDARY_VISUALIZE_CREATURE, Position(startPosition.GetPositionX() + front.first*BOUNDARY_VISUALIZE_STEP_SIZE, startPosition.GetPositionY() + front.second*BOUNDARY_VISUALIZE_STEP_SIZE, spawnZ), TEMPSUMMON_TIMED_DESPAWN, duration * IN_MILLISECONDS)) { point->SetObjectScale(BOUNDARY_VISUALIZE_CREATURE_SCALE); point->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_STUNNED | UNIT_FLAG_IMMUNE_TO_NPC); if (!hasOutOfBoundsNeighbor) point->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); } Q.pop(); } return boundsWarning ? LANG_CREATURE_MOVEMENT_MAYBE_UNBOUNDED : 0; }
void UpdateAI(uint32 diff) override { if (!UpdateVictim()) return; events.Update(diff); if (me->HasUnitState(UNIT_STATE_CASTING)) return; while (uint32 eventId = events.ExecuteEvent()) { switch (eventId) { case EVENT_SHADOWBOLT_VOLLEY: DoCast(me, SPELL_SHADOWBOLT_VOLLEY); events.ScheduleEvent(EVENT_SHADOWBOLT_VOLLEY, urand(15000, 30000)); break; case EVENT_BANISH: if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 30.0f, false)) DoCast(target, SPELL_BANISH); events.ScheduleEvent(EVENT_BANISH, 16000); break; case EVENT_DRAW_SHADOWS: { Map* map = me->GetMap(); Map::PlayerList const &PlayerList = map->GetPlayers(); for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) if (Player* i_pl = i->GetSource()) if (i_pl->IsAlive() && !i_pl->HasAura(SPELL_BANISH)) i_pl->TeleportTo(me->GetMapId(), VorpilPosition.GetPositionX(), VorpilPosition.GetPositionY(), VorpilPosition.GetPositionZ(), VorpilPosition.GetOrientation(), TELE_TO_NOT_LEAVE_COMBAT); me->SetPosition(VorpilPosition); DoCast(me, SPELL_DRAW_SHADOWS, true); DoCast(me, SPELL_RAIN_OF_FIRE); events.ScheduleEvent(EVENT_SHADOWBOLT_VOLLEY, 6000); events.ScheduleEvent(EVENT_DRAW_SHADOWS, 30000); break; } case EVENT_SUMMON_TRAVELER: spawnVoidTraveler(); events.ScheduleEvent(EVENT_SUMMON_TRAVELER, 10000); // enrage at 20% if (HealthBelowPct(20)) events.ScheduleEvent(EVENT_SUMMON_TRAVELER, 5000); break; } } DoMeleeAttackIfReady(); }
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_CURSE: DoCastAOE(SPELL_CURSE_PLAGUEBRINGER); events.ScheduleEvent(EVENT_CURSE, urand(50000, 60000)); return; case EVENT_WARRIOR: Talk(SAY_SUMMON); SummonUndead(NPC_WARRIOR, RAID_MODE(2, 3)); events.ScheduleEvent(EVENT_WARRIOR, 30000); return; case EVENT_BLINK: DoCastAOE(SPELL_CRIPPLE, true); DoCastAOE(SPELL_BLINK); DoResetThreat(); events.ScheduleEvent(EVENT_BLINK, 40000); return; case EVENT_BALCONY: me->SetReactState(REACT_PASSIVE); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); me->AttackStop(); me->RemoveAllAuras(); me->NearTeleportTo(Teleport.GetPositionX(), Teleport.GetPositionY(), Teleport.GetPositionZ(), Teleport.GetOrientation()); events.Reset(); events.ScheduleEvent(EVENT_WAVE, urand(2000, 5000)); waveCount = 0; return; case EVENT_WAVE: Talk(SAY_SUMMON); switch (balconyCount) { case 0: SummonUndead(NPC_CHAMPION, RAID_MODE(2, 4)); break; case 1: SummonUndead(NPC_CHAMPION, RAID_MODE(1, 2)); SummonUndead(NPC_GUARDIAN, RAID_MODE(1, 2)); break; case 2: SummonUndead(NPC_GUARDIAN, RAID_MODE(2, 4)); break; default: SummonUndead(NPC_CHAMPION, RAID_MODE(5, 10)); SummonUndead(NPC_GUARDIAN, RAID_MODE(5, 10)); break; } ++waveCount; events.ScheduleEvent(waveCount < 2 ? EVENT_WAVE : EVENT_GROUND, urand(30000, 45000)); return; case EVENT_GROUND: { ++balconyCount; float x, y, z, o; me->GetHomePosition(x, y, z, o); me->NearTeleportTo(x, y, z, o); events.ScheduleEvent(EVENT_BALCONY, 110000); EnterPhaseGround(); return; } } } if (me->HasReactState(REACT_AGGRESSIVE)) DoMeleeAttackIfReady(); }
bool Execute(uint64 /*currTime*/, uint32 /*diff*/) { if (InstanceScript* instance = obj->GetInstanceScript()) { if (obj) { switch (modifier) { case 0: { std::list<Player*> pl_list; obj->GetPlayerListInGrid(pl_list, 500.0f); if (pl_list.empty()) return false; for (auto itr : pl_list) { itr->AddAura(45066, itr); } Creature* lei_shen = obj->SummonCreature(CREATURE_LEI_SHEN, Lei_Shen, TEMPSUMMON_MANUAL_DESPAWN); if (lei_shen) { lei_shen->SetObjectScale(2.5); lei_shen->AI()->Talk(LEI_SHEN_TALK_01); obj->m_Events.AddEvent(new tortos_bridge_Event(lei_shen, 1), obj->m_Events.CalculateTime(10000)); } break; } case 1: { if (Creature* lei_shen = obj->ToCreature()) lei_shen->AI()->Talk(LEI_SHEN_TALK_02); obj->m_Events.AddEvent(new tortos_bridge_Event(obj, 2), obj->m_Events.CalculateTime(10000)); break; } case 2: { if (Creature* lei_shen = obj->ToCreature()) lei_shen->AI()->Talk(LEI_SHEN_TALK_03); obj->m_Events.AddEvent(new tortos_bridge_Event(obj, 3), obj->m_Events.CalculateTime(6000)); break; } case 3: { Creature* lightning_storm_trigger = obj->SummonCreature(TRIGGER_LIGHTNING_STORM, LightningStormTrigger, TEMPSUMMON_TIMED_DESPAWN); if (lightning_storm_trigger) { lightning_storm_trigger->setFaction(35); lightning_storm_trigger->CastSpell(lightning_storm_trigger, SPELL_COSMETIC_LIGHTNING_STORM); obj->m_Events.AddEvent(new tortos_bridge_Event(obj, 4), obj->m_Events.CalculateTime(15000)); } break; } case 4: { std::list<Player*> pl_list; obj->GetPlayerListInGrid(pl_list, 500.0f); if (pl_list.empty()) return false; for (auto itr : pl_list) { itr->NearTeleportTo(TortosLair.GetPositionX(), TortosLair.GetPositionY(), TortosLair.GetPositionZ(), TortosLair.GetOrientation()); } instance->DoRemoveAurasDueToSpellOnPlayers(45066); instance->DoRemoveAurasDueToSpellOnPlayers(140560); break; } } } } return true; }
void UpdateAI(const uint32 diff) { //Return since we have no target if (!UpdateVictim()) return; if (bIsWaitingToAppear) { me->StopMoving(); me->AttackStop(); if (uiIsWaitingToAppearTimer <= diff) { me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); bIsWaitingToAppear = false; } else uiIsWaitingToAppearTimer -= diff; return; } if ((Phase == 1) ||(Phase == 3)) { if (bFireMagusDead && bFrostMagusDead && bArcaneMagusDead) { for (uint8 n = 0; n < 3; ++n) time[n] = 0; me->GetMotionMaster()->Clear(); me->GetMap()->CreatureRelocation(me, CenterOfRoom.GetPositionX(), CenterOfRoom.GetPositionY(), CenterOfRoom.GetPositionZ(), CenterOfRoom.GetOrientation()); DoCast(me, SPELL_TELESTRA_BACK); me->SetVisible(true); Phase++; uiFireMagusGUID = 0; uiFrostMagusGUID = 0; uiArcaneMagusGUID = 0; bIsWaitingToAppear = true; uiIsWaitingToAppearTimer = 4*IN_MILLISECONDS; DoScriptText(SAY_MERGE, me); } else return; } if ((Phase == 0) && HealthBelowPct(50)) { Phase = 1; me->CastStop(); me->RemoveAllAuras(); me->SetVisible(false); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); uiFireMagusGUID = SplitPersonality(MOB_FIRE_MAGUS); uiFrostMagusGUID = SplitPersonality(MOB_FROST_MAGUS); uiArcaneMagusGUID = SplitPersonality(MOB_ARCANE_MAGUS); bFireMagusDead = false; bFrostMagusDead = false; bArcaneMagusDead = false; DoScriptText(RAND(SAY_SPLIT_1, SAY_SPLIT_2), me); return; } if (IsHeroic() && (Phase == 2) && HealthBelowPct(15)) { Phase = 3; me->CastStop(); me->RemoveAllAuras(); me->SetVisible(false); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); uiFireMagusGUID = SplitPersonality(MOB_FIRE_MAGUS); uiFrostMagusGUID = SplitPersonality(MOB_FROST_MAGUS); uiArcaneMagusGUID = SplitPersonality(MOB_ARCANE_MAGUS); bFireMagusDead = false; bFrostMagusDead = false; bArcaneMagusDead = false; DoScriptText(RAND(SAY_SPLIT_1, SAY_SPLIT_2), me); return; } if (uiCooldown) { if (uiCooldown <= diff) uiCooldown = 0; else { uiCooldown -= diff; return; } } if (uiIceNovaTimer <= diff) { if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) { DoCast(target, SPELL_ICE_NOVA, false); uiCooldown = 1500; } uiIceNovaTimer = 15*IN_MILLISECONDS; } else uiIceNovaTimer -= diff; if (uiGravityWellTimer <= diff) { if (Unit* target = me->getVictim()) { DoCast(target, SPELL_GRAVITY_WELL); uiCooldown = 6*IN_MILLISECONDS; } uiGravityWellTimer = 15*IN_MILLISECONDS; } else uiGravityWellTimer -= diff; if (uiFireBombTimer <= diff) { if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) { DoCast(target, SPELL_FIREBOMB, false); uiCooldown = 2*IN_MILLISECONDS; } uiFireBombTimer = 2*IN_MILLISECONDS; } else uiFireBombTimer -=diff; DoMeleeAttackIfReady(); }