Orfen changes.

Source: Liamxroy
This commit is contained in:
MobiusDevelopment 2020-04-24 10:33:26 +00:00
parent 2b7de9b722
commit 1477d2fd83
6 changed files with 657 additions and 290 deletions

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
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<PlayerInstance> 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<PlayerInstance> 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();
}
}

View File

@ -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<Attackable> _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");
}

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
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<PlayerInstance> 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<PlayerInstance> 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();
}
}

View File

@ -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<Attackable> _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");
}

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
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<PlayerInstance> 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<PlayerInstance> 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();
}
}

View File

@ -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<Attackable> _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");
}