Lindvior AI.
Contributed by gigilo1968.
This commit is contained in:
@@ -75,7 +75,7 @@ public class AltarOfSacrifice extends AbstractNpcAI
|
||||
@Override
|
||||
public String onSeeCreature(L2Npc npc, L2Character creature, boolean isSummon)
|
||||
{
|
||||
if (creature.isPlayer() && _jenas_guard.isScriptValue(0))
|
||||
if ((creature != null) && creature.isPlayer() && _jenas_guard.isScriptValue(0))
|
||||
{
|
||||
startQuestTimer("msg_text", 3000, npc, null);
|
||||
_jenas_guard.setScriptValue(1);
|
||||
|
3
L2J_Mobius_2.5_Underground/dist/game/data/scripts/ai/bosses/Lindvior/19477-01.html
vendored
Normal file
3
L2J_Mobius_2.5_Underground/dist/game/data/scripts/ai/bosses/Lindvior/19477-01.html
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
<html><head><body>Generator:<br>
|
||||
The generator is now supplying power to the sealed structure.
|
||||
</body></html>
|
3
L2J_Mobius_2.5_Underground/dist/game/data/scripts/ai/bosses/Lindvior/19477.html
vendored
Normal file
3
L2J_Mobius_2.5_Underground/dist/game/data/scripts/ai/bosses/Lindvior/19477.html
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
<body>Generator:<br><br>
|
||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest Lindvior stage_1_activate_generator">Activate the Generator</button>
|
||||
</body></html>
|
@@ -0,0 +1,4 @@
|
||||
<html><body>Rune Castle Patrol Kato:<br>
|
||||
On the Lindvior there is an attack!<br>
|
||||
At this time it's impossible to enter the altar.
|
||||
</body></html>
|
@@ -0,0 +1,4 @@
|
||||
<html><body>Rune Castle Patrol Kato:<br>
|
||||
Lindvior? You're too late, friend.<br>
|
||||
A group of warriors drove him off not long ago.
|
||||
</body></html>
|
@@ -0,0 +1,4 @@
|
||||
<html><body>Rune Castle Patrol Kato:<br>
|
||||
You are overcome by a voice, a voice so powerful you are helpless as it speaks:<br>
|
||||
(The players who belong to an association can only enter through the Association Leader.)
|
||||
</body></html>
|
@@ -0,0 +1,3 @@
|
||||
<html><body>Rune Castle Patrol Kato:<br>
|
||||
(A command channel needs at least minimu: <font color="LEVEL">%min%</font> and maximum: <font color="LEVEL">%max%</font> members to challenge Lindvior.)
|
||||
</body></html>
|
@@ -0,0 +1,3 @@
|
||||
<html><body>Rune Castle Patrol Kato:<br>
|
||||
(A command channel members level must be minimum: <font color="LEVEL">%minlvl% Lvl</font> or higher to challenge Lindvior.)
|
||||
</body></html>
|
6
L2J_Mobius_2.5_Underground/dist/game/data/scripts/ai/bosses/Lindvior/KatoSicanus/33881.html
vendored
Normal file
6
L2J_Mobius_2.5_Underground/dist/game/data/scripts/ai/bosses/Lindvior/KatoSicanus/33881.html
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
<html><body>Rune Castle Patrol Kato:<br>
|
||||
Dire times dictated that I come myself from Rune Castle to help those in need here.<br>
|
||||
What do you need?<br>
|
||||
<Button ALIGN=LEFT ICON="TELEPORT" action="bypass -h Quest KatoSicanus teleport">"I want to test my strength against Lindvior."</Button>
|
||||
<Button ALIGN=LEFT ICON="QUEST" action="bypass -h npc_%objectId%_Quest">Quest</Button>
|
||||
</body></html>
|
129
L2J_Mobius_2.5_Underground/dist/game/data/scripts/ai/bosses/Lindvior/KatoSicanus/KatoSicanus.java
vendored
Normal file
129
L2J_Mobius_2.5_Underground/dist/game/data/scripts/ai/bosses/Lindvior/KatoSicanus/KatoSicanus.java
vendored
Normal file
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
* 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.bosses.Lindvior.KatoSicanus;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.l2jmobius.Config;
|
||||
import com.l2jmobius.gameserver.instancemanager.GrandBossManager;
|
||||
import com.l2jmobius.gameserver.model.L2Party;
|
||||
import com.l2jmobius.gameserver.model.Location;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.NpcHtmlMessage;
|
||||
|
||||
import ai.AbstractNpcAI;
|
||||
|
||||
/**
|
||||
* Kato Sicanus Teleporter AI
|
||||
* @author Gigi
|
||||
* @date 2017-07-13 - [22:17:16]
|
||||
*/
|
||||
public class KatoSicanus extends AbstractNpcAI
|
||||
{
|
||||
// NPCs
|
||||
private static final int KATO_SICANUS = 33881;
|
||||
private static final int LINDVIOR_RAID = 29240;
|
||||
private static final int INVISIBLE = 8572;
|
||||
// Location
|
||||
private static final Location LINDVIOR_LOCATION = new Location(46929, -28807, -1400);
|
||||
|
||||
public KatoSicanus()
|
||||
{
|
||||
addFirstTalkId(KATO_SICANUS);
|
||||
addTalkId(KATO_SICANUS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
if (event.equals("teleport"))
|
||||
{
|
||||
final int status = GrandBossManager.getInstance().getBossStatus(LINDVIOR_RAID);
|
||||
if (player.isGM())
|
||||
{
|
||||
player.teleToLocation(LINDVIOR_LOCATION, true);
|
||||
addSpawn(INVISIBLE, 46707, -28586, -1400, 0, false, 60000, false);
|
||||
GrandBossManager.getInstance().setBossStatus(LINDVIOR_RAID, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (status == 2)
|
||||
{
|
||||
return "33881-1.html";
|
||||
}
|
||||
if (status == 3)
|
||||
{
|
||||
return "33881-2.html";
|
||||
}
|
||||
if (!player.isInParty())
|
||||
{
|
||||
return "33881-3.html";
|
||||
}
|
||||
final L2Party party = player.getParty();
|
||||
final boolean isInCC = party.isInCommandChannel();
|
||||
final List<L2PcInstance> members = (isInCC) ? party.getCommandChannel().getMembers() : party.getMembers();
|
||||
final boolean isPartyLeader = (isInCC) ? party.getCommandChannel().isLeader(player) : party.isLeader(player);
|
||||
if (!isPartyLeader)
|
||||
{
|
||||
return "33881-3.html";
|
||||
}
|
||||
if ((members.size() < Config.LINDVIOR_MIN_PLAYERS) || (members.size() > Config.LINDVIOR_MAX_PLAYERS))
|
||||
{
|
||||
final NpcHtmlMessage packet = new NpcHtmlMessage(npc.getObjectId());
|
||||
packet.setHtml(getHtm(player.getHtmlPrefix(), "33881-4.html"));
|
||||
packet.replace("%min%", Integer.toString(Config.LINDVIOR_MIN_PLAYERS));
|
||||
packet.replace("%max%", Integer.toString(Config.LINDVIOR_MAX_PLAYERS));
|
||||
player.sendPacket(packet);
|
||||
return null;
|
||||
}
|
||||
for (L2PcInstance member : members)
|
||||
{
|
||||
if (member.getLevel() < Config.LINDVIOR_MIN_PLAYER_LVL)
|
||||
{
|
||||
final NpcHtmlMessage packet = new NpcHtmlMessage(npc.getObjectId());
|
||||
packet.setHtml(getHtm(player.getHtmlPrefix(), "33881-5.html"));
|
||||
packet.replace("%minlvl%", Integer.toString(Config.LINDVIOR_MIN_PLAYER_LVL));
|
||||
player.sendPacket(packet);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
for (L2PcInstance member : members)
|
||||
{
|
||||
if (member.isInsideRadius(npc, 1500, true, false))
|
||||
{
|
||||
member.teleToLocation(LINDVIOR_LOCATION, true);
|
||||
addSpawn(INVISIBLE, 46707, -28586, -1400, 0, false, 0, false);
|
||||
GrandBossManager.getInstance().setBossStatus(LINDVIOR_RAID, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onFirstTalk(L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
return "33881.html";
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new KatoSicanus();
|
||||
}
|
||||
}
|
976
L2J_Mobius_2.5_Underground/dist/game/data/scripts/ai/bosses/Lindvior/Lindvior.java
vendored
Normal file
976
L2J_Mobius_2.5_Underground/dist/game/data/scripts/ai/bosses/Lindvior/Lindvior.java
vendored
Normal file
@@ -0,0 +1,976 @@
|
||||
/*
|
||||
* 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.bosses.Lindvior;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
|
||||
import com.l2jmobius.Config;
|
||||
import com.l2jmobius.commons.util.Rnd;
|
||||
import com.l2jmobius.gameserver.ThreadPoolManager;
|
||||
import com.l2jmobius.gameserver.ai.CtrlIntention;
|
||||
import com.l2jmobius.gameserver.datatables.SpawnTable;
|
||||
import com.l2jmobius.gameserver.enums.ChatType;
|
||||
import com.l2jmobius.gameserver.enums.Movie;
|
||||
import com.l2jmobius.gameserver.instancemanager.GrandBossManager;
|
||||
import com.l2jmobius.gameserver.instancemanager.ZoneManager;
|
||||
import com.l2jmobius.gameserver.model.L2Object;
|
||||
import com.l2jmobius.gameserver.model.L2World;
|
||||
import com.l2jmobius.gameserver.model.Location;
|
||||
import com.l2jmobius.gameserver.model.StatsSet;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Attackable;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Character;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2GrandBossInstance;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2GuardInstance;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.events.EventType;
|
||||
import com.l2jmobius.gameserver.model.events.ListenerRegisterType;
|
||||
import com.l2jmobius.gameserver.model.events.annotations.Id;
|
||||
import com.l2jmobius.gameserver.model.events.annotations.RegisterEvent;
|
||||
import com.l2jmobius.gameserver.model.events.annotations.RegisterType;
|
||||
import com.l2jmobius.gameserver.model.events.impl.character.OnCreatureDamageReceived;
|
||||
import com.l2jmobius.gameserver.model.holders.SkillHolder;
|
||||
import com.l2jmobius.gameserver.model.skills.Skill;
|
||||
import com.l2jmobius.gameserver.model.zone.L2ZoneType;
|
||||
import com.l2jmobius.gameserver.model.zone.type.L2NoSummonFriendZone;
|
||||
import com.l2jmobius.gameserver.network.NpcStringId;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.Earthquake;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ExSendUIEvent;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ExShowScreenMessage;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.IClientOutgoingPacket;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.OnEventTrigger;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.SocialAction;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.SpecialCamera;
|
||||
|
||||
import ai.AbstractNpcAI;
|
||||
|
||||
/**
|
||||
* Lindvior Boss
|
||||
* @author Gigi
|
||||
* @date 2017-07-11 - [17:42:53]
|
||||
* <p>
|
||||
* @VIDEO - https://www.youtube.com/watch?v=VknjOjRO9Cw
|
||||
*/
|
||||
public class Lindvior extends AbstractNpcAI
|
||||
{
|
||||
// Monsters
|
||||
private static final int LINDVIOR_FAKE = 19423;
|
||||
private static final int LINDVIOR_GROUND = 25899;
|
||||
private static final int LINDVIOR_RAID = 29240;
|
||||
private static final int LINDVIOR_FLY = 19424;
|
||||
private static final int NPC_GENERATOR = 19477;
|
||||
private static final int GENERATOR_GUARD = 19479;
|
||||
private static final int NPC_ATTACKER_GENERATORS = 25897;
|
||||
private static final int NPC_ATTACKER_GENERATORS_1 = 25895;
|
||||
private static final int LYN_DRACO_ATTACKER_GENERATORS = 29241;
|
||||
private static final int NPC_ATTACKER_SMALL_VORTEX = 25898;
|
||||
private static final int NPC_ATTACKER_BIG_VORTEX = 19427;
|
||||
private static final int INVISIBLE = 8572;
|
||||
private static final int LIONEL_HUNTER = 33886;
|
||||
private static final int LINDVIOR_CAMERA = 19428;
|
||||
// Zone
|
||||
private final static int ZONE_ID = 12107;
|
||||
static final Location CENTER_LOCATION = new Location(46424, -26200, -1400);
|
||||
// Skills
|
||||
private static final SkillHolder SKILL_RECHARGE_POSIBLE = new SkillHolder(15605, 1);
|
||||
private static final SkillHolder RECHARGE = new SkillHolder(15606, 1);
|
||||
private static final SkillHolder SKILL_REFLECT = new SkillHolder(15592, 1);
|
||||
// Item
|
||||
private static final int LINDVIORS_SCALE = 37495;
|
||||
// Trigers
|
||||
private static final int FIRST_STAGE_EVENT_TRIGGER = 21170112;
|
||||
private static final int SECOND_STAGE_EVENT_TRIGGER = 21170100;
|
||||
private static final int ALL_GENERATORS_CONNECTED_EFFECT = 21170110;
|
||||
private static final int RED_ZONE_EFFECT = 21170120;
|
||||
// Status
|
||||
private static final int ALIVE = 0;
|
||||
private static final int FIGHTING = 2;
|
||||
private static final int DEAD = 3;
|
||||
// Tasks
|
||||
protected ScheduledFuture<?> _socialTask;
|
||||
protected ScheduledFuture<?> _mobsSpawnTask;
|
||||
protected ScheduledFuture<?> _collapseTask;
|
||||
protected ScheduledFuture<?> _announceTask;
|
||||
protected ScheduledFuture<?> _announceProtect;
|
||||
protected ScheduledFuture<?> _skillCastTask;
|
||||
protected ScheduledFuture<?> _LynDracoTask;
|
||||
protected ScheduledFuture<?> _smallVortexesTask;
|
||||
protected ScheduledFuture<?> _bigVortexesTask;
|
||||
protected L2NoSummonFriendZone _zoneLair;
|
||||
protected L2GrandBossInstance _lindvior = null;
|
||||
protected L2Npc _lindvior2 = null;
|
||||
protected L2Npc _dummyLindvior;
|
||||
protected L2Npc _vortex = null;
|
||||
protected L2Npc _lionel = null;
|
||||
protected List<L2Npc> _guardSpawn = new ArrayList<>();
|
||||
protected List<L2GuardInstance> _generatorSpawn = new ArrayList<>();
|
||||
protected List<L2Npc> _monsterSpawn = new ArrayList<>();
|
||||
protected List<L2Npc> _LinDracoSpawn = new ArrayList<>();
|
||||
protected int _activeMask = 0;
|
||||
protected int _chargedMask = 0;
|
||||
protected int _status = 0;
|
||||
|
||||
private static final Location[] CONTROL_GENERATOR_SPAWNS =
|
||||
{
|
||||
new Location(45288, -30360, -1432, 0),
|
||||
new Location(48486, -27175, -1432, 0),
|
||||
new Location(45272, -23976, -1432, 0),
|
||||
new Location(42088, -27160, -1432, 0)
|
||||
};
|
||||
private static final Location[] SCHEME_GENERATOR_SPAWNS =
|
||||
{
|
||||
new Location(48440, -26824, -1438, 0),
|
||||
new Location(48392, -27448, -1438, 0),
|
||||
new Location(42136, -27480, -1438, 0),
|
||||
new Location(42136, -26840, -1438, 0),
|
||||
new Location(44936, -24024, -1438, 0),
|
||||
new Location(45592, -24008, -1438, 0),
|
||||
new Location(45608, -30312, -1438, 0),
|
||||
new Location(44984, -30360, -1438, 0)
|
||||
};
|
||||
private static final Location[] ATTACKER_GENERATOR_SPAWNS =
|
||||
{
|
||||
new Location(44863, -24272, -1413, 33713),
|
||||
new Location(45675, -24272, -1413, 33713),
|
||||
new Location(45675, -30057, -1413, 64987),
|
||||
new Location(44863, -30057, -1413, 64987),
|
||||
new Location(42350, -27563, -1413, 46871),
|
||||
new Location(42350, -26809, -1413, 46871),
|
||||
new Location(48220, -26809, -1413, 16383),
|
||||
new Location(48220, -27563, -1413, 16383)
|
||||
};
|
||||
private static final Location[] LYN_DRACO_SPAWNS =
|
||||
{
|
||||
new Location(45300, -28402, -1400, 48845),
|
||||
new Location(46379, -27178, -1400, 1154),
|
||||
new Location(45292, -26043, -1400, 13027),
|
||||
new Location(44215, -27172, -1400, 33966)
|
||||
};
|
||||
private static final Location[] ATTACKER_SMALL_VORTEX_SPAWNS = new Location[]
|
||||
{
|
||||
new Location(46256, -30159, -1430, 57430),
|
||||
new Location(45155, -29987, -1430, 14860),
|
||||
new Location(46219, -27704, -1430, 1744),
|
||||
new Location(46135, -28995, -1430, 43626),
|
||||
new Location(43973, -28265, -1430, 16516),
|
||||
new Location(46782, -29065, -1430, 63368),
|
||||
new Location(47214, -29836, -1430, 46966),
|
||||
new Location(44754, -29120, -1430, 56118),
|
||||
new Location(47089, -28198, -1430, 8537),
|
||||
new Location(44992, -28152, -1430, 11592),
|
||||
new Location(44737, -24885, -1430, 3146),
|
||||
new Location(46096, -24976, -1430, 49650),
|
||||
new Location(46972, -25911, -1430, 62925),
|
||||
new Location(46977, -27136, -1430, 2150),
|
||||
new Location(42889, -24767, -1430, 10246),
|
||||
new Location(47299, -25256, -1430, 1453),
|
||||
new Location(44204, -25026, -1430, 39225),
|
||||
new Location(42875, -28035, -1430, 34755),
|
||||
new Location(41963, -26031, -1430, 18822),
|
||||
new Location(43171, -25942, -1430, 44279),
|
||||
new Location(41874, -27174, -1430, 56030),
|
||||
new Location(44983, -26082, -1430, 7042),
|
||||
new Location(46145, -26804, -1430, 24394),
|
||||
new Location(46148, -26019, -1430, 34151),
|
||||
new Location(45161, -24275, -1430, 39262),
|
||||
new Location(47288, -24141, -1430, 21644),
|
||||
new Location(43722, -26174, -1430, 11001),
|
||||
new Location(44942, -27169, -1430, 39703),
|
||||
new Location(46105, -24170, -1430, 28224),
|
||||
new Location(49084, -27206, -1430, 41996),
|
||||
new Location(48159, -27091, -1430, 62682),
|
||||
new Location(48094, -28789, -1430, 49189),
|
||||
new Location(48958, -27844, -1430, 59758),
|
||||
new Location(43828, -23981, -1430, 10994),
|
||||
new Location(48165, -25777, -1430, 53084),
|
||||
new Location(48267, -28086, -1430, 9266),
|
||||
new Location(43268, -28981, -1430, 23736),
|
||||
new Location(44155, -29821, -1430, 39281),
|
||||
new Location(43991, -29275, -1430, 27277),
|
||||
new Location(44057, -27133, -1430, 64484),
|
||||
new Location(43257, -26764, -1430, 14161),
|
||||
new Location(42300, -25194, -1430, 7811),
|
||||
new Location(42091, -27981, -1430, 30628),
|
||||
new Location(47854, -24735, -1430, 14438)
|
||||
};
|
||||
// @formatter:off
|
||||
private static final int[][] GENERATOR_TRIGERS =
|
||||
{
|
||||
{21170102, 21170103},
|
||||
{21170104, 21170105},
|
||||
{21170106, 21170107},
|
||||
{21170108, 21170109}
|
||||
};
|
||||
protected final int _chargedValues[] = new int[] {0, 0, 0, 0};
|
||||
private static final int[] LINDVIOR_SERVITOR = {25895, 25896, 25897, 29242, 29241, 29243};
|
||||
// @formatter:on
|
||||
private static final NpcStringId[] GUARD_MSG =
|
||||
{
|
||||
NpcStringId.ACTIVATE_THE_GENERATOR_HURRY,
|
||||
NpcStringId.WE_WILL_HOLD_OFF_LINDVIOR_S_MINIONS,
|
||||
};
|
||||
private static final NpcStringId[] GUARD_MSG_1 =
|
||||
{
|
||||
NpcStringId.HOLD_ONTO_THE_GENERATOR_TO_ACTIVATE_THE_CHARGE_SKILL,
|
||||
NpcStringId.THE_GENERATOR_IS_CONNECTED_TO_THE_CANNON,
|
||||
};
|
||||
|
||||
public Lindvior()
|
||||
{
|
||||
super();
|
||||
addAttackId(LINDVIOR_GROUND, LINDVIOR_FLY, LINDVIOR_RAID);
|
||||
addEnterZoneId(ZONE_ID);
|
||||
addExitZoneId(ZONE_ID);
|
||||
addKillId(LINDVIOR_RAID, NPC_GENERATOR);
|
||||
addSkillSeeId(NPC_GENERATOR);
|
||||
addSpawnId(NPC_ATTACKER_GENERATORS, NPC_ATTACKER_GENERATORS_1, LYN_DRACO_ATTACKER_GENERATORS, GENERATOR_GUARD, NPC_GENERATOR);
|
||||
addFirstTalkId(NPC_GENERATOR);
|
||||
addSeeCreatureId(INVISIBLE);
|
||||
_zoneLair = ZoneManager.getInstance().getZoneById(ZONE_ID, L2NoSummonFriendZone.class);
|
||||
// Unlock
|
||||
final StatsSet info = GrandBossManager.getInstance().getStatsSet(LINDVIOR_RAID);
|
||||
final long time = info.getLong("respawn_time") - System.currentTimeMillis();
|
||||
if (time > 0)
|
||||
{
|
||||
startQuestTimer("unlock_lindvior", time, null, null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAttack(L2Npc npc, L2PcInstance attacker, int damage, boolean isSummon)
|
||||
{
|
||||
// Anti BUGGERS
|
||||
if (!_zoneLair.isInsideZone(attacker))
|
||||
{
|
||||
attacker.doDie(null);
|
||||
_log.warning(getName() + ": Character: " + attacker.getName() + " attacked: " + npc.getName() + " out of the boss zone!");
|
||||
}
|
||||
if (!_zoneLair.isInsideZone(npc))
|
||||
{
|
||||
npc.teleToLocation(CENTER_LOCATION, true);
|
||||
_log.warning(getName() + ": Character: " + attacker.getName() + " attacked: " + npc.getName() + " wich is out of the boss zone!");
|
||||
}
|
||||
|
||||
double percent = ((npc.getCurrentHp() - damage) / npc.getMaxHp()) * 100;
|
||||
if ((percent <= 80) && (_status == 0))
|
||||
{
|
||||
_zoneLair.broadcastPacket(new OnEventTrigger(RED_ZONE_EFFECT, true));
|
||||
_zoneLair.getPlayersInside().stream().forEach(p ->
|
||||
{
|
||||
startQuestTimer("stop_red_zone", 10000, _lindvior, p);
|
||||
p.broadcastPacket(new ExShowScreenMessage(NpcStringId.A_FEARSOME_POWER_EMANATES_FROM_LINDVIOR, ExShowScreenMessage.TOP_CENTER, 2000, true));
|
||||
});
|
||||
_lindvior.broadcastPacket(new SocialAction(_lindvior.getObjectId(), 1));
|
||||
_lindvior.setIsDead(true);
|
||||
_lindvior.deleteMe();
|
||||
|
||||
_lindvior = (L2GrandBossInstance) addSpawn(LINDVIOR_FLY, _lindvior.getLocation(), false, 0, false);
|
||||
_lindvior.setCurrentHp(_lindvior.getMaxHp() * 0.8);
|
||||
for (Location loc : ATTACKER_SMALL_VORTEX_SPAWNS)
|
||||
{
|
||||
addSpawn(NPC_ATTACKER_SMALL_VORTEX, loc, true);
|
||||
addSpawn(LINDVIOR_SERVITOR[0], loc, true);
|
||||
}
|
||||
_status = 1;
|
||||
}
|
||||
else if ((percent <= 75) && (_status == 1))
|
||||
{
|
||||
_bigVortexesTask = ThreadPoolManager.schedule(() -> spawnServitor(1, 300, _lindvior.getLocation(), NPC_ATTACKER_BIG_VORTEX), 1000);
|
||||
for (Location loc : ATTACKER_SMALL_VORTEX_SPAWNS)
|
||||
{
|
||||
addSpawn(LINDVIOR_SERVITOR[1], loc, true);
|
||||
}
|
||||
_zoneLair.getPlayersInside().stream().forEach(p -> p.broadcastPacket(new ExShowScreenMessage(NpcStringId.A_GIGANTIC_WHIRLWIND_HAS_APPEARED, ExShowScreenMessage.TOP_CENTER, 2000, true)));
|
||||
_status = 2;
|
||||
}
|
||||
else if ((percent <= 60) && (_status == 2))
|
||||
{
|
||||
_lindvior.broadcastPacket(new SocialAction(_lindvior.getObjectId(), 1));
|
||||
_lindvior.setIsDead(true);
|
||||
_lindvior.deleteMe();
|
||||
|
||||
_lindvior = (L2GrandBossInstance) addSpawn(LINDVIOR_GROUND, _lindvior.getLocation(), false, 0, false);
|
||||
_lindvior.setCurrentHp(_lindvior.getMaxHp() * 0.6);
|
||||
spawnServitor(10, 2000, _lindvior.getLocation(), LINDVIOR_SERVITOR);
|
||||
for (Location loc : ATTACKER_SMALL_VORTEX_SPAWNS)
|
||||
{
|
||||
addSpawn(LINDVIOR_SERVITOR[2], loc, true);
|
||||
}
|
||||
_skillCastTask = ThreadPoolManager.scheduleAtFixedRate(() -> _lindvior.doCast(SKILL_REFLECT.getSkill()), 5000, 80000);
|
||||
_status = 3;
|
||||
}
|
||||
else if ((percent <= 40) && (_status == 3))
|
||||
{
|
||||
_lindvior.broadcastPacket(new SocialAction(_lindvior.getObjectId(), 1));
|
||||
_lindvior.setIsDead(true);
|
||||
_lindvior.deleteMe();
|
||||
|
||||
_lindvior = (L2GrandBossInstance) addSpawn(LINDVIOR_FLY, _lindvior.getLocation(), false, 0, false);
|
||||
_lindvior.setCurrentHp(_lindvior.getMaxHp() * 0.4);
|
||||
|
||||
if (SpawnTable.getInstance().getSpawns(NPC_ATTACKER_BIG_VORTEX) != null)
|
||||
{
|
||||
if ((_vortex != null) && (_vortex.getId() == NPC_ATTACKER_SMALL_VORTEX))
|
||||
{
|
||||
_vortex.getSpawn().stopRespawn();
|
||||
_vortex.deleteMe();
|
||||
}
|
||||
}
|
||||
_status = 4;
|
||||
}
|
||||
else if ((percent <= 35) && (_status == 4))
|
||||
{
|
||||
_smallVortexesTask = ThreadPoolManager.scheduleAtFixedRate(() ->
|
||||
{
|
||||
for (Location loc : ATTACKER_SMALL_VORTEX_SPAWNS)
|
||||
{
|
||||
addSpawn(NPC_ATTACKER_SMALL_VORTEX, loc, true, 60000);
|
||||
addSpawn(LINDVIOR_SERVITOR[3], loc, true);
|
||||
}
|
||||
|
||||
}, 20000, 60000);
|
||||
_status = 5;
|
||||
}
|
||||
else if ((percent <= 20) && (_status == 5))
|
||||
{
|
||||
if (_smallVortexesTask != null)
|
||||
{
|
||||
_smallVortexesTask.cancel(true);
|
||||
_smallVortexesTask = null;
|
||||
}
|
||||
_zoneLair.broadcastPacket(new ExShowScreenMessage(NpcStringId.LINDVIOR_HAS_LANDED, 2, 5000, true));
|
||||
_lindvior.broadcastPacket(new SocialAction(_lindvior.getObjectId(), 1));
|
||||
_lindvior.setIsDead(true);
|
||||
_lindvior.deleteMe();
|
||||
_lindvior = (L2GrandBossInstance) addSpawn(LINDVIOR_RAID, _lindvior.getLocation(), false, 0, false);
|
||||
_lindvior.setCurrentHp(_lindvior.getMaxHp() * 0.2);
|
||||
_bigVortexesTask = ThreadPoolManager.schedule(() -> spawnServitor(1, 300, _lindvior.getLocation(), NPC_ATTACKER_BIG_VORTEX), 1000);
|
||||
for (Location loc : ATTACKER_SMALL_VORTEX_SPAWNS)
|
||||
{
|
||||
addSpawn(NPC_ATTACKER_SMALL_VORTEX, loc, true);
|
||||
addSpawn(LINDVIOR_SERVITOR[4], loc, true);
|
||||
addSpawn(LINDVIOR_SERVITOR[3], loc, true);
|
||||
}
|
||||
_collapseTask = ThreadPoolManager.schedule(Lindvior.this::Clean, 600000);
|
||||
_status = 6;
|
||||
}
|
||||
return super.onAttack(npc, attacker, damage, isSummon);
|
||||
}
|
||||
|
||||
protected void Clean()
|
||||
{
|
||||
_status = 0;
|
||||
if (_socialTask != null)
|
||||
{
|
||||
_socialTask.cancel(false);
|
||||
_socialTask = null;
|
||||
}
|
||||
if (_announceTask != null)
|
||||
{
|
||||
_announceTask.cancel(false);
|
||||
_announceTask = null;
|
||||
}
|
||||
if (_announceProtect != null)
|
||||
{
|
||||
_announceProtect.cancel(false);
|
||||
_announceProtect = null;
|
||||
}
|
||||
if (_skillCastTask != null)
|
||||
{
|
||||
_skillCastTask.cancel(false);
|
||||
_skillCastTask = null;
|
||||
}
|
||||
if (_LynDracoTask != null)
|
||||
{
|
||||
_LynDracoTask.cancel(false);
|
||||
_LynDracoTask = null;
|
||||
}
|
||||
if (_mobsSpawnTask != null)
|
||||
{
|
||||
_mobsSpawnTask.cancel(false);
|
||||
_mobsSpawnTask = null;
|
||||
}
|
||||
if (_collapseTask != null)
|
||||
{
|
||||
_collapseTask.cancel(false);
|
||||
_collapseTask = null;
|
||||
}
|
||||
if (_bigVortexesTask != null)
|
||||
{
|
||||
_bigVortexesTask.cancel(false);
|
||||
_bigVortexesTask = null;
|
||||
}
|
||||
if (_smallVortexesTask != null)
|
||||
{
|
||||
_smallVortexesTask.cancel(false);
|
||||
_smallVortexesTask = null;
|
||||
}
|
||||
if (_lionel != null)
|
||||
{
|
||||
_lionel.deleteMe();
|
||||
}
|
||||
_zoneLair.getCharactersInside().forEach(mob ->
|
||||
{
|
||||
if (mob.isNpc())
|
||||
{
|
||||
mob.deleteMe();
|
||||
mob.setIsDead(true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void Fail(boolean clean)
|
||||
{
|
||||
if (clean)
|
||||
{
|
||||
Clean();
|
||||
}
|
||||
_zoneLair.oustAllPlayers();
|
||||
_zoneLair.broadcastPacket(new OnEventTrigger(FIRST_STAGE_EVENT_TRIGGER, false));
|
||||
cancelQuestTimers("attack_generator");
|
||||
if (GrandBossManager.getInstance().getBossStatus(LINDVIOR_RAID) != 3)
|
||||
{
|
||||
GrandBossManager.getInstance().setBossStatus(LINDVIOR_RAID, ALIVE);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized String onSkillSee(L2Npc npc, L2PcInstance caster, Skill skill, L2Object[] targets, boolean isSummon)
|
||||
{
|
||||
if ((skill.getId() == 15606) && (npc.getId() == NPC_GENERATOR))
|
||||
{
|
||||
synchronized (_chargedValues)
|
||||
{
|
||||
int index = npc.getScriptValue();
|
||||
if (!hasFlag(_chargedMask, 1 << index))
|
||||
{
|
||||
_chargedValues[index] += caster.isGM() ? (30 / 4) + 2 : (1 / 4) + 2;
|
||||
_chargedValues[index] = Math.min(_chargedValues[index], 120);
|
||||
|
||||
L2World.getInstance().forEachVisibleObjectInRange(npc, L2PcInstance.class, 3000, player ->
|
||||
{
|
||||
player.sendPacket(new ExShowScreenMessage(NpcStringId.S1_HAS_CHARGED_THE_CANNON, ExShowScreenMessage.TOP_CENTER, 10000, true, caster.getName()));
|
||||
player.sendPacket(new ExSendUIEvent(player, ExSendUIEvent.TYPE_NORNIL, _chargedValues[index], 120, NpcStringId.CHARGING));
|
||||
});
|
||||
if (_chargedValues[index] >= 120)
|
||||
{
|
||||
_chargedMask |= 1 << index;
|
||||
_chargedValues[index] = 0;
|
||||
}
|
||||
|
||||
if (hasFlag(_chargedMask, 0xf))
|
||||
{
|
||||
nextStage(3);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSpawn(L2Npc npc)
|
||||
{
|
||||
switch (npc.getId())
|
||||
{
|
||||
case NPC_ATTACKER_GENERATORS:
|
||||
case NPC_ATTACKER_GENERATORS_1:
|
||||
{
|
||||
L2World.getInstance().forEachVisibleObjectInRange(npc, L2GuardInstance.class, 800, cha ->
|
||||
{
|
||||
|
||||
if (cha.getId() == GENERATOR_GUARD)
|
||||
{
|
||||
npc.reduceCurrentHp(1, cha, null);
|
||||
cha.reduceCurrentHp(1, npc, null);
|
||||
}
|
||||
if (cha.getId() == NPC_GENERATOR)
|
||||
{
|
||||
((L2Attackable) npc).addDamageHate(cha, 500, 98);
|
||||
}
|
||||
});
|
||||
break;
|
||||
}
|
||||
case LYN_DRACO_ATTACKER_GENERATORS:
|
||||
{
|
||||
((L2Attackable) npc).setCanStopAttackByTime(false);
|
||||
((L2Attackable) npc).setCanReturnToSpawnPoint(false);
|
||||
startQuestTimer("attack_generator", 10000, npc, null, true);
|
||||
break;
|
||||
}
|
||||
case GENERATOR_GUARD:
|
||||
{
|
||||
getTimers().addTimer("NPC_SHOUT", (10 + getRandom(5)) * 1000, npc, null);
|
||||
((L2GuardInstance) npc).setIsInvul(true);
|
||||
break;
|
||||
}
|
||||
case NPC_GENERATOR:
|
||||
{
|
||||
npc.disableCoreAI(true);
|
||||
npc.setDisplayEffect(1);
|
||||
npc.setRandomWalking(false);
|
||||
npc.setIsInvul(true); // Can't get damage now
|
||||
_activeMask = 0;
|
||||
_chargedMask = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return super.onSpawn(npc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSeeCreature(L2Npc npc, L2Character player, boolean isSummon)
|
||||
{
|
||||
setLindviorSpawnTask();
|
||||
npc.getSpawn().stopRespawn();
|
||||
npc.deleteMe();
|
||||
return super.onSeeCreature(npc, player, isSummon);
|
||||
}
|
||||
|
||||
private void nextStage(int _taskId)
|
||||
{
|
||||
switch (_taskId)
|
||||
{
|
||||
case 1: // Spawn Generators
|
||||
{
|
||||
_zoneLair.broadcastPacket(new OnEventTrigger(FIRST_STAGE_EVENT_TRIGGER, true));
|
||||
int i = 0;
|
||||
L2GuardInstance guard;
|
||||
for (Location loc : CONTROL_GENERATOR_SPAWNS)
|
||||
{
|
||||
guard = (L2GuardInstance) addSpawn(NPC_GENERATOR, loc, true);
|
||||
guard.setDisplayEffect(0x01);
|
||||
guard.setScriptValue(i++);
|
||||
_generatorSpawn.add(guard);
|
||||
}
|
||||
|
||||
L2Npc npc;
|
||||
for (Location loc : SCHEME_GENERATOR_SPAWNS)
|
||||
{
|
||||
npc = addSpawn(GENERATOR_GUARD, loc, true);
|
||||
npc.setRandomWalking(false);
|
||||
_guardSpawn.add(npc);
|
||||
}
|
||||
|
||||
_mobsSpawnTask = ThreadPoolManager.scheduleAtFixedRate(() ->
|
||||
{
|
||||
for (Location loc : ATTACKER_GENERATOR_SPAWNS)
|
||||
{
|
||||
if (getRandom(10) <= 5)
|
||||
{
|
||||
_monsterSpawn.add(addSpawn(NPC_ATTACKER_GENERATORS, loc, true));
|
||||
}
|
||||
else
|
||||
{
|
||||
_monsterSpawn.add(addSpawn(NPC_ATTACKER_GENERATORS_1, loc, true));
|
||||
}
|
||||
}
|
||||
}, 30000, 80000);
|
||||
|
||||
_dummyLindvior = addSpawn(LINDVIOR_CAMERA, 45259, -27115, -638, 41325, false, 0, false);
|
||||
_announceTask = ThreadPoolManager.scheduleAtFixedRate(() -> _zoneLair.getPlayersInside().forEach(player -> player.sendPacket(new ExShowScreenMessage(NpcStringId.YOU_MUST_ACTIVATE_THE_4_GENERATORS, ExShowScreenMessage.TOP_CENTER, 7000, true))), 10000, 20000);
|
||||
break;
|
||||
}
|
||||
case 2: // After activation of 4 generators, we wait to be charged
|
||||
{
|
||||
if (_announceTask != null)
|
||||
{
|
||||
_announceTask.cancel(true);
|
||||
_announceTask = null;
|
||||
}
|
||||
_generatorSpawn.forEach(npc ->
|
||||
{
|
||||
npc.setDisplayEffect(1);
|
||||
npc.setIsInvul(false);
|
||||
npc.broadcastInfo();
|
||||
});
|
||||
|
||||
_zoneLair.getPlayersInside().forEach(player ->
|
||||
{
|
||||
player.sendPacket(new OnEventTrigger(FIRST_STAGE_EVENT_TRIGGER, false));
|
||||
cancelQuestTimers("NPC_SHOUT");
|
||||
_guardSpawn.stream().forEach(guard ->
|
||||
{
|
||||
guard.broadcastSay(ChatType.NPC_GENERAL, NpcStringId.ALL_4_GENERATORS_MUST_BE_ACTIVATED);
|
||||
});
|
||||
_announceProtect = ThreadPoolManager.scheduleAtFixedRate(() -> _zoneLair.getPlayersInside().forEach(p -> player.sendPacket(new ExShowScreenMessage(NpcStringId.PROTECT_THE_GENERATOR, ExShowScreenMessage.TOP_CENTER, 7000, true))), 10000, 18000);
|
||||
_zoneLair.broadcastPacket(new SpecialCamera(_dummyLindvior, 3300, 200, 20, 11000, 10500, 0, 8, 1, 0, 0));
|
||||
_generatorSpawn.forEach(npc -> npc.sendInfo(player));
|
||||
startQuestTimer("show_movie", 13000, null, null);
|
||||
startQuestTimer("start_charge", 35000, null, null);
|
||||
startQuestTimer("show_shield_animation", 2000, null, null);
|
||||
});
|
||||
break;
|
||||
}
|
||||
case 3: // After charging all the generators
|
||||
{
|
||||
_zoneLair.broadcastPacket(new OnEventTrigger(ALL_GENERATORS_CONNECTED_EFFECT, true));
|
||||
if (_announceTask != null)
|
||||
{
|
||||
_announceTask.cancel(true);
|
||||
_announceTask = null;
|
||||
}
|
||||
if (_announceProtect != null)
|
||||
{
|
||||
_announceProtect.cancel(false);
|
||||
_announceProtect = null;
|
||||
}
|
||||
if (_skillCastTask != null)
|
||||
{
|
||||
_skillCastTask.cancel(true);
|
||||
_skillCastTask = null;
|
||||
}
|
||||
if (_LynDracoTask != null)
|
||||
{
|
||||
_LynDracoTask.cancel(true);
|
||||
_LynDracoTask = null;
|
||||
}
|
||||
if (_mobsSpawnTask != null)
|
||||
{
|
||||
_mobsSpawnTask.cancel(true);
|
||||
_mobsSpawnTask = null;
|
||||
}
|
||||
_monsterSpawn.forEach(npc ->
|
||||
{
|
||||
if (npc != null)
|
||||
{
|
||||
npc.deleteMe();
|
||||
}
|
||||
});
|
||||
_LinDracoSpawn.forEach(npc ->
|
||||
{
|
||||
if (npc != null)
|
||||
{
|
||||
npc.deleteMe();
|
||||
}
|
||||
});
|
||||
_generatorSpawn.forEach(npc ->
|
||||
{
|
||||
if (npc != null)
|
||||
{
|
||||
npc.deleteMe();
|
||||
}
|
||||
});
|
||||
_guardSpawn.forEach(npc ->
|
||||
{
|
||||
if (npc != null)
|
||||
{
|
||||
npc.deleteMe();
|
||||
}
|
||||
});
|
||||
cancelQuestTimers("attack_generator");
|
||||
_lindvior2.setIsDead(true);
|
||||
_lindvior2.deleteMe();
|
||||
GrandBossManager.getInstance().setBossStatus(LINDVIOR_RAID, FIGHTING);
|
||||
_lionel = addSpawn(LIONEL_HUNTER, 42630, -48231, -792, 855, false, 0, false);
|
||||
|
||||
_lindvior = (L2GrandBossInstance) addSpawn(LINDVIOR_GROUND, CENTER_LOCATION, false, 0, true);
|
||||
_zoneLair.broadcastPacket(new SocialAction(_lindvior.getObjectId(), 1));
|
||||
_zoneLair.getPlayersInside().forEach(_lindvior::sendInfo);
|
||||
_zoneLair.broadcastPacket(new ExShowScreenMessage(NpcStringId.LINDVIOR_HAS_FALLEN_FROM_THE_SKY, ExShowScreenMessage.TOP_CENTER, 7000));
|
||||
_mobsSpawnTask = ThreadPoolManager.scheduleAtFixedRate(() -> spawnServitor(2, 1000, _lindvior.getLocation(), LINDVIOR_SERVITOR), 60000, 180000);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
switch (event)
|
||||
{
|
||||
case "unlock_lindvior":
|
||||
{
|
||||
GrandBossManager.getInstance().setBossStatus(LINDVIOR_RAID, ALIVE);
|
||||
break;
|
||||
}
|
||||
case "stage_1_activate_generator":
|
||||
{
|
||||
int index = npc.getScriptValue();
|
||||
if (!hasFlag(_activeMask, 1 << index))
|
||||
{
|
||||
_activeMask |= 1 << index;
|
||||
npc.setDisplayEffect(0x02);
|
||||
sendEventTrigger(true, GENERATOR_TRIGERS[index]);
|
||||
_zoneLair.getPlayersInside().stream().forEach(p -> p.broadcastPacket(new Earthquake(p.getX(), p.getY(), p.getZ(), 20, 10)));
|
||||
if (hasFlag(_activeMask, 0xf))
|
||||
{
|
||||
nextStage(2);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "show_shield_animation": // zone brodcat shield event triger
|
||||
{
|
||||
_zoneLair.getPlayersInside().forEach(p ->
|
||||
{
|
||||
p.sendPacket(new OnEventTrigger(SECOND_STAGE_EVENT_TRIGGER, true));
|
||||
});
|
||||
_guardSpawn.stream().forEach(guard ->
|
||||
{
|
||||
guard.broadcastSay(ChatType.NPC_GENERAL, NpcStringId.THE_GENERATOR_IS_CONNECTED_TO_THE_CANNON);
|
||||
});
|
||||
break;
|
||||
}
|
||||
case "show_movie": // zone brodcat Lindvior scene movie
|
||||
{
|
||||
_zoneLair.getPlayersInside().forEach(p ->
|
||||
{
|
||||
playMovie(p, Movie.SC_LIND_OPENING);
|
||||
});
|
||||
_dummyLindvior.deleteMe();
|
||||
_lindvior2 = addSpawn(LINDVIOR_FAKE, CENTER_LOCATION, false, 0, false);
|
||||
_lindvior2.setTargetable(false);
|
||||
_announceTask = ThreadPoolManager.scheduleAtFixedRate(() -> _zoneLair.getPlayersInside().forEach(p -> p.sendPacket(new ExShowScreenMessage(NpcStringId.CHARGE_THE_CANNON_USING_THE_GENERATOR, ExShowScreenMessage.TOP_CENTER, 7000, true))), 40000, 20000);
|
||||
break;
|
||||
}
|
||||
case "start_charge":
|
||||
{
|
||||
_skillCastTask = ThreadPoolManager.scheduleAtFixedRate(() -> _generatorSpawn.forEach(generators ->
|
||||
{
|
||||
int index = generators.getScriptValue();
|
||||
if (!generators.isCastingNow() && (generators.getEffectList().getBuffInfoBySkillId(SKILL_RECHARGE_POSIBLE.getSkillId()) == null) && !hasFlag(_chargedMask, 1 << index))
|
||||
{
|
||||
// TODO Need core implemented combo skill packet.
|
||||
// On this moment player automatic charge generator if distance generator and player <= 900
|
||||
generators.doCast(SKILL_RECHARGE_POSIBLE.getSkill());
|
||||
L2World.getInstance().forEachVisibleObjectInRange(generators, L2PcInstance.class, 900, p ->
|
||||
{
|
||||
p.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
|
||||
p.setTarget(generators);
|
||||
p.doCast(RECHARGE.getSkill());
|
||||
});
|
||||
_guardSpawn.stream().forEach(guard ->
|
||||
{
|
||||
guard.setTarget(generators);
|
||||
guard.doCast(RECHARGE.getSkill());
|
||||
guard.setIsInvul(false);
|
||||
if (!guard.isDead())
|
||||
{
|
||||
guard.broadcastSay(ChatType.NPC_GENERAL, GUARD_MSG_1[getRandom(GUARD_MSG_1.length)]);
|
||||
}
|
||||
});
|
||||
}
|
||||
}), 10000, 20000);
|
||||
_LynDracoTask = ThreadPoolManager.scheduleAtFixedRate(() ->
|
||||
{
|
||||
for (Location loc : LYN_DRACO_SPAWNS)
|
||||
{
|
||||
_LinDracoSpawn.add(addSpawn(LYN_DRACO_ATTACKER_GENERATORS, loc, true));
|
||||
}
|
||||
}, 20000, 60000);
|
||||
break;
|
||||
}
|
||||
case "stop_red_zone":
|
||||
{
|
||||
_zoneLair.broadcastPacket(new OnEventTrigger(RED_ZONE_EFFECT, false));
|
||||
break;
|
||||
}
|
||||
case "attack_generator":
|
||||
{
|
||||
if ((npc != null) && !npc.isDead())
|
||||
{
|
||||
L2World.getInstance().forEachVisibleObjectInRange(npc, L2GuardInstance.class, 3000, generator ->
|
||||
{
|
||||
if (generator.getId() == NPC_GENERATOR)
|
||||
{
|
||||
npc.setTarget(generator);
|
||||
npc.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, generator.getLocation());
|
||||
if (npc.distFromMe(generator) < 500)
|
||||
{
|
||||
npc.reduceCurrentHp(1, generator, null);
|
||||
generator.reduceCurrentHp(1, npc, null);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
|
||||
{
|
||||
if (npc.getId() == LINDVIOR_RAID)
|
||||
{
|
||||
_zoneLair.broadcastPacket(new ExShowScreenMessage(NpcStringId.HONORABLE_WARRIORS_HAVE_DRIVEN_OFF_LINDVIOR_THE_EVIL_WIND_DRAGON, ExShowScreenMessage.TOP_CENTER, 10000, true));
|
||||
GrandBossManager.getInstance().setBossStatus(LINDVIOR_RAID, DEAD);
|
||||
final long respawnTime = (Config.LINDVIOR_SPAWN_INTERVAL + getRandom(-Config.LINDVIOR_SPAWN_RANDOM, Config.LINDVIOR_SPAWN_RANDOM)) * 3600000;
|
||||
final StatsSet info = GrandBossManager.getInstance().getStatsSet(LINDVIOR_RAID);
|
||||
info.set("respawn_time", System.currentTimeMillis() + respawnTime);
|
||||
GrandBossManager.getInstance().setStatsSet(LINDVIOR_RAID, info);
|
||||
startQuestTimer("unlock_lindvior", respawnTime, null, null);
|
||||
if (_mobsSpawnTask != null)
|
||||
{
|
||||
_mobsSpawnTask.cancel(true);
|
||||
_mobsSpawnTask = null;
|
||||
}
|
||||
_zoneLair.getCharactersInside().stream().filter(L2Character::isNpc).forEach(mob -> mob.deleteMe());
|
||||
ThreadPoolManager.schedule(() -> npc.decayMe(), 10000);
|
||||
_zoneLair.broadcastPacket(new OnEventTrigger(SECOND_STAGE_EVENT_TRIGGER, false));
|
||||
_zoneLair.broadcastPacket(new OnEventTrigger(FIRST_STAGE_EVENT_TRIGGER, true));
|
||||
_lionel.deleteMe();
|
||||
}
|
||||
else if (npc.getId() == NPC_GENERATOR)
|
||||
{
|
||||
_zoneLair.broadcastPacket(new ExShowScreenMessage(NpcStringId.THE_GENERATOR_HAS_BEEN_DESTROYED, ExShowScreenMessage.TOP_CENTER, 5000, true));
|
||||
Clean();
|
||||
_collapseTask = ThreadPoolManager.schedule(() -> Fail(false), 20000);
|
||||
}
|
||||
return super.onKill(npc, killer, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onFirstTalk(L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
if (npc.getId() == NPC_GENERATOR)
|
||||
{
|
||||
return npc.getDisplayEffect() == 1 ? "19477.html" : "19477-01.html";
|
||||
}
|
||||
return super.onFirstTalk(npc, player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onEnterZone(L2Character character, L2ZoneType zone)
|
||||
{
|
||||
if (zone.getId() == ZONE_ID)
|
||||
{
|
||||
if (_collapseTask != null)
|
||||
{
|
||||
_collapseTask.cancel(true);
|
||||
_collapseTask = null;
|
||||
}
|
||||
}
|
||||
return super.onEnterZone(character, zone);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onExitZone(L2Character character, L2ZoneType zone)
|
||||
{
|
||||
if (zone.getId() == ZONE_ID)
|
||||
{
|
||||
if (zone.getPlayersInside().isEmpty())
|
||||
{
|
||||
_collapseTask = ThreadPoolManager.schedule(() -> Fail(true), 900000);
|
||||
}
|
||||
}
|
||||
return super.onExitZone(character, zone);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTimerEvent(String event, StatsSet params, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
if (event.equals("NPC_SHOUT"))
|
||||
{
|
||||
if ((npc != null) && !npc.isDead())
|
||||
{
|
||||
npc.broadcastSay(ChatType.NPC_GENERAL, GUARD_MSG[getRandom(GUARD_MSG.length)]);
|
||||
getTimers().addTimer("NPC_SHOUT", (10 + getRandom(5)) * 1000, npc, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void sendEventTrigger(boolean status, int... triggers)
|
||||
{
|
||||
IClientOutgoingPacket[] pakets = new IClientOutgoingPacket[triggers.length];
|
||||
for (int i = 0; i < triggers.length; i++)
|
||||
{
|
||||
pakets[i] = new OnEventTrigger(triggers[i], status);
|
||||
}
|
||||
for (IClientOutgoingPacket packet : pakets)
|
||||
{
|
||||
_zoneLair.broadcastPacket(packet);
|
||||
}
|
||||
}
|
||||
|
||||
private void spawnServitor(int count, int radius, Location loc, int... npcIds)
|
||||
{
|
||||
int x = loc.getX(), y = loc.getY();
|
||||
if (radius > 0)
|
||||
{
|
||||
x += Rnd.get(-radius, radius);
|
||||
y += Rnd.get(-radius, radius);
|
||||
}
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
_monsterSpawn.add(addSpawn(npcIds[getRandom(npcIds.length)], x, y, loc.getZ(), loc.getHeading(), true, 0, true));
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean hasFlag(int val, int flag)
|
||||
{
|
||||
return (val & flag) == flag;
|
||||
}
|
||||
|
||||
public void setLindviorSpawnTask()
|
||||
{
|
||||
synchronized (this)
|
||||
{
|
||||
if (_socialTask == null)
|
||||
{
|
||||
_socialTask = ThreadPoolManager.schedule(() -> nextStage(1), 3000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@RegisterEvent(EventType.ON_CREATURE_DAMAGE_RECEIVED)
|
||||
@RegisterType(ListenerRegisterType.NPC)
|
||||
@Id(LINDVIOR_FLY)
|
||||
@Id(LINDVIOR_RAID)
|
||||
@Id(LINDVIOR_GROUND)
|
||||
public void onCreatureDamageReceived(OnCreatureDamageReceived event)
|
||||
{
|
||||
_zoneLair.getPlayersInside().stream().forEach(p ->
|
||||
{
|
||||
switch (_status)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
{
|
||||
giveItemRandomly(p, null, LINDVIORS_SCALE, 1, -1, 0.015, true);
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
giveItemRandomly(p, null, LINDVIORS_SCALE, 2, -1, 0.015, true);
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
case 4:
|
||||
{
|
||||
giveItemRandomly(p, null, LINDVIORS_SCALE, 3, -1, 0.015, true);
|
||||
break;
|
||||
}
|
||||
case 5:
|
||||
{
|
||||
giveItemRandomly(p, null, LINDVIORS_SCALE, 4, -1, 0.015, true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new Lindvior();
|
||||
}
|
||||
}
|
175
L2J_Mobius_2.5_Underground/dist/game/data/scripts/ai/bosses/Lindvior/LindviorBoss.java
vendored
Normal file
175
L2J_Mobius_2.5_Underground/dist/game/data/scripts/ai/bosses/Lindvior/LindviorBoss.java
vendored
Normal file
@@ -0,0 +1,175 @@
|
||||
/*
|
||||
* 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.bosses.Lindvior;
|
||||
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.holders.SkillHolder;
|
||||
|
||||
import ai.AbstractNpcAI;
|
||||
|
||||
/**
|
||||
* LindviorBoss AI
|
||||
* @author Gigi
|
||||
* @date 2017-08-02 - [11:05:21]
|
||||
*/
|
||||
public class LindviorBoss extends AbstractNpcAI
|
||||
{
|
||||
// Boss
|
||||
private static final int LINDVIOR_GROUND = 25899;
|
||||
private static final int LINDVIOR_RAID = 29240;
|
||||
private static final int LINDVIOR_FLY = 19424;
|
||||
// Skills
|
||||
private static final SkillHolder SKILL_FLY_UP = new SkillHolder(15278, 1);
|
||||
private static final SkillHolder SKILL_RABIES = new SkillHolder(15269, 1);
|
||||
private static final SkillHolder SKILL_FLY = new SkillHolder(15279, 1);
|
||||
private static final SkillHolder MASS_HELL_BINDING = new SkillHolder(11052, 6);
|
||||
private static final SkillHolder MIGHTY_WIND_STRIKE = new SkillHolder(15274, 1);
|
||||
private static final SkillHolder WIND_PULL = new SkillHolder(15591, 1);
|
||||
private static final SkillHolder LINDVIORS_JUMP = new SkillHolder(15430, 1);
|
||||
private static final SkillHolder BODY_SLAM = new SkillHolder(15271, 1);
|
||||
private static final SkillHolder SOAR = new SkillHolder(15279, 1);
|
||||
private static final SkillHolder WIND_BREAT = new SkillHolder(15272, 1);
|
||||
private static final SkillHolder TAIL_SWIPE = new SkillHolder(15273, 1);
|
||||
private static final SkillHolder TORNADO = new SkillHolder(15275, 1);
|
||||
private static final SkillHolder LINDVIORS_ATTACK = new SkillHolder(15600, 1);
|
||||
// Chances
|
||||
private final static int CHANCE_MIGHTY_WIND_STRIKE = 9;
|
||||
private final static int CHANCE_WIND_PULL = 4;
|
||||
private final static int CHANCE_LINDVIORS_JUMP = 7;
|
||||
private final static int CHANCE_BODY_SLAM = 2;
|
||||
private final static int CHANCE_SOAR = 8;
|
||||
private final static int CHANCE_WIND_BREAT = 3;
|
||||
private final static int CHANCE_TAIL_SWIPE = 5;
|
||||
private final static int CHANCE_TORNADO = 6;
|
||||
private final static int CHANCE_LINDVIORS_ATTACK = 1;
|
||||
|
||||
public LindviorBoss()
|
||||
{
|
||||
super();
|
||||
addAttackId(LINDVIOR_GROUND, LINDVIOR_FLY, LINDVIOR_RAID);
|
||||
addSpawnId(LINDVIOR_FLY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAttack(L2Npc npc, L2PcInstance attacker, int damage, boolean isSummon)
|
||||
{
|
||||
double percent = ((npc.getCurrentHp() - damage) / npc.getMaxHp()) * 100;
|
||||
final int chance = getRandom(100);
|
||||
switch (npc.getId())
|
||||
{
|
||||
case LINDVIOR_GROUND:
|
||||
{
|
||||
if ((percent <= 80) && npc.isScriptValue(0))
|
||||
{
|
||||
|
||||
npc.doCast(SKILL_FLY_UP.getSkill());
|
||||
npc.doCast(SKILL_RABIES.getSkill());
|
||||
npc.setScriptValue(1);
|
||||
}
|
||||
else if ((percent <= 40) && (npc.isScriptValue(1)))
|
||||
{
|
||||
npc.doCast(SKILL_FLY.getSkill());
|
||||
npc.setScriptValue(2);
|
||||
}
|
||||
else if (!npc.isCastingNow() && (chance <= CHANCE_MIGHTY_WIND_STRIKE))
|
||||
{
|
||||
npc.setTarget(attacker);
|
||||
npc.doCast(MIGHTY_WIND_STRIKE.getSkill());
|
||||
}
|
||||
else if (!npc.isCastingNow() && (chance <= CHANCE_WIND_PULL))
|
||||
{
|
||||
npc.setTarget(attacker);
|
||||
npc.doCast(WIND_PULL.getSkill());
|
||||
}
|
||||
else if (!npc.isCastingNow() && (chance <= CHANCE_LINDVIORS_JUMP))
|
||||
{
|
||||
npc.setTarget(attacker);
|
||||
npc.doCast(LINDVIORS_JUMP.getSkill());
|
||||
}
|
||||
else if (!npc.isCastingNow() && (chance <= CHANCE_BODY_SLAM))
|
||||
{
|
||||
npc.setTarget(attacker);
|
||||
npc.doCast(BODY_SLAM.getSkill());
|
||||
}
|
||||
else if (!npc.isCastingNow() && (chance <= CHANCE_TAIL_SWIPE))
|
||||
{
|
||||
npc.setTarget(attacker);
|
||||
npc.doCast(TAIL_SWIPE.getSkill());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case LINDVIOR_FLY:
|
||||
{
|
||||
if (!npc.isCastingNow() && (chance <= CHANCE_SOAR))
|
||||
{
|
||||
npc.setTarget(attacker);
|
||||
npc.doCast(SOAR.getSkill());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case LINDVIOR_RAID:
|
||||
{
|
||||
if ((percent <= 20) && (npc.isScriptValue(0)))
|
||||
{
|
||||
npc.doCast(SKILL_FLY.getSkill());
|
||||
npc.setScriptValue(1);
|
||||
}
|
||||
else if (!npc.isCastingNow() && (chance <= CHANCE_WIND_BREAT))
|
||||
{
|
||||
npc.setTarget(attacker);
|
||||
npc.doCast(WIND_BREAT.getSkill());
|
||||
}
|
||||
else if (!npc.isCastingNow() && (chance <= CHANCE_WIND_PULL))
|
||||
{
|
||||
npc.setTarget(attacker);
|
||||
npc.doCast(WIND_PULL.getSkill());
|
||||
}
|
||||
else if (!npc.isCastingNow() && (chance <= CHANCE_TAIL_SWIPE))
|
||||
{
|
||||
npc.setTarget(attacker);
|
||||
npc.doCast(TAIL_SWIPE.getSkill());
|
||||
}
|
||||
else if (!npc.isCastingNow() && (chance <= CHANCE_TORNADO))
|
||||
{
|
||||
npc.setTarget(attacker);
|
||||
npc.doCast(TORNADO.getSkill());
|
||||
}
|
||||
else if (!npc.isCastingNow() && (chance <= CHANCE_LINDVIORS_ATTACK))
|
||||
{
|
||||
npc.setTarget(attacker);
|
||||
npc.doCast(LINDVIORS_ATTACK.getSkill());
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return super.onAttack(npc, attacker, damage, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSpawn(L2Npc npc)
|
||||
{
|
||||
npc.setRandomWalking(true);
|
||||
npc.doCast(MASS_HELL_BINDING.getSkill());
|
||||
return super.onSpawn(npc);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new LindviorBoss();
|
||||
}
|
||||
}
|
67
L2J_Mobius_2.5_Underground/dist/game/data/scripts/ai/bosses/Lindvior/LionelHunter.java
vendored
Normal file
67
L2J_Mobius_2.5_Underground/dist/game/data/scripts/ai/bosses/Lindvior/LionelHunter.java
vendored
Normal file
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* 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.bosses.Lindvior;
|
||||
|
||||
import com.l2jmobius.gameserver.enums.ChatType;
|
||||
import com.l2jmobius.gameserver.instancemanager.WalkingManager;
|
||||
import com.l2jmobius.gameserver.model.StatsSet;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.network.NpcStringId;
|
||||
|
||||
import ai.AbstractNpcAI;
|
||||
|
||||
/**
|
||||
* Lionel Hunter AI
|
||||
* @author Gigi
|
||||
* @date 2017-07-23 - [22:54:59]
|
||||
*/
|
||||
public class LionelHunter extends AbstractNpcAI
|
||||
{
|
||||
// Npc
|
||||
private static final int LIONEL_HUNTER = 33886;
|
||||
// Misc
|
||||
private static final String ROUTE_NAME = "Rune_Lionel";
|
||||
|
||||
public LionelHunter()
|
||||
{
|
||||
addSpawnId(LIONEL_HUNTER);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTimerEvent(String event, StatsSet params, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
if (event.equals("NPC_SHOUT") && (npc != null))
|
||||
{
|
||||
npc.broadcastSay(ChatType.NPC_GENERAL, NpcStringId.WE_JUST_LOCATED_LINDVIOR_THOSE_WHO_ARE_WILLING_TO_FIGHT_CAN_DO_SO_AT_ANY_TIME_NOW);
|
||||
getTimers().addTimer("NPC_SHOUT", (10 + getRandom(5)) * 1000, npc, null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSpawn(L2Npc npc)
|
||||
{
|
||||
getTimers().addTimer("NPC_SHOUT", (10 + getRandom(5)) * 1000, npc, null);
|
||||
WalkingManager.getInstance().startMoving(npc, ROUTE_NAME);
|
||||
return super.onSpawn(npc);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new LionelHunter();
|
||||
}
|
||||
}
|
176
L2J_Mobius_2.5_Underground/dist/game/data/scripts/ai/bosses/Lindvior/Vortex.java
vendored
Normal file
176
L2J_Mobius_2.5_Underground/dist/game/data/scripts/ai/bosses/Lindvior/Vortex.java
vendored
Normal file
@@ -0,0 +1,176 @@
|
||||
/*
|
||||
* 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.bosses.Lindvior;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import com.l2jmobius.gameserver.ai.CtrlIntention;
|
||||
import com.l2jmobius.gameserver.geoengine.GeoEngine;
|
||||
import com.l2jmobius.gameserver.model.L2World;
|
||||
import com.l2jmobius.gameserver.model.Location;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Character;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.FlyToLocation;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ValidateLocation;
|
||||
|
||||
import ai.AbstractNpcAI;
|
||||
|
||||
/**
|
||||
* Vortex AI
|
||||
* @author Gigi
|
||||
* @date 2017-07-23 - [10:32:50]
|
||||
*/
|
||||
public class Vortex extends AbstractNpcAI
|
||||
{
|
||||
private static final int SMALL_VORTEX = 25898;
|
||||
private static final int BIG_VORTEX = 19427;
|
||||
|
||||
public Vortex()
|
||||
{
|
||||
super();
|
||||
addSeeCreatureId(SMALL_VORTEX, BIG_VORTEX);
|
||||
addSpawnId(SMALL_VORTEX, BIG_VORTEX);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
switch (event)
|
||||
{
|
||||
case "rnd_small":
|
||||
{
|
||||
L2World.getInstance().forEachVisibleObjectInRange(npc, L2PcInstance.class, 250, attackers ->
|
||||
{
|
||||
if ((attackers != null) && !attackers.isDead() && !attackers.isAlikeDead())
|
||||
{
|
||||
attackers.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
|
||||
final int radians = (int) Math.toRadians(npc.calculateDirectionTo(attackers));
|
||||
final int x = (int) (attackers.getX() + (600 * Math.cos(radians)));
|
||||
final int y = (int) (attackers.getY() + (600 * Math.sin(radians)));
|
||||
final int z = attackers.getZ();
|
||||
final Location loc = GeoEngine.getInstance().canMoveToTargetLoc(attackers.getX(), attackers.getY(), attackers.getZ(), x, y, z, attackers.getInstanceWorld());
|
||||
attackers.broadcastPacket(new FlyToLocation(attackers, x, y, z, FlyToLocation.FlyType.THROW_UP, 800, 800, 800));
|
||||
attackers.setXYZ(loc);
|
||||
attackers.broadcastPacket(new ValidateLocation(attackers));
|
||||
npc.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, player);
|
||||
startQuestTimer("stop_knock_down", 5000, npc, attackers);
|
||||
startQuestTimer("despawn_small", 5000, npc, null);
|
||||
}
|
||||
});
|
||||
break;
|
||||
}
|
||||
case "rnd_big":
|
||||
{
|
||||
L2World.getInstance().forEachVisibleObjectInRange(npc, L2PcInstance.class, 500, attackers ->
|
||||
{
|
||||
if ((attackers != null) && !attackers.isDead() && !attackers.isAlikeDead())
|
||||
{
|
||||
attackers.setCurrentHp(1.0);
|
||||
attackers.setCurrentMp(1.0);
|
||||
attackers.setCurrentCp(1.0);
|
||||
startQuestTimer("despawn_big", 600000, npc, null);
|
||||
}
|
||||
});
|
||||
break;
|
||||
}
|
||||
case "despawn_small":
|
||||
{
|
||||
if (npc != null)
|
||||
{
|
||||
cancelQuestTimers("rnd_small");
|
||||
npc.getSpawn().stopRespawn();
|
||||
npc.doDie(null);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "despawn_big":
|
||||
{
|
||||
if (npc != null)
|
||||
{
|
||||
cancelQuestTimers("despawn_big");
|
||||
npc.getSpawn().stopRespawn();
|
||||
npc.deleteMe();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return super.onAdvEvent(event, npc, player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSeeCreature(L2Npc npc, L2Character player, boolean isSummon)
|
||||
{
|
||||
switch (npc.getId())
|
||||
{
|
||||
case SMALL_VORTEX:
|
||||
{
|
||||
startQuestTimer("rnd_small", 5000, npc, null, true);
|
||||
break;
|
||||
}
|
||||
case BIG_VORTEX:
|
||||
{
|
||||
startQuestTimer("rnd_big", 10000, npc, null, true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return super.onSeeCreature(npc, player, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSpawn(L2Npc npc)
|
||||
{
|
||||
switch (npc.getId())
|
||||
{
|
||||
case SMALL_VORTEX:
|
||||
{
|
||||
attackRandomTarget(npc);
|
||||
npc.setRandomWalking(true);
|
||||
npc.setIsRunning(true);
|
||||
break;
|
||||
}
|
||||
case BIG_VORTEX:
|
||||
{
|
||||
attackRandomTarget(npc);
|
||||
npc.setRandomWalking(true);
|
||||
npc.setIsRunning(true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return super.onSpawn(npc);
|
||||
}
|
||||
|
||||
private void attackRandomTarget(L2Npc npc)
|
||||
{
|
||||
final Collection<L2PcInstance> players = L2World.getInstance().getVisibleObjects(npc, L2PcInstance.class);
|
||||
{
|
||||
if ((players == null) || players.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (players.size() > 0)
|
||||
{
|
||||
addAttackPlayerDesire(npc, players.stream().findAny().get());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new Vortex();
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user