diff --git a/L2J_Mobius_5.5_EtinasFate/dist/game/data/scripts/ai/areas/SeaOfSpores/SeaOfSpores.java b/L2J_Mobius_5.5_EtinasFate/dist/game/data/scripts/ai/areas/SeaOfSpores/SeaOfSpores.java new file mode 100644 index 0000000000..f76b4463cb --- /dev/null +++ b/L2J_Mobius_5.5_EtinasFate/dist/game/data/scripts/ai/areas/SeaOfSpores/SeaOfSpores.java @@ -0,0 +1,141 @@ +/* + * This file is part of the L2J Mobius project. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ai.areas.SeaOfSpores; + +import java.util.ArrayList; +import java.util.List; + +import org.l2jmobius.commons.util.CommonUtil; +import org.l2jmobius.gameserver.model.actor.Npc; +import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; +import org.l2jmobius.gameserver.model.holders.SkillHolder; + +import ai.AbstractNpcAI; + +/** + * @author NviX + */ +public class SeaOfSpores extends AbstractNpcAI +{ + // Mobs + private static final int[] GROUP_MOBS = + { + 24227, // Keros + 24228, // Falena + 24229, // Atrofa + 24230, // Nuba + 24231 // Torfedo + }; + private static final int[] SOLO_MOBS = + { + 24234, // Lesatanas + 24235, // Arbor + 24236, // Tergus + 24237, // Skeletus + 24238, // Atrofine + }; + // Special Mobs + private static final int ARANEA = 24226; + private static final int ARIMA = 24232; + private static final int HARANE = 24233; + private static final int ARIMUS = 24239; + // Skills + private static final SkillHolder ABSORB_ENERGY1 = new SkillHolder(32483, 1); + private static final SkillHolder ABSORB_ENERGY2 = new SkillHolder(32481, 1); + private static final SkillHolder REFINED_ENERGY = new SkillHolder(32485, 1); + + private SeaOfSpores() + { + addAttackId(ARIMA, ARIMUS); + addKillId(SOLO_MOBS); + addKillId(GROUP_MOBS); + addKillId(ARIMA, ARIMUS); + } + + @Override + public String onAttack(Npc npc, PlayerInstance attacker, int damage, boolean isSummon) + { + if ((npc.getCurrentHp() <= (npc.getMaxHp() * 0.7)) && !npc.isCastingNow()) + { + if (npc.getId() == ARIMA) + { + npc.doCast(ABSORB_ENERGY2.getSkill()); + } + else if (npc.getId() == ARIMUS) + { + npc.doCast(ABSORB_ENERGY1.getSkill()); + } + } + return super.onAttack(npc, attacker, damage, isSummon); + } + + @Override + public String onKill(Npc npc, PlayerInstance killer, boolean isSummon) + { + if (CommonUtil.contains(SOLO_MOBS, npc.getId()) && (getRandom(1000) < 2)) + { + addSpawn(ARIMUS, npc, false, 300000); + } + else if (CommonUtil.contains(GROUP_MOBS, npc.getId()) && (getRandom(1000) < 2)) + { + addSpawn(ARIMA, npc, false, 300000); + } + else if (npc.getId() == ARIMA) + { + List members = new ArrayList<>(); + if (killer.getParty() != null) + { + members = killer.getParty().getMembers(); + } + else + { + members.add(killer); + } + for (PlayerInstance member : members) + { + member.doCast(REFINED_ENERGY.getSkill()); + } + if (getRandom(1000) < 2) + { + addSpawn(ARANEA, npc, false, 300000); + addSpawn(HARANE, npc, false, 300000); + } + } + else if (npc.getId() == ARIMUS) + { + List members = new ArrayList<>(); + if (killer.getParty() != null) + { + members = killer.getParty().getMembers(); + } + else + { + members.add(killer); + } + for (PlayerInstance member : members) + { + member.doCast(REFINED_ENERGY.getSkill()); + } + } + return super.onKill(npc, killer, isSummon); + } + + public static void main(String[] args) + { + new SeaOfSpores(); + } +} diff --git a/L2J_Mobius_5.5_EtinasFate/dist/game/data/scripts/ai/bosses/Orfen/Orfen.java b/L2J_Mobius_5.5_EtinasFate/dist/game/data/scripts/ai/bosses/Orfen/Orfen.java index ba7b1b9681..8f5d996e6c 100644 --- a/L2J_Mobius_5.5_EtinasFate/dist/game/data/scripts/ai/bosses/Orfen/Orfen.java +++ b/L2J_Mobius_5.5_EtinasFate/dist/game/data/scripts/ai/bosses/Orfen/Orfen.java @@ -23,20 +23,14 @@ import org.l2jmobius.Config; import org.l2jmobius.gameserver.ai.CtrlIntention; import org.l2jmobius.gameserver.enums.ChatType; import org.l2jmobius.gameserver.instancemanager.GrandBossManager; -import org.l2jmobius.gameserver.instancemanager.ZoneManager; import org.l2jmobius.gameserver.model.Location; -import org.l2jmobius.gameserver.model.Spawn; import org.l2jmobius.gameserver.model.StatSet; -import org.l2jmobius.gameserver.model.WorldObject; import org.l2jmobius.gameserver.model.actor.Attackable; -import org.l2jmobius.gameserver.model.actor.Creature; import org.l2jmobius.gameserver.model.actor.Npc; import org.l2jmobius.gameserver.model.actor.instance.GrandBossInstance; import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; import org.l2jmobius.gameserver.model.holders.SkillHolder; -import org.l2jmobius.gameserver.model.skills.Skill; import org.l2jmobius.gameserver.model.skills.SkillCaster; -import org.l2jmobius.gameserver.model.zone.ZoneType; import org.l2jmobius.gameserver.network.NpcStringId; import org.l2jmobius.gameserver.network.serverpackets.PlaySound; @@ -48,13 +42,7 @@ import ai.AbstractNpcAI; */ public class Orfen extends AbstractNpcAI { - private static final Location[] POS = - { - new Location(43200, 16304, -4395), - new Location(43300, 16404, -4395), - new Location(43400, 16504, -4395), - new Location(43500, 16604, -4395) - }; + private static final Location POS = new Location(43728, 17220, -4342); private static final NpcStringId[] TEXT = { @@ -65,21 +53,26 @@ public class Orfen extends AbstractNpcAI }; private static final int ORFEN = 29325; - // private static final int RAIKEL = 29015; private static final int ARIMA = 29326; - // private static final int RIBA = 29017; private static final int ARIMUS = 29327; - private static boolean _IsTeleported; private static Set _minions = ConcurrentHashMap.newKeySet(); - private static ZoneType ZONE; private static final byte ALIVE = 0; private static final byte DEAD = 1; - private static final SkillHolder PARALYSIS = new SkillHolder(4064, 1); private static final SkillHolder BLOW = new SkillHolder(4067, 4); private static final SkillHolder ORFEN_HEAL = new SkillHolder(4516, 1); + private static final SkillHolder ORFEN_SLASHER = new SkillHolder(32486, 1); + private static final SkillHolder ORFEN_FATAL_SLASHER = new SkillHolder(32487, 1); + private static final SkillHolder ORFEN_ENERGY_SCATTER = new SkillHolder(32488, 1); + private static final SkillHolder ORFEN_FURY_ENERGY_WAVE = new SkillHolder(32489, 1); + private static final SkillHolder YOKE_OF_ORFEN = new SkillHolder(32490, 1); + private static final SkillHolder ORFEN_BLOW_UP = new SkillHolder(32491, 1); + private static final SkillHolder ORFEN_FATAL_STAMP = new SkillHolder(32492, 1); + private static final SkillHolder ORFEN_RAISE_SPORE = new SkillHolder(32493, 1); + private static final SkillHolder HALLUCINATING_DUST = new SkillHolder(32494, 1); + private static final SkillHolder ORFEN_RAGE = new SkillHolder(32495, 1); private Orfen() { @@ -90,8 +83,6 @@ public class Orfen extends AbstractNpcAI ARIMUS }; registerMobs(mobs); - _IsTeleported = false; - ZONE = ZoneManager.getInstance().getZoneById(12013); final StatSet info = GrandBossManager.getInstance().getStatSet(ORFEN); final int status = GrandBossManager.getInstance().getBossStatus(ORFEN); if (status == DEAD) @@ -107,21 +98,7 @@ public class Orfen extends AbstractNpcAI else { // the time has already expired while the server was offline. Immediately spawn Orfen. - final int i = getRandom(10); - Location loc; - if (i < 4) - { - loc = POS[1]; - } - else if (i < 7) - { - loc = POS[2]; - } - else - { - loc = POS[3]; - } - final GrandBossInstance orfen = (GrandBossInstance) addSpawn(ORFEN, loc, false, 0); + final GrandBossInstance orfen = (GrandBossInstance) addSpawn(ORFEN, POS, false, 0); GrandBossManager.getInstance().setBossStatus(ORFEN, ALIVE); spawnBoss(orfen); } @@ -140,20 +117,10 @@ public class Orfen extends AbstractNpcAI } } - public void setSpawnPoint(Npc npc, int index) - { - ((Attackable) npc).clearAggroList(); - npc.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE, null, null); - final Spawn spawn = npc.getSpawn(); - spawn.setLocation(POS[index]); - npc.teleToLocation(POS[index], false); - } - public void spawnBoss(GrandBossInstance npc) { GrandBossManager.getInstance().addBoss(npc); npc.broadcastPacket(new PlaySound(1, "BS01_A", 1, npc.getObjectId(), npc.getX(), npc.getY(), npc.getZ())); - startQuestTimer("check_orfen_pos", 10000, npc, null, true); // Spawn minions final int x = npc.getX(); final int y = npc.getY(); @@ -178,36 +145,10 @@ public class Orfen extends AbstractNpcAI { if (event.equalsIgnoreCase("orfen_unlock")) { - final int i = getRandom(10); - Location loc; - if (i < 4) - { - loc = POS[1]; - } - else if (i < 7) - { - loc = POS[2]; - } - else - { - loc = POS[3]; - } - final GrandBossInstance orfen = (GrandBossInstance) addSpawn(ORFEN, loc, false, 0); + final GrandBossInstance orfen = (GrandBossInstance) addSpawn(ORFEN, POS, false, 0); GrandBossManager.getInstance().setBossStatus(ORFEN, ALIVE); spawnBoss(orfen); } - else if (event.equalsIgnoreCase("check_orfen_pos")) - { - if ((_IsTeleported && (npc.getCurrentHp() > (npc.getMaxHp() * 0.95))) || (!ZONE.isInsideZone(npc) && !_IsTeleported)) - { - setSpawnPoint(npc, getRandom(3) + 1); - _IsTeleported = false; - } - else if (_IsTeleported && !ZONE.isInsideZone(npc)) - { - setSpawnPoint(npc, 0); - } - } else if (event.equalsIgnoreCase("check_minion_loc")) { for (Attackable mob : _minions) @@ -237,23 +178,6 @@ public class Orfen extends AbstractNpcAI return super.onAdvEvent(event, npc, player); } - @Override - public String onSkillSee(Npc npc, PlayerInstance caster, Skill skill, WorldObject[] targets, boolean isSummon) - { - if (npc.getId() == ORFEN) - { - final Creature originalCaster = isSummon ? caster.getServitors().values().stream().findFirst().orElse(caster.getPet()) : caster; - if ((skill.getEffectPoint() > 0) && (getRandom(5) == 0) && npc.isInsideRadius2D(originalCaster, 1000)) - { - npc.broadcastSay(ChatType.NPC_GENERAL, TEXT[getRandom(4)], caster.getName()); - originalCaster.teleToLocation(npc.getLocation()); - npc.setTarget(originalCaster); - npc.doCast(PARALYSIS.getSkill()); - } - } - return super.onSkillSee(npc, caster, skill, targets, isSummon); - } - @Override public String onFactionCall(Npc npc, Npc caller, PlayerInstance attacker, boolean isSummon) { @@ -291,17 +215,65 @@ public class Orfen extends AbstractNpcAI final int npcId = npc.getId(); if (npcId == ORFEN) { - if (!_IsTeleported && ((npc.getCurrentHp() - damage) < (npc.getMaxHp() / 2))) - { - _IsTeleported = true; - setSpawnPoint(npc, 0); - } - else if (npc.isInsideRadius2D(attacker, 1000) && !npc.isInsideRadius2D(attacker, 300) && (getRandom(10) == 0)) + if (manageSkills(npc) && npc.isInsideRadius2D(attacker, 1000) && (getRandom(10) == 0)) { npc.broadcastSay(ChatType.NPC_GENERAL, TEXT[getRandom(3)], attacker.getName()); - attacker.teleToLocation(npc.getLocation()); npc.setTarget(attacker); - npc.doCast(PARALYSIS.getSkill()); + npc.doCast(ORFEN_FATAL_SLASHER.getSkill()); + } + else if (manageSkills(npc) && npc.isInsideRadius2D(attacker, 1000) && (getRandom(10) == 0)) + { + npc.broadcastSay(ChatType.NPC_GENERAL, TEXT[getRandom(3)], attacker.getName()); + npc.setTarget(attacker); + npc.doCast(ORFEN_ENERGY_SCATTER.getSkill()); + } + else if (manageSkills(npc) && npc.isInsideRadius2D(attacker, 1000) && (getRandom(10) == 0)) + { + npc.broadcastSay(ChatType.NPC_GENERAL, TEXT[getRandom(3)], attacker.getName()); + npc.setTarget(attacker); + npc.doCast(ORFEN_FURY_ENERGY_WAVE.getSkill()); + } + else if (manageSkills(npc) && npc.isInsideRadius2D(attacker, 1000) && (getRandom(10) == 0)) + { + npc.broadcastSay(ChatType.NPC_GENERAL, TEXT[getRandom(3)], attacker.getName()); + npc.setTarget(attacker); + npc.doCast(YOKE_OF_ORFEN.getSkill()); + } + else if (manageSkills(npc) && npc.isInsideRadius2D(attacker, 1000) && (getRandom(10) == 0)) + { + npc.broadcastSay(ChatType.NPC_GENERAL, TEXT[getRandom(3)], attacker.getName()); + npc.setTarget(attacker); + npc.doCast(ORFEN_BLOW_UP.getSkill()); + } + else if (manageSkills(npc) && npc.isInsideRadius2D(attacker, 1000) && (getRandom(10) == 0)) + { + npc.broadcastSay(ChatType.NPC_GENERAL, TEXT[getRandom(3)], attacker.getName()); + npc.setTarget(attacker); + npc.doCast(ORFEN_FATAL_STAMP.getSkill()); + } + else if (manageSkills(npc) && npc.isInsideRadius2D(attacker, 1000) && (getRandom(10) == 0)) + { + npc.broadcastSay(ChatType.NPC_GENERAL, TEXT[getRandom(3)], attacker.getName()); + npc.setTarget(attacker); + npc.doCast(ORFEN_RAISE_SPORE.getSkill()); + } + else if (manageSkills(npc) && npc.isInsideRadius2D(attacker, 1000) && (getRandom(10) == 0)) + { + npc.broadcastSay(ChatType.NPC_GENERAL, TEXT[getRandom(3)], attacker.getName()); + npc.setTarget(attacker); + npc.doCast(HALLUCINATING_DUST.getSkill()); + } + else if (manageSkills(npc) && npc.isInsideRadius2D(attacker, 1000) && (getRandom(10) == 0) && (npc.getCurrentHp() <= (npc.getMaxHp() * 0.5))) + { + npc.broadcastSay(ChatType.NPC_GENERAL, TEXT[getRandom(3)], attacker.getName()); + npc.setTarget(attacker); + npc.doCast(ORFEN_RAGE.getSkill()); + } + else if (manageSkills(npc) && npc.isInsideRadius2D(attacker, 1000)) + { + npc.broadcastSay(ChatType.NPC_GENERAL, TEXT[getRandom(3)], attacker.getName()); + npc.setTarget(attacker); + npc.doCast(ORFEN_SLASHER.getSkill()); } } else if (npcId == ARIMUS) @@ -315,6 +287,15 @@ public class Orfen extends AbstractNpcAI return super.onAttack(npc, attacker, damage, isSummon); } + private boolean manageSkills(Npc npc) + { + if (npc.isCastingNow()) + { + return false; + } + return true; + } + @Override public String onKill(Npc npc, PlayerInstance killer, boolean isSummon) { @@ -331,7 +312,6 @@ public class Orfen extends AbstractNpcAI info.set("respawn_time", System.currentTimeMillis() + respawnTime); GrandBossManager.getInstance().setStatSet(ORFEN, info); cancelQuestTimer("check_minion_loc", npc, null); - cancelQuestTimer("check_orfen_pos", npc, null); startQuestTimer("despawn_minions", 20000, null, null); cancelQuestTimers("spawn_minion"); } diff --git a/L2J_Mobius_6.0_Fafurion/dist/game/data/scripts/ai/areas/SeaOfSpores/SeaOfSpores.java b/L2J_Mobius_6.0_Fafurion/dist/game/data/scripts/ai/areas/SeaOfSpores/SeaOfSpores.java new file mode 100644 index 0000000000..f76b4463cb --- /dev/null +++ b/L2J_Mobius_6.0_Fafurion/dist/game/data/scripts/ai/areas/SeaOfSpores/SeaOfSpores.java @@ -0,0 +1,141 @@ +/* + * This file is part of the L2J Mobius project. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ai.areas.SeaOfSpores; + +import java.util.ArrayList; +import java.util.List; + +import org.l2jmobius.commons.util.CommonUtil; +import org.l2jmobius.gameserver.model.actor.Npc; +import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; +import org.l2jmobius.gameserver.model.holders.SkillHolder; + +import ai.AbstractNpcAI; + +/** + * @author NviX + */ +public class SeaOfSpores extends AbstractNpcAI +{ + // Mobs + private static final int[] GROUP_MOBS = + { + 24227, // Keros + 24228, // Falena + 24229, // Atrofa + 24230, // Nuba + 24231 // Torfedo + }; + private static final int[] SOLO_MOBS = + { + 24234, // Lesatanas + 24235, // Arbor + 24236, // Tergus + 24237, // Skeletus + 24238, // Atrofine + }; + // Special Mobs + private static final int ARANEA = 24226; + private static final int ARIMA = 24232; + private static final int HARANE = 24233; + private static final int ARIMUS = 24239; + // Skills + private static final SkillHolder ABSORB_ENERGY1 = new SkillHolder(32483, 1); + private static final SkillHolder ABSORB_ENERGY2 = new SkillHolder(32481, 1); + private static final SkillHolder REFINED_ENERGY = new SkillHolder(32485, 1); + + private SeaOfSpores() + { + addAttackId(ARIMA, ARIMUS); + addKillId(SOLO_MOBS); + addKillId(GROUP_MOBS); + addKillId(ARIMA, ARIMUS); + } + + @Override + public String onAttack(Npc npc, PlayerInstance attacker, int damage, boolean isSummon) + { + if ((npc.getCurrentHp() <= (npc.getMaxHp() * 0.7)) && !npc.isCastingNow()) + { + if (npc.getId() == ARIMA) + { + npc.doCast(ABSORB_ENERGY2.getSkill()); + } + else if (npc.getId() == ARIMUS) + { + npc.doCast(ABSORB_ENERGY1.getSkill()); + } + } + return super.onAttack(npc, attacker, damage, isSummon); + } + + @Override + public String onKill(Npc npc, PlayerInstance killer, boolean isSummon) + { + if (CommonUtil.contains(SOLO_MOBS, npc.getId()) && (getRandom(1000) < 2)) + { + addSpawn(ARIMUS, npc, false, 300000); + } + else if (CommonUtil.contains(GROUP_MOBS, npc.getId()) && (getRandom(1000) < 2)) + { + addSpawn(ARIMA, npc, false, 300000); + } + else if (npc.getId() == ARIMA) + { + List members = new ArrayList<>(); + if (killer.getParty() != null) + { + members = killer.getParty().getMembers(); + } + else + { + members.add(killer); + } + for (PlayerInstance member : members) + { + member.doCast(REFINED_ENERGY.getSkill()); + } + if (getRandom(1000) < 2) + { + addSpawn(ARANEA, npc, false, 300000); + addSpawn(HARANE, npc, false, 300000); + } + } + else if (npc.getId() == ARIMUS) + { + List members = new ArrayList<>(); + if (killer.getParty() != null) + { + members = killer.getParty().getMembers(); + } + else + { + members.add(killer); + } + for (PlayerInstance member : members) + { + member.doCast(REFINED_ENERGY.getSkill()); + } + } + return super.onKill(npc, killer, isSummon); + } + + public static void main(String[] args) + { + new SeaOfSpores(); + } +} diff --git a/L2J_Mobius_6.0_Fafurion/dist/game/data/scripts/ai/bosses/Orfen/Orfen.java b/L2J_Mobius_6.0_Fafurion/dist/game/data/scripts/ai/bosses/Orfen/Orfen.java index 29da6a5a6b..8f5d996e6c 100644 --- a/L2J_Mobius_6.0_Fafurion/dist/game/data/scripts/ai/bosses/Orfen/Orfen.java +++ b/L2J_Mobius_6.0_Fafurion/dist/game/data/scripts/ai/bosses/Orfen/Orfen.java @@ -23,20 +23,14 @@ import org.l2jmobius.Config; import org.l2jmobius.gameserver.ai.CtrlIntention; import org.l2jmobius.gameserver.enums.ChatType; import org.l2jmobius.gameserver.instancemanager.GrandBossManager; -import org.l2jmobius.gameserver.instancemanager.ZoneManager; import org.l2jmobius.gameserver.model.Location; -import org.l2jmobius.gameserver.model.Spawn; import org.l2jmobius.gameserver.model.StatSet; -import org.l2jmobius.gameserver.model.WorldObject; import org.l2jmobius.gameserver.model.actor.Attackable; -import org.l2jmobius.gameserver.model.actor.Creature; import org.l2jmobius.gameserver.model.actor.Npc; import org.l2jmobius.gameserver.model.actor.instance.GrandBossInstance; import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; import org.l2jmobius.gameserver.model.holders.SkillHolder; -import org.l2jmobius.gameserver.model.skills.Skill; import org.l2jmobius.gameserver.model.skills.SkillCaster; -import org.l2jmobius.gameserver.model.zone.ZoneType; import org.l2jmobius.gameserver.network.NpcStringId; import org.l2jmobius.gameserver.network.serverpackets.PlaySound; @@ -48,13 +42,7 @@ import ai.AbstractNpcAI; */ public class Orfen extends AbstractNpcAI { - private static final Location[] POS = - { - new Location(43200, 16304, -4395), - new Location(43300, 16404, -4395), - new Location(43400, 16504, -4395), - new Location(43500, 16604, -4395) - }; + private static final Location POS = new Location(43728, 17220, -4342); private static final NpcStringId[] TEXT = { @@ -68,16 +56,23 @@ public class Orfen extends AbstractNpcAI private static final int ARIMA = 29326; private static final int ARIMUS = 29327; - private static boolean _IsTeleported; private static Set _minions = ConcurrentHashMap.newKeySet(); - private static ZoneType ZONE; private static final byte ALIVE = 0; private static final byte DEAD = 1; - private static final SkillHolder PARALYSIS = new SkillHolder(4064, 1); private static final SkillHolder BLOW = new SkillHolder(4067, 4); private static final SkillHolder ORFEN_HEAL = new SkillHolder(4516, 1); + private static final SkillHolder ORFEN_SLASHER = new SkillHolder(32486, 1); + private static final SkillHolder ORFEN_FATAL_SLASHER = new SkillHolder(32487, 1); + private static final SkillHolder ORFEN_ENERGY_SCATTER = new SkillHolder(32488, 1); + private static final SkillHolder ORFEN_FURY_ENERGY_WAVE = new SkillHolder(32489, 1); + private static final SkillHolder YOKE_OF_ORFEN = new SkillHolder(32490, 1); + private static final SkillHolder ORFEN_BLOW_UP = new SkillHolder(32491, 1); + private static final SkillHolder ORFEN_FATAL_STAMP = new SkillHolder(32492, 1); + private static final SkillHolder ORFEN_RAISE_SPORE = new SkillHolder(32493, 1); + private static final SkillHolder HALLUCINATING_DUST = new SkillHolder(32494, 1); + private static final SkillHolder ORFEN_RAGE = new SkillHolder(32495, 1); private Orfen() { @@ -88,8 +83,6 @@ public class Orfen extends AbstractNpcAI ARIMUS }; registerMobs(mobs); - _IsTeleported = false; - ZONE = ZoneManager.getInstance().getZoneById(12013); final StatSet info = GrandBossManager.getInstance().getStatSet(ORFEN); final int status = GrandBossManager.getInstance().getBossStatus(ORFEN); if (status == DEAD) @@ -105,21 +98,7 @@ public class Orfen extends AbstractNpcAI else { // the time has already expired while the server was offline. Immediately spawn Orfen. - final int i = getRandom(10); - Location loc; - if (i < 4) - { - loc = POS[1]; - } - else if (i < 7) - { - loc = POS[2]; - } - else - { - loc = POS[3]; - } - final GrandBossInstance orfen = (GrandBossInstance) addSpawn(ORFEN, loc, false, 0); + final GrandBossInstance orfen = (GrandBossInstance) addSpawn(ORFEN, POS, false, 0); GrandBossManager.getInstance().setBossStatus(ORFEN, ALIVE); spawnBoss(orfen); } @@ -138,20 +117,10 @@ public class Orfen extends AbstractNpcAI } } - public void setSpawnPoint(Npc npc, int index) - { - ((Attackable) npc).clearAggroList(); - npc.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE, null, null); - final Spawn spawn = npc.getSpawn(); - spawn.setLocation(POS[index]); - npc.teleToLocation(POS[index], false); - } - public void spawnBoss(GrandBossInstance npc) { GrandBossManager.getInstance().addBoss(npc); npc.broadcastPacket(new PlaySound(1, "BS01_A", 1, npc.getObjectId(), npc.getX(), npc.getY(), npc.getZ())); - startQuestTimer("check_orfen_pos", 10000, npc, null, true); // Spawn minions final int x = npc.getX(); final int y = npc.getY(); @@ -176,36 +145,10 @@ public class Orfen extends AbstractNpcAI { if (event.equalsIgnoreCase("orfen_unlock")) { - final int i = getRandom(10); - Location loc; - if (i < 4) - { - loc = POS[1]; - } - else if (i < 7) - { - loc = POS[2]; - } - else - { - loc = POS[3]; - } - final GrandBossInstance orfen = (GrandBossInstance) addSpawn(ORFEN, loc, false, 0); + final GrandBossInstance orfen = (GrandBossInstance) addSpawn(ORFEN, POS, false, 0); GrandBossManager.getInstance().setBossStatus(ORFEN, ALIVE); spawnBoss(orfen); } - else if (event.equalsIgnoreCase("check_orfen_pos")) - { - if ((_IsTeleported && (npc.getCurrentHp() > (npc.getMaxHp() * 0.95))) || (!ZONE.isInsideZone(npc) && !_IsTeleported)) - { - setSpawnPoint(npc, getRandom(3) + 1); - _IsTeleported = false; - } - else if (_IsTeleported && !ZONE.isInsideZone(npc)) - { - setSpawnPoint(npc, 0); - } - } else if (event.equalsIgnoreCase("check_minion_loc")) { for (Attackable mob : _minions) @@ -235,23 +178,6 @@ public class Orfen extends AbstractNpcAI return super.onAdvEvent(event, npc, player); } - @Override - public String onSkillSee(Npc npc, PlayerInstance caster, Skill skill, WorldObject[] targets, boolean isSummon) - { - if (npc.getId() == ORFEN) - { - final Creature originalCaster = isSummon ? caster.getServitors().values().stream().findFirst().orElse(caster.getPet()) : caster; - if ((skill.getEffectPoint() > 0) && (getRandom(5) == 0) && npc.isInsideRadius2D(originalCaster, 1000)) - { - npc.broadcastSay(ChatType.NPC_GENERAL, TEXT[getRandom(4)], caster.getName()); - originalCaster.teleToLocation(npc.getLocation()); - npc.setTarget(originalCaster); - npc.doCast(PARALYSIS.getSkill()); - } - } - return super.onSkillSee(npc, caster, skill, targets, isSummon); - } - @Override public String onFactionCall(Npc npc, Npc caller, PlayerInstance attacker, boolean isSummon) { @@ -289,17 +215,65 @@ public class Orfen extends AbstractNpcAI final int npcId = npc.getId(); if (npcId == ORFEN) { - if (!_IsTeleported && ((npc.getCurrentHp() - damage) < (npc.getMaxHp() / 2))) - { - _IsTeleported = true; - setSpawnPoint(npc, 0); - } - else if (npc.isInsideRadius2D(attacker, 1000) && !npc.isInsideRadius2D(attacker, 300) && (getRandom(10) == 0)) + if (manageSkills(npc) && npc.isInsideRadius2D(attacker, 1000) && (getRandom(10) == 0)) { npc.broadcastSay(ChatType.NPC_GENERAL, TEXT[getRandom(3)], attacker.getName()); - attacker.teleToLocation(npc.getLocation()); npc.setTarget(attacker); - npc.doCast(PARALYSIS.getSkill()); + npc.doCast(ORFEN_FATAL_SLASHER.getSkill()); + } + else if (manageSkills(npc) && npc.isInsideRadius2D(attacker, 1000) && (getRandom(10) == 0)) + { + npc.broadcastSay(ChatType.NPC_GENERAL, TEXT[getRandom(3)], attacker.getName()); + npc.setTarget(attacker); + npc.doCast(ORFEN_ENERGY_SCATTER.getSkill()); + } + else if (manageSkills(npc) && npc.isInsideRadius2D(attacker, 1000) && (getRandom(10) == 0)) + { + npc.broadcastSay(ChatType.NPC_GENERAL, TEXT[getRandom(3)], attacker.getName()); + npc.setTarget(attacker); + npc.doCast(ORFEN_FURY_ENERGY_WAVE.getSkill()); + } + else if (manageSkills(npc) && npc.isInsideRadius2D(attacker, 1000) && (getRandom(10) == 0)) + { + npc.broadcastSay(ChatType.NPC_GENERAL, TEXT[getRandom(3)], attacker.getName()); + npc.setTarget(attacker); + npc.doCast(YOKE_OF_ORFEN.getSkill()); + } + else if (manageSkills(npc) && npc.isInsideRadius2D(attacker, 1000) && (getRandom(10) == 0)) + { + npc.broadcastSay(ChatType.NPC_GENERAL, TEXT[getRandom(3)], attacker.getName()); + npc.setTarget(attacker); + npc.doCast(ORFEN_BLOW_UP.getSkill()); + } + else if (manageSkills(npc) && npc.isInsideRadius2D(attacker, 1000) && (getRandom(10) == 0)) + { + npc.broadcastSay(ChatType.NPC_GENERAL, TEXT[getRandom(3)], attacker.getName()); + npc.setTarget(attacker); + npc.doCast(ORFEN_FATAL_STAMP.getSkill()); + } + else if (manageSkills(npc) && npc.isInsideRadius2D(attacker, 1000) && (getRandom(10) == 0)) + { + npc.broadcastSay(ChatType.NPC_GENERAL, TEXT[getRandom(3)], attacker.getName()); + npc.setTarget(attacker); + npc.doCast(ORFEN_RAISE_SPORE.getSkill()); + } + else if (manageSkills(npc) && npc.isInsideRadius2D(attacker, 1000) && (getRandom(10) == 0)) + { + npc.broadcastSay(ChatType.NPC_GENERAL, TEXT[getRandom(3)], attacker.getName()); + npc.setTarget(attacker); + npc.doCast(HALLUCINATING_DUST.getSkill()); + } + else if (manageSkills(npc) && npc.isInsideRadius2D(attacker, 1000) && (getRandom(10) == 0) && (npc.getCurrentHp() <= (npc.getMaxHp() * 0.5))) + { + npc.broadcastSay(ChatType.NPC_GENERAL, TEXT[getRandom(3)], attacker.getName()); + npc.setTarget(attacker); + npc.doCast(ORFEN_RAGE.getSkill()); + } + else if (manageSkills(npc) && npc.isInsideRadius2D(attacker, 1000)) + { + npc.broadcastSay(ChatType.NPC_GENERAL, TEXT[getRandom(3)], attacker.getName()); + npc.setTarget(attacker); + npc.doCast(ORFEN_SLASHER.getSkill()); } } else if (npcId == ARIMUS) @@ -313,6 +287,15 @@ public class Orfen extends AbstractNpcAI return super.onAttack(npc, attacker, damage, isSummon); } + private boolean manageSkills(Npc npc) + { + if (npc.isCastingNow()) + { + return false; + } + return true; + } + @Override public String onKill(Npc npc, PlayerInstance killer, boolean isSummon) { @@ -329,7 +312,6 @@ public class Orfen extends AbstractNpcAI info.set("respawn_time", System.currentTimeMillis() + respawnTime); GrandBossManager.getInstance().setStatSet(ORFEN, info); cancelQuestTimer("check_minion_loc", npc, null); - cancelQuestTimer("check_orfen_pos", npc, null); startQuestTimer("despawn_minions", 20000, null, null); cancelQuestTimers("spawn_minion"); } diff --git a/L2J_Mobius_7.0_PreludeOfWar/dist/game/data/scripts/ai/areas/SeaOfSpores/SeaOfSpores.java b/L2J_Mobius_7.0_PreludeOfWar/dist/game/data/scripts/ai/areas/SeaOfSpores/SeaOfSpores.java new file mode 100644 index 0000000000..f76b4463cb --- /dev/null +++ b/L2J_Mobius_7.0_PreludeOfWar/dist/game/data/scripts/ai/areas/SeaOfSpores/SeaOfSpores.java @@ -0,0 +1,141 @@ +/* + * This file is part of the L2J Mobius project. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ai.areas.SeaOfSpores; + +import java.util.ArrayList; +import java.util.List; + +import org.l2jmobius.commons.util.CommonUtil; +import org.l2jmobius.gameserver.model.actor.Npc; +import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; +import org.l2jmobius.gameserver.model.holders.SkillHolder; + +import ai.AbstractNpcAI; + +/** + * @author NviX + */ +public class SeaOfSpores extends AbstractNpcAI +{ + // Mobs + private static final int[] GROUP_MOBS = + { + 24227, // Keros + 24228, // Falena + 24229, // Atrofa + 24230, // Nuba + 24231 // Torfedo + }; + private static final int[] SOLO_MOBS = + { + 24234, // Lesatanas + 24235, // Arbor + 24236, // Tergus + 24237, // Skeletus + 24238, // Atrofine + }; + // Special Mobs + private static final int ARANEA = 24226; + private static final int ARIMA = 24232; + private static final int HARANE = 24233; + private static final int ARIMUS = 24239; + // Skills + private static final SkillHolder ABSORB_ENERGY1 = new SkillHolder(32483, 1); + private static final SkillHolder ABSORB_ENERGY2 = new SkillHolder(32481, 1); + private static final SkillHolder REFINED_ENERGY = new SkillHolder(32485, 1); + + private SeaOfSpores() + { + addAttackId(ARIMA, ARIMUS); + addKillId(SOLO_MOBS); + addKillId(GROUP_MOBS); + addKillId(ARIMA, ARIMUS); + } + + @Override + public String onAttack(Npc npc, PlayerInstance attacker, int damage, boolean isSummon) + { + if ((npc.getCurrentHp() <= (npc.getMaxHp() * 0.7)) && !npc.isCastingNow()) + { + if (npc.getId() == ARIMA) + { + npc.doCast(ABSORB_ENERGY2.getSkill()); + } + else if (npc.getId() == ARIMUS) + { + npc.doCast(ABSORB_ENERGY1.getSkill()); + } + } + return super.onAttack(npc, attacker, damage, isSummon); + } + + @Override + public String onKill(Npc npc, PlayerInstance killer, boolean isSummon) + { + if (CommonUtil.contains(SOLO_MOBS, npc.getId()) && (getRandom(1000) < 2)) + { + addSpawn(ARIMUS, npc, false, 300000); + } + else if (CommonUtil.contains(GROUP_MOBS, npc.getId()) && (getRandom(1000) < 2)) + { + addSpawn(ARIMA, npc, false, 300000); + } + else if (npc.getId() == ARIMA) + { + List members = new ArrayList<>(); + if (killer.getParty() != null) + { + members = killer.getParty().getMembers(); + } + else + { + members.add(killer); + } + for (PlayerInstance member : members) + { + member.doCast(REFINED_ENERGY.getSkill()); + } + if (getRandom(1000) < 2) + { + addSpawn(ARANEA, npc, false, 300000); + addSpawn(HARANE, npc, false, 300000); + } + } + else if (npc.getId() == ARIMUS) + { + List members = new ArrayList<>(); + if (killer.getParty() != null) + { + members = killer.getParty().getMembers(); + } + else + { + members.add(killer); + } + for (PlayerInstance member : members) + { + member.doCast(REFINED_ENERGY.getSkill()); + } + } + return super.onKill(npc, killer, isSummon); + } + + public static void main(String[] args) + { + new SeaOfSpores(); + } +} diff --git a/L2J_Mobius_7.0_PreludeOfWar/dist/game/data/scripts/ai/bosses/Orfen/Orfen.java b/L2J_Mobius_7.0_PreludeOfWar/dist/game/data/scripts/ai/bosses/Orfen/Orfen.java index 29da6a5a6b..8f5d996e6c 100644 --- a/L2J_Mobius_7.0_PreludeOfWar/dist/game/data/scripts/ai/bosses/Orfen/Orfen.java +++ b/L2J_Mobius_7.0_PreludeOfWar/dist/game/data/scripts/ai/bosses/Orfen/Orfen.java @@ -23,20 +23,14 @@ import org.l2jmobius.Config; import org.l2jmobius.gameserver.ai.CtrlIntention; import org.l2jmobius.gameserver.enums.ChatType; import org.l2jmobius.gameserver.instancemanager.GrandBossManager; -import org.l2jmobius.gameserver.instancemanager.ZoneManager; import org.l2jmobius.gameserver.model.Location; -import org.l2jmobius.gameserver.model.Spawn; import org.l2jmobius.gameserver.model.StatSet; -import org.l2jmobius.gameserver.model.WorldObject; import org.l2jmobius.gameserver.model.actor.Attackable; -import org.l2jmobius.gameserver.model.actor.Creature; import org.l2jmobius.gameserver.model.actor.Npc; import org.l2jmobius.gameserver.model.actor.instance.GrandBossInstance; import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; import org.l2jmobius.gameserver.model.holders.SkillHolder; -import org.l2jmobius.gameserver.model.skills.Skill; import org.l2jmobius.gameserver.model.skills.SkillCaster; -import org.l2jmobius.gameserver.model.zone.ZoneType; import org.l2jmobius.gameserver.network.NpcStringId; import org.l2jmobius.gameserver.network.serverpackets.PlaySound; @@ -48,13 +42,7 @@ import ai.AbstractNpcAI; */ public class Orfen extends AbstractNpcAI { - private static final Location[] POS = - { - new Location(43200, 16304, -4395), - new Location(43300, 16404, -4395), - new Location(43400, 16504, -4395), - new Location(43500, 16604, -4395) - }; + private static final Location POS = new Location(43728, 17220, -4342); private static final NpcStringId[] TEXT = { @@ -68,16 +56,23 @@ public class Orfen extends AbstractNpcAI private static final int ARIMA = 29326; private static final int ARIMUS = 29327; - private static boolean _IsTeleported; private static Set _minions = ConcurrentHashMap.newKeySet(); - private static ZoneType ZONE; private static final byte ALIVE = 0; private static final byte DEAD = 1; - private static final SkillHolder PARALYSIS = new SkillHolder(4064, 1); private static final SkillHolder BLOW = new SkillHolder(4067, 4); private static final SkillHolder ORFEN_HEAL = new SkillHolder(4516, 1); + private static final SkillHolder ORFEN_SLASHER = new SkillHolder(32486, 1); + private static final SkillHolder ORFEN_FATAL_SLASHER = new SkillHolder(32487, 1); + private static final SkillHolder ORFEN_ENERGY_SCATTER = new SkillHolder(32488, 1); + private static final SkillHolder ORFEN_FURY_ENERGY_WAVE = new SkillHolder(32489, 1); + private static final SkillHolder YOKE_OF_ORFEN = new SkillHolder(32490, 1); + private static final SkillHolder ORFEN_BLOW_UP = new SkillHolder(32491, 1); + private static final SkillHolder ORFEN_FATAL_STAMP = new SkillHolder(32492, 1); + private static final SkillHolder ORFEN_RAISE_SPORE = new SkillHolder(32493, 1); + private static final SkillHolder HALLUCINATING_DUST = new SkillHolder(32494, 1); + private static final SkillHolder ORFEN_RAGE = new SkillHolder(32495, 1); private Orfen() { @@ -88,8 +83,6 @@ public class Orfen extends AbstractNpcAI ARIMUS }; registerMobs(mobs); - _IsTeleported = false; - ZONE = ZoneManager.getInstance().getZoneById(12013); final StatSet info = GrandBossManager.getInstance().getStatSet(ORFEN); final int status = GrandBossManager.getInstance().getBossStatus(ORFEN); if (status == DEAD) @@ -105,21 +98,7 @@ public class Orfen extends AbstractNpcAI else { // the time has already expired while the server was offline. Immediately spawn Orfen. - final int i = getRandom(10); - Location loc; - if (i < 4) - { - loc = POS[1]; - } - else if (i < 7) - { - loc = POS[2]; - } - else - { - loc = POS[3]; - } - final GrandBossInstance orfen = (GrandBossInstance) addSpawn(ORFEN, loc, false, 0); + final GrandBossInstance orfen = (GrandBossInstance) addSpawn(ORFEN, POS, false, 0); GrandBossManager.getInstance().setBossStatus(ORFEN, ALIVE); spawnBoss(orfen); } @@ -138,20 +117,10 @@ public class Orfen extends AbstractNpcAI } } - public void setSpawnPoint(Npc npc, int index) - { - ((Attackable) npc).clearAggroList(); - npc.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE, null, null); - final Spawn spawn = npc.getSpawn(); - spawn.setLocation(POS[index]); - npc.teleToLocation(POS[index], false); - } - public void spawnBoss(GrandBossInstance npc) { GrandBossManager.getInstance().addBoss(npc); npc.broadcastPacket(new PlaySound(1, "BS01_A", 1, npc.getObjectId(), npc.getX(), npc.getY(), npc.getZ())); - startQuestTimer("check_orfen_pos", 10000, npc, null, true); // Spawn minions final int x = npc.getX(); final int y = npc.getY(); @@ -176,36 +145,10 @@ public class Orfen extends AbstractNpcAI { if (event.equalsIgnoreCase("orfen_unlock")) { - final int i = getRandom(10); - Location loc; - if (i < 4) - { - loc = POS[1]; - } - else if (i < 7) - { - loc = POS[2]; - } - else - { - loc = POS[3]; - } - final GrandBossInstance orfen = (GrandBossInstance) addSpawn(ORFEN, loc, false, 0); + final GrandBossInstance orfen = (GrandBossInstance) addSpawn(ORFEN, POS, false, 0); GrandBossManager.getInstance().setBossStatus(ORFEN, ALIVE); spawnBoss(orfen); } - else if (event.equalsIgnoreCase("check_orfen_pos")) - { - if ((_IsTeleported && (npc.getCurrentHp() > (npc.getMaxHp() * 0.95))) || (!ZONE.isInsideZone(npc) && !_IsTeleported)) - { - setSpawnPoint(npc, getRandom(3) + 1); - _IsTeleported = false; - } - else if (_IsTeleported && !ZONE.isInsideZone(npc)) - { - setSpawnPoint(npc, 0); - } - } else if (event.equalsIgnoreCase("check_minion_loc")) { for (Attackable mob : _minions) @@ -235,23 +178,6 @@ public class Orfen extends AbstractNpcAI return super.onAdvEvent(event, npc, player); } - @Override - public String onSkillSee(Npc npc, PlayerInstance caster, Skill skill, WorldObject[] targets, boolean isSummon) - { - if (npc.getId() == ORFEN) - { - final Creature originalCaster = isSummon ? caster.getServitors().values().stream().findFirst().orElse(caster.getPet()) : caster; - if ((skill.getEffectPoint() > 0) && (getRandom(5) == 0) && npc.isInsideRadius2D(originalCaster, 1000)) - { - npc.broadcastSay(ChatType.NPC_GENERAL, TEXT[getRandom(4)], caster.getName()); - originalCaster.teleToLocation(npc.getLocation()); - npc.setTarget(originalCaster); - npc.doCast(PARALYSIS.getSkill()); - } - } - return super.onSkillSee(npc, caster, skill, targets, isSummon); - } - @Override public String onFactionCall(Npc npc, Npc caller, PlayerInstance attacker, boolean isSummon) { @@ -289,17 +215,65 @@ public class Orfen extends AbstractNpcAI final int npcId = npc.getId(); if (npcId == ORFEN) { - if (!_IsTeleported && ((npc.getCurrentHp() - damage) < (npc.getMaxHp() / 2))) - { - _IsTeleported = true; - setSpawnPoint(npc, 0); - } - else if (npc.isInsideRadius2D(attacker, 1000) && !npc.isInsideRadius2D(attacker, 300) && (getRandom(10) == 0)) + if (manageSkills(npc) && npc.isInsideRadius2D(attacker, 1000) && (getRandom(10) == 0)) { npc.broadcastSay(ChatType.NPC_GENERAL, TEXT[getRandom(3)], attacker.getName()); - attacker.teleToLocation(npc.getLocation()); npc.setTarget(attacker); - npc.doCast(PARALYSIS.getSkill()); + npc.doCast(ORFEN_FATAL_SLASHER.getSkill()); + } + else if (manageSkills(npc) && npc.isInsideRadius2D(attacker, 1000) && (getRandom(10) == 0)) + { + npc.broadcastSay(ChatType.NPC_GENERAL, TEXT[getRandom(3)], attacker.getName()); + npc.setTarget(attacker); + npc.doCast(ORFEN_ENERGY_SCATTER.getSkill()); + } + else if (manageSkills(npc) && npc.isInsideRadius2D(attacker, 1000) && (getRandom(10) == 0)) + { + npc.broadcastSay(ChatType.NPC_GENERAL, TEXT[getRandom(3)], attacker.getName()); + npc.setTarget(attacker); + npc.doCast(ORFEN_FURY_ENERGY_WAVE.getSkill()); + } + else if (manageSkills(npc) && npc.isInsideRadius2D(attacker, 1000) && (getRandom(10) == 0)) + { + npc.broadcastSay(ChatType.NPC_GENERAL, TEXT[getRandom(3)], attacker.getName()); + npc.setTarget(attacker); + npc.doCast(YOKE_OF_ORFEN.getSkill()); + } + else if (manageSkills(npc) && npc.isInsideRadius2D(attacker, 1000) && (getRandom(10) == 0)) + { + npc.broadcastSay(ChatType.NPC_GENERAL, TEXT[getRandom(3)], attacker.getName()); + npc.setTarget(attacker); + npc.doCast(ORFEN_BLOW_UP.getSkill()); + } + else if (manageSkills(npc) && npc.isInsideRadius2D(attacker, 1000) && (getRandom(10) == 0)) + { + npc.broadcastSay(ChatType.NPC_GENERAL, TEXT[getRandom(3)], attacker.getName()); + npc.setTarget(attacker); + npc.doCast(ORFEN_FATAL_STAMP.getSkill()); + } + else if (manageSkills(npc) && npc.isInsideRadius2D(attacker, 1000) && (getRandom(10) == 0)) + { + npc.broadcastSay(ChatType.NPC_GENERAL, TEXT[getRandom(3)], attacker.getName()); + npc.setTarget(attacker); + npc.doCast(ORFEN_RAISE_SPORE.getSkill()); + } + else if (manageSkills(npc) && npc.isInsideRadius2D(attacker, 1000) && (getRandom(10) == 0)) + { + npc.broadcastSay(ChatType.NPC_GENERAL, TEXT[getRandom(3)], attacker.getName()); + npc.setTarget(attacker); + npc.doCast(HALLUCINATING_DUST.getSkill()); + } + else if (manageSkills(npc) && npc.isInsideRadius2D(attacker, 1000) && (getRandom(10) == 0) && (npc.getCurrentHp() <= (npc.getMaxHp() * 0.5))) + { + npc.broadcastSay(ChatType.NPC_GENERAL, TEXT[getRandom(3)], attacker.getName()); + npc.setTarget(attacker); + npc.doCast(ORFEN_RAGE.getSkill()); + } + else if (manageSkills(npc) && npc.isInsideRadius2D(attacker, 1000)) + { + npc.broadcastSay(ChatType.NPC_GENERAL, TEXT[getRandom(3)], attacker.getName()); + npc.setTarget(attacker); + npc.doCast(ORFEN_SLASHER.getSkill()); } } else if (npcId == ARIMUS) @@ -313,6 +287,15 @@ public class Orfen extends AbstractNpcAI return super.onAttack(npc, attacker, damage, isSummon); } + private boolean manageSkills(Npc npc) + { + if (npc.isCastingNow()) + { + return false; + } + return true; + } + @Override public String onKill(Npc npc, PlayerInstance killer, boolean isSummon) { @@ -329,7 +312,6 @@ public class Orfen extends AbstractNpcAI info.set("respawn_time", System.currentTimeMillis() + respawnTime); GrandBossManager.getInstance().setStatSet(ORFEN, info); cancelQuestTimer("check_minion_loc", npc, null); - cancelQuestTimer("check_orfen_pos", npc, null); startQuestTimer("despawn_minions", 20000, null, null); cancelQuestTimers("spawn_minion"); }