From 5902d813a28b7a65d6453597da4d6e6399d53189 Mon Sep 17 00:00:00 2001 From: MobiusDevelopment <8391001+MobiusDevelopment@users.noreply.github.com> Date: Wed, 22 Apr 2020 08:52:31 +0000 Subject: [PATCH] Helios changes. Source: Liamxroy --- .../data/scripts/ai/bosses/Helios/Helios.java | 379 +++++++++++++++++- .../scripts/ai/bosses/Helios/Helios1.java | 182 +++++++++ .../scripts/ai/bosses/Helios/Helios2.java | 182 +++++++++ .../scripts/ai/bosses/Helios/Helios3.java | 187 +++++++++ .../ai/bosses/Helios/RoyalArchmageMinion.java | 177 ++++++++ .../data/scripts/ai/bosses/Helios/Helios.java | 379 +++++++++++++++++- .../scripts/ai/bosses/Helios/Helios1.java | 182 +++++++++ .../scripts/ai/bosses/Helios/Helios2.java | 182 +++++++++ .../scripts/ai/bosses/Helios/Helios3.java | 187 +++++++++ .../ai/bosses/Helios/RoyalArchmageMinion.java | 177 ++++++++ .../data/scripts/ai/bosses/Helios/Helios.java | 379 +++++++++++++++++- .../scripts/ai/bosses/Helios/Helios1.java | 182 +++++++++ .../scripts/ai/bosses/Helios/Helios2.java | 182 +++++++++ .../scripts/ai/bosses/Helios/Helios3.java | 187 +++++++++ .../ai/bosses/Helios/RoyalArchmageMinion.java | 177 ++++++++ .../data/scripts/ai/bosses/Helios/Helios.java | 379 +++++++++++++++++- .../scripts/ai/bosses/Helios/Helios1.java | 182 +++++++++ .../scripts/ai/bosses/Helios/Helios2.java | 182 +++++++++ .../scripts/ai/bosses/Helios/Helios3.java | 187 +++++++++ .../ai/bosses/Helios/RoyalArchmageMinion.java | 177 ++++++++ .../data/scripts/ai/bosses/Helios/Helios.java | 379 +++++++++++++++++- .../scripts/ai/bosses/Helios/Helios1.java | 182 +++++++++ .../scripts/ai/bosses/Helios/Helios2.java | 182 +++++++++ .../scripts/ai/bosses/Helios/Helios3.java | 187 +++++++++ .../ai/bosses/Helios/RoyalArchmageMinion.java | 177 ++++++++ .../data/scripts/ai/bosses/Helios/Helios.java | 379 +++++++++++++++++- .../scripts/ai/bosses/Helios/Helios1.java | 182 +++++++++ .../scripts/ai/bosses/Helios/Helios2.java | 182 +++++++++ .../scripts/ai/bosses/Helios/Helios3.java | 187 +++++++++ .../ai/bosses/Helios/RoyalArchmageMinion.java | 177 ++++++++ 30 files changed, 6582 insertions(+), 60 deletions(-) create mode 100644 L2J_Mobius_3.0_Helios/dist/game/data/scripts/ai/bosses/Helios/Helios1.java create mode 100644 L2J_Mobius_3.0_Helios/dist/game/data/scripts/ai/bosses/Helios/Helios2.java create mode 100644 L2J_Mobius_3.0_Helios/dist/game/data/scripts/ai/bosses/Helios/Helios3.java create mode 100644 L2J_Mobius_3.0_Helios/dist/game/data/scripts/ai/bosses/Helios/RoyalArchmageMinion.java create mode 100644 L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/ai/bosses/Helios/Helios1.java create mode 100644 L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/ai/bosses/Helios/Helios2.java create mode 100644 L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/ai/bosses/Helios/Helios3.java create mode 100644 L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/ai/bosses/Helios/RoyalArchmageMinion.java create mode 100644 L2J_Mobius_5.0_Salvation/dist/game/data/scripts/ai/bosses/Helios/Helios1.java create mode 100644 L2J_Mobius_5.0_Salvation/dist/game/data/scripts/ai/bosses/Helios/Helios2.java create mode 100644 L2J_Mobius_5.0_Salvation/dist/game/data/scripts/ai/bosses/Helios/Helios3.java create mode 100644 L2J_Mobius_5.0_Salvation/dist/game/data/scripts/ai/bosses/Helios/RoyalArchmageMinion.java create mode 100644 L2J_Mobius_5.5_EtinasFate/dist/game/data/scripts/ai/bosses/Helios/Helios1.java create mode 100644 L2J_Mobius_5.5_EtinasFate/dist/game/data/scripts/ai/bosses/Helios/Helios2.java create mode 100644 L2J_Mobius_5.5_EtinasFate/dist/game/data/scripts/ai/bosses/Helios/Helios3.java create mode 100644 L2J_Mobius_5.5_EtinasFate/dist/game/data/scripts/ai/bosses/Helios/RoyalArchmageMinion.java create mode 100644 L2J_Mobius_6.0_Fafurion/dist/game/data/scripts/ai/bosses/Helios/Helios1.java create mode 100644 L2J_Mobius_6.0_Fafurion/dist/game/data/scripts/ai/bosses/Helios/Helios2.java create mode 100644 L2J_Mobius_6.0_Fafurion/dist/game/data/scripts/ai/bosses/Helios/Helios3.java create mode 100644 L2J_Mobius_6.0_Fafurion/dist/game/data/scripts/ai/bosses/Helios/RoyalArchmageMinion.java create mode 100644 L2J_Mobius_7.0_PreludeOfWar/dist/game/data/scripts/ai/bosses/Helios/Helios1.java create mode 100644 L2J_Mobius_7.0_PreludeOfWar/dist/game/data/scripts/ai/bosses/Helios/Helios2.java create mode 100644 L2J_Mobius_7.0_PreludeOfWar/dist/game/data/scripts/ai/bosses/Helios/Helios3.java create mode 100644 L2J_Mobius_7.0_PreludeOfWar/dist/game/data/scripts/ai/bosses/Helios/RoyalArchmageMinion.java diff --git a/L2J_Mobius_3.0_Helios/dist/game/data/scripts/ai/bosses/Helios/Helios.java b/L2J_Mobius_3.0_Helios/dist/game/data/scripts/ai/bosses/Helios/Helios.java index 0f70177f83..9b7f63de07 100644 --- a/L2J_Mobius_3.0_Helios/dist/game/data/scripts/ai/bosses/Helios/Helios.java +++ b/L2J_Mobius_3.0_Helios/dist/game/data/scripts/ai/bosses/Helios/Helios.java @@ -16,30 +16,59 @@ */ package ai.bosses.Helios; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ScheduledFuture; + import org.l2jmobius.Config; +import org.l2jmobius.commons.concurrent.ThreadPool; +import org.l2jmobius.gameserver.enums.Movie; import org.l2jmobius.gameserver.instancemanager.GrandBossManager; import org.l2jmobius.gameserver.instancemanager.ZoneManager; import org.l2jmobius.gameserver.model.Location; import org.l2jmobius.gameserver.model.StatSet; import org.l2jmobius.gameserver.model.actor.Npc; +import org.l2jmobius.gameserver.model.actor.instance.GrandBossInstance; import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; +import org.l2jmobius.gameserver.model.holders.SkillHolder; +import org.l2jmobius.gameserver.model.holders.SpawnHolder; import org.l2jmobius.gameserver.model.zone.type.NoSummonFriendZone; import org.l2jmobius.gameserver.network.NpcStringId; import org.l2jmobius.gameserver.network.serverpackets.ExShowScreenMessage; +import org.l2jmobius.gameserver.util.Broadcast; import ai.AbstractNpcAI; /** - * @author Mobius + * @author Mobius, NviX */ public class Helios extends AbstractNpcAI { - // NPCs + // Raid private static final int HELIOS1 = 29303; private static final int HELIOS2 = 29304; private static final int HELIOS3 = 29305; + // Minions + private static final int LEOPOLD = 29306; + private static final int HELIOS_RED_LIGHTNING = 29307; + private static final int HELIOS_BLUE_LIGHTNING = 29308; + private static final int LEOPOLD_ORIGIN = 29309; + private static final int ENUMA_ELISH_ORIGIN = 29310; + private static final int ROYAL_TEMPLAR_COLONEL = 29311; + private static final int ROYAL_SHARPSHOOTER = 29312; + private static final int ROYAL_ARCHMAGE = 29313; + private static final int ROYAL_GATEKEEPER = 29314; + private static final int MIMILLION = 29315; + private static final int MIMILLUS = 29316; // Location private static final Location HELIOS_SPAWN_LOC = new Location(92771, 161909, 3494, 38329); + private static final Location BLUE_LIGHTNING_SPEAR_LOC = new Location(93208, 161269, 3489); + private static final Location RED_LIGHTNING_SPEAR_LOC = new Location(92348, 162558, 3489); + private static final Location MIMILLION_LOC = new Location(92465, 162465, 3487); + private static final Location MIMILLUS_LOC = new Location(93174, 161394, 3487); + private static final Location LEOPOLD_LOC = new Location(93531, 162415, 3487); + private static final Location LEOPOLD_ORIGIN_LOC = new Location(92601, 162196, 3464); + private static final Location ENUMA_ELISH_ORIGIN_LOC = new Location(92957, 161640, 3485); // Zone private static final int ZONE_ID = 210109; // Status @@ -47,14 +76,73 @@ public class Helios extends AbstractNpcAI private static final int WAITING = 1; private static final int FIGHTING = 2; private static final int DEAD = 3; + // Skills + private static final SkillHolder AUDIENCE_DEBUFF = new SkillHolder(16613, 1); + private static final SkillHolder RED_LIGHTNING_SPEAR = new SkillHolder(16617, 1); + private static final SkillHolder BLUE_LIGHTNING_SPEAR = new SkillHolder(16618, 1); + private static final SkillHolder PRANARACH = new SkillHolder(16624, 1); + private static final SkillHolder HELIOS_RAGE1 = new SkillHolder(16625, 1); + private static final SkillHolder HELIOS_RAGE2 = new SkillHolder(16625, 2); + private static final SkillHolder HELIOS_RAGE3 = new SkillHolder(16625, 3); + private static final SkillHolder HELIOS_RAGE4 = new SkillHolder(16625, 4); + private static final SkillHolder LEOPOLD_BOMB = new SkillHolder(16629, 1); + private static final SkillHolder LEOPOLD_PLASMA_BOMB = new SkillHolder(16630, 1); + private static final SkillHolder LEOPOLD_ENERGY_BOMB = new SkillHolder(16631, 1); + private static final SkillHolder LEOPOLD_MINI_GUN = new SkillHolder(16632, 1); + private static final SkillHolder LEOPOLD_SPRAY_SHOT = new SkillHolder(16633, 1); + private static final SkillHolder LEOPOLD_HARPOON = new SkillHolder(16634, 1); + // Spawns + private static final List SPAWNS_MINIONS = new ArrayList<>(); + static + { + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_TEMPLAR_COLONEL, HELIOS_SPAWN_LOC, 0, false)); + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_TEMPLAR_COLONEL, HELIOS_SPAWN_LOC, 0, false)); + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_TEMPLAR_COLONEL, HELIOS_SPAWN_LOC, 0, false)); + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_TEMPLAR_COLONEL, HELIOS_SPAWN_LOC, 0, false)); + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_TEMPLAR_COLONEL, HELIOS_SPAWN_LOC, 0, false)); + + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_SHARPSHOOTER, HELIOS_SPAWN_LOC, 0, false)); + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_SHARPSHOOTER, HELIOS_SPAWN_LOC, 0, false)); + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_SHARPSHOOTER, HELIOS_SPAWN_LOC, 0, false)); + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_SHARPSHOOTER, HELIOS_SPAWN_LOC, 0, false)); + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_SHARPSHOOTER, HELIOS_SPAWN_LOC, 0, false)); + + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_ARCHMAGE, HELIOS_SPAWN_LOC, 0, false)); + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_ARCHMAGE, HELIOS_SPAWN_LOC, 0, false)); + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_ARCHMAGE, HELIOS_SPAWN_LOC, 0, false)); + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_ARCHMAGE, HELIOS_SPAWN_LOC, 0, false)); + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_ARCHMAGE, HELIOS_SPAWN_LOC, 0, false)); + + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_GATEKEEPER, HELIOS_SPAWN_LOC, 0, false)); + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_GATEKEEPER, HELIOS_SPAWN_LOC, 0, false)); + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_GATEKEEPER, HELIOS_SPAWN_LOC, 0, false)); + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_GATEKEEPER, HELIOS_SPAWN_LOC, 0, false)); + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_GATEKEEPER, HELIOS_SPAWN_LOC, 0, false)); + } // Misc private static final int HELIOS_RAID_DURATION = 5; // hours private static Npc bossInstance; private final NoSummonFriendZone bossZone; + private GrandBossInstance _tempHelios; + private static List _minionSpawns = new ArrayList<>(); + private static Npc blueLightning; + private static Npc redLightning; + private static Npc leopold; + private boolean activated = false; + private boolean stage1_50 = false; + private boolean stage2_50 = false; + private boolean helios80 = false; + private boolean helios50 = false; + private boolean _announce = false; + protected ScheduledFuture _blueSpearTask; + protected ScheduledFuture _redSpearTask; + protected ScheduledFuture _leopoldTask; + protected ScheduledFuture _debuffTask; private Helios() { - addKillId(HELIOS1, HELIOS2, HELIOS3); + addAttackId(HELIOS1, HELIOS2, HELIOS3); + addKillId(HELIOS1, HELIOS2, HELIOS3, MIMILLION, MIMILLUS); // Zone bossZone = ZoneManager.getInstance().getZoneById(ZONE_ID, NoSummonFriendZone.class); // Unlock @@ -69,23 +157,184 @@ public class Helios extends AbstractNpcAI } else { + _tempHelios = (GrandBossInstance) addSpawn(HELIOS3, -113360, -244676, -15536, 0, false, 0); + GrandBossManager.getInstance().addBoss(_tempHelios); GrandBossManager.getInstance().setBossStatus(HELIOS3, ALIVE); } } - else if (status != ALIVE) + else { + _tempHelios = (GrandBossInstance) addSpawn(HELIOS3, -113360, -244676, -15536, 0, false, 0); + GrandBossManager.getInstance().addBoss(_tempHelios); GrandBossManager.getInstance().setBossStatus(HELIOS3, ALIVE); } } + @Override + public String onAttack(Npc npc, PlayerInstance attacker, int damage, boolean isSummon) + { + if ((npc.getId() == HELIOS1) && !_announce) + { + _announce = true; + _debuffTask = ThreadPool.scheduleAtFixedRate(() -> + { + bossZone.getPlayersInside().forEach(player -> + { + AUDIENCE_DEBUFF.getSkill().applyEffects(player, player); + }); + }, 5000, 20000); + Broadcast.toAllOnlinePlayers(new ExShowScreenMessage(NpcStringId.THE_ADEN_WARRIORS_BEGIN_BATTLE_WITH_THE_GIANT_EMPEROR_HELIOS, ExShowScreenMessage.TOP_CENTER, 10000, true)); + } + if ((npc.getId() == HELIOS1) && !stage1_50 && (npc.getCurrentHp() <= (npc.getMaxHp() * 0.5))) + { + stage1_50 = true; + HELIOS_RAGE1.getSkill().applyEffects(bossInstance, bossInstance); + } + if ((npc.getId() == HELIOS2) && !activated) + { + activated = true; + HELIOS_RAGE1.getSkill().applyEffects(bossInstance, bossInstance); + _blueSpearTask = ThreadPool.scheduleAtFixedRate(() -> + { + int count = bossZone.getPlayersInside().size(); + if (count > 0) + { + PlayerInstance randomPlayer = bossZone.getPlayersInside().get(getRandom(count)); + if (blueLightning != null) + { + blueLightning.setTarget(randomPlayer); + blueLightning.doCast(BLUE_LIGHTNING_SPEAR.getSkill()); + } + } + bossZone.broadcastPacket(new ExShowScreenMessage(NpcStringId.HELIOS_PICKS_UP_THE_BLUE_LIGHTNING_SPEAR_AND_BEGINS_GATHERING_HIS_POWER, ExShowScreenMessage.TOP_CENTER, 10000, true)); + }, 10000, 120000); + _redSpearTask = ThreadPool.scheduleAtFixedRate(() -> + { + int count = bossZone.getPlayersInside().size(); + if (count > 0) + { + PlayerInstance randomPlayer = bossZone.getPlayersInside().get(getRandom(count)); + if (redLightning != null) + { + redLightning.setTarget(randomPlayer); + redLightning.doCast(RED_LIGHTNING_SPEAR.getSkill()); + } + } + bossZone.broadcastPacket(new ExShowScreenMessage(NpcStringId.HELIOS_PICKS_UP_THE_RED_LIGHTNING_SPEAR_AND_BEGINS_GATHERING_HIS_POWER, ExShowScreenMessage.TOP_CENTER, 10000, true)); + }, 30000, 120000); + _leopoldTask = ThreadPool.scheduleAtFixedRate(() -> + { + int count = bossZone.getPlayersInside().size(); + if (count > 0) + { + PlayerInstance randomPlayer = bossZone.getPlayersInside().get(getRandom(count)); + if (leopold != null) + { + leopold.setTarget(randomPlayer); + int rnd = getRandom(100); + if (rnd < 16) + { + leopold.doCast(LEOPOLD_BOMB.getSkill()); + } + else if (rnd < 32) + { + leopold.doCast(LEOPOLD_PLASMA_BOMB.getSkill()); + } + else if (rnd < 48) + { + leopold.doCast(LEOPOLD_ENERGY_BOMB.getSkill()); + } + else if (rnd < 64) + { + leopold.doCast(LEOPOLD_MINI_GUN.getSkill()); + } + else if (rnd < 80) + { + leopold.doCast(LEOPOLD_SPRAY_SHOT.getSkill()); + } + else + { + leopold.doCast(LEOPOLD_HARPOON.getSkill()); + } + } + } + }, 5000, 10000); + } + if ((npc.getId() == HELIOS2) && !stage2_50 && (npc.getCurrentHp() <= (npc.getMaxHp() * 0.5))) + { + stage2_50 = true; + HELIOS_RAGE2.getSkill().applyEffects(bossInstance, bossInstance); + } + if ((npc.getId() == HELIOS3) && !activated) + { + activated = true; + HELIOS_RAGE3.getSkill().applyEffects(bossInstance, bossInstance); + _leopoldTask = ThreadPool.scheduleAtFixedRate(() -> + { + int count = bossZone.getPlayersInside().size(); + if (count > 0) + { + PlayerInstance randomPlayer = bossZone.getPlayersInside().get(getRandom(count)); + if (leopold != null) + { + leopold.setTarget(randomPlayer); + int rnd = getRandom(100); + if (rnd < 16) + { + leopold.doCast(LEOPOLD_BOMB.getSkill()); + } + else if (rnd < 32) + { + leopold.doCast(LEOPOLD_PLASMA_BOMB.getSkill()); + } + else if (rnd < 48) + { + leopold.doCast(LEOPOLD_ENERGY_BOMB.getSkill()); + } + else if (rnd < 64) + { + leopold.doCast(LEOPOLD_MINI_GUN.getSkill()); + } + else if (rnd < 80) + { + leopold.doCast(LEOPOLD_SPRAY_SHOT.getSkill()); + } + else + { + leopold.doCast(LEOPOLD_HARPOON.getSkill()); + } + } + } + }, 5000, 10000); + } + if ((npc.getId() == HELIOS3) && !helios80 && (npc.getCurrentHp() <= (npc.getMaxHp() * 0.8))) + { + helios80 = true; + addSpawn(LEOPOLD_ORIGIN, LEOPOLD_ORIGIN_LOC, false, 0); + addSpawn(ENUMA_ELISH_ORIGIN, ENUMA_ELISH_ORIGIN_LOC, false, 0); + bossZone.broadcastPacket(new ExShowScreenMessage(NpcStringId.THE_KAMAEL_ORIGINS_ABOVE_THE_THRONE_OF_HELIOS_BEGIN_TO_SOAR, ExShowScreenMessage.TOP_CENTER, 10000, true)); + } + else if ((npc.getId() == HELIOS3) && !helios50 && (npc.getCurrentHp() <= (npc.getMaxHp() * 0.5))) + { + helios50 = true; + HELIOS_RAGE4.getSkill().applyEffects(bossInstance, bossInstance); + bossZone.broadcastPacket(new ExShowScreenMessage(NpcStringId.HELIOS_USES_THE_PRANARACH_SHIELD_OF_LIGHT_TO_MINIMIZE_DAMAGE, ExShowScreenMessage.TOP_CENTER, 10000, true)); + bossInstance.abortCast(); + bossInstance.doCast(PRANARACH.getSkill()); + } + return super.onAttack(npc, attacker, damage, isSummon); + } + @Override public String onAdvEvent(String event, Npc npc, PlayerInstance player) { - final String htmltext = null; + String htmltext = null; switch (event) { case "unlock_helios": { + _tempHelios = (GrandBossInstance) addSpawn(HELIOS3, -113360, -244676, -15536, 0, false, 0); + GrandBossManager.getInstance().addBoss(_tempHelios); GrandBossManager.getInstance().setBossStatus(HELIOS3, ALIVE); break; } @@ -95,6 +344,10 @@ public class Helios extends AbstractNpcAI { GrandBossManager.getInstance().setBossStatus(HELIOS3, FIGHTING); bossInstance = addSpawn(HELIOS1, HELIOS_SPAWN_LOC.getX(), HELIOS_SPAWN_LOC.getY(), HELIOS_SPAWN_LOC.getZ(), HELIOS_SPAWN_LOC.getHeading(), false, 0, false); + for (SpawnHolder spawn : SPAWNS_MINIONS) + { + _minionSpawns.add(addSpawn(spawn.getNpcId(), spawn.getLocation())); + } startQuestTimer("resetRaid", HELIOS_RAID_DURATION * 60 * 60 * 1000, bossInstance, null); } break; @@ -104,35 +357,141 @@ public class Helios extends AbstractNpcAI final int status = GrandBossManager.getInstance().getBossStatus(HELIOS3); if ((status > ALIVE) && (status < DEAD)) { + bossZone.oustAllPlayers(); + Broadcast.toAllOnlinePlayers(new ExShowScreenMessage(NpcStringId.THE_HEROES_DRAINED_OF_THEIR_POWERS_HAVE_BEEN_BANISHED_FROM_THE_THRONE_OF_HELIOS_BY_HELIOS_POWERS, ExShowScreenMessage.TOP_CENTER, 10000, true)); GrandBossManager.getInstance().setBossStatus(HELIOS3, ALIVE); - npc.deleteMe(); + Clean(); } break; } + case "stage2": + { + bossInstance = addSpawn(HELIOS2, HELIOS_SPAWN_LOC.getX(), HELIOS_SPAWN_LOC.getY(), HELIOS_SPAWN_LOC.getZ(), HELIOS_SPAWN_LOC.getHeading(), false, 0, false); + bossZone.broadcastPacket(new ExShowScreenMessage(NpcStringId.HELIOS_APPEARANCE_CHANGES_AND_HE_BEGINS_TO_GROW_STRONGER, ExShowScreenMessage.TOP_CENTER, 10000, true)); + for (SpawnHolder spawn : SPAWNS_MINIONS) + { + _minionSpawns.add(addSpawn(spawn.getNpcId(), spawn.getLocation())); + } + startQuestTimer("spheresSpawn", 10000, null, null); + break; + } + case "stage3": + { + activated = false; + bossInstance = addSpawn(HELIOS3, HELIOS_SPAWN_LOC.getX(), HELIOS_SPAWN_LOC.getY(), HELIOS_SPAWN_LOC.getZ(), HELIOS_SPAWN_LOC.getHeading(), false, 0, false); + bossZone.broadcastPacket(new ExShowScreenMessage(NpcStringId.HELIOS_APPEARANCE_CHANGES_AND_HE_BEGINS_TO_GROW_STRONGER, ExShowScreenMessage.TOP_CENTER, 10000, true)); + startQuestTimer("leopoldSpawn", 10000, null, null); + break; + } + case "spheresSpawn": + { + blueLightning = addSpawn(HELIOS_BLUE_LIGHTNING, BLUE_LIGHTNING_SPEAR_LOC, false, 0); + redLightning = addSpawn(HELIOS_RED_LIGHTNING, RED_LIGHTNING_SPEAR_LOC, false, 0); + blueLightning.setInvul(true); + redLightning.setInvul(true); + bossZone.broadcastPacket(new ExShowScreenMessage(NpcStringId.THE_ENUMA_ELISH_SPEAR_ON_THE_THRONE_OF_HELIOS_IS_PREPARED_AND_PLACED_IN_POSITION, ExShowScreenMessage.TOP_CENTER, 10000, true)); + startQuestTimer("protectorsSpawn", 10000, null, null); + break; + } + case "protectorsSpawn": + { + bossZone.broadcastPacket(new ExShowScreenMessage(NpcStringId.MIMILLION_AND_MIMILLUS_APPEAR_IN_ORDER_TO_PROTECT_THE_ENUMA_ELISH_OF_RED_LIGHTNING_AND_THE_ENUMA_ELISH_OF_BLUE_LIGHTNING, ExShowScreenMessage.TOP_CENTER, 10000, true)); + addSpawn(MIMILLION, MIMILLION_LOC, false, 0); + addSpawn(MIMILLUS, MIMILLUS_LOC, false, 0); + startQuestTimer("leopoldSpawn", 10000, null, null); + break; + } + case "leopoldSpawn": + { + leopold = addSpawn(LEOPOLD, LEOPOLD_LOC, false, 0); + bossZone.broadcastPacket(new ExShowScreenMessage(NpcStringId.THE_SIEGE_CANNON_LEOPOLD_ON_THE_THRONE_OF_HELIOS_BEGINS_TO_PREPARE_TO_FIRE, ExShowScreenMessage.TOP_CENTER, 10000, true)); + break; + } } return htmltext; } + private void Clean() + { + bossZone.getCharactersInside().forEach(mob -> + { + if (mob.isNpc()) + { + mob.deleteMe(); + } + }); + if (_blueSpearTask != null) + { + _blueSpearTask.cancel(true); + _blueSpearTask = null; + } + if (_redSpearTask != null) + { + _redSpearTask.cancel(true); + _redSpearTask = null; + } + if (_leopoldTask != null) + { + _leopoldTask.cancel(true); + _leopoldTask = null; + } + if (_debuffTask != null) + { + _debuffTask.cancel(true); + _debuffTask = null; + } + } + @Override public String onKill(Npc npc, PlayerInstance killer, boolean isSummon) { switch (npc.getId()) { + case MIMILLION: + { + if (redLightning != null) + { + redLightning.deleteMe(); + bossZone.broadcastPacket(new ExShowScreenMessage(NpcStringId.MIMILLION_FALLS_AND_THE_RED_LIGHTNING_SPEAR_VANISHES, ExShowScreenMessage.TOP_CENTER, 10000, true)); + } + break; + } + case MIMILLUS: + { + if (blueLightning != null) + { + blueLightning.deleteMe(); + bossZone.broadcastPacket(new ExShowScreenMessage(NpcStringId.MIMILLUS_FALLS_AND_THE_BLUE_LIGHTNING_SPEAR_VANISHES, ExShowScreenMessage.TOP_CENTER, 10000, true)); + } + break; + } case HELIOS1: { bossInstance.deleteMe(); - bossInstance = addSpawn(HELIOS2, HELIOS_SPAWN_LOC.getX(), HELIOS_SPAWN_LOC.getY(), HELIOS_SPAWN_LOC.getZ(), HELIOS_SPAWN_LOC.getHeading(), false, 0, false); - bossZone.broadcastPacket(new ExShowScreenMessage(NpcStringId.HELIOS_APPEARANCE_CHANGES_AND_HE_BEGINS_TO_GROW_STRONGER, ExShowScreenMessage.TOP_CENTER, 10000, true)); + bossZone.getPlayersInside().forEach(player -> + { + playMovie(player, Movie.SC_HELIOS_TRANS_A); + }); + startQuestTimer("stage2", 15000, null, null); break; } case HELIOS2: { bossInstance.deleteMe(); - bossInstance = addSpawn(HELIOS3, HELIOS_SPAWN_LOC.getX(), HELIOS_SPAWN_LOC.getY(), HELIOS_SPAWN_LOC.getZ(), HELIOS_SPAWN_LOC.getHeading(), false, 0, false); + if (leopold != null) + { + leopold.deleteMe(); + } + bossZone.getPlayersInside().forEach(player -> + { + playMovie(player, Movie.SC_HELIOS_TRANS_B); + }); + startQuestTimer("stage3", 15000, null, null); break; } case HELIOS3: { + Clean(); bossZone.broadcastPacket(new ExShowScreenMessage(NpcStringId.HELIOS_DEFEATED_TAKES_FLIGHT_DEEP_IN_TO_THE_SUPERION_FORT_HIS_THRONE_IS_RENDERED_INACTIVE, ExShowScreenMessage.TOP_CENTER, 10000, true)); GrandBossManager.getInstance().setBossStatus(HELIOS3, DEAD); final long respawnTime = (Config.HELIOS_SPAWN_INTERVAL + getRandom(-Config.HELIOS_SPAWN_RANDOM, Config.HELIOS_SPAWN_RANDOM)) * 3600000; @@ -150,4 +509,4 @@ public class Helios extends AbstractNpcAI { new Helios(); } -} +} \ No newline at end of file diff --git a/L2J_Mobius_3.0_Helios/dist/game/data/scripts/ai/bosses/Helios/Helios1.java b/L2J_Mobius_3.0_Helios/dist/game/data/scripts/ai/bosses/Helios/Helios1.java new file mode 100644 index 0000000000..336c5de75a --- /dev/null +++ b/L2J_Mobius_3.0_Helios/dist/game/data/scripts/ai/bosses/Helios/Helios1.java @@ -0,0 +1,182 @@ +/* + * This file is part of the L2J Mobius project. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ai.bosses.Helios; + +import org.l2jmobius.commons.util.CommonUtil; +import org.l2jmobius.gameserver.model.actor.Creature; +import org.l2jmobius.gameserver.model.actor.Npc; +import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; +import org.l2jmobius.gameserver.model.holders.SkillHolder; +import org.l2jmobius.gameserver.model.skills.Skill; +import org.l2jmobius.gameserver.model.skills.SkillCaster; +import org.l2jmobius.gameserver.model.variables.NpcVariables; + +import ai.AbstractNpcAI; + +/** + * @author NviX + */ +public class Helios1 extends AbstractNpcAI +{ + // Npc + private static final int HELIOS = 29303; + // Skills + private static final SkillHolder HELIOS_PLASMA = new SkillHolder(16609, 1); + private static final SkillHolder HELIOS_GRAND_PLASMA = new SkillHolder(16610, 1); + private static final SkillHolder HELIOS_THRONE_OF_AGONY = new SkillHolder(16611, 1); + + private Helios1() + { + registerMobs(HELIOS); + } + + @Override + public String onAdvEvent(String event, Npc npc, PlayerInstance player) + { + switch (event) + { + case "MANAGE_SKILLS": + { + if (npc != null) + { + manageSkills(npc); + } + break; + } + } + return super.onAdvEvent(event, npc, player); + } + + @Override + public String onAttack(Npc npc, PlayerInstance attacker, int damage, boolean isSummon, Skill skill) + { + if (npc.getId() == HELIOS) + { + if (skill == null) + { + refreshAiParams(attacker, npc, (damage * 1000)); + } + else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.25)) + { + refreshAiParams(attacker, npc, ((damage / 3) * 100)); + } + else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.5)) + { + refreshAiParams(attacker, npc, (damage * 20)); + } + else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.75)) + { + refreshAiParams(attacker, npc, (damage * 10)); + } + else + { + refreshAiParams(attacker, npc, ((damage / 3) * 20)); + } + manageSkills(npc); + } + + return super.onAttack(npc, attacker, damage, isSummon); + } + + private final void refreshAiParams(Creature attacker, Npc npc, int damage) + { + refreshAiParams(attacker, npc, damage, damage); + } + + private final void refreshAiParams(Creature attacker, Npc npc, int damage, int aggro) + { + final int newAggroVal = damage + getRandom(3000); + final int aggroVal = aggro + 1000; + final NpcVariables vars = npc.getVariables(); + for (int i = 0; i < 3; i++) + { + if (attacker == vars.getObject("c_quest" + i, Creature.class)) + { + if (vars.getInt("i_quest" + i) < aggroVal) + { + vars.set("i_quest" + i, newAggroVal); + } + return; + } + } + final int index = CommonUtil.getIndexOfMinValue(vars.getInt("i_quest0"), vars.getInt("i_quest1"), vars.getInt("i_quest2")); + vars.set("i_quest" + index, newAggroVal); + vars.set("c_quest" + index, attacker); + } + + @Override + public String onSpellFinished(Npc npc, PlayerInstance player, Skill skill) + { + startQuestTimer("MANAGE_SKILLS", 1000, npc, null); + + return super.onSpellFinished(npc, player, skill); + } + + private void manageSkills(Npc npc) + { + if (npc.isCastingNow(SkillCaster::isAnyNormalType) || npc.isCoreAIDisabled() || !npc.isInCombat()) + { + return; + } + + final NpcVariables vars = npc.getVariables(); + for (int i = 0; i < 3; i++) + { + final Creature attacker = vars.getObject("c_quest" + i, Creature.class); + if ((attacker == null) || ((npc.calculateDistance3D(attacker) > 9000) || attacker.isDead())) + { + vars.set("i_quest" + i, 0); + } + } + final int index = CommonUtil.getIndexOfMaxValue(vars.getInt("i_quest0"), vars.getInt("i_quest1"), vars.getInt("i_quest2")); + final Creature player = vars.getObject("c_quest" + index, Creature.class); + final int i2 = vars.getInt("i_quest" + index); + if ((i2 > 0) && (getRandom(100) < 70)) + { + vars.set("i_quest" + index, 500); + } + + SkillHolder skillToCast = null; + if ((player != null) && !player.isDead()) + { + if (getRandom(100) < 30) + { + skillToCast = HELIOS_GRAND_PLASMA; + } + else if (getRandom(100) < 50) + { + skillToCast = HELIOS_THRONE_OF_AGONY; + } + else + { + skillToCast = HELIOS_PLASMA; + } + } + + if ((skillToCast != null) && SkillCaster.checkUseConditions(npc, skillToCast.getSkill())) + + { + npc.setTarget(player); + npc.doCast(skillToCast.getSkill()); + } + } + + public static void main(String[] args) + { + new Helios1(); + } +} diff --git a/L2J_Mobius_3.0_Helios/dist/game/data/scripts/ai/bosses/Helios/Helios2.java b/L2J_Mobius_3.0_Helios/dist/game/data/scripts/ai/bosses/Helios/Helios2.java new file mode 100644 index 0000000000..cf7ad4b0e6 --- /dev/null +++ b/L2J_Mobius_3.0_Helios/dist/game/data/scripts/ai/bosses/Helios/Helios2.java @@ -0,0 +1,182 @@ +/* + * This file is part of the L2J Mobius project. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ai.bosses.Helios; + +import org.l2jmobius.commons.util.CommonUtil; +import org.l2jmobius.gameserver.model.actor.Creature; +import org.l2jmobius.gameserver.model.actor.Npc; +import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; +import org.l2jmobius.gameserver.model.holders.SkillHolder; +import org.l2jmobius.gameserver.model.skills.Skill; +import org.l2jmobius.gameserver.model.skills.SkillCaster; +import org.l2jmobius.gameserver.model.variables.NpcVariables; + +import ai.AbstractNpcAI; + +/** + * @author NviX + */ +public class Helios2 extends AbstractNpcAI +{ + // Npc + private static final int HELIOS = 29304; + // Skills + private static final SkillHolder EMPEROR_HELIOS_AUTHORITY = new SkillHolder(16612, 1); + private static final SkillHolder HELIOS_PLASMA_PRESSURE = new SkillHolder(16614, 1); + private static final SkillHolder HELIOS_PLASMA_WALL = new SkillHolder(16615, 1); + + private Helios2() + { + registerMobs(HELIOS); + } + + @Override + public String onAdvEvent(String event, Npc npc, PlayerInstance player) + { + switch (event) + { + case "MANAGE_SKILLS": + { + if (npc != null) + { + manageSkills(npc); + } + break; + } + } + return super.onAdvEvent(event, npc, player); + } + + @Override + public String onAttack(Npc npc, PlayerInstance attacker, int damage, boolean isSummon, Skill skill) + { + if (npc.getId() == HELIOS) + { + if (skill == null) + { + refreshAiParams(attacker, npc, (damage * 1000)); + } + else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.25)) + { + refreshAiParams(attacker, npc, ((damage / 3) * 100)); + } + else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.5)) + { + refreshAiParams(attacker, npc, (damage * 20)); + } + else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.75)) + { + refreshAiParams(attacker, npc, (damage * 10)); + } + else + { + refreshAiParams(attacker, npc, ((damage / 3) * 20)); + } + manageSkills(npc); + } + + return super.onAttack(npc, attacker, damage, isSummon); + } + + private final void refreshAiParams(Creature attacker, Npc npc, int damage) + { + refreshAiParams(attacker, npc, damage, damage); + } + + private final void refreshAiParams(Creature attacker, Npc npc, int damage, int aggro) + { + final int newAggroVal = damage + getRandom(3000); + final int aggroVal = aggro + 1000; + final NpcVariables vars = npc.getVariables(); + for (int i = 0; i < 3; i++) + { + if (attacker == vars.getObject("c_quest" + i, Creature.class)) + { + if (vars.getInt("i_quest" + i) < aggroVal) + { + vars.set("i_quest" + i, newAggroVal); + } + return; + } + } + final int index = CommonUtil.getIndexOfMinValue(vars.getInt("i_quest0"), vars.getInt("i_quest1"), vars.getInt("i_quest2")); + vars.set("i_quest" + index, newAggroVal); + vars.set("c_quest" + index, attacker); + } + + @Override + public String onSpellFinished(Npc npc, PlayerInstance player, Skill skill) + { + startQuestTimer("MANAGE_SKILLS", 1000, npc, null); + + return super.onSpellFinished(npc, player, skill); + } + + private void manageSkills(Npc npc) + { + if (npc.isCastingNow(SkillCaster::isAnyNormalType) || npc.isCoreAIDisabled() || !npc.isInCombat()) + { + return; + } + + final NpcVariables vars = npc.getVariables(); + for (int i = 0; i < 3; i++) + { + final Creature attacker = vars.getObject("c_quest" + i, Creature.class); + if ((attacker == null) || ((npc.calculateDistance3D(attacker) > 9000) || attacker.isDead())) + { + vars.set("i_quest" + i, 0); + } + } + final int index = CommonUtil.getIndexOfMaxValue(vars.getInt("i_quest0"), vars.getInt("i_quest1"), vars.getInt("i_quest2")); + final Creature player = vars.getObject("c_quest" + index, Creature.class); + final int i2 = vars.getInt("i_quest" + index); + if ((i2 > 0) && (getRandom(100) < 70)) + { + vars.set("i_quest" + index, 500); + } + + SkillHolder skillToCast = null; + if ((player != null) && !player.isDead()) + { + if (getRandom(100) < 30) + { + skillToCast = EMPEROR_HELIOS_AUTHORITY; + } + else if (getRandom(100) < 50) + { + skillToCast = HELIOS_PLASMA_PRESSURE; + } + else + { + skillToCast = HELIOS_PLASMA_WALL; + } + } + + if ((skillToCast != null) && SkillCaster.checkUseConditions(npc, skillToCast.getSkill())) + + { + npc.setTarget(player); + npc.doCast(skillToCast.getSkill()); + } + } + + public static void main(String[] args) + { + new Helios2(); + } +} diff --git a/L2J_Mobius_3.0_Helios/dist/game/data/scripts/ai/bosses/Helios/Helios3.java b/L2J_Mobius_3.0_Helios/dist/game/data/scripts/ai/bosses/Helios/Helios3.java new file mode 100644 index 0000000000..efa78d5d99 --- /dev/null +++ b/L2J_Mobius_3.0_Helios/dist/game/data/scripts/ai/bosses/Helios/Helios3.java @@ -0,0 +1,187 @@ +/* + * This file is part of the L2J Mobius project. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ai.bosses.Helios; + +import org.l2jmobius.commons.util.CommonUtil; +import org.l2jmobius.gameserver.model.actor.Creature; +import org.l2jmobius.gameserver.model.actor.Npc; +import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; +import org.l2jmobius.gameserver.model.holders.SkillHolder; +import org.l2jmobius.gameserver.model.skills.Skill; +import org.l2jmobius.gameserver.model.skills.SkillCaster; +import org.l2jmobius.gameserver.model.variables.NpcVariables; + +import ai.AbstractNpcAI; + +/** + * @author NviX + */ +public class Helios3 extends AbstractNpcAI +{ + // Npc + private static final int HELIOS = 29305; + // Skills + private static final SkillHolder HELIOS_OVERAWING_GAZE = new SkillHolder(16616, 1); + private static final SkillHolder HELIOS_HOLY_SPIKE = new SkillHolder(16621, 1); + private static final SkillHolder HELIOS_BIONIC_BOMB = new SkillHolder(16622, 1); + private static final SkillHolder HELIOS_LIGHTNING_OF_ANGER = new SkillHolder(16623, 1); + + private Helios3() + { + registerMobs(HELIOS); + } + + @Override + public String onAdvEvent(String event, Npc npc, PlayerInstance player) + { + switch (event) + { + case "MANAGE_SKILLS": + { + if (npc != null) + { + manageSkills(npc); + } + break; + } + } + return super.onAdvEvent(event, npc, player); + } + + @Override + public String onAttack(Npc npc, PlayerInstance attacker, int damage, boolean isSummon, Skill skill) + { + if (npc.getId() == HELIOS) + { + if (skill == null) + { + refreshAiParams(attacker, npc, (damage * 1000)); + } + else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.25)) + { + refreshAiParams(attacker, npc, ((damage / 3) * 100)); + } + else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.5)) + { + refreshAiParams(attacker, npc, (damage * 20)); + } + else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.75)) + { + refreshAiParams(attacker, npc, (damage * 10)); + } + else + { + refreshAiParams(attacker, npc, ((damage / 3) * 20)); + } + manageSkills(npc); + } + + return super.onAttack(npc, attacker, damage, isSummon); + } + + private final void refreshAiParams(Creature attacker, Npc npc, int damage) + { + refreshAiParams(attacker, npc, damage, damage); + } + + private final void refreshAiParams(Creature attacker, Npc npc, int damage, int aggro) + { + final int newAggroVal = damage + getRandom(3000); + final int aggroVal = aggro + 1000; + final NpcVariables vars = npc.getVariables(); + for (int i = 0; i < 3; i++) + { + if (attacker == vars.getObject("c_quest" + i, Creature.class)) + { + if (vars.getInt("i_quest" + i) < aggroVal) + { + vars.set("i_quest" + i, newAggroVal); + } + return; + } + } + final int index = CommonUtil.getIndexOfMinValue(vars.getInt("i_quest0"), vars.getInt("i_quest1"), vars.getInt("i_quest2")); + vars.set("i_quest" + index, newAggroVal); + vars.set("c_quest" + index, attacker); + } + + @Override + public String onSpellFinished(Npc npc, PlayerInstance player, Skill skill) + { + startQuestTimer("MANAGE_SKILLS", 1000, npc, null); + + return super.onSpellFinished(npc, player, skill); + } + + private void manageSkills(Npc npc) + { + if (npc.isCastingNow(SkillCaster::isAnyNormalType) || npc.isCoreAIDisabled() || !npc.isInCombat()) + { + return; + } + + final NpcVariables vars = npc.getVariables(); + for (int i = 0; i < 3; i++) + { + final Creature attacker = vars.getObject("c_quest" + i, Creature.class); + if ((attacker == null) || ((npc.calculateDistance3D(attacker) > 9000) || attacker.isDead())) + { + vars.set("i_quest" + i, 0); + } + } + final int index = CommonUtil.getIndexOfMaxValue(vars.getInt("i_quest0"), vars.getInt("i_quest1"), vars.getInt("i_quest2")); + final Creature player = vars.getObject("c_quest" + index, Creature.class); + final int i2 = vars.getInt("i_quest" + index); + if ((i2 > 0) && (getRandom(100) < 70)) + { + vars.set("i_quest" + index, 500); + } + + SkillHolder skillToCast = null; + if ((player != null) && !player.isDead()) + { + if (getRandom(100) < 10) + { + skillToCast = HELIOS_LIGHTNING_OF_ANGER; + } + else if (getRandom(100) < 30) + { + skillToCast = HELIOS_OVERAWING_GAZE; + } + else if (getRandom(100) < 50) + { + skillToCast = HELIOS_BIONIC_BOMB; + } + else + { + skillToCast = HELIOS_HOLY_SPIKE; + } + } + + if ((skillToCast != null) && SkillCaster.checkUseConditions(npc, skillToCast.getSkill())) + + { + npc.setTarget(player); + npc.doCast(skillToCast.getSkill()); + } + } + + public static void main(String[] args) + { + new Helios3(); + } +} diff --git a/L2J_Mobius_3.0_Helios/dist/game/data/scripts/ai/bosses/Helios/RoyalArchmageMinion.java b/L2J_Mobius_3.0_Helios/dist/game/data/scripts/ai/bosses/Helios/RoyalArchmageMinion.java new file mode 100644 index 0000000000..1529d6f1fb --- /dev/null +++ b/L2J_Mobius_3.0_Helios/dist/game/data/scripts/ai/bosses/Helios/RoyalArchmageMinion.java @@ -0,0 +1,177 @@ +/* + * This file is part of the L2J Mobius project. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ai.bosses.Helios; + +import org.l2jmobius.commons.util.CommonUtil; +import org.l2jmobius.gameserver.model.actor.Creature; +import org.l2jmobius.gameserver.model.actor.Npc; +import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; +import org.l2jmobius.gameserver.model.holders.SkillHolder; +import org.l2jmobius.gameserver.model.skills.Skill; +import org.l2jmobius.gameserver.model.skills.SkillCaster; +import org.l2jmobius.gameserver.model.variables.NpcVariables; + +import ai.AbstractNpcAI; + +/** + * @author NviX + */ +public class RoyalArchmageMinion extends AbstractNpcAI +{ + // Npc + private static final int ROYAL_ARCHMAGE = 29313; + // Skills + private static final SkillHolder ULTRA_PLASMA_BALL = new SkillHolder(16685, 1); + private static final SkillHolder ULTRA_PLASMA_WAVE = new SkillHolder(16686, 1); + + private RoyalArchmageMinion() + { + registerMobs(ROYAL_ARCHMAGE); + } + + @Override + public String onAdvEvent(String event, Npc npc, PlayerInstance player) + { + switch (event) + { + case "MANAGE_SKILLS": + { + if (npc != null) + { + manageSkills(npc); + } + break; + } + } + return super.onAdvEvent(event, npc, player); + } + + @Override + public String onAttack(Npc npc, PlayerInstance attacker, int damage, boolean isSummon, Skill skill) + { + if (npc.getId() == ROYAL_ARCHMAGE) + { + if (skill == null) + { + refreshAiParams(attacker, npc, (damage * 1000)); + } + else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.25)) + { + refreshAiParams(attacker, npc, ((damage / 3) * 100)); + } + else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.5)) + { + refreshAiParams(attacker, npc, (damage * 20)); + } + else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.75)) + { + refreshAiParams(attacker, npc, (damage * 10)); + } + else + { + refreshAiParams(attacker, npc, ((damage / 3) * 20)); + } + manageSkills(npc); + } + + return super.onAttack(npc, attacker, damage, isSummon); + } + + private final void refreshAiParams(Creature attacker, Npc npc, int damage) + { + refreshAiParams(attacker, npc, damage, damage); + } + + private final void refreshAiParams(Creature attacker, Npc npc, int damage, int aggro) + { + final int newAggroVal = damage + getRandom(3000); + final int aggroVal = aggro + 1000; + final NpcVariables vars = npc.getVariables(); + for (int i = 0; i < 3; i++) + { + if (attacker == vars.getObject("c_quest" + i, Creature.class)) + { + if (vars.getInt("i_quest" + i) < aggroVal) + { + vars.set("i_quest" + i, newAggroVal); + } + return; + } + } + final int index = CommonUtil.getIndexOfMinValue(vars.getInt("i_quest0"), vars.getInt("i_quest1"), vars.getInt("i_quest2")); + vars.set("i_quest" + index, newAggroVal); + vars.set("c_quest" + index, attacker); + } + + @Override + public String onSpellFinished(Npc npc, PlayerInstance player, Skill skill) + { + startQuestTimer("MANAGE_SKILLS", 1000, npc, null); + + return super.onSpellFinished(npc, player, skill); + } + + private void manageSkills(Npc npc) + { + if (npc.isCastingNow(SkillCaster::isAnyNormalType) || npc.isCoreAIDisabled() || !npc.isInCombat()) + { + return; + } + + final NpcVariables vars = npc.getVariables(); + for (int i = 0; i < 3; i++) + { + final Creature attacker = vars.getObject("c_quest" + i, Creature.class); + if ((attacker == null) || ((npc.calculateDistance3D(attacker) > 9000) || attacker.isDead())) + { + vars.set("i_quest" + i, 0); + } + } + final int index = CommonUtil.getIndexOfMaxValue(vars.getInt("i_quest0"), vars.getInt("i_quest1"), vars.getInt("i_quest2")); + final Creature player = vars.getObject("c_quest" + index, Creature.class); + final int i2 = vars.getInt("i_quest" + index); + if ((i2 > 0) && (getRandom(100) < 70)) + { + vars.set("i_quest" + index, 500); + } + + SkillHolder skillToCast = null; + if ((player != null) && !player.isDead()) + { + if (getRandom(100) < 50) + { + skillToCast = ULTRA_PLASMA_WAVE; + } + else + { + skillToCast = ULTRA_PLASMA_BALL; + } + } + + if ((skillToCast != null) && SkillCaster.checkUseConditions(npc, skillToCast.getSkill())) + + { + npc.setTarget(player); + npc.doCast(skillToCast.getSkill()); + } + } + + public static void main(String[] args) + { + new RoyalArchmageMinion(); + } +} diff --git a/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/ai/bosses/Helios/Helios.java b/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/ai/bosses/Helios/Helios.java index 0f70177f83..9b7f63de07 100644 --- a/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/ai/bosses/Helios/Helios.java +++ b/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/ai/bosses/Helios/Helios.java @@ -16,30 +16,59 @@ */ package ai.bosses.Helios; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ScheduledFuture; + import org.l2jmobius.Config; +import org.l2jmobius.commons.concurrent.ThreadPool; +import org.l2jmobius.gameserver.enums.Movie; import org.l2jmobius.gameserver.instancemanager.GrandBossManager; import org.l2jmobius.gameserver.instancemanager.ZoneManager; import org.l2jmobius.gameserver.model.Location; import org.l2jmobius.gameserver.model.StatSet; import org.l2jmobius.gameserver.model.actor.Npc; +import org.l2jmobius.gameserver.model.actor.instance.GrandBossInstance; import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; +import org.l2jmobius.gameserver.model.holders.SkillHolder; +import org.l2jmobius.gameserver.model.holders.SpawnHolder; import org.l2jmobius.gameserver.model.zone.type.NoSummonFriendZone; import org.l2jmobius.gameserver.network.NpcStringId; import org.l2jmobius.gameserver.network.serverpackets.ExShowScreenMessage; +import org.l2jmobius.gameserver.util.Broadcast; import ai.AbstractNpcAI; /** - * @author Mobius + * @author Mobius, NviX */ public class Helios extends AbstractNpcAI { - // NPCs + // Raid private static final int HELIOS1 = 29303; private static final int HELIOS2 = 29304; private static final int HELIOS3 = 29305; + // Minions + private static final int LEOPOLD = 29306; + private static final int HELIOS_RED_LIGHTNING = 29307; + private static final int HELIOS_BLUE_LIGHTNING = 29308; + private static final int LEOPOLD_ORIGIN = 29309; + private static final int ENUMA_ELISH_ORIGIN = 29310; + private static final int ROYAL_TEMPLAR_COLONEL = 29311; + private static final int ROYAL_SHARPSHOOTER = 29312; + private static final int ROYAL_ARCHMAGE = 29313; + private static final int ROYAL_GATEKEEPER = 29314; + private static final int MIMILLION = 29315; + private static final int MIMILLUS = 29316; // Location private static final Location HELIOS_SPAWN_LOC = new Location(92771, 161909, 3494, 38329); + private static final Location BLUE_LIGHTNING_SPEAR_LOC = new Location(93208, 161269, 3489); + private static final Location RED_LIGHTNING_SPEAR_LOC = new Location(92348, 162558, 3489); + private static final Location MIMILLION_LOC = new Location(92465, 162465, 3487); + private static final Location MIMILLUS_LOC = new Location(93174, 161394, 3487); + private static final Location LEOPOLD_LOC = new Location(93531, 162415, 3487); + private static final Location LEOPOLD_ORIGIN_LOC = new Location(92601, 162196, 3464); + private static final Location ENUMA_ELISH_ORIGIN_LOC = new Location(92957, 161640, 3485); // Zone private static final int ZONE_ID = 210109; // Status @@ -47,14 +76,73 @@ public class Helios extends AbstractNpcAI private static final int WAITING = 1; private static final int FIGHTING = 2; private static final int DEAD = 3; + // Skills + private static final SkillHolder AUDIENCE_DEBUFF = new SkillHolder(16613, 1); + private static final SkillHolder RED_LIGHTNING_SPEAR = new SkillHolder(16617, 1); + private static final SkillHolder BLUE_LIGHTNING_SPEAR = new SkillHolder(16618, 1); + private static final SkillHolder PRANARACH = new SkillHolder(16624, 1); + private static final SkillHolder HELIOS_RAGE1 = new SkillHolder(16625, 1); + private static final SkillHolder HELIOS_RAGE2 = new SkillHolder(16625, 2); + private static final SkillHolder HELIOS_RAGE3 = new SkillHolder(16625, 3); + private static final SkillHolder HELIOS_RAGE4 = new SkillHolder(16625, 4); + private static final SkillHolder LEOPOLD_BOMB = new SkillHolder(16629, 1); + private static final SkillHolder LEOPOLD_PLASMA_BOMB = new SkillHolder(16630, 1); + private static final SkillHolder LEOPOLD_ENERGY_BOMB = new SkillHolder(16631, 1); + private static final SkillHolder LEOPOLD_MINI_GUN = new SkillHolder(16632, 1); + private static final SkillHolder LEOPOLD_SPRAY_SHOT = new SkillHolder(16633, 1); + private static final SkillHolder LEOPOLD_HARPOON = new SkillHolder(16634, 1); + // Spawns + private static final List SPAWNS_MINIONS = new ArrayList<>(); + static + { + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_TEMPLAR_COLONEL, HELIOS_SPAWN_LOC, 0, false)); + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_TEMPLAR_COLONEL, HELIOS_SPAWN_LOC, 0, false)); + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_TEMPLAR_COLONEL, HELIOS_SPAWN_LOC, 0, false)); + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_TEMPLAR_COLONEL, HELIOS_SPAWN_LOC, 0, false)); + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_TEMPLAR_COLONEL, HELIOS_SPAWN_LOC, 0, false)); + + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_SHARPSHOOTER, HELIOS_SPAWN_LOC, 0, false)); + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_SHARPSHOOTER, HELIOS_SPAWN_LOC, 0, false)); + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_SHARPSHOOTER, HELIOS_SPAWN_LOC, 0, false)); + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_SHARPSHOOTER, HELIOS_SPAWN_LOC, 0, false)); + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_SHARPSHOOTER, HELIOS_SPAWN_LOC, 0, false)); + + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_ARCHMAGE, HELIOS_SPAWN_LOC, 0, false)); + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_ARCHMAGE, HELIOS_SPAWN_LOC, 0, false)); + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_ARCHMAGE, HELIOS_SPAWN_LOC, 0, false)); + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_ARCHMAGE, HELIOS_SPAWN_LOC, 0, false)); + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_ARCHMAGE, HELIOS_SPAWN_LOC, 0, false)); + + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_GATEKEEPER, HELIOS_SPAWN_LOC, 0, false)); + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_GATEKEEPER, HELIOS_SPAWN_LOC, 0, false)); + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_GATEKEEPER, HELIOS_SPAWN_LOC, 0, false)); + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_GATEKEEPER, HELIOS_SPAWN_LOC, 0, false)); + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_GATEKEEPER, HELIOS_SPAWN_LOC, 0, false)); + } // Misc private static final int HELIOS_RAID_DURATION = 5; // hours private static Npc bossInstance; private final NoSummonFriendZone bossZone; + private GrandBossInstance _tempHelios; + private static List _minionSpawns = new ArrayList<>(); + private static Npc blueLightning; + private static Npc redLightning; + private static Npc leopold; + private boolean activated = false; + private boolean stage1_50 = false; + private boolean stage2_50 = false; + private boolean helios80 = false; + private boolean helios50 = false; + private boolean _announce = false; + protected ScheduledFuture _blueSpearTask; + protected ScheduledFuture _redSpearTask; + protected ScheduledFuture _leopoldTask; + protected ScheduledFuture _debuffTask; private Helios() { - addKillId(HELIOS1, HELIOS2, HELIOS3); + addAttackId(HELIOS1, HELIOS2, HELIOS3); + addKillId(HELIOS1, HELIOS2, HELIOS3, MIMILLION, MIMILLUS); // Zone bossZone = ZoneManager.getInstance().getZoneById(ZONE_ID, NoSummonFriendZone.class); // Unlock @@ -69,23 +157,184 @@ public class Helios extends AbstractNpcAI } else { + _tempHelios = (GrandBossInstance) addSpawn(HELIOS3, -113360, -244676, -15536, 0, false, 0); + GrandBossManager.getInstance().addBoss(_tempHelios); GrandBossManager.getInstance().setBossStatus(HELIOS3, ALIVE); } } - else if (status != ALIVE) + else { + _tempHelios = (GrandBossInstance) addSpawn(HELIOS3, -113360, -244676, -15536, 0, false, 0); + GrandBossManager.getInstance().addBoss(_tempHelios); GrandBossManager.getInstance().setBossStatus(HELIOS3, ALIVE); } } + @Override + public String onAttack(Npc npc, PlayerInstance attacker, int damage, boolean isSummon) + { + if ((npc.getId() == HELIOS1) && !_announce) + { + _announce = true; + _debuffTask = ThreadPool.scheduleAtFixedRate(() -> + { + bossZone.getPlayersInside().forEach(player -> + { + AUDIENCE_DEBUFF.getSkill().applyEffects(player, player); + }); + }, 5000, 20000); + Broadcast.toAllOnlinePlayers(new ExShowScreenMessage(NpcStringId.THE_ADEN_WARRIORS_BEGIN_BATTLE_WITH_THE_GIANT_EMPEROR_HELIOS, ExShowScreenMessage.TOP_CENTER, 10000, true)); + } + if ((npc.getId() == HELIOS1) && !stage1_50 && (npc.getCurrentHp() <= (npc.getMaxHp() * 0.5))) + { + stage1_50 = true; + HELIOS_RAGE1.getSkill().applyEffects(bossInstance, bossInstance); + } + if ((npc.getId() == HELIOS2) && !activated) + { + activated = true; + HELIOS_RAGE1.getSkill().applyEffects(bossInstance, bossInstance); + _blueSpearTask = ThreadPool.scheduleAtFixedRate(() -> + { + int count = bossZone.getPlayersInside().size(); + if (count > 0) + { + PlayerInstance randomPlayer = bossZone.getPlayersInside().get(getRandom(count)); + if (blueLightning != null) + { + blueLightning.setTarget(randomPlayer); + blueLightning.doCast(BLUE_LIGHTNING_SPEAR.getSkill()); + } + } + bossZone.broadcastPacket(new ExShowScreenMessage(NpcStringId.HELIOS_PICKS_UP_THE_BLUE_LIGHTNING_SPEAR_AND_BEGINS_GATHERING_HIS_POWER, ExShowScreenMessage.TOP_CENTER, 10000, true)); + }, 10000, 120000); + _redSpearTask = ThreadPool.scheduleAtFixedRate(() -> + { + int count = bossZone.getPlayersInside().size(); + if (count > 0) + { + PlayerInstance randomPlayer = bossZone.getPlayersInside().get(getRandom(count)); + if (redLightning != null) + { + redLightning.setTarget(randomPlayer); + redLightning.doCast(RED_LIGHTNING_SPEAR.getSkill()); + } + } + bossZone.broadcastPacket(new ExShowScreenMessage(NpcStringId.HELIOS_PICKS_UP_THE_RED_LIGHTNING_SPEAR_AND_BEGINS_GATHERING_HIS_POWER, ExShowScreenMessage.TOP_CENTER, 10000, true)); + }, 30000, 120000); + _leopoldTask = ThreadPool.scheduleAtFixedRate(() -> + { + int count = bossZone.getPlayersInside().size(); + if (count > 0) + { + PlayerInstance randomPlayer = bossZone.getPlayersInside().get(getRandom(count)); + if (leopold != null) + { + leopold.setTarget(randomPlayer); + int rnd = getRandom(100); + if (rnd < 16) + { + leopold.doCast(LEOPOLD_BOMB.getSkill()); + } + else if (rnd < 32) + { + leopold.doCast(LEOPOLD_PLASMA_BOMB.getSkill()); + } + else if (rnd < 48) + { + leopold.doCast(LEOPOLD_ENERGY_BOMB.getSkill()); + } + else if (rnd < 64) + { + leopold.doCast(LEOPOLD_MINI_GUN.getSkill()); + } + else if (rnd < 80) + { + leopold.doCast(LEOPOLD_SPRAY_SHOT.getSkill()); + } + else + { + leopold.doCast(LEOPOLD_HARPOON.getSkill()); + } + } + } + }, 5000, 10000); + } + if ((npc.getId() == HELIOS2) && !stage2_50 && (npc.getCurrentHp() <= (npc.getMaxHp() * 0.5))) + { + stage2_50 = true; + HELIOS_RAGE2.getSkill().applyEffects(bossInstance, bossInstance); + } + if ((npc.getId() == HELIOS3) && !activated) + { + activated = true; + HELIOS_RAGE3.getSkill().applyEffects(bossInstance, bossInstance); + _leopoldTask = ThreadPool.scheduleAtFixedRate(() -> + { + int count = bossZone.getPlayersInside().size(); + if (count > 0) + { + PlayerInstance randomPlayer = bossZone.getPlayersInside().get(getRandom(count)); + if (leopold != null) + { + leopold.setTarget(randomPlayer); + int rnd = getRandom(100); + if (rnd < 16) + { + leopold.doCast(LEOPOLD_BOMB.getSkill()); + } + else if (rnd < 32) + { + leopold.doCast(LEOPOLD_PLASMA_BOMB.getSkill()); + } + else if (rnd < 48) + { + leopold.doCast(LEOPOLD_ENERGY_BOMB.getSkill()); + } + else if (rnd < 64) + { + leopold.doCast(LEOPOLD_MINI_GUN.getSkill()); + } + else if (rnd < 80) + { + leopold.doCast(LEOPOLD_SPRAY_SHOT.getSkill()); + } + else + { + leopold.doCast(LEOPOLD_HARPOON.getSkill()); + } + } + } + }, 5000, 10000); + } + if ((npc.getId() == HELIOS3) && !helios80 && (npc.getCurrentHp() <= (npc.getMaxHp() * 0.8))) + { + helios80 = true; + addSpawn(LEOPOLD_ORIGIN, LEOPOLD_ORIGIN_LOC, false, 0); + addSpawn(ENUMA_ELISH_ORIGIN, ENUMA_ELISH_ORIGIN_LOC, false, 0); + bossZone.broadcastPacket(new ExShowScreenMessage(NpcStringId.THE_KAMAEL_ORIGINS_ABOVE_THE_THRONE_OF_HELIOS_BEGIN_TO_SOAR, ExShowScreenMessage.TOP_CENTER, 10000, true)); + } + else if ((npc.getId() == HELIOS3) && !helios50 && (npc.getCurrentHp() <= (npc.getMaxHp() * 0.5))) + { + helios50 = true; + HELIOS_RAGE4.getSkill().applyEffects(bossInstance, bossInstance); + bossZone.broadcastPacket(new ExShowScreenMessage(NpcStringId.HELIOS_USES_THE_PRANARACH_SHIELD_OF_LIGHT_TO_MINIMIZE_DAMAGE, ExShowScreenMessage.TOP_CENTER, 10000, true)); + bossInstance.abortCast(); + bossInstance.doCast(PRANARACH.getSkill()); + } + return super.onAttack(npc, attacker, damage, isSummon); + } + @Override public String onAdvEvent(String event, Npc npc, PlayerInstance player) { - final String htmltext = null; + String htmltext = null; switch (event) { case "unlock_helios": { + _tempHelios = (GrandBossInstance) addSpawn(HELIOS3, -113360, -244676, -15536, 0, false, 0); + GrandBossManager.getInstance().addBoss(_tempHelios); GrandBossManager.getInstance().setBossStatus(HELIOS3, ALIVE); break; } @@ -95,6 +344,10 @@ public class Helios extends AbstractNpcAI { GrandBossManager.getInstance().setBossStatus(HELIOS3, FIGHTING); bossInstance = addSpawn(HELIOS1, HELIOS_SPAWN_LOC.getX(), HELIOS_SPAWN_LOC.getY(), HELIOS_SPAWN_LOC.getZ(), HELIOS_SPAWN_LOC.getHeading(), false, 0, false); + for (SpawnHolder spawn : SPAWNS_MINIONS) + { + _minionSpawns.add(addSpawn(spawn.getNpcId(), spawn.getLocation())); + } startQuestTimer("resetRaid", HELIOS_RAID_DURATION * 60 * 60 * 1000, bossInstance, null); } break; @@ -104,35 +357,141 @@ public class Helios extends AbstractNpcAI final int status = GrandBossManager.getInstance().getBossStatus(HELIOS3); if ((status > ALIVE) && (status < DEAD)) { + bossZone.oustAllPlayers(); + Broadcast.toAllOnlinePlayers(new ExShowScreenMessage(NpcStringId.THE_HEROES_DRAINED_OF_THEIR_POWERS_HAVE_BEEN_BANISHED_FROM_THE_THRONE_OF_HELIOS_BY_HELIOS_POWERS, ExShowScreenMessage.TOP_CENTER, 10000, true)); GrandBossManager.getInstance().setBossStatus(HELIOS3, ALIVE); - npc.deleteMe(); + Clean(); } break; } + case "stage2": + { + bossInstance = addSpawn(HELIOS2, HELIOS_SPAWN_LOC.getX(), HELIOS_SPAWN_LOC.getY(), HELIOS_SPAWN_LOC.getZ(), HELIOS_SPAWN_LOC.getHeading(), false, 0, false); + bossZone.broadcastPacket(new ExShowScreenMessage(NpcStringId.HELIOS_APPEARANCE_CHANGES_AND_HE_BEGINS_TO_GROW_STRONGER, ExShowScreenMessage.TOP_CENTER, 10000, true)); + for (SpawnHolder spawn : SPAWNS_MINIONS) + { + _minionSpawns.add(addSpawn(spawn.getNpcId(), spawn.getLocation())); + } + startQuestTimer("spheresSpawn", 10000, null, null); + break; + } + case "stage3": + { + activated = false; + bossInstance = addSpawn(HELIOS3, HELIOS_SPAWN_LOC.getX(), HELIOS_SPAWN_LOC.getY(), HELIOS_SPAWN_LOC.getZ(), HELIOS_SPAWN_LOC.getHeading(), false, 0, false); + bossZone.broadcastPacket(new ExShowScreenMessage(NpcStringId.HELIOS_APPEARANCE_CHANGES_AND_HE_BEGINS_TO_GROW_STRONGER, ExShowScreenMessage.TOP_CENTER, 10000, true)); + startQuestTimer("leopoldSpawn", 10000, null, null); + break; + } + case "spheresSpawn": + { + blueLightning = addSpawn(HELIOS_BLUE_LIGHTNING, BLUE_LIGHTNING_SPEAR_LOC, false, 0); + redLightning = addSpawn(HELIOS_RED_LIGHTNING, RED_LIGHTNING_SPEAR_LOC, false, 0); + blueLightning.setInvul(true); + redLightning.setInvul(true); + bossZone.broadcastPacket(new ExShowScreenMessage(NpcStringId.THE_ENUMA_ELISH_SPEAR_ON_THE_THRONE_OF_HELIOS_IS_PREPARED_AND_PLACED_IN_POSITION, ExShowScreenMessage.TOP_CENTER, 10000, true)); + startQuestTimer("protectorsSpawn", 10000, null, null); + break; + } + case "protectorsSpawn": + { + bossZone.broadcastPacket(new ExShowScreenMessage(NpcStringId.MIMILLION_AND_MIMILLUS_APPEAR_IN_ORDER_TO_PROTECT_THE_ENUMA_ELISH_OF_RED_LIGHTNING_AND_THE_ENUMA_ELISH_OF_BLUE_LIGHTNING, ExShowScreenMessage.TOP_CENTER, 10000, true)); + addSpawn(MIMILLION, MIMILLION_LOC, false, 0); + addSpawn(MIMILLUS, MIMILLUS_LOC, false, 0); + startQuestTimer("leopoldSpawn", 10000, null, null); + break; + } + case "leopoldSpawn": + { + leopold = addSpawn(LEOPOLD, LEOPOLD_LOC, false, 0); + bossZone.broadcastPacket(new ExShowScreenMessage(NpcStringId.THE_SIEGE_CANNON_LEOPOLD_ON_THE_THRONE_OF_HELIOS_BEGINS_TO_PREPARE_TO_FIRE, ExShowScreenMessage.TOP_CENTER, 10000, true)); + break; + } } return htmltext; } + private void Clean() + { + bossZone.getCharactersInside().forEach(mob -> + { + if (mob.isNpc()) + { + mob.deleteMe(); + } + }); + if (_blueSpearTask != null) + { + _blueSpearTask.cancel(true); + _blueSpearTask = null; + } + if (_redSpearTask != null) + { + _redSpearTask.cancel(true); + _redSpearTask = null; + } + if (_leopoldTask != null) + { + _leopoldTask.cancel(true); + _leopoldTask = null; + } + if (_debuffTask != null) + { + _debuffTask.cancel(true); + _debuffTask = null; + } + } + @Override public String onKill(Npc npc, PlayerInstance killer, boolean isSummon) { switch (npc.getId()) { + case MIMILLION: + { + if (redLightning != null) + { + redLightning.deleteMe(); + bossZone.broadcastPacket(new ExShowScreenMessage(NpcStringId.MIMILLION_FALLS_AND_THE_RED_LIGHTNING_SPEAR_VANISHES, ExShowScreenMessage.TOP_CENTER, 10000, true)); + } + break; + } + case MIMILLUS: + { + if (blueLightning != null) + { + blueLightning.deleteMe(); + bossZone.broadcastPacket(new ExShowScreenMessage(NpcStringId.MIMILLUS_FALLS_AND_THE_BLUE_LIGHTNING_SPEAR_VANISHES, ExShowScreenMessage.TOP_CENTER, 10000, true)); + } + break; + } case HELIOS1: { bossInstance.deleteMe(); - bossInstance = addSpawn(HELIOS2, HELIOS_SPAWN_LOC.getX(), HELIOS_SPAWN_LOC.getY(), HELIOS_SPAWN_LOC.getZ(), HELIOS_SPAWN_LOC.getHeading(), false, 0, false); - bossZone.broadcastPacket(new ExShowScreenMessage(NpcStringId.HELIOS_APPEARANCE_CHANGES_AND_HE_BEGINS_TO_GROW_STRONGER, ExShowScreenMessage.TOP_CENTER, 10000, true)); + bossZone.getPlayersInside().forEach(player -> + { + playMovie(player, Movie.SC_HELIOS_TRANS_A); + }); + startQuestTimer("stage2", 15000, null, null); break; } case HELIOS2: { bossInstance.deleteMe(); - bossInstance = addSpawn(HELIOS3, HELIOS_SPAWN_LOC.getX(), HELIOS_SPAWN_LOC.getY(), HELIOS_SPAWN_LOC.getZ(), HELIOS_SPAWN_LOC.getHeading(), false, 0, false); + if (leopold != null) + { + leopold.deleteMe(); + } + bossZone.getPlayersInside().forEach(player -> + { + playMovie(player, Movie.SC_HELIOS_TRANS_B); + }); + startQuestTimer("stage3", 15000, null, null); break; } case HELIOS3: { + Clean(); bossZone.broadcastPacket(new ExShowScreenMessage(NpcStringId.HELIOS_DEFEATED_TAKES_FLIGHT_DEEP_IN_TO_THE_SUPERION_FORT_HIS_THRONE_IS_RENDERED_INACTIVE, ExShowScreenMessage.TOP_CENTER, 10000, true)); GrandBossManager.getInstance().setBossStatus(HELIOS3, DEAD); final long respawnTime = (Config.HELIOS_SPAWN_INTERVAL + getRandom(-Config.HELIOS_SPAWN_RANDOM, Config.HELIOS_SPAWN_RANDOM)) * 3600000; @@ -150,4 +509,4 @@ public class Helios extends AbstractNpcAI { new Helios(); } -} +} \ No newline at end of file diff --git a/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/ai/bosses/Helios/Helios1.java b/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/ai/bosses/Helios/Helios1.java new file mode 100644 index 0000000000..336c5de75a --- /dev/null +++ b/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/ai/bosses/Helios/Helios1.java @@ -0,0 +1,182 @@ +/* + * This file is part of the L2J Mobius project. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ai.bosses.Helios; + +import org.l2jmobius.commons.util.CommonUtil; +import org.l2jmobius.gameserver.model.actor.Creature; +import org.l2jmobius.gameserver.model.actor.Npc; +import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; +import org.l2jmobius.gameserver.model.holders.SkillHolder; +import org.l2jmobius.gameserver.model.skills.Skill; +import org.l2jmobius.gameserver.model.skills.SkillCaster; +import org.l2jmobius.gameserver.model.variables.NpcVariables; + +import ai.AbstractNpcAI; + +/** + * @author NviX + */ +public class Helios1 extends AbstractNpcAI +{ + // Npc + private static final int HELIOS = 29303; + // Skills + private static final SkillHolder HELIOS_PLASMA = new SkillHolder(16609, 1); + private static final SkillHolder HELIOS_GRAND_PLASMA = new SkillHolder(16610, 1); + private static final SkillHolder HELIOS_THRONE_OF_AGONY = new SkillHolder(16611, 1); + + private Helios1() + { + registerMobs(HELIOS); + } + + @Override + public String onAdvEvent(String event, Npc npc, PlayerInstance player) + { + switch (event) + { + case "MANAGE_SKILLS": + { + if (npc != null) + { + manageSkills(npc); + } + break; + } + } + return super.onAdvEvent(event, npc, player); + } + + @Override + public String onAttack(Npc npc, PlayerInstance attacker, int damage, boolean isSummon, Skill skill) + { + if (npc.getId() == HELIOS) + { + if (skill == null) + { + refreshAiParams(attacker, npc, (damage * 1000)); + } + else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.25)) + { + refreshAiParams(attacker, npc, ((damage / 3) * 100)); + } + else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.5)) + { + refreshAiParams(attacker, npc, (damage * 20)); + } + else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.75)) + { + refreshAiParams(attacker, npc, (damage * 10)); + } + else + { + refreshAiParams(attacker, npc, ((damage / 3) * 20)); + } + manageSkills(npc); + } + + return super.onAttack(npc, attacker, damage, isSummon); + } + + private final void refreshAiParams(Creature attacker, Npc npc, int damage) + { + refreshAiParams(attacker, npc, damage, damage); + } + + private final void refreshAiParams(Creature attacker, Npc npc, int damage, int aggro) + { + final int newAggroVal = damage + getRandom(3000); + final int aggroVal = aggro + 1000; + final NpcVariables vars = npc.getVariables(); + for (int i = 0; i < 3; i++) + { + if (attacker == vars.getObject("c_quest" + i, Creature.class)) + { + if (vars.getInt("i_quest" + i) < aggroVal) + { + vars.set("i_quest" + i, newAggroVal); + } + return; + } + } + final int index = CommonUtil.getIndexOfMinValue(vars.getInt("i_quest0"), vars.getInt("i_quest1"), vars.getInt("i_quest2")); + vars.set("i_quest" + index, newAggroVal); + vars.set("c_quest" + index, attacker); + } + + @Override + public String onSpellFinished(Npc npc, PlayerInstance player, Skill skill) + { + startQuestTimer("MANAGE_SKILLS", 1000, npc, null); + + return super.onSpellFinished(npc, player, skill); + } + + private void manageSkills(Npc npc) + { + if (npc.isCastingNow(SkillCaster::isAnyNormalType) || npc.isCoreAIDisabled() || !npc.isInCombat()) + { + return; + } + + final NpcVariables vars = npc.getVariables(); + for (int i = 0; i < 3; i++) + { + final Creature attacker = vars.getObject("c_quest" + i, Creature.class); + if ((attacker == null) || ((npc.calculateDistance3D(attacker) > 9000) || attacker.isDead())) + { + vars.set("i_quest" + i, 0); + } + } + final int index = CommonUtil.getIndexOfMaxValue(vars.getInt("i_quest0"), vars.getInt("i_quest1"), vars.getInt("i_quest2")); + final Creature player = vars.getObject("c_quest" + index, Creature.class); + final int i2 = vars.getInt("i_quest" + index); + if ((i2 > 0) && (getRandom(100) < 70)) + { + vars.set("i_quest" + index, 500); + } + + SkillHolder skillToCast = null; + if ((player != null) && !player.isDead()) + { + if (getRandom(100) < 30) + { + skillToCast = HELIOS_GRAND_PLASMA; + } + else if (getRandom(100) < 50) + { + skillToCast = HELIOS_THRONE_OF_AGONY; + } + else + { + skillToCast = HELIOS_PLASMA; + } + } + + if ((skillToCast != null) && SkillCaster.checkUseConditions(npc, skillToCast.getSkill())) + + { + npc.setTarget(player); + npc.doCast(skillToCast.getSkill()); + } + } + + public static void main(String[] args) + { + new Helios1(); + } +} diff --git a/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/ai/bosses/Helios/Helios2.java b/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/ai/bosses/Helios/Helios2.java new file mode 100644 index 0000000000..cf7ad4b0e6 --- /dev/null +++ b/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/ai/bosses/Helios/Helios2.java @@ -0,0 +1,182 @@ +/* + * This file is part of the L2J Mobius project. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ai.bosses.Helios; + +import org.l2jmobius.commons.util.CommonUtil; +import org.l2jmobius.gameserver.model.actor.Creature; +import org.l2jmobius.gameserver.model.actor.Npc; +import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; +import org.l2jmobius.gameserver.model.holders.SkillHolder; +import org.l2jmobius.gameserver.model.skills.Skill; +import org.l2jmobius.gameserver.model.skills.SkillCaster; +import org.l2jmobius.gameserver.model.variables.NpcVariables; + +import ai.AbstractNpcAI; + +/** + * @author NviX + */ +public class Helios2 extends AbstractNpcAI +{ + // Npc + private static final int HELIOS = 29304; + // Skills + private static final SkillHolder EMPEROR_HELIOS_AUTHORITY = new SkillHolder(16612, 1); + private static final SkillHolder HELIOS_PLASMA_PRESSURE = new SkillHolder(16614, 1); + private static final SkillHolder HELIOS_PLASMA_WALL = new SkillHolder(16615, 1); + + private Helios2() + { + registerMobs(HELIOS); + } + + @Override + public String onAdvEvent(String event, Npc npc, PlayerInstance player) + { + switch (event) + { + case "MANAGE_SKILLS": + { + if (npc != null) + { + manageSkills(npc); + } + break; + } + } + return super.onAdvEvent(event, npc, player); + } + + @Override + public String onAttack(Npc npc, PlayerInstance attacker, int damage, boolean isSummon, Skill skill) + { + if (npc.getId() == HELIOS) + { + if (skill == null) + { + refreshAiParams(attacker, npc, (damage * 1000)); + } + else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.25)) + { + refreshAiParams(attacker, npc, ((damage / 3) * 100)); + } + else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.5)) + { + refreshAiParams(attacker, npc, (damage * 20)); + } + else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.75)) + { + refreshAiParams(attacker, npc, (damage * 10)); + } + else + { + refreshAiParams(attacker, npc, ((damage / 3) * 20)); + } + manageSkills(npc); + } + + return super.onAttack(npc, attacker, damage, isSummon); + } + + private final void refreshAiParams(Creature attacker, Npc npc, int damage) + { + refreshAiParams(attacker, npc, damage, damage); + } + + private final void refreshAiParams(Creature attacker, Npc npc, int damage, int aggro) + { + final int newAggroVal = damage + getRandom(3000); + final int aggroVal = aggro + 1000; + final NpcVariables vars = npc.getVariables(); + for (int i = 0; i < 3; i++) + { + if (attacker == vars.getObject("c_quest" + i, Creature.class)) + { + if (vars.getInt("i_quest" + i) < aggroVal) + { + vars.set("i_quest" + i, newAggroVal); + } + return; + } + } + final int index = CommonUtil.getIndexOfMinValue(vars.getInt("i_quest0"), vars.getInt("i_quest1"), vars.getInt("i_quest2")); + vars.set("i_quest" + index, newAggroVal); + vars.set("c_quest" + index, attacker); + } + + @Override + public String onSpellFinished(Npc npc, PlayerInstance player, Skill skill) + { + startQuestTimer("MANAGE_SKILLS", 1000, npc, null); + + return super.onSpellFinished(npc, player, skill); + } + + private void manageSkills(Npc npc) + { + if (npc.isCastingNow(SkillCaster::isAnyNormalType) || npc.isCoreAIDisabled() || !npc.isInCombat()) + { + return; + } + + final NpcVariables vars = npc.getVariables(); + for (int i = 0; i < 3; i++) + { + final Creature attacker = vars.getObject("c_quest" + i, Creature.class); + if ((attacker == null) || ((npc.calculateDistance3D(attacker) > 9000) || attacker.isDead())) + { + vars.set("i_quest" + i, 0); + } + } + final int index = CommonUtil.getIndexOfMaxValue(vars.getInt("i_quest0"), vars.getInt("i_quest1"), vars.getInt("i_quest2")); + final Creature player = vars.getObject("c_quest" + index, Creature.class); + final int i2 = vars.getInt("i_quest" + index); + if ((i2 > 0) && (getRandom(100) < 70)) + { + vars.set("i_quest" + index, 500); + } + + SkillHolder skillToCast = null; + if ((player != null) && !player.isDead()) + { + if (getRandom(100) < 30) + { + skillToCast = EMPEROR_HELIOS_AUTHORITY; + } + else if (getRandom(100) < 50) + { + skillToCast = HELIOS_PLASMA_PRESSURE; + } + else + { + skillToCast = HELIOS_PLASMA_WALL; + } + } + + if ((skillToCast != null) && SkillCaster.checkUseConditions(npc, skillToCast.getSkill())) + + { + npc.setTarget(player); + npc.doCast(skillToCast.getSkill()); + } + } + + public static void main(String[] args) + { + new Helios2(); + } +} diff --git a/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/ai/bosses/Helios/Helios3.java b/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/ai/bosses/Helios/Helios3.java new file mode 100644 index 0000000000..efa78d5d99 --- /dev/null +++ b/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/ai/bosses/Helios/Helios3.java @@ -0,0 +1,187 @@ +/* + * This file is part of the L2J Mobius project. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ai.bosses.Helios; + +import org.l2jmobius.commons.util.CommonUtil; +import org.l2jmobius.gameserver.model.actor.Creature; +import org.l2jmobius.gameserver.model.actor.Npc; +import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; +import org.l2jmobius.gameserver.model.holders.SkillHolder; +import org.l2jmobius.gameserver.model.skills.Skill; +import org.l2jmobius.gameserver.model.skills.SkillCaster; +import org.l2jmobius.gameserver.model.variables.NpcVariables; + +import ai.AbstractNpcAI; + +/** + * @author NviX + */ +public class Helios3 extends AbstractNpcAI +{ + // Npc + private static final int HELIOS = 29305; + // Skills + private static final SkillHolder HELIOS_OVERAWING_GAZE = new SkillHolder(16616, 1); + private static final SkillHolder HELIOS_HOLY_SPIKE = new SkillHolder(16621, 1); + private static final SkillHolder HELIOS_BIONIC_BOMB = new SkillHolder(16622, 1); + private static final SkillHolder HELIOS_LIGHTNING_OF_ANGER = new SkillHolder(16623, 1); + + private Helios3() + { + registerMobs(HELIOS); + } + + @Override + public String onAdvEvent(String event, Npc npc, PlayerInstance player) + { + switch (event) + { + case "MANAGE_SKILLS": + { + if (npc != null) + { + manageSkills(npc); + } + break; + } + } + return super.onAdvEvent(event, npc, player); + } + + @Override + public String onAttack(Npc npc, PlayerInstance attacker, int damage, boolean isSummon, Skill skill) + { + if (npc.getId() == HELIOS) + { + if (skill == null) + { + refreshAiParams(attacker, npc, (damage * 1000)); + } + else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.25)) + { + refreshAiParams(attacker, npc, ((damage / 3) * 100)); + } + else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.5)) + { + refreshAiParams(attacker, npc, (damage * 20)); + } + else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.75)) + { + refreshAiParams(attacker, npc, (damage * 10)); + } + else + { + refreshAiParams(attacker, npc, ((damage / 3) * 20)); + } + manageSkills(npc); + } + + return super.onAttack(npc, attacker, damage, isSummon); + } + + private final void refreshAiParams(Creature attacker, Npc npc, int damage) + { + refreshAiParams(attacker, npc, damage, damage); + } + + private final void refreshAiParams(Creature attacker, Npc npc, int damage, int aggro) + { + final int newAggroVal = damage + getRandom(3000); + final int aggroVal = aggro + 1000; + final NpcVariables vars = npc.getVariables(); + for (int i = 0; i < 3; i++) + { + if (attacker == vars.getObject("c_quest" + i, Creature.class)) + { + if (vars.getInt("i_quest" + i) < aggroVal) + { + vars.set("i_quest" + i, newAggroVal); + } + return; + } + } + final int index = CommonUtil.getIndexOfMinValue(vars.getInt("i_quest0"), vars.getInt("i_quest1"), vars.getInt("i_quest2")); + vars.set("i_quest" + index, newAggroVal); + vars.set("c_quest" + index, attacker); + } + + @Override + public String onSpellFinished(Npc npc, PlayerInstance player, Skill skill) + { + startQuestTimer("MANAGE_SKILLS", 1000, npc, null); + + return super.onSpellFinished(npc, player, skill); + } + + private void manageSkills(Npc npc) + { + if (npc.isCastingNow(SkillCaster::isAnyNormalType) || npc.isCoreAIDisabled() || !npc.isInCombat()) + { + return; + } + + final NpcVariables vars = npc.getVariables(); + for (int i = 0; i < 3; i++) + { + final Creature attacker = vars.getObject("c_quest" + i, Creature.class); + if ((attacker == null) || ((npc.calculateDistance3D(attacker) > 9000) || attacker.isDead())) + { + vars.set("i_quest" + i, 0); + } + } + final int index = CommonUtil.getIndexOfMaxValue(vars.getInt("i_quest0"), vars.getInt("i_quest1"), vars.getInt("i_quest2")); + final Creature player = vars.getObject("c_quest" + index, Creature.class); + final int i2 = vars.getInt("i_quest" + index); + if ((i2 > 0) && (getRandom(100) < 70)) + { + vars.set("i_quest" + index, 500); + } + + SkillHolder skillToCast = null; + if ((player != null) && !player.isDead()) + { + if (getRandom(100) < 10) + { + skillToCast = HELIOS_LIGHTNING_OF_ANGER; + } + else if (getRandom(100) < 30) + { + skillToCast = HELIOS_OVERAWING_GAZE; + } + else if (getRandom(100) < 50) + { + skillToCast = HELIOS_BIONIC_BOMB; + } + else + { + skillToCast = HELIOS_HOLY_SPIKE; + } + } + + if ((skillToCast != null) && SkillCaster.checkUseConditions(npc, skillToCast.getSkill())) + + { + npc.setTarget(player); + npc.doCast(skillToCast.getSkill()); + } + } + + public static void main(String[] args) + { + new Helios3(); + } +} diff --git a/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/ai/bosses/Helios/RoyalArchmageMinion.java b/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/ai/bosses/Helios/RoyalArchmageMinion.java new file mode 100644 index 0000000000..1529d6f1fb --- /dev/null +++ b/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/ai/bosses/Helios/RoyalArchmageMinion.java @@ -0,0 +1,177 @@ +/* + * This file is part of the L2J Mobius project. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ai.bosses.Helios; + +import org.l2jmobius.commons.util.CommonUtil; +import org.l2jmobius.gameserver.model.actor.Creature; +import org.l2jmobius.gameserver.model.actor.Npc; +import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; +import org.l2jmobius.gameserver.model.holders.SkillHolder; +import org.l2jmobius.gameserver.model.skills.Skill; +import org.l2jmobius.gameserver.model.skills.SkillCaster; +import org.l2jmobius.gameserver.model.variables.NpcVariables; + +import ai.AbstractNpcAI; + +/** + * @author NviX + */ +public class RoyalArchmageMinion extends AbstractNpcAI +{ + // Npc + private static final int ROYAL_ARCHMAGE = 29313; + // Skills + private static final SkillHolder ULTRA_PLASMA_BALL = new SkillHolder(16685, 1); + private static final SkillHolder ULTRA_PLASMA_WAVE = new SkillHolder(16686, 1); + + private RoyalArchmageMinion() + { + registerMobs(ROYAL_ARCHMAGE); + } + + @Override + public String onAdvEvent(String event, Npc npc, PlayerInstance player) + { + switch (event) + { + case "MANAGE_SKILLS": + { + if (npc != null) + { + manageSkills(npc); + } + break; + } + } + return super.onAdvEvent(event, npc, player); + } + + @Override + public String onAttack(Npc npc, PlayerInstance attacker, int damage, boolean isSummon, Skill skill) + { + if (npc.getId() == ROYAL_ARCHMAGE) + { + if (skill == null) + { + refreshAiParams(attacker, npc, (damage * 1000)); + } + else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.25)) + { + refreshAiParams(attacker, npc, ((damage / 3) * 100)); + } + else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.5)) + { + refreshAiParams(attacker, npc, (damage * 20)); + } + else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.75)) + { + refreshAiParams(attacker, npc, (damage * 10)); + } + else + { + refreshAiParams(attacker, npc, ((damage / 3) * 20)); + } + manageSkills(npc); + } + + return super.onAttack(npc, attacker, damage, isSummon); + } + + private final void refreshAiParams(Creature attacker, Npc npc, int damage) + { + refreshAiParams(attacker, npc, damage, damage); + } + + private final void refreshAiParams(Creature attacker, Npc npc, int damage, int aggro) + { + final int newAggroVal = damage + getRandom(3000); + final int aggroVal = aggro + 1000; + final NpcVariables vars = npc.getVariables(); + for (int i = 0; i < 3; i++) + { + if (attacker == vars.getObject("c_quest" + i, Creature.class)) + { + if (vars.getInt("i_quest" + i) < aggroVal) + { + vars.set("i_quest" + i, newAggroVal); + } + return; + } + } + final int index = CommonUtil.getIndexOfMinValue(vars.getInt("i_quest0"), vars.getInt("i_quest1"), vars.getInt("i_quest2")); + vars.set("i_quest" + index, newAggroVal); + vars.set("c_quest" + index, attacker); + } + + @Override + public String onSpellFinished(Npc npc, PlayerInstance player, Skill skill) + { + startQuestTimer("MANAGE_SKILLS", 1000, npc, null); + + return super.onSpellFinished(npc, player, skill); + } + + private void manageSkills(Npc npc) + { + if (npc.isCastingNow(SkillCaster::isAnyNormalType) || npc.isCoreAIDisabled() || !npc.isInCombat()) + { + return; + } + + final NpcVariables vars = npc.getVariables(); + for (int i = 0; i < 3; i++) + { + final Creature attacker = vars.getObject("c_quest" + i, Creature.class); + if ((attacker == null) || ((npc.calculateDistance3D(attacker) > 9000) || attacker.isDead())) + { + vars.set("i_quest" + i, 0); + } + } + final int index = CommonUtil.getIndexOfMaxValue(vars.getInt("i_quest0"), vars.getInt("i_quest1"), vars.getInt("i_quest2")); + final Creature player = vars.getObject("c_quest" + index, Creature.class); + final int i2 = vars.getInt("i_quest" + index); + if ((i2 > 0) && (getRandom(100) < 70)) + { + vars.set("i_quest" + index, 500); + } + + SkillHolder skillToCast = null; + if ((player != null) && !player.isDead()) + { + if (getRandom(100) < 50) + { + skillToCast = ULTRA_PLASMA_WAVE; + } + else + { + skillToCast = ULTRA_PLASMA_BALL; + } + } + + if ((skillToCast != null) && SkillCaster.checkUseConditions(npc, skillToCast.getSkill())) + + { + npc.setTarget(player); + npc.doCast(skillToCast.getSkill()); + } + } + + public static void main(String[] args) + { + new RoyalArchmageMinion(); + } +} diff --git a/L2J_Mobius_5.0_Salvation/dist/game/data/scripts/ai/bosses/Helios/Helios.java b/L2J_Mobius_5.0_Salvation/dist/game/data/scripts/ai/bosses/Helios/Helios.java index 0f70177f83..9b7f63de07 100644 --- a/L2J_Mobius_5.0_Salvation/dist/game/data/scripts/ai/bosses/Helios/Helios.java +++ b/L2J_Mobius_5.0_Salvation/dist/game/data/scripts/ai/bosses/Helios/Helios.java @@ -16,30 +16,59 @@ */ package ai.bosses.Helios; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ScheduledFuture; + import org.l2jmobius.Config; +import org.l2jmobius.commons.concurrent.ThreadPool; +import org.l2jmobius.gameserver.enums.Movie; import org.l2jmobius.gameserver.instancemanager.GrandBossManager; import org.l2jmobius.gameserver.instancemanager.ZoneManager; import org.l2jmobius.gameserver.model.Location; import org.l2jmobius.gameserver.model.StatSet; import org.l2jmobius.gameserver.model.actor.Npc; +import org.l2jmobius.gameserver.model.actor.instance.GrandBossInstance; import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; +import org.l2jmobius.gameserver.model.holders.SkillHolder; +import org.l2jmobius.gameserver.model.holders.SpawnHolder; import org.l2jmobius.gameserver.model.zone.type.NoSummonFriendZone; import org.l2jmobius.gameserver.network.NpcStringId; import org.l2jmobius.gameserver.network.serverpackets.ExShowScreenMessage; +import org.l2jmobius.gameserver.util.Broadcast; import ai.AbstractNpcAI; /** - * @author Mobius + * @author Mobius, NviX */ public class Helios extends AbstractNpcAI { - // NPCs + // Raid private static final int HELIOS1 = 29303; private static final int HELIOS2 = 29304; private static final int HELIOS3 = 29305; + // Minions + private static final int LEOPOLD = 29306; + private static final int HELIOS_RED_LIGHTNING = 29307; + private static final int HELIOS_BLUE_LIGHTNING = 29308; + private static final int LEOPOLD_ORIGIN = 29309; + private static final int ENUMA_ELISH_ORIGIN = 29310; + private static final int ROYAL_TEMPLAR_COLONEL = 29311; + private static final int ROYAL_SHARPSHOOTER = 29312; + private static final int ROYAL_ARCHMAGE = 29313; + private static final int ROYAL_GATEKEEPER = 29314; + private static final int MIMILLION = 29315; + private static final int MIMILLUS = 29316; // Location private static final Location HELIOS_SPAWN_LOC = new Location(92771, 161909, 3494, 38329); + private static final Location BLUE_LIGHTNING_SPEAR_LOC = new Location(93208, 161269, 3489); + private static final Location RED_LIGHTNING_SPEAR_LOC = new Location(92348, 162558, 3489); + private static final Location MIMILLION_LOC = new Location(92465, 162465, 3487); + private static final Location MIMILLUS_LOC = new Location(93174, 161394, 3487); + private static final Location LEOPOLD_LOC = new Location(93531, 162415, 3487); + private static final Location LEOPOLD_ORIGIN_LOC = new Location(92601, 162196, 3464); + private static final Location ENUMA_ELISH_ORIGIN_LOC = new Location(92957, 161640, 3485); // Zone private static final int ZONE_ID = 210109; // Status @@ -47,14 +76,73 @@ public class Helios extends AbstractNpcAI private static final int WAITING = 1; private static final int FIGHTING = 2; private static final int DEAD = 3; + // Skills + private static final SkillHolder AUDIENCE_DEBUFF = new SkillHolder(16613, 1); + private static final SkillHolder RED_LIGHTNING_SPEAR = new SkillHolder(16617, 1); + private static final SkillHolder BLUE_LIGHTNING_SPEAR = new SkillHolder(16618, 1); + private static final SkillHolder PRANARACH = new SkillHolder(16624, 1); + private static final SkillHolder HELIOS_RAGE1 = new SkillHolder(16625, 1); + private static final SkillHolder HELIOS_RAGE2 = new SkillHolder(16625, 2); + private static final SkillHolder HELIOS_RAGE3 = new SkillHolder(16625, 3); + private static final SkillHolder HELIOS_RAGE4 = new SkillHolder(16625, 4); + private static final SkillHolder LEOPOLD_BOMB = new SkillHolder(16629, 1); + private static final SkillHolder LEOPOLD_PLASMA_BOMB = new SkillHolder(16630, 1); + private static final SkillHolder LEOPOLD_ENERGY_BOMB = new SkillHolder(16631, 1); + private static final SkillHolder LEOPOLD_MINI_GUN = new SkillHolder(16632, 1); + private static final SkillHolder LEOPOLD_SPRAY_SHOT = new SkillHolder(16633, 1); + private static final SkillHolder LEOPOLD_HARPOON = new SkillHolder(16634, 1); + // Spawns + private static final List SPAWNS_MINIONS = new ArrayList<>(); + static + { + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_TEMPLAR_COLONEL, HELIOS_SPAWN_LOC, 0, false)); + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_TEMPLAR_COLONEL, HELIOS_SPAWN_LOC, 0, false)); + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_TEMPLAR_COLONEL, HELIOS_SPAWN_LOC, 0, false)); + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_TEMPLAR_COLONEL, HELIOS_SPAWN_LOC, 0, false)); + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_TEMPLAR_COLONEL, HELIOS_SPAWN_LOC, 0, false)); + + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_SHARPSHOOTER, HELIOS_SPAWN_LOC, 0, false)); + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_SHARPSHOOTER, HELIOS_SPAWN_LOC, 0, false)); + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_SHARPSHOOTER, HELIOS_SPAWN_LOC, 0, false)); + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_SHARPSHOOTER, HELIOS_SPAWN_LOC, 0, false)); + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_SHARPSHOOTER, HELIOS_SPAWN_LOC, 0, false)); + + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_ARCHMAGE, HELIOS_SPAWN_LOC, 0, false)); + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_ARCHMAGE, HELIOS_SPAWN_LOC, 0, false)); + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_ARCHMAGE, HELIOS_SPAWN_LOC, 0, false)); + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_ARCHMAGE, HELIOS_SPAWN_LOC, 0, false)); + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_ARCHMAGE, HELIOS_SPAWN_LOC, 0, false)); + + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_GATEKEEPER, HELIOS_SPAWN_LOC, 0, false)); + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_GATEKEEPER, HELIOS_SPAWN_LOC, 0, false)); + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_GATEKEEPER, HELIOS_SPAWN_LOC, 0, false)); + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_GATEKEEPER, HELIOS_SPAWN_LOC, 0, false)); + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_GATEKEEPER, HELIOS_SPAWN_LOC, 0, false)); + } // Misc private static final int HELIOS_RAID_DURATION = 5; // hours private static Npc bossInstance; private final NoSummonFriendZone bossZone; + private GrandBossInstance _tempHelios; + private static List _minionSpawns = new ArrayList<>(); + private static Npc blueLightning; + private static Npc redLightning; + private static Npc leopold; + private boolean activated = false; + private boolean stage1_50 = false; + private boolean stage2_50 = false; + private boolean helios80 = false; + private boolean helios50 = false; + private boolean _announce = false; + protected ScheduledFuture _blueSpearTask; + protected ScheduledFuture _redSpearTask; + protected ScheduledFuture _leopoldTask; + protected ScheduledFuture _debuffTask; private Helios() { - addKillId(HELIOS1, HELIOS2, HELIOS3); + addAttackId(HELIOS1, HELIOS2, HELIOS3); + addKillId(HELIOS1, HELIOS2, HELIOS3, MIMILLION, MIMILLUS); // Zone bossZone = ZoneManager.getInstance().getZoneById(ZONE_ID, NoSummonFriendZone.class); // Unlock @@ -69,23 +157,184 @@ public class Helios extends AbstractNpcAI } else { + _tempHelios = (GrandBossInstance) addSpawn(HELIOS3, -113360, -244676, -15536, 0, false, 0); + GrandBossManager.getInstance().addBoss(_tempHelios); GrandBossManager.getInstance().setBossStatus(HELIOS3, ALIVE); } } - else if (status != ALIVE) + else { + _tempHelios = (GrandBossInstance) addSpawn(HELIOS3, -113360, -244676, -15536, 0, false, 0); + GrandBossManager.getInstance().addBoss(_tempHelios); GrandBossManager.getInstance().setBossStatus(HELIOS3, ALIVE); } } + @Override + public String onAttack(Npc npc, PlayerInstance attacker, int damage, boolean isSummon) + { + if ((npc.getId() == HELIOS1) && !_announce) + { + _announce = true; + _debuffTask = ThreadPool.scheduleAtFixedRate(() -> + { + bossZone.getPlayersInside().forEach(player -> + { + AUDIENCE_DEBUFF.getSkill().applyEffects(player, player); + }); + }, 5000, 20000); + Broadcast.toAllOnlinePlayers(new ExShowScreenMessage(NpcStringId.THE_ADEN_WARRIORS_BEGIN_BATTLE_WITH_THE_GIANT_EMPEROR_HELIOS, ExShowScreenMessage.TOP_CENTER, 10000, true)); + } + if ((npc.getId() == HELIOS1) && !stage1_50 && (npc.getCurrentHp() <= (npc.getMaxHp() * 0.5))) + { + stage1_50 = true; + HELIOS_RAGE1.getSkill().applyEffects(bossInstance, bossInstance); + } + if ((npc.getId() == HELIOS2) && !activated) + { + activated = true; + HELIOS_RAGE1.getSkill().applyEffects(bossInstance, bossInstance); + _blueSpearTask = ThreadPool.scheduleAtFixedRate(() -> + { + int count = bossZone.getPlayersInside().size(); + if (count > 0) + { + PlayerInstance randomPlayer = bossZone.getPlayersInside().get(getRandom(count)); + if (blueLightning != null) + { + blueLightning.setTarget(randomPlayer); + blueLightning.doCast(BLUE_LIGHTNING_SPEAR.getSkill()); + } + } + bossZone.broadcastPacket(new ExShowScreenMessage(NpcStringId.HELIOS_PICKS_UP_THE_BLUE_LIGHTNING_SPEAR_AND_BEGINS_GATHERING_HIS_POWER, ExShowScreenMessage.TOP_CENTER, 10000, true)); + }, 10000, 120000); + _redSpearTask = ThreadPool.scheduleAtFixedRate(() -> + { + int count = bossZone.getPlayersInside().size(); + if (count > 0) + { + PlayerInstance randomPlayer = bossZone.getPlayersInside().get(getRandom(count)); + if (redLightning != null) + { + redLightning.setTarget(randomPlayer); + redLightning.doCast(RED_LIGHTNING_SPEAR.getSkill()); + } + } + bossZone.broadcastPacket(new ExShowScreenMessage(NpcStringId.HELIOS_PICKS_UP_THE_RED_LIGHTNING_SPEAR_AND_BEGINS_GATHERING_HIS_POWER, ExShowScreenMessage.TOP_CENTER, 10000, true)); + }, 30000, 120000); + _leopoldTask = ThreadPool.scheduleAtFixedRate(() -> + { + int count = bossZone.getPlayersInside().size(); + if (count > 0) + { + PlayerInstance randomPlayer = bossZone.getPlayersInside().get(getRandom(count)); + if (leopold != null) + { + leopold.setTarget(randomPlayer); + int rnd = getRandom(100); + if (rnd < 16) + { + leopold.doCast(LEOPOLD_BOMB.getSkill()); + } + else if (rnd < 32) + { + leopold.doCast(LEOPOLD_PLASMA_BOMB.getSkill()); + } + else if (rnd < 48) + { + leopold.doCast(LEOPOLD_ENERGY_BOMB.getSkill()); + } + else if (rnd < 64) + { + leopold.doCast(LEOPOLD_MINI_GUN.getSkill()); + } + else if (rnd < 80) + { + leopold.doCast(LEOPOLD_SPRAY_SHOT.getSkill()); + } + else + { + leopold.doCast(LEOPOLD_HARPOON.getSkill()); + } + } + } + }, 5000, 10000); + } + if ((npc.getId() == HELIOS2) && !stage2_50 && (npc.getCurrentHp() <= (npc.getMaxHp() * 0.5))) + { + stage2_50 = true; + HELIOS_RAGE2.getSkill().applyEffects(bossInstance, bossInstance); + } + if ((npc.getId() == HELIOS3) && !activated) + { + activated = true; + HELIOS_RAGE3.getSkill().applyEffects(bossInstance, bossInstance); + _leopoldTask = ThreadPool.scheduleAtFixedRate(() -> + { + int count = bossZone.getPlayersInside().size(); + if (count > 0) + { + PlayerInstance randomPlayer = bossZone.getPlayersInside().get(getRandom(count)); + if (leopold != null) + { + leopold.setTarget(randomPlayer); + int rnd = getRandom(100); + if (rnd < 16) + { + leopold.doCast(LEOPOLD_BOMB.getSkill()); + } + else if (rnd < 32) + { + leopold.doCast(LEOPOLD_PLASMA_BOMB.getSkill()); + } + else if (rnd < 48) + { + leopold.doCast(LEOPOLD_ENERGY_BOMB.getSkill()); + } + else if (rnd < 64) + { + leopold.doCast(LEOPOLD_MINI_GUN.getSkill()); + } + else if (rnd < 80) + { + leopold.doCast(LEOPOLD_SPRAY_SHOT.getSkill()); + } + else + { + leopold.doCast(LEOPOLD_HARPOON.getSkill()); + } + } + } + }, 5000, 10000); + } + if ((npc.getId() == HELIOS3) && !helios80 && (npc.getCurrentHp() <= (npc.getMaxHp() * 0.8))) + { + helios80 = true; + addSpawn(LEOPOLD_ORIGIN, LEOPOLD_ORIGIN_LOC, false, 0); + addSpawn(ENUMA_ELISH_ORIGIN, ENUMA_ELISH_ORIGIN_LOC, false, 0); + bossZone.broadcastPacket(new ExShowScreenMessage(NpcStringId.THE_KAMAEL_ORIGINS_ABOVE_THE_THRONE_OF_HELIOS_BEGIN_TO_SOAR, ExShowScreenMessage.TOP_CENTER, 10000, true)); + } + else if ((npc.getId() == HELIOS3) && !helios50 && (npc.getCurrentHp() <= (npc.getMaxHp() * 0.5))) + { + helios50 = true; + HELIOS_RAGE4.getSkill().applyEffects(bossInstance, bossInstance); + bossZone.broadcastPacket(new ExShowScreenMessage(NpcStringId.HELIOS_USES_THE_PRANARACH_SHIELD_OF_LIGHT_TO_MINIMIZE_DAMAGE, ExShowScreenMessage.TOP_CENTER, 10000, true)); + bossInstance.abortCast(); + bossInstance.doCast(PRANARACH.getSkill()); + } + return super.onAttack(npc, attacker, damage, isSummon); + } + @Override public String onAdvEvent(String event, Npc npc, PlayerInstance player) { - final String htmltext = null; + String htmltext = null; switch (event) { case "unlock_helios": { + _tempHelios = (GrandBossInstance) addSpawn(HELIOS3, -113360, -244676, -15536, 0, false, 0); + GrandBossManager.getInstance().addBoss(_tempHelios); GrandBossManager.getInstance().setBossStatus(HELIOS3, ALIVE); break; } @@ -95,6 +344,10 @@ public class Helios extends AbstractNpcAI { GrandBossManager.getInstance().setBossStatus(HELIOS3, FIGHTING); bossInstance = addSpawn(HELIOS1, HELIOS_SPAWN_LOC.getX(), HELIOS_SPAWN_LOC.getY(), HELIOS_SPAWN_LOC.getZ(), HELIOS_SPAWN_LOC.getHeading(), false, 0, false); + for (SpawnHolder spawn : SPAWNS_MINIONS) + { + _minionSpawns.add(addSpawn(spawn.getNpcId(), spawn.getLocation())); + } startQuestTimer("resetRaid", HELIOS_RAID_DURATION * 60 * 60 * 1000, bossInstance, null); } break; @@ -104,35 +357,141 @@ public class Helios extends AbstractNpcAI final int status = GrandBossManager.getInstance().getBossStatus(HELIOS3); if ((status > ALIVE) && (status < DEAD)) { + bossZone.oustAllPlayers(); + Broadcast.toAllOnlinePlayers(new ExShowScreenMessage(NpcStringId.THE_HEROES_DRAINED_OF_THEIR_POWERS_HAVE_BEEN_BANISHED_FROM_THE_THRONE_OF_HELIOS_BY_HELIOS_POWERS, ExShowScreenMessage.TOP_CENTER, 10000, true)); GrandBossManager.getInstance().setBossStatus(HELIOS3, ALIVE); - npc.deleteMe(); + Clean(); } break; } + case "stage2": + { + bossInstance = addSpawn(HELIOS2, HELIOS_SPAWN_LOC.getX(), HELIOS_SPAWN_LOC.getY(), HELIOS_SPAWN_LOC.getZ(), HELIOS_SPAWN_LOC.getHeading(), false, 0, false); + bossZone.broadcastPacket(new ExShowScreenMessage(NpcStringId.HELIOS_APPEARANCE_CHANGES_AND_HE_BEGINS_TO_GROW_STRONGER, ExShowScreenMessage.TOP_CENTER, 10000, true)); + for (SpawnHolder spawn : SPAWNS_MINIONS) + { + _minionSpawns.add(addSpawn(spawn.getNpcId(), spawn.getLocation())); + } + startQuestTimer("spheresSpawn", 10000, null, null); + break; + } + case "stage3": + { + activated = false; + bossInstance = addSpawn(HELIOS3, HELIOS_SPAWN_LOC.getX(), HELIOS_SPAWN_LOC.getY(), HELIOS_SPAWN_LOC.getZ(), HELIOS_SPAWN_LOC.getHeading(), false, 0, false); + bossZone.broadcastPacket(new ExShowScreenMessage(NpcStringId.HELIOS_APPEARANCE_CHANGES_AND_HE_BEGINS_TO_GROW_STRONGER, ExShowScreenMessage.TOP_CENTER, 10000, true)); + startQuestTimer("leopoldSpawn", 10000, null, null); + break; + } + case "spheresSpawn": + { + blueLightning = addSpawn(HELIOS_BLUE_LIGHTNING, BLUE_LIGHTNING_SPEAR_LOC, false, 0); + redLightning = addSpawn(HELIOS_RED_LIGHTNING, RED_LIGHTNING_SPEAR_LOC, false, 0); + blueLightning.setInvul(true); + redLightning.setInvul(true); + bossZone.broadcastPacket(new ExShowScreenMessage(NpcStringId.THE_ENUMA_ELISH_SPEAR_ON_THE_THRONE_OF_HELIOS_IS_PREPARED_AND_PLACED_IN_POSITION, ExShowScreenMessage.TOP_CENTER, 10000, true)); + startQuestTimer("protectorsSpawn", 10000, null, null); + break; + } + case "protectorsSpawn": + { + bossZone.broadcastPacket(new ExShowScreenMessage(NpcStringId.MIMILLION_AND_MIMILLUS_APPEAR_IN_ORDER_TO_PROTECT_THE_ENUMA_ELISH_OF_RED_LIGHTNING_AND_THE_ENUMA_ELISH_OF_BLUE_LIGHTNING, ExShowScreenMessage.TOP_CENTER, 10000, true)); + addSpawn(MIMILLION, MIMILLION_LOC, false, 0); + addSpawn(MIMILLUS, MIMILLUS_LOC, false, 0); + startQuestTimer("leopoldSpawn", 10000, null, null); + break; + } + case "leopoldSpawn": + { + leopold = addSpawn(LEOPOLD, LEOPOLD_LOC, false, 0); + bossZone.broadcastPacket(new ExShowScreenMessage(NpcStringId.THE_SIEGE_CANNON_LEOPOLD_ON_THE_THRONE_OF_HELIOS_BEGINS_TO_PREPARE_TO_FIRE, ExShowScreenMessage.TOP_CENTER, 10000, true)); + break; + } } return htmltext; } + private void Clean() + { + bossZone.getCharactersInside().forEach(mob -> + { + if (mob.isNpc()) + { + mob.deleteMe(); + } + }); + if (_blueSpearTask != null) + { + _blueSpearTask.cancel(true); + _blueSpearTask = null; + } + if (_redSpearTask != null) + { + _redSpearTask.cancel(true); + _redSpearTask = null; + } + if (_leopoldTask != null) + { + _leopoldTask.cancel(true); + _leopoldTask = null; + } + if (_debuffTask != null) + { + _debuffTask.cancel(true); + _debuffTask = null; + } + } + @Override public String onKill(Npc npc, PlayerInstance killer, boolean isSummon) { switch (npc.getId()) { + case MIMILLION: + { + if (redLightning != null) + { + redLightning.deleteMe(); + bossZone.broadcastPacket(new ExShowScreenMessage(NpcStringId.MIMILLION_FALLS_AND_THE_RED_LIGHTNING_SPEAR_VANISHES, ExShowScreenMessage.TOP_CENTER, 10000, true)); + } + break; + } + case MIMILLUS: + { + if (blueLightning != null) + { + blueLightning.deleteMe(); + bossZone.broadcastPacket(new ExShowScreenMessage(NpcStringId.MIMILLUS_FALLS_AND_THE_BLUE_LIGHTNING_SPEAR_VANISHES, ExShowScreenMessage.TOP_CENTER, 10000, true)); + } + break; + } case HELIOS1: { bossInstance.deleteMe(); - bossInstance = addSpawn(HELIOS2, HELIOS_SPAWN_LOC.getX(), HELIOS_SPAWN_LOC.getY(), HELIOS_SPAWN_LOC.getZ(), HELIOS_SPAWN_LOC.getHeading(), false, 0, false); - bossZone.broadcastPacket(new ExShowScreenMessage(NpcStringId.HELIOS_APPEARANCE_CHANGES_AND_HE_BEGINS_TO_GROW_STRONGER, ExShowScreenMessage.TOP_CENTER, 10000, true)); + bossZone.getPlayersInside().forEach(player -> + { + playMovie(player, Movie.SC_HELIOS_TRANS_A); + }); + startQuestTimer("stage2", 15000, null, null); break; } case HELIOS2: { bossInstance.deleteMe(); - bossInstance = addSpawn(HELIOS3, HELIOS_SPAWN_LOC.getX(), HELIOS_SPAWN_LOC.getY(), HELIOS_SPAWN_LOC.getZ(), HELIOS_SPAWN_LOC.getHeading(), false, 0, false); + if (leopold != null) + { + leopold.deleteMe(); + } + bossZone.getPlayersInside().forEach(player -> + { + playMovie(player, Movie.SC_HELIOS_TRANS_B); + }); + startQuestTimer("stage3", 15000, null, null); break; } case HELIOS3: { + Clean(); bossZone.broadcastPacket(new ExShowScreenMessage(NpcStringId.HELIOS_DEFEATED_TAKES_FLIGHT_DEEP_IN_TO_THE_SUPERION_FORT_HIS_THRONE_IS_RENDERED_INACTIVE, ExShowScreenMessage.TOP_CENTER, 10000, true)); GrandBossManager.getInstance().setBossStatus(HELIOS3, DEAD); final long respawnTime = (Config.HELIOS_SPAWN_INTERVAL + getRandom(-Config.HELIOS_SPAWN_RANDOM, Config.HELIOS_SPAWN_RANDOM)) * 3600000; @@ -150,4 +509,4 @@ public class Helios extends AbstractNpcAI { new Helios(); } -} +} \ No newline at end of file diff --git a/L2J_Mobius_5.0_Salvation/dist/game/data/scripts/ai/bosses/Helios/Helios1.java b/L2J_Mobius_5.0_Salvation/dist/game/data/scripts/ai/bosses/Helios/Helios1.java new file mode 100644 index 0000000000..336c5de75a --- /dev/null +++ b/L2J_Mobius_5.0_Salvation/dist/game/data/scripts/ai/bosses/Helios/Helios1.java @@ -0,0 +1,182 @@ +/* + * This file is part of the L2J Mobius project. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ai.bosses.Helios; + +import org.l2jmobius.commons.util.CommonUtil; +import org.l2jmobius.gameserver.model.actor.Creature; +import org.l2jmobius.gameserver.model.actor.Npc; +import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; +import org.l2jmobius.gameserver.model.holders.SkillHolder; +import org.l2jmobius.gameserver.model.skills.Skill; +import org.l2jmobius.gameserver.model.skills.SkillCaster; +import org.l2jmobius.gameserver.model.variables.NpcVariables; + +import ai.AbstractNpcAI; + +/** + * @author NviX + */ +public class Helios1 extends AbstractNpcAI +{ + // Npc + private static final int HELIOS = 29303; + // Skills + private static final SkillHolder HELIOS_PLASMA = new SkillHolder(16609, 1); + private static final SkillHolder HELIOS_GRAND_PLASMA = new SkillHolder(16610, 1); + private static final SkillHolder HELIOS_THRONE_OF_AGONY = new SkillHolder(16611, 1); + + private Helios1() + { + registerMobs(HELIOS); + } + + @Override + public String onAdvEvent(String event, Npc npc, PlayerInstance player) + { + switch (event) + { + case "MANAGE_SKILLS": + { + if (npc != null) + { + manageSkills(npc); + } + break; + } + } + return super.onAdvEvent(event, npc, player); + } + + @Override + public String onAttack(Npc npc, PlayerInstance attacker, int damage, boolean isSummon, Skill skill) + { + if (npc.getId() == HELIOS) + { + if (skill == null) + { + refreshAiParams(attacker, npc, (damage * 1000)); + } + else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.25)) + { + refreshAiParams(attacker, npc, ((damage / 3) * 100)); + } + else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.5)) + { + refreshAiParams(attacker, npc, (damage * 20)); + } + else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.75)) + { + refreshAiParams(attacker, npc, (damage * 10)); + } + else + { + refreshAiParams(attacker, npc, ((damage / 3) * 20)); + } + manageSkills(npc); + } + + return super.onAttack(npc, attacker, damage, isSummon); + } + + private final void refreshAiParams(Creature attacker, Npc npc, int damage) + { + refreshAiParams(attacker, npc, damage, damage); + } + + private final void refreshAiParams(Creature attacker, Npc npc, int damage, int aggro) + { + final int newAggroVal = damage + getRandom(3000); + final int aggroVal = aggro + 1000; + final NpcVariables vars = npc.getVariables(); + for (int i = 0; i < 3; i++) + { + if (attacker == vars.getObject("c_quest" + i, Creature.class)) + { + if (vars.getInt("i_quest" + i) < aggroVal) + { + vars.set("i_quest" + i, newAggroVal); + } + return; + } + } + final int index = CommonUtil.getIndexOfMinValue(vars.getInt("i_quest0"), vars.getInt("i_quest1"), vars.getInt("i_quest2")); + vars.set("i_quest" + index, newAggroVal); + vars.set("c_quest" + index, attacker); + } + + @Override + public String onSpellFinished(Npc npc, PlayerInstance player, Skill skill) + { + startQuestTimer("MANAGE_SKILLS", 1000, npc, null); + + return super.onSpellFinished(npc, player, skill); + } + + private void manageSkills(Npc npc) + { + if (npc.isCastingNow(SkillCaster::isAnyNormalType) || npc.isCoreAIDisabled() || !npc.isInCombat()) + { + return; + } + + final NpcVariables vars = npc.getVariables(); + for (int i = 0; i < 3; i++) + { + final Creature attacker = vars.getObject("c_quest" + i, Creature.class); + if ((attacker == null) || ((npc.calculateDistance3D(attacker) > 9000) || attacker.isDead())) + { + vars.set("i_quest" + i, 0); + } + } + final int index = CommonUtil.getIndexOfMaxValue(vars.getInt("i_quest0"), vars.getInt("i_quest1"), vars.getInt("i_quest2")); + final Creature player = vars.getObject("c_quest" + index, Creature.class); + final int i2 = vars.getInt("i_quest" + index); + if ((i2 > 0) && (getRandom(100) < 70)) + { + vars.set("i_quest" + index, 500); + } + + SkillHolder skillToCast = null; + if ((player != null) && !player.isDead()) + { + if (getRandom(100) < 30) + { + skillToCast = HELIOS_GRAND_PLASMA; + } + else if (getRandom(100) < 50) + { + skillToCast = HELIOS_THRONE_OF_AGONY; + } + else + { + skillToCast = HELIOS_PLASMA; + } + } + + if ((skillToCast != null) && SkillCaster.checkUseConditions(npc, skillToCast.getSkill())) + + { + npc.setTarget(player); + npc.doCast(skillToCast.getSkill()); + } + } + + public static void main(String[] args) + { + new Helios1(); + } +} diff --git a/L2J_Mobius_5.0_Salvation/dist/game/data/scripts/ai/bosses/Helios/Helios2.java b/L2J_Mobius_5.0_Salvation/dist/game/data/scripts/ai/bosses/Helios/Helios2.java new file mode 100644 index 0000000000..cf7ad4b0e6 --- /dev/null +++ b/L2J_Mobius_5.0_Salvation/dist/game/data/scripts/ai/bosses/Helios/Helios2.java @@ -0,0 +1,182 @@ +/* + * This file is part of the L2J Mobius project. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ai.bosses.Helios; + +import org.l2jmobius.commons.util.CommonUtil; +import org.l2jmobius.gameserver.model.actor.Creature; +import org.l2jmobius.gameserver.model.actor.Npc; +import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; +import org.l2jmobius.gameserver.model.holders.SkillHolder; +import org.l2jmobius.gameserver.model.skills.Skill; +import org.l2jmobius.gameserver.model.skills.SkillCaster; +import org.l2jmobius.gameserver.model.variables.NpcVariables; + +import ai.AbstractNpcAI; + +/** + * @author NviX + */ +public class Helios2 extends AbstractNpcAI +{ + // Npc + private static final int HELIOS = 29304; + // Skills + private static final SkillHolder EMPEROR_HELIOS_AUTHORITY = new SkillHolder(16612, 1); + private static final SkillHolder HELIOS_PLASMA_PRESSURE = new SkillHolder(16614, 1); + private static final SkillHolder HELIOS_PLASMA_WALL = new SkillHolder(16615, 1); + + private Helios2() + { + registerMobs(HELIOS); + } + + @Override + public String onAdvEvent(String event, Npc npc, PlayerInstance player) + { + switch (event) + { + case "MANAGE_SKILLS": + { + if (npc != null) + { + manageSkills(npc); + } + break; + } + } + return super.onAdvEvent(event, npc, player); + } + + @Override + public String onAttack(Npc npc, PlayerInstance attacker, int damage, boolean isSummon, Skill skill) + { + if (npc.getId() == HELIOS) + { + if (skill == null) + { + refreshAiParams(attacker, npc, (damage * 1000)); + } + else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.25)) + { + refreshAiParams(attacker, npc, ((damage / 3) * 100)); + } + else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.5)) + { + refreshAiParams(attacker, npc, (damage * 20)); + } + else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.75)) + { + refreshAiParams(attacker, npc, (damage * 10)); + } + else + { + refreshAiParams(attacker, npc, ((damage / 3) * 20)); + } + manageSkills(npc); + } + + return super.onAttack(npc, attacker, damage, isSummon); + } + + private final void refreshAiParams(Creature attacker, Npc npc, int damage) + { + refreshAiParams(attacker, npc, damage, damage); + } + + private final void refreshAiParams(Creature attacker, Npc npc, int damage, int aggro) + { + final int newAggroVal = damage + getRandom(3000); + final int aggroVal = aggro + 1000; + final NpcVariables vars = npc.getVariables(); + for (int i = 0; i < 3; i++) + { + if (attacker == vars.getObject("c_quest" + i, Creature.class)) + { + if (vars.getInt("i_quest" + i) < aggroVal) + { + vars.set("i_quest" + i, newAggroVal); + } + return; + } + } + final int index = CommonUtil.getIndexOfMinValue(vars.getInt("i_quest0"), vars.getInt("i_quest1"), vars.getInt("i_quest2")); + vars.set("i_quest" + index, newAggroVal); + vars.set("c_quest" + index, attacker); + } + + @Override + public String onSpellFinished(Npc npc, PlayerInstance player, Skill skill) + { + startQuestTimer("MANAGE_SKILLS", 1000, npc, null); + + return super.onSpellFinished(npc, player, skill); + } + + private void manageSkills(Npc npc) + { + if (npc.isCastingNow(SkillCaster::isAnyNormalType) || npc.isCoreAIDisabled() || !npc.isInCombat()) + { + return; + } + + final NpcVariables vars = npc.getVariables(); + for (int i = 0; i < 3; i++) + { + final Creature attacker = vars.getObject("c_quest" + i, Creature.class); + if ((attacker == null) || ((npc.calculateDistance3D(attacker) > 9000) || attacker.isDead())) + { + vars.set("i_quest" + i, 0); + } + } + final int index = CommonUtil.getIndexOfMaxValue(vars.getInt("i_quest0"), vars.getInt("i_quest1"), vars.getInt("i_quest2")); + final Creature player = vars.getObject("c_quest" + index, Creature.class); + final int i2 = vars.getInt("i_quest" + index); + if ((i2 > 0) && (getRandom(100) < 70)) + { + vars.set("i_quest" + index, 500); + } + + SkillHolder skillToCast = null; + if ((player != null) && !player.isDead()) + { + if (getRandom(100) < 30) + { + skillToCast = EMPEROR_HELIOS_AUTHORITY; + } + else if (getRandom(100) < 50) + { + skillToCast = HELIOS_PLASMA_PRESSURE; + } + else + { + skillToCast = HELIOS_PLASMA_WALL; + } + } + + if ((skillToCast != null) && SkillCaster.checkUseConditions(npc, skillToCast.getSkill())) + + { + npc.setTarget(player); + npc.doCast(skillToCast.getSkill()); + } + } + + public static void main(String[] args) + { + new Helios2(); + } +} diff --git a/L2J_Mobius_5.0_Salvation/dist/game/data/scripts/ai/bosses/Helios/Helios3.java b/L2J_Mobius_5.0_Salvation/dist/game/data/scripts/ai/bosses/Helios/Helios3.java new file mode 100644 index 0000000000..efa78d5d99 --- /dev/null +++ b/L2J_Mobius_5.0_Salvation/dist/game/data/scripts/ai/bosses/Helios/Helios3.java @@ -0,0 +1,187 @@ +/* + * This file is part of the L2J Mobius project. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ai.bosses.Helios; + +import org.l2jmobius.commons.util.CommonUtil; +import org.l2jmobius.gameserver.model.actor.Creature; +import org.l2jmobius.gameserver.model.actor.Npc; +import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; +import org.l2jmobius.gameserver.model.holders.SkillHolder; +import org.l2jmobius.gameserver.model.skills.Skill; +import org.l2jmobius.gameserver.model.skills.SkillCaster; +import org.l2jmobius.gameserver.model.variables.NpcVariables; + +import ai.AbstractNpcAI; + +/** + * @author NviX + */ +public class Helios3 extends AbstractNpcAI +{ + // Npc + private static final int HELIOS = 29305; + // Skills + private static final SkillHolder HELIOS_OVERAWING_GAZE = new SkillHolder(16616, 1); + private static final SkillHolder HELIOS_HOLY_SPIKE = new SkillHolder(16621, 1); + private static final SkillHolder HELIOS_BIONIC_BOMB = new SkillHolder(16622, 1); + private static final SkillHolder HELIOS_LIGHTNING_OF_ANGER = new SkillHolder(16623, 1); + + private Helios3() + { + registerMobs(HELIOS); + } + + @Override + public String onAdvEvent(String event, Npc npc, PlayerInstance player) + { + switch (event) + { + case "MANAGE_SKILLS": + { + if (npc != null) + { + manageSkills(npc); + } + break; + } + } + return super.onAdvEvent(event, npc, player); + } + + @Override + public String onAttack(Npc npc, PlayerInstance attacker, int damage, boolean isSummon, Skill skill) + { + if (npc.getId() == HELIOS) + { + if (skill == null) + { + refreshAiParams(attacker, npc, (damage * 1000)); + } + else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.25)) + { + refreshAiParams(attacker, npc, ((damage / 3) * 100)); + } + else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.5)) + { + refreshAiParams(attacker, npc, (damage * 20)); + } + else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.75)) + { + refreshAiParams(attacker, npc, (damage * 10)); + } + else + { + refreshAiParams(attacker, npc, ((damage / 3) * 20)); + } + manageSkills(npc); + } + + return super.onAttack(npc, attacker, damage, isSummon); + } + + private final void refreshAiParams(Creature attacker, Npc npc, int damage) + { + refreshAiParams(attacker, npc, damage, damage); + } + + private final void refreshAiParams(Creature attacker, Npc npc, int damage, int aggro) + { + final int newAggroVal = damage + getRandom(3000); + final int aggroVal = aggro + 1000; + final NpcVariables vars = npc.getVariables(); + for (int i = 0; i < 3; i++) + { + if (attacker == vars.getObject("c_quest" + i, Creature.class)) + { + if (vars.getInt("i_quest" + i) < aggroVal) + { + vars.set("i_quest" + i, newAggroVal); + } + return; + } + } + final int index = CommonUtil.getIndexOfMinValue(vars.getInt("i_quest0"), vars.getInt("i_quest1"), vars.getInt("i_quest2")); + vars.set("i_quest" + index, newAggroVal); + vars.set("c_quest" + index, attacker); + } + + @Override + public String onSpellFinished(Npc npc, PlayerInstance player, Skill skill) + { + startQuestTimer("MANAGE_SKILLS", 1000, npc, null); + + return super.onSpellFinished(npc, player, skill); + } + + private void manageSkills(Npc npc) + { + if (npc.isCastingNow(SkillCaster::isAnyNormalType) || npc.isCoreAIDisabled() || !npc.isInCombat()) + { + return; + } + + final NpcVariables vars = npc.getVariables(); + for (int i = 0; i < 3; i++) + { + final Creature attacker = vars.getObject("c_quest" + i, Creature.class); + if ((attacker == null) || ((npc.calculateDistance3D(attacker) > 9000) || attacker.isDead())) + { + vars.set("i_quest" + i, 0); + } + } + final int index = CommonUtil.getIndexOfMaxValue(vars.getInt("i_quest0"), vars.getInt("i_quest1"), vars.getInt("i_quest2")); + final Creature player = vars.getObject("c_quest" + index, Creature.class); + final int i2 = vars.getInt("i_quest" + index); + if ((i2 > 0) && (getRandom(100) < 70)) + { + vars.set("i_quest" + index, 500); + } + + SkillHolder skillToCast = null; + if ((player != null) && !player.isDead()) + { + if (getRandom(100) < 10) + { + skillToCast = HELIOS_LIGHTNING_OF_ANGER; + } + else if (getRandom(100) < 30) + { + skillToCast = HELIOS_OVERAWING_GAZE; + } + else if (getRandom(100) < 50) + { + skillToCast = HELIOS_BIONIC_BOMB; + } + else + { + skillToCast = HELIOS_HOLY_SPIKE; + } + } + + if ((skillToCast != null) && SkillCaster.checkUseConditions(npc, skillToCast.getSkill())) + + { + npc.setTarget(player); + npc.doCast(skillToCast.getSkill()); + } + } + + public static void main(String[] args) + { + new Helios3(); + } +} diff --git a/L2J_Mobius_5.0_Salvation/dist/game/data/scripts/ai/bosses/Helios/RoyalArchmageMinion.java b/L2J_Mobius_5.0_Salvation/dist/game/data/scripts/ai/bosses/Helios/RoyalArchmageMinion.java new file mode 100644 index 0000000000..1529d6f1fb --- /dev/null +++ b/L2J_Mobius_5.0_Salvation/dist/game/data/scripts/ai/bosses/Helios/RoyalArchmageMinion.java @@ -0,0 +1,177 @@ +/* + * This file is part of the L2J Mobius project. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ai.bosses.Helios; + +import org.l2jmobius.commons.util.CommonUtil; +import org.l2jmobius.gameserver.model.actor.Creature; +import org.l2jmobius.gameserver.model.actor.Npc; +import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; +import org.l2jmobius.gameserver.model.holders.SkillHolder; +import org.l2jmobius.gameserver.model.skills.Skill; +import org.l2jmobius.gameserver.model.skills.SkillCaster; +import org.l2jmobius.gameserver.model.variables.NpcVariables; + +import ai.AbstractNpcAI; + +/** + * @author NviX + */ +public class RoyalArchmageMinion extends AbstractNpcAI +{ + // Npc + private static final int ROYAL_ARCHMAGE = 29313; + // Skills + private static final SkillHolder ULTRA_PLASMA_BALL = new SkillHolder(16685, 1); + private static final SkillHolder ULTRA_PLASMA_WAVE = new SkillHolder(16686, 1); + + private RoyalArchmageMinion() + { + registerMobs(ROYAL_ARCHMAGE); + } + + @Override + public String onAdvEvent(String event, Npc npc, PlayerInstance player) + { + switch (event) + { + case "MANAGE_SKILLS": + { + if (npc != null) + { + manageSkills(npc); + } + break; + } + } + return super.onAdvEvent(event, npc, player); + } + + @Override + public String onAttack(Npc npc, PlayerInstance attacker, int damage, boolean isSummon, Skill skill) + { + if (npc.getId() == ROYAL_ARCHMAGE) + { + if (skill == null) + { + refreshAiParams(attacker, npc, (damage * 1000)); + } + else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.25)) + { + refreshAiParams(attacker, npc, ((damage / 3) * 100)); + } + else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.5)) + { + refreshAiParams(attacker, npc, (damage * 20)); + } + else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.75)) + { + refreshAiParams(attacker, npc, (damage * 10)); + } + else + { + refreshAiParams(attacker, npc, ((damage / 3) * 20)); + } + manageSkills(npc); + } + + return super.onAttack(npc, attacker, damage, isSummon); + } + + private final void refreshAiParams(Creature attacker, Npc npc, int damage) + { + refreshAiParams(attacker, npc, damage, damage); + } + + private final void refreshAiParams(Creature attacker, Npc npc, int damage, int aggro) + { + final int newAggroVal = damage + getRandom(3000); + final int aggroVal = aggro + 1000; + final NpcVariables vars = npc.getVariables(); + for (int i = 0; i < 3; i++) + { + if (attacker == vars.getObject("c_quest" + i, Creature.class)) + { + if (vars.getInt("i_quest" + i) < aggroVal) + { + vars.set("i_quest" + i, newAggroVal); + } + return; + } + } + final int index = CommonUtil.getIndexOfMinValue(vars.getInt("i_quest0"), vars.getInt("i_quest1"), vars.getInt("i_quest2")); + vars.set("i_quest" + index, newAggroVal); + vars.set("c_quest" + index, attacker); + } + + @Override + public String onSpellFinished(Npc npc, PlayerInstance player, Skill skill) + { + startQuestTimer("MANAGE_SKILLS", 1000, npc, null); + + return super.onSpellFinished(npc, player, skill); + } + + private void manageSkills(Npc npc) + { + if (npc.isCastingNow(SkillCaster::isAnyNormalType) || npc.isCoreAIDisabled() || !npc.isInCombat()) + { + return; + } + + final NpcVariables vars = npc.getVariables(); + for (int i = 0; i < 3; i++) + { + final Creature attacker = vars.getObject("c_quest" + i, Creature.class); + if ((attacker == null) || ((npc.calculateDistance3D(attacker) > 9000) || attacker.isDead())) + { + vars.set("i_quest" + i, 0); + } + } + final int index = CommonUtil.getIndexOfMaxValue(vars.getInt("i_quest0"), vars.getInt("i_quest1"), vars.getInt("i_quest2")); + final Creature player = vars.getObject("c_quest" + index, Creature.class); + final int i2 = vars.getInt("i_quest" + index); + if ((i2 > 0) && (getRandom(100) < 70)) + { + vars.set("i_quest" + index, 500); + } + + SkillHolder skillToCast = null; + if ((player != null) && !player.isDead()) + { + if (getRandom(100) < 50) + { + skillToCast = ULTRA_PLASMA_WAVE; + } + else + { + skillToCast = ULTRA_PLASMA_BALL; + } + } + + if ((skillToCast != null) && SkillCaster.checkUseConditions(npc, skillToCast.getSkill())) + + { + npc.setTarget(player); + npc.doCast(skillToCast.getSkill()); + } + } + + public static void main(String[] args) + { + new RoyalArchmageMinion(); + } +} diff --git a/L2J_Mobius_5.5_EtinasFate/dist/game/data/scripts/ai/bosses/Helios/Helios.java b/L2J_Mobius_5.5_EtinasFate/dist/game/data/scripts/ai/bosses/Helios/Helios.java index 0f70177f83..9b7f63de07 100644 --- a/L2J_Mobius_5.5_EtinasFate/dist/game/data/scripts/ai/bosses/Helios/Helios.java +++ b/L2J_Mobius_5.5_EtinasFate/dist/game/data/scripts/ai/bosses/Helios/Helios.java @@ -16,30 +16,59 @@ */ package ai.bosses.Helios; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ScheduledFuture; + import org.l2jmobius.Config; +import org.l2jmobius.commons.concurrent.ThreadPool; +import org.l2jmobius.gameserver.enums.Movie; import org.l2jmobius.gameserver.instancemanager.GrandBossManager; import org.l2jmobius.gameserver.instancemanager.ZoneManager; import org.l2jmobius.gameserver.model.Location; import org.l2jmobius.gameserver.model.StatSet; import org.l2jmobius.gameserver.model.actor.Npc; +import org.l2jmobius.gameserver.model.actor.instance.GrandBossInstance; import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; +import org.l2jmobius.gameserver.model.holders.SkillHolder; +import org.l2jmobius.gameserver.model.holders.SpawnHolder; import org.l2jmobius.gameserver.model.zone.type.NoSummonFriendZone; import org.l2jmobius.gameserver.network.NpcStringId; import org.l2jmobius.gameserver.network.serverpackets.ExShowScreenMessage; +import org.l2jmobius.gameserver.util.Broadcast; import ai.AbstractNpcAI; /** - * @author Mobius + * @author Mobius, NviX */ public class Helios extends AbstractNpcAI { - // NPCs + // Raid private static final int HELIOS1 = 29303; private static final int HELIOS2 = 29304; private static final int HELIOS3 = 29305; + // Minions + private static final int LEOPOLD = 29306; + private static final int HELIOS_RED_LIGHTNING = 29307; + private static final int HELIOS_BLUE_LIGHTNING = 29308; + private static final int LEOPOLD_ORIGIN = 29309; + private static final int ENUMA_ELISH_ORIGIN = 29310; + private static final int ROYAL_TEMPLAR_COLONEL = 29311; + private static final int ROYAL_SHARPSHOOTER = 29312; + private static final int ROYAL_ARCHMAGE = 29313; + private static final int ROYAL_GATEKEEPER = 29314; + private static final int MIMILLION = 29315; + private static final int MIMILLUS = 29316; // Location private static final Location HELIOS_SPAWN_LOC = new Location(92771, 161909, 3494, 38329); + private static final Location BLUE_LIGHTNING_SPEAR_LOC = new Location(93208, 161269, 3489); + private static final Location RED_LIGHTNING_SPEAR_LOC = new Location(92348, 162558, 3489); + private static final Location MIMILLION_LOC = new Location(92465, 162465, 3487); + private static final Location MIMILLUS_LOC = new Location(93174, 161394, 3487); + private static final Location LEOPOLD_LOC = new Location(93531, 162415, 3487); + private static final Location LEOPOLD_ORIGIN_LOC = new Location(92601, 162196, 3464); + private static final Location ENUMA_ELISH_ORIGIN_LOC = new Location(92957, 161640, 3485); // Zone private static final int ZONE_ID = 210109; // Status @@ -47,14 +76,73 @@ public class Helios extends AbstractNpcAI private static final int WAITING = 1; private static final int FIGHTING = 2; private static final int DEAD = 3; + // Skills + private static final SkillHolder AUDIENCE_DEBUFF = new SkillHolder(16613, 1); + private static final SkillHolder RED_LIGHTNING_SPEAR = new SkillHolder(16617, 1); + private static final SkillHolder BLUE_LIGHTNING_SPEAR = new SkillHolder(16618, 1); + private static final SkillHolder PRANARACH = new SkillHolder(16624, 1); + private static final SkillHolder HELIOS_RAGE1 = new SkillHolder(16625, 1); + private static final SkillHolder HELIOS_RAGE2 = new SkillHolder(16625, 2); + private static final SkillHolder HELIOS_RAGE3 = new SkillHolder(16625, 3); + private static final SkillHolder HELIOS_RAGE4 = new SkillHolder(16625, 4); + private static final SkillHolder LEOPOLD_BOMB = new SkillHolder(16629, 1); + private static final SkillHolder LEOPOLD_PLASMA_BOMB = new SkillHolder(16630, 1); + private static final SkillHolder LEOPOLD_ENERGY_BOMB = new SkillHolder(16631, 1); + private static final SkillHolder LEOPOLD_MINI_GUN = new SkillHolder(16632, 1); + private static final SkillHolder LEOPOLD_SPRAY_SHOT = new SkillHolder(16633, 1); + private static final SkillHolder LEOPOLD_HARPOON = new SkillHolder(16634, 1); + // Spawns + private static final List SPAWNS_MINIONS = new ArrayList<>(); + static + { + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_TEMPLAR_COLONEL, HELIOS_SPAWN_LOC, 0, false)); + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_TEMPLAR_COLONEL, HELIOS_SPAWN_LOC, 0, false)); + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_TEMPLAR_COLONEL, HELIOS_SPAWN_LOC, 0, false)); + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_TEMPLAR_COLONEL, HELIOS_SPAWN_LOC, 0, false)); + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_TEMPLAR_COLONEL, HELIOS_SPAWN_LOC, 0, false)); + + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_SHARPSHOOTER, HELIOS_SPAWN_LOC, 0, false)); + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_SHARPSHOOTER, HELIOS_SPAWN_LOC, 0, false)); + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_SHARPSHOOTER, HELIOS_SPAWN_LOC, 0, false)); + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_SHARPSHOOTER, HELIOS_SPAWN_LOC, 0, false)); + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_SHARPSHOOTER, HELIOS_SPAWN_LOC, 0, false)); + + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_ARCHMAGE, HELIOS_SPAWN_LOC, 0, false)); + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_ARCHMAGE, HELIOS_SPAWN_LOC, 0, false)); + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_ARCHMAGE, HELIOS_SPAWN_LOC, 0, false)); + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_ARCHMAGE, HELIOS_SPAWN_LOC, 0, false)); + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_ARCHMAGE, HELIOS_SPAWN_LOC, 0, false)); + + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_GATEKEEPER, HELIOS_SPAWN_LOC, 0, false)); + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_GATEKEEPER, HELIOS_SPAWN_LOC, 0, false)); + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_GATEKEEPER, HELIOS_SPAWN_LOC, 0, false)); + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_GATEKEEPER, HELIOS_SPAWN_LOC, 0, false)); + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_GATEKEEPER, HELIOS_SPAWN_LOC, 0, false)); + } // Misc private static final int HELIOS_RAID_DURATION = 5; // hours private static Npc bossInstance; private final NoSummonFriendZone bossZone; + private GrandBossInstance _tempHelios; + private static List _minionSpawns = new ArrayList<>(); + private static Npc blueLightning; + private static Npc redLightning; + private static Npc leopold; + private boolean activated = false; + private boolean stage1_50 = false; + private boolean stage2_50 = false; + private boolean helios80 = false; + private boolean helios50 = false; + private boolean _announce = false; + protected ScheduledFuture _blueSpearTask; + protected ScheduledFuture _redSpearTask; + protected ScheduledFuture _leopoldTask; + protected ScheduledFuture _debuffTask; private Helios() { - addKillId(HELIOS1, HELIOS2, HELIOS3); + addAttackId(HELIOS1, HELIOS2, HELIOS3); + addKillId(HELIOS1, HELIOS2, HELIOS3, MIMILLION, MIMILLUS); // Zone bossZone = ZoneManager.getInstance().getZoneById(ZONE_ID, NoSummonFriendZone.class); // Unlock @@ -69,23 +157,184 @@ public class Helios extends AbstractNpcAI } else { + _tempHelios = (GrandBossInstance) addSpawn(HELIOS3, -113360, -244676, -15536, 0, false, 0); + GrandBossManager.getInstance().addBoss(_tempHelios); GrandBossManager.getInstance().setBossStatus(HELIOS3, ALIVE); } } - else if (status != ALIVE) + else { + _tempHelios = (GrandBossInstance) addSpawn(HELIOS3, -113360, -244676, -15536, 0, false, 0); + GrandBossManager.getInstance().addBoss(_tempHelios); GrandBossManager.getInstance().setBossStatus(HELIOS3, ALIVE); } } + @Override + public String onAttack(Npc npc, PlayerInstance attacker, int damage, boolean isSummon) + { + if ((npc.getId() == HELIOS1) && !_announce) + { + _announce = true; + _debuffTask = ThreadPool.scheduleAtFixedRate(() -> + { + bossZone.getPlayersInside().forEach(player -> + { + AUDIENCE_DEBUFF.getSkill().applyEffects(player, player); + }); + }, 5000, 20000); + Broadcast.toAllOnlinePlayers(new ExShowScreenMessage(NpcStringId.THE_ADEN_WARRIORS_BEGIN_BATTLE_WITH_THE_GIANT_EMPEROR_HELIOS, ExShowScreenMessage.TOP_CENTER, 10000, true)); + } + if ((npc.getId() == HELIOS1) && !stage1_50 && (npc.getCurrentHp() <= (npc.getMaxHp() * 0.5))) + { + stage1_50 = true; + HELIOS_RAGE1.getSkill().applyEffects(bossInstance, bossInstance); + } + if ((npc.getId() == HELIOS2) && !activated) + { + activated = true; + HELIOS_RAGE1.getSkill().applyEffects(bossInstance, bossInstance); + _blueSpearTask = ThreadPool.scheduleAtFixedRate(() -> + { + int count = bossZone.getPlayersInside().size(); + if (count > 0) + { + PlayerInstance randomPlayer = bossZone.getPlayersInside().get(getRandom(count)); + if (blueLightning != null) + { + blueLightning.setTarget(randomPlayer); + blueLightning.doCast(BLUE_LIGHTNING_SPEAR.getSkill()); + } + } + bossZone.broadcastPacket(new ExShowScreenMessage(NpcStringId.HELIOS_PICKS_UP_THE_BLUE_LIGHTNING_SPEAR_AND_BEGINS_GATHERING_HIS_POWER, ExShowScreenMessage.TOP_CENTER, 10000, true)); + }, 10000, 120000); + _redSpearTask = ThreadPool.scheduleAtFixedRate(() -> + { + int count = bossZone.getPlayersInside().size(); + if (count > 0) + { + PlayerInstance randomPlayer = bossZone.getPlayersInside().get(getRandom(count)); + if (redLightning != null) + { + redLightning.setTarget(randomPlayer); + redLightning.doCast(RED_LIGHTNING_SPEAR.getSkill()); + } + } + bossZone.broadcastPacket(new ExShowScreenMessage(NpcStringId.HELIOS_PICKS_UP_THE_RED_LIGHTNING_SPEAR_AND_BEGINS_GATHERING_HIS_POWER, ExShowScreenMessage.TOP_CENTER, 10000, true)); + }, 30000, 120000); + _leopoldTask = ThreadPool.scheduleAtFixedRate(() -> + { + int count = bossZone.getPlayersInside().size(); + if (count > 0) + { + PlayerInstance randomPlayer = bossZone.getPlayersInside().get(getRandom(count)); + if (leopold != null) + { + leopold.setTarget(randomPlayer); + int rnd = getRandom(100); + if (rnd < 16) + { + leopold.doCast(LEOPOLD_BOMB.getSkill()); + } + else if (rnd < 32) + { + leopold.doCast(LEOPOLD_PLASMA_BOMB.getSkill()); + } + else if (rnd < 48) + { + leopold.doCast(LEOPOLD_ENERGY_BOMB.getSkill()); + } + else if (rnd < 64) + { + leopold.doCast(LEOPOLD_MINI_GUN.getSkill()); + } + else if (rnd < 80) + { + leopold.doCast(LEOPOLD_SPRAY_SHOT.getSkill()); + } + else + { + leopold.doCast(LEOPOLD_HARPOON.getSkill()); + } + } + } + }, 5000, 10000); + } + if ((npc.getId() == HELIOS2) && !stage2_50 && (npc.getCurrentHp() <= (npc.getMaxHp() * 0.5))) + { + stage2_50 = true; + HELIOS_RAGE2.getSkill().applyEffects(bossInstance, bossInstance); + } + if ((npc.getId() == HELIOS3) && !activated) + { + activated = true; + HELIOS_RAGE3.getSkill().applyEffects(bossInstance, bossInstance); + _leopoldTask = ThreadPool.scheduleAtFixedRate(() -> + { + int count = bossZone.getPlayersInside().size(); + if (count > 0) + { + PlayerInstance randomPlayer = bossZone.getPlayersInside().get(getRandom(count)); + if (leopold != null) + { + leopold.setTarget(randomPlayer); + int rnd = getRandom(100); + if (rnd < 16) + { + leopold.doCast(LEOPOLD_BOMB.getSkill()); + } + else if (rnd < 32) + { + leopold.doCast(LEOPOLD_PLASMA_BOMB.getSkill()); + } + else if (rnd < 48) + { + leopold.doCast(LEOPOLD_ENERGY_BOMB.getSkill()); + } + else if (rnd < 64) + { + leopold.doCast(LEOPOLD_MINI_GUN.getSkill()); + } + else if (rnd < 80) + { + leopold.doCast(LEOPOLD_SPRAY_SHOT.getSkill()); + } + else + { + leopold.doCast(LEOPOLD_HARPOON.getSkill()); + } + } + } + }, 5000, 10000); + } + if ((npc.getId() == HELIOS3) && !helios80 && (npc.getCurrentHp() <= (npc.getMaxHp() * 0.8))) + { + helios80 = true; + addSpawn(LEOPOLD_ORIGIN, LEOPOLD_ORIGIN_LOC, false, 0); + addSpawn(ENUMA_ELISH_ORIGIN, ENUMA_ELISH_ORIGIN_LOC, false, 0); + bossZone.broadcastPacket(new ExShowScreenMessage(NpcStringId.THE_KAMAEL_ORIGINS_ABOVE_THE_THRONE_OF_HELIOS_BEGIN_TO_SOAR, ExShowScreenMessage.TOP_CENTER, 10000, true)); + } + else if ((npc.getId() == HELIOS3) && !helios50 && (npc.getCurrentHp() <= (npc.getMaxHp() * 0.5))) + { + helios50 = true; + HELIOS_RAGE4.getSkill().applyEffects(bossInstance, bossInstance); + bossZone.broadcastPacket(new ExShowScreenMessage(NpcStringId.HELIOS_USES_THE_PRANARACH_SHIELD_OF_LIGHT_TO_MINIMIZE_DAMAGE, ExShowScreenMessage.TOP_CENTER, 10000, true)); + bossInstance.abortCast(); + bossInstance.doCast(PRANARACH.getSkill()); + } + return super.onAttack(npc, attacker, damage, isSummon); + } + @Override public String onAdvEvent(String event, Npc npc, PlayerInstance player) { - final String htmltext = null; + String htmltext = null; switch (event) { case "unlock_helios": { + _tempHelios = (GrandBossInstance) addSpawn(HELIOS3, -113360, -244676, -15536, 0, false, 0); + GrandBossManager.getInstance().addBoss(_tempHelios); GrandBossManager.getInstance().setBossStatus(HELIOS3, ALIVE); break; } @@ -95,6 +344,10 @@ public class Helios extends AbstractNpcAI { GrandBossManager.getInstance().setBossStatus(HELIOS3, FIGHTING); bossInstance = addSpawn(HELIOS1, HELIOS_SPAWN_LOC.getX(), HELIOS_SPAWN_LOC.getY(), HELIOS_SPAWN_LOC.getZ(), HELIOS_SPAWN_LOC.getHeading(), false, 0, false); + for (SpawnHolder spawn : SPAWNS_MINIONS) + { + _minionSpawns.add(addSpawn(spawn.getNpcId(), spawn.getLocation())); + } startQuestTimer("resetRaid", HELIOS_RAID_DURATION * 60 * 60 * 1000, bossInstance, null); } break; @@ -104,35 +357,141 @@ public class Helios extends AbstractNpcAI final int status = GrandBossManager.getInstance().getBossStatus(HELIOS3); if ((status > ALIVE) && (status < DEAD)) { + bossZone.oustAllPlayers(); + Broadcast.toAllOnlinePlayers(new ExShowScreenMessage(NpcStringId.THE_HEROES_DRAINED_OF_THEIR_POWERS_HAVE_BEEN_BANISHED_FROM_THE_THRONE_OF_HELIOS_BY_HELIOS_POWERS, ExShowScreenMessage.TOP_CENTER, 10000, true)); GrandBossManager.getInstance().setBossStatus(HELIOS3, ALIVE); - npc.deleteMe(); + Clean(); } break; } + case "stage2": + { + bossInstance = addSpawn(HELIOS2, HELIOS_SPAWN_LOC.getX(), HELIOS_SPAWN_LOC.getY(), HELIOS_SPAWN_LOC.getZ(), HELIOS_SPAWN_LOC.getHeading(), false, 0, false); + bossZone.broadcastPacket(new ExShowScreenMessage(NpcStringId.HELIOS_APPEARANCE_CHANGES_AND_HE_BEGINS_TO_GROW_STRONGER, ExShowScreenMessage.TOP_CENTER, 10000, true)); + for (SpawnHolder spawn : SPAWNS_MINIONS) + { + _minionSpawns.add(addSpawn(spawn.getNpcId(), spawn.getLocation())); + } + startQuestTimer("spheresSpawn", 10000, null, null); + break; + } + case "stage3": + { + activated = false; + bossInstance = addSpawn(HELIOS3, HELIOS_SPAWN_LOC.getX(), HELIOS_SPAWN_LOC.getY(), HELIOS_SPAWN_LOC.getZ(), HELIOS_SPAWN_LOC.getHeading(), false, 0, false); + bossZone.broadcastPacket(new ExShowScreenMessage(NpcStringId.HELIOS_APPEARANCE_CHANGES_AND_HE_BEGINS_TO_GROW_STRONGER, ExShowScreenMessage.TOP_CENTER, 10000, true)); + startQuestTimer("leopoldSpawn", 10000, null, null); + break; + } + case "spheresSpawn": + { + blueLightning = addSpawn(HELIOS_BLUE_LIGHTNING, BLUE_LIGHTNING_SPEAR_LOC, false, 0); + redLightning = addSpawn(HELIOS_RED_LIGHTNING, RED_LIGHTNING_SPEAR_LOC, false, 0); + blueLightning.setInvul(true); + redLightning.setInvul(true); + bossZone.broadcastPacket(new ExShowScreenMessage(NpcStringId.THE_ENUMA_ELISH_SPEAR_ON_THE_THRONE_OF_HELIOS_IS_PREPARED_AND_PLACED_IN_POSITION, ExShowScreenMessage.TOP_CENTER, 10000, true)); + startQuestTimer("protectorsSpawn", 10000, null, null); + break; + } + case "protectorsSpawn": + { + bossZone.broadcastPacket(new ExShowScreenMessage(NpcStringId.MIMILLION_AND_MIMILLUS_APPEAR_IN_ORDER_TO_PROTECT_THE_ENUMA_ELISH_OF_RED_LIGHTNING_AND_THE_ENUMA_ELISH_OF_BLUE_LIGHTNING, ExShowScreenMessage.TOP_CENTER, 10000, true)); + addSpawn(MIMILLION, MIMILLION_LOC, false, 0); + addSpawn(MIMILLUS, MIMILLUS_LOC, false, 0); + startQuestTimer("leopoldSpawn", 10000, null, null); + break; + } + case "leopoldSpawn": + { + leopold = addSpawn(LEOPOLD, LEOPOLD_LOC, false, 0); + bossZone.broadcastPacket(new ExShowScreenMessage(NpcStringId.THE_SIEGE_CANNON_LEOPOLD_ON_THE_THRONE_OF_HELIOS_BEGINS_TO_PREPARE_TO_FIRE, ExShowScreenMessage.TOP_CENTER, 10000, true)); + break; + } } return htmltext; } + private void Clean() + { + bossZone.getCharactersInside().forEach(mob -> + { + if (mob.isNpc()) + { + mob.deleteMe(); + } + }); + if (_blueSpearTask != null) + { + _blueSpearTask.cancel(true); + _blueSpearTask = null; + } + if (_redSpearTask != null) + { + _redSpearTask.cancel(true); + _redSpearTask = null; + } + if (_leopoldTask != null) + { + _leopoldTask.cancel(true); + _leopoldTask = null; + } + if (_debuffTask != null) + { + _debuffTask.cancel(true); + _debuffTask = null; + } + } + @Override public String onKill(Npc npc, PlayerInstance killer, boolean isSummon) { switch (npc.getId()) { + case MIMILLION: + { + if (redLightning != null) + { + redLightning.deleteMe(); + bossZone.broadcastPacket(new ExShowScreenMessage(NpcStringId.MIMILLION_FALLS_AND_THE_RED_LIGHTNING_SPEAR_VANISHES, ExShowScreenMessage.TOP_CENTER, 10000, true)); + } + break; + } + case MIMILLUS: + { + if (blueLightning != null) + { + blueLightning.deleteMe(); + bossZone.broadcastPacket(new ExShowScreenMessage(NpcStringId.MIMILLUS_FALLS_AND_THE_BLUE_LIGHTNING_SPEAR_VANISHES, ExShowScreenMessage.TOP_CENTER, 10000, true)); + } + break; + } case HELIOS1: { bossInstance.deleteMe(); - bossInstance = addSpawn(HELIOS2, HELIOS_SPAWN_LOC.getX(), HELIOS_SPAWN_LOC.getY(), HELIOS_SPAWN_LOC.getZ(), HELIOS_SPAWN_LOC.getHeading(), false, 0, false); - bossZone.broadcastPacket(new ExShowScreenMessage(NpcStringId.HELIOS_APPEARANCE_CHANGES_AND_HE_BEGINS_TO_GROW_STRONGER, ExShowScreenMessage.TOP_CENTER, 10000, true)); + bossZone.getPlayersInside().forEach(player -> + { + playMovie(player, Movie.SC_HELIOS_TRANS_A); + }); + startQuestTimer("stage2", 15000, null, null); break; } case HELIOS2: { bossInstance.deleteMe(); - bossInstance = addSpawn(HELIOS3, HELIOS_SPAWN_LOC.getX(), HELIOS_SPAWN_LOC.getY(), HELIOS_SPAWN_LOC.getZ(), HELIOS_SPAWN_LOC.getHeading(), false, 0, false); + if (leopold != null) + { + leopold.deleteMe(); + } + bossZone.getPlayersInside().forEach(player -> + { + playMovie(player, Movie.SC_HELIOS_TRANS_B); + }); + startQuestTimer("stage3", 15000, null, null); break; } case HELIOS3: { + Clean(); bossZone.broadcastPacket(new ExShowScreenMessage(NpcStringId.HELIOS_DEFEATED_TAKES_FLIGHT_DEEP_IN_TO_THE_SUPERION_FORT_HIS_THRONE_IS_RENDERED_INACTIVE, ExShowScreenMessage.TOP_CENTER, 10000, true)); GrandBossManager.getInstance().setBossStatus(HELIOS3, DEAD); final long respawnTime = (Config.HELIOS_SPAWN_INTERVAL + getRandom(-Config.HELIOS_SPAWN_RANDOM, Config.HELIOS_SPAWN_RANDOM)) * 3600000; @@ -150,4 +509,4 @@ public class Helios extends AbstractNpcAI { new Helios(); } -} +} \ No newline at end of file diff --git a/L2J_Mobius_5.5_EtinasFate/dist/game/data/scripts/ai/bosses/Helios/Helios1.java b/L2J_Mobius_5.5_EtinasFate/dist/game/data/scripts/ai/bosses/Helios/Helios1.java new file mode 100644 index 0000000000..336c5de75a --- /dev/null +++ b/L2J_Mobius_5.5_EtinasFate/dist/game/data/scripts/ai/bosses/Helios/Helios1.java @@ -0,0 +1,182 @@ +/* + * This file is part of the L2J Mobius project. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ai.bosses.Helios; + +import org.l2jmobius.commons.util.CommonUtil; +import org.l2jmobius.gameserver.model.actor.Creature; +import org.l2jmobius.gameserver.model.actor.Npc; +import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; +import org.l2jmobius.gameserver.model.holders.SkillHolder; +import org.l2jmobius.gameserver.model.skills.Skill; +import org.l2jmobius.gameserver.model.skills.SkillCaster; +import org.l2jmobius.gameserver.model.variables.NpcVariables; + +import ai.AbstractNpcAI; + +/** + * @author NviX + */ +public class Helios1 extends AbstractNpcAI +{ + // Npc + private static final int HELIOS = 29303; + // Skills + private static final SkillHolder HELIOS_PLASMA = new SkillHolder(16609, 1); + private static final SkillHolder HELIOS_GRAND_PLASMA = new SkillHolder(16610, 1); + private static final SkillHolder HELIOS_THRONE_OF_AGONY = new SkillHolder(16611, 1); + + private Helios1() + { + registerMobs(HELIOS); + } + + @Override + public String onAdvEvent(String event, Npc npc, PlayerInstance player) + { + switch (event) + { + case "MANAGE_SKILLS": + { + if (npc != null) + { + manageSkills(npc); + } + break; + } + } + return super.onAdvEvent(event, npc, player); + } + + @Override + public String onAttack(Npc npc, PlayerInstance attacker, int damage, boolean isSummon, Skill skill) + { + if (npc.getId() == HELIOS) + { + if (skill == null) + { + refreshAiParams(attacker, npc, (damage * 1000)); + } + else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.25)) + { + refreshAiParams(attacker, npc, ((damage / 3) * 100)); + } + else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.5)) + { + refreshAiParams(attacker, npc, (damage * 20)); + } + else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.75)) + { + refreshAiParams(attacker, npc, (damage * 10)); + } + else + { + refreshAiParams(attacker, npc, ((damage / 3) * 20)); + } + manageSkills(npc); + } + + return super.onAttack(npc, attacker, damage, isSummon); + } + + private final void refreshAiParams(Creature attacker, Npc npc, int damage) + { + refreshAiParams(attacker, npc, damage, damage); + } + + private final void refreshAiParams(Creature attacker, Npc npc, int damage, int aggro) + { + final int newAggroVal = damage + getRandom(3000); + final int aggroVal = aggro + 1000; + final NpcVariables vars = npc.getVariables(); + for (int i = 0; i < 3; i++) + { + if (attacker == vars.getObject("c_quest" + i, Creature.class)) + { + if (vars.getInt("i_quest" + i) < aggroVal) + { + vars.set("i_quest" + i, newAggroVal); + } + return; + } + } + final int index = CommonUtil.getIndexOfMinValue(vars.getInt("i_quest0"), vars.getInt("i_quest1"), vars.getInt("i_quest2")); + vars.set("i_quest" + index, newAggroVal); + vars.set("c_quest" + index, attacker); + } + + @Override + public String onSpellFinished(Npc npc, PlayerInstance player, Skill skill) + { + startQuestTimer("MANAGE_SKILLS", 1000, npc, null); + + return super.onSpellFinished(npc, player, skill); + } + + private void manageSkills(Npc npc) + { + if (npc.isCastingNow(SkillCaster::isAnyNormalType) || npc.isCoreAIDisabled() || !npc.isInCombat()) + { + return; + } + + final NpcVariables vars = npc.getVariables(); + for (int i = 0; i < 3; i++) + { + final Creature attacker = vars.getObject("c_quest" + i, Creature.class); + if ((attacker == null) || ((npc.calculateDistance3D(attacker) > 9000) || attacker.isDead())) + { + vars.set("i_quest" + i, 0); + } + } + final int index = CommonUtil.getIndexOfMaxValue(vars.getInt("i_quest0"), vars.getInt("i_quest1"), vars.getInt("i_quest2")); + final Creature player = vars.getObject("c_quest" + index, Creature.class); + final int i2 = vars.getInt("i_quest" + index); + if ((i2 > 0) && (getRandom(100) < 70)) + { + vars.set("i_quest" + index, 500); + } + + SkillHolder skillToCast = null; + if ((player != null) && !player.isDead()) + { + if (getRandom(100) < 30) + { + skillToCast = HELIOS_GRAND_PLASMA; + } + else if (getRandom(100) < 50) + { + skillToCast = HELIOS_THRONE_OF_AGONY; + } + else + { + skillToCast = HELIOS_PLASMA; + } + } + + if ((skillToCast != null) && SkillCaster.checkUseConditions(npc, skillToCast.getSkill())) + + { + npc.setTarget(player); + npc.doCast(skillToCast.getSkill()); + } + } + + public static void main(String[] args) + { + new Helios1(); + } +} diff --git a/L2J_Mobius_5.5_EtinasFate/dist/game/data/scripts/ai/bosses/Helios/Helios2.java b/L2J_Mobius_5.5_EtinasFate/dist/game/data/scripts/ai/bosses/Helios/Helios2.java new file mode 100644 index 0000000000..cf7ad4b0e6 --- /dev/null +++ b/L2J_Mobius_5.5_EtinasFate/dist/game/data/scripts/ai/bosses/Helios/Helios2.java @@ -0,0 +1,182 @@ +/* + * This file is part of the L2J Mobius project. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ai.bosses.Helios; + +import org.l2jmobius.commons.util.CommonUtil; +import org.l2jmobius.gameserver.model.actor.Creature; +import org.l2jmobius.gameserver.model.actor.Npc; +import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; +import org.l2jmobius.gameserver.model.holders.SkillHolder; +import org.l2jmobius.gameserver.model.skills.Skill; +import org.l2jmobius.gameserver.model.skills.SkillCaster; +import org.l2jmobius.gameserver.model.variables.NpcVariables; + +import ai.AbstractNpcAI; + +/** + * @author NviX + */ +public class Helios2 extends AbstractNpcAI +{ + // Npc + private static final int HELIOS = 29304; + // Skills + private static final SkillHolder EMPEROR_HELIOS_AUTHORITY = new SkillHolder(16612, 1); + private static final SkillHolder HELIOS_PLASMA_PRESSURE = new SkillHolder(16614, 1); + private static final SkillHolder HELIOS_PLASMA_WALL = new SkillHolder(16615, 1); + + private Helios2() + { + registerMobs(HELIOS); + } + + @Override + public String onAdvEvent(String event, Npc npc, PlayerInstance player) + { + switch (event) + { + case "MANAGE_SKILLS": + { + if (npc != null) + { + manageSkills(npc); + } + break; + } + } + return super.onAdvEvent(event, npc, player); + } + + @Override + public String onAttack(Npc npc, PlayerInstance attacker, int damage, boolean isSummon, Skill skill) + { + if (npc.getId() == HELIOS) + { + if (skill == null) + { + refreshAiParams(attacker, npc, (damage * 1000)); + } + else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.25)) + { + refreshAiParams(attacker, npc, ((damage / 3) * 100)); + } + else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.5)) + { + refreshAiParams(attacker, npc, (damage * 20)); + } + else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.75)) + { + refreshAiParams(attacker, npc, (damage * 10)); + } + else + { + refreshAiParams(attacker, npc, ((damage / 3) * 20)); + } + manageSkills(npc); + } + + return super.onAttack(npc, attacker, damage, isSummon); + } + + private final void refreshAiParams(Creature attacker, Npc npc, int damage) + { + refreshAiParams(attacker, npc, damage, damage); + } + + private final void refreshAiParams(Creature attacker, Npc npc, int damage, int aggro) + { + final int newAggroVal = damage + getRandom(3000); + final int aggroVal = aggro + 1000; + final NpcVariables vars = npc.getVariables(); + for (int i = 0; i < 3; i++) + { + if (attacker == vars.getObject("c_quest" + i, Creature.class)) + { + if (vars.getInt("i_quest" + i) < aggroVal) + { + vars.set("i_quest" + i, newAggroVal); + } + return; + } + } + final int index = CommonUtil.getIndexOfMinValue(vars.getInt("i_quest0"), vars.getInt("i_quest1"), vars.getInt("i_quest2")); + vars.set("i_quest" + index, newAggroVal); + vars.set("c_quest" + index, attacker); + } + + @Override + public String onSpellFinished(Npc npc, PlayerInstance player, Skill skill) + { + startQuestTimer("MANAGE_SKILLS", 1000, npc, null); + + return super.onSpellFinished(npc, player, skill); + } + + private void manageSkills(Npc npc) + { + if (npc.isCastingNow(SkillCaster::isAnyNormalType) || npc.isCoreAIDisabled() || !npc.isInCombat()) + { + return; + } + + final NpcVariables vars = npc.getVariables(); + for (int i = 0; i < 3; i++) + { + final Creature attacker = vars.getObject("c_quest" + i, Creature.class); + if ((attacker == null) || ((npc.calculateDistance3D(attacker) > 9000) || attacker.isDead())) + { + vars.set("i_quest" + i, 0); + } + } + final int index = CommonUtil.getIndexOfMaxValue(vars.getInt("i_quest0"), vars.getInt("i_quest1"), vars.getInt("i_quest2")); + final Creature player = vars.getObject("c_quest" + index, Creature.class); + final int i2 = vars.getInt("i_quest" + index); + if ((i2 > 0) && (getRandom(100) < 70)) + { + vars.set("i_quest" + index, 500); + } + + SkillHolder skillToCast = null; + if ((player != null) && !player.isDead()) + { + if (getRandom(100) < 30) + { + skillToCast = EMPEROR_HELIOS_AUTHORITY; + } + else if (getRandom(100) < 50) + { + skillToCast = HELIOS_PLASMA_PRESSURE; + } + else + { + skillToCast = HELIOS_PLASMA_WALL; + } + } + + if ((skillToCast != null) && SkillCaster.checkUseConditions(npc, skillToCast.getSkill())) + + { + npc.setTarget(player); + npc.doCast(skillToCast.getSkill()); + } + } + + public static void main(String[] args) + { + new Helios2(); + } +} diff --git a/L2J_Mobius_5.5_EtinasFate/dist/game/data/scripts/ai/bosses/Helios/Helios3.java b/L2J_Mobius_5.5_EtinasFate/dist/game/data/scripts/ai/bosses/Helios/Helios3.java new file mode 100644 index 0000000000..efa78d5d99 --- /dev/null +++ b/L2J_Mobius_5.5_EtinasFate/dist/game/data/scripts/ai/bosses/Helios/Helios3.java @@ -0,0 +1,187 @@ +/* + * This file is part of the L2J Mobius project. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ai.bosses.Helios; + +import org.l2jmobius.commons.util.CommonUtil; +import org.l2jmobius.gameserver.model.actor.Creature; +import org.l2jmobius.gameserver.model.actor.Npc; +import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; +import org.l2jmobius.gameserver.model.holders.SkillHolder; +import org.l2jmobius.gameserver.model.skills.Skill; +import org.l2jmobius.gameserver.model.skills.SkillCaster; +import org.l2jmobius.gameserver.model.variables.NpcVariables; + +import ai.AbstractNpcAI; + +/** + * @author NviX + */ +public class Helios3 extends AbstractNpcAI +{ + // Npc + private static final int HELIOS = 29305; + // Skills + private static final SkillHolder HELIOS_OVERAWING_GAZE = new SkillHolder(16616, 1); + private static final SkillHolder HELIOS_HOLY_SPIKE = new SkillHolder(16621, 1); + private static final SkillHolder HELIOS_BIONIC_BOMB = new SkillHolder(16622, 1); + private static final SkillHolder HELIOS_LIGHTNING_OF_ANGER = new SkillHolder(16623, 1); + + private Helios3() + { + registerMobs(HELIOS); + } + + @Override + public String onAdvEvent(String event, Npc npc, PlayerInstance player) + { + switch (event) + { + case "MANAGE_SKILLS": + { + if (npc != null) + { + manageSkills(npc); + } + break; + } + } + return super.onAdvEvent(event, npc, player); + } + + @Override + public String onAttack(Npc npc, PlayerInstance attacker, int damage, boolean isSummon, Skill skill) + { + if (npc.getId() == HELIOS) + { + if (skill == null) + { + refreshAiParams(attacker, npc, (damage * 1000)); + } + else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.25)) + { + refreshAiParams(attacker, npc, ((damage / 3) * 100)); + } + else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.5)) + { + refreshAiParams(attacker, npc, (damage * 20)); + } + else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.75)) + { + refreshAiParams(attacker, npc, (damage * 10)); + } + else + { + refreshAiParams(attacker, npc, ((damage / 3) * 20)); + } + manageSkills(npc); + } + + return super.onAttack(npc, attacker, damage, isSummon); + } + + private final void refreshAiParams(Creature attacker, Npc npc, int damage) + { + refreshAiParams(attacker, npc, damage, damage); + } + + private final void refreshAiParams(Creature attacker, Npc npc, int damage, int aggro) + { + final int newAggroVal = damage + getRandom(3000); + final int aggroVal = aggro + 1000; + final NpcVariables vars = npc.getVariables(); + for (int i = 0; i < 3; i++) + { + if (attacker == vars.getObject("c_quest" + i, Creature.class)) + { + if (vars.getInt("i_quest" + i) < aggroVal) + { + vars.set("i_quest" + i, newAggroVal); + } + return; + } + } + final int index = CommonUtil.getIndexOfMinValue(vars.getInt("i_quest0"), vars.getInt("i_quest1"), vars.getInt("i_quest2")); + vars.set("i_quest" + index, newAggroVal); + vars.set("c_quest" + index, attacker); + } + + @Override + public String onSpellFinished(Npc npc, PlayerInstance player, Skill skill) + { + startQuestTimer("MANAGE_SKILLS", 1000, npc, null); + + return super.onSpellFinished(npc, player, skill); + } + + private void manageSkills(Npc npc) + { + if (npc.isCastingNow(SkillCaster::isAnyNormalType) || npc.isCoreAIDisabled() || !npc.isInCombat()) + { + return; + } + + final NpcVariables vars = npc.getVariables(); + for (int i = 0; i < 3; i++) + { + final Creature attacker = vars.getObject("c_quest" + i, Creature.class); + if ((attacker == null) || ((npc.calculateDistance3D(attacker) > 9000) || attacker.isDead())) + { + vars.set("i_quest" + i, 0); + } + } + final int index = CommonUtil.getIndexOfMaxValue(vars.getInt("i_quest0"), vars.getInt("i_quest1"), vars.getInt("i_quest2")); + final Creature player = vars.getObject("c_quest" + index, Creature.class); + final int i2 = vars.getInt("i_quest" + index); + if ((i2 > 0) && (getRandom(100) < 70)) + { + vars.set("i_quest" + index, 500); + } + + SkillHolder skillToCast = null; + if ((player != null) && !player.isDead()) + { + if (getRandom(100) < 10) + { + skillToCast = HELIOS_LIGHTNING_OF_ANGER; + } + else if (getRandom(100) < 30) + { + skillToCast = HELIOS_OVERAWING_GAZE; + } + else if (getRandom(100) < 50) + { + skillToCast = HELIOS_BIONIC_BOMB; + } + else + { + skillToCast = HELIOS_HOLY_SPIKE; + } + } + + if ((skillToCast != null) && SkillCaster.checkUseConditions(npc, skillToCast.getSkill())) + + { + npc.setTarget(player); + npc.doCast(skillToCast.getSkill()); + } + } + + public static void main(String[] args) + { + new Helios3(); + } +} diff --git a/L2J_Mobius_5.5_EtinasFate/dist/game/data/scripts/ai/bosses/Helios/RoyalArchmageMinion.java b/L2J_Mobius_5.5_EtinasFate/dist/game/data/scripts/ai/bosses/Helios/RoyalArchmageMinion.java new file mode 100644 index 0000000000..1529d6f1fb --- /dev/null +++ b/L2J_Mobius_5.5_EtinasFate/dist/game/data/scripts/ai/bosses/Helios/RoyalArchmageMinion.java @@ -0,0 +1,177 @@ +/* + * This file is part of the L2J Mobius project. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ai.bosses.Helios; + +import org.l2jmobius.commons.util.CommonUtil; +import org.l2jmobius.gameserver.model.actor.Creature; +import org.l2jmobius.gameserver.model.actor.Npc; +import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; +import org.l2jmobius.gameserver.model.holders.SkillHolder; +import org.l2jmobius.gameserver.model.skills.Skill; +import org.l2jmobius.gameserver.model.skills.SkillCaster; +import org.l2jmobius.gameserver.model.variables.NpcVariables; + +import ai.AbstractNpcAI; + +/** + * @author NviX + */ +public class RoyalArchmageMinion extends AbstractNpcAI +{ + // Npc + private static final int ROYAL_ARCHMAGE = 29313; + // Skills + private static final SkillHolder ULTRA_PLASMA_BALL = new SkillHolder(16685, 1); + private static final SkillHolder ULTRA_PLASMA_WAVE = new SkillHolder(16686, 1); + + private RoyalArchmageMinion() + { + registerMobs(ROYAL_ARCHMAGE); + } + + @Override + public String onAdvEvent(String event, Npc npc, PlayerInstance player) + { + switch (event) + { + case "MANAGE_SKILLS": + { + if (npc != null) + { + manageSkills(npc); + } + break; + } + } + return super.onAdvEvent(event, npc, player); + } + + @Override + public String onAttack(Npc npc, PlayerInstance attacker, int damage, boolean isSummon, Skill skill) + { + if (npc.getId() == ROYAL_ARCHMAGE) + { + if (skill == null) + { + refreshAiParams(attacker, npc, (damage * 1000)); + } + else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.25)) + { + refreshAiParams(attacker, npc, ((damage / 3) * 100)); + } + else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.5)) + { + refreshAiParams(attacker, npc, (damage * 20)); + } + else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.75)) + { + refreshAiParams(attacker, npc, (damage * 10)); + } + else + { + refreshAiParams(attacker, npc, ((damage / 3) * 20)); + } + manageSkills(npc); + } + + return super.onAttack(npc, attacker, damage, isSummon); + } + + private final void refreshAiParams(Creature attacker, Npc npc, int damage) + { + refreshAiParams(attacker, npc, damage, damage); + } + + private final void refreshAiParams(Creature attacker, Npc npc, int damage, int aggro) + { + final int newAggroVal = damage + getRandom(3000); + final int aggroVal = aggro + 1000; + final NpcVariables vars = npc.getVariables(); + for (int i = 0; i < 3; i++) + { + if (attacker == vars.getObject("c_quest" + i, Creature.class)) + { + if (vars.getInt("i_quest" + i) < aggroVal) + { + vars.set("i_quest" + i, newAggroVal); + } + return; + } + } + final int index = CommonUtil.getIndexOfMinValue(vars.getInt("i_quest0"), vars.getInt("i_quest1"), vars.getInt("i_quest2")); + vars.set("i_quest" + index, newAggroVal); + vars.set("c_quest" + index, attacker); + } + + @Override + public String onSpellFinished(Npc npc, PlayerInstance player, Skill skill) + { + startQuestTimer("MANAGE_SKILLS", 1000, npc, null); + + return super.onSpellFinished(npc, player, skill); + } + + private void manageSkills(Npc npc) + { + if (npc.isCastingNow(SkillCaster::isAnyNormalType) || npc.isCoreAIDisabled() || !npc.isInCombat()) + { + return; + } + + final NpcVariables vars = npc.getVariables(); + for (int i = 0; i < 3; i++) + { + final Creature attacker = vars.getObject("c_quest" + i, Creature.class); + if ((attacker == null) || ((npc.calculateDistance3D(attacker) > 9000) || attacker.isDead())) + { + vars.set("i_quest" + i, 0); + } + } + final int index = CommonUtil.getIndexOfMaxValue(vars.getInt("i_quest0"), vars.getInt("i_quest1"), vars.getInt("i_quest2")); + final Creature player = vars.getObject("c_quest" + index, Creature.class); + final int i2 = vars.getInt("i_quest" + index); + if ((i2 > 0) && (getRandom(100) < 70)) + { + vars.set("i_quest" + index, 500); + } + + SkillHolder skillToCast = null; + if ((player != null) && !player.isDead()) + { + if (getRandom(100) < 50) + { + skillToCast = ULTRA_PLASMA_WAVE; + } + else + { + skillToCast = ULTRA_PLASMA_BALL; + } + } + + if ((skillToCast != null) && SkillCaster.checkUseConditions(npc, skillToCast.getSkill())) + + { + npc.setTarget(player); + npc.doCast(skillToCast.getSkill()); + } + } + + public static void main(String[] args) + { + new RoyalArchmageMinion(); + } +} diff --git a/L2J_Mobius_6.0_Fafurion/dist/game/data/scripts/ai/bosses/Helios/Helios.java b/L2J_Mobius_6.0_Fafurion/dist/game/data/scripts/ai/bosses/Helios/Helios.java index 0f70177f83..9b7f63de07 100644 --- a/L2J_Mobius_6.0_Fafurion/dist/game/data/scripts/ai/bosses/Helios/Helios.java +++ b/L2J_Mobius_6.0_Fafurion/dist/game/data/scripts/ai/bosses/Helios/Helios.java @@ -16,30 +16,59 @@ */ package ai.bosses.Helios; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ScheduledFuture; + import org.l2jmobius.Config; +import org.l2jmobius.commons.concurrent.ThreadPool; +import org.l2jmobius.gameserver.enums.Movie; import org.l2jmobius.gameserver.instancemanager.GrandBossManager; import org.l2jmobius.gameserver.instancemanager.ZoneManager; import org.l2jmobius.gameserver.model.Location; import org.l2jmobius.gameserver.model.StatSet; import org.l2jmobius.gameserver.model.actor.Npc; +import org.l2jmobius.gameserver.model.actor.instance.GrandBossInstance; import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; +import org.l2jmobius.gameserver.model.holders.SkillHolder; +import org.l2jmobius.gameserver.model.holders.SpawnHolder; import org.l2jmobius.gameserver.model.zone.type.NoSummonFriendZone; import org.l2jmobius.gameserver.network.NpcStringId; import org.l2jmobius.gameserver.network.serverpackets.ExShowScreenMessage; +import org.l2jmobius.gameserver.util.Broadcast; import ai.AbstractNpcAI; /** - * @author Mobius + * @author Mobius, NviX */ public class Helios extends AbstractNpcAI { - // NPCs + // Raid private static final int HELIOS1 = 29303; private static final int HELIOS2 = 29304; private static final int HELIOS3 = 29305; + // Minions + private static final int LEOPOLD = 29306; + private static final int HELIOS_RED_LIGHTNING = 29307; + private static final int HELIOS_BLUE_LIGHTNING = 29308; + private static final int LEOPOLD_ORIGIN = 29309; + private static final int ENUMA_ELISH_ORIGIN = 29310; + private static final int ROYAL_TEMPLAR_COLONEL = 29311; + private static final int ROYAL_SHARPSHOOTER = 29312; + private static final int ROYAL_ARCHMAGE = 29313; + private static final int ROYAL_GATEKEEPER = 29314; + private static final int MIMILLION = 29315; + private static final int MIMILLUS = 29316; // Location private static final Location HELIOS_SPAWN_LOC = new Location(92771, 161909, 3494, 38329); + private static final Location BLUE_LIGHTNING_SPEAR_LOC = new Location(93208, 161269, 3489); + private static final Location RED_LIGHTNING_SPEAR_LOC = new Location(92348, 162558, 3489); + private static final Location MIMILLION_LOC = new Location(92465, 162465, 3487); + private static final Location MIMILLUS_LOC = new Location(93174, 161394, 3487); + private static final Location LEOPOLD_LOC = new Location(93531, 162415, 3487); + private static final Location LEOPOLD_ORIGIN_LOC = new Location(92601, 162196, 3464); + private static final Location ENUMA_ELISH_ORIGIN_LOC = new Location(92957, 161640, 3485); // Zone private static final int ZONE_ID = 210109; // Status @@ -47,14 +76,73 @@ public class Helios extends AbstractNpcAI private static final int WAITING = 1; private static final int FIGHTING = 2; private static final int DEAD = 3; + // Skills + private static final SkillHolder AUDIENCE_DEBUFF = new SkillHolder(16613, 1); + private static final SkillHolder RED_LIGHTNING_SPEAR = new SkillHolder(16617, 1); + private static final SkillHolder BLUE_LIGHTNING_SPEAR = new SkillHolder(16618, 1); + private static final SkillHolder PRANARACH = new SkillHolder(16624, 1); + private static final SkillHolder HELIOS_RAGE1 = new SkillHolder(16625, 1); + private static final SkillHolder HELIOS_RAGE2 = new SkillHolder(16625, 2); + private static final SkillHolder HELIOS_RAGE3 = new SkillHolder(16625, 3); + private static final SkillHolder HELIOS_RAGE4 = new SkillHolder(16625, 4); + private static final SkillHolder LEOPOLD_BOMB = new SkillHolder(16629, 1); + private static final SkillHolder LEOPOLD_PLASMA_BOMB = new SkillHolder(16630, 1); + private static final SkillHolder LEOPOLD_ENERGY_BOMB = new SkillHolder(16631, 1); + private static final SkillHolder LEOPOLD_MINI_GUN = new SkillHolder(16632, 1); + private static final SkillHolder LEOPOLD_SPRAY_SHOT = new SkillHolder(16633, 1); + private static final SkillHolder LEOPOLD_HARPOON = new SkillHolder(16634, 1); + // Spawns + private static final List SPAWNS_MINIONS = new ArrayList<>(); + static + { + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_TEMPLAR_COLONEL, HELIOS_SPAWN_LOC, 0, false)); + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_TEMPLAR_COLONEL, HELIOS_SPAWN_LOC, 0, false)); + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_TEMPLAR_COLONEL, HELIOS_SPAWN_LOC, 0, false)); + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_TEMPLAR_COLONEL, HELIOS_SPAWN_LOC, 0, false)); + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_TEMPLAR_COLONEL, HELIOS_SPAWN_LOC, 0, false)); + + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_SHARPSHOOTER, HELIOS_SPAWN_LOC, 0, false)); + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_SHARPSHOOTER, HELIOS_SPAWN_LOC, 0, false)); + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_SHARPSHOOTER, HELIOS_SPAWN_LOC, 0, false)); + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_SHARPSHOOTER, HELIOS_SPAWN_LOC, 0, false)); + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_SHARPSHOOTER, HELIOS_SPAWN_LOC, 0, false)); + + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_ARCHMAGE, HELIOS_SPAWN_LOC, 0, false)); + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_ARCHMAGE, HELIOS_SPAWN_LOC, 0, false)); + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_ARCHMAGE, HELIOS_SPAWN_LOC, 0, false)); + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_ARCHMAGE, HELIOS_SPAWN_LOC, 0, false)); + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_ARCHMAGE, HELIOS_SPAWN_LOC, 0, false)); + + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_GATEKEEPER, HELIOS_SPAWN_LOC, 0, false)); + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_GATEKEEPER, HELIOS_SPAWN_LOC, 0, false)); + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_GATEKEEPER, HELIOS_SPAWN_LOC, 0, false)); + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_GATEKEEPER, HELIOS_SPAWN_LOC, 0, false)); + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_GATEKEEPER, HELIOS_SPAWN_LOC, 0, false)); + } // Misc private static final int HELIOS_RAID_DURATION = 5; // hours private static Npc bossInstance; private final NoSummonFriendZone bossZone; + private GrandBossInstance _tempHelios; + private static List _minionSpawns = new ArrayList<>(); + private static Npc blueLightning; + private static Npc redLightning; + private static Npc leopold; + private boolean activated = false; + private boolean stage1_50 = false; + private boolean stage2_50 = false; + private boolean helios80 = false; + private boolean helios50 = false; + private boolean _announce = false; + protected ScheduledFuture _blueSpearTask; + protected ScheduledFuture _redSpearTask; + protected ScheduledFuture _leopoldTask; + protected ScheduledFuture _debuffTask; private Helios() { - addKillId(HELIOS1, HELIOS2, HELIOS3); + addAttackId(HELIOS1, HELIOS2, HELIOS3); + addKillId(HELIOS1, HELIOS2, HELIOS3, MIMILLION, MIMILLUS); // Zone bossZone = ZoneManager.getInstance().getZoneById(ZONE_ID, NoSummonFriendZone.class); // Unlock @@ -69,23 +157,184 @@ public class Helios extends AbstractNpcAI } else { + _tempHelios = (GrandBossInstance) addSpawn(HELIOS3, -113360, -244676, -15536, 0, false, 0); + GrandBossManager.getInstance().addBoss(_tempHelios); GrandBossManager.getInstance().setBossStatus(HELIOS3, ALIVE); } } - else if (status != ALIVE) + else { + _tempHelios = (GrandBossInstance) addSpawn(HELIOS3, -113360, -244676, -15536, 0, false, 0); + GrandBossManager.getInstance().addBoss(_tempHelios); GrandBossManager.getInstance().setBossStatus(HELIOS3, ALIVE); } } + @Override + public String onAttack(Npc npc, PlayerInstance attacker, int damage, boolean isSummon) + { + if ((npc.getId() == HELIOS1) && !_announce) + { + _announce = true; + _debuffTask = ThreadPool.scheduleAtFixedRate(() -> + { + bossZone.getPlayersInside().forEach(player -> + { + AUDIENCE_DEBUFF.getSkill().applyEffects(player, player); + }); + }, 5000, 20000); + Broadcast.toAllOnlinePlayers(new ExShowScreenMessage(NpcStringId.THE_ADEN_WARRIORS_BEGIN_BATTLE_WITH_THE_GIANT_EMPEROR_HELIOS, ExShowScreenMessage.TOP_CENTER, 10000, true)); + } + if ((npc.getId() == HELIOS1) && !stage1_50 && (npc.getCurrentHp() <= (npc.getMaxHp() * 0.5))) + { + stage1_50 = true; + HELIOS_RAGE1.getSkill().applyEffects(bossInstance, bossInstance); + } + if ((npc.getId() == HELIOS2) && !activated) + { + activated = true; + HELIOS_RAGE1.getSkill().applyEffects(bossInstance, bossInstance); + _blueSpearTask = ThreadPool.scheduleAtFixedRate(() -> + { + int count = bossZone.getPlayersInside().size(); + if (count > 0) + { + PlayerInstance randomPlayer = bossZone.getPlayersInside().get(getRandom(count)); + if (blueLightning != null) + { + blueLightning.setTarget(randomPlayer); + blueLightning.doCast(BLUE_LIGHTNING_SPEAR.getSkill()); + } + } + bossZone.broadcastPacket(new ExShowScreenMessage(NpcStringId.HELIOS_PICKS_UP_THE_BLUE_LIGHTNING_SPEAR_AND_BEGINS_GATHERING_HIS_POWER, ExShowScreenMessage.TOP_CENTER, 10000, true)); + }, 10000, 120000); + _redSpearTask = ThreadPool.scheduleAtFixedRate(() -> + { + int count = bossZone.getPlayersInside().size(); + if (count > 0) + { + PlayerInstance randomPlayer = bossZone.getPlayersInside().get(getRandom(count)); + if (redLightning != null) + { + redLightning.setTarget(randomPlayer); + redLightning.doCast(RED_LIGHTNING_SPEAR.getSkill()); + } + } + bossZone.broadcastPacket(new ExShowScreenMessage(NpcStringId.HELIOS_PICKS_UP_THE_RED_LIGHTNING_SPEAR_AND_BEGINS_GATHERING_HIS_POWER, ExShowScreenMessage.TOP_CENTER, 10000, true)); + }, 30000, 120000); + _leopoldTask = ThreadPool.scheduleAtFixedRate(() -> + { + int count = bossZone.getPlayersInside().size(); + if (count > 0) + { + PlayerInstance randomPlayer = bossZone.getPlayersInside().get(getRandom(count)); + if (leopold != null) + { + leopold.setTarget(randomPlayer); + int rnd = getRandom(100); + if (rnd < 16) + { + leopold.doCast(LEOPOLD_BOMB.getSkill()); + } + else if (rnd < 32) + { + leopold.doCast(LEOPOLD_PLASMA_BOMB.getSkill()); + } + else if (rnd < 48) + { + leopold.doCast(LEOPOLD_ENERGY_BOMB.getSkill()); + } + else if (rnd < 64) + { + leopold.doCast(LEOPOLD_MINI_GUN.getSkill()); + } + else if (rnd < 80) + { + leopold.doCast(LEOPOLD_SPRAY_SHOT.getSkill()); + } + else + { + leopold.doCast(LEOPOLD_HARPOON.getSkill()); + } + } + } + }, 5000, 10000); + } + if ((npc.getId() == HELIOS2) && !stage2_50 && (npc.getCurrentHp() <= (npc.getMaxHp() * 0.5))) + { + stage2_50 = true; + HELIOS_RAGE2.getSkill().applyEffects(bossInstance, bossInstance); + } + if ((npc.getId() == HELIOS3) && !activated) + { + activated = true; + HELIOS_RAGE3.getSkill().applyEffects(bossInstance, bossInstance); + _leopoldTask = ThreadPool.scheduleAtFixedRate(() -> + { + int count = bossZone.getPlayersInside().size(); + if (count > 0) + { + PlayerInstance randomPlayer = bossZone.getPlayersInside().get(getRandom(count)); + if (leopold != null) + { + leopold.setTarget(randomPlayer); + int rnd = getRandom(100); + if (rnd < 16) + { + leopold.doCast(LEOPOLD_BOMB.getSkill()); + } + else if (rnd < 32) + { + leopold.doCast(LEOPOLD_PLASMA_BOMB.getSkill()); + } + else if (rnd < 48) + { + leopold.doCast(LEOPOLD_ENERGY_BOMB.getSkill()); + } + else if (rnd < 64) + { + leopold.doCast(LEOPOLD_MINI_GUN.getSkill()); + } + else if (rnd < 80) + { + leopold.doCast(LEOPOLD_SPRAY_SHOT.getSkill()); + } + else + { + leopold.doCast(LEOPOLD_HARPOON.getSkill()); + } + } + } + }, 5000, 10000); + } + if ((npc.getId() == HELIOS3) && !helios80 && (npc.getCurrentHp() <= (npc.getMaxHp() * 0.8))) + { + helios80 = true; + addSpawn(LEOPOLD_ORIGIN, LEOPOLD_ORIGIN_LOC, false, 0); + addSpawn(ENUMA_ELISH_ORIGIN, ENUMA_ELISH_ORIGIN_LOC, false, 0); + bossZone.broadcastPacket(new ExShowScreenMessage(NpcStringId.THE_KAMAEL_ORIGINS_ABOVE_THE_THRONE_OF_HELIOS_BEGIN_TO_SOAR, ExShowScreenMessage.TOP_CENTER, 10000, true)); + } + else if ((npc.getId() == HELIOS3) && !helios50 && (npc.getCurrentHp() <= (npc.getMaxHp() * 0.5))) + { + helios50 = true; + HELIOS_RAGE4.getSkill().applyEffects(bossInstance, bossInstance); + bossZone.broadcastPacket(new ExShowScreenMessage(NpcStringId.HELIOS_USES_THE_PRANARACH_SHIELD_OF_LIGHT_TO_MINIMIZE_DAMAGE, ExShowScreenMessage.TOP_CENTER, 10000, true)); + bossInstance.abortCast(); + bossInstance.doCast(PRANARACH.getSkill()); + } + return super.onAttack(npc, attacker, damage, isSummon); + } + @Override public String onAdvEvent(String event, Npc npc, PlayerInstance player) { - final String htmltext = null; + String htmltext = null; switch (event) { case "unlock_helios": { + _tempHelios = (GrandBossInstance) addSpawn(HELIOS3, -113360, -244676, -15536, 0, false, 0); + GrandBossManager.getInstance().addBoss(_tempHelios); GrandBossManager.getInstance().setBossStatus(HELIOS3, ALIVE); break; } @@ -95,6 +344,10 @@ public class Helios extends AbstractNpcAI { GrandBossManager.getInstance().setBossStatus(HELIOS3, FIGHTING); bossInstance = addSpawn(HELIOS1, HELIOS_SPAWN_LOC.getX(), HELIOS_SPAWN_LOC.getY(), HELIOS_SPAWN_LOC.getZ(), HELIOS_SPAWN_LOC.getHeading(), false, 0, false); + for (SpawnHolder spawn : SPAWNS_MINIONS) + { + _minionSpawns.add(addSpawn(spawn.getNpcId(), spawn.getLocation())); + } startQuestTimer("resetRaid", HELIOS_RAID_DURATION * 60 * 60 * 1000, bossInstance, null); } break; @@ -104,35 +357,141 @@ public class Helios extends AbstractNpcAI final int status = GrandBossManager.getInstance().getBossStatus(HELIOS3); if ((status > ALIVE) && (status < DEAD)) { + bossZone.oustAllPlayers(); + Broadcast.toAllOnlinePlayers(new ExShowScreenMessage(NpcStringId.THE_HEROES_DRAINED_OF_THEIR_POWERS_HAVE_BEEN_BANISHED_FROM_THE_THRONE_OF_HELIOS_BY_HELIOS_POWERS, ExShowScreenMessage.TOP_CENTER, 10000, true)); GrandBossManager.getInstance().setBossStatus(HELIOS3, ALIVE); - npc.deleteMe(); + Clean(); } break; } + case "stage2": + { + bossInstance = addSpawn(HELIOS2, HELIOS_SPAWN_LOC.getX(), HELIOS_SPAWN_LOC.getY(), HELIOS_SPAWN_LOC.getZ(), HELIOS_SPAWN_LOC.getHeading(), false, 0, false); + bossZone.broadcastPacket(new ExShowScreenMessage(NpcStringId.HELIOS_APPEARANCE_CHANGES_AND_HE_BEGINS_TO_GROW_STRONGER, ExShowScreenMessage.TOP_CENTER, 10000, true)); + for (SpawnHolder spawn : SPAWNS_MINIONS) + { + _minionSpawns.add(addSpawn(spawn.getNpcId(), spawn.getLocation())); + } + startQuestTimer("spheresSpawn", 10000, null, null); + break; + } + case "stage3": + { + activated = false; + bossInstance = addSpawn(HELIOS3, HELIOS_SPAWN_LOC.getX(), HELIOS_SPAWN_LOC.getY(), HELIOS_SPAWN_LOC.getZ(), HELIOS_SPAWN_LOC.getHeading(), false, 0, false); + bossZone.broadcastPacket(new ExShowScreenMessage(NpcStringId.HELIOS_APPEARANCE_CHANGES_AND_HE_BEGINS_TO_GROW_STRONGER, ExShowScreenMessage.TOP_CENTER, 10000, true)); + startQuestTimer("leopoldSpawn", 10000, null, null); + break; + } + case "spheresSpawn": + { + blueLightning = addSpawn(HELIOS_BLUE_LIGHTNING, BLUE_LIGHTNING_SPEAR_LOC, false, 0); + redLightning = addSpawn(HELIOS_RED_LIGHTNING, RED_LIGHTNING_SPEAR_LOC, false, 0); + blueLightning.setInvul(true); + redLightning.setInvul(true); + bossZone.broadcastPacket(new ExShowScreenMessage(NpcStringId.THE_ENUMA_ELISH_SPEAR_ON_THE_THRONE_OF_HELIOS_IS_PREPARED_AND_PLACED_IN_POSITION, ExShowScreenMessage.TOP_CENTER, 10000, true)); + startQuestTimer("protectorsSpawn", 10000, null, null); + break; + } + case "protectorsSpawn": + { + bossZone.broadcastPacket(new ExShowScreenMessage(NpcStringId.MIMILLION_AND_MIMILLUS_APPEAR_IN_ORDER_TO_PROTECT_THE_ENUMA_ELISH_OF_RED_LIGHTNING_AND_THE_ENUMA_ELISH_OF_BLUE_LIGHTNING, ExShowScreenMessage.TOP_CENTER, 10000, true)); + addSpawn(MIMILLION, MIMILLION_LOC, false, 0); + addSpawn(MIMILLUS, MIMILLUS_LOC, false, 0); + startQuestTimer("leopoldSpawn", 10000, null, null); + break; + } + case "leopoldSpawn": + { + leopold = addSpawn(LEOPOLD, LEOPOLD_LOC, false, 0); + bossZone.broadcastPacket(new ExShowScreenMessage(NpcStringId.THE_SIEGE_CANNON_LEOPOLD_ON_THE_THRONE_OF_HELIOS_BEGINS_TO_PREPARE_TO_FIRE, ExShowScreenMessage.TOP_CENTER, 10000, true)); + break; + } } return htmltext; } + private void Clean() + { + bossZone.getCharactersInside().forEach(mob -> + { + if (mob.isNpc()) + { + mob.deleteMe(); + } + }); + if (_blueSpearTask != null) + { + _blueSpearTask.cancel(true); + _blueSpearTask = null; + } + if (_redSpearTask != null) + { + _redSpearTask.cancel(true); + _redSpearTask = null; + } + if (_leopoldTask != null) + { + _leopoldTask.cancel(true); + _leopoldTask = null; + } + if (_debuffTask != null) + { + _debuffTask.cancel(true); + _debuffTask = null; + } + } + @Override public String onKill(Npc npc, PlayerInstance killer, boolean isSummon) { switch (npc.getId()) { + case MIMILLION: + { + if (redLightning != null) + { + redLightning.deleteMe(); + bossZone.broadcastPacket(new ExShowScreenMessage(NpcStringId.MIMILLION_FALLS_AND_THE_RED_LIGHTNING_SPEAR_VANISHES, ExShowScreenMessage.TOP_CENTER, 10000, true)); + } + break; + } + case MIMILLUS: + { + if (blueLightning != null) + { + blueLightning.deleteMe(); + bossZone.broadcastPacket(new ExShowScreenMessage(NpcStringId.MIMILLUS_FALLS_AND_THE_BLUE_LIGHTNING_SPEAR_VANISHES, ExShowScreenMessage.TOP_CENTER, 10000, true)); + } + break; + } case HELIOS1: { bossInstance.deleteMe(); - bossInstance = addSpawn(HELIOS2, HELIOS_SPAWN_LOC.getX(), HELIOS_SPAWN_LOC.getY(), HELIOS_SPAWN_LOC.getZ(), HELIOS_SPAWN_LOC.getHeading(), false, 0, false); - bossZone.broadcastPacket(new ExShowScreenMessage(NpcStringId.HELIOS_APPEARANCE_CHANGES_AND_HE_BEGINS_TO_GROW_STRONGER, ExShowScreenMessage.TOP_CENTER, 10000, true)); + bossZone.getPlayersInside().forEach(player -> + { + playMovie(player, Movie.SC_HELIOS_TRANS_A); + }); + startQuestTimer("stage2", 15000, null, null); break; } case HELIOS2: { bossInstance.deleteMe(); - bossInstance = addSpawn(HELIOS3, HELIOS_SPAWN_LOC.getX(), HELIOS_SPAWN_LOC.getY(), HELIOS_SPAWN_LOC.getZ(), HELIOS_SPAWN_LOC.getHeading(), false, 0, false); + if (leopold != null) + { + leopold.deleteMe(); + } + bossZone.getPlayersInside().forEach(player -> + { + playMovie(player, Movie.SC_HELIOS_TRANS_B); + }); + startQuestTimer("stage3", 15000, null, null); break; } case HELIOS3: { + Clean(); bossZone.broadcastPacket(new ExShowScreenMessage(NpcStringId.HELIOS_DEFEATED_TAKES_FLIGHT_DEEP_IN_TO_THE_SUPERION_FORT_HIS_THRONE_IS_RENDERED_INACTIVE, ExShowScreenMessage.TOP_CENTER, 10000, true)); GrandBossManager.getInstance().setBossStatus(HELIOS3, DEAD); final long respawnTime = (Config.HELIOS_SPAWN_INTERVAL + getRandom(-Config.HELIOS_SPAWN_RANDOM, Config.HELIOS_SPAWN_RANDOM)) * 3600000; @@ -150,4 +509,4 @@ public class Helios extends AbstractNpcAI { new Helios(); } -} +} \ No newline at end of file diff --git a/L2J_Mobius_6.0_Fafurion/dist/game/data/scripts/ai/bosses/Helios/Helios1.java b/L2J_Mobius_6.0_Fafurion/dist/game/data/scripts/ai/bosses/Helios/Helios1.java new file mode 100644 index 0000000000..336c5de75a --- /dev/null +++ b/L2J_Mobius_6.0_Fafurion/dist/game/data/scripts/ai/bosses/Helios/Helios1.java @@ -0,0 +1,182 @@ +/* + * This file is part of the L2J Mobius project. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ai.bosses.Helios; + +import org.l2jmobius.commons.util.CommonUtil; +import org.l2jmobius.gameserver.model.actor.Creature; +import org.l2jmobius.gameserver.model.actor.Npc; +import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; +import org.l2jmobius.gameserver.model.holders.SkillHolder; +import org.l2jmobius.gameserver.model.skills.Skill; +import org.l2jmobius.gameserver.model.skills.SkillCaster; +import org.l2jmobius.gameserver.model.variables.NpcVariables; + +import ai.AbstractNpcAI; + +/** + * @author NviX + */ +public class Helios1 extends AbstractNpcAI +{ + // Npc + private static final int HELIOS = 29303; + // Skills + private static final SkillHolder HELIOS_PLASMA = new SkillHolder(16609, 1); + private static final SkillHolder HELIOS_GRAND_PLASMA = new SkillHolder(16610, 1); + private static final SkillHolder HELIOS_THRONE_OF_AGONY = new SkillHolder(16611, 1); + + private Helios1() + { + registerMobs(HELIOS); + } + + @Override + public String onAdvEvent(String event, Npc npc, PlayerInstance player) + { + switch (event) + { + case "MANAGE_SKILLS": + { + if (npc != null) + { + manageSkills(npc); + } + break; + } + } + return super.onAdvEvent(event, npc, player); + } + + @Override + public String onAttack(Npc npc, PlayerInstance attacker, int damage, boolean isSummon, Skill skill) + { + if (npc.getId() == HELIOS) + { + if (skill == null) + { + refreshAiParams(attacker, npc, (damage * 1000)); + } + else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.25)) + { + refreshAiParams(attacker, npc, ((damage / 3) * 100)); + } + else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.5)) + { + refreshAiParams(attacker, npc, (damage * 20)); + } + else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.75)) + { + refreshAiParams(attacker, npc, (damage * 10)); + } + else + { + refreshAiParams(attacker, npc, ((damage / 3) * 20)); + } + manageSkills(npc); + } + + return super.onAttack(npc, attacker, damage, isSummon); + } + + private final void refreshAiParams(Creature attacker, Npc npc, int damage) + { + refreshAiParams(attacker, npc, damage, damage); + } + + private final void refreshAiParams(Creature attacker, Npc npc, int damage, int aggro) + { + final int newAggroVal = damage + getRandom(3000); + final int aggroVal = aggro + 1000; + final NpcVariables vars = npc.getVariables(); + for (int i = 0; i < 3; i++) + { + if (attacker == vars.getObject("c_quest" + i, Creature.class)) + { + if (vars.getInt("i_quest" + i) < aggroVal) + { + vars.set("i_quest" + i, newAggroVal); + } + return; + } + } + final int index = CommonUtil.getIndexOfMinValue(vars.getInt("i_quest0"), vars.getInt("i_quest1"), vars.getInt("i_quest2")); + vars.set("i_quest" + index, newAggroVal); + vars.set("c_quest" + index, attacker); + } + + @Override + public String onSpellFinished(Npc npc, PlayerInstance player, Skill skill) + { + startQuestTimer("MANAGE_SKILLS", 1000, npc, null); + + return super.onSpellFinished(npc, player, skill); + } + + private void manageSkills(Npc npc) + { + if (npc.isCastingNow(SkillCaster::isAnyNormalType) || npc.isCoreAIDisabled() || !npc.isInCombat()) + { + return; + } + + final NpcVariables vars = npc.getVariables(); + for (int i = 0; i < 3; i++) + { + final Creature attacker = vars.getObject("c_quest" + i, Creature.class); + if ((attacker == null) || ((npc.calculateDistance3D(attacker) > 9000) || attacker.isDead())) + { + vars.set("i_quest" + i, 0); + } + } + final int index = CommonUtil.getIndexOfMaxValue(vars.getInt("i_quest0"), vars.getInt("i_quest1"), vars.getInt("i_quest2")); + final Creature player = vars.getObject("c_quest" + index, Creature.class); + final int i2 = vars.getInt("i_quest" + index); + if ((i2 > 0) && (getRandom(100) < 70)) + { + vars.set("i_quest" + index, 500); + } + + SkillHolder skillToCast = null; + if ((player != null) && !player.isDead()) + { + if (getRandom(100) < 30) + { + skillToCast = HELIOS_GRAND_PLASMA; + } + else if (getRandom(100) < 50) + { + skillToCast = HELIOS_THRONE_OF_AGONY; + } + else + { + skillToCast = HELIOS_PLASMA; + } + } + + if ((skillToCast != null) && SkillCaster.checkUseConditions(npc, skillToCast.getSkill())) + + { + npc.setTarget(player); + npc.doCast(skillToCast.getSkill()); + } + } + + public static void main(String[] args) + { + new Helios1(); + } +} diff --git a/L2J_Mobius_6.0_Fafurion/dist/game/data/scripts/ai/bosses/Helios/Helios2.java b/L2J_Mobius_6.0_Fafurion/dist/game/data/scripts/ai/bosses/Helios/Helios2.java new file mode 100644 index 0000000000..cf7ad4b0e6 --- /dev/null +++ b/L2J_Mobius_6.0_Fafurion/dist/game/data/scripts/ai/bosses/Helios/Helios2.java @@ -0,0 +1,182 @@ +/* + * This file is part of the L2J Mobius project. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ai.bosses.Helios; + +import org.l2jmobius.commons.util.CommonUtil; +import org.l2jmobius.gameserver.model.actor.Creature; +import org.l2jmobius.gameserver.model.actor.Npc; +import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; +import org.l2jmobius.gameserver.model.holders.SkillHolder; +import org.l2jmobius.gameserver.model.skills.Skill; +import org.l2jmobius.gameserver.model.skills.SkillCaster; +import org.l2jmobius.gameserver.model.variables.NpcVariables; + +import ai.AbstractNpcAI; + +/** + * @author NviX + */ +public class Helios2 extends AbstractNpcAI +{ + // Npc + private static final int HELIOS = 29304; + // Skills + private static final SkillHolder EMPEROR_HELIOS_AUTHORITY = new SkillHolder(16612, 1); + private static final SkillHolder HELIOS_PLASMA_PRESSURE = new SkillHolder(16614, 1); + private static final SkillHolder HELIOS_PLASMA_WALL = new SkillHolder(16615, 1); + + private Helios2() + { + registerMobs(HELIOS); + } + + @Override + public String onAdvEvent(String event, Npc npc, PlayerInstance player) + { + switch (event) + { + case "MANAGE_SKILLS": + { + if (npc != null) + { + manageSkills(npc); + } + break; + } + } + return super.onAdvEvent(event, npc, player); + } + + @Override + public String onAttack(Npc npc, PlayerInstance attacker, int damage, boolean isSummon, Skill skill) + { + if (npc.getId() == HELIOS) + { + if (skill == null) + { + refreshAiParams(attacker, npc, (damage * 1000)); + } + else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.25)) + { + refreshAiParams(attacker, npc, ((damage / 3) * 100)); + } + else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.5)) + { + refreshAiParams(attacker, npc, (damage * 20)); + } + else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.75)) + { + refreshAiParams(attacker, npc, (damage * 10)); + } + else + { + refreshAiParams(attacker, npc, ((damage / 3) * 20)); + } + manageSkills(npc); + } + + return super.onAttack(npc, attacker, damage, isSummon); + } + + private final void refreshAiParams(Creature attacker, Npc npc, int damage) + { + refreshAiParams(attacker, npc, damage, damage); + } + + private final void refreshAiParams(Creature attacker, Npc npc, int damage, int aggro) + { + final int newAggroVal = damage + getRandom(3000); + final int aggroVal = aggro + 1000; + final NpcVariables vars = npc.getVariables(); + for (int i = 0; i < 3; i++) + { + if (attacker == vars.getObject("c_quest" + i, Creature.class)) + { + if (vars.getInt("i_quest" + i) < aggroVal) + { + vars.set("i_quest" + i, newAggroVal); + } + return; + } + } + final int index = CommonUtil.getIndexOfMinValue(vars.getInt("i_quest0"), vars.getInt("i_quest1"), vars.getInt("i_quest2")); + vars.set("i_quest" + index, newAggroVal); + vars.set("c_quest" + index, attacker); + } + + @Override + public String onSpellFinished(Npc npc, PlayerInstance player, Skill skill) + { + startQuestTimer("MANAGE_SKILLS", 1000, npc, null); + + return super.onSpellFinished(npc, player, skill); + } + + private void manageSkills(Npc npc) + { + if (npc.isCastingNow(SkillCaster::isAnyNormalType) || npc.isCoreAIDisabled() || !npc.isInCombat()) + { + return; + } + + final NpcVariables vars = npc.getVariables(); + for (int i = 0; i < 3; i++) + { + final Creature attacker = vars.getObject("c_quest" + i, Creature.class); + if ((attacker == null) || ((npc.calculateDistance3D(attacker) > 9000) || attacker.isDead())) + { + vars.set("i_quest" + i, 0); + } + } + final int index = CommonUtil.getIndexOfMaxValue(vars.getInt("i_quest0"), vars.getInt("i_quest1"), vars.getInt("i_quest2")); + final Creature player = vars.getObject("c_quest" + index, Creature.class); + final int i2 = vars.getInt("i_quest" + index); + if ((i2 > 0) && (getRandom(100) < 70)) + { + vars.set("i_quest" + index, 500); + } + + SkillHolder skillToCast = null; + if ((player != null) && !player.isDead()) + { + if (getRandom(100) < 30) + { + skillToCast = EMPEROR_HELIOS_AUTHORITY; + } + else if (getRandom(100) < 50) + { + skillToCast = HELIOS_PLASMA_PRESSURE; + } + else + { + skillToCast = HELIOS_PLASMA_WALL; + } + } + + if ((skillToCast != null) && SkillCaster.checkUseConditions(npc, skillToCast.getSkill())) + + { + npc.setTarget(player); + npc.doCast(skillToCast.getSkill()); + } + } + + public static void main(String[] args) + { + new Helios2(); + } +} diff --git a/L2J_Mobius_6.0_Fafurion/dist/game/data/scripts/ai/bosses/Helios/Helios3.java b/L2J_Mobius_6.0_Fafurion/dist/game/data/scripts/ai/bosses/Helios/Helios3.java new file mode 100644 index 0000000000..efa78d5d99 --- /dev/null +++ b/L2J_Mobius_6.0_Fafurion/dist/game/data/scripts/ai/bosses/Helios/Helios3.java @@ -0,0 +1,187 @@ +/* + * This file is part of the L2J Mobius project. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ai.bosses.Helios; + +import org.l2jmobius.commons.util.CommonUtil; +import org.l2jmobius.gameserver.model.actor.Creature; +import org.l2jmobius.gameserver.model.actor.Npc; +import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; +import org.l2jmobius.gameserver.model.holders.SkillHolder; +import org.l2jmobius.gameserver.model.skills.Skill; +import org.l2jmobius.gameserver.model.skills.SkillCaster; +import org.l2jmobius.gameserver.model.variables.NpcVariables; + +import ai.AbstractNpcAI; + +/** + * @author NviX + */ +public class Helios3 extends AbstractNpcAI +{ + // Npc + private static final int HELIOS = 29305; + // Skills + private static final SkillHolder HELIOS_OVERAWING_GAZE = new SkillHolder(16616, 1); + private static final SkillHolder HELIOS_HOLY_SPIKE = new SkillHolder(16621, 1); + private static final SkillHolder HELIOS_BIONIC_BOMB = new SkillHolder(16622, 1); + private static final SkillHolder HELIOS_LIGHTNING_OF_ANGER = new SkillHolder(16623, 1); + + private Helios3() + { + registerMobs(HELIOS); + } + + @Override + public String onAdvEvent(String event, Npc npc, PlayerInstance player) + { + switch (event) + { + case "MANAGE_SKILLS": + { + if (npc != null) + { + manageSkills(npc); + } + break; + } + } + return super.onAdvEvent(event, npc, player); + } + + @Override + public String onAttack(Npc npc, PlayerInstance attacker, int damage, boolean isSummon, Skill skill) + { + if (npc.getId() == HELIOS) + { + if (skill == null) + { + refreshAiParams(attacker, npc, (damage * 1000)); + } + else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.25)) + { + refreshAiParams(attacker, npc, ((damage / 3) * 100)); + } + else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.5)) + { + refreshAiParams(attacker, npc, (damage * 20)); + } + else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.75)) + { + refreshAiParams(attacker, npc, (damage * 10)); + } + else + { + refreshAiParams(attacker, npc, ((damage / 3) * 20)); + } + manageSkills(npc); + } + + return super.onAttack(npc, attacker, damage, isSummon); + } + + private final void refreshAiParams(Creature attacker, Npc npc, int damage) + { + refreshAiParams(attacker, npc, damage, damage); + } + + private final void refreshAiParams(Creature attacker, Npc npc, int damage, int aggro) + { + final int newAggroVal = damage + getRandom(3000); + final int aggroVal = aggro + 1000; + final NpcVariables vars = npc.getVariables(); + for (int i = 0; i < 3; i++) + { + if (attacker == vars.getObject("c_quest" + i, Creature.class)) + { + if (vars.getInt("i_quest" + i) < aggroVal) + { + vars.set("i_quest" + i, newAggroVal); + } + return; + } + } + final int index = CommonUtil.getIndexOfMinValue(vars.getInt("i_quest0"), vars.getInt("i_quest1"), vars.getInt("i_quest2")); + vars.set("i_quest" + index, newAggroVal); + vars.set("c_quest" + index, attacker); + } + + @Override + public String onSpellFinished(Npc npc, PlayerInstance player, Skill skill) + { + startQuestTimer("MANAGE_SKILLS", 1000, npc, null); + + return super.onSpellFinished(npc, player, skill); + } + + private void manageSkills(Npc npc) + { + if (npc.isCastingNow(SkillCaster::isAnyNormalType) || npc.isCoreAIDisabled() || !npc.isInCombat()) + { + return; + } + + final NpcVariables vars = npc.getVariables(); + for (int i = 0; i < 3; i++) + { + final Creature attacker = vars.getObject("c_quest" + i, Creature.class); + if ((attacker == null) || ((npc.calculateDistance3D(attacker) > 9000) || attacker.isDead())) + { + vars.set("i_quest" + i, 0); + } + } + final int index = CommonUtil.getIndexOfMaxValue(vars.getInt("i_quest0"), vars.getInt("i_quest1"), vars.getInt("i_quest2")); + final Creature player = vars.getObject("c_quest" + index, Creature.class); + final int i2 = vars.getInt("i_quest" + index); + if ((i2 > 0) && (getRandom(100) < 70)) + { + vars.set("i_quest" + index, 500); + } + + SkillHolder skillToCast = null; + if ((player != null) && !player.isDead()) + { + if (getRandom(100) < 10) + { + skillToCast = HELIOS_LIGHTNING_OF_ANGER; + } + else if (getRandom(100) < 30) + { + skillToCast = HELIOS_OVERAWING_GAZE; + } + else if (getRandom(100) < 50) + { + skillToCast = HELIOS_BIONIC_BOMB; + } + else + { + skillToCast = HELIOS_HOLY_SPIKE; + } + } + + if ((skillToCast != null) && SkillCaster.checkUseConditions(npc, skillToCast.getSkill())) + + { + npc.setTarget(player); + npc.doCast(skillToCast.getSkill()); + } + } + + public static void main(String[] args) + { + new Helios3(); + } +} diff --git a/L2J_Mobius_6.0_Fafurion/dist/game/data/scripts/ai/bosses/Helios/RoyalArchmageMinion.java b/L2J_Mobius_6.0_Fafurion/dist/game/data/scripts/ai/bosses/Helios/RoyalArchmageMinion.java new file mode 100644 index 0000000000..1529d6f1fb --- /dev/null +++ b/L2J_Mobius_6.0_Fafurion/dist/game/data/scripts/ai/bosses/Helios/RoyalArchmageMinion.java @@ -0,0 +1,177 @@ +/* + * This file is part of the L2J Mobius project. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ai.bosses.Helios; + +import org.l2jmobius.commons.util.CommonUtil; +import org.l2jmobius.gameserver.model.actor.Creature; +import org.l2jmobius.gameserver.model.actor.Npc; +import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; +import org.l2jmobius.gameserver.model.holders.SkillHolder; +import org.l2jmobius.gameserver.model.skills.Skill; +import org.l2jmobius.gameserver.model.skills.SkillCaster; +import org.l2jmobius.gameserver.model.variables.NpcVariables; + +import ai.AbstractNpcAI; + +/** + * @author NviX + */ +public class RoyalArchmageMinion extends AbstractNpcAI +{ + // Npc + private static final int ROYAL_ARCHMAGE = 29313; + // Skills + private static final SkillHolder ULTRA_PLASMA_BALL = new SkillHolder(16685, 1); + private static final SkillHolder ULTRA_PLASMA_WAVE = new SkillHolder(16686, 1); + + private RoyalArchmageMinion() + { + registerMobs(ROYAL_ARCHMAGE); + } + + @Override + public String onAdvEvent(String event, Npc npc, PlayerInstance player) + { + switch (event) + { + case "MANAGE_SKILLS": + { + if (npc != null) + { + manageSkills(npc); + } + break; + } + } + return super.onAdvEvent(event, npc, player); + } + + @Override + public String onAttack(Npc npc, PlayerInstance attacker, int damage, boolean isSummon, Skill skill) + { + if (npc.getId() == ROYAL_ARCHMAGE) + { + if (skill == null) + { + refreshAiParams(attacker, npc, (damage * 1000)); + } + else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.25)) + { + refreshAiParams(attacker, npc, ((damage / 3) * 100)); + } + else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.5)) + { + refreshAiParams(attacker, npc, (damage * 20)); + } + else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.75)) + { + refreshAiParams(attacker, npc, (damage * 10)); + } + else + { + refreshAiParams(attacker, npc, ((damage / 3) * 20)); + } + manageSkills(npc); + } + + return super.onAttack(npc, attacker, damage, isSummon); + } + + private final void refreshAiParams(Creature attacker, Npc npc, int damage) + { + refreshAiParams(attacker, npc, damage, damage); + } + + private final void refreshAiParams(Creature attacker, Npc npc, int damage, int aggro) + { + final int newAggroVal = damage + getRandom(3000); + final int aggroVal = aggro + 1000; + final NpcVariables vars = npc.getVariables(); + for (int i = 0; i < 3; i++) + { + if (attacker == vars.getObject("c_quest" + i, Creature.class)) + { + if (vars.getInt("i_quest" + i) < aggroVal) + { + vars.set("i_quest" + i, newAggroVal); + } + return; + } + } + final int index = CommonUtil.getIndexOfMinValue(vars.getInt("i_quest0"), vars.getInt("i_quest1"), vars.getInt("i_quest2")); + vars.set("i_quest" + index, newAggroVal); + vars.set("c_quest" + index, attacker); + } + + @Override + public String onSpellFinished(Npc npc, PlayerInstance player, Skill skill) + { + startQuestTimer("MANAGE_SKILLS", 1000, npc, null); + + return super.onSpellFinished(npc, player, skill); + } + + private void manageSkills(Npc npc) + { + if (npc.isCastingNow(SkillCaster::isAnyNormalType) || npc.isCoreAIDisabled() || !npc.isInCombat()) + { + return; + } + + final NpcVariables vars = npc.getVariables(); + for (int i = 0; i < 3; i++) + { + final Creature attacker = vars.getObject("c_quest" + i, Creature.class); + if ((attacker == null) || ((npc.calculateDistance3D(attacker) > 9000) || attacker.isDead())) + { + vars.set("i_quest" + i, 0); + } + } + final int index = CommonUtil.getIndexOfMaxValue(vars.getInt("i_quest0"), vars.getInt("i_quest1"), vars.getInt("i_quest2")); + final Creature player = vars.getObject("c_quest" + index, Creature.class); + final int i2 = vars.getInt("i_quest" + index); + if ((i2 > 0) && (getRandom(100) < 70)) + { + vars.set("i_quest" + index, 500); + } + + SkillHolder skillToCast = null; + if ((player != null) && !player.isDead()) + { + if (getRandom(100) < 50) + { + skillToCast = ULTRA_PLASMA_WAVE; + } + else + { + skillToCast = ULTRA_PLASMA_BALL; + } + } + + if ((skillToCast != null) && SkillCaster.checkUseConditions(npc, skillToCast.getSkill())) + + { + npc.setTarget(player); + npc.doCast(skillToCast.getSkill()); + } + } + + public static void main(String[] args) + { + new RoyalArchmageMinion(); + } +} diff --git a/L2J_Mobius_7.0_PreludeOfWar/dist/game/data/scripts/ai/bosses/Helios/Helios.java b/L2J_Mobius_7.0_PreludeOfWar/dist/game/data/scripts/ai/bosses/Helios/Helios.java index 0f70177f83..9b7f63de07 100644 --- a/L2J_Mobius_7.0_PreludeOfWar/dist/game/data/scripts/ai/bosses/Helios/Helios.java +++ b/L2J_Mobius_7.0_PreludeOfWar/dist/game/data/scripts/ai/bosses/Helios/Helios.java @@ -16,30 +16,59 @@ */ package ai.bosses.Helios; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ScheduledFuture; + import org.l2jmobius.Config; +import org.l2jmobius.commons.concurrent.ThreadPool; +import org.l2jmobius.gameserver.enums.Movie; import org.l2jmobius.gameserver.instancemanager.GrandBossManager; import org.l2jmobius.gameserver.instancemanager.ZoneManager; import org.l2jmobius.gameserver.model.Location; import org.l2jmobius.gameserver.model.StatSet; import org.l2jmobius.gameserver.model.actor.Npc; +import org.l2jmobius.gameserver.model.actor.instance.GrandBossInstance; import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; +import org.l2jmobius.gameserver.model.holders.SkillHolder; +import org.l2jmobius.gameserver.model.holders.SpawnHolder; import org.l2jmobius.gameserver.model.zone.type.NoSummonFriendZone; import org.l2jmobius.gameserver.network.NpcStringId; import org.l2jmobius.gameserver.network.serverpackets.ExShowScreenMessage; +import org.l2jmobius.gameserver.util.Broadcast; import ai.AbstractNpcAI; /** - * @author Mobius + * @author Mobius, NviX */ public class Helios extends AbstractNpcAI { - // NPCs + // Raid private static final int HELIOS1 = 29303; private static final int HELIOS2 = 29304; private static final int HELIOS3 = 29305; + // Minions + private static final int LEOPOLD = 29306; + private static final int HELIOS_RED_LIGHTNING = 29307; + private static final int HELIOS_BLUE_LIGHTNING = 29308; + private static final int LEOPOLD_ORIGIN = 29309; + private static final int ENUMA_ELISH_ORIGIN = 29310; + private static final int ROYAL_TEMPLAR_COLONEL = 29311; + private static final int ROYAL_SHARPSHOOTER = 29312; + private static final int ROYAL_ARCHMAGE = 29313; + private static final int ROYAL_GATEKEEPER = 29314; + private static final int MIMILLION = 29315; + private static final int MIMILLUS = 29316; // Location private static final Location HELIOS_SPAWN_LOC = new Location(92771, 161909, 3494, 38329); + private static final Location BLUE_LIGHTNING_SPEAR_LOC = new Location(93208, 161269, 3489); + private static final Location RED_LIGHTNING_SPEAR_LOC = new Location(92348, 162558, 3489); + private static final Location MIMILLION_LOC = new Location(92465, 162465, 3487); + private static final Location MIMILLUS_LOC = new Location(93174, 161394, 3487); + private static final Location LEOPOLD_LOC = new Location(93531, 162415, 3487); + private static final Location LEOPOLD_ORIGIN_LOC = new Location(92601, 162196, 3464); + private static final Location ENUMA_ELISH_ORIGIN_LOC = new Location(92957, 161640, 3485); // Zone private static final int ZONE_ID = 210109; // Status @@ -47,14 +76,73 @@ public class Helios extends AbstractNpcAI private static final int WAITING = 1; private static final int FIGHTING = 2; private static final int DEAD = 3; + // Skills + private static final SkillHolder AUDIENCE_DEBUFF = new SkillHolder(16613, 1); + private static final SkillHolder RED_LIGHTNING_SPEAR = new SkillHolder(16617, 1); + private static final SkillHolder BLUE_LIGHTNING_SPEAR = new SkillHolder(16618, 1); + private static final SkillHolder PRANARACH = new SkillHolder(16624, 1); + private static final SkillHolder HELIOS_RAGE1 = new SkillHolder(16625, 1); + private static final SkillHolder HELIOS_RAGE2 = new SkillHolder(16625, 2); + private static final SkillHolder HELIOS_RAGE3 = new SkillHolder(16625, 3); + private static final SkillHolder HELIOS_RAGE4 = new SkillHolder(16625, 4); + private static final SkillHolder LEOPOLD_BOMB = new SkillHolder(16629, 1); + private static final SkillHolder LEOPOLD_PLASMA_BOMB = new SkillHolder(16630, 1); + private static final SkillHolder LEOPOLD_ENERGY_BOMB = new SkillHolder(16631, 1); + private static final SkillHolder LEOPOLD_MINI_GUN = new SkillHolder(16632, 1); + private static final SkillHolder LEOPOLD_SPRAY_SHOT = new SkillHolder(16633, 1); + private static final SkillHolder LEOPOLD_HARPOON = new SkillHolder(16634, 1); + // Spawns + private static final List SPAWNS_MINIONS = new ArrayList<>(); + static + { + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_TEMPLAR_COLONEL, HELIOS_SPAWN_LOC, 0, false)); + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_TEMPLAR_COLONEL, HELIOS_SPAWN_LOC, 0, false)); + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_TEMPLAR_COLONEL, HELIOS_SPAWN_LOC, 0, false)); + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_TEMPLAR_COLONEL, HELIOS_SPAWN_LOC, 0, false)); + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_TEMPLAR_COLONEL, HELIOS_SPAWN_LOC, 0, false)); + + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_SHARPSHOOTER, HELIOS_SPAWN_LOC, 0, false)); + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_SHARPSHOOTER, HELIOS_SPAWN_LOC, 0, false)); + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_SHARPSHOOTER, HELIOS_SPAWN_LOC, 0, false)); + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_SHARPSHOOTER, HELIOS_SPAWN_LOC, 0, false)); + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_SHARPSHOOTER, HELIOS_SPAWN_LOC, 0, false)); + + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_ARCHMAGE, HELIOS_SPAWN_LOC, 0, false)); + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_ARCHMAGE, HELIOS_SPAWN_LOC, 0, false)); + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_ARCHMAGE, HELIOS_SPAWN_LOC, 0, false)); + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_ARCHMAGE, HELIOS_SPAWN_LOC, 0, false)); + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_ARCHMAGE, HELIOS_SPAWN_LOC, 0, false)); + + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_GATEKEEPER, HELIOS_SPAWN_LOC, 0, false)); + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_GATEKEEPER, HELIOS_SPAWN_LOC, 0, false)); + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_GATEKEEPER, HELIOS_SPAWN_LOC, 0, false)); + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_GATEKEEPER, HELIOS_SPAWN_LOC, 0, false)); + SPAWNS_MINIONS.add(new SpawnHolder(ROYAL_GATEKEEPER, HELIOS_SPAWN_LOC, 0, false)); + } // Misc private static final int HELIOS_RAID_DURATION = 5; // hours private static Npc bossInstance; private final NoSummonFriendZone bossZone; + private GrandBossInstance _tempHelios; + private static List _minionSpawns = new ArrayList<>(); + private static Npc blueLightning; + private static Npc redLightning; + private static Npc leopold; + private boolean activated = false; + private boolean stage1_50 = false; + private boolean stage2_50 = false; + private boolean helios80 = false; + private boolean helios50 = false; + private boolean _announce = false; + protected ScheduledFuture _blueSpearTask; + protected ScheduledFuture _redSpearTask; + protected ScheduledFuture _leopoldTask; + protected ScheduledFuture _debuffTask; private Helios() { - addKillId(HELIOS1, HELIOS2, HELIOS3); + addAttackId(HELIOS1, HELIOS2, HELIOS3); + addKillId(HELIOS1, HELIOS2, HELIOS3, MIMILLION, MIMILLUS); // Zone bossZone = ZoneManager.getInstance().getZoneById(ZONE_ID, NoSummonFriendZone.class); // Unlock @@ -69,23 +157,184 @@ public class Helios extends AbstractNpcAI } else { + _tempHelios = (GrandBossInstance) addSpawn(HELIOS3, -113360, -244676, -15536, 0, false, 0); + GrandBossManager.getInstance().addBoss(_tempHelios); GrandBossManager.getInstance().setBossStatus(HELIOS3, ALIVE); } } - else if (status != ALIVE) + else { + _tempHelios = (GrandBossInstance) addSpawn(HELIOS3, -113360, -244676, -15536, 0, false, 0); + GrandBossManager.getInstance().addBoss(_tempHelios); GrandBossManager.getInstance().setBossStatus(HELIOS3, ALIVE); } } + @Override + public String onAttack(Npc npc, PlayerInstance attacker, int damage, boolean isSummon) + { + if ((npc.getId() == HELIOS1) && !_announce) + { + _announce = true; + _debuffTask = ThreadPool.scheduleAtFixedRate(() -> + { + bossZone.getPlayersInside().forEach(player -> + { + AUDIENCE_DEBUFF.getSkill().applyEffects(player, player); + }); + }, 5000, 20000); + Broadcast.toAllOnlinePlayers(new ExShowScreenMessage(NpcStringId.THE_ADEN_WARRIORS_BEGIN_BATTLE_WITH_THE_GIANT_EMPEROR_HELIOS, ExShowScreenMessage.TOP_CENTER, 10000, true)); + } + if ((npc.getId() == HELIOS1) && !stage1_50 && (npc.getCurrentHp() <= (npc.getMaxHp() * 0.5))) + { + stage1_50 = true; + HELIOS_RAGE1.getSkill().applyEffects(bossInstance, bossInstance); + } + if ((npc.getId() == HELIOS2) && !activated) + { + activated = true; + HELIOS_RAGE1.getSkill().applyEffects(bossInstance, bossInstance); + _blueSpearTask = ThreadPool.scheduleAtFixedRate(() -> + { + int count = bossZone.getPlayersInside().size(); + if (count > 0) + { + PlayerInstance randomPlayer = bossZone.getPlayersInside().get(getRandom(count)); + if (blueLightning != null) + { + blueLightning.setTarget(randomPlayer); + blueLightning.doCast(BLUE_LIGHTNING_SPEAR.getSkill()); + } + } + bossZone.broadcastPacket(new ExShowScreenMessage(NpcStringId.HELIOS_PICKS_UP_THE_BLUE_LIGHTNING_SPEAR_AND_BEGINS_GATHERING_HIS_POWER, ExShowScreenMessage.TOP_CENTER, 10000, true)); + }, 10000, 120000); + _redSpearTask = ThreadPool.scheduleAtFixedRate(() -> + { + int count = bossZone.getPlayersInside().size(); + if (count > 0) + { + PlayerInstance randomPlayer = bossZone.getPlayersInside().get(getRandom(count)); + if (redLightning != null) + { + redLightning.setTarget(randomPlayer); + redLightning.doCast(RED_LIGHTNING_SPEAR.getSkill()); + } + } + bossZone.broadcastPacket(new ExShowScreenMessage(NpcStringId.HELIOS_PICKS_UP_THE_RED_LIGHTNING_SPEAR_AND_BEGINS_GATHERING_HIS_POWER, ExShowScreenMessage.TOP_CENTER, 10000, true)); + }, 30000, 120000); + _leopoldTask = ThreadPool.scheduleAtFixedRate(() -> + { + int count = bossZone.getPlayersInside().size(); + if (count > 0) + { + PlayerInstance randomPlayer = bossZone.getPlayersInside().get(getRandom(count)); + if (leopold != null) + { + leopold.setTarget(randomPlayer); + int rnd = getRandom(100); + if (rnd < 16) + { + leopold.doCast(LEOPOLD_BOMB.getSkill()); + } + else if (rnd < 32) + { + leopold.doCast(LEOPOLD_PLASMA_BOMB.getSkill()); + } + else if (rnd < 48) + { + leopold.doCast(LEOPOLD_ENERGY_BOMB.getSkill()); + } + else if (rnd < 64) + { + leopold.doCast(LEOPOLD_MINI_GUN.getSkill()); + } + else if (rnd < 80) + { + leopold.doCast(LEOPOLD_SPRAY_SHOT.getSkill()); + } + else + { + leopold.doCast(LEOPOLD_HARPOON.getSkill()); + } + } + } + }, 5000, 10000); + } + if ((npc.getId() == HELIOS2) && !stage2_50 && (npc.getCurrentHp() <= (npc.getMaxHp() * 0.5))) + { + stage2_50 = true; + HELIOS_RAGE2.getSkill().applyEffects(bossInstance, bossInstance); + } + if ((npc.getId() == HELIOS3) && !activated) + { + activated = true; + HELIOS_RAGE3.getSkill().applyEffects(bossInstance, bossInstance); + _leopoldTask = ThreadPool.scheduleAtFixedRate(() -> + { + int count = bossZone.getPlayersInside().size(); + if (count > 0) + { + PlayerInstance randomPlayer = bossZone.getPlayersInside().get(getRandom(count)); + if (leopold != null) + { + leopold.setTarget(randomPlayer); + int rnd = getRandom(100); + if (rnd < 16) + { + leopold.doCast(LEOPOLD_BOMB.getSkill()); + } + else if (rnd < 32) + { + leopold.doCast(LEOPOLD_PLASMA_BOMB.getSkill()); + } + else if (rnd < 48) + { + leopold.doCast(LEOPOLD_ENERGY_BOMB.getSkill()); + } + else if (rnd < 64) + { + leopold.doCast(LEOPOLD_MINI_GUN.getSkill()); + } + else if (rnd < 80) + { + leopold.doCast(LEOPOLD_SPRAY_SHOT.getSkill()); + } + else + { + leopold.doCast(LEOPOLD_HARPOON.getSkill()); + } + } + } + }, 5000, 10000); + } + if ((npc.getId() == HELIOS3) && !helios80 && (npc.getCurrentHp() <= (npc.getMaxHp() * 0.8))) + { + helios80 = true; + addSpawn(LEOPOLD_ORIGIN, LEOPOLD_ORIGIN_LOC, false, 0); + addSpawn(ENUMA_ELISH_ORIGIN, ENUMA_ELISH_ORIGIN_LOC, false, 0); + bossZone.broadcastPacket(new ExShowScreenMessage(NpcStringId.THE_KAMAEL_ORIGINS_ABOVE_THE_THRONE_OF_HELIOS_BEGIN_TO_SOAR, ExShowScreenMessage.TOP_CENTER, 10000, true)); + } + else if ((npc.getId() == HELIOS3) && !helios50 && (npc.getCurrentHp() <= (npc.getMaxHp() * 0.5))) + { + helios50 = true; + HELIOS_RAGE4.getSkill().applyEffects(bossInstance, bossInstance); + bossZone.broadcastPacket(new ExShowScreenMessage(NpcStringId.HELIOS_USES_THE_PRANARACH_SHIELD_OF_LIGHT_TO_MINIMIZE_DAMAGE, ExShowScreenMessage.TOP_CENTER, 10000, true)); + bossInstance.abortCast(); + bossInstance.doCast(PRANARACH.getSkill()); + } + return super.onAttack(npc, attacker, damage, isSummon); + } + @Override public String onAdvEvent(String event, Npc npc, PlayerInstance player) { - final String htmltext = null; + String htmltext = null; switch (event) { case "unlock_helios": { + _tempHelios = (GrandBossInstance) addSpawn(HELIOS3, -113360, -244676, -15536, 0, false, 0); + GrandBossManager.getInstance().addBoss(_tempHelios); GrandBossManager.getInstance().setBossStatus(HELIOS3, ALIVE); break; } @@ -95,6 +344,10 @@ public class Helios extends AbstractNpcAI { GrandBossManager.getInstance().setBossStatus(HELIOS3, FIGHTING); bossInstance = addSpawn(HELIOS1, HELIOS_SPAWN_LOC.getX(), HELIOS_SPAWN_LOC.getY(), HELIOS_SPAWN_LOC.getZ(), HELIOS_SPAWN_LOC.getHeading(), false, 0, false); + for (SpawnHolder spawn : SPAWNS_MINIONS) + { + _minionSpawns.add(addSpawn(spawn.getNpcId(), spawn.getLocation())); + } startQuestTimer("resetRaid", HELIOS_RAID_DURATION * 60 * 60 * 1000, bossInstance, null); } break; @@ -104,35 +357,141 @@ public class Helios extends AbstractNpcAI final int status = GrandBossManager.getInstance().getBossStatus(HELIOS3); if ((status > ALIVE) && (status < DEAD)) { + bossZone.oustAllPlayers(); + Broadcast.toAllOnlinePlayers(new ExShowScreenMessage(NpcStringId.THE_HEROES_DRAINED_OF_THEIR_POWERS_HAVE_BEEN_BANISHED_FROM_THE_THRONE_OF_HELIOS_BY_HELIOS_POWERS, ExShowScreenMessage.TOP_CENTER, 10000, true)); GrandBossManager.getInstance().setBossStatus(HELIOS3, ALIVE); - npc.deleteMe(); + Clean(); } break; } + case "stage2": + { + bossInstance = addSpawn(HELIOS2, HELIOS_SPAWN_LOC.getX(), HELIOS_SPAWN_LOC.getY(), HELIOS_SPAWN_LOC.getZ(), HELIOS_SPAWN_LOC.getHeading(), false, 0, false); + bossZone.broadcastPacket(new ExShowScreenMessage(NpcStringId.HELIOS_APPEARANCE_CHANGES_AND_HE_BEGINS_TO_GROW_STRONGER, ExShowScreenMessage.TOP_CENTER, 10000, true)); + for (SpawnHolder spawn : SPAWNS_MINIONS) + { + _minionSpawns.add(addSpawn(spawn.getNpcId(), spawn.getLocation())); + } + startQuestTimer("spheresSpawn", 10000, null, null); + break; + } + case "stage3": + { + activated = false; + bossInstance = addSpawn(HELIOS3, HELIOS_SPAWN_LOC.getX(), HELIOS_SPAWN_LOC.getY(), HELIOS_SPAWN_LOC.getZ(), HELIOS_SPAWN_LOC.getHeading(), false, 0, false); + bossZone.broadcastPacket(new ExShowScreenMessage(NpcStringId.HELIOS_APPEARANCE_CHANGES_AND_HE_BEGINS_TO_GROW_STRONGER, ExShowScreenMessage.TOP_CENTER, 10000, true)); + startQuestTimer("leopoldSpawn", 10000, null, null); + break; + } + case "spheresSpawn": + { + blueLightning = addSpawn(HELIOS_BLUE_LIGHTNING, BLUE_LIGHTNING_SPEAR_LOC, false, 0); + redLightning = addSpawn(HELIOS_RED_LIGHTNING, RED_LIGHTNING_SPEAR_LOC, false, 0); + blueLightning.setInvul(true); + redLightning.setInvul(true); + bossZone.broadcastPacket(new ExShowScreenMessage(NpcStringId.THE_ENUMA_ELISH_SPEAR_ON_THE_THRONE_OF_HELIOS_IS_PREPARED_AND_PLACED_IN_POSITION, ExShowScreenMessage.TOP_CENTER, 10000, true)); + startQuestTimer("protectorsSpawn", 10000, null, null); + break; + } + case "protectorsSpawn": + { + bossZone.broadcastPacket(new ExShowScreenMessage(NpcStringId.MIMILLION_AND_MIMILLUS_APPEAR_IN_ORDER_TO_PROTECT_THE_ENUMA_ELISH_OF_RED_LIGHTNING_AND_THE_ENUMA_ELISH_OF_BLUE_LIGHTNING, ExShowScreenMessage.TOP_CENTER, 10000, true)); + addSpawn(MIMILLION, MIMILLION_LOC, false, 0); + addSpawn(MIMILLUS, MIMILLUS_LOC, false, 0); + startQuestTimer("leopoldSpawn", 10000, null, null); + break; + } + case "leopoldSpawn": + { + leopold = addSpawn(LEOPOLD, LEOPOLD_LOC, false, 0); + bossZone.broadcastPacket(new ExShowScreenMessage(NpcStringId.THE_SIEGE_CANNON_LEOPOLD_ON_THE_THRONE_OF_HELIOS_BEGINS_TO_PREPARE_TO_FIRE, ExShowScreenMessage.TOP_CENTER, 10000, true)); + break; + } } return htmltext; } + private void Clean() + { + bossZone.getCharactersInside().forEach(mob -> + { + if (mob.isNpc()) + { + mob.deleteMe(); + } + }); + if (_blueSpearTask != null) + { + _blueSpearTask.cancel(true); + _blueSpearTask = null; + } + if (_redSpearTask != null) + { + _redSpearTask.cancel(true); + _redSpearTask = null; + } + if (_leopoldTask != null) + { + _leopoldTask.cancel(true); + _leopoldTask = null; + } + if (_debuffTask != null) + { + _debuffTask.cancel(true); + _debuffTask = null; + } + } + @Override public String onKill(Npc npc, PlayerInstance killer, boolean isSummon) { switch (npc.getId()) { + case MIMILLION: + { + if (redLightning != null) + { + redLightning.deleteMe(); + bossZone.broadcastPacket(new ExShowScreenMessage(NpcStringId.MIMILLION_FALLS_AND_THE_RED_LIGHTNING_SPEAR_VANISHES, ExShowScreenMessage.TOP_CENTER, 10000, true)); + } + break; + } + case MIMILLUS: + { + if (blueLightning != null) + { + blueLightning.deleteMe(); + bossZone.broadcastPacket(new ExShowScreenMessage(NpcStringId.MIMILLUS_FALLS_AND_THE_BLUE_LIGHTNING_SPEAR_VANISHES, ExShowScreenMessage.TOP_CENTER, 10000, true)); + } + break; + } case HELIOS1: { bossInstance.deleteMe(); - bossInstance = addSpawn(HELIOS2, HELIOS_SPAWN_LOC.getX(), HELIOS_SPAWN_LOC.getY(), HELIOS_SPAWN_LOC.getZ(), HELIOS_SPAWN_LOC.getHeading(), false, 0, false); - bossZone.broadcastPacket(new ExShowScreenMessage(NpcStringId.HELIOS_APPEARANCE_CHANGES_AND_HE_BEGINS_TO_GROW_STRONGER, ExShowScreenMessage.TOP_CENTER, 10000, true)); + bossZone.getPlayersInside().forEach(player -> + { + playMovie(player, Movie.SC_HELIOS_TRANS_A); + }); + startQuestTimer("stage2", 15000, null, null); break; } case HELIOS2: { bossInstance.deleteMe(); - bossInstance = addSpawn(HELIOS3, HELIOS_SPAWN_LOC.getX(), HELIOS_SPAWN_LOC.getY(), HELIOS_SPAWN_LOC.getZ(), HELIOS_SPAWN_LOC.getHeading(), false, 0, false); + if (leopold != null) + { + leopold.deleteMe(); + } + bossZone.getPlayersInside().forEach(player -> + { + playMovie(player, Movie.SC_HELIOS_TRANS_B); + }); + startQuestTimer("stage3", 15000, null, null); break; } case HELIOS3: { + Clean(); bossZone.broadcastPacket(new ExShowScreenMessage(NpcStringId.HELIOS_DEFEATED_TAKES_FLIGHT_DEEP_IN_TO_THE_SUPERION_FORT_HIS_THRONE_IS_RENDERED_INACTIVE, ExShowScreenMessage.TOP_CENTER, 10000, true)); GrandBossManager.getInstance().setBossStatus(HELIOS3, DEAD); final long respawnTime = (Config.HELIOS_SPAWN_INTERVAL + getRandom(-Config.HELIOS_SPAWN_RANDOM, Config.HELIOS_SPAWN_RANDOM)) * 3600000; @@ -150,4 +509,4 @@ public class Helios extends AbstractNpcAI { new Helios(); } -} +} \ No newline at end of file diff --git a/L2J_Mobius_7.0_PreludeOfWar/dist/game/data/scripts/ai/bosses/Helios/Helios1.java b/L2J_Mobius_7.0_PreludeOfWar/dist/game/data/scripts/ai/bosses/Helios/Helios1.java new file mode 100644 index 0000000000..336c5de75a --- /dev/null +++ b/L2J_Mobius_7.0_PreludeOfWar/dist/game/data/scripts/ai/bosses/Helios/Helios1.java @@ -0,0 +1,182 @@ +/* + * This file is part of the L2J Mobius project. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ai.bosses.Helios; + +import org.l2jmobius.commons.util.CommonUtil; +import org.l2jmobius.gameserver.model.actor.Creature; +import org.l2jmobius.gameserver.model.actor.Npc; +import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; +import org.l2jmobius.gameserver.model.holders.SkillHolder; +import org.l2jmobius.gameserver.model.skills.Skill; +import org.l2jmobius.gameserver.model.skills.SkillCaster; +import org.l2jmobius.gameserver.model.variables.NpcVariables; + +import ai.AbstractNpcAI; + +/** + * @author NviX + */ +public class Helios1 extends AbstractNpcAI +{ + // Npc + private static final int HELIOS = 29303; + // Skills + private static final SkillHolder HELIOS_PLASMA = new SkillHolder(16609, 1); + private static final SkillHolder HELIOS_GRAND_PLASMA = new SkillHolder(16610, 1); + private static final SkillHolder HELIOS_THRONE_OF_AGONY = new SkillHolder(16611, 1); + + private Helios1() + { + registerMobs(HELIOS); + } + + @Override + public String onAdvEvent(String event, Npc npc, PlayerInstance player) + { + switch (event) + { + case "MANAGE_SKILLS": + { + if (npc != null) + { + manageSkills(npc); + } + break; + } + } + return super.onAdvEvent(event, npc, player); + } + + @Override + public String onAttack(Npc npc, PlayerInstance attacker, int damage, boolean isSummon, Skill skill) + { + if (npc.getId() == HELIOS) + { + if (skill == null) + { + refreshAiParams(attacker, npc, (damage * 1000)); + } + else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.25)) + { + refreshAiParams(attacker, npc, ((damage / 3) * 100)); + } + else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.5)) + { + refreshAiParams(attacker, npc, (damage * 20)); + } + else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.75)) + { + refreshAiParams(attacker, npc, (damage * 10)); + } + else + { + refreshAiParams(attacker, npc, ((damage / 3) * 20)); + } + manageSkills(npc); + } + + return super.onAttack(npc, attacker, damage, isSummon); + } + + private final void refreshAiParams(Creature attacker, Npc npc, int damage) + { + refreshAiParams(attacker, npc, damage, damage); + } + + private final void refreshAiParams(Creature attacker, Npc npc, int damage, int aggro) + { + final int newAggroVal = damage + getRandom(3000); + final int aggroVal = aggro + 1000; + final NpcVariables vars = npc.getVariables(); + for (int i = 0; i < 3; i++) + { + if (attacker == vars.getObject("c_quest" + i, Creature.class)) + { + if (vars.getInt("i_quest" + i) < aggroVal) + { + vars.set("i_quest" + i, newAggroVal); + } + return; + } + } + final int index = CommonUtil.getIndexOfMinValue(vars.getInt("i_quest0"), vars.getInt("i_quest1"), vars.getInt("i_quest2")); + vars.set("i_quest" + index, newAggroVal); + vars.set("c_quest" + index, attacker); + } + + @Override + public String onSpellFinished(Npc npc, PlayerInstance player, Skill skill) + { + startQuestTimer("MANAGE_SKILLS", 1000, npc, null); + + return super.onSpellFinished(npc, player, skill); + } + + private void manageSkills(Npc npc) + { + if (npc.isCastingNow(SkillCaster::isAnyNormalType) || npc.isCoreAIDisabled() || !npc.isInCombat()) + { + return; + } + + final NpcVariables vars = npc.getVariables(); + for (int i = 0; i < 3; i++) + { + final Creature attacker = vars.getObject("c_quest" + i, Creature.class); + if ((attacker == null) || ((npc.calculateDistance3D(attacker) > 9000) || attacker.isDead())) + { + vars.set("i_quest" + i, 0); + } + } + final int index = CommonUtil.getIndexOfMaxValue(vars.getInt("i_quest0"), vars.getInt("i_quest1"), vars.getInt("i_quest2")); + final Creature player = vars.getObject("c_quest" + index, Creature.class); + final int i2 = vars.getInt("i_quest" + index); + if ((i2 > 0) && (getRandom(100) < 70)) + { + vars.set("i_quest" + index, 500); + } + + SkillHolder skillToCast = null; + if ((player != null) && !player.isDead()) + { + if (getRandom(100) < 30) + { + skillToCast = HELIOS_GRAND_PLASMA; + } + else if (getRandom(100) < 50) + { + skillToCast = HELIOS_THRONE_OF_AGONY; + } + else + { + skillToCast = HELIOS_PLASMA; + } + } + + if ((skillToCast != null) && SkillCaster.checkUseConditions(npc, skillToCast.getSkill())) + + { + npc.setTarget(player); + npc.doCast(skillToCast.getSkill()); + } + } + + public static void main(String[] args) + { + new Helios1(); + } +} diff --git a/L2J_Mobius_7.0_PreludeOfWar/dist/game/data/scripts/ai/bosses/Helios/Helios2.java b/L2J_Mobius_7.0_PreludeOfWar/dist/game/data/scripts/ai/bosses/Helios/Helios2.java new file mode 100644 index 0000000000..cf7ad4b0e6 --- /dev/null +++ b/L2J_Mobius_7.0_PreludeOfWar/dist/game/data/scripts/ai/bosses/Helios/Helios2.java @@ -0,0 +1,182 @@ +/* + * This file is part of the L2J Mobius project. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ai.bosses.Helios; + +import org.l2jmobius.commons.util.CommonUtil; +import org.l2jmobius.gameserver.model.actor.Creature; +import org.l2jmobius.gameserver.model.actor.Npc; +import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; +import org.l2jmobius.gameserver.model.holders.SkillHolder; +import org.l2jmobius.gameserver.model.skills.Skill; +import org.l2jmobius.gameserver.model.skills.SkillCaster; +import org.l2jmobius.gameserver.model.variables.NpcVariables; + +import ai.AbstractNpcAI; + +/** + * @author NviX + */ +public class Helios2 extends AbstractNpcAI +{ + // Npc + private static final int HELIOS = 29304; + // Skills + private static final SkillHolder EMPEROR_HELIOS_AUTHORITY = new SkillHolder(16612, 1); + private static final SkillHolder HELIOS_PLASMA_PRESSURE = new SkillHolder(16614, 1); + private static final SkillHolder HELIOS_PLASMA_WALL = new SkillHolder(16615, 1); + + private Helios2() + { + registerMobs(HELIOS); + } + + @Override + public String onAdvEvent(String event, Npc npc, PlayerInstance player) + { + switch (event) + { + case "MANAGE_SKILLS": + { + if (npc != null) + { + manageSkills(npc); + } + break; + } + } + return super.onAdvEvent(event, npc, player); + } + + @Override + public String onAttack(Npc npc, PlayerInstance attacker, int damage, boolean isSummon, Skill skill) + { + if (npc.getId() == HELIOS) + { + if (skill == null) + { + refreshAiParams(attacker, npc, (damage * 1000)); + } + else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.25)) + { + refreshAiParams(attacker, npc, ((damage / 3) * 100)); + } + else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.5)) + { + refreshAiParams(attacker, npc, (damage * 20)); + } + else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.75)) + { + refreshAiParams(attacker, npc, (damage * 10)); + } + else + { + refreshAiParams(attacker, npc, ((damage / 3) * 20)); + } + manageSkills(npc); + } + + return super.onAttack(npc, attacker, damage, isSummon); + } + + private final void refreshAiParams(Creature attacker, Npc npc, int damage) + { + refreshAiParams(attacker, npc, damage, damage); + } + + private final void refreshAiParams(Creature attacker, Npc npc, int damage, int aggro) + { + final int newAggroVal = damage + getRandom(3000); + final int aggroVal = aggro + 1000; + final NpcVariables vars = npc.getVariables(); + for (int i = 0; i < 3; i++) + { + if (attacker == vars.getObject("c_quest" + i, Creature.class)) + { + if (vars.getInt("i_quest" + i) < aggroVal) + { + vars.set("i_quest" + i, newAggroVal); + } + return; + } + } + final int index = CommonUtil.getIndexOfMinValue(vars.getInt("i_quest0"), vars.getInt("i_quest1"), vars.getInt("i_quest2")); + vars.set("i_quest" + index, newAggroVal); + vars.set("c_quest" + index, attacker); + } + + @Override + public String onSpellFinished(Npc npc, PlayerInstance player, Skill skill) + { + startQuestTimer("MANAGE_SKILLS", 1000, npc, null); + + return super.onSpellFinished(npc, player, skill); + } + + private void manageSkills(Npc npc) + { + if (npc.isCastingNow(SkillCaster::isAnyNormalType) || npc.isCoreAIDisabled() || !npc.isInCombat()) + { + return; + } + + final NpcVariables vars = npc.getVariables(); + for (int i = 0; i < 3; i++) + { + final Creature attacker = vars.getObject("c_quest" + i, Creature.class); + if ((attacker == null) || ((npc.calculateDistance3D(attacker) > 9000) || attacker.isDead())) + { + vars.set("i_quest" + i, 0); + } + } + final int index = CommonUtil.getIndexOfMaxValue(vars.getInt("i_quest0"), vars.getInt("i_quest1"), vars.getInt("i_quest2")); + final Creature player = vars.getObject("c_quest" + index, Creature.class); + final int i2 = vars.getInt("i_quest" + index); + if ((i2 > 0) && (getRandom(100) < 70)) + { + vars.set("i_quest" + index, 500); + } + + SkillHolder skillToCast = null; + if ((player != null) && !player.isDead()) + { + if (getRandom(100) < 30) + { + skillToCast = EMPEROR_HELIOS_AUTHORITY; + } + else if (getRandom(100) < 50) + { + skillToCast = HELIOS_PLASMA_PRESSURE; + } + else + { + skillToCast = HELIOS_PLASMA_WALL; + } + } + + if ((skillToCast != null) && SkillCaster.checkUseConditions(npc, skillToCast.getSkill())) + + { + npc.setTarget(player); + npc.doCast(skillToCast.getSkill()); + } + } + + public static void main(String[] args) + { + new Helios2(); + } +} diff --git a/L2J_Mobius_7.0_PreludeOfWar/dist/game/data/scripts/ai/bosses/Helios/Helios3.java b/L2J_Mobius_7.0_PreludeOfWar/dist/game/data/scripts/ai/bosses/Helios/Helios3.java new file mode 100644 index 0000000000..efa78d5d99 --- /dev/null +++ b/L2J_Mobius_7.0_PreludeOfWar/dist/game/data/scripts/ai/bosses/Helios/Helios3.java @@ -0,0 +1,187 @@ +/* + * This file is part of the L2J Mobius project. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ai.bosses.Helios; + +import org.l2jmobius.commons.util.CommonUtil; +import org.l2jmobius.gameserver.model.actor.Creature; +import org.l2jmobius.gameserver.model.actor.Npc; +import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; +import org.l2jmobius.gameserver.model.holders.SkillHolder; +import org.l2jmobius.gameserver.model.skills.Skill; +import org.l2jmobius.gameserver.model.skills.SkillCaster; +import org.l2jmobius.gameserver.model.variables.NpcVariables; + +import ai.AbstractNpcAI; + +/** + * @author NviX + */ +public class Helios3 extends AbstractNpcAI +{ + // Npc + private static final int HELIOS = 29305; + // Skills + private static final SkillHolder HELIOS_OVERAWING_GAZE = new SkillHolder(16616, 1); + private static final SkillHolder HELIOS_HOLY_SPIKE = new SkillHolder(16621, 1); + private static final SkillHolder HELIOS_BIONIC_BOMB = new SkillHolder(16622, 1); + private static final SkillHolder HELIOS_LIGHTNING_OF_ANGER = new SkillHolder(16623, 1); + + private Helios3() + { + registerMobs(HELIOS); + } + + @Override + public String onAdvEvent(String event, Npc npc, PlayerInstance player) + { + switch (event) + { + case "MANAGE_SKILLS": + { + if (npc != null) + { + manageSkills(npc); + } + break; + } + } + return super.onAdvEvent(event, npc, player); + } + + @Override + public String onAttack(Npc npc, PlayerInstance attacker, int damage, boolean isSummon, Skill skill) + { + if (npc.getId() == HELIOS) + { + if (skill == null) + { + refreshAiParams(attacker, npc, (damage * 1000)); + } + else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.25)) + { + refreshAiParams(attacker, npc, ((damage / 3) * 100)); + } + else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.5)) + { + refreshAiParams(attacker, npc, (damage * 20)); + } + else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.75)) + { + refreshAiParams(attacker, npc, (damage * 10)); + } + else + { + refreshAiParams(attacker, npc, ((damage / 3) * 20)); + } + manageSkills(npc); + } + + return super.onAttack(npc, attacker, damage, isSummon); + } + + private final void refreshAiParams(Creature attacker, Npc npc, int damage) + { + refreshAiParams(attacker, npc, damage, damage); + } + + private final void refreshAiParams(Creature attacker, Npc npc, int damage, int aggro) + { + final int newAggroVal = damage + getRandom(3000); + final int aggroVal = aggro + 1000; + final NpcVariables vars = npc.getVariables(); + for (int i = 0; i < 3; i++) + { + if (attacker == vars.getObject("c_quest" + i, Creature.class)) + { + if (vars.getInt("i_quest" + i) < aggroVal) + { + vars.set("i_quest" + i, newAggroVal); + } + return; + } + } + final int index = CommonUtil.getIndexOfMinValue(vars.getInt("i_quest0"), vars.getInt("i_quest1"), vars.getInt("i_quest2")); + vars.set("i_quest" + index, newAggroVal); + vars.set("c_quest" + index, attacker); + } + + @Override + public String onSpellFinished(Npc npc, PlayerInstance player, Skill skill) + { + startQuestTimer("MANAGE_SKILLS", 1000, npc, null); + + return super.onSpellFinished(npc, player, skill); + } + + private void manageSkills(Npc npc) + { + if (npc.isCastingNow(SkillCaster::isAnyNormalType) || npc.isCoreAIDisabled() || !npc.isInCombat()) + { + return; + } + + final NpcVariables vars = npc.getVariables(); + for (int i = 0; i < 3; i++) + { + final Creature attacker = vars.getObject("c_quest" + i, Creature.class); + if ((attacker == null) || ((npc.calculateDistance3D(attacker) > 9000) || attacker.isDead())) + { + vars.set("i_quest" + i, 0); + } + } + final int index = CommonUtil.getIndexOfMaxValue(vars.getInt("i_quest0"), vars.getInt("i_quest1"), vars.getInt("i_quest2")); + final Creature player = vars.getObject("c_quest" + index, Creature.class); + final int i2 = vars.getInt("i_quest" + index); + if ((i2 > 0) && (getRandom(100) < 70)) + { + vars.set("i_quest" + index, 500); + } + + SkillHolder skillToCast = null; + if ((player != null) && !player.isDead()) + { + if (getRandom(100) < 10) + { + skillToCast = HELIOS_LIGHTNING_OF_ANGER; + } + else if (getRandom(100) < 30) + { + skillToCast = HELIOS_OVERAWING_GAZE; + } + else if (getRandom(100) < 50) + { + skillToCast = HELIOS_BIONIC_BOMB; + } + else + { + skillToCast = HELIOS_HOLY_SPIKE; + } + } + + if ((skillToCast != null) && SkillCaster.checkUseConditions(npc, skillToCast.getSkill())) + + { + npc.setTarget(player); + npc.doCast(skillToCast.getSkill()); + } + } + + public static void main(String[] args) + { + new Helios3(); + } +} diff --git a/L2J_Mobius_7.0_PreludeOfWar/dist/game/data/scripts/ai/bosses/Helios/RoyalArchmageMinion.java b/L2J_Mobius_7.0_PreludeOfWar/dist/game/data/scripts/ai/bosses/Helios/RoyalArchmageMinion.java new file mode 100644 index 0000000000..1529d6f1fb --- /dev/null +++ b/L2J_Mobius_7.0_PreludeOfWar/dist/game/data/scripts/ai/bosses/Helios/RoyalArchmageMinion.java @@ -0,0 +1,177 @@ +/* + * This file is part of the L2J Mobius project. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ai.bosses.Helios; + +import org.l2jmobius.commons.util.CommonUtil; +import org.l2jmobius.gameserver.model.actor.Creature; +import org.l2jmobius.gameserver.model.actor.Npc; +import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; +import org.l2jmobius.gameserver.model.holders.SkillHolder; +import org.l2jmobius.gameserver.model.skills.Skill; +import org.l2jmobius.gameserver.model.skills.SkillCaster; +import org.l2jmobius.gameserver.model.variables.NpcVariables; + +import ai.AbstractNpcAI; + +/** + * @author NviX + */ +public class RoyalArchmageMinion extends AbstractNpcAI +{ + // Npc + private static final int ROYAL_ARCHMAGE = 29313; + // Skills + private static final SkillHolder ULTRA_PLASMA_BALL = new SkillHolder(16685, 1); + private static final SkillHolder ULTRA_PLASMA_WAVE = new SkillHolder(16686, 1); + + private RoyalArchmageMinion() + { + registerMobs(ROYAL_ARCHMAGE); + } + + @Override + public String onAdvEvent(String event, Npc npc, PlayerInstance player) + { + switch (event) + { + case "MANAGE_SKILLS": + { + if (npc != null) + { + manageSkills(npc); + } + break; + } + } + return super.onAdvEvent(event, npc, player); + } + + @Override + public String onAttack(Npc npc, PlayerInstance attacker, int damage, boolean isSummon, Skill skill) + { + if (npc.getId() == ROYAL_ARCHMAGE) + { + if (skill == null) + { + refreshAiParams(attacker, npc, (damage * 1000)); + } + else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.25)) + { + refreshAiParams(attacker, npc, ((damage / 3) * 100)); + } + else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.5)) + { + refreshAiParams(attacker, npc, (damage * 20)); + } + else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.75)) + { + refreshAiParams(attacker, npc, (damage * 10)); + } + else + { + refreshAiParams(attacker, npc, ((damage / 3) * 20)); + } + manageSkills(npc); + } + + return super.onAttack(npc, attacker, damage, isSummon); + } + + private final void refreshAiParams(Creature attacker, Npc npc, int damage) + { + refreshAiParams(attacker, npc, damage, damage); + } + + private final void refreshAiParams(Creature attacker, Npc npc, int damage, int aggro) + { + final int newAggroVal = damage + getRandom(3000); + final int aggroVal = aggro + 1000; + final NpcVariables vars = npc.getVariables(); + for (int i = 0; i < 3; i++) + { + if (attacker == vars.getObject("c_quest" + i, Creature.class)) + { + if (vars.getInt("i_quest" + i) < aggroVal) + { + vars.set("i_quest" + i, newAggroVal); + } + return; + } + } + final int index = CommonUtil.getIndexOfMinValue(vars.getInt("i_quest0"), vars.getInt("i_quest1"), vars.getInt("i_quest2")); + vars.set("i_quest" + index, newAggroVal); + vars.set("c_quest" + index, attacker); + } + + @Override + public String onSpellFinished(Npc npc, PlayerInstance player, Skill skill) + { + startQuestTimer("MANAGE_SKILLS", 1000, npc, null); + + return super.onSpellFinished(npc, player, skill); + } + + private void manageSkills(Npc npc) + { + if (npc.isCastingNow(SkillCaster::isAnyNormalType) || npc.isCoreAIDisabled() || !npc.isInCombat()) + { + return; + } + + final NpcVariables vars = npc.getVariables(); + for (int i = 0; i < 3; i++) + { + final Creature attacker = vars.getObject("c_quest" + i, Creature.class); + if ((attacker == null) || ((npc.calculateDistance3D(attacker) > 9000) || attacker.isDead())) + { + vars.set("i_quest" + i, 0); + } + } + final int index = CommonUtil.getIndexOfMaxValue(vars.getInt("i_quest0"), vars.getInt("i_quest1"), vars.getInt("i_quest2")); + final Creature player = vars.getObject("c_quest" + index, Creature.class); + final int i2 = vars.getInt("i_quest" + index); + if ((i2 > 0) && (getRandom(100) < 70)) + { + vars.set("i_quest" + index, 500); + } + + SkillHolder skillToCast = null; + if ((player != null) && !player.isDead()) + { + if (getRandom(100) < 50) + { + skillToCast = ULTRA_PLASMA_WAVE; + } + else + { + skillToCast = ULTRA_PLASMA_BALL; + } + } + + if ((skillToCast != null) && SkillCaster.checkUseConditions(npc, skillToCast.getSkill())) + + { + npc.setTarget(player); + npc.doCast(skillToCast.getSkill()); + } + } + + public static void main(String[] args) + { + new RoyalArchmageMinion(); + } +}