void CreatureAI::DoZoneInCombatWithPlayers(bool force) { Map* map = me->GetMap(); if (!map->IsDungeon()) { sLog.outError("CreatureAI::DoZoneInCombatWithPlayers called on a map that is not an instance (creature entry = %u)", me->GetEntry()); return; } if (!force) { if (!me->CanHaveThreatList() || me->getThreatManager().isThreatListEmpty()) { error_log("CreatureAI::DoZoneInCombatWithPlayers called for a creature that either cannot have a threat list or has empty threat list (creature entry = %u)", me->GetEntry()); return; } } Map::PlayerList const &PlayerList = map->GetPlayers(); for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) { if (Player* pPlayer = i->GetSource()) { if (pPlayer->IsGameMaster()) continue; if (pPlayer->IsAlive()) { me->SetInCombatWith(pPlayer); pPlayer->SetInCombatWith(me); me->AddThreat(pPlayer, 0.0f); } } } }
bool OnGossipHello(Player* player, Creature* creature) { if (creature->GetMap()->IsHeroic()) { uint32 gongCounter = 0; if (Creature* nefarianHelperheroic = creature->FindNearestCreature(NPC_NEFARIAN_HELPER_HEROIC, 150.0f, true)) nefarianHelperheroic->AI()->Talk(26); if (Creature* gong = creature->FindNearestCreature(42949, 20.0f)) if(gongCounter < 3) { creature->Kill(gong); gongCounter++; } } if(Creature* atramedes = creature->FindNearestCreature(BOSS_ATRAMEDES, 200.0f)) { creature->CastSpell(atramedes, SPELL_RESONATING_DRAGON, true); creature->AddAura(SPELL_VERTIGO, atramedes); creature->AddAura(SPELL_NOISY, player); creature->CastSpell(player, SPELL_RESONATING_PLAYER, true); Map::PlayerList const &PlayerList = creature->GetMap()->GetPlayers(); if (!PlayerList.isEmpty()) for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) if (Player* playr = i->GetSource()) playr->AddAura(SPELL_SOUND_AURA, playr); // reset the bar. creature->setDeathState(JUST_DIED); } return true; }
void JustDied(Unit* pPlayer) { Talk(SAY_DEAD); char msg[250]; snprintf(msg, 250, "|cffff0000[Boss System]|r Boss|cffff6060 Lightshadow|r wurde getoetet! Respawn in 4h 33min. Darkshadow ist nun der rechtmaessige Prinz! %u", playerdie); sWorld->SendGlobalText(msg, NULL); Map::PlayerList const &PlList = pPlayer->GetMap()->GetPlayers(); if (PlList.isEmpty()) return; Lootchange(playerdie); for (Map::PlayerList::const_iterator i = PlList.begin(); i != PlList.end(); ++i) { if (Player* player = i->GetSource()) { if (player->IsGameMaster()) continue; if (player->IsAlive()) { player->RemoveAllAuras(); if (player->hasQuest(899000) && playerdie == 0){ Questcomplete(); } else { player->SendQuestFailed(899000,EQUIP_ERR_OK); } } } } }
void CreatureAI::DoZoneInCombat(Creature* creature /*= NULL*/, float maxRangeToNearestTarget /* = 50.0f*/) { if (!creature) creature = me; if (!creature->CanHaveThreatList()) return; Map* map = creature->GetMap(); if (!map->IsDungeon()) //use IsDungeon instead of Instanceable, in case battlegrounds will be instantiated { TC_LOG_ERROR("misc", "DoZoneInCombat call for map that isn't an instance (creature entry = %d)", creature->GetTypeId() == TYPEID_UNIT ? creature->ToCreature()->GetEntry() : 0); return; } if (!creature->HasReactState(REACT_PASSIVE) && !creature->GetVictim()) { if (Unit* nearTarget = creature->SelectNearestTarget(maxRangeToNearestTarget)) creature->AI()->AttackStart(nearTarget); else if (creature->IsSummon()) { if (Unit* summoner = creature->ToTempSummon()->GetSummoner()) { Unit* target = summoner->getAttackerForHelper(); if (!target && summoner->CanHaveThreatList() && !summoner->getThreatManager().isThreatListEmpty()) target = summoner->getThreatManager().getHostilTarget(); if (target && (creature->IsFriendlyTo(summoner) || creature->IsHostileTo(target))) creature->AI()->AttackStart(target); } } } // Intended duplicated check, the code above this should select a victim // If it can't find a suitable attack target then we should error out. if (!creature->HasReactState(REACT_PASSIVE) && !creature->GetVictim()) { TC_LOG_ERROR("misc", "DoZoneInCombat called for creature that has empty threat list (creature entry = %u)", creature->GetEntry()); return; } Map::PlayerList const& playerList = map->GetPlayers(); if (playerList.isEmpty()) return; for (Map::PlayerList::const_iterator itr = playerList.begin(); itr != playerList.end(); ++itr) { if (Player* player = itr->GetSource()) { if (player->IsGameMaster()) continue; if (player->IsAlive()) { creature->SetInCombatWith(player); player->SetInCombatWith(creature); creature->AddThreat(player, 0.0f); } /* Causes certain things to never leave the threat list (Priest Lightwell, etc): for (Unit::ControlList::const_iterator itr = player->m_Controlled.begin(); itr != player->m_Controlled.end(); ++itr) { creature->SetInCombatWith(*itr); (*itr)->SetInCombatWith(creature); creature->AddThreat(*itr, 0.0f); }*/ } } }
void UpdateAI(uint32 diff) { if (!UpdateVictim()) return; if( me->GetPositionX() < 490.0f || me->GetPositionX() > 690.0f || me->GetPositionY() < 130.0f || me->GetPositionY() > 410.0f ) { EnterEvadeMode(); return; } events.Update(diff); if (me->HasUnitState(UNIT_STATE_CASTING)) return; switch (events.GetEvent()) { case 0: break; case EVENT_ACTIVATE_CONSTRUCT: me->CastCustomSpell(SPELL_ACTIVATE_CONSTRUCT, SPELLVALUE_MAX_TARGETS, 1, (Unit*)NULL, false); if (++counter >= 20) { me->MonsterYell(TEXT_BERSERK, LANG_UNIVERSAL, 0); me->PlayDirectSound(SOUND_BERSERK); me->CastSpell(me, SPELL_BERSERK, true); events.PopEvent(); break; } events.RepeatEvent(RAID_MODE(40000,30000)); break; case EVENT_SPELL_SCORCH: if( rand()%2 ) { me->MonsterYell(TEXT_SCORCH_1, LANG_UNIVERSAL, 0); me->PlayDirectSound(SOUND_SCORCH_1); } else { me->MonsterYell(TEXT_SCORCH_2, LANG_UNIVERSAL, 0); me->PlayDirectSound(SOUND_SCORCH_2); } me->SetControlled(true, UNIT_STATE_ROOT); me->DisableRotate(true); me->SendMovementFlagUpdate(); me->CastSpell(me->GetVictim(), S_SCORCH, false); events.RepeatEvent(20000); events.RescheduleEvent(EVENT_ENABLE_ROTATE, 3001); break; case EVENT_ENABLE_ROTATE: me->SetControlled(false, UNIT_STATE_ROOT); me->DisableRotate(false); events.PopEvent(); break; case EVENT_SPELL_FLAME_JETS: me->MonsterTextEmote(TEXT_FLAME_JETS, 0, true); me->CastSpell(me->GetVictim(), S_FLAME_JETS, false); events.RepeatEvent(25000); break; case EVENT_GRAB: { std::list<Creature*> icl; me->GetCreaturesWithEntryInRange(icl, 300.0f, NPC_IRON_CONSTRUCT); std::vector<uint64> playerGUIDs; Map::PlayerList const& pl = me->GetMap()->GetPlayers(); Player* temp = NULL; for( Map::PlayerList::const_iterator itr = pl.begin(); itr != pl.end(); ++itr ) { temp = itr->GetSource(); if( !temp->IsAlive() || temp->GetExactDist2d(me) > 90.0f ) continue; if( me->GetVictim() && temp->GetGUID() == me->GetVictim()->GetGUID() ) continue; bool found = false; for( std::list<Creature*>::iterator itr = icl.begin(); itr != icl.end(); ++itr ) if( (*itr)->GetVictim() && (*itr)->GetVictim()->GetGUID() == temp->GetGUID() ) { found = true; break; } if( !found ) playerGUIDs.push_back(temp->GetGUID()); } if( !playerGUIDs.empty() ) { int8 pos = urand(0, playerGUIDs.size()-1); if( Player* pTarget = ObjectAccessor::GetPlayer(*me,playerGUIDs.at(pos)) ) { me->MonsterYell(TEXT_SLAG_POT, LANG_UNIVERSAL, 0); me->PlayDirectSound(SOUND_SLAG_POT); me->CastSpell(pTarget, SPELL_GRAB, false); } } events.RepeatEvent(24000); // +6000 below events.DelayEvents(6000); } break; } DoMeleeAttackIfReady(); }
bool Transport::TeleportTransport(uint32 newMapid, float x, float y, float z) { Map const* oldMap = GetMap(); if (oldMap->GetId() != newMapid) { Map* newMap = sMapMgr->CreateBaseMap(newMapid); Map::PlayerList const& oldPlayers = GetMap()->GetPlayers(); if (!oldPlayers.isEmpty()) { UpdateData data(GetMapId()); BuildOutOfRangeUpdateBlock(&data); WorldPacket packet; data.BuildPacket(&packet); for (Map::PlayerList::const_iterator itr = oldPlayers.begin(); itr != oldPlayers.end(); ++itr) if (itr->GetSource()->GetTransport() != this) itr->GetSource()->SendDirectMessage(&packet); } UnloadStaticPassengers(); GetMap()->RemoveFromMap<Transport>(this, false); SetMap(newMap); Map::PlayerList const& newPlayers = GetMap()->GetPlayers(); if (!newPlayers.isEmpty()) { for (Map::PlayerList::const_iterator itr = newPlayers.begin(); itr != newPlayers.end(); ++itr) { if (itr->GetSource()->GetTransport() != this) { UpdateData data(newMapid); BuildCreateUpdateBlockForPlayer(&data, itr->GetSource()); WorldPacket packet; data.BuildPacket(&packet); itr->GetSource()->SendDirectMessage(&packet); } } } for (std::set<WorldObject*>::iterator itr = _passengers.begin(); itr != _passengers.end();) { WorldObject* obj = (*itr++); float destX, destY, destZ, destO; obj->m_movementInfo.transport.pos.GetPosition(destX, destY, destZ, destO); TransportBase::CalculatePassengerPosition(destX, destY, destZ, &destO, x, y, z, GetOrientation()); switch (obj->GetTypeId()) { case TYPEID_PLAYER: if (!obj->ToPlayer()->TeleportTo(newMapid, destX, destY, destZ, destO, TELE_TO_NOT_LEAVE_TRANSPORT)) _passengers.erase(obj); break; default: RemovePassenger(obj); break; } } Relocate(x, y, z, GetOrientation()); GetMap()->AddToMap<Transport>(this); return true; } else { UpdatePosition(x, y, z, GetOrientation()); return false; } }
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) { if (events.IsInPhase(PHASE_NORMAL)) { case EVENT_BLOODTHIRST: DoCast(me, SPELL_BLOODTHIRST); events.ScheduleEvent(EVENT_BLOODTHIRST, 10000); break; case EVENT_FLAME_SPHERE: DoCastVictim(SPELL_CONJURE_FLAME_SPHERE); events.SetPhase(PHASE_SPECIAL); events.ScheduleEvent(EVENT_CASTING_FLAME_SPHERES, 3000); events.ScheduleEvent(EVENT_FLAME_SPHERE, 15000); break; case EVENT_VANISH: { Map::PlayerList const& players = me->GetMap()->GetPlayers(); uint32 targets = 0; for (Map::PlayerList::const_iterator i = players.begin(); i != players.end(); ++i) { Player* player = i->GetSource(); if (player && player->IsAlive()) ++targets; } if (targets > 2) { Talk(SAY_VANISH); DoCast(me, SPELL_VANISH); events.SetPhase(PHASE_SPECIAL); events.ScheduleEvent(EVENT_JUST_VANISHED, 500); if (Unit* embraceTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)) _embraceTargetGUID = embraceTarget->GetGUID(); } events.ScheduleEvent(EVENT_VANISH, urand(25000, 35000)); break; } } case EVENT_CASTING_FLAME_SPHERES: { events.SetPhase(PHASE_NORMAL); Unit* sphereTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true); if (!sphereTarget) break; float angle, x, y; //DoCast(me, SPELL_FLAME_SPHERE_SUMMON_1); if (Creature* sphere = DoSpawnCreature(CREATURE_FLAME_SPHERE, 0, 0, 5, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 10 * IN_MILLISECONDS)) { angle = sphere->GetAngle(sphereTarget); x = sphere->GetPositionX() + DATA_SPHERE_DISTANCE * std::cos(angle); y = sphere->GetPositionY() + DATA_SPHERE_DISTANCE * std::sin(angle); sphere->GetMotionMaster()->MovePoint(0, x, y, sphere->GetPositionZ()); } if (IsHeroic()) { //DoCast(me, H_SPELL_FLAME_SPHERE_SUMMON_1); if (Creature* sphere = DoSpawnCreature(H_CREATURE_FLAME_SPHERE_1, 0, 0, 5, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 10 * IN_MILLISECONDS)) { angle = sphere->GetAngle(sphereTarget) + DATA_SPHERE_ANGLE_OFFSET; x = sphere->GetPositionX() + DATA_SPHERE_DISTANCE/2 * std::cos(angle); y = sphere->GetPositionY() + DATA_SPHERE_DISTANCE/2 * std::sin(angle); sphere->GetMotionMaster()->MovePoint(0, x, y, sphere->GetPositionZ()); } //DoCast(me, H_SPELL_FLAME_SPHERE_SUMMON_2); if (Creature* sphere = DoSpawnCreature(H_CREATURE_FLAME_SPHERE_2, 0, 0, 5, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 10 * IN_MILLISECONDS)) { angle = sphere->GetAngle(sphereTarget) - DATA_SPHERE_ANGLE_OFFSET; x = sphere->GetPositionX() + DATA_SPHERE_DISTANCE/2 * std::cos(angle); y = sphere->GetPositionY() + DATA_SPHERE_DISTANCE/2 * std::sin(angle); sphere->GetMotionMaster()->MovePoint(0, x, y, sphere->GetPositionZ()); } } break; } case EVENT_JUST_VANISHED: if (Unit* embraceTarget = GetEmbraceTarget()) { me->GetMotionMaster()->Clear(); me->SetSpeed(MOVE_WALK, 2.0f, true); me->GetMotionMaster()->MoveChase(embraceTarget); } events.ScheduleEvent(EVENT_VANISHED, 1300); break; case EVENT_VANISHED: if (Unit* embraceTarget = GetEmbraceTarget()) DoCast(embraceTarget, SPELL_EMBRACE_OF_THE_VAMPYR); Talk(SAY_FEED); me->GetMotionMaster()->Clear(); me->SetSpeed(MOVE_WALK, 1.0f, true); me->GetMotionMaster()->MoveChase(me->GetVictim()); events.ScheduleEvent(EVENT_FEEDING, 20000); break; case EVENT_FEEDING: _embraceTargetGUID = 0; events.SetPhase(PHASE_NORMAL); break; default: break; } } DoMeleeAttackIfReady(); }
void CreatureTextMgr::SendNonChatPacket(WorldObject* source, WorldPacket* data, ChatMsg msgType, WorldObject const* whisperTarget, CreatureTextRange range, Team team, bool gmOnly) const { float dist = GetRangeForChatType(msgType); switch (msgType) { case CHAT_MSG_MONSTER_WHISPER: case CHAT_MSG_RAID_BOSS_WHISPER: { if (range == TEXT_RANGE_NORMAL)//ignores team and gmOnly { if (!whisperTarget || whisperTarget->GetTypeId() != TYPEID_PLAYER) return; whisperTarget->ToPlayer()->GetSession()->SendPacket(data); return; } break; } default: break; } switch (range) { case TEXT_RANGE_AREA: { uint32 areaId = source->GetAreaId(); Map::PlayerList const& players = source->GetMap()->GetPlayers(); for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) if (itr->GetSource()->GetAreaId() == areaId && (!team || Team(itr->GetSource()->GetTeam()) == team) && (!gmOnly || itr->GetSource()->IsGameMaster())) itr->GetSource()->GetSession()->SendPacket(data); return; } case TEXT_RANGE_ZONE: { uint32 zoneId = source->GetZoneId(); Map::PlayerList const& players = source->GetMap()->GetPlayers(); for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) if (itr->GetSource()->GetZoneId() == zoneId && (!team || Team(itr->GetSource()->GetTeam()) == team) && (!gmOnly || itr->GetSource()->IsGameMaster())) itr->GetSource()->GetSession()->SendPacket(data); return; } case TEXT_RANGE_MAP: { Map::PlayerList const& players = source->GetMap()->GetPlayers(); for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) if ((!team || Team(itr->GetSource()->GetTeam()) == team) && (!gmOnly || itr->GetSource()->IsGameMaster())) itr->GetSource()->GetSession()->SendPacket(data); return; } case TEXT_RANGE_WORLD: { SessionMap const& smap = sWorld->GetAllSessions(); for (SessionMap::const_iterator iter = smap.begin(); iter != smap.end(); ++iter) if (Player* player = iter->second->GetPlayer()) if (player->GetSession() && (!team || Team(player->GetTeam()) == team) && (!gmOnly || player->IsGameMaster())) player->GetSession()->SendPacket(data); return; } case TEXT_RANGE_NORMAL: default: break; } source->SendMessageToSetInRange(data, dist, true); }
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_BLOODTHIRST: DoCast(me, SPELL_BLOODTHIRST); events.ScheduleEvent(EVENT_BLOODTHIRST, 10000); break; case EVENT_CONJURE_FLAME_SPHERES: // random target? if (Unit* victim = me->GetVictim()) { _flameSphereTargetGUID = victim->GetGUID(); DoCast(victim, SPELL_CONJURE_FLAME_SPHERE); } events.ScheduleEvent(EVENT_CONJURE_FLAME_SPHERES, 15000); break; case EVENT_VANISH: { Map::PlayerList const& players = me->GetMap()->GetPlayers(); uint32 targets = 0; for (Map::PlayerList::const_iterator i = players.begin(); i != players.end(); ++i) { Player* player = i->GetSource(); if (player && player->IsAlive()) ++targets; } if (targets > 2) { Talk(SAY_VANISH); DoCast(me, SPELL_VANISH); me->SetInCombatState(true); // Prevents the boss from resetting events.DelayEvents(500); events.ScheduleEvent(EVENT_JUST_VANISHED, 500); if (Unit* embraceTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100.0f, true)) _embraceTargetGUID = embraceTarget->GetGUID(); } events.ScheduleEvent(EVENT_VANISH, urand(25000, 35000)); break; } case EVENT_JUST_VANISHED: if (Unit* embraceTarget = GetEmbraceTarget()) { me->GetMotionMaster()->Clear(); me->SetSpeed(MOVE_WALK, 2.0f, true); me->GetMotionMaster()->MoveChase(embraceTarget); } events.ScheduleEvent(EVENT_VANISHED, 1300); break; case EVENT_VANISHED: if (Unit* embraceTarget = GetEmbraceTarget()) DoCast(embraceTarget, SPELL_EMBRACE_OF_THE_VAMPYR); Talk(SAY_FEED); me->GetMotionMaster()->Clear(); me->SetSpeed(MOVE_WALK, 1.0f, true); me->GetMotionMaster()->MoveChase(me->GetVictim()); events.ScheduleEvent(EVENT_FEEDING, 20000); break; case EVENT_FEEDING: _embraceTargetGUID.Clear(); break; default: break; } } DoMeleeAttackIfReady(); }
bool SetBossState(uint32 type, EncounterState state) { if (!InstanceScript::SetBossState(type, state)) return false; switch (type) { case BOSS_LEVIATHAN: case BOSS_IGNIS: case BOSS_RAZORSCALE: case BOSS_XT002: case BOSS_AURIAYA: break; case BOSS_MIMIRON: if (state == DONE) instance->SummonCreature(NPC_MIMIRON_OBSERVATION_RING, ObservationRingKeepersPos[3]); break; case BOSS_FREYA: if (state == DONE) instance->SummonCreature(NPC_FREYA_OBSERVATION_RING, ObservationRingKeepersPos[0]); break; case BOSS_ASSEMBLY_OF_IRON: if (state == DONE) HandleGameObject(ArchivumDoorGUID, true); break; case BOSS_VEZAX: if (state == DONE) HandleGameObject(VezaxDoorGUID, true); break; case BOSS_YOGG_SARON: break; case BOSS_KOLOGARN: if (state == DONE) { if (GameObject* gameObject = instance->GetGameObject(KologarnChestGUID)) { gameObject->SetRespawnTime(gameObject->GetRespawnDelay()); gameObject->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); } HandleGameObject(KologarnBridgeGUID, false); } break; case BOSS_HODIR: if (state == DONE) { if (GameObject* HodirRareCache = instance->GetGameObject(HodirRareCacheGUID)) if (GetData(DATA_HODIR_RARE_CACHE)) HodirRareCache->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); if (GameObject* HodirChest = instance->GetGameObject(HodirChestGUID)) HodirChest->SetRespawnTime(HodirChest->GetRespawnDelay()); HandleGameObject(HodirDoorGUID, true); HandleGameObject(HodirIceDoorGUID, true); instance->SummonCreature(NPC_HODIR_OBSERVATION_RING, ObservationRingKeepersPos[1]); } break; case BOSS_THORIM: if (state == DONE) { if (GameObject* gameObject = instance->GetGameObject(ThorimChestGUID)) gameObject->SetRespawnTime(gameObject->GetRespawnDelay()); instance->SummonCreature(NPC_THORIM_OBSERVATION_RING, ObservationRingKeepersPos[2]); } break; case BOSS_ALGALON: if (state == DONE) { _events.CancelEvent(EVENT_UPDATE_ALGALON_TIMER); _events.CancelEvent(EVENT_DESPAWN_ALGALON); DoUpdateWorldState(WORLD_STATE_ALGALON_TIMER_ENABLED, 0); _algalonTimer = 61; if (GameObject* gameObject = instance->GetGameObject(GiftOfTheObserverGUID)) gameObject->SetRespawnTime(gameObject->GetRespawnDelay()); // get item level (recheck weapons) Map::PlayerList const& players = instance->GetPlayers(); for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) if (Player* player = itr->GetSource()) for (uint8 slot = EQUIPMENT_SLOT_MAINHAND; slot <= EQUIPMENT_SLOT_RANGED; ++slot) if (Item* item = player->GetItemByPos(INVENTORY_SLOT_BAG_0, slot)) if (item->GetTemplate()->ItemLevel > _maxWeaponItemLevel) _maxWeaponItemLevel = item->GetTemplate()->ItemLevel; } else if (state == IN_PROGRESS) { // get item level (armor cannot be swapped in combat) Map::PlayerList const& players = instance->GetPlayers(); for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) { if (Player* player = itr->GetSource()) { for (uint8 slot = EQUIPMENT_SLOT_START; slot < EQUIPMENT_SLOT_END; ++slot) { if (slot == EQUIPMENT_SLOT_TABARD || slot == EQUIPMENT_SLOT_BODY) continue; if (Item* item = player->GetItemByPos(INVENTORY_SLOT_BAG_0, slot)) { if (slot >= EQUIPMENT_SLOT_MAINHAND && slot <= EQUIPMENT_SLOT_RANGED) { if (item->GetTemplate()->ItemLevel > _maxWeaponItemLevel) _maxWeaponItemLevel = item->GetTemplate()->ItemLevel; } else if (item->GetTemplate()->ItemLevel > _maxArmorItemLevel) _maxArmorItemLevel = item->GetTemplate()->ItemLevel; } } } } } break; } return true; }
void UpdateAI(uint32 diff) { if (wipe_timer <= diff) { if (me->GetInstanceScript() && me->GetInstanceScript()->GetData(TYPE_IS_WIPE)) { me->GetInstanceScript()->SetData(TYPE_IS_WIPE, 1); wipe_timer = 2000; } } else wipe_timer -= diff; if (!UpdateVictim()) return; events.Update(diff); if (me->GetHealthPct() < 70.f && status == PHASE_1) { me->AddAura(SPELL_JADE_ESSENCE, me); events.Reset(); events.ScheduleEvent(EVENT_JADE_SERPENT_STRIKE, 5000); events.ScheduleEvent(EVENT_JADE_SERPENT_KICK, 10000); Talk(TALK_EVENT_01); status = PHASE_2; } if (me->GetHealthPct() < 30.f && status == PHASE_2) { events.Reset(); events.ScheduleEvent(EVENT_SUMMON_YULON, 500); Talk(TALK_EVENT_02); status = PHASE_3; } while (uint32 eventId = events.ExecuteEvent()) { switch (eventId) { case EVENT_SERPENT_STRIKE: { me->CastSpell(me->GetVictim(), SPELL_SERPENT_STRIKE, false); Map::PlayerList const& PlayerList = me->GetInstanceScript()->instance->GetPlayers(); if (!PlayerList.isEmpty()) { for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) { Player* plr = i->GetSource(); if (!plr) continue; if (plr->GetDistance2d(me) < 10.f) plr->KnockbackFrom(me->GetPositionX(), me->GetPositionY(), 10, 10); } } events.ScheduleEvent(EVENT_SERPENT_STRIKE, 10000); events.ScheduleEvent(EVENT_SERPENT_WAVE, 4000); } break; case EVENT_SERPENT_KICK: me->CastSpell(me->GetVictim(), SPELL_SERPENT_KICK, false); events.ScheduleEvent(EVENT_SERPENT_KICK, 10000); break; case EVENT_SERPENT_WAVE: { TempSummon* sum = nullptr; sum = me->SummonCreature(CREATURE_TRIGGER_WAVE, 932.775f, -2548.743f, 179.821f, 1.254f); if (sum) { sum->SetDisplayId(11686); sum->CastSpell(sum, SPELL_SERPENT_WAVE_VISUAL, false); sum->CastSpell(sum, SPELL_SERPENT_WAVE_PERIODIC, false); sum->GetMotionMaster()->MovePoint(0, 939.796f, -2530.586f, 179.941f); sum->DespawnOrUnsummon(3200); } sum = me->SummonCreature(CREATURE_TRIGGER_WAVE, 940.014f, -2564.114f, 179.821f, 5.978f); if (sum) { sum->SetDisplayId(11686); sum->CastSpell(sum, SPELL_SERPENT_WAVE_VISUAL, false); sum->CastSpell(sum, SPELL_SERPENT_WAVE_PERIODIC, false); sum->GetMotionMaster()->MovePoint(0, 957.711f, -2570.030f, 179.941f); sum->DespawnOrUnsummon(3200); } sum = me->SummonCreature(CREATURE_TRIGGER_WAVE, 925.971f, -2572.423f, 179.821f, 4.395f); if (sum) { sum->SetDisplayId(11686); sum->CastSpell(sum, SPELL_SERPENT_WAVE_VISUAL, false); sum->CastSpell(sum, SPELL_SERPENT_WAVE_PERIODIC, false); sum->GetMotionMaster()->MovePoint(0, 919.606f, -2591.245f, 179.941f); sum->DespawnOrUnsummon(3200); } sum = me->SummonCreature(CREATURE_TRIGGER_WAVE, 918.923f, -2557.356f, 179.821f, 2.821f); if (sum) { sum->SetDisplayId(11686); sum->CastSpell(sum, SPELL_SERPENT_WAVE_VISUAL, false); sum->CastSpell(sum, SPELL_SERPENT_WAVE_PERIODIC, false); sum->GetMotionMaster()->MovePoint(0, 901.839f, -2551.843f, 179.941f); sum->DespawnOrUnsummon(3200); } } break; case EVENT_JADE_SERPENT_STRIKE: { me->CastSpell(me->GetVictim(), SPELL_JADE_SERPENT_STRIKE, false); Map::PlayerList const& PlayerList = me->GetInstanceScript()->instance->GetPlayers(); if (!PlayerList.isEmpty()) { for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) { Player* plr = i->GetSource(); if (!plr) continue; if (plr->GetDistance2d(me) < 10.f) plr->KnockbackFrom(me->GetPositionX(), me->GetPositionY(), 10, 10); } } events.ScheduleEvent(EVENT_JADE_SERPENT_STRIKE, 10000); events.ScheduleEvent(EVENT_JADE_SERPENT_WAVE, 4000); } break; case EVENT_JADE_SERPENT_KICK: me->CastSpell(me->GetVictim(), SPELL_JADE_SERPENT_KICK, false); events.ScheduleEvent(EVENT_JADE_SERPENT_KICK, 10000); break; case EVENT_JADE_SERPENT_WAVE: { TempSummon* sum = nullptr; sum = me->SummonCreature(CREATURE_TRIGGER_WAVE, 932.775f, -2548.743f, 179.821f, 1.254f); if (sum) { sum->SetDisplayId(11686); sum->CastSpell(sum, SPELL_JADE_SERPENT_WAVE_VISUAL, false); sum->CastSpell(sum, SPELL_SERPENT_WAVE_PERIODIC, false); sum->GetMotionMaster()->MovePoint(0, 939.796f, -2530.586f, 179.941f); sum->DespawnOrUnsummon(3200); } sum = me->SummonCreature(CREATURE_TRIGGER_WAVE, 940.014f, -2564.114f, 179.821f, 5.978f); if (sum) { sum->SetDisplayId(11686); sum->CastSpell(sum, SPELL_JADE_SERPENT_WAVE_VISUAL, false); sum->CastSpell(sum, SPELL_SERPENT_WAVE_PERIODIC, false); sum->GetMotionMaster()->MovePoint(0, 957.711f, -2570.030f, 179.941f); sum->DespawnOrUnsummon(3200); } sum = me->SummonCreature(CREATURE_TRIGGER_WAVE, 925.971f, -2572.423f, 179.821f, 4.395f); if (sum) { sum->SetDisplayId(11686); sum->CastSpell(sum, SPELL_JADE_SERPENT_WAVE_VISUAL, false); sum->CastSpell(sum, SPELL_SERPENT_WAVE_PERIODIC, false); sum->GetMotionMaster()->MovePoint(0, 919.606f, -2591.245f, 179.941f); sum->DespawnOrUnsummon(3200); } sum = me->SummonCreature(CREATURE_TRIGGER_WAVE, 918.923f, -2557.356f, 179.821f, 2.821f); if (sum) { sum->SetDisplayId(11686); sum->CastSpell(sum, SPELL_JADE_SERPENT_WAVE_VISUAL, false); sum->CastSpell(sum, SPELL_SERPENT_WAVE_PERIODIC, false); sum->GetMotionMaster()->MovePoint(0, 901.839f, -2551.843f, 179.941f); sum->DespawnOrUnsummon(3200); } } break; case EVENT_SUMMON_YULON: me->CastSpell(me, SPELL_SUMMON_JADE_SERPENT, false); me->CastSpell(me, SPELL_JADE_SOUL, false); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); me->ApplySpellImmune(SPELL_JADE_SOUL, IMMUNITY_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, true); me->ApplySpellImmune(SPELL_JADE_SOUL, IMMUNITY_DAMAGE, SPELL_SCHOOL_MASK_MAGIC, true); me->SetReactState(REACT_PASSIVE); me->AddUnitState(UNIT_STATE_ROOT); events.ScheduleEvent(EVENT_AURA_JADE, 3000); break; case EVENT_AURA_JADE: me->CastSpell(me, SPELL_JADE_SOUL, false); events.ScheduleEvent(EVENT_AURA_JADE, 2500); break; } } DoMeleeAttackIfReady(); }
void UpdateAI(uint32 diff) { events.Update(diff); uint32 eventId = events.GetEvent(); if (eventId == EVENT_SPELL_INHIBIT_MAGIC) { Map::PlayerList const &PlayerList = me->GetMap()->GetPlayers(); for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) if (Player* player = i->GetSource()) { float dist = me->GetDistance(player); if (player->IsAlive() && dist < 45.0f) { Aura* aura = player->GetAura(SPELL_INHIBIT_MAGIC); if (!aura) aura = me->AddAura(SPELL_INHIBIT_MAGIC, player); else aura->RefreshDuration(); if (aura) aura->SetStackAmount(getStackCount(dist)); } else player->RemoveAurasDueToSpell(SPELL_INHIBIT_MAGIC); } events.RepeatEvent(3000); return; } if (!UpdateVictim()) return; switch (eventId) { case EVENT_SPELL_ATTRACT_MAGIC: me->CastSpell(me, SPELL_ATTRACT_MAGIC, false); events.RepeatEvent(30000); events.RescheduleEvent(EVENT_SPELL_CARNIVOROUS, 1500); break; case EVENT_SPELL_CARNIVOROUS: me->CastSpell(me, DUNGEON_MODE(SPELL_CARNIVOROUS_BITE_N, SPELL_CARNIVOROUS_BITE_H), false); events.RepeatEvent(10000); break; case EVENT_SPELL_FOCUS_FIRE: if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 60.0f, true)) { if (Creature* cr = me->SummonCreature(ENTRY_FOCUS_FIRE, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 7000)) focusGUID = cr->GetGUID(); Talk(EMOTE_FOCUSED, target); } events.RepeatEvent(urand(15000, 20000)); events.ScheduleEvent(EVENT_SPELL_FOCUS_FIRE_2, 3000); events.ScheduleEvent(EVENT_SPELL_FOCUS_FIRE_2, 3500); events.ScheduleEvent(EVENT_SPELL_FOCUS_FIRE_2, 4000); events.ScheduleEvent(EVENT_SPELL_FOCUS_FIRE_3, 5000); me->SetControlled(true, UNIT_STATE_ROOT); break; case EVENT_SPELL_FOCUS_FIRE_2: if (Unit* flare = ObjectAccessor::GetCreature(*me, focusGUID)) me->CastSpell(flare, SPELL_FOCUS_CAST, true); events.PopEvent(); break; case EVENT_SPELL_FOCUS_FIRE_3: me->SetControlled(false, UNIT_STATE_ROOT); events.PopEvent(); break; } DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 diff) { //Inhibitmagic_Timer if (Inhibitmagic_Timer <= diff) { float dist; 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() && (dist = i_pl->IsWithinDist(me, 45))) { i_pl->RemoveAurasDueToSpell(SPELL_INHIBITMAGIC); me->AddAura(SPELL_INHIBITMAGIC, i_pl); if (dist < 35) me->AddAura(SPELL_INHIBITMAGIC, i_pl); if (dist < 25) me->AddAura(SPELL_INHIBITMAGIC, i_pl); if (dist < 15) me->AddAura(SPELL_INHIBITMAGIC, i_pl); } Inhibitmagic_Timer = 3000+(rand()%1000); } else Inhibitmagic_Timer -= diff; //Return since we have no target if (!UpdateVictim()) return; //Attractmagic_Timer if (Attractmagic_Timer <= diff) { DoCast(me, SPELL_ATTRACTMAGIC); Attractmagic_Timer = 30000; Carnivorousbite_Timer = 1500; } else Attractmagic_Timer -= diff; //Carnivorousbite_Timer if (Carnivorousbite_Timer <= diff) { DoCast(me, SPELL_CARNIVOROUSBITE); Carnivorousbite_Timer = 10000; } else Carnivorousbite_Timer -= diff; //FocusFire_Timer if (FocusFire_Timer <= diff) { // Summon Focus Fire & Emote Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1); if (target && target->GetTypeId() == TYPEID_PLAYER && target->IsAlive()) { FocusedTargetGUID = target->GetGUID(); me->SummonCreature(ENTRY_FOCUS_FIRE, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 5500); // TODO: Find better way to handle emote // Emote std::string emote(EMOTE_FOCUSES_ON); emote.append(target->GetName()); emote.push_back('!'); me->MonsterTextEmote(emote, 0, true); } FocusFire_Timer = 15000+(rand()%5000); } else FocusFire_Timer -= diff; DoMeleeAttackIfReady(); }
void UpdateAI(uint32 diff) { if (!UpdateVictim()) return; events.Update(diff); if (me->HasUnitState(UNIT_STATE_CASTING)) return; while (uint32 eventId = events.ExecuteEvent()) { switch (eventId) { case EVENT_SHIMMER: { // Remove old vulnerabilty spell if (CurrentVurln_Spell) me->RemoveAurasDueToSpell(CurrentVurln_Spell); // Cast new random vulnerabilty on self uint32 spell = RAND(SPELL_FIRE_VULNERABILITY, SPELL_FROST_VULNERABILITY, SPELL_SHADOW_VULNERABILITY, SPELL_NATURE_VULNERABILITY, SPELL_ARCANE_VULNERABILITY); DoCast(me, spell); CurrentVurln_Spell = spell; Talk(EMOTE_SHIMMER); events.ScheduleEvent(EVENT_SHIMMER, 45000); break; } case EVENT_BREATH_1: DoCastVictim(Breath1_Spell); events.ScheduleEvent(EVENT_BREATH_1, 60000); break; case EVENT_BREATH_2: DoCastVictim(Breath2_Spell); events.ScheduleEvent(EVENT_BREATH_2, 60000); break; case EVENT_AFFLICTION: { Map::PlayerList const &players = me->GetMap()->GetPlayers(); for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) { if (Player* player = itr->GetSource()->ToPlayer()) { DoCast(player, RAND(SPELL_BROODAF_BLUE, SPELL_BROODAF_BLACK, SPELL_BROODAF_RED, SPELL_BROODAF_BRONZE, SPELL_BROODAF_GREEN), true); if (player->HasAura(SPELL_BROODAF_BLUE) && player->HasAura(SPELL_BROODAF_BLACK) && player->HasAura(SPELL_BROODAF_RED) && player->HasAura(SPELL_BROODAF_BRONZE) && player->HasAura(SPELL_BROODAF_GREEN)) { DoCast(player, SPELL_CHROMATIC_MUT_1); } } } } events.ScheduleEvent(EVENT_AFFLICTION, 10000); break; case EVENT_FRENZY: DoCast(me, SPELL_FRENZY); events.ScheduleEvent(EVENT_FRENZY, urand(10000, 15000)); break; } } // Enrage if not already enraged and below 20% if (!Enraged && HealthBelowPct(20)) { DoCast(me, SPELL_ENRAGE); Enraged = true; } DoMeleeAttackIfReady(); }
void UpdateAI(uint32 diff) { if (!pInstance || !UpdateVictim()) return; Summons.DespawnAll(); events.Update(diff); while (uint32 eventId = events.ExecuteEvent()) { switch (eventId) { case EVENT_LIGHTNING_BOLT: if (me->HasUnitState(UNIT_STATE_CASTING)) return; DoCastVictim(SPELL_LIGHTNING_BOLT); events.ScheduleEvent(EVENT_LIGHTNING_BOLT, 2000); break; case EVENT_CALL_VORTEX: for (uint8 i = 0; i < 8; i++) if (_vortexes[i]) { float _angle; _angle = me->GetAngle(_vortexes[i]->GetPositionX(), _vortexes[i]->GetPositionY()); Position _pos = me->GetNearPosition(5.0f, _angle); _vortexes[i]->GetMotionMaster()->MovementExpired(false); _vortexes[i]->GetMotionMaster()->MovePoint(1, _pos); } events.ScheduleEvent(EVENT_RESET_VORTEX, urand(14000, 17000)); break; case EVENT_RESET_VORTEX: for (uint8 i = 0; i < 8; i++) if (_vortexes[i]) { _vortexes[i]->GetMotionMaster()->MovementExpired(false); _vortexes[i]->GetMotionMaster()->MovePoint(2, ertanvortexPos_1[i]); } events.ScheduleEvent(EVENT_CALL_VORTEX, urand(20000, 25000)); break; case EVENT_STORM_EDGE: _distance = me->GetDistance2d(_vortexes[1]); if (me->GetMap()->GetPlayers().isEmpty()) return; for (Map::PlayerList::const_iterator itr = me->GetMap()->GetPlayers().begin(); itr != me->GetMap()->GetPlayers().end(); ++itr) { if (Player* pPlayer = itr->GetSource()) { if (me->GetDistance2d(pPlayer) > _distance) { //uint8 i = urand(0, 7); //if (_vortexes[i]) //_vortexes[i]->CastSpell(itr->GetSource(), SPELL_STORM_EDGE, true); DoCast(pPlayer, SPELL_STORM_EDGE, true); } } } events.ScheduleEvent(EVENT_STORM_EDGE, 2000); break; } } }
bool Transport::TeleportTransport(uint32 newMapid, float x, float y, float z) { Map const* oldMap = GetMap(); if (oldMap->GetId() != newMapid) { Map* newMap = sMapMgr->CreateBaseMap(newMapid); Map::PlayerList const& oldPlayers = GetMap()->GetPlayers(); if (!oldPlayers.isEmpty()) { UpdateData data; BuildOutOfRangeUpdateBlock(&data); WorldPacket packet; data.BuildPacket(&packet); for (Map::PlayerList::const_iterator itr = oldPlayers.begin(); itr != oldPlayers.end(); ++itr) if (itr->GetSource()->GetTransport() != this) itr->GetSource()->SendDirectMessage(&packet); } UnloadStaticPassengers(); GetMap()->RemoveFromMap<Transport>(this, false); SetMap(newMap); Map::PlayerList const& newPlayers = GetMap()->GetPlayers(); if (!newPlayers.isEmpty()) { for (Map::PlayerList::const_iterator itr = newPlayers.begin(); itr != newPlayers.end(); ++itr) { if (itr->GetSource()->GetTransport() != this) { UpdateData data; BuildCreateUpdateBlockForPlayer(&data, itr->GetSource()); WorldPacket packet; data.BuildPacket(&packet); itr->GetSource()->SendDirectMessage(&packet); } } } for (std::set<WorldObject*>::iterator itr = _passengers.begin(); itr != _passengers.end();) { WorldObject* obj = (*itr++); float destX, destY, destZ, destO; obj->m_movementInfo.transport.pos.GetPosition(destX, destY, destZ, destO); TransportBase::CalculatePassengerPosition(destX, destY, destZ, &destO, x, y, z, GetOrientation()); switch (obj->GetTypeId()) { case TYPEID_UNIT: if (!IS_PLAYER_GUID(obj->ToUnit()->GetOwnerGUID())) // pets should be teleported with player obj->ToCreature()->FarTeleportTo(newMap, destX, destY, destZ, destO); break; case TYPEID_GAMEOBJECT: { GameObject* go = obj->ToGameObject(); go->GetMap()->RemoveFromMap(go, false); go->Relocate(destX, destY, destZ, destO); go->SetMap(newMap); newMap->AddToMap(go); break; } case TYPEID_PLAYER: if (!obj->ToPlayer()->TeleportTo(newMapid, destX, destY, destZ, destO, TELE_TO_NOT_LEAVE_TRANSPORT)) _passengers.erase(obj); break; default: break; } } Relocate(x, y, z, GetOrientation()); GetMap()->AddToMap<Transport>(this); return true; } else { // Teleport players, they need to know it for (std::set<WorldObject*>::iterator itr = _passengers.begin(); itr != _passengers.end(); ++itr) { if ((*itr)->GetTypeId() == TYPEID_PLAYER) { float destX, destY, destZ, destO; (*itr)->m_movementInfo.transport.pos.GetPosition(destX, destY, destZ, destO); TransportBase::CalculatePassengerPosition(destX, destY, destZ, &destO, x, y, z, GetOrientation()); (*itr)->ToUnit()->NearTeleportTo(destX, destY, destZ, destO); } } UpdatePosition(x, y, z, GetOrientation()); return false; } }
void UpdateAI(uint32 diff) { if (!IsInRoom(me)) return; if (!UpdateVictim()) return; events.Update(diff); //if (me->HasUnitState(UNIT_STATE_CASTING)) // return; switch (events.GetEvent()) { case EVENT_SPELL_SPELL_DISRUPTION: me->CastSpell(me, SPELL_SPELL_DISRUPTION, false); events.RepeatEvent(10000); break; case EVENT_SPELL_DECEPIT_FEVER: me->CastSpell(me, RAID_MODE(SPELL_DECREPIT_FEVER_10, SPELL_DECREPIT_FEVER_25), false); events.RepeatEvent(20000); break; case EVENT_SWITCH_PHASE: StartFightPhase(currentPhase == PHASE_SLOW_DANCE ? PHASE_FAST_DANCE : PHASE_SLOW_DANCE); // no pop, there is reset in start fight break; case EVENT_ERUPT_SECTION: if (pInstance) { pInstance->SetData(DATA_HEIGAN_ERUPTION, currentSection); if (currentSection == 3) moveRight = false; else if (currentSection == 0) moveRight = true; moveRight ? currentSection++ : currentSection--; } if (currentPhase == PHASE_SLOW_DANCE && !urand(0,3)) Talk(SAY_TAUNT); events.RepeatEvent(currentPhase == PHASE_SLOW_DANCE ? 10000 : 4000); break; case EVENT_SAFETY_DANCE: { Map::PlayerList const& pList = me->GetMap()->GetPlayers(); for(Map::PlayerList::const_iterator itr = pList.begin(); itr != pList.end(); ++itr) { if (IsInRoom(itr->GetSource()) && !itr->GetSource()->IsAlive()) { events.PopEvent(); pInstance->SetData(DATA_DANCE_FAIL, 0); pInstance->SetData(DATA_IMMORTAL_FAIL, 0); return; } } events.RepeatEvent(5000); return; } } DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 diff) { if (pInstance) { if (!leotherasGUID) leotherasGUID = pInstance->GetData64(DATA_LEOTHERAS); if (!me->IsInCombat() && pInstance->GetData64(DATA_LEOTHERAS_EVENT_STARTER)) { Unit* victim = NULL; victim = Unit::GetUnit(*me, pInstance->GetData64(DATA_LEOTHERAS_EVENT_STARTER)); if (victim) AttackStart(victim); } } if (!UpdateVictim()) { CastChanneling(); return; } if (pInstance && !pInstance->GetData64(DATA_LEOTHERAS_EVENT_STARTER)) { EnterEvadeMode(); return; } if (Mindblast_Timer <= diff) { Unit* pTarget = NULL; pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0); if (pTarget)DoCast(pTarget, SPELL_MINDBLAST); Mindblast_Timer = 10000 + rand() % 5000; } else Mindblast_Timer -= diff; if (Earthshock_Timer <= diff) { Map* pMap = me->GetMap(); Map::PlayerList const& PlayerList = pMap->GetPlayers(); for (Map::PlayerList::const_iterator itr = PlayerList.begin(); itr != PlayerList.end(); ++itr) { if (Player* i_pl = itr->GetSource()) { bool isCasting = false; for (uint8 i = 0; i < CURRENT_MAX_SPELL; ++i) if (i_pl->GetCurrentSpell(i)) isCasting = true; if (isCasting) { DoCast(i_pl, SPELL_EARTHSHOCK); break; } } } Earthshock_Timer = 8000 + rand() % 7000; } else Earthshock_Timer -= diff; DoMeleeAttackIfReady(); }
void SetData(uint32 type, uint32 data) { switch (type) { case DATA_RAGEWINTERCHILLEVENT: Encounters[0] = data; break; case DATA_ANETHERONEVENT: Encounters[1] = data; break; case DATA_KAZROGALEVENT: Encounters[2] = data; break; case DATA_AZGALOREVENT: { Encounters[3] = data; if (data == DONE) { if (ArchiYell)break; ArchiYell = true; Creature* pCreature = instance->GetCreature(Azgalor); if (pCreature) { Creature* pUnit = pCreature->SummonCreature(21987, pCreature->GetPositionX(), pCreature->GetPositionY(), pCreature->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 10000); Map* pMap = pCreature->GetMap(); if (pMap->IsDungeon() && pUnit) { pUnit->SetVisible(false); Map::PlayerList const& PlayerList = pMap->GetPlayers(); if (PlayerList.isEmpty()) return; for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) { if (i->GetSource()) { WorldPacket data(SMSG_MESSAGECHAT, 200); pUnit->BuildMonsterChat(&data, CHAT_MSG_MONSTER_YELL, YELL_EFFORTS, 0, YELL_EFFORTS_NAME, i->GetSource()->GetGUID()); i->GetSource()->GetSession()->SendPacket(&data); WorldPacket data2(SMSG_PLAY_SOUND, 4); data2 << 10986; i->GetSource()->GetSession()->SendPacket(&data2); } } } } } } break; case DATA_ARCHIMONDEEVENT: Encounters[4] = data; break; case DATA_RESET_TRASH_COUNT: Trash = 0; break; case DATA_TRASH: if (data) Trash = data; else Trash--; UpdateWorldState(WORLD_STATE_ENEMYCOUNT, Trash); break; case DATA_ALLIANCE_RETREAT: allianceRetreat = data; OpenDoor(HordeGate, true); SaveToDB(); break; case DATA_HORDE_RETREAT: hordeRetreat = data; OpenDoor(ElfGate, true); SaveToDB(); break; case DATA_RAIDDAMAGE: RaidDamage += data; if (RaidDamage >= MINRAIDDAMAGE) RaidDamage = MINRAIDDAMAGE; break; case DATA_RESET_RAIDDAMAGE: RaidDamage = 0; break; } debug_log("OSCR: Instance Hyjal: Instance data updated for event %u (Data=%u)", type, data); if (data == DONE) SaveToDB(); }
void WaypointReached(uint32 waypointId) override { switch (waypointId) { case 8: SetRun(false); me->SummonCreature(18764, 2181.87f, 112.46f, 89.45f, 0.26f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); break; case 9: Talk(SAY_TH_ARMORY); me->SetVirtualItem(0, THRALL_WEAPON_ITEM); //me->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO, THRALL_WEAPON_INFO); //me->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO+1, 781); me->SetVirtualItem(1, THRALL_SHIELD_ITEM); //me->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO+2, THRALL_SHIELD_INFO); //me->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO+3, 1038); break; case 10: me->SetDisplayId(THRALL_MODEL_EQUIPPED); break; case 11: SetRun(); break; case 15: me->SummonCreature(NPC_RIFLE, 2200.28f, 137.37f, 87.93f, 5.07f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); me->SummonCreature(NPC_WARDEN, 2197.44f, 131.83f, 87.93f, 0.78f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); me->SummonCreature(NPC_VETERAN, 2203.62f, 135.40f, 87.93f, 3.70f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); me->SummonCreature(NPC_VETERAN, 2200.75f, 130.13f, 87.93f, 1.48f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); break; case 21: me->SummonCreature(NPC_RIFLE, 2135.80f, 154.01f, 67.45f, 4.98f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); me->SummonCreature(NPC_WARDEN, 2144.36f, 151.87f, 67.74f, 4.46f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); me->SummonCreature(NPC_VETERAN, 2142.12f, 154.41f, 67.12f, 4.56f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); me->SummonCreature(NPC_VETERAN, 2138.08f, 155.38f, 67.24f, 4.60f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); break; case 25: me->SummonCreature(NPC_RIFLE, 2102.98f, 192.17f, 65.24f, 6.02f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); me->SummonCreature(NPC_WARDEN, 2108.48f, 198.75f, 65.18f, 5.15f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); me->SummonCreature(NPC_VETERAN, 2106.11f, 197.29f, 65.18f, 5.63f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); me->SummonCreature(NPC_VETERAN, 2104.18f, 194.82f, 65.18f, 5.75f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); break; case 29: Talk(SAY_TH_SKARLOC_MEET); me->SummonCreature(ENTRY_SCARLOC, 2036.48f, 271.22f, 63.43f, 5.27f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000); //temporary, skarloc should rather be triggered to walk up to thrall break; case 30: SetEscortPaused(true); me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); SetRun(false); break; case 31: Talk(SAY_TH_MOUNTS_UP); DoMount(); SetRun(); break; case 37: //possibly regular patrollers? If so, remove this and let database handle them me->SummonCreature(NPC_WATCHMAN, 2124.26f, 522.16f, 56.87f, 3.99f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); me->SummonCreature(NPC_WATCHMAN, 2121.69f, 525.37f, 57.11f, 4.01f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); me->SummonCreature(NPC_SENTRY, 2124.65f, 524.55f, 56.63f, 3.98f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); break; case 59: me->SummonCreature(SKARLOC_MOUNT, 2488.64f, 625.77f, 58.26f, 4.71f, TEMPSUMMON_TIMED_DESPAWN, 10000); DoUnmount(); HadMount = false; SetRun(false); break; case 60: me->HandleEmoteCommand(EMOTE_ONESHOT_EXCLAMATION); //make horsie run off SetEscortPaused(true); me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); instance->SetData(TYPE_THRALL_PART2, DONE); SetRun(); break; case 64: SetRun(false); break; case 68: me->SummonCreature(NPC_BARN_PROTECTOR, 2500.22f, 692.60f, 55.50f, 2.84f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); me->SummonCreature(NPC_BARN_LOOKOUT, 2500.13f, 696.55f, 55.51f, 3.38f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); me->SummonCreature(NPC_BARN_GUARDSMAN, 2500.55f, 693.64f, 55.50f, 3.14f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); me->SummonCreature(NPC_BARN_GUARDSMAN, 2500.94f, 695.81f, 55.50f, 3.14f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); break; case 71: SetRun(); break; case 81: SetRun(false); break; case 83: me->SummonCreature(NPC_CHURCH_PROTECTOR, 2627.33f, 646.82f, 56.03f, 4.28f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 5000); me->SummonCreature(NPC_CHURCH_LOOKOUT, 2624.14f, 648.03f, 56.03f, 4.50f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 5000); me->SummonCreature(NPC_CHURCH_GUARDSMAN, 2625.32f, 649.60f, 56.03f, 4.38f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 5000); me->SummonCreature(NPC_CHURCH_GUARDSMAN, 2627.22f, 649.00f, 56.03f, 4.34f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 5000); break; case 84: Talk(SAY_TH_CHURCH_END); SetRun(); break; case 91: me->SetWalk(true); SetRun(false); break; case 93: me->SummonCreature(NPC_INN_PROTECTOR, 2652.71f, 660.31f, 61.93f, 1.67f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); me->SummonCreature(NPC_INN_LOOKOUT, 2648.96f, 662.59f, 61.93f, 0.79f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); me->SummonCreature(NPC_INN_GUARDSMAN, 2657.36f, 662.34f, 61.93f, 2.68f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); me->SummonCreature(NPC_INN_GUARDSMAN, 2656.39f, 659.77f, 61.93f, 2.61f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); break; case 94: if (Creature* Taretha = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_TARETHA))) Taretha->AI()->Talk(SAY_TA_ESCAPED, me); break; case 95: Talk(SAY_TH_MEET_TARETHA); instance->SetData(TYPE_THRALL_PART3, DONE); SetEscortPaused(true); break; case 96: Talk(SAY_TH_EPOCH_WONDER); break; case 97: Talk(SAY_TH_EPOCH_KILL_TARETHA); SetRun(); break; case 98: //trigger epoch Yell("Thrall! Come outside and face your fate! ....") //from here, thrall should not never be allowed to move to point 106 which he currently does. break; case 106: { //trigger taretha to run down outside if (Creature* Taretha = instance->instance->GetCreature(instance->GetGuidData(DATA_TARETHA))) { if (Player* player = GetPlayerForEscort()) ENSURE_AI(npc_escortAI, (Taretha->AI()))->Start(false, true, player->GetGUID()); } //kill credit Creature for quest Map::PlayerList const& players = me->GetMap()->GetPlayers(); for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) { if (Player* player = itr->GetSource()) player->KilledMonsterCredit(20156); } //alot will happen here, thrall and taretha talk, erozion appear at spot to explain me->SummonCreature(EROZION_ENTRY, 2646.47f, 680.416f, 55.38f, 4.16f, TEMPSUMMON_TIMED_DESPAWN, 120000); } break; case 108: //last waypoint, just set Thrall invisible, respawn is turned off me->SetVisible(false); break; } }
void UpdateAI(uint32 diff) { if (!CanStartEvent) // boss is invisible, don't attack { if (CheckCanStart()) { if (Submerged) { me->SetVisible(true); Submerged = false; WaitTimer2 = 500; } if (!Submerged && WaitTimer2 <= diff) // wait 500ms before emerge anim { me->RemoveAllAuras(); me->SetUInt32Value(UNIT_NPC_EMOTESTATE, 0); DoCast(me, SPELL_EMERGE, false); WaitTimer2 = 60000; // never reached WaitTimer = 3000; } else WaitTimer2 -= diff; if (WaitTimer <= diff) // wait 3secs for emerge anim, then attack { WaitTimer = 3000; CanStartEvent = true; // fresh fished from pool me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); } else WaitTimer -= diff; } return; } if (me->getThreatManager().getThreatList().empty()) // check if should evade { if (me->IsInCombat()) EnterEvadeMode(); return; } if (!Submerged) { if (PhaseTimer <= diff) { me->InterruptNonMeleeSpells(false); DoCast(me, SPELL_SUBMERGE); PhaseTimer = 60000; // 60secs submerged Submerged = true; } else PhaseTimer-=diff; if (SpoutTimer <= diff) { me->MonsterTextEmote(EMOTE_SPOUT, 0, true); me->SetReactState(REACT_PASSIVE); me->GetMotionMaster()->MoveRotate(20000, urand(0, 1) ? ROTATE_DIRECTION_LEFT : ROTATE_DIRECTION_RIGHT); SpoutTimer = 45000; WhirlTimer = 20000; // whirl directly after spout RotTimer = 20000; return; } else SpoutTimer -= diff; // Whirl directly after a Spout and at random times if (WhirlTimer <= diff) { WhirlTimer = 18000; DoCast(me, SPELL_WHIRL); } else WhirlTimer -= diff; if (CheckTimer <= diff)//check if there are players in melee range { InRange = false; Map* map = me->GetMap(); Map::PlayerList const &PlayerList = map->GetPlayers(); if (!PlayerList.isEmpty()) { for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) { if (me->IsWithinMeleeRange(i->GetSource())) InRange = true; } } CheckTimer = 2000; } else CheckTimer -= diff; if (RotTimer) { Map* map = me->GetMap(); if (map->IsDungeon()) { Map::PlayerList const &PlayerList = map->GetPlayers(); for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) { if (i->GetSource() && i->GetSource()->IsAlive() && me->HasInArc(float(diff/20000*M_PI*2), i->GetSource()) && me->IsWithinDist(i->GetSource(), SPOUT_DIST) && !i->GetSource()->IsInWater()) DoCast(i->GetSource(), SPELL_SPOUT, true); // only knock back players in arc, in 100yards, not in water } } if (SpoutAnimTimer <= diff) { DoCast(me, SPELL_SPOUT_ANIM, true); SpoutAnimTimer = 1000; } else SpoutAnimTimer -= diff; if (RotTimer <= diff) { RotTimer = 0; } else RotTimer -= diff; return; } if (GeyserTimer <= diff) { Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1); if (!target && me->GetVictim()) target = me->GetVictim(); if (target) DoCast(target, SPELL_GEYSER, true); GeyserTimer = rand()%5000 + 15000; } else GeyserTimer -= diff; if (!InRange) // if on players in melee range cast Waterbolt { if (WaterboltTimer <= diff) { Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0); if (!target && me->GetVictim()) target = me->GetVictim(); if (target) DoCast(target, SPELL_WATERBOLT, true); WaterboltTimer = 3000; } else WaterboltTimer -= diff; } if (!UpdateVictim()) return; DoMeleeAttackIfReady(); } else // submerged { if (PhaseTimer <= diff) { Submerged = false; me->InterruptNonMeleeSpells(false); // shouldn't be any me->RemoveAllAuras(); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); me->RemoveFlag(UNIT_NPC_EMOTESTATE, EMOTE_STATE_SUBMERGED); DoCast(me, SPELL_EMERGE, true); Spawned = false; SpoutTimer = 3000; // directly cast Spout after emerging! PhaseTimer = 120000; return; } else PhaseTimer-=diff; if (me->getThreatManager().getThreatList().empty()) // check if should evade { EnterEvadeMode(); return; } if (!me->IsInCombat()) DoZoneInCombat(); if (!Spawned) { me->SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); // spawn adds for (uint8 i = 0; i < 9; ++i) if (Creature* summoned = me->SummonCreature(i < 6 ? NPC_COILFANG_AMBUSHER : NPC_COILFANG_GUARDIAN, AddPos[i][0], AddPos[i][1], AddPos[i][2], 0, TEMPSUMMON_CORPSE_DESPAWN, 0)) Summons.Summon(summoned); Spawned = true; } } }
void OnCreatureCreate(Creature* creature) { if (TeamIdInInstance == TEAM_NEUTRAL) { Map::PlayerList const &players = instance->GetPlayers(); if (!players.isEmpty()) for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) if (Player* p = itr->GetSource()) if (!p->IsGameMaster()) { TeamIdInInstance = p->GetTeamId(); break; } } switch(creature->GetEntry()) { case NPC_SYLVANAS_PART1: creature->SetVisible(false); NPC_LeaderIntroGUID = creature->GetGUID(); if (TeamIdInInstance == TEAM_ALLIANCE) creature->UpdateEntry(NPC_JAINA_PART1); creature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP | UNIT_NPC_FLAG_QUESTGIVER); creature->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING); break; case NPC_DARK_RANGER_LORALEN: creature->SetVisible(false); NPC_GuardGUID = creature->GetGUID(); if (TeamIdInInstance == TEAM_ALLIANCE) creature->UpdateEntry(NPC_ARCHMAGE_ELANDRA); break; case NPC_UTHER: creature->SetVisible(false); NPC_UtherGUID = creature->GetGUID(); creature->SetReactState(REACT_PASSIVE); break; case NPC_LICH_KING_EVENT: creature->SetVisible(false); NPC_LichKingIntroGUID = creature->GetGUID(); creature->SetReactState(REACT_PASSIVE); creature->AddUnitMovementFlag(MOVEMENTFLAG_WALKING); break; case NPC_FALRIC: creature->SetVisible(false); NPC_FalricGUID = creature->GetGUID(); creature->AddUnitMovementFlag(MOVEMENTFLAG_WALKING); break; case NPC_MARWYN: creature->SetVisible(false); NPC_MarwynGUID = creature->GetGUID(); creature->AddUnitMovementFlag(MOVEMENTFLAG_WALKING); break; case NPC_WAVE_MERCENARY: case NPC_WAVE_FOOTMAN: case NPC_WAVE_RIFLEMAN: case NPC_WAVE_PRIEST: case NPC_WAVE_MAGE: if (TrashCounter < NUM_OF_TRASH) NPC_TrashGUID[TrashCounter++] = creature->GetGUID(); if (!(EncounterMask & (1 << DATA_MARWYN)) && !creature->IsAlive()) creature->Respawn(); creature->SetVisible(false); break; case NPC_FROSTSWORN_GENERAL: if (!(EncounterMask & (1 << DATA_MARWYN))) { creature->SetVisible(false); creature->SetReactState(REACT_PASSIVE); } NPC_FrostswornGeneralGUID = creature->GetGUID(); break; case NPC_SPIRITUAL_REFLECTION: for (uint8 i=0; i<5; ++i) if (!NPC_SpiritualReflectionGUID[i]) { NPC_SpiritualReflectionGUID[i] = creature->GetGUID(); break; } creature->SetVisible(false); break; case NPC_LICH_KING_BOSS: if (!(EncounterMask & (1 << DATA_FROSTSWORN_GENERAL))) creature->SetVisible(false); if (!(EncounterMask & (1 << DATA_LK_INTRO))) { creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_ATTACK2HTIGHT); if (TeamIdInInstance != TEAM_ALLIANCE) { creature->StopMoving(); creature->SetFacingTo(creature->GetAngle(&SylvanasFightPos)); } } else if (!(EncounterMask & (1 << DATA_LICH_KING))) creature->AddAura(TeamIdInInstance == TEAM_ALLIANCE ? SPELL_JAINA_ICE_PRISON : SPELL_SYLVANAS_DARK_BINDING, creature); else creature->SetVisible(false); NPC_LichKingGUID = creature->GetGUID(); creature->SetHealth((creature->GetMaxHealth()*3)/4); creature->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING); break; case NPC_SYLVANAS_PART2: if (!creature->IsAlive()) creature->Respawn(); NPC_LeaderGUID = creature->GetGUID(); if (TeamIdInInstance == TEAM_ALLIANCE) creature->UpdateEntry(NPC_JAINA_PART2); creature->SetHealth(creature->GetMaxHealth()/20); if (!(EncounterMask & (1 << DATA_FROSTSWORN_GENERAL))) creature->SetVisible(false); if (!(EncounterMask & (1 << DATA_LK_INTRO))) { creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, TeamIdInInstance == TEAM_ALLIANCE ? EMOTE_ONESHOT_ATTACK2HTIGHT : EMOTE_ONESHOT_ATTACK1H); creature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP | UNIT_NPC_FLAG_QUESTGIVER); creature->CastSpell(creature, TeamIdInInstance == TEAM_ALLIANCE ? SPELL_JAINA_ICE_BARRIER : SPELL_SYLVANAS_CLOAK_OF_DARKNESS, true); if (TeamIdInInstance != TEAM_ALLIANCE) { creature->UpdatePosition(SylvanasFightPos, true); creature->StopMovingOnCurrentPos(); } } else if (!(EncounterMask & (1 << DATA_LICH_KING))) { creature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER); creature->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); creature->UpdatePosition(LeaderEscapePos, true); creature->StopMovingOnCurrentPos(); } else { instance->LoadGrid(PathWaypoints[PATH_WP_COUNT-1].GetPositionX(), PathWaypoints[PATH_WP_COUNT-1].GetPositionY()); creature->UpdatePosition(PathWaypoints[PATH_WP_COUNT-1], true); creature->StopMovingOnCurrentPos(); } creature->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING); break; case NPC_ICE_WALL_TARGET: if (creature->GetPositionX() > 5525.0f) NPC_IceWallTargetGUID[0] = creature->GetGUID(); else if (creature->GetPositionX() > 5475.0f) NPC_IceWallTargetGUID[1] = creature->GetGUID(); else if (creature->GetPositionX() > 5400.0f) NPC_IceWallTargetGUID[2] = creature->GetGUID(); else NPC_IceWallTargetGUID[3] = creature->GetGUID(); break; case NPC_ALTAR_BUNNY: NPC_AltarBunnyGUID = creature->GetGUID(); break; case NPC_QUEL_DELAR: NPC_QuelDelarGUID = creature->GetGUID(); creature->SetReactState(REACT_PASSIVE); break; case NPC_HIGH_CAPTAIN_JUSTIN_BARLETT: case NPC_SKY_REAVER_KORM_BLACKSKAR: NPC_ShipCaptainGUID = creature->GetGUID(); break; } }
void UpdateAI(uint32 diff) { if (spawnTimer) { spawnTimer += diff; if (spawnTimer >= 21500) { me->SetVisible(true); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); me->SetReactState(REACT_AGGRESSIVE); spawnTimer = 0; } return; } if (!IsInRoom()) return; if (!UpdateVictim()) return; events.Update(diff); if (me->HasUnitState(UNIT_STATE_CASTING)) return; switch (events.GetEvent()) { case EVENT_BERSERK: Talk(EMOTE_ENRAGE); me->CastSpell(me, SPELL_BERSERK, true); events.PopEvent(); return; case EVENT_SPELL_CLEAVE: me->CastSpell(me->GetVictim(), SPELL_CLEAVE, false); events.RepeatEvent(10000); return; case EVENT_SPELL_TAIL_SWEEP: me->CastSpell(me, RAID_MODE(SPELL_TAIL_SWEEP_10, SPELL_TAIL_SWEEP_25), false); events.RepeatEvent(10000); return; case EVENT_SPELL_LIFE_DRAIN: me->CastCustomSpell(RAID_MODE(SPELL_LIFE_DRAIN_10, SPELL_LIFE_DRAIN_25), SPELLVALUE_MAX_TARGETS, RAID_MODE(2, 5), me, false); events.RepeatEvent(24000); return; case EVENT_SPELL_BLIZZARD: { Creature* cr; if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 40.0f, true)) cr = me->SummonCreature(NPC_BLIZZARD, *target, TEMPSUMMON_TIMED_DESPAWN, 16000); else cr = me->SummonCreature(NPC_BLIZZARD, *me, TEMPSUMMON_TIMED_DESPAWN, 16000); if (cr) cr->GetMotionMaster()->MoveRandom(40); events.RepeatEvent(RAID_MODE(8000, 6500)); return; } case EVENT_FLIGHT_START: if (me->HealthBelowPct(11)) { events.PopEvent(); return; } events.RepeatEvent(45000); events.DelayEvents(35000); me->SetReactState(REACT_PASSIVE); me->AttackStop(); float x, y, z, o; me->GetHomePosition(x, y, z, o); me->GetMotionMaster()->MovePoint(POINT_CENTER, x, y, z); return; case EVENT_FLIGHT_LIFTOFF: me->GetMotionMaster()->MoveIdle(); me->SendMeleeAttackStop(me->GetVictim()); me->HandleEmoteCommand(EMOTE_ONESHOT_LIFTOFF); me->SetDisableGravity(true); currentTarget = 0; events.PopEvent(); events.ScheduleEvent(EVENT_FLIGHT_ICEBOLT, 3000); iceboltCount = RAID_MODE(2, 3); return; case EVENT_FLIGHT_ICEBOLT: { events.PopEvent(); if (currentTarget) if (Unit* target = ObjectAccessor::GetUnit(*me, currentTarget)) me->SummonGameObject(GO_ICE_BLOCK, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), target->GetOrientation(), 0.0f, 0.0f, 0.0f, 0.0f, 0); std::vector<Unit*> targets; ThreatContainer::StorageType::const_iterator i = me->getThreatManager().getThreatList().begin(); for (; i != me->getThreatManager().getThreatList().end(); ++i) if ((*i)->getTarget()->GetTypeId() == TYPEID_PLAYER) { bool inList = false; if (!blockList.empty()) for (std::list<uint64>::const_iterator itr = blockList.begin(); itr != blockList.end(); ++itr) if ((*i)->getTarget()->GetGUID() == *itr) { inList = true; break; } if (!inList) targets.push_back((*i)->getTarget()); } if (!targets.empty() && iceboltCount) { std::vector<Unit*>::iterator itr = targets.begin(); advance(itr, urand(0, targets.size()-1)); me->CastSpell(*itr, SPELL_ICEBOLT_CAST, false); blockList.push_back((*itr)->GetGUID()); currentTarget = (*itr)->GetGUID(); --iceboltCount; events.ScheduleEvent(EVENT_FLIGHT_ICEBOLT, (me->GetExactDist(*itr) / 13.0f)*IN_MILLISECONDS); } else events.ScheduleEvent(EVENT_FLIGHT_BREATH, 1000); return; } case EVENT_FLIGHT_BREATH: currentTarget = 0; Talk(EMOTE_BREATH); me->CastSpell(me, SPELL_FROST_MISSILE, false); events.ScheduleEvent(EVENT_FLIGHT_SPELL_EXPLOSION, 8500); events.PopEvent(); return; case EVENT_FLIGHT_SPELL_EXPLOSION: me->CastSpell(me, SPELL_FROST_EXPLOSION, true); events.PopEvent(); events.ScheduleEvent(EVENT_FLIGHT_START_LAND, 3000); return; case EVENT_FLIGHT_START_LAND: if (!blockList.empty()) for (std::list<uint64>::const_iterator itr = blockList.begin(); itr != blockList.end(); ++itr) if (Unit* block = ObjectAccessor::GetUnit(*me, *itr)) block->RemoveAurasDueToSpell(SPELL_ICEBOLT_TRIGGER); blockList.clear(); me->RemoveAllGameObjects(); events.ScheduleEvent(EVENT_LAND, 1000); events.PopEvent(); return; case EVENT_LAND: me->HandleEmoteCommand(EMOTE_ONESHOT_LAND); me->SetDisableGravity(false); events.PopEvent(); events.ScheduleEvent(EVENT_GROUND, 1500); return; case EVENT_GROUND: me->SetReactState(REACT_AGGRESSIVE); me->SetInCombatWithZone(); events.PopEvent(); return; case EVENT_HUNDRED_CLUB: { Map::PlayerList const& pList = me->GetMap()->GetPlayers(); for(Map::PlayerList::const_iterator itr = pList.begin(); itr != pList.end(); ++itr) { if (itr->GetSource()->GetResistance(SPELL_SCHOOL_FROST) > 100 && pInstance) { events.PopEvent(); pInstance->SetData(DATA_HUNDRED_CLUB, 0); return; } } events.RepeatEvent(5000); return; } } DoMeleeAttackIfReady(); }
void SetData(uint32 type, uint32 data) { switch(type) { case DATA_INTRO: EncounterMask |= (1 << DATA_INTRO); AddWave1(); break; case ACTION_SHOW_TRASH: RandomizeCompositionsAndShow(); break; case DATA_FALRIC: if (WaveNumber) { if (data == NOT_STARTED) DoWipe1(); else if (data == DONE) { NextWaveTimer = 60000; EncounterMask |= (1 << DATA_FALRIC); } } break; case DATA_MARWYN: if (WaveNumber) { if (data == NOT_STARTED) DoWipe1(); else if (data == DONE) { EncounterMask |= (1 << DATA_MARWYN); HandleGameObject(GO_FrontDoorGUID, true); HandleGameObject(GO_ArthasDoorGUID, true); if (Creature* c = instance->GetCreature(NPC_FrostswornGeneralGUID)) { c->SetVisible(true); c->SetReactState(REACT_AGGRESSIVE); } WaveNumber = 0; DoUpdateWorldState(WORLD_STATE_HOR_COUNTER, 0); // give quest Map::PlayerList const& pl = instance->GetPlayers(); for (Map::PlayerList::const_iterator itr = pl.begin(); itr != pl.end(); ++itr) if (Player* p = itr->GetSource()) p->CastSpell(p, p->GetTeamId() == TEAM_ALLIANCE ? SPELL_HOR_START_QUEST_ALLY : SPELL_HOR_START_QUEST_HORDE, true); } } break; case DATA_FROSTSWORN_GENERAL: EncounterMask |= (1 << DATA_FROSTSWORN_GENERAL); if (data == DONE) { if (Creature* c = instance->GetCreature(NPC_LichKingGUID)) c->SetVisible(true); if (Creature* c = instance->GetCreature(NPC_LeaderGUID)) c->SetVisible(true); } break; case ACTION_SPIRITUAL_REFLECTIONS_COPY: { uint8 i=0; Map::PlayerList const& pl = instance->GetPlayers(); for (Map::PlayerList::const_iterator itr = pl.begin(); itr != pl.end(); ++itr) if (Player* p = itr->GetSource()) if (p->IsAlive() && !p->IsGameMaster()) if (Creature* c = instance->GetCreature(NPC_SpiritualReflectionGUID[i++])) { if (!c->IsAlive()) c->Respawn(); c->SetDisableGravity(true); c->SetCanFly(true); c->SetVisible(true); Item* i; i = p->GetWeaponForAttack(BASE_ATTACK); c->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 0, i ? i->GetEntry() : 0); i = p->GetWeaponForAttack(OFF_ATTACK); c->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 1, i ? i->GetEntry() : 0); i = p->GetWeaponForAttack(RANGED_ATTACK); c->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 2, i ? i->GetEntry() : 0); p->CastSpell(c, SPELL_HOR_CLONE, true); p->CastSpell(c, SPELL_HOR_CLONE_NAME, true); } } break; case ACTION_SPIRITUAL_REFLECTIONS_ACTIVATE: if (Creature* fg = instance->GetCreature(NPC_FrostswornGeneralGUID)) for (uint8 i=0; i<5; ++i) if (Creature* c = instance->GetCreature(NPC_SpiritualReflectionGUID[i])) if (c->IsVisible()) { c->SetInCombatWithZone(); c->SetDisableGravity(false); c->SetCanFly(false); c->GetMotionMaster()->MoveJump(fg->GetPositionX(), fg->GetPositionY(), fg->GetPositionZ(), 20.0f, 10.0f); } break; case ACTION_SPIRITUAL_REFLECTIONS_HIDE: for (uint8 i=0; i<5; ++i) if (Creature* c = instance->GetCreature(NPC_SpiritualReflectionGUID[i])) c->AI()->EnterEvadeMode(); break; case DATA_LK_INTRO: EncounterMask |= (1 << DATA_LK_INTRO); if (Creature* c = instance->GetCreature(NPC_LeaderGUID)) c->AI()->DoAction(ACTION_START_INTRO); break; case ACTION_START_LK_FIGHT: IsDuringLKFight = true; DoStopTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_RETREATING_TIMED_EVENT); DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_RETREATING_TIMED_EVENT); break; case ACTION_STOP_LK_FIGHT: if (!IsDuringLKFight) break; instance->LoadGrid(LeaderEscapePos.GetPositionX(), LeaderEscapePos.GetPositionY()); if (Creature* c = instance->GetCreature(NPC_LeaderGUID)) { if (!c->IsAlive()) { c->Respawn(); if (TeamIdInInstance == TEAM_ALLIANCE) c->UpdateEntry(NPC_JAINA_PART2); } c->DeleteThreatList(); c->CombatStop(true); c->InterruptNonMeleeSpells(true); c->GetMotionMaster()->Clear(); c->GetMotionMaster()->MoveIdle(); c->UpdatePosition(LeaderEscapePos, true); c->StopMovingOnCurrentPos(); c->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER); c->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); c->SetHealth(c->GetMaxHealth()/20); c->AI()->Reset(); c->setActive(false); c->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING); c->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_NONE); } if (Creature* c = instance->GetCreature(NPC_LichKingGUID)) { c->DeleteThreatList(); c->CombatStop(true); c->InterruptNonMeleeSpells(true); c->GetMotionMaster()->Clear(); c->GetMotionMaster()->MoveIdle(); c->UpdatePosition(c->GetHomePosition(), true); c->StopMovingOnCurrentPos(); c->RemoveAllAuras(); c->AddAura(TeamIdInInstance == TEAM_ALLIANCE ? SPELL_JAINA_ICE_PRISON : SPELL_SYLVANAS_DARK_BINDING, c); c->AI()->Reset(); c->setActive(false); c->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING); c->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_NONE); c->SetSpeed(MOVE_RUN, c->GetCreatureTemplate()->speed_run); } IsDuringLKFight = false; outroTimer = 0; outroStep = 0; // no break intended case ACTION_DELETE_ICE_WALL: HandleGameObject(GO_IceWallGUID, true); GO_IceWallGUID = 0; break; case DATA_LICH_KING: if (data == DONE) { instance->LoadGrid(PathWaypoints[0].GetPositionX(), PathWaypoints[0].GetPositionY()); EncounterMask |= (1 << DATA_LICH_KING); if (Creature* c = instance->GetCreature(NPC_LeaderGUID)) c->setActive(false); if (Creature* c = instance->GetCreature(NPC_LichKingGUID)) c->setActive(false); IsDuringLKFight = false; outroStep = 1; outroTimer = 0; } break; case DATA_BATTERED_HILT: { if (EncounterMask & (1 << DATA_BATTERED_HILT)) return; switch(data) { case 1: // talked to leader EncounterMask |= (1 << DATA_BATTERED_HILT); SaveToDB(); break; case 2: if (BatteredHiltStatus) break; BatteredHiltStatus |= BHSF_STARTED; if (Creature* c = instance->GetCreature(NPC_AltarBunnyGUID)) c->CastSpell(c, 70720, true); if (Creature* c = instance->GetCreature(NPC_UtherGUID)) c->m_Events.AddEvent(new UtherBatteredHiltEvent(*c, 1), c->m_Events.CalculateTime(3000)); break; case 3: if ((BatteredHiltStatus & BHSF_STARTED) == 0 || (BatteredHiltStatus & BHSF_THROWN)) break; BatteredHiltStatus |= BHSF_THROWN; if (Creature* c = instance->GetCreature(NPC_UtherGUID)) { c->AI()->Talk(SAY_BATTERED_HILT_LEAP); c->m_Events.AddEvent(new UtherBatteredHiltEvent(*c, 3), c->m_Events.CalculateTime(1500)); } break; case 4: if (Creature* c = instance->GetCreature(NPC_QuelDelarGUID)) { c->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING); c->SetSpeed(MOVE_RUN, 2.5f); } break; case 5: if (Creature* c = instance->GetCreature(NPC_UtherGUID)) c->m_Events.AddEvent(new UtherBatteredHiltEvent(*c, 6), c->m_Events.CalculateTime(3000)); break; case 6: if (Creature* c = instance->GetCreature(NPC_QuelDelarGUID)) { c->SetSpeed(MOVE_RUN, c->GetCreatureTemplate()->speed_run); c->GetMotionMaster()->MoveLand(0, c->GetPositionX(), c->GetPositionY(), 707.70f, 7.0f); } break; case 7: if (Creature* c = instance->GetCreature(NPC_QuelDelarGUID)) { c->SetReactState(REACT_AGGRESSIVE); c->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_IMMUNE_TO_NPC); c->RemoveAurasDueToSpell(70300); } break; case 8: if (Creature* c = instance->GetCreature(NPC_QuelDelarGUID)) c->SetInCombatWithZone(); break; case 9: EncounterMask |= (1 << DATA_BATTERED_HILT); BatteredHiltStatus |= BHSF_FINISHED; SaveToDB(); break; } } return; } if (data == DONE) SaveToDB(); }
void UpdateAI(const uint32 diff) { npc_escortAI::UpdateAI(diff); if (HasEscortState(STATE_ESCORT_PAUSED)) { if (TalkTimer <= diff) { if (TalkCount > 3) { if (Creature* pSpotlight = Unit::GetCreature(*me, m_uiSpotlightGUID)) pSpotlight->ForcedDespawn(); SetEscortPaused(false); return; } Talk(TalkCount); ++TalkCount; } else TalkTimer -= diff; } if (PerformanceReady) { if (!RaidWiped) { if (WipeTimer <= diff) { Map* pMap = me->GetMap(); if (!pMap->IsDungeon()) return; Map::PlayerList const& PlayerList = pMap->GetPlayers(); if (PlayerList.isEmpty()) return; RaidWiped = true; for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) { if (i->GetSource()->IsAlive() && !i->GetSource()->IsGameMaster()) { RaidWiped = false; break; } } if (RaidWiped) { RaidWiped = true; EnterEvadeMode(); return; } WipeTimer = 15000; } else WipeTimer -= diff; } } }
void Update(uint32 diff) { if (!instance->HavePlayers()) return; if (CheckPlayersTimer <= diff) { CheckPlayersTimer = 5000; if ((EncounterMask & (1 << DATA_INTRO)) && !(EncounterMask & (1 << DATA_MARWYN))) // first event { Map::PlayerList const& pl = instance->GetPlayers(); if (WaveNumber || NextWaveTimer) { bool allDead = true; bool outOfRange = false; for (Map::PlayerList::const_iterator itr = pl.begin(); itr != pl.end(); ++itr) if (Player* p = itr->GetSource()) { if (p->IsGameMaster()) continue; if (p->IsAlive()) allDead = false; if (p->GetExactDist2d(&CenterPos) > MAX_DIST_FROM_CENTER_IN_COMBAT) { outOfRange = true; break; } } if (allDead || outOfRange) DoWipe1(); } else if (!ResumeFirstEventTimer) { bool allInRangeAndAlive = (instance->GetPlayersCountExceptGMs() > 0 ? true : false); for (Map::PlayerList::const_iterator itr = pl.begin(); itr != pl.end(); ++itr) if (Player* p = itr->GetSource()) if (!p->IsGameMaster() && (p->GetExactDist2d(&CenterPos) > MAX_DIST_FROM_CENTER_TO_START || !p->IsAlive())) { allInRangeAndAlive = false; break; } if (allInRangeAndAlive) { ResumeFirstEventTimer = 1; ResumeFirstEventStep = 0; } } } } else CheckPlayersTimer -= diff; if (NextWaveTimer) { if (NextWaveTimer <= diff) { NextWaveTimer = 0; AddWave1(); } else NextWaveTimer -= diff; } if (ResumeFirstEventTimer) { if (ResumeFirstEventTimer <= diff) { switch (ResumeFirstEventStep) { case 0: if (Creature* pFalric = instance->GetCreature(NPC_FalricGUID)) { pFalric->UpdatePosition(5274.9f, 2039.2f, 709.319f, 5.4619f, true); pFalric->StopMovingOnCurrentPos(); pFalric->SetVisible(true); if (pFalric->IsAlive()) { pFalric->GetMotionMaster()->MovePoint(0, FalricMovePos); if (Aura* a = pFalric->AddAura(SPELL_SHADOWMOURNE_VISUAL, pFalric)) a->SetDuration(8000); } } if (Creature* pMarwyn = instance->GetCreature(NPC_MarwynGUID)) { pMarwyn->UpdatePosition(5343.77f, 1973.86f, 709.319f, 2.35173f, true); pMarwyn->StopMovingOnCurrentPos(); pMarwyn->SetVisible(true); if (pMarwyn->IsAlive()) { pMarwyn->GetMotionMaster()->MovePoint(0, MarwynMovePos); if (Aura* a = pMarwyn->AddAura(SPELL_SHADOWMOURNE_VISUAL, pMarwyn)) a->SetDuration(8000); } pMarwyn->MonsterTextEmote("Spirits appear and surround the altar!", 0, true); } ++ResumeFirstEventStep; ResumeFirstEventTimer = 7500; break; case 1: if (Creature* pFalric = instance->GetCreature(NPC_FalricGUID)) pFalric->AI()->Talk(SAY_FALRIC_INTRO_2); SetData(ACTION_SHOW_TRASH, 1); ResumeFirstEventStep = 0; ResumeFirstEventTimer = 0; NextWaveTimer = 7000; break; default: for (uint8 i=0; i<NUM_OF_TRASH; ++i) if (Creature* c = instance->GetCreature(NPC_TrashGUID[i])) c->SetVisible(false); if (Creature* falric = instance->GetCreature(NPC_FalricGUID)) falric->SetVisible(false); if (Creature* marwyn = instance->GetCreature(NPC_MarwynGUID)) marwyn->SetVisible(false); ResumeFirstEventStep = 0; ResumeFirstEventTimer = 0; break; } } else ResumeFirstEventTimer -= diff; } if (outroStep) { if (outroTimer <= diff) { switch (outroStep) { case 1: if (Creature* lk = instance->GetCreature(NPC_LichKingGUID)) { lk->UpdatePosition(PathWaypoints[PATH_WP_COUNT-2], true); lk->StopMovingOnCurrentPos(); lk->RemoveAllAuras(); lk->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_CUSTOM_SPELL_02); if (!lk->IsVisible()) lk->SetVisible(true); if (Creature* leader = instance->GetCreature(NPC_LeaderGUID)) { leader->UpdatePosition(PathWaypoints[PATH_WP_COUNT-1], true); leader->StopMovingOnCurrentPos(); leader->RemoveAllAuras(); leader->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_READY1H); if (!leader->IsVisible()) leader->SetVisible(true); lk->CastSpell(leader, SPELL_HARVEST_SOUL, false); } } ++outroStep; outroTimer = 500; break; case 2: { uint32 entry = TeamIdInInstance == TEAM_ALLIANCE ? GO_THE_SKYBREAKER : GO_ORGRIMS_HAMMER; T1 = sTransportMgr->CreateTransport(entry, 0, instance); ++outroStep; outroTimer = TeamIdInInstance == TEAM_ALLIANCE ? 10000 : 10500; } break; case 3: if (T1) T1->EnableMovement(false); if (Creature* c = instance->GetCreature(NPC_ShipCaptainGUID)) c->AI()->Talk(TeamIdInInstance == TEAM_ALLIANCE ? SAY_FIRE_ALLY : SAY_FIRE_HORDE); if (Creature* c = instance->GetCreature(NPC_LeaderGUID)) { c->RemoveAllAuras(); c->CastSpell(c, SPELL_GUNSHIP_CANNON_FIRE_PERIODIC, true); } if (Creature* c = instance->GetCreature(NPC_LichKingGUID)) { c->InterruptNonMeleeSpells(true); c->RemoveAllAuras(); } ++outroStep; outroTimer = 5000; break; case 4: HandleGameObject(GO_CaveInGUID, false); ++outroStep; outroTimer = 3000; break; case 5: if (Creature* c = instance->GetCreature(NPC_LeaderGUID)) c->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_NONE); if (Creature* c = instance->GetCreature(NPC_LichKingGUID)) { c->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_NONE); c->DeleteThreatList(); c->CombatStop(true); c->InterruptNonMeleeSpells(true); c->SetVisible(false); } if (instance->IsHeroic()) instance->ToInstanceMap()->PermBindAllPlayers(); if (Creature* c = instance->GetCreature(NPC_LeaderGUID)) c->CastSpell(c, SPELL_ACHIEVEMENT_CHECK, true); ++outroStep; outroTimer = 1000; break; case 6: if (T1) T1->EnableMovement(true); ++outroStep; outroTimer = 3500; break; case 7: if (T1) T1->EnableMovement(false); if (Creature* leader = instance->GetCreature(NPC_LeaderGUID)) { uint8 index = TeamIdInInstance == TEAM_ALLIANCE ? 0 : 1; for (uint8 i=0; i<3; ++i) if (StairsPos[index][i].GetPositionX()) if (GameObject* go = leader->SummonGameObject(TeamIdInInstance == TEAM_ALLIANCE ? GO_STAIRS_ALLIANCE : GO_STAIRS_HORDE, StairsPos[index][i].GetPositionX(), StairsPos[index][i].GetPositionY(), StairsPos[index][i].GetPositionZ(), StairsPos[index][i].GetOrientation(), 0.0f, 0.0f, 0.0f, 0.0f, 86400, false)) go->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_INTERACT_COND | GO_FLAG_NOT_SELECTABLE); //Position pos = TeamIdInInstance == TEAM_ALLIANCE ? AllyPortalPos : HordePortalPos; //leader->SummonGameObject(GO_PORTAL_TO_DALARAN, pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation(), 0.0f, 0.0f, 0.0f, 0.0f, 86400); //pos = TeamIdInInstance == TEAM_ALLIANCE ? AllyChestPos : HordeChestPos; //leader->SummonGameObject(instance->GetSpawnMode() ? GO_CHEST_HEROIC : GO_CHEST_NORMAL, pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation(), 0.0f, 0.0f, 0.0f, 0.0f, 86400); } ++outroStep; outroTimer = 1000; break; case 8: if (Creature* c = instance->GetCreature(NPC_ShipCaptainGUID)) c->AI()->Talk(TeamIdInInstance == TEAM_ALLIANCE ? SAY_ONBOARD_ALLY : SAY_ONBOARD_HORDE); if (Creature* c = instance->GetCreature(NPC_LeaderGUID)) { c->AddUnitMovementFlag(MOVEMENTFLAG_WALKING); c->GetMotionMaster()->MovePoint(0, WalkCaveInPos); } ++outroStep; outroTimer = 6000; break; case 9: if (Creature* c = instance->GetCreature(NPC_LeaderGUID)) c->AI()->Talk(TeamIdInInstance == TEAM_ALLIANCE ? SAY_FINAL_ALLY : SAY_FINAL_HORDE); HandleGameObject(GO_CaveInGUID, true); ++outroStep; outroTimer = 11000; break; case 10: ++outroStep; outroTimer = 0; for (Map::PlayerList::const_iterator itr = instance->GetPlayers().begin(); itr != instance->GetPlayers().end(); ++itr) if (Player* p = itr->GetSource()) p->KilledMonsterCredit(NPC_WRATH_OF_THE_LICH_KING_CREDIT, 0); if (TeamIdInInstance == TEAM_ALLIANCE) if (Creature* c = instance->GetCreature(NPC_LeaderGUID)) { c->AI()->Talk(SAY_FINAL_ALLY_SECOND); outroTimer = 10000; } break; case 11: if (Creature* c = instance->GetCreature(NPC_LeaderGUID)) c->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER); ++outroStep; outroTimer = 300*1000; break; case 12: outroStep = 0; outroTimer = 0; if (T1) T1->setActive(false); break; } } else outroTimer -= diff; } }
void UpdateAI(uint32 diff) override { if (!UpdateVictim()) { events.Update(diff); while (uint32 eventId = events.ExecuteEvent()) { switch (eventId) { case EVENT_RESPAWN: { // Respawn all Blackhand Incarcerators std::list<Creature*> creatureList; GetCreatureListWithEntryInGrid(creatureList, me, NPC_BLACKHAND_INCARCERATOR, 35.0f); for (std::list<Creature*>::iterator itr = creatureList.begin(); itr != creatureList.end(); ++itr) if (Creature* creature = *itr) { if (!creature->IsAlive()) creature->Respawn(); creature->AI()->SetData(1, 1); } me->AddAura(SPELL_ENCAGED_EMBERSEER, me); instance->SetBossState(DATA_PYROGAURD_EMBERSEER, NOT_STARTED); break; } case EVENT_PRE_FIGHT_1: { // Set data on all Blackhand Incarcerators std::list<Creature*> creatureList; GetCreatureListWithEntryInGrid(creatureList, me, NPC_BLACKHAND_INCARCERATOR, 35.0f); for (std::list<Creature*>::iterator itr = creatureList.begin(); itr != creatureList.end(); ++itr) { if (Creature* creature = *itr) creature->AI()->SetData(1, 1); } events.ScheduleEvent(EVENT_PRE_FIGHT_2, 32000); break; } case EVENT_PRE_FIGHT_2: me->CastSpell(me, SPELL_FREEZE_ANIM); me->CastSpell(me, SPELL_EMBERSEER_GROWING); Talk(EMOTE_ONE_STACK); break; case EVENT_FIRE_SHIELD: // #### Spell isn't doing any damage ??? #### DoCast(me, SPELL_FIRE_SHIELD); events.ScheduleEvent(EVENT_FIRE_SHIELD, 3000); break; case EVENT_PLAYER_CHECK: { // Check to see if all players in instance have aura SPELL_EMBERSEER_START before starting event bool _hasAura = true; Map::PlayerList const &players = me->GetMap()->GetPlayers(); for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) if (Player* player = itr->GetSource()->ToPlayer()) if (!player->HasAura(SPELL_EMBERSEER_OBJECT_VISUAL)) _hasAura = false; if (_hasAura) { events.ScheduleEvent(EVENT_PRE_FIGHT_1, 1000); instance->SetBossState(DATA_PYROGAURD_EMBERSEER, IN_PROGRESS); } break; } case EVENT_ENTER_COMBAT: AttackStart(me->SelectNearestPlayer(30.0f)); break; default: break; } } return; } events.Update(diff); while (uint32 eventId = events.ExecuteEvent()) { switch (eventId) { case EVENT_FIRE_SHIELD: DoCast(me, SPELL_FIRE_SHIELD); events.ScheduleEvent(EVENT_FIRE_SHIELD, 3000); break; case EVENT_FIRENOVA: DoCast(me, SPELL_FIRENOVA); events.ScheduleEvent(EVENT_FIRENOVA, 6000); break; case EVENT_FLAMEBUFFET: DoCast(me, SPELL_FLAMEBUFFET); events.ScheduleEvent(EVENT_FLAMEBUFFET, 14000); break; case EVENT_PYROBLAST: if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)) DoCast(target, SPELL_PYROBLAST); events.ScheduleEvent(EVENT_PYROBLAST, 15000); break; default: break; } } DoMeleeAttackIfReady(); }
void UpdateAI(uint32 diff) override { //Check if we have a target if (!UpdateVictim()) { //No target so we'll use this section to do our random wispers instance wide //WisperTimer if (WisperTimer <= diff) { //Play random sound to the zone Map::PlayerList const &PlayerList = me->GetMap()->GetPlayers(); for (Map::PlayerList::const_iterator itr = PlayerList.begin(); itr != PlayerList.end(); ++itr) me->PlayDirectSound(RANDOM_SOUND_WHISPER, itr->GetSource()); //One random wisper every 90 - 300 seconds WisperTimer = urand(90000, 300000); } else WisperTimer -= diff; return; } me->SetTarget(ObjectGuid::Empty); uint32 currentPhase = instance->GetData(DATA_CTHUN_PHASE); if (currentPhase == PHASE_CTHUN_STOMACH || currentPhase == PHASE_CTHUN_WEAK) { // EyeTentacleTimer if (EyeTentacleTimer <= diff) { //Spawn the 8 Eye Tentacles in the corret spots SpawnEyeTentacle(0, 20); //south SpawnEyeTentacle(10, 10); //south west SpawnEyeTentacle(20, 0); //west SpawnEyeTentacle(10, -10); //north west SpawnEyeTentacle(0, -20); //north SpawnEyeTentacle(-10, -10); //north east SpawnEyeTentacle(-20, 0); // east SpawnEyeTentacle(-10, 10); // south east EyeTentacleTimer = 30000; // every 30sec in phase 2 } else EyeTentacleTimer -= diff; } switch (currentPhase) { //Transition phase case PHASE_CTHUN_TRANSITION: //PhaseTimer if (PhaseTimer <= diff) { //Switch instance->SetData(DATA_CTHUN_PHASE, PHASE_CTHUN_STOMACH); //Switch to c'thun model me->InterruptNonMeleeSpells(false); DoCast(me, SPELL_TRANSFORM, false); me->SetFullHealth(); me->SetVisible(true); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_NON_ATTACKABLE); //Emerging phase //AttackStart(ObjectAccessor::GetUnit(*me, HoldpPlayer)); DoZoneInCombat(); //Place all units in threat list on outside of stomach Stomach_Map.clear(); for (std::list<HostileReference*>::const_iterator i = me->getThreatManager().getThreatList().begin(); i != me->getThreatManager().getThreatList().end(); ++i) Stomach_Map[(*i)->getUnitGuid()] = false; //Outside stomach //Spawn 2 flesh tentacles FleshTentaclesKilled = 0; //Spawn flesh tentacle for (uint8 i = 0; i < 2; i++) { Creature* spawned = me->SummonCreature(NPC_FLESH_TENTACLE, FleshTentaclePos[i], TEMPSUMMON_CORPSE_DESPAWN); if (!spawned) ++FleshTentaclesKilled; } PhaseTimer = 0; } else PhaseTimer -= diff; break; //Body Phase case PHASE_CTHUN_STOMACH: //Remove Target field me->SetTarget(ObjectGuid::Empty); //Weaken if (FleshTentaclesKilled > 1) { instance->SetData(DATA_CTHUN_PHASE, PHASE_CTHUN_WEAK); Talk(EMOTE_WEAKENED); PhaseTimer = 45000; DoCast(me, SPELL_PURPLE_COLORATION, true); std::unordered_map<ObjectGuid, bool>::iterator i = Stomach_Map.begin(); //Kick all players out of stomach while (i != Stomach_Map.end()) { //Check for valid player Unit* unit = ObjectAccessor::GetUnit(*me, i->first); //Only move units in stomach if (unit && i->second == true) { //Teleport each player out DoTeleportPlayer(unit, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ() + 10, float(rand32() % 6)); //Cast knockback on them DoCast(unit, SPELL_EXIT_STOMACH_KNOCKBACK, true); //Remove the acid debuff unit->RemoveAurasDueToSpell(SPELL_DIGESTIVE_ACID); i->second = false; } ++i; } return; } //Stomach acid if (StomachAcidTimer <= diff) { //Apply aura to all players in stomach std::unordered_map<ObjectGuid, bool>::iterator i = Stomach_Map.begin(); while (i != Stomach_Map.end()) { //Check for valid player Unit* unit = ObjectAccessor::GetUnit(*me, i->first); //Only apply to units in stomach if (unit && i->second == true) { //Cast digestive acid on them DoCast(unit, SPELL_DIGESTIVE_ACID, true); //Check if player should be kicked from stomach if (unit->IsWithinDist3d(&KickPos, 15.0f)) { //Teleport each player out DoTeleportPlayer(unit, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ() + 10, float(rand32() % 6)); //Cast knockback on them DoCast(unit, SPELL_EXIT_STOMACH_KNOCKBACK, true); //Remove the acid debuff unit->RemoveAurasDueToSpell(SPELL_DIGESTIVE_ACID); i->second = false; } } ++i; } StomachAcidTimer = 4000; } else StomachAcidTimer -= diff; //Stomach Enter Timer if (StomachEnterTimer <= diff) { if (Unit* target = SelectRandomNotStomach()) { //Set target in stomach Stomach_Map[target->GetGUID()] = true; target->InterruptNonMeleeSpells(false); target->CastSpell(target, SPELL_MOUTH_TENTACLE, true, NULL, NULL, me->GetGUID()); StomachEnterTarget = target->GetGUID(); StomachEnterVisTimer = 3800; } StomachEnterTimer = 13800; } else StomachEnterTimer -= diff; if (StomachEnterVisTimer && !StomachEnterTarget.IsEmpty()) { if (StomachEnterVisTimer <= diff) { //Check for valid player Unit* unit = ObjectAccessor::GetUnit(*me, StomachEnterTarget); if (unit) { DoTeleportPlayer(unit, STOMACH_X, STOMACH_Y, STOMACH_Z, STOMACH_O); } StomachEnterTarget.Clear(); StomachEnterVisTimer = 0; } else StomachEnterVisTimer -= diff; } //GientClawTentacleTimer if (GiantClawTentacleTimer <= diff) { if (Unit* target = SelectRandomNotStomach()) { //Spawn claw tentacle on the random target if (Creature* spawned = me->SummonCreature(NPC_GIANT_CLAW_TENTACLE, *target, TEMPSUMMON_CORPSE_DESPAWN, 500)) if (spawned->AI()) spawned->AI()->AttackStart(target); } //One giant claw tentacle every minute GiantClawTentacleTimer = 60000; } else GiantClawTentacleTimer -= diff; //GiantEyeTentacleTimer if (GiantEyeTentacleTimer <= diff) { if (Unit* target = SelectRandomNotStomach()) { //Spawn claw tentacle on the random target if (Creature* spawned = me->SummonCreature(NPC_GIANT_EYE_TENTACLE, *target, TEMPSUMMON_CORPSE_DESPAWN, 500)) if (spawned->AI()) spawned->AI()->AttackStart(target); } //One giant eye tentacle every minute GiantEyeTentacleTimer = 60000; } else GiantEyeTentacleTimer -= diff; break; //Weakened state case PHASE_CTHUN_WEAK: //PhaseTimer if (PhaseTimer <= diff) { //Switch instance->SetData(DATA_CTHUN_PHASE, PHASE_CTHUN_STOMACH); //Remove purple coloration me->RemoveAurasDueToSpell(SPELL_PURPLE_COLORATION); //Spawn 2 flesh tentacles FleshTentaclesKilled = 0; //Spawn flesh tentacle for (uint8 i = 0; i < 2; i++) { Creature* spawned = me->SummonCreature(NPC_FLESH_TENTACLE, FleshTentaclePos[i], TEMPSUMMON_CORPSE_DESPAWN); if (!spawned) ++FleshTentaclesKilled; } PhaseTimer = 0; } else PhaseTimer -= diff; break; } }
void SetData(uint32 type, uint32 data) override { switch (type) { case TYPE_MEDIVH: if (data == SPECIAL && m_auiEncounter[0] == IN_PROGRESS) { --mShieldPercent; DoUpdateWorldState(WORLD_STATE_BM_SHIELD, mShieldPercent); if (!mShieldPercent) { if (Creature* medivh = instance->GetCreature(_medivhGUID)) { if (medivh->IsAlive()) { medivh->DealDamage(medivh, medivh->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); m_auiEncounter[0] = FAIL; m_auiEncounter[1] = NOT_STARTED; } } } } else { if (data == IN_PROGRESS) { TC_LOG_DEBUG("scripts", "Instance The Black Morass: Starting event."); InitWorldState(); m_auiEncounter[1] = IN_PROGRESS; ScheduleEventNextPortal(15000); } if (data == DONE) { //this may be completed further out in the post-event TC_LOG_DEBUG("scripts", "Instance The Black Morass: Event completed."); Map::PlayerList const& players = instance->GetPlayers(); if (!players.isEmpty()) { for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) { if (Player* player = itr->GetSource()) { if (player->GetQuestStatus(QUEST_OPENING_PORTAL) == QUEST_STATUS_INCOMPLETE) player->AreaExploredOrEventHappens(QUEST_OPENING_PORTAL); if (player->GetQuestStatus(QUEST_MASTER_TOUCH) == QUEST_STATUS_INCOMPLETE) player->AreaExploredOrEventHappens(QUEST_MASTER_TOUCH); } } } } m_auiEncounter[0] = data; } break; case TYPE_RIFT: if (data == SPECIAL) { if (mRiftPortalCount < 7) ScheduleEventNextPortal(5000); } else m_auiEncounter[1] = data; break; } }
void UpdateAI(uint32 diff) override { if (!UpdateVictim()) return; events.Update(diff); if (me->HasUnitState(UNIT_STATE_CASTING)) return; switch (_stage) { case 0: { while (uint32 eventId = events.ExecuteEvent()) { switch (eventId) { case EVENT_FEROCIOUS_BUTT: DoCastVictim(SPELL_FEROCIOUS_BUTT); events.ScheduleEvent(EVENT_FEROCIOUS_BUTT, urand(15*IN_MILLISECONDS, 30*IN_MILLISECONDS)); return; case EVENT_ARCTIC_BREATH: if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true)) DoCast(target, SPELL_ARCTIC_BREATH); return; case EVENT_WHIRL: DoCastAOE(SPELL_WHIRL); events.ScheduleEvent(EVENT_WHIRL, urand(15*IN_MILLISECONDS, 30*IN_MILLISECONDS)); return; case EVENT_MASSIVE_CRASH: me->GetMotionMaster()->MoveJump(ToCCommonLoc[1].GetPositionX(), ToCCommonLoc[1].GetPositionY(), ToCCommonLoc[1].GetPositionZ(), 20.0f, 20.0f, 0); // 1: Middle of the room SetCombatMovement(false); me->AttackStop(); _stage = 7; //Invalid (Do nothing more than move) return; default: break; } } DoMeleeAttackIfReady(); break; } case 1: DoCastAOE(SPELL_MASSIVE_CRASH); me->StopMoving(); me->AttackStop(); _stage = 2; break; case 2: if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true)) { me->StopMoving(); me->AttackStop(); _trampleTargetGUID = target->GetGUID(); me->SetTarget(_trampleTargetGUID); _trampleCasted = false; SetCombatMovement(false); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_DISABLE_MOVE); me->GetMotionMaster()->Clear(); me->GetMotionMaster()->MoveIdle(); events.ScheduleEvent(EVENT_TRAMPLE, 4*IN_MILLISECONDS); _stage = 3; } else _stage = 6; break; case 3: while (uint32 eventId = events.ExecuteEvent()) { switch (eventId) { case EVENT_TRAMPLE: { if (Unit* target = ObjectAccessor::GetPlayer(*me, _trampleTargetGUID)) { me->StopMoving(); me->AttackStop(); _trampleCasted = false; _movementStarted = true; _trampleTargetX = target->GetPositionX(); _trampleTargetY = target->GetPositionY(); _trampleTargetZ = target->GetPositionZ(); // 2: Hop Backwards me->GetMotionMaster()->MoveJump(2*me->GetPositionX() - _trampleTargetX, 2*me->GetPositionY() - _trampleTargetY, me->GetPositionZ(), 30.0f, 20.0f, 0); _stage = 7; //Invalid (Do nothing more than move) } else _stage = 6; break; } default: break; } } break; case 4: me->StopMoving(); me->AttackStop(); Talk(EMOTE_TRAMPLE_START, sObjectAccessor->GetUnit(*me, _trampleTargetGUID)); me->GetMotionMaster()->MoveCharge(_trampleTargetX, _trampleTargetY, _trampleTargetZ, 42, 1); me->SetTarget(0); _stage = 5; break; case 5: if (_movementFinish) { DoCastAOE(SPELL_TRAMPLE); _movementFinish = false; _stage = 6; return; } if (events.ExecuteEvent() == EVENT_TRAMPLE) { Map::PlayerList const &lPlayers = me->GetMap()->GetPlayers(); for (Map::PlayerList::const_iterator itr = lPlayers.begin(); itr != lPlayers.end(); ++itr) { if (Unit* player = itr->GetSource()) { if (player->IsAlive() && player->IsWithinDistInMap(me, 6.0f)) { DoCastAOE(SPELL_TRAMPLE); events.ScheduleEvent(EVENT_TRAMPLE, 4*IN_MILLISECONDS); break; } } } } break; case 6: if (!_trampleCasted) { DoCast(me, SPELL_STAGGERED_DAZE); Talk(EMOTE_TRAMPLE_CRASH); } else { DoCast(me, SPELL_FROTHING_RAGE, true); Talk(EMOTE_TRAMPLE_FAIL); } _movementStarted = false; me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_DISABLE_MOVE); SetCombatMovement(true); me->GetMotionMaster()->MovementExpired(); me->GetMotionMaster()->Clear(); me->GetMotionMaster()->MoveChase(me->GetVictim()); AttackStart(me->GetVictim()); events.ScheduleEvent(EVENT_MASSIVE_CRASH, 40*IN_MILLISECONDS); events.ScheduleEvent(EVENT_ARCTIC_BREATH, urand(15*IN_MILLISECONDS, 25*IN_MILLISECONDS)); _stage = 0; break; default: break; } }