From 822621c70ee123e879cfa1040f42a6059c02abcf Mon Sep 17 00:00:00 2001 From: MobiusDevelopment <8391001+MobiusDevelopment@users.noreply.github.com> Date: Tue, 11 May 2021 21:41:50 +0000 Subject: [PATCH] Addition of Etis Van Etina solo instance. Contributed by CostyKiller. --- .../game/data/instances/EtisVanEtinaSolo.xml | 196 +++++ .../instances/EtisVanEtinaSolo/34471-01.html | 4 + .../instances/EtisVanEtinaSolo/34471-02.htm | 5 + .../instances/EtisVanEtinaSolo/34471-03.html | 3 + .../instances/EtisVanEtinaSolo/34471.htm | 5 + .../instances/EtisVanEtinaSolo/34472.html | 3 + .../instances/EtisVanEtinaSolo/34473.html | 3 + .../instances/EtisVanEtinaSolo/34474.html | 3 + .../instances/EtisVanEtinaSolo/34475.html | 3 + .../EtisVanEtinaSolo/EtinaHelperAliber.java | 283 +++++++ .../EtisVanEtinaSolo/EtinaHelperDevianne.java | 171 +++++ .../EtisVanEtinaSolo/EtinaHelperElikia.java | 170 ++++ .../EtisVanEtinaSolo/EtinaHelperLeona.java | 203 +++++ .../EtisVanEtinaSolo/EtinaHelperSporcha.java | 170 ++++ .../EtisVanEtinaSolo/EtisVanEtinaSolo.java | 723 ++++++++++++++++++ .../EtisVanEtinaSolo/condNoGroup.html | 3 + .../EtisVanEtinaSolo/condNoLevel.html | 4 + .../dist/game/data/stats/npcs/24100-24199.xml | 121 ++- .../dist/game/data/stats/npcs/26300-26399.xml | 112 ++- .../game/data/instances/EtisVanEtinaSolo.xml | 196 +++++ .../instances/EtisVanEtinaSolo/34471-01.html | 4 + .../instances/EtisVanEtinaSolo/34471-02.htm | 5 + .../instances/EtisVanEtinaSolo/34471-03.html | 3 + .../instances/EtisVanEtinaSolo/34471.htm | 5 + .../instances/EtisVanEtinaSolo/34472.html | 3 + .../instances/EtisVanEtinaSolo/34473.html | 3 + .../instances/EtisVanEtinaSolo/34474.html | 3 + .../instances/EtisVanEtinaSolo/34475.html | 3 + .../EtisVanEtinaSolo/EtinaHelperAliber.java | 283 +++++++ .../EtisVanEtinaSolo/EtinaHelperDevianne.java | 171 +++++ .../EtisVanEtinaSolo/EtinaHelperElikia.java | 170 ++++ .../EtisVanEtinaSolo/EtinaHelperLeona.java | 203 +++++ .../EtisVanEtinaSolo/EtinaHelperSporcha.java | 170 ++++ .../EtisVanEtinaSolo/EtisVanEtinaSolo.java | 723 ++++++++++++++++++ .../EtisVanEtinaSolo/condNoGroup.html | 3 + .../EtisVanEtinaSolo/condNoLevel.html | 4 + .../dist/game/data/stats/npcs/24100-24199.xml | 121 ++- .../dist/game/data/stats/npcs/26300-26399.xml | 112 ++- 38 files changed, 4322 insertions(+), 48 deletions(-) create mode 100644 L2J_Mobius_8.0_Homunculus/dist/game/data/instances/EtisVanEtinaSolo.xml create mode 100644 L2J_Mobius_8.0_Homunculus/dist/game/data/scripts/instances/EtisVanEtinaSolo/34471-01.html create mode 100644 L2J_Mobius_8.0_Homunculus/dist/game/data/scripts/instances/EtisVanEtinaSolo/34471-02.htm create mode 100644 L2J_Mobius_8.0_Homunculus/dist/game/data/scripts/instances/EtisVanEtinaSolo/34471-03.html create mode 100644 L2J_Mobius_8.0_Homunculus/dist/game/data/scripts/instances/EtisVanEtinaSolo/34471.htm create mode 100644 L2J_Mobius_8.0_Homunculus/dist/game/data/scripts/instances/EtisVanEtinaSolo/34472.html create mode 100644 L2J_Mobius_8.0_Homunculus/dist/game/data/scripts/instances/EtisVanEtinaSolo/34473.html create mode 100644 L2J_Mobius_8.0_Homunculus/dist/game/data/scripts/instances/EtisVanEtinaSolo/34474.html create mode 100644 L2J_Mobius_8.0_Homunculus/dist/game/data/scripts/instances/EtisVanEtinaSolo/34475.html create mode 100644 L2J_Mobius_8.0_Homunculus/dist/game/data/scripts/instances/EtisVanEtinaSolo/EtinaHelperAliber.java create mode 100644 L2J_Mobius_8.0_Homunculus/dist/game/data/scripts/instances/EtisVanEtinaSolo/EtinaHelperDevianne.java create mode 100644 L2J_Mobius_8.0_Homunculus/dist/game/data/scripts/instances/EtisVanEtinaSolo/EtinaHelperElikia.java create mode 100644 L2J_Mobius_8.0_Homunculus/dist/game/data/scripts/instances/EtisVanEtinaSolo/EtinaHelperLeona.java create mode 100644 L2J_Mobius_8.0_Homunculus/dist/game/data/scripts/instances/EtisVanEtinaSolo/EtinaHelperSporcha.java create mode 100644 L2J_Mobius_8.0_Homunculus/dist/game/data/scripts/instances/EtisVanEtinaSolo/EtisVanEtinaSolo.java create mode 100644 L2J_Mobius_8.0_Homunculus/dist/game/data/scripts/instances/EtisVanEtinaSolo/condNoGroup.html create mode 100644 L2J_Mobius_8.0_Homunculus/dist/game/data/scripts/instances/EtisVanEtinaSolo/condNoLevel.html create mode 100644 L2J_Mobius_9.0_ReturnOfTheQueenAnt/dist/game/data/instances/EtisVanEtinaSolo.xml create mode 100644 L2J_Mobius_9.0_ReturnOfTheQueenAnt/dist/game/data/scripts/instances/EtisVanEtinaSolo/34471-01.html create mode 100644 L2J_Mobius_9.0_ReturnOfTheQueenAnt/dist/game/data/scripts/instances/EtisVanEtinaSolo/34471-02.htm create mode 100644 L2J_Mobius_9.0_ReturnOfTheQueenAnt/dist/game/data/scripts/instances/EtisVanEtinaSolo/34471-03.html create mode 100644 L2J_Mobius_9.0_ReturnOfTheQueenAnt/dist/game/data/scripts/instances/EtisVanEtinaSolo/34471.htm create mode 100644 L2J_Mobius_9.0_ReturnOfTheQueenAnt/dist/game/data/scripts/instances/EtisVanEtinaSolo/34472.html create mode 100644 L2J_Mobius_9.0_ReturnOfTheQueenAnt/dist/game/data/scripts/instances/EtisVanEtinaSolo/34473.html create mode 100644 L2J_Mobius_9.0_ReturnOfTheQueenAnt/dist/game/data/scripts/instances/EtisVanEtinaSolo/34474.html create mode 100644 L2J_Mobius_9.0_ReturnOfTheQueenAnt/dist/game/data/scripts/instances/EtisVanEtinaSolo/34475.html create mode 100644 L2J_Mobius_9.0_ReturnOfTheQueenAnt/dist/game/data/scripts/instances/EtisVanEtinaSolo/EtinaHelperAliber.java create mode 100644 L2J_Mobius_9.0_ReturnOfTheQueenAnt/dist/game/data/scripts/instances/EtisVanEtinaSolo/EtinaHelperDevianne.java create mode 100644 L2J_Mobius_9.0_ReturnOfTheQueenAnt/dist/game/data/scripts/instances/EtisVanEtinaSolo/EtinaHelperElikia.java create mode 100644 L2J_Mobius_9.0_ReturnOfTheQueenAnt/dist/game/data/scripts/instances/EtisVanEtinaSolo/EtinaHelperLeona.java create mode 100644 L2J_Mobius_9.0_ReturnOfTheQueenAnt/dist/game/data/scripts/instances/EtisVanEtinaSolo/EtinaHelperSporcha.java create mode 100644 L2J_Mobius_9.0_ReturnOfTheQueenAnt/dist/game/data/scripts/instances/EtisVanEtinaSolo/EtisVanEtinaSolo.java create mode 100644 L2J_Mobius_9.0_ReturnOfTheQueenAnt/dist/game/data/scripts/instances/EtisVanEtinaSolo/condNoGroup.html create mode 100644 L2J_Mobius_9.0_ReturnOfTheQueenAnt/dist/game/data/scripts/instances/EtisVanEtinaSolo/condNoLevel.html diff --git a/L2J_Mobius_8.0_Homunculus/dist/game/data/instances/EtisVanEtinaSolo.xml b/L2J_Mobius_8.0_Homunculus/dist/game/data/instances/EtisVanEtinaSolo.xml new file mode 100644 index 0000000000..64f03d23d9 --- /dev/null +++ b/L2J_Mobius_8.0_Homunculus/dist/game/data/instances/EtisVanEtinaSolo.xml @@ -0,0 +1,196 @@ + + + + \ No newline at end of file diff --git a/L2J_Mobius_8.0_Homunculus/dist/game/data/scripts/instances/EtisVanEtinaSolo/34471-01.html b/L2J_Mobius_8.0_Homunculus/dist/game/data/scripts/instances/EtisVanEtinaSolo/34471-01.html new file mode 100644 index 0000000000..3d860da0ab --- /dev/null +++ b/L2J_Mobius_8.0_Homunculus/dist/game/data/scripts/instances/EtisVanEtinaSolo/34471-01.html @@ -0,0 +1,4 @@ +Blackbird Clan Lord Leona Blackbird:
+Let us defeat our enemies.
+Let's go to Etis van Etina, the Head of the Embryo, as fast as we can. + \ No newline at end of file diff --git a/L2J_Mobius_8.0_Homunculus/dist/game/data/scripts/instances/EtisVanEtinaSolo/34471-02.htm b/L2J_Mobius_8.0_Homunculus/dist/game/data/scripts/instances/EtisVanEtinaSolo/34471-02.htm new file mode 100644 index 0000000000..7a02b2ead9 --- /dev/null +++ b/L2J_Mobius_8.0_Homunculus/dist/game/data/scripts/instances/EtisVanEtinaSolo/34471-02.htm @@ -0,0 +1,5 @@ +Blackbird Clan Lord Leona Blackbird:
+Thanks to you, we were able to come this far this time.
+But why is it so quiet? It can't be this empty...
+ + \ No newline at end of file diff --git a/L2J_Mobius_8.0_Homunculus/dist/game/data/scripts/instances/EtisVanEtinaSolo/34471-03.html b/L2J_Mobius_8.0_Homunculus/dist/game/data/scripts/instances/EtisVanEtinaSolo/34471-03.html new file mode 100644 index 0000000000..528abbaadb --- /dev/null +++ b/L2J_Mobius_8.0_Homunculus/dist/game/data/scripts/instances/EtisVanEtinaSolo/34471-03.html @@ -0,0 +1,3 @@ +Blackbird Clan Lord Leona Blackbird:
+You don't have to worry ab- Ah! Oh no! What's that?
+ \ No newline at end of file diff --git a/L2J_Mobius_8.0_Homunculus/dist/game/data/scripts/instances/EtisVanEtinaSolo/34471.htm b/L2J_Mobius_8.0_Homunculus/dist/game/data/scripts/instances/EtisVanEtinaSolo/34471.htm new file mode 100644 index 0000000000..fa5014df9f --- /dev/null +++ b/L2J_Mobius_8.0_Homunculus/dist/game/data/scripts/instances/EtisVanEtinaSolo/34471.htm @@ -0,0 +1,5 @@ +Blackbird Clan Lord Leona Blackbird:
+This is the Great Etina Temple. Setting foot in this place again reminds me of old memories. I used my new power to sneak in so the enemy should be unaware of our presence.
+Now, let's take down the Embryos and Etis van Etina before they even realize. Are you ready?
+ + \ No newline at end of file diff --git a/L2J_Mobius_8.0_Homunculus/dist/game/data/scripts/instances/EtisVanEtinaSolo/34472.html b/L2J_Mobius_8.0_Homunculus/dist/game/data/scripts/instances/EtisVanEtinaSolo/34472.html new file mode 100644 index 0000000000..cbc5604977 --- /dev/null +++ b/L2J_Mobius_8.0_Homunculus/dist/game/data/scripts/instances/EtisVanEtinaSolo/34472.html @@ -0,0 +1,3 @@ +Devianne:
+Behold the power of the Ivory Tower Wizards!
+ \ No newline at end of file diff --git a/L2J_Mobius_8.0_Homunculus/dist/game/data/scripts/instances/EtisVanEtinaSolo/34473.html b/L2J_Mobius_8.0_Homunculus/dist/game/data/scripts/instances/EtisVanEtinaSolo/34473.html new file mode 100644 index 0000000000..eef8b17456 --- /dev/null +++ b/L2J_Mobius_8.0_Homunculus/dist/game/data/scripts/instances/EtisVanEtinaSolo/34473.html @@ -0,0 +1,3 @@ +Elikia:
+Let's take down the Embryos and Etis van Etina before they even realize.
+ \ No newline at end of file diff --git a/L2J_Mobius_8.0_Homunculus/dist/game/data/scripts/instances/EtisVanEtinaSolo/34474.html b/L2J_Mobius_8.0_Homunculus/dist/game/data/scripts/instances/EtisVanEtinaSolo/34474.html new file mode 100644 index 0000000000..9c0807c63a --- /dev/null +++ b/L2J_Mobius_8.0_Homunculus/dist/game/data/scripts/instances/EtisVanEtinaSolo/34474.html @@ -0,0 +1,3 @@ +Sporcha:
+Are you ready to fight?
+ \ No newline at end of file diff --git a/L2J_Mobius_8.0_Homunculus/dist/game/data/scripts/instances/EtisVanEtinaSolo/34475.html b/L2J_Mobius_8.0_Homunculus/dist/game/data/scripts/instances/EtisVanEtinaSolo/34475.html new file mode 100644 index 0000000000..ec99f9f6d0 --- /dev/null +++ b/L2J_Mobius_8.0_Homunculus/dist/game/data/scripts/instances/EtisVanEtinaSolo/34475.html @@ -0,0 +1,3 @@ +Aliber:
+Rage against all that stands in our way!
+ \ No newline at end of file diff --git a/L2J_Mobius_8.0_Homunculus/dist/game/data/scripts/instances/EtisVanEtinaSolo/EtinaHelperAliber.java b/L2J_Mobius_8.0_Homunculus/dist/game/data/scripts/instances/EtisVanEtinaSolo/EtinaHelperAliber.java new file mode 100644 index 0000000000..df86f9ab85 --- /dev/null +++ b/L2J_Mobius_8.0_Homunculus/dist/game/data/scripts/instances/EtisVanEtinaSolo/EtinaHelperAliber.java @@ -0,0 +1,283 @@ +/* + * 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 instances.EtisVanEtinaSolo; + +import org.l2jmobius.commons.util.CommonUtil; +import org.l2jmobius.gameserver.ai.CtrlIntention; +import org.l2jmobius.gameserver.enums.ChatType; +import org.l2jmobius.gameserver.geoengine.GeoEngine; +import org.l2jmobius.gameserver.model.Location; +import org.l2jmobius.gameserver.model.StatSet; +import org.l2jmobius.gameserver.model.World; +import org.l2jmobius.gameserver.model.WorldObject; +import org.l2jmobius.gameserver.model.actor.Creature; +import org.l2jmobius.gameserver.model.actor.Npc; +import org.l2jmobius.gameserver.model.actor.instance.FriendlyNpcInstance; +import org.l2jmobius.gameserver.model.actor.instance.MonsterInstance; +import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; +import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureAttacked; +import org.l2jmobius.gameserver.model.events.impl.instance.OnInstanceStatusChange; +import org.l2jmobius.gameserver.model.holders.SkillHolder; +import org.l2jmobius.gameserver.model.instancezone.Instance; +import org.l2jmobius.gameserver.network.NpcStringId; +import org.l2jmobius.gameserver.network.serverpackets.ExShowScreenMessage; +import org.l2jmobius.gameserver.network.serverpackets.MagicSkillUse; + +import ai.AbstractNpcAI; + +/** + * Etina Helper Aliber AI. + * @author CostyKiller + */ +public class EtinaHelperAliber extends AbstractNpcAI +{ + // NPCs + private static final int ETINA_HELPER_ALIBER = 34475; + // Corridor Mobs + //@formatter:off + private static final int[] CORRIDOR_MOBS_1 = {24173, 24174, 24175, 24176}; + private static final int[] CORRIDOR_MOBS_2 = {24180, 24181, 24182, 24183}; + private static final int[] CORRIDOR_MOBS_3 = {24184, 24185, 24186, 24187, 24188, 24189, 24190, 24191, 24192}; + private static final int[] NOT_ATK_NPCS = + { + 33798, // Common Decoration - Barricade + 19677, // Seal of Gnosis + 19678, // Seal of Strife + 19679, // Seal of Avarice + 19680, // Seal of Punishment + 19681, // Seal of Awakening + 19682, // Seal of Calamity + 19683, // Seal of Destruction + }; + private static final int[] ETINA_HELPERS = + { + 34471, // Leona Blackbird + 34472, // Devianne + 34473, // Elikia + 34474, // Sporcha + 34475, // Aliber + }; + // Skill Cast Locations + private static final Location[] SKILL_CAST_LOCATIONS = + { + new Location(-245751, 182321, 2861, 16612), // First barricade line + new Location(-245751, 184001, 3025, 16612), // Second barricade line + new Location(-245751, 185298, 3031, 16612), // Third barricade line + new Location(-245751, 186612, 3038, 16612), // Fourth barricade line + }; + // Support Npcs Skills + private static final SkillHolder BARRICADE_DESTRUCTION = new SkillHolder(32286, 1); + // Misc + private static final int[] ETINA_SOLO_INSTANCES = + { + 292, // Fall of Etina (Solo) + 293, // Fall of Etina (Solo) + }; + + private EtinaHelperAliber() + { + setCreatureAttackedId(this::onCreatureAttacked, ETINA_HELPER_ALIBER); + addSpellFinishedId(ETINA_HELPER_ALIBER); + addSeeCreatureId(ETINA_HELPER_ALIBER); + setInstanceStatusChangeId(this::onInstanceStatusChange, ETINA_SOLO_INSTANCES); + } + + @Override + public void onTimerEvent(String event, StatSet params, Npc npc, PlayerInstance player) + { + final Instance instance = npc.getInstanceWorld(); + if (instance != null) + { + switch (event) + { + case "CHECK_ACTION": + { + final StatSet npcVars = npc.getVariables(); + final PlayerInstance plr = npcVars.getObject("PLAYER_OBJECT", PlayerInstance.class); + final MonsterInstance monster = getRandomEntry(World.getInstance().getVisibleObjectsInRange(npc, MonsterInstance.class, 2500)); + if (plr != null) + { + final double distance = npc.calculateDistance2D(plr); + if (!npc.isAttackingNow() && !npc.isMoving() && (distance > 250)) + { + final Location loc = new Location(plr.getX(), plr.getY(), plr.getZ() + 50); + final Location randLoc = new Location(loc.getX() + getRandom(-100, 100), loc.getY() + getRandom(-100, 100), loc.getZ()); + if (distance > 600) + { + npc.teleToLocation(loc); + } + else + { + npc.setRunning(); + } + addMoveToDesire(npc, randLoc, 23); + ((FriendlyNpcInstance) npc).setCanReturnToSpawnPoint(false); + } + else if (!npc.isInCombat() || !npc.isAttackingNow() || (npc.getTarget() == null)) + { + WorldObject target = npc.getTarget(); + if (target == null) + { + npc.setTarget(monster); + } + if ((target != null) && !target.isInvul() && target.isTargetable() && GeoEngine.getInstance().canSeeTarget(npc, target) && !CommonUtil.contains(NOT_ATK_NPCS, target.getId()) && !CommonUtil.contains(ETINA_HELPERS, target.getId())) + { + npc.setInvul(true); + npc.setRunning(); + ((FriendlyNpcInstance) npc).setCanReturnToSpawnPoint(false); + addAttackDesire(npc, (Creature) target); + // addSkillCastDesire(npc, target, ALIBER_SPLASH, 23); + // npc.reduceCurrentHp(1, monster, null); + } + } + } + break; + } + case "DESTROY_BARRICADES": + { + final FriendlyNpcInstance _aliber = (FriendlyNpcInstance) instance.getNpc(ETINA_HELPER_ALIBER); + boolean BARRICADE_DESTROYED = instance.getParameters().getBoolean("BARRICADE_DESTROYED", false); + if (!instance.getNpcsOfGroup("BARRICADES_1").isEmpty()) + { + _aliber.setRunning(); + _aliber.setInvul(true); + _aliber.setCanReturnToSpawnPoint(false); + _aliber.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, SKILL_CAST_LOCATIONS[0]); + if (_aliber.getLocation().isIn2DRadius(SKILL_CAST_LOCATIONS[0], 200) && (BARRICADE_DESTROYED == false)) + { + _aliber.broadcastPacket(new MagicSkillUse(_aliber, _aliber, BARRICADE_DESTRUCTION.getSkillId(), 1, 500, 0)); + _aliber.broadcastPacket(new ExShowScreenMessage(NpcStringId.ALIBER_IS_CASTING_A_SPELL_TO_DESTROY_THE_BARRICADE, ExShowScreenMessage.TOP_CENTER, 7000, true)); + instance.getNpcsOfGroup("BARRICADES_1").forEach(barricade -> + { + if (barricade != null) + { + barricade.decayMe(); + } + }); + instance.getParameters().set("BARRICADE_DESTROYED", true); + instance.despawnGroup("BARRICADES_1"); + } + } + else if (!instance.getNpcsOfGroup("BARRICADES_2").isEmpty() && instance.getAliveNpcs(CORRIDOR_MOBS_1).isEmpty() && instance.getNpcsOfGroup("BARRICADES_1").isEmpty()) + { + _aliber.setRunning(); + _aliber.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, SKILL_CAST_LOCATIONS[1]); + if (_aliber.getLocation().isIn2DRadius(SKILL_CAST_LOCATIONS[1], 200) && (BARRICADE_DESTROYED == false)) + { + _aliber.broadcastPacket(new MagicSkillUse(_aliber, _aliber, BARRICADE_DESTRUCTION.getSkillId(), 1, 500, 0)); + _aliber.broadcastPacket(new ExShowScreenMessage(NpcStringId.ALIBER_IS_CASTING_A_SPELL_TO_DESTROY_THE_BARRICADE, ExShowScreenMessage.TOP_CENTER, 7000, true)); + instance.getNpcsOfGroup("BARRICADES_2").forEach(barricade -> + { + if (barricade != null) + { + barricade.decayMe(); + } + }); + instance.getParameters().set("BARRICADE_DESTROYED", true); + instance.despawnGroup("BARRICADES_2"); + } + } + else if (!instance.getNpcsOfGroup("BARRICADES_3").isEmpty() && instance.getAliveNpcs(CORRIDOR_MOBS_2).isEmpty() && instance.getNpcsOfGroup("BARRICADES_2").isEmpty()) + { + _aliber.setRunning(); + _aliber.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, SKILL_CAST_LOCATIONS[2]); + if (_aliber.getLocation().isIn2DRadius(SKILL_CAST_LOCATIONS[2], 200) && (BARRICADE_DESTROYED == false)) + { + _aliber.broadcastPacket(new MagicSkillUse(_aliber, _aliber, BARRICADE_DESTRUCTION.getSkillId(), 1, 500, 0)); + _aliber.broadcastPacket(new ExShowScreenMessage(NpcStringId.ALIBER_IS_CASTING_A_SPELL_TO_DESTROY_THE_BARRICADE, ExShowScreenMessage.TOP_CENTER, 7000, true)); + instance.getNpcsOfGroup("BARRICADES_3").forEach(barricade -> + { + if (barricade != null) + { + barricade.decayMe(); + } + }); + instance.getParameters().set("BARRICADE_DESTROYED", true); + instance.despawnGroup("BARRICADES_3"); + } + } + else if (!instance.getNpcsOfGroup("BARRICADES_4").isEmpty() && instance.getAliveNpcs(CORRIDOR_MOBS_3).isEmpty() && instance.getNpcsOfGroup("BARRICADES_3").isEmpty()) + { + _aliber.setRunning(); + _aliber.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, SKILL_CAST_LOCATIONS[3]); + if (_aliber.getLocation().isIn2DRadius(SKILL_CAST_LOCATIONS[3], 200) && (BARRICADE_DESTROYED == false)) + { + _aliber.broadcastPacket(new MagicSkillUse(_aliber, _aliber, BARRICADE_DESTRUCTION.getSkillId(), 1, 500, 0)); + _aliber.broadcastPacket(new ExShowScreenMessage(NpcStringId.ALIBER_IS_CASTING_A_SPELL_TO_DESTROY_THE_BARRICADE, ExShowScreenMessage.TOP_CENTER, 7000, true)); + instance.getNpcsOfGroup("BARRICADES_4").forEach(barricade -> + { + if (barricade != null) + { + barricade.decayMe(); + } + }); + instance.getParameters().set("BARRICADE_DESTROYED", true); + instance.despawnGroup("BARRICADES_4"); + } + } + } + break; + } + } + } + + public void onCreatureAttacked(OnCreatureAttacked event) + { + final FriendlyNpcInstance npc = (FriendlyNpcInstance) event.getTarget(); + if (npc != null) + { + final Instance instance = npc.getInstanceWorld(); + if ((instance != null) && !event.getAttacker().isPlayable() && !CommonUtil.contains(ETINA_HELPERS, event.getAttacker().getId())) + { + if (!npc.isInCombat()) + { + if (getRandom(50) < 5) + { + npc.broadcastSay(ChatType.NPC_GENERAL, NpcStringId.RAGE_AGAINST_ALL_THAT_STANDS_IN_OUR_WAY); + } + } + } + } + } + + public void onInstanceStatusChange(OnInstanceStatusChange event) + { + final Instance instance = event.getWorld(); + final int status = event.getStatus(); + if ((status == 1) || (status == 2) || (status == 3)) + { + instance.getAliveNpcs(ETINA_HELPER_ALIBER).forEach(etinaHelperAliber -> getTimers().addRepeatingTimer("CHECK_ACTION", 3000, etinaHelperAliber, null)); + instance.getAliveNpcs(ETINA_HELPER_ALIBER).forEach(etinaHelperAliber -> getTimers().addRepeatingTimer("USE_SKILL", 6000, etinaHelperAliber, null)); + instance.getAliveNpcs(ETINA_HELPER_ALIBER).forEach(etinaHelperAliber -> getTimers().addRepeatingTimer("DESTROY_BARRICADES", 5000, etinaHelperAliber, null)); + } + } + + @Override + public String onSeeCreature(Npc npc, Creature creature, boolean isSummon) + { + if (creature.isPlayer()) + { + npc.getVariables().set("PLAYER_OBJECT", creature.getActingPlayer()); + } + return super.onSeeCreature(npc, creature, isSummon); + } + + public static void main(String[] args) + { + new EtinaHelperAliber(); + } +} \ No newline at end of file diff --git a/L2J_Mobius_8.0_Homunculus/dist/game/data/scripts/instances/EtisVanEtinaSolo/EtinaHelperDevianne.java b/L2J_Mobius_8.0_Homunculus/dist/game/data/scripts/instances/EtisVanEtinaSolo/EtinaHelperDevianne.java new file mode 100644 index 0000000000..258d606210 --- /dev/null +++ b/L2J_Mobius_8.0_Homunculus/dist/game/data/scripts/instances/EtisVanEtinaSolo/EtinaHelperDevianne.java @@ -0,0 +1,171 @@ +/* + * 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 instances.EtisVanEtinaSolo; + +import org.l2jmobius.commons.util.CommonUtil; +import org.l2jmobius.gameserver.enums.ChatType; +import org.l2jmobius.gameserver.geoengine.GeoEngine; +import org.l2jmobius.gameserver.model.Location; +import org.l2jmobius.gameserver.model.StatSet; +import org.l2jmobius.gameserver.model.World; +import org.l2jmobius.gameserver.model.WorldObject; +import org.l2jmobius.gameserver.model.actor.Creature; +import org.l2jmobius.gameserver.model.actor.Npc; +import org.l2jmobius.gameserver.model.actor.instance.FriendlyNpcInstance; +import org.l2jmobius.gameserver.model.actor.instance.MonsterInstance; +import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; +import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureAttacked; +import org.l2jmobius.gameserver.model.events.impl.instance.OnInstanceStatusChange; +import org.l2jmobius.gameserver.model.instancezone.Instance; +import org.l2jmobius.gameserver.network.NpcStringId; + +import ai.AbstractNpcAI; + +/** + * Etina Helper Devianne AI. + * @author CostyKiller + */ +public class EtinaHelperDevianne extends AbstractNpcAI +{ + // NPCs + private static final int ETINA_HELPER_DEVIANNE = 34472; + private static final int[] NOT_ATK_NPCS = + { + 33798, // Common Decoration - Barricade + 19677, // Seal of Gnosis + 19678, // Seal of Strife + 19679, // Seal of Avarice + 19680, // Seal of Punishment + 19681, // Seal of Awakening + 19682, // Seal of Calamity + 19683, // Seal of Destruction + }; + private static final int[] ETINA_HELPERS = + { + 34471, // Leona Blackbird + 34472, // Devianne + 34473, // Elikia + 34474, // Sporcha + 34475, // Aliber + }; + // Misc + private static final int[] ETINA_SOLO_INSTANCES = + { + 292, // Fall of Etina (Solo) + 293, // Fall of Etina (Solo) + }; + + private EtinaHelperDevianne() + { + setCreatureAttackedId(this::onCreatureAttacked, ETINA_HELPER_DEVIANNE); + addSpellFinishedId(ETINA_HELPER_DEVIANNE); + addSeeCreatureId(ETINA_HELPER_DEVIANNE); + setInstanceStatusChangeId(this::onInstanceStatusChange, ETINA_SOLO_INSTANCES); + } + + @Override + public void onTimerEvent(String event, StatSet params, Npc npc, PlayerInstance player) + { + final Instance instance = npc.getInstanceWorld(); + if ((instance != null) && event.equals("CHECK_ACTION")) + { + final StatSet npcVars = npc.getVariables(); + final PlayerInstance plr = npcVars.getObject("PLAYER_OBJECT", PlayerInstance.class); + final MonsterInstance monster = getRandomEntry(World.getInstance().getVisibleObjectsInRange(npc, MonsterInstance.class, 2500)); + if (plr != null) + { + final double distance = npc.calculateDistance2D(plr); + if (!npc.isAttackingNow() && !npc.isMoving() && (distance > 250)) + { + final Location loc = new Location(plr.getX(), plr.getY(), plr.getZ() + 50); + final Location randLoc = new Location(loc.getX() + getRandom(-100, 100), loc.getY() + getRandom(-100, 100), loc.getZ()); + if (distance > 600) + { + npc.teleToLocation(loc); + } + else + { + npc.setRunning(); + } + addMoveToDesire(npc, randLoc, 23); + ((FriendlyNpcInstance) npc).setCanReturnToSpawnPoint(false); + } + else if (!npc.isInCombat() || !npc.isAttackingNow() || (npc.getTarget() == null)) + { + WorldObject target = npc.getTarget(); + if (target == null) + { + npc.setTarget(monster); + } + if ((target != null) && !target.isInvul() && target.isTargetable() && GeoEngine.getInstance().canSeeTarget(npc, target) && !CommonUtil.contains(NOT_ATK_NPCS, target.getId()) && !CommonUtil.contains(ETINA_HELPERS, target.getId())) + { + npc.setInvul(true); + npc.setRunning(); + ((FriendlyNpcInstance) npc).setCanReturnToSpawnPoint(false); + addAttackDesire(npc, (Creature) target); + // npc.reduceCurrentHp(1, monster, null); + } + } + } + } + } + + public void onCreatureAttacked(OnCreatureAttacked event) + { + final FriendlyNpcInstance npc = (FriendlyNpcInstance) event.getTarget(); + if (npc != null) + { + final Instance instance = npc.getInstanceWorld(); + if ((instance != null) && !event.getAttacker().isPlayable() && !CommonUtil.contains(ETINA_HELPERS, event.getAttacker().getId())) + { + if (!npc.isInCombat()) + { + if (getRandom(50) < 5) + { + npc.broadcastSay(ChatType.NPC_GENERAL, NpcStringId.BEHOLD_THE_POWER_OF_THE_IVORY_TOWER_WIZARDS); + } + + } + } + } + } + + public void onInstanceStatusChange(OnInstanceStatusChange event) + { + final Instance instance = event.getWorld(); + final int status = event.getStatus(); + if ((status == 1) || (status == 2) || (status == 3)) + { + instance.getAliveNpcs(ETINA_HELPER_DEVIANNE).forEach(etinaHelperDevianne -> getTimers().addRepeatingTimer("CHECK_ACTION", 3000, etinaHelperDevianne, null)); + } + } + + @Override + public String onSeeCreature(Npc npc, Creature creature, boolean isSummon) + { + if (creature.isPlayer()) + { + npc.getVariables().set("PLAYER_OBJECT", creature.getActingPlayer()); + } + return super.onSeeCreature(npc, creature, isSummon); + } + + public static void main(String[] args) + { + new EtinaHelperDevianne(); + } +} \ No newline at end of file diff --git a/L2J_Mobius_8.0_Homunculus/dist/game/data/scripts/instances/EtisVanEtinaSolo/EtinaHelperElikia.java b/L2J_Mobius_8.0_Homunculus/dist/game/data/scripts/instances/EtisVanEtinaSolo/EtinaHelperElikia.java new file mode 100644 index 0000000000..ff41fcd13e --- /dev/null +++ b/L2J_Mobius_8.0_Homunculus/dist/game/data/scripts/instances/EtisVanEtinaSolo/EtinaHelperElikia.java @@ -0,0 +1,170 @@ +/* + * 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 instances.EtisVanEtinaSolo; + +import org.l2jmobius.commons.util.CommonUtil; +import org.l2jmobius.gameserver.enums.ChatType; +import org.l2jmobius.gameserver.geoengine.GeoEngine; +import org.l2jmobius.gameserver.model.Location; +import org.l2jmobius.gameserver.model.StatSet; +import org.l2jmobius.gameserver.model.World; +import org.l2jmobius.gameserver.model.WorldObject; +import org.l2jmobius.gameserver.model.actor.Creature; +import org.l2jmobius.gameserver.model.actor.Npc; +import org.l2jmobius.gameserver.model.actor.instance.FriendlyNpcInstance; +import org.l2jmobius.gameserver.model.actor.instance.MonsterInstance; +import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; +import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureAttacked; +import org.l2jmobius.gameserver.model.events.impl.instance.OnInstanceStatusChange; +import org.l2jmobius.gameserver.model.instancezone.Instance; +import org.l2jmobius.gameserver.network.NpcStringId; + +import ai.AbstractNpcAI; + +/** + * Etina Helper Elikia AI. + * @author CostyKiller + */ +public class EtinaHelperElikia extends AbstractNpcAI +{ + // NPCs + private static final int ETINA_HELPER_ELIKIA = 34473; + private static final int[] NOT_ATK_NPCS = + { + 33798, // Common Decoration - Barricade + 19677, // Seal of Gnosis + 19678, // Seal of Strife + 19679, // Seal of Avarice + 19680, // Seal of Punishment + 19681, // Seal of Awakening + 19682, // Seal of Calamity + 19683, // Seal of Destruction + }; + private static final int[] ETINA_HELPERS = + { + 34471, // Leona Blackbird + 34472, // Devianne + 34473, // Elikia + 34474, // Sporcha + 34475, // Aliber + }; + // Misc + private static final int[] ETINA_SOLO_INSTANCES = + { + 292, // Fall of Etina (Solo) + 293, // Fall of Etina (Solo) + }; + + private EtinaHelperElikia() + { + setCreatureAttackedId(this::onCreatureAttacked, ETINA_HELPER_ELIKIA); + addSpellFinishedId(ETINA_HELPER_ELIKIA); + addSeeCreatureId(ETINA_HELPER_ELIKIA); + setInstanceStatusChangeId(this::onInstanceStatusChange, ETINA_SOLO_INSTANCES); + } + + @Override + public void onTimerEvent(String event, StatSet params, Npc npc, PlayerInstance player) + { + final Instance instance = npc.getInstanceWorld(); + if ((instance != null) && event.equals("CHECK_ACTION")) + { + final StatSet npcVars = npc.getVariables(); + final PlayerInstance plr = npcVars.getObject("PLAYER_OBJECT", PlayerInstance.class); + final MonsterInstance monster = getRandomEntry(World.getInstance().getVisibleObjectsInRange(npc, MonsterInstance.class, 2500)); + if (plr != null) + { + final double distance = npc.calculateDistance2D(plr); + if (!npc.isAttackingNow() && !npc.isMoving() && (distance > 250)) + { + final Location loc = new Location(plr.getX(), plr.getY(), plr.getZ() + 50); + final Location randLoc = new Location(loc.getX() + getRandom(-100, 100), loc.getY() + getRandom(-100, 100), loc.getZ()); + if (distance > 600) + { + npc.teleToLocation(loc); + } + else + { + npc.setRunning(); + } + addMoveToDesire(npc, randLoc, 23); + ((FriendlyNpcInstance) npc).setCanReturnToSpawnPoint(false); + } + else if (!npc.isInCombat() || !npc.isAttackingNow() || (npc.getTarget() == null)) + { + WorldObject target = npc.getTarget(); + if (target == null) + { + npc.setTarget(monster); + } + if ((target != null) && !target.isInvul() && target.isTargetable() && GeoEngine.getInstance().canSeeTarget(npc, target) && !CommonUtil.contains(NOT_ATK_NPCS, target.getId()) && !CommonUtil.contains(ETINA_HELPERS, target.getId())) + { + npc.setInvul(true); + npc.setRunning(); + ((FriendlyNpcInstance) npc).setCanReturnToSpawnPoint(false); + addAttackDesire(npc, (Creature) target); + // npc.reduceCurrentHp(1, monster, null); + } + } + } + } + } + + public void onCreatureAttacked(OnCreatureAttacked event) + { + final FriendlyNpcInstance npc = (FriendlyNpcInstance) event.getTarget(); + if (npc != null) + { + final Instance instance = npc.getInstanceWorld(); + if ((instance != null) && !event.getAttacker().isPlayable() && !CommonUtil.contains(ETINA_HELPERS, event.getAttacker().getId())) + { + if (!npc.isInCombat()) + { + if (getRandom(50) < 5) + { + npc.broadcastSay(ChatType.NPC_GENERAL, NpcStringId.DON_T_GET_IN_MY_WAY); + } + } + } + } + } + + public void onInstanceStatusChange(OnInstanceStatusChange event) + { + final Instance instance = event.getWorld(); + final int status = event.getStatus(); + if ((status == 1) || (status == 2) || (status == 3)) + { + instance.getAliveNpcs(ETINA_HELPER_ELIKIA).forEach(etinaHelperElikia -> getTimers().addRepeatingTimer("CHECK_ACTION", 3000, etinaHelperElikia, null)); + } + } + + @Override + public String onSeeCreature(Npc npc, Creature creature, boolean isSummon) + { + if (creature.isPlayer()) + { + npc.getVariables().set("PLAYER_OBJECT", creature.getActingPlayer()); + } + return super.onSeeCreature(npc, creature, isSummon); + } + + public static void main(String[] args) + { + new EtinaHelperElikia(); + } +} \ No newline at end of file diff --git a/L2J_Mobius_8.0_Homunculus/dist/game/data/scripts/instances/EtisVanEtinaSolo/EtinaHelperLeona.java b/L2J_Mobius_8.0_Homunculus/dist/game/data/scripts/instances/EtisVanEtinaSolo/EtinaHelperLeona.java new file mode 100644 index 0000000000..21f0035a18 --- /dev/null +++ b/L2J_Mobius_8.0_Homunculus/dist/game/data/scripts/instances/EtisVanEtinaSolo/EtinaHelperLeona.java @@ -0,0 +1,203 @@ +/* + * 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 instances.EtisVanEtinaSolo; + +import org.l2jmobius.commons.util.CommonUtil; +import org.l2jmobius.gameserver.enums.ChatType; +import org.l2jmobius.gameserver.geoengine.GeoEngine; +import org.l2jmobius.gameserver.model.Location; +import org.l2jmobius.gameserver.model.StatSet; +import org.l2jmobius.gameserver.model.World; +import org.l2jmobius.gameserver.model.WorldObject; +import org.l2jmobius.gameserver.model.actor.Creature; +import org.l2jmobius.gameserver.model.actor.Npc; +import org.l2jmobius.gameserver.model.actor.instance.FriendlyNpcInstance; +import org.l2jmobius.gameserver.model.actor.instance.MonsterInstance; +import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; +import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureAttacked; +import org.l2jmobius.gameserver.model.events.impl.instance.OnInstanceStatusChange; +import org.l2jmobius.gameserver.model.instancezone.Instance; +import org.l2jmobius.gameserver.network.NpcStringId; + +import ai.AbstractNpcAI; + +/** + * Etina Helper Leona AI. + * @author CostyKiller + */ +public class EtinaHelperLeona extends AbstractNpcAI +{ + // NPCs + private static final int ETINA_HELPER_LEONA = 34471; + private static final int[] NOT_ATK_NPCS = + { + 33798, // Common Decoration - Barricade + 19677, // Seal of Gnosis + 19678, // Seal of Strife + 19679, // Seal of Avarice + 19680, // Seal of Punishment + 19681, // Seal of Awakening + 19682, // Seal of Calamity + 19683, // Seal of Destruction + }; + private static final int[] ETINA_HELPERS = + { + 34471, // Leona Blackbird + 34472, // Devianne + 34473, // Elikia + 34474, // Sporcha + 34475, // Aliber + }; + // RB + private static final int ETIS_VAN_ETINA1 = 26321; + private static final int ETIS_VAN_ETINA2 = 26322; + private static final int KAIN_VAN_HALTER = 26235; + private static final int CAMILLE = 26236; + // Misc + private static final int[] ETINA_SOLO_INSTANCES = + { + 292, // Fall of Etina (Solo) + 293, // Fall of Etina (Solo) + }; + + private EtinaHelperLeona() + { + setCreatureAttackedId(this::onCreatureAttacked, ETINA_HELPER_LEONA); + addSpellFinishedId(ETINA_HELPER_LEONA); + addSeeCreatureId(ETINA_HELPER_LEONA); + setInstanceStatusChangeId(this::onInstanceStatusChange, ETINA_SOLO_INSTANCES); + } + + @Override + public void onTimerEvent(String event, StatSet params, Npc npc, PlayerInstance player) + { + final Instance instance = npc.getInstanceWorld(); + if ((instance != null) && event.equals("CHECK_ACTION")) + { + final StatSet npcVars = npc.getVariables(); + final PlayerInstance plr = npcVars.getObject("PLAYER_OBJECT", PlayerInstance.class); + final MonsterInstance monster = getRandomEntry(World.getInstance().getVisibleObjectsInRange(npc, MonsterInstance.class, 2500)); + if (plr != null) + { + final double distance = npc.calculateDistance2D(plr); + if (!npc.isAttackingNow() && !npc.isMoving() && (distance > 250)) + { + final Location loc = new Location(plr.getX(), plr.getY(), plr.getZ() + 50); + final Location randLoc = new Location(loc.getX() + getRandom(-100, 100), loc.getY() + getRandom(-100, 100), loc.getZ()); + if (distance > 600) + { + npc.teleToLocation(loc); + } + else + { + npc.setRunning(); + } + addMoveToDesire(npc, randLoc, 23); + ((FriendlyNpcInstance) npc).setCanReturnToSpawnPoint(false); + } + else if (!npc.isInCombat() || !npc.isAttackingNow() || (npc.getTarget() == null)) + { + WorldObject target = npc.getTarget(); + if (target == null) + { + npc.setTarget(monster); + } + if ((target != null) && !target.isInvul() && target.isTargetable() && GeoEngine.getInstance().canSeeTarget(npc, target) && !CommonUtil.contains(NOT_ATK_NPCS, target.getId()) && !CommonUtil.contains(ETINA_HELPERS, target.getId())) + { + npc.setInvul(true); + npc.setRunning(); + ((FriendlyNpcInstance) npc).setCanReturnToSpawnPoint(false); + addAttackDesire(npc, (Creature) target); + // npc.reduceCurrentHp(1, monster, null); + } + } + } + } + } + + public void onCreatureAttacked(OnCreatureAttacked event) + { + final FriendlyNpcInstance npc = (FriendlyNpcInstance) event.getTarget(); + final Npc attacker = (Npc) event.getAttacker(); + if (npc != null) + { + final Instance instance = npc.getInstanceWorld(); + if ((instance != null) && !event.getAttacker().isPlayable() && !CommonUtil.contains(ETINA_HELPERS, event.getAttacker().getId())) + { + if (!npc.isInCombat()) + { + switch (attacker.getId()) + { + default: + { + if (getRandom(50) < 5) + { + npc.broadcastSay(ChatType.NPC_GENERAL, NpcStringId.DON_T_GET_IN_MY_WAY); + } + break; + } + case CAMILLE: + { + npc.broadcastSay(ChatType.NPC_GENERAL, NpcStringId.GISELLE_NO_IS_SHE_CAMILLE_IN_THAT_STATE); + break; + } + case KAIN_VAN_HALTER: + { + break; + } + case ETIS_VAN_ETINA1: + { + npc.broadcastSay(ChatType.NPC_GENERAL, NpcStringId.EVEN_THE_MIGHTY_ETINA_SEEMS_TO_FEAR_US); + break; + } + case ETIS_VAN_ETINA2: + { + npc.broadcastSay(ChatType.NPC_GENERAL, NpcStringId.ETIS_VAN_ETINA_WE_FINALLY_MEET); + break; + } + } + } + } + } + } + + public void onInstanceStatusChange(OnInstanceStatusChange event) + { + final Instance instance = event.getWorld(); + final int status = event.getStatus(); + if ((status == 1) || (status == 2) || (status == 3)) + { + instance.getAliveNpcs(ETINA_HELPER_LEONA).forEach(etinaHelperLeona -> getTimers().addRepeatingTimer("CHECK_ACTION", 3000, etinaHelperLeona, null)); + // instance.getAliveNpcs(ETINA_HELPER_LEONA).forEach(etinaHelperLeona -> getTimers().addRepeatingTimer("USE_SKILL", 6000, etinaHelperLeona, null)); + } + } + + @Override + public String onSeeCreature(Npc npc, Creature creature, boolean isSummon) + { + if (creature.isPlayer()) + { + npc.getVariables().set("PLAYER_OBJECT", creature.getActingPlayer()); + } + return super.onSeeCreature(npc, creature, isSummon); + } + + public static void main(String[] args) + { + new EtinaHelperLeona(); + } +} \ No newline at end of file diff --git a/L2J_Mobius_8.0_Homunculus/dist/game/data/scripts/instances/EtisVanEtinaSolo/EtinaHelperSporcha.java b/L2J_Mobius_8.0_Homunculus/dist/game/data/scripts/instances/EtisVanEtinaSolo/EtinaHelperSporcha.java new file mode 100644 index 0000000000..929fbe07ce --- /dev/null +++ b/L2J_Mobius_8.0_Homunculus/dist/game/data/scripts/instances/EtisVanEtinaSolo/EtinaHelperSporcha.java @@ -0,0 +1,170 @@ +/* + * 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 instances.EtisVanEtinaSolo; + +import org.l2jmobius.commons.util.CommonUtil; +import org.l2jmobius.gameserver.enums.ChatType; +import org.l2jmobius.gameserver.geoengine.GeoEngine; +import org.l2jmobius.gameserver.model.Location; +import org.l2jmobius.gameserver.model.StatSet; +import org.l2jmobius.gameserver.model.World; +import org.l2jmobius.gameserver.model.WorldObject; +import org.l2jmobius.gameserver.model.actor.Creature; +import org.l2jmobius.gameserver.model.actor.Npc; +import org.l2jmobius.gameserver.model.actor.instance.FriendlyNpcInstance; +import org.l2jmobius.gameserver.model.actor.instance.MonsterInstance; +import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; +import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureAttacked; +import org.l2jmobius.gameserver.model.events.impl.instance.OnInstanceStatusChange; +import org.l2jmobius.gameserver.model.instancezone.Instance; +import org.l2jmobius.gameserver.network.NpcStringId; + +import ai.AbstractNpcAI; + +/** + * Etina Helper Sporcha AI. + * @author CostyKiller + */ +public class EtinaHelperSporcha extends AbstractNpcAI +{ + // NPCs + private static final int ETINA_HELPER_SPORCHA = 34474; + private static final int[] NOT_ATK_NPCS = + { + 33798, // Common Decoration - Barricade + 19677, // Seal of Gnosis + 19678, // Seal of Strife + 19679, // Seal of Avarice + 19680, // Seal of Punishment + 19681, // Seal of Awakening + 19682, // Seal of Calamity + 19683, // Seal of Destruction + }; + private static final int[] ETINA_HELPERS = + { + 34471, // Leona Blackbird + 34472, // Devianne + 34473, // Elikia + 34474, // Sporcha + 34475, // Aliber + }; + // Misc + private static final int[] ETINA_SOLO_INSTANCES = + { + 292, // Fall of Etina (Solo) + 293, // Fall of Etina (Solo) + }; + + private EtinaHelperSporcha() + { + setCreatureAttackedId(this::onCreatureAttacked, ETINA_HELPER_SPORCHA); + addSpellFinishedId(ETINA_HELPER_SPORCHA); + addSeeCreatureId(ETINA_HELPER_SPORCHA); + setInstanceStatusChangeId(this::onInstanceStatusChange, ETINA_SOLO_INSTANCES); + } + + @Override + public void onTimerEvent(String event, StatSet params, Npc npc, PlayerInstance player) + { + final Instance instance = npc.getInstanceWorld(); + if ((instance != null) && event.equals("CHECK_ACTION")) + { + final StatSet npcVars = npc.getVariables(); + final PlayerInstance plr = npcVars.getObject("PLAYER_OBJECT", PlayerInstance.class); + final MonsterInstance monster = getRandomEntry(World.getInstance().getVisibleObjectsInRange(npc, MonsterInstance.class, 2500)); + if (plr != null) + { + final double distance = npc.calculateDistance2D(plr); + if (!npc.isAttackingNow() && !npc.isMoving() && (distance > 250)) + { + final Location loc = new Location(plr.getX(), plr.getY(), plr.getZ() + 50); + final Location randLoc = new Location(loc.getX() + getRandom(-100, 100), loc.getY() + getRandom(-100, 100), loc.getZ()); + if (distance > 600) + { + npc.teleToLocation(loc); + } + else + { + npc.setRunning(); + } + addMoveToDesire(npc, randLoc, 23); + ((FriendlyNpcInstance) npc).setCanReturnToSpawnPoint(false); + } + else if (!npc.isInCombat() || !npc.isAttackingNow() || (npc.getTarget() == null)) + { + WorldObject target = npc.getTarget(); + if (target == null) + { + npc.setTarget(monster); + } + if ((target != null) && !target.isInvul() && target.isTargetable() && GeoEngine.getInstance().canSeeTarget(npc, target) && !CommonUtil.contains(NOT_ATK_NPCS, target.getId()) && !CommonUtil.contains(ETINA_HELPERS, target.getId())) + { + npc.setInvul(true); + npc.setRunning(); + ((FriendlyNpcInstance) npc).setCanReturnToSpawnPoint(false); + addAttackDesire(npc, (Creature) target); + // npc.reduceCurrentHp(1, monster, null); + } + } + } + } + } + + public void onCreatureAttacked(OnCreatureAttacked event) + { + final FriendlyNpcInstance npc = (FriendlyNpcInstance) event.getTarget(); + if (npc != null) + { + final Instance instance = npc.getInstanceWorld(); + if ((instance != null) && !event.getAttacker().isPlayable() && !CommonUtil.contains(ETINA_HELPERS, event.getAttacker().getId())) + { + if (!npc.isInCombat()) + { + if (getRandom(50) < 5) + { + npc.broadcastSay(ChatType.NPC_GENERAL, NpcStringId.DON_T_GET_IN_MY_WAY); + } + } + } + } + } + + public void onInstanceStatusChange(OnInstanceStatusChange event) + { + final Instance instance = event.getWorld(); + final int status = event.getStatus(); + if ((status == 1) || (status == 2) || (status == 3)) + { + instance.getAliveNpcs(ETINA_HELPER_SPORCHA).forEach(etinaHelperSporcha -> getTimers().addRepeatingTimer("CHECK_ACTION", 3000, etinaHelperSporcha, null)); + } + } + + @Override + public String onSeeCreature(Npc npc, Creature creature, boolean isSummon) + { + if (creature.isPlayer()) + { + npc.getVariables().set("PLAYER_OBJECT", creature.getActingPlayer()); + } + return super.onSeeCreature(npc, creature, isSummon); + } + + public static void main(String[] args) + { + new EtinaHelperSporcha(); + } +} \ No newline at end of file diff --git a/L2J_Mobius_8.0_Homunculus/dist/game/data/scripts/instances/EtisVanEtinaSolo/EtisVanEtinaSolo.java b/L2J_Mobius_8.0_Homunculus/dist/game/data/scripts/instances/EtisVanEtinaSolo/EtisVanEtinaSolo.java new file mode 100644 index 0000000000..8f1db0d8d6 --- /dev/null +++ b/L2J_Mobius_8.0_Homunculus/dist/game/data/scripts/instances/EtisVanEtinaSolo/EtisVanEtinaSolo.java @@ -0,0 +1,723 @@ +/* + * 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 instances.EtisVanEtinaSolo; + +import org.l2jmobius.commons.util.CommonUtil; +import org.l2jmobius.gameserver.enums.ChatType; +import org.l2jmobius.gameserver.enums.Movie; +import org.l2jmobius.gameserver.model.World; +import org.l2jmobius.gameserver.model.actor.Attackable; +import org.l2jmobius.gameserver.model.actor.Npc; +import org.l2jmobius.gameserver.model.actor.instance.MonsterInstance; +import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; +import org.l2jmobius.gameserver.model.holders.SkillHolder; +import org.l2jmobius.gameserver.model.instancezone.Instance; +import org.l2jmobius.gameserver.model.skills.AbnormalVisualEffect; +import org.l2jmobius.gameserver.network.NpcStringId; +import org.l2jmobius.gameserver.network.serverpackets.ExShowScreenMessage; +import org.l2jmobius.gameserver.network.serverpackets.MagicSkillUse; + +import instances.AbstractInstance; + +/** + * @author CostyKiller + * @URL: https://l2wiki.com/Fall_of_Etina_(Solo) + * @URL: https://youtu.be/3flFpg0KGcA + * @TODO: Add helper npcs skills + * @TODO: Add instance buff Elikia Emblem + */ +public class EtisVanEtinaSolo extends AbstractInstance +{ + // NPC + private static final int LEONA_OUTLET = 34426; + private static final int LEONA_BLACKBIRD = 34471; + private static final int DEVIANNE = 34472; + private static final int ELIKIA = 34473; + private static final int SPORCHA = 34474; + private static final int ALIBER = 34475; + // RB + private static final int ETIS_VAN_ETINA1 = 26321; + private static final int ETIS_VAN_ETINA2 = 26322; + private static final int KAIN_VAN_HALTER = 26235; + private static final int CAMILLE = 26236; + // Corridor Mobs + //@formatter:off + private static final int[] CORRIDOR_MOBS_1 = {24173, 24174, 24175, 24176}; + private static final int[] CORRIDOR_MOBS_2 = {24180, 24181, 24182, 24183}; + private static final int[] CORRIDOR_MOBS_3 = {24184, 24185, 24186, 24187, 24188, 24189, 24190, 24191, 24192}; + private static final int[] CORRIDOR_MOBS_4 = {24189, 24190, 24191, 24192}; + //@formatter:on + private static final int PARAGON = 24193; + // Seals + private static final int SEAL_OF_GNOSIS = 19677; + private static final int SEAL_OF_STRIFE = 19678; + private static final int SEAL_OF_AVARICE = 19679; + private static final int SEAL_OF_PUNISHMENT = 19680; + private static final int SEAL_OF_AWAKENING = 19681; + private static final int SEAL_OF_CALAMITY = 19682; + private static final int SEAL_OF_DESTRUCTION = 19683; + // Others + private static final int DOOR1 = 12230702; + private static final int DOOR2 = 12230704; + private static final int DOOR3 = 12230802; + private static final int DOOR4 = 12230804; + // Skills + private static final SkillHolder CALL_OF_SEVEN_SIGNS = new SkillHolder(32317, 1); + private static final SkillHolder CALL_OF_SEVEN_SIGNS_SEAL_N = new SkillHolder(32004, 1); + private static final SkillHolder ETINA_REVELATION = new SkillHolder(32014, 2); + private static final SkillHolder STIGMA_OF_REVELATION = new SkillHolder(32015, 1); + private static final SkillHolder CRY_OF_HOLY_WAR = new SkillHolder(32017, 2); + private static final SkillHolder STIGMA_OF_MARTYR = new SkillHolder(32018, 1); + private static final SkillHolder UNDEAD_CREATURE = new SkillHolder(32020, 2); + private static final SkillHolder ETINA_DIVINE_PUNISHMENT = new SkillHolder(32023, 2); + private static final SkillHolder ETINA_OBSERVATION = new SkillHolder(32024, 2); + private static final SkillHolder RAGE_OF_THE_OPEN_EYE = new SkillHolder(32026, 2); + + // Camille -> Horseshoe Trampling, Horizon Bash, Joust Lunge, Call of Etina (summon minions?) + // Misc + private static final int TEMPLATE_ID = 293; + + public EtisVanEtinaSolo() + { + super(TEMPLATE_ID); + addInstanceCreatedId(TEMPLATE_ID); + addStartNpc(LEONA_OUTLET); + addTalkId(LEONA_OUTLET, LEONA_BLACKBIRD); + addFirstTalkId(LEONA_BLACKBIRD, DEVIANNE, ELIKIA, SPORCHA, ALIBER); + addAttackId(CORRIDOR_MOBS_1); + addAttackId(CORRIDOR_MOBS_2); + addAttackId(CORRIDOR_MOBS_3); + addAttackId(CORRIDOR_MOBS_4); + addAttackId(CAMILLE, KAIN_VAN_HALTER, ETIS_VAN_ETINA1, ETIS_VAN_ETINA2); + addKillId(CORRIDOR_MOBS_1); + addKillId(CORRIDOR_MOBS_2); + addKillId(CORRIDOR_MOBS_3); + addKillId(CORRIDOR_MOBS_4); + addKillId(PARAGON, CAMILLE, KAIN_VAN_HALTER, ETIS_VAN_ETINA1, ETIS_VAN_ETINA2); + } + + @Override + public void onInstanceCreated(Instance world, PlayerInstance player) + { + world.setStatus(0); + world.getParameters().set("BARRICADE_DESTROYED", false); + world.getParameters().set("CORRIDOR_MOBS_1_SPAWNED", false); + world.getParameters().set("CORRIDOR_MOBS_2_SPAWNED", false); + world.getParameters().set("CORRIDOR_MOBS_3_SPAWNED", false); + world.getParameters().set("CORRIDOR_MOBS_4_SPAWNED", false); + world.getParameters().set("CAMILLE_30", false); + world.getParameters().set("CAMILLE_60", false); + world.getParameters().set("KAIN_30", false); + world.getParameters().set("KAIN_60", false); + world.getParameters().set("ETINA_80", false); + world.getParameters().set("ETINA_15", false); + } + + @Override + public String onAdvEvent(String event, Npc npc, PlayerInstance player) + { + switch (event) + { + case "enterInstance": + { + playMovie(player, Movie.EP5_ETINA_QST_START_A); + startQuestTimer("enterEtina", 20000, npc, player); + startQuestTimer("intro_movie", 20000, npc, player); + startQuestTimer("talkLeona", 25000, npc, player); + break; + } + case "enterEtina": + { + enterInstance(player, npc, TEMPLATE_ID); + break; + } + case "intro_movie": + { + final Instance world = player.getInstanceWorld(); + if (isInInstance(world)) + { + playMovie(world.getPlayers(), Movie.EP5_ETINA_QST_START_B); + } + break; + } + case "talkLeona": + { + final Instance world = player.getInstanceWorld(); + if (isInInstance(world)) + { + showOnScreenMsg(world, NpcStringId.TALK_TO_LEONA_BLACKBIRD_13, ExShowScreenMessage.TOP_CENTER, 10000, true); + } + break; + } + case "startStage1": + { + final Instance world = player.getInstanceWorld(); + if (isInInstance(world)) + { + showOnScreenMsg(world, NpcStringId.ALRIGHT_LET_S_GO_DEFEAT_ETIS_VAN_ETINA, ExShowScreenMessage.TOP_CENTER, 7000, true); + startQuestTimer("checkProgress", 5000, npc, player, true); + world.setStatus(1); + return "34471-01.html"; + } + break; + } + case "checkProgress": + { + final Instance world = player.getInstanceWorld(); + boolean CORRIDOR_MOBS_1_SPAWNED = world.getParameters().getBoolean("CORRIDOR_MOBS_1_SPAWNED", false); + boolean CORRIDOR_MOBS_2_SPAWNED = world.getParameters().getBoolean("CORRIDOR_MOBS_2_SPAWNED", false); + boolean CORRIDOR_MOBS_3_SPAWNED = world.getParameters().getBoolean("CORRIDOR_MOBS_3_SPAWNED", false); + boolean CORRIDOR_MOBS_4_SPAWNED = world.getParameters().getBoolean("CORRIDOR_MOBS_4_SPAWNED", false); + if (isInInstance(world)) + { + final MonsterInstance monsterCheck = getRandomEntry(World.getInstance().getVisibleObjectsInRange(npc, MonsterInstance.class, 2500)); + if (monsterCheck == null) + { + if (!world.getNpcsOfGroup("BARRICADES_2").isEmpty() && world.getAliveNpcs(CORRIDOR_MOBS_1).isEmpty() && world.getNpcsOfGroup("BARRICADES_1").isEmpty()) + { + world.getParameters().set("BARRICADE_DESTROYED", false); + } + else if (!world.getNpcsOfGroup("BARRICADES_3").isEmpty() && world.getAliveNpcs(CORRIDOR_MOBS_2).isEmpty() && world.getNpcsOfGroup("BARRICADES_2").isEmpty()) + { + world.getParameters().set("BARRICADE_DESTROYED", false); + } + else if (!world.getNpcsOfGroup("BARRICADES_4").isEmpty() && world.getAliveNpcs(CORRIDOR_MOBS_3).isEmpty() && world.getNpcsOfGroup("BARRICADES_3").isEmpty()) + { + world.getParameters().set("BARRICADE_DESTROYED", false); + } + } + if (!CORRIDOR_MOBS_1_SPAWNED && world.getNpcsOfGroup("BARRICADES_1").isEmpty() && !world.getNpcsOfGroup("BARRICADES_2").isEmpty() && world.getAliveNpcs(CORRIDOR_MOBS_1).isEmpty()) + { + world.spawnGroup("CORRIDOR_MOBS_1"); + world.getNpcsOfGroup("CORRIDOR_MOBS_1").forEach(mob -> + { + if (mob != null) + { + mob.setRandomWalking(false); + } + }); + world.getParameters().set("CORRIDOR_MOBS_1_SPAWNED", true); + } + if (!CORRIDOR_MOBS_2_SPAWNED && world.getNpcsOfGroup("BARRICADES_2").isEmpty() && !world.getNpcsOfGroup("BARRICADES_3").isEmpty() && world.getAliveNpcs(CORRIDOR_MOBS_2).isEmpty()) + { + world.spawnGroup("CORRIDOR_MOBS_2"); + world.getNpcsOfGroup("CORRIDOR_MOBS_2").forEach(mob -> + { + if (mob != null) + { + mob.setRandomWalking(false); + } + }); + world.getParameters().set("CORRIDOR_MOBS_2_SPAWNED", true); + } + if (!CORRIDOR_MOBS_3_SPAWNED && world.getNpcsOfGroup("BARRICADES_3").isEmpty() && !world.getNpcsOfGroup("BARRICADES_4").isEmpty() && world.getAliveNpcs(CORRIDOR_MOBS_3).isEmpty()) + { + world.spawnGroup("CORRIDOR_MOBS_3"); + world.getNpcsOfGroup("CORRIDOR_MOBS_3").forEach(mob -> + { + if (mob != null) + { + mob.setRandomWalking(false); + } + }); + world.getParameters().set("CORRIDOR_MOBS_3_SPAWNED", true); + } + if (!CORRIDOR_MOBS_4_SPAWNED && world.getNpcsOfGroup("BARRICADES_4").isEmpty() && world.getAliveNpcs(CORRIDOR_MOBS_4).isEmpty()) + { + world.spawnGroup("CORRIDOR_MOBS_4"); + world.spawnGroup("PARAGON"); + world.getParameters().set("CORRIDOR_MOBS_4_SPAWNED", true); + world.getNpcsOfGroup("CORRIDOR_MOBS_4").forEach(mob -> + { + if (mob != null) + { + mob.setRandomWalking(false); + } + }); + if (world.getNpc(PARAGON) != null) + { + world.getNpc(PARAGON).setInvul(true); + world.getNpc(PARAGON).getEffectList().startAbnormalVisualEffect(AbnormalVisualEffect.INVINCIBILITY); + } + npc.broadcastPacket(new ExShowScreenMessage(NpcStringId.YOU_CAN_T_DEFEAT_PARAGON_WHILE_PARAGON_S_MINIONS_ARE_ALIVE, ExShowScreenMessage.TOP_CENTER, 7000, true)); + } + if (world.getNpcsOfGroup("BARRICADES_4").isEmpty() && world.getAliveNpcs(CORRIDOR_MOBS_4).isEmpty()) + { + if ((world.getNpc(PARAGON) != null) && world.getNpc(PARAGON).isInvul()) + { + world.getNpc(PARAGON).setInvul(false); + world.getNpc(PARAGON).getEffectList().stopAbnormalVisualEffect(AbnormalVisualEffect.INVINCIBILITY); + showOnScreenMsg(world, NpcStringId.PARAGON_IS_NO_LONGER_INVINCIBLE, ExShowScreenMessage.TOP_CENTER, 7000, true); + world.getNpc(LEONA_BLACKBIRD).broadcastSay(ChatType.NPC_GENERAL, NpcStringId.TODAY_IS_THE_DAY_THAT_I_WILL_ENTER); + } + } + if ((world.getStatus() == 1) && world.getNpcsOfGroup("BARRICADES_4").isEmpty() && (world.getAliveNpcs(PARAGON).isEmpty())) + { + startQuestTimer("openInnerDoors", 5000, null, player); + cancelQuestTimer("checkProgress", npc, player); + } + } + break; + } + case "openInnerDoors": + { + final Instance world = player.getInstanceWorld(); + if (isInInstance(world)) + { + openDoor(DOOR1, world.getId()); + openDoor(DOOR2, world.getId()); + openDoor(DOOR3, world.getId()); + openDoor(DOOR4, world.getId()); + world.setStatus(2); + startQuestTimer("talkLeona", 5000, null, player); + } + break; + } + case "startStage2": + { + final Instance world = player.getInstanceWorld(); + if (isInInstance(world)) + { + startQuestTimer("show_intro_movie_camille", 5000, null, player); + return "34471-03.html"; + } + break; + } + case "show_intro_movie_camille": + { + final Instance world = player.getInstanceWorld(); + if (isInInstance(world)) + { + playMovie(world.getPlayers(), Movie.SC_INZONE_CAMILLE_INTRO); + startQuestTimer("spawn_camille", 5000, null, player); + } + break; + } + case "spawn_camille": + { + final Instance world = player.getInstanceWorld(); + if (isInInstance(world)) + { + closeDoor(DOOR1, world.getId()); + closeDoor(DOOR2, world.getId()); + closeDoor(DOOR3, world.getId()); + closeDoor(DOOR4, world.getId()); + world.setStatus(3); + world.spawnGroup("CAMILLE"); + world.getNpc(LEONA_BLACKBIRD).broadcastSay(ChatType.NPC_GENERAL, NpcStringId.GISELLE_NO_IS_SHE_CAMILLE_IN_THAT_STATE); + } + break; + } + case "spawn_kain": + { + final Instance world = player.getInstanceWorld(); + if (isInInstance(world)) + { + world.spawnGroup("KAIN"); + world.spawnGroup("ETINA_1"); + world.getNpc(ETIS_VAN_ETINA1).setInvul(true); + world.getNpc(ETIS_VAN_ETINA1).setTargetable(false); + world.getNpc(ETIS_VAN_ETINA1).setImmobilized(true); + showOnScreenMsg(world, NpcStringId.ETIS_VAN_ETINA_AND_HIS_APOSTLES_HAVE_APPEARED, ExShowScreenMessage.TOP_CENTER, 7000, true); + world.getNpc(LEONA_BLACKBIRD).broadcastSay(ChatType.NPC_GENERAL, NpcStringId.EVEN_THE_MIGHTY_ETINA_SEEMS_TO_FEAR_US); + } + break; + } + case "spawnTransformedEtina": + { + final Instance world = player.getInstanceWorld(); + if (isInInstance(world)) + { + world.spawnGroup("ETINA_2"); + world.spawnGroup("ETINA_MINIONS"); + world.getNpc(LEONA_BLACKBIRD).broadcastSay(ChatType.NPC_GENERAL, NpcStringId.ETIS_VAN_ETINA_WE_FINALLY_MEET); + } + break; + } + case "gnosisCastTimer": + { + final Instance world = player.getInstanceWorld(); + if (isInInstance(world)) + { + final Npc _sealOfGnosis = world.getNpc(SEAL_OF_GNOSIS); + _sealOfGnosis.setDisplayEffect(3); + _sealOfGnosis.broadcastPacket(new MagicSkillUse(_sealOfGnosis, _sealOfGnosis, CALL_OF_SEVEN_SIGNS_SEAL_N.getSkillId(), 1, 10000, 0)); + PlayerInstance member = world.getPlayers().stream().findAny().get(); + STIGMA_OF_REVELATION.getSkill().applyEffects(member, member); + world.getNpcsOfGroup("ETINA_MINIONS").forEach(minion -> + { + if (minion != null) + { + ETINA_REVELATION.getSkill().applyEffects(minion, minion); + ((Attackable) minion).addDamageHate(member, 0, 999999999); + } + }); + showOnScreenMsg(world, NpcStringId.THE_SEAL_OF_GNOSIS_ACTIVATES_AND_ENORMOUS_POWER_BEGINS_TO_FLOW_OUT, ExShowScreenMessage.TOP_CENTER, 7000, true); + } + break; + } + case "strifeCastTimer": + { + final Instance world = player.getInstanceWorld(); + if (isInInstance(world)) + { + final Npc _sealOfStrife = world.getNpc(SEAL_OF_STRIFE); + _sealOfStrife.setDisplayEffect(3); + _sealOfStrife.broadcastPacket(new MagicSkillUse(_sealOfStrife, _sealOfStrife, CALL_OF_SEVEN_SIGNS_SEAL_N.getSkillId(), 2, 10000, 0)); + world.getNpcsOfGroup("ETINA_MINIONS").forEach(minion -> + { + if (minion != null) + { + CRY_OF_HOLY_WAR.getSkill().applyEffects(minion, minion); + } + }); + world.getPlayers().forEach(plr -> STIGMA_OF_MARTYR.getSkill().applyEffects(player, player)); + showOnScreenMsg(world, NpcStringId.THE_SEAL_OF_STRIFE_ACTIVATES_AND_ENORMOUS_POWER_BEGINS_TO_FLOW_OUT, ExShowScreenMessage.TOP_CENTER, 7000, true); + } + break; + } + case "avariceCastTimer": + { + final Instance world = player.getInstanceWorld(); + if (isInInstance(world)) + { + final Npc _sealOfAvarice = world.getNpc(SEAL_OF_AVARICE); + _sealOfAvarice.setDisplayEffect(3); + _sealOfAvarice.broadcastPacket(new MagicSkillUse(_sealOfAvarice, _sealOfAvarice, CALL_OF_SEVEN_SIGNS_SEAL_N.getSkillId(), 3, 10000, 0)); + world.getNpcsOfGroup("ETINA_MINIONS").forEach(minion -> + { + if (minion != null) + { + UNDEAD_CREATURE.getSkill().applyEffects(minion, minion); + } + }); + showOnScreenMsg(world, NpcStringId.THE_SEAL_OF_AVARICE_ACTIVATES_AND_ENORMOUS_POWER_BEGINS_TO_FLOW_OUT, ExShowScreenMessage.TOP_CENTER, 7000, true); + } + break; + } + case "punishmentCastTimer": + { + final Instance world = player.getInstanceWorld(); + if (isInInstance(world)) + { + final Npc _sealOfPunishment = world.getNpc(SEAL_OF_PUNISHMENT); + _sealOfPunishment.setDisplayEffect(3); + _sealOfPunishment.broadcastPacket(new MagicSkillUse(_sealOfPunishment, _sealOfPunishment, CALL_OF_SEVEN_SIGNS_SEAL_N.getSkillId(), 4, 10000, 0)); + world.getNpcsOfGroup("ETINA_MINIONS").forEach(minion -> + { + if (minion != null) + { + ETINA_DIVINE_PUNISHMENT.getSkill().applyEffects(minion, minion); + } + }); + world.getPlayers().forEach(plr -> ETINA_OBSERVATION.getSkill().applyEffects(player, player)); + showOnScreenMsg(world, NpcStringId.THE_SEAL_OF_PUNISHMENT_ACTIVATES_AND_ENORMOUS_POWER_BEGINS_TO_FLOW_OUT, ExShowScreenMessage.TOP_CENTER, 7000, true); + } + break; + } + case "awakeningCastTimer": + { + final Instance world = player.getInstanceWorld(); + if (isInInstance(world)) + { + final Npc _sealOfAwakening = world.getNpc(SEAL_OF_AWAKENING); + _sealOfAwakening.setDisplayEffect(3); + _sealOfAwakening.broadcastPacket(new MagicSkillUse(_sealOfAwakening, _sealOfAwakening, CALL_OF_SEVEN_SIGNS_SEAL_N.getSkillId(), 5, 10000, 0)); + world.getNpcsOfGroup("ETINA_MINIONS").forEach(minion -> + { + if (minion != null) + { + RAGE_OF_THE_OPEN_EYE.getSkill().applyEffects(minion, minion); + } + }); + showOnScreenMsg(world, NpcStringId.THE_SEAL_OF_AWAKENING_ACTIVATES_AND_ENORMOUS_POWER_BEGINS_TO_FLOW_OUT, ExShowScreenMessage.TOP_CENTER, 7000, true); + } + break; + } + case "calamityCastTimer": + { + final Instance world = player.getInstanceWorld(); + if (isInInstance(world)) + { + final Npc _sealOfCalamity = world.getNpc(SEAL_OF_CALAMITY); + _sealOfCalamity.setDisplayEffect(3); + _sealOfCalamity.broadcastPacket(new MagicSkillUse(_sealOfCalamity, _sealOfCalamity, CALL_OF_SEVEN_SIGNS_SEAL_N.getSkillId(), 6, 10000, 0)); + showOnScreenMsg(world, NpcStringId.THE_SEAL_OF_CALAMITY_ACTIVATES_AND_ENORMOUS_POWER_BEGINS_TO_FLOW_OUT, ExShowScreenMessage.TOP_CENTER, 7000, true); + } + break; + } + case "destructionCastTimer": + { + final Instance world = player.getInstanceWorld(); + if (isInInstance(world)) + { + final Npc _sealOfDestruction = world.getNpc(SEAL_OF_DESTRUCTION); + _sealOfDestruction.setDisplayEffect(3); + _sealOfDestruction.broadcastPacket(new MagicSkillUse(_sealOfDestruction, _sealOfDestruction, CALL_OF_SEVEN_SIGNS_SEAL_N.getSkillId(), 7, 10000, 0)); + showOnScreenMsg(world, NpcStringId.THE_SEAL_OF_DESTRUCTION_IS_ACTIVATED_AND_ETINA_S_GRAND_TEMPLE_IS_NOW_UNDER_ITS_INFLUENCE, ExShowScreenMessage.TOP_CENTER, 7000, true); + } + break; + } + } + return super.onAdvEvent(event, npc, player); + } + + @Override + public String onAttack(Npc npc, PlayerInstance attacker, int damage, boolean isSummon) + { + final Instance world = attacker.getInstanceWorld(); + if (isInInstance(world)) + { + final boolean CAMILLE_30 = world.getParameters().getBoolean("CAMILLE_30", false); + final boolean CAMILLE_60 = world.getParameters().getBoolean("CAMILLE_60", false); + final boolean KAIN_30 = world.getParameters().getBoolean("KAIN_30", false); + final boolean KAIN_60 = world.getParameters().getBoolean("KAIN_60", false); + final boolean ETINA_80 = world.getParameters().getBoolean("ETINA_80", false); + final boolean ETINA_15 = world.getParameters().getBoolean("ETINA_15", false); + if (npc.getId() == CAMILLE) + { + if ((npc.getCurrentHp() <= (npc.getMaxHp() * 0.3)) && !CAMILLE_30) + { + world.getParameters().set("CAMILLE_30", true); + world.spawnGroup("CAMILLE_MINIONS"); + } + else if ((npc.getCurrentHp() <= (npc.getMaxHp() * 0.6)) && !CAMILLE_60) + { + world.getParameters().set("CAMILLE_60", true); + world.spawnGroup("CAMILLE_MINIONS"); + } + } + else if (npc.getId() == KAIN_VAN_HALTER) + { + if ((npc.getCurrentHp() <= (npc.getMaxHp() * 0.3)) && !KAIN_30) + { + world.getParameters().set("KAIN_30", true); + showOnScreenMsg(world, NpcStringId.ETIS_VAN_ETINA_SUMMONS_HIS_APOSTLES_MINIONS, ExShowScreenMessage.TOP_CENTER, 7000, true); + world.spawnGroup("KAIN_MINIONS"); + } + else if ((npc.getCurrentHp() <= (npc.getMaxHp() * 0.6)) && !KAIN_60) + { + world.getParameters().set("KAIN_60", true); + showOnScreenMsg(world, NpcStringId.ETIS_VAN_ETINA_SUMMONS_HIS_APOSTLES_MINIONS, ExShowScreenMessage.TOP_CENTER, 7000, true); + world.spawnGroup("KAIN_MINIONS"); + } + } + else if ((npc.getId() == ETIS_VAN_ETINA1)) + { + if ((npc.getCurrentHp() <= (npc.getMaxHp() * 0.8)) && !ETINA_80) + { + final Npc _etina1 = world.getNpc(ETIS_VAN_ETINA1); + world.getParameters().set("ETINA_80", true); + world.spawnGroup("ETINA_MINIONS"); + _etina1.abortCast(); + _etina1.broadcastPacket(new MagicSkillUse(_etina1, _etina1, CALL_OF_SEVEN_SIGNS.getSkillId(), CALL_OF_SEVEN_SIGNS.getSkillLevel(), 3000, 0)); + showOnScreenMsg(world, NpcStringId.ETIS_VAN_ETINA_USES_THE_POWER_OF_THE_SEVEN_SIGNS_TO_SUMMON_ALL_7_SEALS_INSIDE_THE_TEMPLE, ExShowScreenMessage.TOP_CENTER, 7000, true); + world.spawnGroup("SEALS"); + startQuestTimer("gnosisCastTimer", 120000, npc, attacker, true); + startQuestTimer("strifeCastTimer", 120000, npc, attacker, true); + startQuestTimer("avariceCastTimer", 120000, npc, attacker, true); + startQuestTimer("punishmentCastTimer", 120000, npc, attacker, true); + startQuestTimer("awakeningCastTimer", 120000, npc, attacker, true); + startQuestTimer("calamityCastTimer", 120000, npc, attacker, true); + startQuestTimer("destructionCastTimer", 120000, npc, attacker, true); + } + else if ((npc.getCurrentHp() <= (npc.getMaxHp() * 0.15)) && !ETINA_15) + { + world.getParameters().set("ETINA_15", true); + world.spawnGroup("ETINA_MINIONS"); + showOnScreenMsg(world, NpcStringId.ETIS_VAN_ETINA_AND_THE_POWER_OF_SIX_SEALS_ARE_WEAKENING, ExShowScreenMessage.TOP_CENTER, 7000, true); + } + } + } + return super.onAttack(npc, attacker, damage, isSummon); + } + + @Override + public String onKill(Npc npc, PlayerInstance killer, boolean isPet) + { + final Instance world = npc.getInstanceWorld(); + if (isInInstance(world)) + { + if (npc.getId() == ETIS_VAN_ETINA1) + { + playMovie(world.getPlayers(), Movie.SC_ETIS_VAN_ETINA_TRANS); + startQuestTimer("spawnTransformedEtina", 15000, null, killer); + } + else if (npc.getId() == ETIS_VAN_ETINA2) + { + playMovie(world.getPlayers(), Movie.SC_ETIS_VAN_ETINA_ENDING); + world.getAliveNpcs().forEach(mob -> + { + mob.deleteMe(); + }); + if (getQuestTimer("gnosisCastTimer", npc, killer) != null) + { + cancelQuestTimer("gnosisCastTimer", npc, killer); + } + if (getQuestTimer("trifeCastTimer", npc, killer) != null) + { + cancelQuestTimer("strifeCastTimer", npc, killer); + } + if (getQuestTimer("avariceCastTimer", npc, killer) != null) + { + cancelQuestTimer("avariceCastTimer", npc, killer); + } + if (getQuestTimer("punishmentCastTimer", npc, killer) != null) + { + cancelQuestTimer("punishmentCastTimer", npc, killer); + } + if (getQuestTimer("awakeningCastTimer", npc, killer) != null) + { + cancelQuestTimer("awakeningCastTimer", npc, killer); + } + if (getQuestTimer("calamityCastTimer", npc, killer) != null) + { + cancelQuestTimer("calamityCastTimer", npc, killer); + } + if (getQuestTimer("destructionCastTimer", npc, killer) != null) + { + cancelQuestTimer("destructionCastTimer", npc, killer); + } + closeDoor(DOOR1, world.getId()); + closeDoor(DOOR2, world.getId()); + closeDoor(DOOR3, world.getId()); + closeDoor(DOOR4, world.getId()); + world.finishInstance(2); + } + else if (CommonUtil.contains(CORRIDOR_MOBS_1, npc.getId())) + { + if (world.getAliveNpcs(CORRIDOR_MOBS_1).isEmpty()) + { + world.getParameters().set("BARRICADE_DESTROYED", false); + } + } + else if (CommonUtil.contains(CORRIDOR_MOBS_2, npc.getId())) + { + if (world.getAliveNpcs(CORRIDOR_MOBS_2).isEmpty()) + { + world.getParameters().set("BARRICADE_DESTROYED", false); + } + } + else if (CommonUtil.contains(CORRIDOR_MOBS_3, npc.getId())) + { + if (world.getAliveNpcs(CORRIDOR_MOBS_3).isEmpty()) + { + world.getParameters().set("BARRICADE_DESTROYED", false); + } + } + else if (CommonUtil.contains(CORRIDOR_MOBS_4, npc.getId())) + { + if (world.getAliveNpcs(CORRIDOR_MOBS_4).isEmpty()) + { + world.getNpc(PARAGON).setInvul(false); + world.getNpc(PARAGON).getEffectList().stopAbnormalVisualEffect(AbnormalVisualEffect.INVINCIBILITY); + showOnScreenMsg(world, NpcStringId.PARAGON_IS_NO_LONGER_INVINCIBLE, ExShowScreenMessage.TOP_CENTER, 7000, true); + world.getNpc(LEONA_BLACKBIRD).broadcastSay(ChatType.NPC_GENERAL, NpcStringId.TODAY_IS_THE_DAY_THAT_I_WILL_ENTER); + } + } + else if (npc.getId() == PARAGON) + { + startQuestTimer("openInnerDoors", 5000, null, killer); + } + else if (npc.getId() == CAMILLE) + { + world.getNpcsOfGroup("CAMILLE_MINIONS").forEach(minion -> + { + if (minion != null) + { + minion.doDie(null); + } + }); + world.getNpc(CAMILLE).deleteMe(); + world.getNpc(LEONA_BLACKBIRD).broadcastSay(ChatType.NPC_GENERAL, NpcStringId.KAIN_IS_OUR_ENEMY_NOW_BE_ON_GUARD); + playMovie(world.getPlayers(), Movie.SC_INZONE_KAIN_INTRO); + startQuestTimer("spawn_kain", 5000, null, killer); + } + else if (npc.getId() == KAIN_VAN_HALTER) + { + world.getNpcsOfGroup("KAIN_MINIONS").forEach(minion -> + { + if (minion != null) + { + minion.doDie(null); + } + }); + world.getNpc(ETIS_VAN_ETINA1).setInvul(false); + world.getNpc(ETIS_VAN_ETINA1).setImmobilized(false); + world.getNpc(ETIS_VAN_ETINA1).setTargetable(true); + showOnScreenMsg(world, NpcStringId.ETIS_VAN_ETINA_APPROACHES, ExShowScreenMessage.TOP_CENTER, 7000, true); + world.getNpc(KAIN_VAN_HALTER).deleteMe(); + playMovie(world.getPlayers(), Movie.SC_KAIN_BOSS_ENDING); + world.getNpc(LEONA_BLACKBIRD).broadcastSay(ChatType.NPC_GENERAL, NpcStringId.KAIN_I_WON_T_FEEL_GUILTY_ABOUT_THIS); + } + } + return super.onKill(npc, killer, isPet); + } + + @Override + public String onFirstTalk(Npc npc, PlayerInstance player) + { + final Instance world = player.getInstanceWorld(); + String htmltext = null; + if (isInInstance(world)) + { + switch (npc.getId()) + { + case DEVIANNE: + case ELIKIA: + case SPORCHA: + case ALIBER: + { + htmltext = npc.getId() + ".html"; + break; + } + case LEONA_BLACKBIRD: + { + switch (world.getStatus()) + { + case 0: + { + htmltext = "34471.htm"; + break; + } + case 1: + { + htmltext = "34471-01.html"; + break; + } + case 2: + { + htmltext = "34471-02.htm"; + break; + } + case 3: + { + htmltext = "34471-03.html"; + break; + } + } + } + } + } + return htmltext; + } + + public static void main(String[] args) + { + new EtisVanEtinaSolo(); + } +} \ No newline at end of file diff --git a/L2J_Mobius_8.0_Homunculus/dist/game/data/scripts/instances/EtisVanEtinaSolo/condNoGroup.html b/L2J_Mobius_8.0_Homunculus/dist/game/data/scripts/instances/EtisVanEtinaSolo/condNoGroup.html new file mode 100644 index 0000000000..a34d6f3c14 --- /dev/null +++ b/L2J_Mobius_8.0_Homunculus/dist/game/data/scripts/instances/EtisVanEtinaSolo/condNoGroup.html @@ -0,0 +1,3 @@ +Leona Blackbird:
+You can enter only solo. + \ No newline at end of file diff --git a/L2J_Mobius_8.0_Homunculus/dist/game/data/scripts/instances/EtisVanEtinaSolo/condNoLevel.html b/L2J_Mobius_8.0_Homunculus/dist/game/data/scripts/instances/EtisVanEtinaSolo/condNoLevel.html new file mode 100644 index 0000000000..5a53e17332 --- /dev/null +++ b/L2J_Mobius_8.0_Homunculus/dist/game/data/scripts/instances/EtisVanEtinaSolo/condNoLevel.html @@ -0,0 +1,4 @@ +Leona Blackbird:
+I won't let you enter.
+(Only players between levels 104-130 may participate.) + \ No newline at end of file diff --git a/L2J_Mobius_8.0_Homunculus/dist/game/data/stats/npcs/24100-24199.xml b/L2J_Mobius_8.0_Homunculus/dist/game/data/stats/npcs/24100-24199.xml index 4421f21547..1fe8ac7fb3 100644 --- a/L2J_Mobius_8.0_Homunculus/dist/game/data/stats/npcs/24100-24199.xml +++ b/L2J_Mobius_8.0_Homunculus/dist/game/data/stats/npcs/24100-24199.xml @@ -2270,6 +2270,11 @@ + + + ETINA_SOLO + + @@ -2296,6 +2301,11 @@ + + + ETINA_SOLO + + @@ -2322,6 +2332,11 @@ + + + ETINA_SOLO + + @@ -2348,6 +2363,11 @@ + + + ETINA_SOLO + + @@ -2373,6 +2393,11 @@ + + + ETINA_SOLO + + @@ -2398,6 +2423,11 @@ + + + ETINA_SOLO + + @@ -2423,6 +2453,11 @@ + + + ETINA_SOLO + + @@ -2448,6 +2483,11 @@ + + + ETINA_SOLO + + @@ -2473,6 +2513,11 @@ + + + ETINA_SOLO + + @@ -2498,6 +2543,11 @@ + + + ETINA_SOLO + + @@ -2523,6 +2573,11 @@ + + + ETINA_SOLO + + @@ -2548,6 +2603,11 @@ + + + ETINA_SOLO + + @@ -2573,6 +2633,11 @@ + + + ETINA_SOLO + + @@ -2598,6 +2663,11 @@ + + + ETINA_SOLO + + @@ -2609,7 +2679,7 @@ - + HUMANOID FEMALE @@ -2622,6 +2692,11 @@ + + + ETINA_SOLO + + @@ -2634,7 +2709,7 @@ - + DEMONIC MALE @@ -2647,6 +2722,11 @@ + + + ETINA_SOLO + + @@ -3102,6 +3182,11 @@ + + + ETINA_SOLO + + @@ -3127,6 +3212,11 @@ + + + ETINA_SOLO + + @@ -3152,6 +3242,11 @@ + + + ETINA_SOLO + + @@ -3163,24 +3258,34 @@ - - + ETC FEMALE - + + + - - - + + + + ETINA_SOLO + + + + + + + + diff --git a/L2J_Mobius_8.0_Homunculus/dist/game/data/stats/npcs/26300-26399.xml b/L2J_Mobius_8.0_Homunculus/dist/game/data/stats/npcs/26300-26399.xml index 4ea02626c1..050c98e131 100644 --- a/L2J_Mobius_8.0_Homunculus/dist/game/data/stats/npcs/26300-26399.xml +++ b/L2J_Mobius_8.0_Homunculus/dist/game/data/stats/npcs/26300-26399.xml @@ -509,43 +509,103 @@ - - - ETC - FEMALE + + HUMANOID + MALE - + + + - - - + + + + ETINA_SOLO + + + + + + + + - - - ETC - FEMALE + + HUMANOID + MALE + - + + + - - - + + + + ETINA_SOLO + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + DEMONIC @@ -560,6 +620,11 @@ + + + ETINA_SOLO + + @@ -585,6 +650,11 @@ + + + ETINA_SOLO + + @@ -610,6 +680,11 @@ + + + ETINA_SOLO + + @@ -635,6 +710,11 @@ + + + ETINA_SOLO + + diff --git a/L2J_Mobius_9.0_ReturnOfTheQueenAnt/dist/game/data/instances/EtisVanEtinaSolo.xml b/L2J_Mobius_9.0_ReturnOfTheQueenAnt/dist/game/data/instances/EtisVanEtinaSolo.xml new file mode 100644 index 0000000000..64f03d23d9 --- /dev/null +++ b/L2J_Mobius_9.0_ReturnOfTheQueenAnt/dist/game/data/instances/EtisVanEtinaSolo.xml @@ -0,0 +1,196 @@ + + + + \ No newline at end of file diff --git a/L2J_Mobius_9.0_ReturnOfTheQueenAnt/dist/game/data/scripts/instances/EtisVanEtinaSolo/34471-01.html b/L2J_Mobius_9.0_ReturnOfTheQueenAnt/dist/game/data/scripts/instances/EtisVanEtinaSolo/34471-01.html new file mode 100644 index 0000000000..3d860da0ab --- /dev/null +++ b/L2J_Mobius_9.0_ReturnOfTheQueenAnt/dist/game/data/scripts/instances/EtisVanEtinaSolo/34471-01.html @@ -0,0 +1,4 @@ +Blackbird Clan Lord Leona Blackbird:
+Let us defeat our enemies.
+Let's go to Etis van Etina, the Head of the Embryo, as fast as we can. + \ No newline at end of file diff --git a/L2J_Mobius_9.0_ReturnOfTheQueenAnt/dist/game/data/scripts/instances/EtisVanEtinaSolo/34471-02.htm b/L2J_Mobius_9.0_ReturnOfTheQueenAnt/dist/game/data/scripts/instances/EtisVanEtinaSolo/34471-02.htm new file mode 100644 index 0000000000..7a02b2ead9 --- /dev/null +++ b/L2J_Mobius_9.0_ReturnOfTheQueenAnt/dist/game/data/scripts/instances/EtisVanEtinaSolo/34471-02.htm @@ -0,0 +1,5 @@ +Blackbird Clan Lord Leona Blackbird:
+Thanks to you, we were able to come this far this time.
+But why is it so quiet? It can't be this empty...
+ + \ No newline at end of file diff --git a/L2J_Mobius_9.0_ReturnOfTheQueenAnt/dist/game/data/scripts/instances/EtisVanEtinaSolo/34471-03.html b/L2J_Mobius_9.0_ReturnOfTheQueenAnt/dist/game/data/scripts/instances/EtisVanEtinaSolo/34471-03.html new file mode 100644 index 0000000000..528abbaadb --- /dev/null +++ b/L2J_Mobius_9.0_ReturnOfTheQueenAnt/dist/game/data/scripts/instances/EtisVanEtinaSolo/34471-03.html @@ -0,0 +1,3 @@ +Blackbird Clan Lord Leona Blackbird:
+You don't have to worry ab- Ah! Oh no! What's that?
+ \ No newline at end of file diff --git a/L2J_Mobius_9.0_ReturnOfTheQueenAnt/dist/game/data/scripts/instances/EtisVanEtinaSolo/34471.htm b/L2J_Mobius_9.0_ReturnOfTheQueenAnt/dist/game/data/scripts/instances/EtisVanEtinaSolo/34471.htm new file mode 100644 index 0000000000..fa5014df9f --- /dev/null +++ b/L2J_Mobius_9.0_ReturnOfTheQueenAnt/dist/game/data/scripts/instances/EtisVanEtinaSolo/34471.htm @@ -0,0 +1,5 @@ +Blackbird Clan Lord Leona Blackbird:
+This is the Great Etina Temple. Setting foot in this place again reminds me of old memories. I used my new power to sneak in so the enemy should be unaware of our presence.
+Now, let's take down the Embryos and Etis van Etina before they even realize. Are you ready?
+ + \ No newline at end of file diff --git a/L2J_Mobius_9.0_ReturnOfTheQueenAnt/dist/game/data/scripts/instances/EtisVanEtinaSolo/34472.html b/L2J_Mobius_9.0_ReturnOfTheQueenAnt/dist/game/data/scripts/instances/EtisVanEtinaSolo/34472.html new file mode 100644 index 0000000000..cbc5604977 --- /dev/null +++ b/L2J_Mobius_9.0_ReturnOfTheQueenAnt/dist/game/data/scripts/instances/EtisVanEtinaSolo/34472.html @@ -0,0 +1,3 @@ +Devianne:
+Behold the power of the Ivory Tower Wizards!
+ \ No newline at end of file diff --git a/L2J_Mobius_9.0_ReturnOfTheQueenAnt/dist/game/data/scripts/instances/EtisVanEtinaSolo/34473.html b/L2J_Mobius_9.0_ReturnOfTheQueenAnt/dist/game/data/scripts/instances/EtisVanEtinaSolo/34473.html new file mode 100644 index 0000000000..eef8b17456 --- /dev/null +++ b/L2J_Mobius_9.0_ReturnOfTheQueenAnt/dist/game/data/scripts/instances/EtisVanEtinaSolo/34473.html @@ -0,0 +1,3 @@ +Elikia:
+Let's take down the Embryos and Etis van Etina before they even realize.
+ \ No newline at end of file diff --git a/L2J_Mobius_9.0_ReturnOfTheQueenAnt/dist/game/data/scripts/instances/EtisVanEtinaSolo/34474.html b/L2J_Mobius_9.0_ReturnOfTheQueenAnt/dist/game/data/scripts/instances/EtisVanEtinaSolo/34474.html new file mode 100644 index 0000000000..9c0807c63a --- /dev/null +++ b/L2J_Mobius_9.0_ReturnOfTheQueenAnt/dist/game/data/scripts/instances/EtisVanEtinaSolo/34474.html @@ -0,0 +1,3 @@ +Sporcha:
+Are you ready to fight?
+ \ No newline at end of file diff --git a/L2J_Mobius_9.0_ReturnOfTheQueenAnt/dist/game/data/scripts/instances/EtisVanEtinaSolo/34475.html b/L2J_Mobius_9.0_ReturnOfTheQueenAnt/dist/game/data/scripts/instances/EtisVanEtinaSolo/34475.html new file mode 100644 index 0000000000..ec99f9f6d0 --- /dev/null +++ b/L2J_Mobius_9.0_ReturnOfTheQueenAnt/dist/game/data/scripts/instances/EtisVanEtinaSolo/34475.html @@ -0,0 +1,3 @@ +Aliber:
+Rage against all that stands in our way!
+ \ No newline at end of file diff --git a/L2J_Mobius_9.0_ReturnOfTheQueenAnt/dist/game/data/scripts/instances/EtisVanEtinaSolo/EtinaHelperAliber.java b/L2J_Mobius_9.0_ReturnOfTheQueenAnt/dist/game/data/scripts/instances/EtisVanEtinaSolo/EtinaHelperAliber.java new file mode 100644 index 0000000000..df86f9ab85 --- /dev/null +++ b/L2J_Mobius_9.0_ReturnOfTheQueenAnt/dist/game/data/scripts/instances/EtisVanEtinaSolo/EtinaHelperAliber.java @@ -0,0 +1,283 @@ +/* + * 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 instances.EtisVanEtinaSolo; + +import org.l2jmobius.commons.util.CommonUtil; +import org.l2jmobius.gameserver.ai.CtrlIntention; +import org.l2jmobius.gameserver.enums.ChatType; +import org.l2jmobius.gameserver.geoengine.GeoEngine; +import org.l2jmobius.gameserver.model.Location; +import org.l2jmobius.gameserver.model.StatSet; +import org.l2jmobius.gameserver.model.World; +import org.l2jmobius.gameserver.model.WorldObject; +import org.l2jmobius.gameserver.model.actor.Creature; +import org.l2jmobius.gameserver.model.actor.Npc; +import org.l2jmobius.gameserver.model.actor.instance.FriendlyNpcInstance; +import org.l2jmobius.gameserver.model.actor.instance.MonsterInstance; +import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; +import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureAttacked; +import org.l2jmobius.gameserver.model.events.impl.instance.OnInstanceStatusChange; +import org.l2jmobius.gameserver.model.holders.SkillHolder; +import org.l2jmobius.gameserver.model.instancezone.Instance; +import org.l2jmobius.gameserver.network.NpcStringId; +import org.l2jmobius.gameserver.network.serverpackets.ExShowScreenMessage; +import org.l2jmobius.gameserver.network.serverpackets.MagicSkillUse; + +import ai.AbstractNpcAI; + +/** + * Etina Helper Aliber AI. + * @author CostyKiller + */ +public class EtinaHelperAliber extends AbstractNpcAI +{ + // NPCs + private static final int ETINA_HELPER_ALIBER = 34475; + // Corridor Mobs + //@formatter:off + private static final int[] CORRIDOR_MOBS_1 = {24173, 24174, 24175, 24176}; + private static final int[] CORRIDOR_MOBS_2 = {24180, 24181, 24182, 24183}; + private static final int[] CORRIDOR_MOBS_3 = {24184, 24185, 24186, 24187, 24188, 24189, 24190, 24191, 24192}; + private static final int[] NOT_ATK_NPCS = + { + 33798, // Common Decoration - Barricade + 19677, // Seal of Gnosis + 19678, // Seal of Strife + 19679, // Seal of Avarice + 19680, // Seal of Punishment + 19681, // Seal of Awakening + 19682, // Seal of Calamity + 19683, // Seal of Destruction + }; + private static final int[] ETINA_HELPERS = + { + 34471, // Leona Blackbird + 34472, // Devianne + 34473, // Elikia + 34474, // Sporcha + 34475, // Aliber + }; + // Skill Cast Locations + private static final Location[] SKILL_CAST_LOCATIONS = + { + new Location(-245751, 182321, 2861, 16612), // First barricade line + new Location(-245751, 184001, 3025, 16612), // Second barricade line + new Location(-245751, 185298, 3031, 16612), // Third barricade line + new Location(-245751, 186612, 3038, 16612), // Fourth barricade line + }; + // Support Npcs Skills + private static final SkillHolder BARRICADE_DESTRUCTION = new SkillHolder(32286, 1); + // Misc + private static final int[] ETINA_SOLO_INSTANCES = + { + 292, // Fall of Etina (Solo) + 293, // Fall of Etina (Solo) + }; + + private EtinaHelperAliber() + { + setCreatureAttackedId(this::onCreatureAttacked, ETINA_HELPER_ALIBER); + addSpellFinishedId(ETINA_HELPER_ALIBER); + addSeeCreatureId(ETINA_HELPER_ALIBER); + setInstanceStatusChangeId(this::onInstanceStatusChange, ETINA_SOLO_INSTANCES); + } + + @Override + public void onTimerEvent(String event, StatSet params, Npc npc, PlayerInstance player) + { + final Instance instance = npc.getInstanceWorld(); + if (instance != null) + { + switch (event) + { + case "CHECK_ACTION": + { + final StatSet npcVars = npc.getVariables(); + final PlayerInstance plr = npcVars.getObject("PLAYER_OBJECT", PlayerInstance.class); + final MonsterInstance monster = getRandomEntry(World.getInstance().getVisibleObjectsInRange(npc, MonsterInstance.class, 2500)); + if (plr != null) + { + final double distance = npc.calculateDistance2D(plr); + if (!npc.isAttackingNow() && !npc.isMoving() && (distance > 250)) + { + final Location loc = new Location(plr.getX(), plr.getY(), plr.getZ() + 50); + final Location randLoc = new Location(loc.getX() + getRandom(-100, 100), loc.getY() + getRandom(-100, 100), loc.getZ()); + if (distance > 600) + { + npc.teleToLocation(loc); + } + else + { + npc.setRunning(); + } + addMoveToDesire(npc, randLoc, 23); + ((FriendlyNpcInstance) npc).setCanReturnToSpawnPoint(false); + } + else if (!npc.isInCombat() || !npc.isAttackingNow() || (npc.getTarget() == null)) + { + WorldObject target = npc.getTarget(); + if (target == null) + { + npc.setTarget(monster); + } + if ((target != null) && !target.isInvul() && target.isTargetable() && GeoEngine.getInstance().canSeeTarget(npc, target) && !CommonUtil.contains(NOT_ATK_NPCS, target.getId()) && !CommonUtil.contains(ETINA_HELPERS, target.getId())) + { + npc.setInvul(true); + npc.setRunning(); + ((FriendlyNpcInstance) npc).setCanReturnToSpawnPoint(false); + addAttackDesire(npc, (Creature) target); + // addSkillCastDesire(npc, target, ALIBER_SPLASH, 23); + // npc.reduceCurrentHp(1, monster, null); + } + } + } + break; + } + case "DESTROY_BARRICADES": + { + final FriendlyNpcInstance _aliber = (FriendlyNpcInstance) instance.getNpc(ETINA_HELPER_ALIBER); + boolean BARRICADE_DESTROYED = instance.getParameters().getBoolean("BARRICADE_DESTROYED", false); + if (!instance.getNpcsOfGroup("BARRICADES_1").isEmpty()) + { + _aliber.setRunning(); + _aliber.setInvul(true); + _aliber.setCanReturnToSpawnPoint(false); + _aliber.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, SKILL_CAST_LOCATIONS[0]); + if (_aliber.getLocation().isIn2DRadius(SKILL_CAST_LOCATIONS[0], 200) && (BARRICADE_DESTROYED == false)) + { + _aliber.broadcastPacket(new MagicSkillUse(_aliber, _aliber, BARRICADE_DESTRUCTION.getSkillId(), 1, 500, 0)); + _aliber.broadcastPacket(new ExShowScreenMessage(NpcStringId.ALIBER_IS_CASTING_A_SPELL_TO_DESTROY_THE_BARRICADE, ExShowScreenMessage.TOP_CENTER, 7000, true)); + instance.getNpcsOfGroup("BARRICADES_1").forEach(barricade -> + { + if (barricade != null) + { + barricade.decayMe(); + } + }); + instance.getParameters().set("BARRICADE_DESTROYED", true); + instance.despawnGroup("BARRICADES_1"); + } + } + else if (!instance.getNpcsOfGroup("BARRICADES_2").isEmpty() && instance.getAliveNpcs(CORRIDOR_MOBS_1).isEmpty() && instance.getNpcsOfGroup("BARRICADES_1").isEmpty()) + { + _aliber.setRunning(); + _aliber.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, SKILL_CAST_LOCATIONS[1]); + if (_aliber.getLocation().isIn2DRadius(SKILL_CAST_LOCATIONS[1], 200) && (BARRICADE_DESTROYED == false)) + { + _aliber.broadcastPacket(new MagicSkillUse(_aliber, _aliber, BARRICADE_DESTRUCTION.getSkillId(), 1, 500, 0)); + _aliber.broadcastPacket(new ExShowScreenMessage(NpcStringId.ALIBER_IS_CASTING_A_SPELL_TO_DESTROY_THE_BARRICADE, ExShowScreenMessage.TOP_CENTER, 7000, true)); + instance.getNpcsOfGroup("BARRICADES_2").forEach(barricade -> + { + if (barricade != null) + { + barricade.decayMe(); + } + }); + instance.getParameters().set("BARRICADE_DESTROYED", true); + instance.despawnGroup("BARRICADES_2"); + } + } + else if (!instance.getNpcsOfGroup("BARRICADES_3").isEmpty() && instance.getAliveNpcs(CORRIDOR_MOBS_2).isEmpty() && instance.getNpcsOfGroup("BARRICADES_2").isEmpty()) + { + _aliber.setRunning(); + _aliber.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, SKILL_CAST_LOCATIONS[2]); + if (_aliber.getLocation().isIn2DRadius(SKILL_CAST_LOCATIONS[2], 200) && (BARRICADE_DESTROYED == false)) + { + _aliber.broadcastPacket(new MagicSkillUse(_aliber, _aliber, BARRICADE_DESTRUCTION.getSkillId(), 1, 500, 0)); + _aliber.broadcastPacket(new ExShowScreenMessage(NpcStringId.ALIBER_IS_CASTING_A_SPELL_TO_DESTROY_THE_BARRICADE, ExShowScreenMessage.TOP_CENTER, 7000, true)); + instance.getNpcsOfGroup("BARRICADES_3").forEach(barricade -> + { + if (barricade != null) + { + barricade.decayMe(); + } + }); + instance.getParameters().set("BARRICADE_DESTROYED", true); + instance.despawnGroup("BARRICADES_3"); + } + } + else if (!instance.getNpcsOfGroup("BARRICADES_4").isEmpty() && instance.getAliveNpcs(CORRIDOR_MOBS_3).isEmpty() && instance.getNpcsOfGroup("BARRICADES_3").isEmpty()) + { + _aliber.setRunning(); + _aliber.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, SKILL_CAST_LOCATIONS[3]); + if (_aliber.getLocation().isIn2DRadius(SKILL_CAST_LOCATIONS[3], 200) && (BARRICADE_DESTROYED == false)) + { + _aliber.broadcastPacket(new MagicSkillUse(_aliber, _aliber, BARRICADE_DESTRUCTION.getSkillId(), 1, 500, 0)); + _aliber.broadcastPacket(new ExShowScreenMessage(NpcStringId.ALIBER_IS_CASTING_A_SPELL_TO_DESTROY_THE_BARRICADE, ExShowScreenMessage.TOP_CENTER, 7000, true)); + instance.getNpcsOfGroup("BARRICADES_4").forEach(barricade -> + { + if (barricade != null) + { + barricade.decayMe(); + } + }); + instance.getParameters().set("BARRICADE_DESTROYED", true); + instance.despawnGroup("BARRICADES_4"); + } + } + } + break; + } + } + } + + public void onCreatureAttacked(OnCreatureAttacked event) + { + final FriendlyNpcInstance npc = (FriendlyNpcInstance) event.getTarget(); + if (npc != null) + { + final Instance instance = npc.getInstanceWorld(); + if ((instance != null) && !event.getAttacker().isPlayable() && !CommonUtil.contains(ETINA_HELPERS, event.getAttacker().getId())) + { + if (!npc.isInCombat()) + { + if (getRandom(50) < 5) + { + npc.broadcastSay(ChatType.NPC_GENERAL, NpcStringId.RAGE_AGAINST_ALL_THAT_STANDS_IN_OUR_WAY); + } + } + } + } + } + + public void onInstanceStatusChange(OnInstanceStatusChange event) + { + final Instance instance = event.getWorld(); + final int status = event.getStatus(); + if ((status == 1) || (status == 2) || (status == 3)) + { + instance.getAliveNpcs(ETINA_HELPER_ALIBER).forEach(etinaHelperAliber -> getTimers().addRepeatingTimer("CHECK_ACTION", 3000, etinaHelperAliber, null)); + instance.getAliveNpcs(ETINA_HELPER_ALIBER).forEach(etinaHelperAliber -> getTimers().addRepeatingTimer("USE_SKILL", 6000, etinaHelperAliber, null)); + instance.getAliveNpcs(ETINA_HELPER_ALIBER).forEach(etinaHelperAliber -> getTimers().addRepeatingTimer("DESTROY_BARRICADES", 5000, etinaHelperAliber, null)); + } + } + + @Override + public String onSeeCreature(Npc npc, Creature creature, boolean isSummon) + { + if (creature.isPlayer()) + { + npc.getVariables().set("PLAYER_OBJECT", creature.getActingPlayer()); + } + return super.onSeeCreature(npc, creature, isSummon); + } + + public static void main(String[] args) + { + new EtinaHelperAliber(); + } +} \ No newline at end of file diff --git a/L2J_Mobius_9.0_ReturnOfTheQueenAnt/dist/game/data/scripts/instances/EtisVanEtinaSolo/EtinaHelperDevianne.java b/L2J_Mobius_9.0_ReturnOfTheQueenAnt/dist/game/data/scripts/instances/EtisVanEtinaSolo/EtinaHelperDevianne.java new file mode 100644 index 0000000000..258d606210 --- /dev/null +++ b/L2J_Mobius_9.0_ReturnOfTheQueenAnt/dist/game/data/scripts/instances/EtisVanEtinaSolo/EtinaHelperDevianne.java @@ -0,0 +1,171 @@ +/* + * 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 instances.EtisVanEtinaSolo; + +import org.l2jmobius.commons.util.CommonUtil; +import org.l2jmobius.gameserver.enums.ChatType; +import org.l2jmobius.gameserver.geoengine.GeoEngine; +import org.l2jmobius.gameserver.model.Location; +import org.l2jmobius.gameserver.model.StatSet; +import org.l2jmobius.gameserver.model.World; +import org.l2jmobius.gameserver.model.WorldObject; +import org.l2jmobius.gameserver.model.actor.Creature; +import org.l2jmobius.gameserver.model.actor.Npc; +import org.l2jmobius.gameserver.model.actor.instance.FriendlyNpcInstance; +import org.l2jmobius.gameserver.model.actor.instance.MonsterInstance; +import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; +import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureAttacked; +import org.l2jmobius.gameserver.model.events.impl.instance.OnInstanceStatusChange; +import org.l2jmobius.gameserver.model.instancezone.Instance; +import org.l2jmobius.gameserver.network.NpcStringId; + +import ai.AbstractNpcAI; + +/** + * Etina Helper Devianne AI. + * @author CostyKiller + */ +public class EtinaHelperDevianne extends AbstractNpcAI +{ + // NPCs + private static final int ETINA_HELPER_DEVIANNE = 34472; + private static final int[] NOT_ATK_NPCS = + { + 33798, // Common Decoration - Barricade + 19677, // Seal of Gnosis + 19678, // Seal of Strife + 19679, // Seal of Avarice + 19680, // Seal of Punishment + 19681, // Seal of Awakening + 19682, // Seal of Calamity + 19683, // Seal of Destruction + }; + private static final int[] ETINA_HELPERS = + { + 34471, // Leona Blackbird + 34472, // Devianne + 34473, // Elikia + 34474, // Sporcha + 34475, // Aliber + }; + // Misc + private static final int[] ETINA_SOLO_INSTANCES = + { + 292, // Fall of Etina (Solo) + 293, // Fall of Etina (Solo) + }; + + private EtinaHelperDevianne() + { + setCreatureAttackedId(this::onCreatureAttacked, ETINA_HELPER_DEVIANNE); + addSpellFinishedId(ETINA_HELPER_DEVIANNE); + addSeeCreatureId(ETINA_HELPER_DEVIANNE); + setInstanceStatusChangeId(this::onInstanceStatusChange, ETINA_SOLO_INSTANCES); + } + + @Override + public void onTimerEvent(String event, StatSet params, Npc npc, PlayerInstance player) + { + final Instance instance = npc.getInstanceWorld(); + if ((instance != null) && event.equals("CHECK_ACTION")) + { + final StatSet npcVars = npc.getVariables(); + final PlayerInstance plr = npcVars.getObject("PLAYER_OBJECT", PlayerInstance.class); + final MonsterInstance monster = getRandomEntry(World.getInstance().getVisibleObjectsInRange(npc, MonsterInstance.class, 2500)); + if (plr != null) + { + final double distance = npc.calculateDistance2D(plr); + if (!npc.isAttackingNow() && !npc.isMoving() && (distance > 250)) + { + final Location loc = new Location(plr.getX(), plr.getY(), plr.getZ() + 50); + final Location randLoc = new Location(loc.getX() + getRandom(-100, 100), loc.getY() + getRandom(-100, 100), loc.getZ()); + if (distance > 600) + { + npc.teleToLocation(loc); + } + else + { + npc.setRunning(); + } + addMoveToDesire(npc, randLoc, 23); + ((FriendlyNpcInstance) npc).setCanReturnToSpawnPoint(false); + } + else if (!npc.isInCombat() || !npc.isAttackingNow() || (npc.getTarget() == null)) + { + WorldObject target = npc.getTarget(); + if (target == null) + { + npc.setTarget(monster); + } + if ((target != null) && !target.isInvul() && target.isTargetable() && GeoEngine.getInstance().canSeeTarget(npc, target) && !CommonUtil.contains(NOT_ATK_NPCS, target.getId()) && !CommonUtil.contains(ETINA_HELPERS, target.getId())) + { + npc.setInvul(true); + npc.setRunning(); + ((FriendlyNpcInstance) npc).setCanReturnToSpawnPoint(false); + addAttackDesire(npc, (Creature) target); + // npc.reduceCurrentHp(1, monster, null); + } + } + } + } + } + + public void onCreatureAttacked(OnCreatureAttacked event) + { + final FriendlyNpcInstance npc = (FriendlyNpcInstance) event.getTarget(); + if (npc != null) + { + final Instance instance = npc.getInstanceWorld(); + if ((instance != null) && !event.getAttacker().isPlayable() && !CommonUtil.contains(ETINA_HELPERS, event.getAttacker().getId())) + { + if (!npc.isInCombat()) + { + if (getRandom(50) < 5) + { + npc.broadcastSay(ChatType.NPC_GENERAL, NpcStringId.BEHOLD_THE_POWER_OF_THE_IVORY_TOWER_WIZARDS); + } + + } + } + } + } + + public void onInstanceStatusChange(OnInstanceStatusChange event) + { + final Instance instance = event.getWorld(); + final int status = event.getStatus(); + if ((status == 1) || (status == 2) || (status == 3)) + { + instance.getAliveNpcs(ETINA_HELPER_DEVIANNE).forEach(etinaHelperDevianne -> getTimers().addRepeatingTimer("CHECK_ACTION", 3000, etinaHelperDevianne, null)); + } + } + + @Override + public String onSeeCreature(Npc npc, Creature creature, boolean isSummon) + { + if (creature.isPlayer()) + { + npc.getVariables().set("PLAYER_OBJECT", creature.getActingPlayer()); + } + return super.onSeeCreature(npc, creature, isSummon); + } + + public static void main(String[] args) + { + new EtinaHelperDevianne(); + } +} \ No newline at end of file diff --git a/L2J_Mobius_9.0_ReturnOfTheQueenAnt/dist/game/data/scripts/instances/EtisVanEtinaSolo/EtinaHelperElikia.java b/L2J_Mobius_9.0_ReturnOfTheQueenAnt/dist/game/data/scripts/instances/EtisVanEtinaSolo/EtinaHelperElikia.java new file mode 100644 index 0000000000..ff41fcd13e --- /dev/null +++ b/L2J_Mobius_9.0_ReturnOfTheQueenAnt/dist/game/data/scripts/instances/EtisVanEtinaSolo/EtinaHelperElikia.java @@ -0,0 +1,170 @@ +/* + * 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 instances.EtisVanEtinaSolo; + +import org.l2jmobius.commons.util.CommonUtil; +import org.l2jmobius.gameserver.enums.ChatType; +import org.l2jmobius.gameserver.geoengine.GeoEngine; +import org.l2jmobius.gameserver.model.Location; +import org.l2jmobius.gameserver.model.StatSet; +import org.l2jmobius.gameserver.model.World; +import org.l2jmobius.gameserver.model.WorldObject; +import org.l2jmobius.gameserver.model.actor.Creature; +import org.l2jmobius.gameserver.model.actor.Npc; +import org.l2jmobius.gameserver.model.actor.instance.FriendlyNpcInstance; +import org.l2jmobius.gameserver.model.actor.instance.MonsterInstance; +import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; +import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureAttacked; +import org.l2jmobius.gameserver.model.events.impl.instance.OnInstanceStatusChange; +import org.l2jmobius.gameserver.model.instancezone.Instance; +import org.l2jmobius.gameserver.network.NpcStringId; + +import ai.AbstractNpcAI; + +/** + * Etina Helper Elikia AI. + * @author CostyKiller + */ +public class EtinaHelperElikia extends AbstractNpcAI +{ + // NPCs + private static final int ETINA_HELPER_ELIKIA = 34473; + private static final int[] NOT_ATK_NPCS = + { + 33798, // Common Decoration - Barricade + 19677, // Seal of Gnosis + 19678, // Seal of Strife + 19679, // Seal of Avarice + 19680, // Seal of Punishment + 19681, // Seal of Awakening + 19682, // Seal of Calamity + 19683, // Seal of Destruction + }; + private static final int[] ETINA_HELPERS = + { + 34471, // Leona Blackbird + 34472, // Devianne + 34473, // Elikia + 34474, // Sporcha + 34475, // Aliber + }; + // Misc + private static final int[] ETINA_SOLO_INSTANCES = + { + 292, // Fall of Etina (Solo) + 293, // Fall of Etina (Solo) + }; + + private EtinaHelperElikia() + { + setCreatureAttackedId(this::onCreatureAttacked, ETINA_HELPER_ELIKIA); + addSpellFinishedId(ETINA_HELPER_ELIKIA); + addSeeCreatureId(ETINA_HELPER_ELIKIA); + setInstanceStatusChangeId(this::onInstanceStatusChange, ETINA_SOLO_INSTANCES); + } + + @Override + public void onTimerEvent(String event, StatSet params, Npc npc, PlayerInstance player) + { + final Instance instance = npc.getInstanceWorld(); + if ((instance != null) && event.equals("CHECK_ACTION")) + { + final StatSet npcVars = npc.getVariables(); + final PlayerInstance plr = npcVars.getObject("PLAYER_OBJECT", PlayerInstance.class); + final MonsterInstance monster = getRandomEntry(World.getInstance().getVisibleObjectsInRange(npc, MonsterInstance.class, 2500)); + if (plr != null) + { + final double distance = npc.calculateDistance2D(plr); + if (!npc.isAttackingNow() && !npc.isMoving() && (distance > 250)) + { + final Location loc = new Location(plr.getX(), plr.getY(), plr.getZ() + 50); + final Location randLoc = new Location(loc.getX() + getRandom(-100, 100), loc.getY() + getRandom(-100, 100), loc.getZ()); + if (distance > 600) + { + npc.teleToLocation(loc); + } + else + { + npc.setRunning(); + } + addMoveToDesire(npc, randLoc, 23); + ((FriendlyNpcInstance) npc).setCanReturnToSpawnPoint(false); + } + else if (!npc.isInCombat() || !npc.isAttackingNow() || (npc.getTarget() == null)) + { + WorldObject target = npc.getTarget(); + if (target == null) + { + npc.setTarget(monster); + } + if ((target != null) && !target.isInvul() && target.isTargetable() && GeoEngine.getInstance().canSeeTarget(npc, target) && !CommonUtil.contains(NOT_ATK_NPCS, target.getId()) && !CommonUtil.contains(ETINA_HELPERS, target.getId())) + { + npc.setInvul(true); + npc.setRunning(); + ((FriendlyNpcInstance) npc).setCanReturnToSpawnPoint(false); + addAttackDesire(npc, (Creature) target); + // npc.reduceCurrentHp(1, monster, null); + } + } + } + } + } + + public void onCreatureAttacked(OnCreatureAttacked event) + { + final FriendlyNpcInstance npc = (FriendlyNpcInstance) event.getTarget(); + if (npc != null) + { + final Instance instance = npc.getInstanceWorld(); + if ((instance != null) && !event.getAttacker().isPlayable() && !CommonUtil.contains(ETINA_HELPERS, event.getAttacker().getId())) + { + if (!npc.isInCombat()) + { + if (getRandom(50) < 5) + { + npc.broadcastSay(ChatType.NPC_GENERAL, NpcStringId.DON_T_GET_IN_MY_WAY); + } + } + } + } + } + + public void onInstanceStatusChange(OnInstanceStatusChange event) + { + final Instance instance = event.getWorld(); + final int status = event.getStatus(); + if ((status == 1) || (status == 2) || (status == 3)) + { + instance.getAliveNpcs(ETINA_HELPER_ELIKIA).forEach(etinaHelperElikia -> getTimers().addRepeatingTimer("CHECK_ACTION", 3000, etinaHelperElikia, null)); + } + } + + @Override + public String onSeeCreature(Npc npc, Creature creature, boolean isSummon) + { + if (creature.isPlayer()) + { + npc.getVariables().set("PLAYER_OBJECT", creature.getActingPlayer()); + } + return super.onSeeCreature(npc, creature, isSummon); + } + + public static void main(String[] args) + { + new EtinaHelperElikia(); + } +} \ No newline at end of file diff --git a/L2J_Mobius_9.0_ReturnOfTheQueenAnt/dist/game/data/scripts/instances/EtisVanEtinaSolo/EtinaHelperLeona.java b/L2J_Mobius_9.0_ReturnOfTheQueenAnt/dist/game/data/scripts/instances/EtisVanEtinaSolo/EtinaHelperLeona.java new file mode 100644 index 0000000000..21f0035a18 --- /dev/null +++ b/L2J_Mobius_9.0_ReturnOfTheQueenAnt/dist/game/data/scripts/instances/EtisVanEtinaSolo/EtinaHelperLeona.java @@ -0,0 +1,203 @@ +/* + * 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 instances.EtisVanEtinaSolo; + +import org.l2jmobius.commons.util.CommonUtil; +import org.l2jmobius.gameserver.enums.ChatType; +import org.l2jmobius.gameserver.geoengine.GeoEngine; +import org.l2jmobius.gameserver.model.Location; +import org.l2jmobius.gameserver.model.StatSet; +import org.l2jmobius.gameserver.model.World; +import org.l2jmobius.gameserver.model.WorldObject; +import org.l2jmobius.gameserver.model.actor.Creature; +import org.l2jmobius.gameserver.model.actor.Npc; +import org.l2jmobius.gameserver.model.actor.instance.FriendlyNpcInstance; +import org.l2jmobius.gameserver.model.actor.instance.MonsterInstance; +import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; +import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureAttacked; +import org.l2jmobius.gameserver.model.events.impl.instance.OnInstanceStatusChange; +import org.l2jmobius.gameserver.model.instancezone.Instance; +import org.l2jmobius.gameserver.network.NpcStringId; + +import ai.AbstractNpcAI; + +/** + * Etina Helper Leona AI. + * @author CostyKiller + */ +public class EtinaHelperLeona extends AbstractNpcAI +{ + // NPCs + private static final int ETINA_HELPER_LEONA = 34471; + private static final int[] NOT_ATK_NPCS = + { + 33798, // Common Decoration - Barricade + 19677, // Seal of Gnosis + 19678, // Seal of Strife + 19679, // Seal of Avarice + 19680, // Seal of Punishment + 19681, // Seal of Awakening + 19682, // Seal of Calamity + 19683, // Seal of Destruction + }; + private static final int[] ETINA_HELPERS = + { + 34471, // Leona Blackbird + 34472, // Devianne + 34473, // Elikia + 34474, // Sporcha + 34475, // Aliber + }; + // RB + private static final int ETIS_VAN_ETINA1 = 26321; + private static final int ETIS_VAN_ETINA2 = 26322; + private static final int KAIN_VAN_HALTER = 26235; + private static final int CAMILLE = 26236; + // Misc + private static final int[] ETINA_SOLO_INSTANCES = + { + 292, // Fall of Etina (Solo) + 293, // Fall of Etina (Solo) + }; + + private EtinaHelperLeona() + { + setCreatureAttackedId(this::onCreatureAttacked, ETINA_HELPER_LEONA); + addSpellFinishedId(ETINA_HELPER_LEONA); + addSeeCreatureId(ETINA_HELPER_LEONA); + setInstanceStatusChangeId(this::onInstanceStatusChange, ETINA_SOLO_INSTANCES); + } + + @Override + public void onTimerEvent(String event, StatSet params, Npc npc, PlayerInstance player) + { + final Instance instance = npc.getInstanceWorld(); + if ((instance != null) && event.equals("CHECK_ACTION")) + { + final StatSet npcVars = npc.getVariables(); + final PlayerInstance plr = npcVars.getObject("PLAYER_OBJECT", PlayerInstance.class); + final MonsterInstance monster = getRandomEntry(World.getInstance().getVisibleObjectsInRange(npc, MonsterInstance.class, 2500)); + if (plr != null) + { + final double distance = npc.calculateDistance2D(plr); + if (!npc.isAttackingNow() && !npc.isMoving() && (distance > 250)) + { + final Location loc = new Location(plr.getX(), plr.getY(), plr.getZ() + 50); + final Location randLoc = new Location(loc.getX() + getRandom(-100, 100), loc.getY() + getRandom(-100, 100), loc.getZ()); + if (distance > 600) + { + npc.teleToLocation(loc); + } + else + { + npc.setRunning(); + } + addMoveToDesire(npc, randLoc, 23); + ((FriendlyNpcInstance) npc).setCanReturnToSpawnPoint(false); + } + else if (!npc.isInCombat() || !npc.isAttackingNow() || (npc.getTarget() == null)) + { + WorldObject target = npc.getTarget(); + if (target == null) + { + npc.setTarget(monster); + } + if ((target != null) && !target.isInvul() && target.isTargetable() && GeoEngine.getInstance().canSeeTarget(npc, target) && !CommonUtil.contains(NOT_ATK_NPCS, target.getId()) && !CommonUtil.contains(ETINA_HELPERS, target.getId())) + { + npc.setInvul(true); + npc.setRunning(); + ((FriendlyNpcInstance) npc).setCanReturnToSpawnPoint(false); + addAttackDesire(npc, (Creature) target); + // npc.reduceCurrentHp(1, monster, null); + } + } + } + } + } + + public void onCreatureAttacked(OnCreatureAttacked event) + { + final FriendlyNpcInstance npc = (FriendlyNpcInstance) event.getTarget(); + final Npc attacker = (Npc) event.getAttacker(); + if (npc != null) + { + final Instance instance = npc.getInstanceWorld(); + if ((instance != null) && !event.getAttacker().isPlayable() && !CommonUtil.contains(ETINA_HELPERS, event.getAttacker().getId())) + { + if (!npc.isInCombat()) + { + switch (attacker.getId()) + { + default: + { + if (getRandom(50) < 5) + { + npc.broadcastSay(ChatType.NPC_GENERAL, NpcStringId.DON_T_GET_IN_MY_WAY); + } + break; + } + case CAMILLE: + { + npc.broadcastSay(ChatType.NPC_GENERAL, NpcStringId.GISELLE_NO_IS_SHE_CAMILLE_IN_THAT_STATE); + break; + } + case KAIN_VAN_HALTER: + { + break; + } + case ETIS_VAN_ETINA1: + { + npc.broadcastSay(ChatType.NPC_GENERAL, NpcStringId.EVEN_THE_MIGHTY_ETINA_SEEMS_TO_FEAR_US); + break; + } + case ETIS_VAN_ETINA2: + { + npc.broadcastSay(ChatType.NPC_GENERAL, NpcStringId.ETIS_VAN_ETINA_WE_FINALLY_MEET); + break; + } + } + } + } + } + } + + public void onInstanceStatusChange(OnInstanceStatusChange event) + { + final Instance instance = event.getWorld(); + final int status = event.getStatus(); + if ((status == 1) || (status == 2) || (status == 3)) + { + instance.getAliveNpcs(ETINA_HELPER_LEONA).forEach(etinaHelperLeona -> getTimers().addRepeatingTimer("CHECK_ACTION", 3000, etinaHelperLeona, null)); + // instance.getAliveNpcs(ETINA_HELPER_LEONA).forEach(etinaHelperLeona -> getTimers().addRepeatingTimer("USE_SKILL", 6000, etinaHelperLeona, null)); + } + } + + @Override + public String onSeeCreature(Npc npc, Creature creature, boolean isSummon) + { + if (creature.isPlayer()) + { + npc.getVariables().set("PLAYER_OBJECT", creature.getActingPlayer()); + } + return super.onSeeCreature(npc, creature, isSummon); + } + + public static void main(String[] args) + { + new EtinaHelperLeona(); + } +} \ No newline at end of file diff --git a/L2J_Mobius_9.0_ReturnOfTheQueenAnt/dist/game/data/scripts/instances/EtisVanEtinaSolo/EtinaHelperSporcha.java b/L2J_Mobius_9.0_ReturnOfTheQueenAnt/dist/game/data/scripts/instances/EtisVanEtinaSolo/EtinaHelperSporcha.java new file mode 100644 index 0000000000..929fbe07ce --- /dev/null +++ b/L2J_Mobius_9.0_ReturnOfTheQueenAnt/dist/game/data/scripts/instances/EtisVanEtinaSolo/EtinaHelperSporcha.java @@ -0,0 +1,170 @@ +/* + * 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 instances.EtisVanEtinaSolo; + +import org.l2jmobius.commons.util.CommonUtil; +import org.l2jmobius.gameserver.enums.ChatType; +import org.l2jmobius.gameserver.geoengine.GeoEngine; +import org.l2jmobius.gameserver.model.Location; +import org.l2jmobius.gameserver.model.StatSet; +import org.l2jmobius.gameserver.model.World; +import org.l2jmobius.gameserver.model.WorldObject; +import org.l2jmobius.gameserver.model.actor.Creature; +import org.l2jmobius.gameserver.model.actor.Npc; +import org.l2jmobius.gameserver.model.actor.instance.FriendlyNpcInstance; +import org.l2jmobius.gameserver.model.actor.instance.MonsterInstance; +import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; +import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureAttacked; +import org.l2jmobius.gameserver.model.events.impl.instance.OnInstanceStatusChange; +import org.l2jmobius.gameserver.model.instancezone.Instance; +import org.l2jmobius.gameserver.network.NpcStringId; + +import ai.AbstractNpcAI; + +/** + * Etina Helper Sporcha AI. + * @author CostyKiller + */ +public class EtinaHelperSporcha extends AbstractNpcAI +{ + // NPCs + private static final int ETINA_HELPER_SPORCHA = 34474; + private static final int[] NOT_ATK_NPCS = + { + 33798, // Common Decoration - Barricade + 19677, // Seal of Gnosis + 19678, // Seal of Strife + 19679, // Seal of Avarice + 19680, // Seal of Punishment + 19681, // Seal of Awakening + 19682, // Seal of Calamity + 19683, // Seal of Destruction + }; + private static final int[] ETINA_HELPERS = + { + 34471, // Leona Blackbird + 34472, // Devianne + 34473, // Elikia + 34474, // Sporcha + 34475, // Aliber + }; + // Misc + private static final int[] ETINA_SOLO_INSTANCES = + { + 292, // Fall of Etina (Solo) + 293, // Fall of Etina (Solo) + }; + + private EtinaHelperSporcha() + { + setCreatureAttackedId(this::onCreatureAttacked, ETINA_HELPER_SPORCHA); + addSpellFinishedId(ETINA_HELPER_SPORCHA); + addSeeCreatureId(ETINA_HELPER_SPORCHA); + setInstanceStatusChangeId(this::onInstanceStatusChange, ETINA_SOLO_INSTANCES); + } + + @Override + public void onTimerEvent(String event, StatSet params, Npc npc, PlayerInstance player) + { + final Instance instance = npc.getInstanceWorld(); + if ((instance != null) && event.equals("CHECK_ACTION")) + { + final StatSet npcVars = npc.getVariables(); + final PlayerInstance plr = npcVars.getObject("PLAYER_OBJECT", PlayerInstance.class); + final MonsterInstance monster = getRandomEntry(World.getInstance().getVisibleObjectsInRange(npc, MonsterInstance.class, 2500)); + if (plr != null) + { + final double distance = npc.calculateDistance2D(plr); + if (!npc.isAttackingNow() && !npc.isMoving() && (distance > 250)) + { + final Location loc = new Location(plr.getX(), plr.getY(), plr.getZ() + 50); + final Location randLoc = new Location(loc.getX() + getRandom(-100, 100), loc.getY() + getRandom(-100, 100), loc.getZ()); + if (distance > 600) + { + npc.teleToLocation(loc); + } + else + { + npc.setRunning(); + } + addMoveToDesire(npc, randLoc, 23); + ((FriendlyNpcInstance) npc).setCanReturnToSpawnPoint(false); + } + else if (!npc.isInCombat() || !npc.isAttackingNow() || (npc.getTarget() == null)) + { + WorldObject target = npc.getTarget(); + if (target == null) + { + npc.setTarget(monster); + } + if ((target != null) && !target.isInvul() && target.isTargetable() && GeoEngine.getInstance().canSeeTarget(npc, target) && !CommonUtil.contains(NOT_ATK_NPCS, target.getId()) && !CommonUtil.contains(ETINA_HELPERS, target.getId())) + { + npc.setInvul(true); + npc.setRunning(); + ((FriendlyNpcInstance) npc).setCanReturnToSpawnPoint(false); + addAttackDesire(npc, (Creature) target); + // npc.reduceCurrentHp(1, monster, null); + } + } + } + } + } + + public void onCreatureAttacked(OnCreatureAttacked event) + { + final FriendlyNpcInstance npc = (FriendlyNpcInstance) event.getTarget(); + if (npc != null) + { + final Instance instance = npc.getInstanceWorld(); + if ((instance != null) && !event.getAttacker().isPlayable() && !CommonUtil.contains(ETINA_HELPERS, event.getAttacker().getId())) + { + if (!npc.isInCombat()) + { + if (getRandom(50) < 5) + { + npc.broadcastSay(ChatType.NPC_GENERAL, NpcStringId.DON_T_GET_IN_MY_WAY); + } + } + } + } + } + + public void onInstanceStatusChange(OnInstanceStatusChange event) + { + final Instance instance = event.getWorld(); + final int status = event.getStatus(); + if ((status == 1) || (status == 2) || (status == 3)) + { + instance.getAliveNpcs(ETINA_HELPER_SPORCHA).forEach(etinaHelperSporcha -> getTimers().addRepeatingTimer("CHECK_ACTION", 3000, etinaHelperSporcha, null)); + } + } + + @Override + public String onSeeCreature(Npc npc, Creature creature, boolean isSummon) + { + if (creature.isPlayer()) + { + npc.getVariables().set("PLAYER_OBJECT", creature.getActingPlayer()); + } + return super.onSeeCreature(npc, creature, isSummon); + } + + public static void main(String[] args) + { + new EtinaHelperSporcha(); + } +} \ No newline at end of file diff --git a/L2J_Mobius_9.0_ReturnOfTheQueenAnt/dist/game/data/scripts/instances/EtisVanEtinaSolo/EtisVanEtinaSolo.java b/L2J_Mobius_9.0_ReturnOfTheQueenAnt/dist/game/data/scripts/instances/EtisVanEtinaSolo/EtisVanEtinaSolo.java new file mode 100644 index 0000000000..8f1db0d8d6 --- /dev/null +++ b/L2J_Mobius_9.0_ReturnOfTheQueenAnt/dist/game/data/scripts/instances/EtisVanEtinaSolo/EtisVanEtinaSolo.java @@ -0,0 +1,723 @@ +/* + * 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 instances.EtisVanEtinaSolo; + +import org.l2jmobius.commons.util.CommonUtil; +import org.l2jmobius.gameserver.enums.ChatType; +import org.l2jmobius.gameserver.enums.Movie; +import org.l2jmobius.gameserver.model.World; +import org.l2jmobius.gameserver.model.actor.Attackable; +import org.l2jmobius.gameserver.model.actor.Npc; +import org.l2jmobius.gameserver.model.actor.instance.MonsterInstance; +import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; +import org.l2jmobius.gameserver.model.holders.SkillHolder; +import org.l2jmobius.gameserver.model.instancezone.Instance; +import org.l2jmobius.gameserver.model.skills.AbnormalVisualEffect; +import org.l2jmobius.gameserver.network.NpcStringId; +import org.l2jmobius.gameserver.network.serverpackets.ExShowScreenMessage; +import org.l2jmobius.gameserver.network.serverpackets.MagicSkillUse; + +import instances.AbstractInstance; + +/** + * @author CostyKiller + * @URL: https://l2wiki.com/Fall_of_Etina_(Solo) + * @URL: https://youtu.be/3flFpg0KGcA + * @TODO: Add helper npcs skills + * @TODO: Add instance buff Elikia Emblem + */ +public class EtisVanEtinaSolo extends AbstractInstance +{ + // NPC + private static final int LEONA_OUTLET = 34426; + private static final int LEONA_BLACKBIRD = 34471; + private static final int DEVIANNE = 34472; + private static final int ELIKIA = 34473; + private static final int SPORCHA = 34474; + private static final int ALIBER = 34475; + // RB + private static final int ETIS_VAN_ETINA1 = 26321; + private static final int ETIS_VAN_ETINA2 = 26322; + private static final int KAIN_VAN_HALTER = 26235; + private static final int CAMILLE = 26236; + // Corridor Mobs + //@formatter:off + private static final int[] CORRIDOR_MOBS_1 = {24173, 24174, 24175, 24176}; + private static final int[] CORRIDOR_MOBS_2 = {24180, 24181, 24182, 24183}; + private static final int[] CORRIDOR_MOBS_3 = {24184, 24185, 24186, 24187, 24188, 24189, 24190, 24191, 24192}; + private static final int[] CORRIDOR_MOBS_4 = {24189, 24190, 24191, 24192}; + //@formatter:on + private static final int PARAGON = 24193; + // Seals + private static final int SEAL_OF_GNOSIS = 19677; + private static final int SEAL_OF_STRIFE = 19678; + private static final int SEAL_OF_AVARICE = 19679; + private static final int SEAL_OF_PUNISHMENT = 19680; + private static final int SEAL_OF_AWAKENING = 19681; + private static final int SEAL_OF_CALAMITY = 19682; + private static final int SEAL_OF_DESTRUCTION = 19683; + // Others + private static final int DOOR1 = 12230702; + private static final int DOOR2 = 12230704; + private static final int DOOR3 = 12230802; + private static final int DOOR4 = 12230804; + // Skills + private static final SkillHolder CALL_OF_SEVEN_SIGNS = new SkillHolder(32317, 1); + private static final SkillHolder CALL_OF_SEVEN_SIGNS_SEAL_N = new SkillHolder(32004, 1); + private static final SkillHolder ETINA_REVELATION = new SkillHolder(32014, 2); + private static final SkillHolder STIGMA_OF_REVELATION = new SkillHolder(32015, 1); + private static final SkillHolder CRY_OF_HOLY_WAR = new SkillHolder(32017, 2); + private static final SkillHolder STIGMA_OF_MARTYR = new SkillHolder(32018, 1); + private static final SkillHolder UNDEAD_CREATURE = new SkillHolder(32020, 2); + private static final SkillHolder ETINA_DIVINE_PUNISHMENT = new SkillHolder(32023, 2); + private static final SkillHolder ETINA_OBSERVATION = new SkillHolder(32024, 2); + private static final SkillHolder RAGE_OF_THE_OPEN_EYE = new SkillHolder(32026, 2); + + // Camille -> Horseshoe Trampling, Horizon Bash, Joust Lunge, Call of Etina (summon minions?) + // Misc + private static final int TEMPLATE_ID = 293; + + public EtisVanEtinaSolo() + { + super(TEMPLATE_ID); + addInstanceCreatedId(TEMPLATE_ID); + addStartNpc(LEONA_OUTLET); + addTalkId(LEONA_OUTLET, LEONA_BLACKBIRD); + addFirstTalkId(LEONA_BLACKBIRD, DEVIANNE, ELIKIA, SPORCHA, ALIBER); + addAttackId(CORRIDOR_MOBS_1); + addAttackId(CORRIDOR_MOBS_2); + addAttackId(CORRIDOR_MOBS_3); + addAttackId(CORRIDOR_MOBS_4); + addAttackId(CAMILLE, KAIN_VAN_HALTER, ETIS_VAN_ETINA1, ETIS_VAN_ETINA2); + addKillId(CORRIDOR_MOBS_1); + addKillId(CORRIDOR_MOBS_2); + addKillId(CORRIDOR_MOBS_3); + addKillId(CORRIDOR_MOBS_4); + addKillId(PARAGON, CAMILLE, KAIN_VAN_HALTER, ETIS_VAN_ETINA1, ETIS_VAN_ETINA2); + } + + @Override + public void onInstanceCreated(Instance world, PlayerInstance player) + { + world.setStatus(0); + world.getParameters().set("BARRICADE_DESTROYED", false); + world.getParameters().set("CORRIDOR_MOBS_1_SPAWNED", false); + world.getParameters().set("CORRIDOR_MOBS_2_SPAWNED", false); + world.getParameters().set("CORRIDOR_MOBS_3_SPAWNED", false); + world.getParameters().set("CORRIDOR_MOBS_4_SPAWNED", false); + world.getParameters().set("CAMILLE_30", false); + world.getParameters().set("CAMILLE_60", false); + world.getParameters().set("KAIN_30", false); + world.getParameters().set("KAIN_60", false); + world.getParameters().set("ETINA_80", false); + world.getParameters().set("ETINA_15", false); + } + + @Override + public String onAdvEvent(String event, Npc npc, PlayerInstance player) + { + switch (event) + { + case "enterInstance": + { + playMovie(player, Movie.EP5_ETINA_QST_START_A); + startQuestTimer("enterEtina", 20000, npc, player); + startQuestTimer("intro_movie", 20000, npc, player); + startQuestTimer("talkLeona", 25000, npc, player); + break; + } + case "enterEtina": + { + enterInstance(player, npc, TEMPLATE_ID); + break; + } + case "intro_movie": + { + final Instance world = player.getInstanceWorld(); + if (isInInstance(world)) + { + playMovie(world.getPlayers(), Movie.EP5_ETINA_QST_START_B); + } + break; + } + case "talkLeona": + { + final Instance world = player.getInstanceWorld(); + if (isInInstance(world)) + { + showOnScreenMsg(world, NpcStringId.TALK_TO_LEONA_BLACKBIRD_13, ExShowScreenMessage.TOP_CENTER, 10000, true); + } + break; + } + case "startStage1": + { + final Instance world = player.getInstanceWorld(); + if (isInInstance(world)) + { + showOnScreenMsg(world, NpcStringId.ALRIGHT_LET_S_GO_DEFEAT_ETIS_VAN_ETINA, ExShowScreenMessage.TOP_CENTER, 7000, true); + startQuestTimer("checkProgress", 5000, npc, player, true); + world.setStatus(1); + return "34471-01.html"; + } + break; + } + case "checkProgress": + { + final Instance world = player.getInstanceWorld(); + boolean CORRIDOR_MOBS_1_SPAWNED = world.getParameters().getBoolean("CORRIDOR_MOBS_1_SPAWNED", false); + boolean CORRIDOR_MOBS_2_SPAWNED = world.getParameters().getBoolean("CORRIDOR_MOBS_2_SPAWNED", false); + boolean CORRIDOR_MOBS_3_SPAWNED = world.getParameters().getBoolean("CORRIDOR_MOBS_3_SPAWNED", false); + boolean CORRIDOR_MOBS_4_SPAWNED = world.getParameters().getBoolean("CORRIDOR_MOBS_4_SPAWNED", false); + if (isInInstance(world)) + { + final MonsterInstance monsterCheck = getRandomEntry(World.getInstance().getVisibleObjectsInRange(npc, MonsterInstance.class, 2500)); + if (monsterCheck == null) + { + if (!world.getNpcsOfGroup("BARRICADES_2").isEmpty() && world.getAliveNpcs(CORRIDOR_MOBS_1).isEmpty() && world.getNpcsOfGroup("BARRICADES_1").isEmpty()) + { + world.getParameters().set("BARRICADE_DESTROYED", false); + } + else if (!world.getNpcsOfGroup("BARRICADES_3").isEmpty() && world.getAliveNpcs(CORRIDOR_MOBS_2).isEmpty() && world.getNpcsOfGroup("BARRICADES_2").isEmpty()) + { + world.getParameters().set("BARRICADE_DESTROYED", false); + } + else if (!world.getNpcsOfGroup("BARRICADES_4").isEmpty() && world.getAliveNpcs(CORRIDOR_MOBS_3).isEmpty() && world.getNpcsOfGroup("BARRICADES_3").isEmpty()) + { + world.getParameters().set("BARRICADE_DESTROYED", false); + } + } + if (!CORRIDOR_MOBS_1_SPAWNED && world.getNpcsOfGroup("BARRICADES_1").isEmpty() && !world.getNpcsOfGroup("BARRICADES_2").isEmpty() && world.getAliveNpcs(CORRIDOR_MOBS_1).isEmpty()) + { + world.spawnGroup("CORRIDOR_MOBS_1"); + world.getNpcsOfGroup("CORRIDOR_MOBS_1").forEach(mob -> + { + if (mob != null) + { + mob.setRandomWalking(false); + } + }); + world.getParameters().set("CORRIDOR_MOBS_1_SPAWNED", true); + } + if (!CORRIDOR_MOBS_2_SPAWNED && world.getNpcsOfGroup("BARRICADES_2").isEmpty() && !world.getNpcsOfGroup("BARRICADES_3").isEmpty() && world.getAliveNpcs(CORRIDOR_MOBS_2).isEmpty()) + { + world.spawnGroup("CORRIDOR_MOBS_2"); + world.getNpcsOfGroup("CORRIDOR_MOBS_2").forEach(mob -> + { + if (mob != null) + { + mob.setRandomWalking(false); + } + }); + world.getParameters().set("CORRIDOR_MOBS_2_SPAWNED", true); + } + if (!CORRIDOR_MOBS_3_SPAWNED && world.getNpcsOfGroup("BARRICADES_3").isEmpty() && !world.getNpcsOfGroup("BARRICADES_4").isEmpty() && world.getAliveNpcs(CORRIDOR_MOBS_3).isEmpty()) + { + world.spawnGroup("CORRIDOR_MOBS_3"); + world.getNpcsOfGroup("CORRIDOR_MOBS_3").forEach(mob -> + { + if (mob != null) + { + mob.setRandomWalking(false); + } + }); + world.getParameters().set("CORRIDOR_MOBS_3_SPAWNED", true); + } + if (!CORRIDOR_MOBS_4_SPAWNED && world.getNpcsOfGroup("BARRICADES_4").isEmpty() && world.getAliveNpcs(CORRIDOR_MOBS_4).isEmpty()) + { + world.spawnGroup("CORRIDOR_MOBS_4"); + world.spawnGroup("PARAGON"); + world.getParameters().set("CORRIDOR_MOBS_4_SPAWNED", true); + world.getNpcsOfGroup("CORRIDOR_MOBS_4").forEach(mob -> + { + if (mob != null) + { + mob.setRandomWalking(false); + } + }); + if (world.getNpc(PARAGON) != null) + { + world.getNpc(PARAGON).setInvul(true); + world.getNpc(PARAGON).getEffectList().startAbnormalVisualEffect(AbnormalVisualEffect.INVINCIBILITY); + } + npc.broadcastPacket(new ExShowScreenMessage(NpcStringId.YOU_CAN_T_DEFEAT_PARAGON_WHILE_PARAGON_S_MINIONS_ARE_ALIVE, ExShowScreenMessage.TOP_CENTER, 7000, true)); + } + if (world.getNpcsOfGroup("BARRICADES_4").isEmpty() && world.getAliveNpcs(CORRIDOR_MOBS_4).isEmpty()) + { + if ((world.getNpc(PARAGON) != null) && world.getNpc(PARAGON).isInvul()) + { + world.getNpc(PARAGON).setInvul(false); + world.getNpc(PARAGON).getEffectList().stopAbnormalVisualEffect(AbnormalVisualEffect.INVINCIBILITY); + showOnScreenMsg(world, NpcStringId.PARAGON_IS_NO_LONGER_INVINCIBLE, ExShowScreenMessage.TOP_CENTER, 7000, true); + world.getNpc(LEONA_BLACKBIRD).broadcastSay(ChatType.NPC_GENERAL, NpcStringId.TODAY_IS_THE_DAY_THAT_I_WILL_ENTER); + } + } + if ((world.getStatus() == 1) && world.getNpcsOfGroup("BARRICADES_4").isEmpty() && (world.getAliveNpcs(PARAGON).isEmpty())) + { + startQuestTimer("openInnerDoors", 5000, null, player); + cancelQuestTimer("checkProgress", npc, player); + } + } + break; + } + case "openInnerDoors": + { + final Instance world = player.getInstanceWorld(); + if (isInInstance(world)) + { + openDoor(DOOR1, world.getId()); + openDoor(DOOR2, world.getId()); + openDoor(DOOR3, world.getId()); + openDoor(DOOR4, world.getId()); + world.setStatus(2); + startQuestTimer("talkLeona", 5000, null, player); + } + break; + } + case "startStage2": + { + final Instance world = player.getInstanceWorld(); + if (isInInstance(world)) + { + startQuestTimer("show_intro_movie_camille", 5000, null, player); + return "34471-03.html"; + } + break; + } + case "show_intro_movie_camille": + { + final Instance world = player.getInstanceWorld(); + if (isInInstance(world)) + { + playMovie(world.getPlayers(), Movie.SC_INZONE_CAMILLE_INTRO); + startQuestTimer("spawn_camille", 5000, null, player); + } + break; + } + case "spawn_camille": + { + final Instance world = player.getInstanceWorld(); + if (isInInstance(world)) + { + closeDoor(DOOR1, world.getId()); + closeDoor(DOOR2, world.getId()); + closeDoor(DOOR3, world.getId()); + closeDoor(DOOR4, world.getId()); + world.setStatus(3); + world.spawnGroup("CAMILLE"); + world.getNpc(LEONA_BLACKBIRD).broadcastSay(ChatType.NPC_GENERAL, NpcStringId.GISELLE_NO_IS_SHE_CAMILLE_IN_THAT_STATE); + } + break; + } + case "spawn_kain": + { + final Instance world = player.getInstanceWorld(); + if (isInInstance(world)) + { + world.spawnGroup("KAIN"); + world.spawnGroup("ETINA_1"); + world.getNpc(ETIS_VAN_ETINA1).setInvul(true); + world.getNpc(ETIS_VAN_ETINA1).setTargetable(false); + world.getNpc(ETIS_VAN_ETINA1).setImmobilized(true); + showOnScreenMsg(world, NpcStringId.ETIS_VAN_ETINA_AND_HIS_APOSTLES_HAVE_APPEARED, ExShowScreenMessage.TOP_CENTER, 7000, true); + world.getNpc(LEONA_BLACKBIRD).broadcastSay(ChatType.NPC_GENERAL, NpcStringId.EVEN_THE_MIGHTY_ETINA_SEEMS_TO_FEAR_US); + } + break; + } + case "spawnTransformedEtina": + { + final Instance world = player.getInstanceWorld(); + if (isInInstance(world)) + { + world.spawnGroup("ETINA_2"); + world.spawnGroup("ETINA_MINIONS"); + world.getNpc(LEONA_BLACKBIRD).broadcastSay(ChatType.NPC_GENERAL, NpcStringId.ETIS_VAN_ETINA_WE_FINALLY_MEET); + } + break; + } + case "gnosisCastTimer": + { + final Instance world = player.getInstanceWorld(); + if (isInInstance(world)) + { + final Npc _sealOfGnosis = world.getNpc(SEAL_OF_GNOSIS); + _sealOfGnosis.setDisplayEffect(3); + _sealOfGnosis.broadcastPacket(new MagicSkillUse(_sealOfGnosis, _sealOfGnosis, CALL_OF_SEVEN_SIGNS_SEAL_N.getSkillId(), 1, 10000, 0)); + PlayerInstance member = world.getPlayers().stream().findAny().get(); + STIGMA_OF_REVELATION.getSkill().applyEffects(member, member); + world.getNpcsOfGroup("ETINA_MINIONS").forEach(minion -> + { + if (minion != null) + { + ETINA_REVELATION.getSkill().applyEffects(minion, minion); + ((Attackable) minion).addDamageHate(member, 0, 999999999); + } + }); + showOnScreenMsg(world, NpcStringId.THE_SEAL_OF_GNOSIS_ACTIVATES_AND_ENORMOUS_POWER_BEGINS_TO_FLOW_OUT, ExShowScreenMessage.TOP_CENTER, 7000, true); + } + break; + } + case "strifeCastTimer": + { + final Instance world = player.getInstanceWorld(); + if (isInInstance(world)) + { + final Npc _sealOfStrife = world.getNpc(SEAL_OF_STRIFE); + _sealOfStrife.setDisplayEffect(3); + _sealOfStrife.broadcastPacket(new MagicSkillUse(_sealOfStrife, _sealOfStrife, CALL_OF_SEVEN_SIGNS_SEAL_N.getSkillId(), 2, 10000, 0)); + world.getNpcsOfGroup("ETINA_MINIONS").forEach(minion -> + { + if (minion != null) + { + CRY_OF_HOLY_WAR.getSkill().applyEffects(minion, minion); + } + }); + world.getPlayers().forEach(plr -> STIGMA_OF_MARTYR.getSkill().applyEffects(player, player)); + showOnScreenMsg(world, NpcStringId.THE_SEAL_OF_STRIFE_ACTIVATES_AND_ENORMOUS_POWER_BEGINS_TO_FLOW_OUT, ExShowScreenMessage.TOP_CENTER, 7000, true); + } + break; + } + case "avariceCastTimer": + { + final Instance world = player.getInstanceWorld(); + if (isInInstance(world)) + { + final Npc _sealOfAvarice = world.getNpc(SEAL_OF_AVARICE); + _sealOfAvarice.setDisplayEffect(3); + _sealOfAvarice.broadcastPacket(new MagicSkillUse(_sealOfAvarice, _sealOfAvarice, CALL_OF_SEVEN_SIGNS_SEAL_N.getSkillId(), 3, 10000, 0)); + world.getNpcsOfGroup("ETINA_MINIONS").forEach(minion -> + { + if (minion != null) + { + UNDEAD_CREATURE.getSkill().applyEffects(minion, minion); + } + }); + showOnScreenMsg(world, NpcStringId.THE_SEAL_OF_AVARICE_ACTIVATES_AND_ENORMOUS_POWER_BEGINS_TO_FLOW_OUT, ExShowScreenMessage.TOP_CENTER, 7000, true); + } + break; + } + case "punishmentCastTimer": + { + final Instance world = player.getInstanceWorld(); + if (isInInstance(world)) + { + final Npc _sealOfPunishment = world.getNpc(SEAL_OF_PUNISHMENT); + _sealOfPunishment.setDisplayEffect(3); + _sealOfPunishment.broadcastPacket(new MagicSkillUse(_sealOfPunishment, _sealOfPunishment, CALL_OF_SEVEN_SIGNS_SEAL_N.getSkillId(), 4, 10000, 0)); + world.getNpcsOfGroup("ETINA_MINIONS").forEach(minion -> + { + if (minion != null) + { + ETINA_DIVINE_PUNISHMENT.getSkill().applyEffects(minion, minion); + } + }); + world.getPlayers().forEach(plr -> ETINA_OBSERVATION.getSkill().applyEffects(player, player)); + showOnScreenMsg(world, NpcStringId.THE_SEAL_OF_PUNISHMENT_ACTIVATES_AND_ENORMOUS_POWER_BEGINS_TO_FLOW_OUT, ExShowScreenMessage.TOP_CENTER, 7000, true); + } + break; + } + case "awakeningCastTimer": + { + final Instance world = player.getInstanceWorld(); + if (isInInstance(world)) + { + final Npc _sealOfAwakening = world.getNpc(SEAL_OF_AWAKENING); + _sealOfAwakening.setDisplayEffect(3); + _sealOfAwakening.broadcastPacket(new MagicSkillUse(_sealOfAwakening, _sealOfAwakening, CALL_OF_SEVEN_SIGNS_SEAL_N.getSkillId(), 5, 10000, 0)); + world.getNpcsOfGroup("ETINA_MINIONS").forEach(minion -> + { + if (minion != null) + { + RAGE_OF_THE_OPEN_EYE.getSkill().applyEffects(minion, minion); + } + }); + showOnScreenMsg(world, NpcStringId.THE_SEAL_OF_AWAKENING_ACTIVATES_AND_ENORMOUS_POWER_BEGINS_TO_FLOW_OUT, ExShowScreenMessage.TOP_CENTER, 7000, true); + } + break; + } + case "calamityCastTimer": + { + final Instance world = player.getInstanceWorld(); + if (isInInstance(world)) + { + final Npc _sealOfCalamity = world.getNpc(SEAL_OF_CALAMITY); + _sealOfCalamity.setDisplayEffect(3); + _sealOfCalamity.broadcastPacket(new MagicSkillUse(_sealOfCalamity, _sealOfCalamity, CALL_OF_SEVEN_SIGNS_SEAL_N.getSkillId(), 6, 10000, 0)); + showOnScreenMsg(world, NpcStringId.THE_SEAL_OF_CALAMITY_ACTIVATES_AND_ENORMOUS_POWER_BEGINS_TO_FLOW_OUT, ExShowScreenMessage.TOP_CENTER, 7000, true); + } + break; + } + case "destructionCastTimer": + { + final Instance world = player.getInstanceWorld(); + if (isInInstance(world)) + { + final Npc _sealOfDestruction = world.getNpc(SEAL_OF_DESTRUCTION); + _sealOfDestruction.setDisplayEffect(3); + _sealOfDestruction.broadcastPacket(new MagicSkillUse(_sealOfDestruction, _sealOfDestruction, CALL_OF_SEVEN_SIGNS_SEAL_N.getSkillId(), 7, 10000, 0)); + showOnScreenMsg(world, NpcStringId.THE_SEAL_OF_DESTRUCTION_IS_ACTIVATED_AND_ETINA_S_GRAND_TEMPLE_IS_NOW_UNDER_ITS_INFLUENCE, ExShowScreenMessage.TOP_CENTER, 7000, true); + } + break; + } + } + return super.onAdvEvent(event, npc, player); + } + + @Override + public String onAttack(Npc npc, PlayerInstance attacker, int damage, boolean isSummon) + { + final Instance world = attacker.getInstanceWorld(); + if (isInInstance(world)) + { + final boolean CAMILLE_30 = world.getParameters().getBoolean("CAMILLE_30", false); + final boolean CAMILLE_60 = world.getParameters().getBoolean("CAMILLE_60", false); + final boolean KAIN_30 = world.getParameters().getBoolean("KAIN_30", false); + final boolean KAIN_60 = world.getParameters().getBoolean("KAIN_60", false); + final boolean ETINA_80 = world.getParameters().getBoolean("ETINA_80", false); + final boolean ETINA_15 = world.getParameters().getBoolean("ETINA_15", false); + if (npc.getId() == CAMILLE) + { + if ((npc.getCurrentHp() <= (npc.getMaxHp() * 0.3)) && !CAMILLE_30) + { + world.getParameters().set("CAMILLE_30", true); + world.spawnGroup("CAMILLE_MINIONS"); + } + else if ((npc.getCurrentHp() <= (npc.getMaxHp() * 0.6)) && !CAMILLE_60) + { + world.getParameters().set("CAMILLE_60", true); + world.spawnGroup("CAMILLE_MINIONS"); + } + } + else if (npc.getId() == KAIN_VAN_HALTER) + { + if ((npc.getCurrentHp() <= (npc.getMaxHp() * 0.3)) && !KAIN_30) + { + world.getParameters().set("KAIN_30", true); + showOnScreenMsg(world, NpcStringId.ETIS_VAN_ETINA_SUMMONS_HIS_APOSTLES_MINIONS, ExShowScreenMessage.TOP_CENTER, 7000, true); + world.spawnGroup("KAIN_MINIONS"); + } + else if ((npc.getCurrentHp() <= (npc.getMaxHp() * 0.6)) && !KAIN_60) + { + world.getParameters().set("KAIN_60", true); + showOnScreenMsg(world, NpcStringId.ETIS_VAN_ETINA_SUMMONS_HIS_APOSTLES_MINIONS, ExShowScreenMessage.TOP_CENTER, 7000, true); + world.spawnGroup("KAIN_MINIONS"); + } + } + else if ((npc.getId() == ETIS_VAN_ETINA1)) + { + if ((npc.getCurrentHp() <= (npc.getMaxHp() * 0.8)) && !ETINA_80) + { + final Npc _etina1 = world.getNpc(ETIS_VAN_ETINA1); + world.getParameters().set("ETINA_80", true); + world.spawnGroup("ETINA_MINIONS"); + _etina1.abortCast(); + _etina1.broadcastPacket(new MagicSkillUse(_etina1, _etina1, CALL_OF_SEVEN_SIGNS.getSkillId(), CALL_OF_SEVEN_SIGNS.getSkillLevel(), 3000, 0)); + showOnScreenMsg(world, NpcStringId.ETIS_VAN_ETINA_USES_THE_POWER_OF_THE_SEVEN_SIGNS_TO_SUMMON_ALL_7_SEALS_INSIDE_THE_TEMPLE, ExShowScreenMessage.TOP_CENTER, 7000, true); + world.spawnGroup("SEALS"); + startQuestTimer("gnosisCastTimer", 120000, npc, attacker, true); + startQuestTimer("strifeCastTimer", 120000, npc, attacker, true); + startQuestTimer("avariceCastTimer", 120000, npc, attacker, true); + startQuestTimer("punishmentCastTimer", 120000, npc, attacker, true); + startQuestTimer("awakeningCastTimer", 120000, npc, attacker, true); + startQuestTimer("calamityCastTimer", 120000, npc, attacker, true); + startQuestTimer("destructionCastTimer", 120000, npc, attacker, true); + } + else if ((npc.getCurrentHp() <= (npc.getMaxHp() * 0.15)) && !ETINA_15) + { + world.getParameters().set("ETINA_15", true); + world.spawnGroup("ETINA_MINIONS"); + showOnScreenMsg(world, NpcStringId.ETIS_VAN_ETINA_AND_THE_POWER_OF_SIX_SEALS_ARE_WEAKENING, ExShowScreenMessage.TOP_CENTER, 7000, true); + } + } + } + return super.onAttack(npc, attacker, damage, isSummon); + } + + @Override + public String onKill(Npc npc, PlayerInstance killer, boolean isPet) + { + final Instance world = npc.getInstanceWorld(); + if (isInInstance(world)) + { + if (npc.getId() == ETIS_VAN_ETINA1) + { + playMovie(world.getPlayers(), Movie.SC_ETIS_VAN_ETINA_TRANS); + startQuestTimer("spawnTransformedEtina", 15000, null, killer); + } + else if (npc.getId() == ETIS_VAN_ETINA2) + { + playMovie(world.getPlayers(), Movie.SC_ETIS_VAN_ETINA_ENDING); + world.getAliveNpcs().forEach(mob -> + { + mob.deleteMe(); + }); + if (getQuestTimer("gnosisCastTimer", npc, killer) != null) + { + cancelQuestTimer("gnosisCastTimer", npc, killer); + } + if (getQuestTimer("trifeCastTimer", npc, killer) != null) + { + cancelQuestTimer("strifeCastTimer", npc, killer); + } + if (getQuestTimer("avariceCastTimer", npc, killer) != null) + { + cancelQuestTimer("avariceCastTimer", npc, killer); + } + if (getQuestTimer("punishmentCastTimer", npc, killer) != null) + { + cancelQuestTimer("punishmentCastTimer", npc, killer); + } + if (getQuestTimer("awakeningCastTimer", npc, killer) != null) + { + cancelQuestTimer("awakeningCastTimer", npc, killer); + } + if (getQuestTimer("calamityCastTimer", npc, killer) != null) + { + cancelQuestTimer("calamityCastTimer", npc, killer); + } + if (getQuestTimer("destructionCastTimer", npc, killer) != null) + { + cancelQuestTimer("destructionCastTimer", npc, killer); + } + closeDoor(DOOR1, world.getId()); + closeDoor(DOOR2, world.getId()); + closeDoor(DOOR3, world.getId()); + closeDoor(DOOR4, world.getId()); + world.finishInstance(2); + } + else if (CommonUtil.contains(CORRIDOR_MOBS_1, npc.getId())) + { + if (world.getAliveNpcs(CORRIDOR_MOBS_1).isEmpty()) + { + world.getParameters().set("BARRICADE_DESTROYED", false); + } + } + else if (CommonUtil.contains(CORRIDOR_MOBS_2, npc.getId())) + { + if (world.getAliveNpcs(CORRIDOR_MOBS_2).isEmpty()) + { + world.getParameters().set("BARRICADE_DESTROYED", false); + } + } + else if (CommonUtil.contains(CORRIDOR_MOBS_3, npc.getId())) + { + if (world.getAliveNpcs(CORRIDOR_MOBS_3).isEmpty()) + { + world.getParameters().set("BARRICADE_DESTROYED", false); + } + } + else if (CommonUtil.contains(CORRIDOR_MOBS_4, npc.getId())) + { + if (world.getAliveNpcs(CORRIDOR_MOBS_4).isEmpty()) + { + world.getNpc(PARAGON).setInvul(false); + world.getNpc(PARAGON).getEffectList().stopAbnormalVisualEffect(AbnormalVisualEffect.INVINCIBILITY); + showOnScreenMsg(world, NpcStringId.PARAGON_IS_NO_LONGER_INVINCIBLE, ExShowScreenMessage.TOP_CENTER, 7000, true); + world.getNpc(LEONA_BLACKBIRD).broadcastSay(ChatType.NPC_GENERAL, NpcStringId.TODAY_IS_THE_DAY_THAT_I_WILL_ENTER); + } + } + else if (npc.getId() == PARAGON) + { + startQuestTimer("openInnerDoors", 5000, null, killer); + } + else if (npc.getId() == CAMILLE) + { + world.getNpcsOfGroup("CAMILLE_MINIONS").forEach(minion -> + { + if (minion != null) + { + minion.doDie(null); + } + }); + world.getNpc(CAMILLE).deleteMe(); + world.getNpc(LEONA_BLACKBIRD).broadcastSay(ChatType.NPC_GENERAL, NpcStringId.KAIN_IS_OUR_ENEMY_NOW_BE_ON_GUARD); + playMovie(world.getPlayers(), Movie.SC_INZONE_KAIN_INTRO); + startQuestTimer("spawn_kain", 5000, null, killer); + } + else if (npc.getId() == KAIN_VAN_HALTER) + { + world.getNpcsOfGroup("KAIN_MINIONS").forEach(minion -> + { + if (minion != null) + { + minion.doDie(null); + } + }); + world.getNpc(ETIS_VAN_ETINA1).setInvul(false); + world.getNpc(ETIS_VAN_ETINA1).setImmobilized(false); + world.getNpc(ETIS_VAN_ETINA1).setTargetable(true); + showOnScreenMsg(world, NpcStringId.ETIS_VAN_ETINA_APPROACHES, ExShowScreenMessage.TOP_CENTER, 7000, true); + world.getNpc(KAIN_VAN_HALTER).deleteMe(); + playMovie(world.getPlayers(), Movie.SC_KAIN_BOSS_ENDING); + world.getNpc(LEONA_BLACKBIRD).broadcastSay(ChatType.NPC_GENERAL, NpcStringId.KAIN_I_WON_T_FEEL_GUILTY_ABOUT_THIS); + } + } + return super.onKill(npc, killer, isPet); + } + + @Override + public String onFirstTalk(Npc npc, PlayerInstance player) + { + final Instance world = player.getInstanceWorld(); + String htmltext = null; + if (isInInstance(world)) + { + switch (npc.getId()) + { + case DEVIANNE: + case ELIKIA: + case SPORCHA: + case ALIBER: + { + htmltext = npc.getId() + ".html"; + break; + } + case LEONA_BLACKBIRD: + { + switch (world.getStatus()) + { + case 0: + { + htmltext = "34471.htm"; + break; + } + case 1: + { + htmltext = "34471-01.html"; + break; + } + case 2: + { + htmltext = "34471-02.htm"; + break; + } + case 3: + { + htmltext = "34471-03.html"; + break; + } + } + } + } + } + return htmltext; + } + + public static void main(String[] args) + { + new EtisVanEtinaSolo(); + } +} \ No newline at end of file diff --git a/L2J_Mobius_9.0_ReturnOfTheQueenAnt/dist/game/data/scripts/instances/EtisVanEtinaSolo/condNoGroup.html b/L2J_Mobius_9.0_ReturnOfTheQueenAnt/dist/game/data/scripts/instances/EtisVanEtinaSolo/condNoGroup.html new file mode 100644 index 0000000000..a34d6f3c14 --- /dev/null +++ b/L2J_Mobius_9.0_ReturnOfTheQueenAnt/dist/game/data/scripts/instances/EtisVanEtinaSolo/condNoGroup.html @@ -0,0 +1,3 @@ +Leona Blackbird:
+You can enter only solo. + \ No newline at end of file diff --git a/L2J_Mobius_9.0_ReturnOfTheQueenAnt/dist/game/data/scripts/instances/EtisVanEtinaSolo/condNoLevel.html b/L2J_Mobius_9.0_ReturnOfTheQueenAnt/dist/game/data/scripts/instances/EtisVanEtinaSolo/condNoLevel.html new file mode 100644 index 0000000000..5a53e17332 --- /dev/null +++ b/L2J_Mobius_9.0_ReturnOfTheQueenAnt/dist/game/data/scripts/instances/EtisVanEtinaSolo/condNoLevel.html @@ -0,0 +1,4 @@ +Leona Blackbird:
+I won't let you enter.
+(Only players between levels 104-130 may participate.) + \ No newline at end of file diff --git a/L2J_Mobius_9.0_ReturnOfTheQueenAnt/dist/game/data/stats/npcs/24100-24199.xml b/L2J_Mobius_9.0_ReturnOfTheQueenAnt/dist/game/data/stats/npcs/24100-24199.xml index 4421f21547..1fe8ac7fb3 100644 --- a/L2J_Mobius_9.0_ReturnOfTheQueenAnt/dist/game/data/stats/npcs/24100-24199.xml +++ b/L2J_Mobius_9.0_ReturnOfTheQueenAnt/dist/game/data/stats/npcs/24100-24199.xml @@ -2270,6 +2270,11 @@ + + + ETINA_SOLO + + @@ -2296,6 +2301,11 @@ + + + ETINA_SOLO + + @@ -2322,6 +2332,11 @@ + + + ETINA_SOLO + + @@ -2348,6 +2363,11 @@ + + + ETINA_SOLO + + @@ -2373,6 +2393,11 @@ + + + ETINA_SOLO + + @@ -2398,6 +2423,11 @@ + + + ETINA_SOLO + + @@ -2423,6 +2453,11 @@ + + + ETINA_SOLO + + @@ -2448,6 +2483,11 @@ + + + ETINA_SOLO + + @@ -2473,6 +2513,11 @@ + + + ETINA_SOLO + + @@ -2498,6 +2543,11 @@ + + + ETINA_SOLO + + @@ -2523,6 +2573,11 @@ + + + ETINA_SOLO + + @@ -2548,6 +2603,11 @@ + + + ETINA_SOLO + + @@ -2573,6 +2633,11 @@ + + + ETINA_SOLO + + @@ -2598,6 +2663,11 @@ + + + ETINA_SOLO + + @@ -2609,7 +2679,7 @@
- + HUMANOID FEMALE @@ -2622,6 +2692,11 @@ + + + ETINA_SOLO + + @@ -2634,7 +2709,7 @@ - + DEMONIC MALE @@ -2647,6 +2722,11 @@ + + + ETINA_SOLO + + @@ -3102,6 +3182,11 @@ + + + ETINA_SOLO + + @@ -3127,6 +3212,11 @@ + + + ETINA_SOLO + + @@ -3152,6 +3242,11 @@ + + + ETINA_SOLO + + @@ -3163,24 +3258,34 @@ - - + ETC FEMALE - + + + - - - + + + + ETINA_SOLO + + + + + + + + diff --git a/L2J_Mobius_9.0_ReturnOfTheQueenAnt/dist/game/data/stats/npcs/26300-26399.xml b/L2J_Mobius_9.0_ReturnOfTheQueenAnt/dist/game/data/stats/npcs/26300-26399.xml index 4ea02626c1..050c98e131 100644 --- a/L2J_Mobius_9.0_ReturnOfTheQueenAnt/dist/game/data/stats/npcs/26300-26399.xml +++ b/L2J_Mobius_9.0_ReturnOfTheQueenAnt/dist/game/data/stats/npcs/26300-26399.xml @@ -509,43 +509,103 @@
- - - ETC - FEMALE + + HUMANOID + MALE - + + + - - - + + + + ETINA_SOLO + + + + + + + + - - - ETC - FEMALE + + HUMANOID + MALE + - + + + - - - + + + + ETINA_SOLO + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + DEMONIC @@ -560,6 +620,11 @@ + + + ETINA_SOLO + + @@ -585,6 +650,11 @@ + + + ETINA_SOLO + + @@ -610,6 +680,11 @@ + + + ETINA_SOLO + + @@ -635,6 +710,11 @@ + + + ETINA_SOLO + +