Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package l2e.scripts.ai.individual.raidbosses;
- import l2e.config.Config;
- import l2e.gameserver.ThreadPoolManager;
- import l2e.gameserver.engine.hookengine.AbstractHookImpl;
- import l2e.gameserver.engine.hookengine.HookType;
- import l2e.gameserver.instancemanager.GrandBossManager;
- import l2e.gameserver.instancemanager.ZoneManager;
- import l2e.gameserver.model.actor.L2Character;
- import l2e.gameserver.model.actor.L2Npc;
- import l2e.gameserver.model.actor.L2Object;
- import l2e.gameserver.model.actor.instance.L2GrandBossInstance;
- import l2e.gameserver.model.actor.instance.L2GuardInstance;
- import l2e.gameserver.model.actor.instance.L2MonsterInstance;
- import l2e.gameserver.model.actor.instance.L2PcInstance;
- import l2e.gameserver.model.skills.SkillTable;
- import l2e.gameserver.model.skills.base.L2Skill;
- import l2e.gameserver.model.skills.stats.StatsSet;
- import l2e.gameserver.model.world.quest.Quest;
- import l2e.gameserver.model.world.zone.L2ZoneType;
- import l2e.gameserver.model.world.zone.Location;
- import l2e.gameserver.model.world.zone.type.L2BossZone;
- import l2e.gameserver.network.game.components.NpcStringId;
- import l2e.gameserver.network.game.serverpackets.EarthQuake;
- import l2e.gameserver.network.game.serverpackets.EventTrigger;
- import l2e.gameserver.network.game.serverpackets.L2GameServerPacket;
- import l2e.gameserver.network.game.serverpackets.SocialAction;
- import l2e.gameserver.network.game.serverpackets.packet.ex.ExSendUIEvent;
- import l2e.gameserver.network.game.serverpackets.packet.ex.ExStartScenePlayer;
- import l2e.gameserver.network.game.serverpackets.packet.info.ExNpcInfo;
- import l2e.gameserver.network.game.serverpackets.packet.show.ExShowScreenMessage;
- import l2e.gameserver.util.Broadcast;
- import l2e.gameserver.util.Rnd;
- import java.util.ArrayList;
- import java.util.List;
- import java.util.concurrent.ScheduledFuture;
- /**
- * User: Mifesto
- * Date: 15:04 / 30.11.2014
- * Team: http://mmo-core.ru/
- * На юге города Руна, в Лесу Неупокоенных находится Жертвенный Алтарь.
- * С помощью него можно зайти в Рейдовую Зону к Линдвиору.
- * Бросить вызов одному из сильнейших рейдовых боссов могут только персонажи 99 уровня,
- * для входа к РБ нужно 49-112 человек (7-16 полных групп) находящиеся в составе командного канала.
- * Внутрь сможет попасть только 1 командный канал.
- * <p>
- * ZONE - 44269 -26152 -1405
- * <p>
- * Рейд - Линдвиор
- * Уровень - 99
- * Количество человек - 49-112(7-16 групп)
- * NPC -Kato Sycamore Maynooth (Като Сиканус) id=33881
- * Примечание - 1 Командный канал (2ая или соло бомжи немогут зайти)
- * <p>
- * Генератор - id=19426
- * Генератор - id=19477
- * Схема генератора - id=19479
- * Линдрако - id=25895(мелкий ползающий) id=29243(летающий) id=29242 id=29241 id=25897 id=25896
- * Линдрако (маленький) - id=19476
- * <p>
- * Система оптимизации графики
- * При походе на Линдвиора, что бы увеличить FPS (количество кадров в секунду),
- * автоматически включается единая система оптимизации.
- * У всех персонажей броня и оружие, кроме головных уборов, становятся одинаковыми.
- * Если у вас нет необходимости в оптимизации графики, то отключите систему, нажав кнопку на мини-карте.
- * <p>
- * Защита
- * Алтарь Жертвоприношений - это огромное круглое здание, в центре которого находится большая башня,
- * а вокруг неё 4 энергоблока. Линдвиор посылает своих бойцов, чтобы уничтожить Энергоблоки,
- * а игроки не должны позволить сломать их.
- * Когда Энергоблоки зарядятся до конца, пушки выстрелят по летающему Линдвиору,
- * и он упадет на землю, после этого начинается фарм Эпического Босса.
- * <p>
- * <p>
- * 1 Этап
- * Первый этап начинается когда Линдвиор спускается на землю, и до того как у него не станет 80% HP.
- * Если стоять перед драконом, можно получить урон от удара ветром, а если стоять со спины,
- * то вы получите урон от удара хвостом.
- * Дракон будет использовать умение Дыхание Ветра - оно наносит урон и отбрасывает спереди дракона,
- * и умение Body Slam, которое наносит урон и оглушает цели вокруг.
- * Во время фарма Линдвиор будет призывать рейдовых бойцов (А).
- * После того, как вы отнимите первые 20% HP у Линдвиора, он взлетит в воздух и использует умение Ярость,
- * которое будет отнимать у всех персонажей по 2500 HP за тик.
- * <p>
- * Используемые умения:
- * - Сотрясение Тела (15271)
- * - Шквальный Ветер (15274)
- * - Прыжок Линдвиора (15430)
- * - Натиск Ветра (15591)
- * <p>
- * Линдрако - id=25895 id=29243 id=29242 id=29241 id=25897 id=25896
- * <p>
- * 2 Этап
- * Сообщение перед взлетом: От линдвиора веет силой
- * Когда HP Линдвиора меньше 80%, он поднимается в воздух и перемещается по всему Алтарю Жертвоприношения,
- * нанося мега удары ветром.
- * С небольшой вероятностью появляются вихри, которые будут затягивать персонажей и наносить урон.
- * Когда HP Линдвиора снизится до 75%, он вызовет огромный вихрь, который будет перемещаться по всей локации.
- * Если вы попадете в гигантский вихрь, ваше HP, MP, CP опустится до 1.
- * Линдвиор также призывает новых рейдовых бойцов (B).
- * Линдрако - id=25895 id=29243 id=29242 id=29241 id=25897 id=25896
- * <p>
- * Используемые умения:
- * - Бешенство Линдвиора (15269)
- * - Шквальный Ветер (15274)
- * <p>
- * <p>
- * 3 Этап
- * Когда HP Линдвиора спускается ниже 60%, он спускается на землю.
- * Он начинает использовать такие же умения, как и на 1 этапе,
- * и дополнительно использует умение Тёмный Ветер - он отражает урон.
- * Это умение легко заметить - Линдвиор потемнеет при его использовании.
- * Также появляются новые рейдовые бойцы (C)
- * Линдрако - id=25895 id=29243 id=29242 id=29241 id=25897 id=25896
- * <p>
- * Используемые умения:
- * - Бешенство Линдвиора (15269)
- * - Дыхание Ветра (15272)
- * - Шквальный Ветер (15274)
- * - Прыжок Линдвиора (15430)
- * <p>
- * 4 Этап
- * HP Линдвиора спускается до 40%, и он опять поднимается в воздух.
- * Этот этап похож на 2 стадию. Когда HP спустится ниже 35%, Рейд Босс призовет Малые Вихри.
- * <p>
- * <p>
- * Используемые умения:
- * - Шквальный Ветер (15274)
- * <p>
- * 5 Этап
- * HP Дракона спускается ниже 20%.
- * Теперь, вам дается 10 минут, чтобы убить Линдвиора.
- * Он использует умение Ярость, и урон по нему снизится.
- * Если вы не успеете убить его за 10 минут, то всех выкинет из рейд зоны.
- * На последнем Этапе Lindvior призывает рейдовых бойцов и вихри, использует умения как на 1 этапе,
- * кроме этого, если вы попадёте в вихрь, то ваша скорость снизится и вас отбросит.
- * <p>
- * Используемые умения:
- * - Шквальный Ветер (15274)
- * - Прыжок Линдвиора (15430)
- * <p>
- * зависимости от HP Линдвиора игрок получает Чешуйки Линдвиора.
- * HP ниже 80%: 1 Чешуйка Линдвиора
- * HP ниже 60%: 2 Чешуйки Линдвиора
- * HP ниже 40%: 3 Чешуйки Линдвиора
- * HP ниже 20%: 4 Чешуйки Линдвиора
- * Чтобы получать Чешуйки Линдвиора, нужно заключить союз с НПЦ в Руне,
- * если расформировать союз или выйти из него, то награду получить нельзя.
- * 100 Чешуек Линдвиора можно обменять на книгу для изучения умения езды на Линдвиоре.
- * <p>
- * http://www.youtube.com/watch?v=hurIT0lyJ70
- */
- public class Lindvior extends Quest
- {
- //Lindvior Status Tracking :
- private static final byte DORMANT = 0; //Lindvior is spawned and no one has entered yet.
- // Entry is unlocked
- private static final byte FIGHTING = 1; //Lindvior is engaged in battle,
- // annihilating his foes. Entry is locked
- private static final byte DEAD = 2; //Lindvior has been killed. Entry is locked
- // Config
- private static final int ACTIVITYTIMEOFLINDVIOR = 120;
- private static final int INACTIVITYTIME = 900000; // 15 min
- private static final boolean EARTH_QUAKE_ON_SPAWN = true;
- // Монстры
- private static final int LINDVIOR_FAKE = 19423;
- private static final int LINDVIOR_GROUND = 25899;
- private static final int LINDVIOR_RAID = 29240;
- private static final int LINDVIOR_FLY = 19424;
- private static final int[] LINDVIOR_SERVITOR = {25895, 29243, 29242, 29241, 25897, 25896};
- // НПЦ
- private static final int NPC_GENERATOR = 19477;
- private static final int NPC_SCHEME_GENERATOR = 19479;
- private static final int NPC_ATTACKER_GENERATORS = 25897;
- private static final int eventTriggerFirstStage = 21170112;
- // zone triggrs
- //private static final int[] EventTriggerRecharge = Util.createRangeArray(21170102, 21170110);
- //private static final int[] EventTriggerCannonShoot = { 21170120, 21170124, 21170130, 21170100 };
- private static final int eventTriggerSecondStage = 21170100;
- // Локации
- private static final Location CENTER_LOCATION = new Location(46424, -26200, -1430);
- // Умения
- private static final L2Skill SKILL = SkillTable.getInstance().getInfo(15605, 1);
- private static final L2GameServerPacket[] GENERATOR_MESSAGES = {
- new ExShowScreenMessage(NpcStringId.YOU_MUST_ACTIVATE_THE_4_GENERATORS, ExShowScreenMessage.TOP_CENTER,
- 7000),
- new ExShowScreenMessage(NpcStringId.PROTECT_THE_GENERATOR, ExShowScreenMessage.TOP_CENTER, 7000)
- };
- private static final Location[] CONTROL_GENERATOR_SPAWNS = {
- new Location(45288, -30360, -1432, 0),
- new Location(48520, -27176, -1438, 0),
- new Location(45272, -23976, -1432, 0),
- new Location(42088, -27160, -1432, 0)
- };
- private static final Location[] SCHEME_GENERATOR_SPAWNS = {
- new Location(48440, -26824, -1438, 0),
- new Location(48392, -27448, -1438, 0),
- new Location(42136, -27480, -1438, 0),
- new Location(42136, -26840, -1438, 0),
- new Location(44936, -24024, -1438, 0),
- new Location(45592, -24008, -1438, 0),
- new Location(45608, -30312, -1438, 0),
- new Location(44984, -30360, -1438, 0)
- };
- private static final Location[] ATTACKER_GENERATOR_SPAWNS = {
- new Location(44863, -24272, -1413, 33713),
- new Location(45675, -24272, -1413, 33713),
- new Location(45675, -30057, -1413, 64987),
- new Location(44863, -30057, -1413, 64987),
- new Location(42350, -27563, -1413, 46871),
- new Location(42350, -26809, -1413, 46871),
- new Location(48220, -26809, -1413, 16383),
- new Location(48220, -27563, -1413, 16383)
- };
- private static final int[][] generatorTriggers = {
- {21170102, 21170103}, {21170104, 21170105}, {21170106, 21170107}, {21170108, 21170109}
- };
- // Зоны
- private final static int ZONE_ID = 12015;
- private static Lindvior _instance;
- protected final int _chargedValues[] = new int[]{0, 0, 0, 0};
- // Spawn data of monsters.
- protected List<L2Npc> _monsterSpawn = new ArrayList<>();
- protected List<L2GuardInstance> _generatorSpawn = new ArrayList<>();
- // Tasks.
- protected ScheduledFuture<?> _socialTask;
- protected ScheduledFuture<?> _announceTask;
- protected ScheduledFuture<?> _skillCastTask;
- protected ScheduledFuture<?> _mobsSpawnTask;
- protected ScheduledFuture<?> _collapseTask;
- protected ScheduledFuture<?> _bigVortexesTask;
- protected ScheduledFuture<?> _smallVortexesTask;
- protected L2GrandBossInstance _lindvior = null;
- protected L2Npc _lindvior2 = null;
- protected L2BossZone _zoneLair;
- protected OnHpChange _hpChange;
- protected int _activeMask = 0;
- protected int _chargedMask = 0;
- protected int _status = 0;
- public Lindvior()
- {
- super();
- addEnterZoneId(ZONE_ID);
- addExitZoneId(ZONE_ID);
- addAskId(NPC_GENERATOR, -1007);
- addFirstTalkId(NPC_GENERATOR);
- registerMobs(NPC_GENERATOR, NPC_ATTACKER_GENERATORS, NPC_SCHEME_GENERATOR, LINDVIOR_FAKE, LINDVIOR_GROUND,
- LINDVIOR_FLY, LINDVIOR_RAID);
- init();
- }
- private static boolean hasFlag(int val, int flag)
- {
- return (val & flag) == flag;
- }
- public static void main(String[] args)
- {
- _instance = new Lindvior();
- }
- public static Lindvior getInstance()
- {
- return _instance;
- }
- private void init()
- {
- _hpChange = new OnHpChange();
- _zoneLair = ZoneManager.getInstance().getZoneById(ZONE_ID, L2BossZone.class);
- StatsSet info = GrandBossManager.getInstance().getStatsSet(LINDVIOR_RAID);
- if (info == null)
- {
- info = new StatsSet();
- info.set("respawn_time", 0);
- GrandBossManager.getInstance().setStatsSet(LINDVIOR_RAID, info);
- }
- int status = GrandBossManager.getInstance().getBossStatus(LINDVIOR_RAID);
- Long respawnTime = info.getLong("respawn_time");
- if (status == FIGHTING || status == DEAD && respawnTime <= System.currentTimeMillis())
- {
- GrandBossManager.getInstance().setBossStatus(LINDVIOR_RAID, DORMANT);
- }
- else if (status == DEAD)
- {
- ThreadPoolManager.getInstance().scheduleGeneral(new UnlockLindvior(),
- respawnTime - System.currentTimeMillis());
- }
- }
- public void setLindviorSpawnTask()
- {
- synchronized (this)
- {
- if (_socialTask == null)
- {
- GrandBossManager.getInstance().setBossStatus(LINDVIOR_RAID, FIGHTING);
- _socialTask = ThreadPoolManager.getInstance().scheduleGeneral(() -> nextStage(1), 1000);
- }
- }
- }
- protected void Clean()
- {
- _status = 0;
- if (_socialTask != null)
- {
- _socialTask.cancel(false);
- _socialTask = null;
- }
- if (_announceTask != null)
- {
- _announceTask.cancel(false);
- _announceTask = null;
- }
- if (_skillCastTask != null)
- {
- _skillCastTask.cancel(false);
- _skillCastTask = null;
- }
- if (_mobsSpawnTask != null)
- {
- _mobsSpawnTask.cancel(false);
- _mobsSpawnTask = null;
- }
- if (_collapseTask != null)
- {
- _collapseTask.cancel(false);
- _collapseTask = null;
- }
- if (_bigVortexesTask != null)
- {
- _bigVortexesTask.cancel(false);
- _bigVortexesTask = null;
- }
- if (_smallVortexesTask != null)
- {
- _smallVortexesTask.cancel(false);
- _smallVortexesTask = null;
- }
- _zoneLair.getCharactersInside().forEach(mob -> {
- if (mob.isNpc())
- {
- mob.onDelete();
- mob.setIsDead(true);
- }
- });
- }
- private void Fail(boolean clean)
- {
- if (clean)
- {
- Clean();
- }
- _zoneLair.oustAllPlayers();
- GrandBossManager.getInstance().setBossStatus(LINDVIOR_RAID, DORMANT);
- }
- @Override
- public String onAsk(L2PcInstance player, L2Npc npc, int ask, int reply)
- {
- if (reply == 1)
- {
- int index = npc.getAiVarInt("index");
- if (!hasFlag(_activeMask, 1 << index))
- {
- _activeMask |= 1 << index;
- npc.setDisplayEffect(0x02);
- sendEventTrigger(true, generatorTriggers[index]);
- if (hasFlag(_activeMask, 0xf))
- {
- nextStage(2);
- }
- }
- }
- return null;
- }
- @Override
- public synchronized String onSkillSee(L2Npc npc, L2PcInstance caster, L2Skill skill, L2Object[] targets,
- boolean isPet)
- {
- if (skill.getId() == 15606 && npc.getNpcId() == NPC_GENERATOR)
- {
- synchronized (_chargedValues)
- {
- int index = npc.getAiVarInt("index");
- if (!hasFlag(_chargedMask, 1 << index))
- {
- _chargedValues[index] += 30;
- _chargedValues[index] = Math.min(_chargedValues[index], 120);
- npc.getKnownList().getKnownPlayersInRadius(1000).forEach(player -> {
- player.sendPacket(new ExShowScreenMessage(NpcStringId.S1_HAS_CHARGED_THE_CANNON,
- ExShowScreenMessage.TOP_CENTER, 10000, caster.getName()));
- player.sendPacket(new ExSendUIEvent(player, 5, 5000, _chargedValues[index], 0,
- NpcStringId.CHARGING.getId()));
- });
- if (_chargedValues[index] >= 120)
- {
- _chargedMask |= 1 << index;
- _chargedValues[index] = 0;
- }
- if (hasFlag(_chargedMask, 0xf))
- {
- nextStage(3);
- }
- }
- }
- }
- return null;
- }
- @Override
- public String onSpawn(L2Npc npc)
- {
- switch (npc.getNpcId())
- {
- case NPC_ATTACKER_GENERATORS:
- {
- npc.getKnownList().getKnownNpcInRadius(1500).forEach(cha -> {
- if (cha.getNpcId() == NPC_SCHEME_GENERATOR)
- {
- ((L2MonsterInstance) npc).attackCharacter(cha);
- ((L2GuardInstance) cha).attackCharacter(npc);
- }
- if (cha.getNpcId() == NPC_GENERATOR)
- {
- ((L2MonsterInstance) npc).addDamageHate(cha, 0, 98);
- }
- });
- break;
- }
- case NPC_SCHEME_GENERATOR:
- {
- ((L2GuardInstance) npc).setCanAttackPlayer(false);
- ((L2GuardInstance) npc).setCanAttackGuard(false);
- break;
- }
- }
- return super.onSpawn(npc);
- }
- @Override
- public String onNpcDie(L2Npc npc, L2Character killer)
- {
- if (npc.getNpcId() == LINDVIOR_RAID)
- {
- if (_mobsSpawnTask != null)
- {
- _mobsSpawnTask.cancel(true);
- _mobsSpawnTask = null;
- }
- _zoneLair.broadcastPacket(new ExShowScreenMessage(NpcStringId
- .HONORABLE_WARRIORS_HAVE_DRIVEN_OFF_LINDVIOR_THE_EVIL_WIND_DRAGON, ExShowScreenMessage.TOP_CENTER,
- 5000));
- GrandBossManager.getInstance().setBossStatus(LINDVIOR_RAID, DEAD);
- long respawnTime = Config.INTERVAL_OF_LINDVIOR_SPAWN + Rnd.get(Config.RANDOM_OF_LINDVIOR_SPAWN);
- // also save the respawn time so that the info is maintained past reboots
- StatsSet info = GrandBossManager.getInstance().getStatsSet(LINDVIOR_RAID);
- info.set("respawn_time", (System.currentTimeMillis() + respawnTime));
- GrandBossManager.getInstance().setStatsSet(LINDVIOR_RAID, info);
- _zoneLair.getCharactersInside().stream().filter(L2Character::isNpc).forEach(mob -> mob
- .getLocationController().delete());
- ThreadPoolManager.getInstance().scheduleGeneral(() -> npc.getLocationController().decay(), 10000L);
- ThreadPoolManager.getInstance().scheduleGeneral(new UnlockLindvior(), respawnTime);
- }
- else if (npc.getNpcId() == NPC_GENERATOR)
- {
- _zoneLair.broadcastPacket(new ExShowScreenMessage(NpcStringId.THE_GENERATOR_HAS_BEEN_DESTROYED,
- ExShowScreenMessage.TOP_CENTER, 5000));
- Clean();
- _collapseTask = ThreadPoolManager.getInstance().scheduleGeneral(() -> Fail(false), 20000L);
- }
- return super.onNpcDie(npc, killer);
- }
- @Override
- public String onFirstTalk(L2Npc npc, L2PcInstance player)
- {
- int index = npc.getAiVarInt("index");
- if (hasFlag(_activeMask, 1 << index))
- {
- return "19477-1.htm";
- }
- return "19477.htm";
- }
- @Override
- public String onEnterZone(L2Character character, L2ZoneType zone)
- {
- if (zone.getId() == ZONE_ID)
- {
- if (_collapseTask != null)
- {
- _collapseTask.cancel(true);
- _collapseTask = null;
- }
- }
- return super.onEnterZone(character, zone);
- }
- @Override
- public String onExitZone(L2Character character, L2ZoneType zone)
- {
- if (zone.getId() == ZONE_ID)
- {
- if (zone.getPlayersInside().isEmpty())
- {
- _collapseTask = ThreadPoolManager.getInstance().scheduleGeneral(() -> Fail(true), INACTIVITYTIME);
- }
- }
- return super.onExitZone(character, zone);
- }
- private void nextStage(int _taskId)
- {
- switch (_taskId)
- {
- case 1: // Спавним генераторы, схемы и аттакеров
- {
- _zoneLair.broadcastPacket(new EventTrigger(eventTriggerFirstStage, true));
- int i = 0;
- L2GuardInstance guard;
- for (Location loc : CONTROL_GENERATOR_SPAWNS)
- {
- guard = (L2GuardInstance) addSpawn(NPC_GENERATOR, loc, false, true);
- guard.setDisplayEffect(0x01);
- guard.setAiVar("index", i++);
- _monsterSpawn.add(guard);
- _generatorSpawn.add(guard);
- }
- L2Npc npc;
- for (Location loc : SCHEME_GENERATOR_SPAWNS)
- {
- npc = addSpawn(NPC_SCHEME_GENERATOR, loc, false, true);
- npc.setIsNoRndWalk(true);
- _monsterSpawn.add(npc);
- }
- _mobsSpawnTask = ThreadPoolManager.getInstance().scheduleAiAtFixedRate(() -> {
- for (Location loc : ATTACKER_GENERATOR_SPAWNS)
- {
- _monsterSpawn.add(addSpawn(NPC_ATTACKER_GENERATORS, loc, false, true));
- }
- }, 20000, 60000);
- _announceTask = ThreadPoolManager.getInstance().scheduleGeneralAtFixedRate(() -> _zoneLair
- .getPlayersInside().forEach(player -> player.sendPacket(Rnd.get(GENERATOR_MESSAGES))), 10000,
- 10000);
- break;
- }
- case 2: // После активации 4х генераторов, ждем их зарядки
- {
- if (_announceTask != null)
- {
- _announceTask.cancel(true);
- _announceTask = null;
- }
- _generatorSpawn.forEach(npc -> {
- npc.setDisplayEffect(0x00);
- npc.broadcastPacket(new ExNpcInfo(npc));
- });
- _zoneLair.getPlayersInside().forEach(player -> {
- player.sendPacket(new EventTrigger(eventTriggerFirstStage, false));
- player.sendPacket(new EventTrigger(eventTriggerSecondStage, true));
- player.showQuestMovie(ExStartScenePlayer.SCENE_LINDVIOR_ARRIVE);
- _generatorSpawn.forEach(npc -> npc.sendInfo(player));
- });
- _lindvior2 = addSpawn(LINDVIOR_FAKE, CENTER_LOCATION, false, true);
- _announceTask = ThreadPoolManager.getInstance().scheduleGeneralAtFixedRate(() -> _zoneLair
- .getPlayersInside().forEach(player -> player.sendPacket(new ExShowScreenMessage(NpcStringId
- .CHARGE_THE_CANNON_USING_THE_GENERATOR, ExShowScreenMessage.TOP_CENTER, 7000))),
- 30000, 10000);
- _skillCastTask = ThreadPoolManager.getInstance().scheduleGeneralAtFixedRate(() -> _generatorSpawn
- .forEach(npc -> {
- int index = npc.getAiVarInt("index");
- if (!npc.isCastingNow() && npc.getFirstEffect(SKILL) == null && !hasFlag(_chargedMask, 1 << index))
- {
- npc.doSimultaneousCast(SKILL);
- }
- }), 25000, 25000);
- break;
- }
- case 3: // После зарядки всех генераторов
- {
- /**
- * 1 Этап
- * Первый этап начинается когда Линдвиор спускается на землю, и до того как у него не станет 80% HP.
- * Если стоять перед драконом, можно получить урон от удара ветром, а если стоять со спины,
- * то вы получите урон от удара хвостом.
- * Дракон будет использовать умение Дыхание Ветра - оно наносит урон и отбрасывает спереди дракона,
- * и умение Body Slam, которое наносит урон и оглушает цели вокруг.
- * Во время фарма Линдвиор будет призывать рейдовых бойцов.
- * Линдрако - id=25895 id=29243 id=29242 id=29241 id=25897 id=25896
- */
- if (_announceTask != null)
- {
- _announceTask.cancel(true);
- _announceTask = null;
- }
- if (_skillCastTask != null)
- {
- _skillCastTask.cancel(true);
- _skillCastTask = null;
- }
- if (_mobsSpawnTask != null)
- {
- _mobsSpawnTask.cancel(true);
- _mobsSpawnTask = null;
- }
- _monsterSpawn.forEach(npc -> {
- if (npc != null)
- {
- npc.onDelete();
- }
- });
- _monsterSpawn.clear();
- ThreadPoolManager.getInstance().scheduleGeneral(() -> _zoneLair.broadcastPacket(new
- ExShowScreenMessage(NpcStringId.LINDVIOR_HAS_FALLEN_FROM_THE_SKY,
- ExShowScreenMessage.TOP_CENTER, 5000)), 15000);
- if (_lindvior2 != null)
- {
- _lindvior2.onDelete();
- }
- _lindvior = (L2GrandBossInstance) addSpawn(LINDVIOR_GROUND, CENTER_LOCATION, false, true);
- _lindvior.getHookContainer().addHook(HookType.ON_HP_CHANGED, _hpChange);
- _zoneLair.getPlayersInside().forEach(_lindvior::sendInfo);
- _mobsSpawnTask = ThreadPoolManager.getInstance().scheduleAiAtFixedRate(() -> spawnServitor(2, 1000,
- _lindvior.getLoc(), LINDVIOR_SERVITOR), 60000, 120000);
- break;
- }
- }
- }
- /**
- * Активируем триггеры зоны
- *
- * @param status статус
- * @param triggers идентификаторы
- */
- private void sendEventTrigger(boolean status, int... triggers)
- {
- L2GameServerPacket[] pakets = new L2GameServerPacket[triggers.length];
- for (int i = 0; i < triggers.length; i++)
- {
- pakets[i] = new EventTrigger(triggers[i], status);
- }
- for (L2GameServerPacket packet : pakets)
- {
- _zoneLair.broadcastPacket(packet);
- }
- }
- /**
- * Призываем монстров
- *
- * @param count количество
- * @param radius разброс
- * @param loc локация
- * @param npcIds списко монстров
- */
- private void spawnServitor(int count, int radius, Location loc, int... npcIds)
- {
- int x = loc.getX(), y = loc.getY();
- if (radius > 0)
- {
- x += Rnd.get(-radius, radius);
- y += Rnd.get(-radius, radius);
- }
- for (int i = 0; i < count; i++)
- {
- _monsterSpawn.add(addSpawn(Rnd.get(npcIds), x, y, loc.getZ(), loc.getHeading(), true, 0, true));
- }
- }
- /**
- * Хит поинт Ченжер, Контролит процен ХП у боссов.
- */
- private class OnHpChange extends AbstractHookImpl
- {
- @Override
- public void onHpChange(L2Character character, L2Character attacker, double damage, double fullDamage)
- {
- if (!character.isNpc())
- {
- return;
- }
- double percent = ((character.getCurrentHp() - damage) / character.getMaxHp()) * 100;
- if (percent <= 20 && _status == 5)
- {
- /**
- * 5 Этап
- * HP Дракона спускается ниже 20%.
- * Теперь, вам дается 10 минут, чтобы убить Линдвиора.
- * Он использует умение Ярость, и урон по нему снизится.
- * Если вы не успеете убить его за 10 минут, то всех выкинет из рейд зоны.
- * На последнем Этапе Lindvior призывает рейдовых бойцов и вихри, использует умения как на 1 этапе,
- * кроме этого, если вы попадёте в вихрь, то ваша скорость снизится и вас отбросит.
- */
- if (_smallVortexesTask != null)
- {
- _smallVortexesTask.cancel(true);
- _smallVortexesTask = null;
- }
- _zoneLair.broadcastPacket(new ExShowScreenMessage(NpcStringId.LINDVIOR_HAS_LANDED,
- ExShowScreenMessage.TOP_CENTER, 5000));
- _lindvior.broadcastPacket(new SocialAction(_lindvior.getObjectId(), 1));
- _lindvior.setIsDead(true);
- _lindvior.onDelete();
- _lindvior = (L2GrandBossInstance) addSpawn(LINDVIOR_RAID, _lindvior.getLoc(), false, true);
- _lindvior.setCurrentHp(_lindvior.getMaxHp() * 0.2);
- _lindvior.getHookContainer().addHook(HookType.ON_HP_CHANGED, _hpChange);
- _collapseTask = ThreadPoolManager.getInstance().scheduleGeneral(Lindvior.this::Clean, 10 * 60 * 1000);
- _status = 6;
- }
- else if (percent <= 35 && _status == 4)
- {
- /**
- * 4 Этап
- * Когда HP спустится ниже 35%, Рейд Босс призовет Малые Вихри.
- */
- _smallVortexesTask = ThreadPoolManager.getInstance().scheduleGeneralAtFixedRate(() -> {
- }, 10000, 10000);
- _status = 5;
- }
- else if (percent <= 40 && _status == 3)
- {
- /**
- * 4 Этап
- * HP Линдвиора спускается до 40%, и он опять поднимается в воздух.
- */
- _lindvior.broadcastPacket(new SocialAction(_lindvior.getObjectId(), 1));
- _lindvior.setIsDead(true);
- _lindvior.onDelete();
- _lindvior = (L2GrandBossInstance) addSpawn(LINDVIOR_FLY, _lindvior.getLoc(), false, true);
- _lindvior.setCurrentHp(_lindvior.getMaxHp() * 0.4);
- _lindvior.getHookContainer().addHook(HookType.ON_HP_CHANGED, _hpChange);
- _status = 4;
- }
- else if (percent <= 60 && _status == 2)
- {
- /**
- * 3 Этап
- * Когда HP Линдвиора спускается ниже 60%, он спускается на землю.
- * Он начинает использовать такие же умения, как и на 1 этапе,
- * и дополнительно использует умение Тёмный Ветер - он отражает урон.
- * Это умение легко заметить - Линдвиор потемнеет при его использовании.
- * Также появляются новые рейдовые бойцы (C)
- * Линдрако - id=25895 id=29243 id=29242 id=29241 id=25897 id=25896
- */
- _lindvior.broadcastPacket(new SocialAction(_lindvior.getObjectId(), 1));
- _lindvior.setIsDead(true);
- _lindvior.onDelete();
- _lindvior = (L2GrandBossInstance) addSpawn(LINDVIOR_RAID, _lindvior.getLoc(), false, true);
- _lindvior.setCurrentHp(_lindvior.getMaxHp() * 0.6);
- _lindvior.getHookContainer().addHook(HookType.ON_HP_CHANGED, _hpChange);
- _status = 3;
- }
- else if (percent <= 75 && _status == 1)
- {
- /**
- * 2 Этап
- * Когда HP Линдвиора снизится до 75%, он вызовет огромный вихрь, который будет перемещаться по всей
- * локации.
- * Если вы попадете в гигантский вихрь, ваше HP, MP, CP опустится до 1.
- * Линдвиор также призывает новых рейдовых бойцов (B).
- * Линдрако - id=25895 id=29243 id=29242 id=29241 id=25897 id=25896
- */
- _bigVortexesTask = ThreadPoolManager.getInstance().scheduleGeneralAtFixedRate(() -> {
- }, 10000, 10000);
- _status = 2;
- }
- else if (percent <= 80 && _status == 0)
- {
- /**
- * 2 Этап
- * Когда HP Линдвиора меньше 80%, он поднимается в воздух и перемещается по всему Алтарю
- * Жертвоприношения,
- * нанося мега удары ветром.
- * С небольшой вероятностью появляются вихри, которые будут затягивать персонажей и наносить урон.
- */
- _lindvior.broadcastPacket(new SocialAction(_lindvior.getObjectId(), 1));
- _lindvior.setIsDead(true);
- _lindvior.onDelete();
- _lindvior = (L2GrandBossInstance) addSpawn(LINDVIOR_FLY, _lindvior.getLoc(), false, true);
- _lindvior.setCurrentHp(_lindvior.getMaxHp() * 0.8);
- _lindvior.getHookContainer().addHook(HookType.ON_HP_CHANGED, _hpChange);
- _status = 1;
- }
- }
- }
- /**
- * Обновляем статус босса при его респауне.
- */
- private class UnlockLindvior implements Runnable
- {
- @Override
- public void run()
- {
- GrandBossManager.getInstance().setBossStatus(LINDVIOR_RAID, DORMANT);
- if (EARTH_QUAKE_ON_SPAWN)
- {
- Broadcast.toAllOnlinePlayers(new EarthQuake(CENTER_LOCATION.getX(), CENTER_LOCATION.getY(),
- CENTER_LOCATION.getZ(), CENTER_LOCATION.getHeading(), 10));
- }
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement