Lindvior AI.

Contributed by gigilo1968.
This commit is contained in:
MobiusDev 2017-09-10 12:29:08 +00:00
parent 96db3acd3f
commit 24bc5b6594
75 changed files with 5372 additions and 342 deletions

View File

@ -17,8 +17,9 @@ INSERT IGNORE INTO `grandboss_data` (`boss_id`,`loc_x`,`loc_y`,`loc_z`,`heading`
(29006, 17726, 108915, -6480, 0, 622493.58388, 3793.536), -- Core
(29014, 55024, 17368, -5412, 10126, 622493.58388, 3793.536), -- Orfen
(29020, 116033, 17447, 10107, -25348, 4068372, 39960), -- Baium
(29028, -105200, -253104, -15264, 0, 62041918, 2248572), -- Valakas
(29068, 185708, 114298, -8221,32768, 62802301, 1998000), -- Antharas
(29028, -105200, -253104, -15264, 0, 62041918, 2248572), -- Valakas
(29240, 0, 0, 0, 0, 288282589, 47100), -- Lindvior
(29118, 0, 0, 0, 0, 4109288, 1220547), -- Beleth
(25286, 185080, -12613, -5499, 16550, 556345880, 86847), -- Anakim
(25283, 185062, -9605, -5499, 15640, 486021997, 79600); -- Lilith

View File

@ -145,3 +145,22 @@ LilithMinPlayerLvl = 85
# Maximum players Level for enter to Lilith. Retail: 89
LilithMaxPlayerLvl = 89
# ---------------------------------------------------------------------------
# Lindvior
# ---------------------------------------------------------------------------
# Interval time of Lindvior. Value is hour. Range 1-480. Retail: 264
IntervalOfLindviorSpawn = 264
# Random interval. Range 1-192. Retail: 72
RandomOfLindviorSpawn = 72
# Minimal count of players for enter to Lindvior. Retail: 49
LindviorMinPlayers = 49
# Maximum count of players for enter to Lindvior. Retail: 112
LindviorMaxPlayers = 112
# Minimum players Level for enter to Lindvior. Retail: 99
LindviorMinPlayerLvl = 99

View File

@ -2352,4 +2352,8 @@
<point X="-113715" Y="236304" Z="-3044" delay="1" run="true" />
<point X="-113670" Y="236689" Z="-3044" delay="0" run="true" />
</route>
<route name="Rune_Lionel" repeat="true" repeatStyle="cycle">
<point X="42630" Y="-48231" Z="-792" delay="0" run="true" />
<point X="45069" Y="-48034" Z="-792" delay="0" run="true" />
</route>
</routes>

View File

@ -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);

View File

@ -0,0 +1,3 @@
<html><head><body>Generator:<br>
The generator is now supplying power to the sealed structure.
</body></html>

View 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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View 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>

View 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();
}
}

View 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();
}
}

View 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();
}
}

View 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();
}
}

View 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();
}
}

View File

@ -1954,7 +1954,7 @@
<attack physical="689.07320120658" magical="470.63282486066" critical="4" attackSpeed="253" range="40" />
<defence physical="296.22641509434" magical="216.70091537456" />
</stats>
<status attackable="false" />
<status attackable="false" targetable="false" showName="false" />
<collision>
<radius normal="11" />
<height normal="25" />

View File

@ -825,58 +825,76 @@
<height normal="40" />
</collision>
</npc>
<npc id="19423" level="99" type="L2Npc" name="Lindvior" title="Wind Dragon">
<npc id="19423" level="102" type="L2GrandBoss" name="Lindvior" title="Wind Dragon">
<!-- AUTO GENERATED NPC TODO: FIX IT -->
<race>DRAGON</race>
<sex>FEMALE</sex>
<mpReward value="20" type="PER" ticks="10" affects="PARTY" />
<stats str="88" int="79" dex="55" wit="78" con="82" men="78">
<vitals hp="8446" hpRegen="10.5" mp="2355" mpRegen="3.6" />
<stats str="164" int="188" dex="55" wit="78" con="111" men="149">
<vitals hp="209461939" hpRegen="10.5" mp="47100.0" mpRegen="3.6" />
<speed>
<walk ground="100" />
<run ground="1" />
<run ground="270" />
</speed>
<attack physical="1518.8555746574" magical="695.44490591753" critical="4" attackSpeed="180" range="40" />
<defence physical="335.10638297872" magical="245.06705989748" />
<attack physical="63862.33880135" magical="11469.742130133" critical="4" attackSpeed="253" range="40" />
<defence physical="7772.0207253886" magical="3235.1068620499" />
<attribute>
<defence fire="20" water="20" wind="20" earth="20" holy="20" dark="20" />
<defence fire="300" water="300" wind="370" earth="250" holy="300" dark="300" />
<attack type="WIND" value="370" />
</attribute>
<abnormalResist physical="0" magical="0" />
</stats>
<status attackable="false" undying="false" />
<status attackable="false" />
<skill_list>
<skill id="4416" level="10" /> <!-- Dragons -->
<skill id="4415" level="1" /> <!-- Bare Hands -->
<skill id="4416" level="10"/> <!-- Dragons -->
<skill id="4408" level="1"/> <!-- HP 1x -->
<skill id="4409" level="1"/> <!-- MP 1x -->
<skill id="4410" level="11"/> <!-- P. Atk. Modifiers. -->
<skill id="4411" level="11"/> <!-- M. Atk. Modifiers. -->
<skill id="4412" level="11"/> <!-- P. Def. Modifiers. -->
<skill id="4413" level="11"/> <!-- M. Def. Modifiers. -->
<skill id="4414" level="2"/> <!-- Heavy Armor Type -->
<skill id="4415" level="1"/> <!-- Bare Hands -->
</skill_list>
<ai aggroRange="2000" isAggressive="true" />
<collision>
<radius normal="190" />
<height normal="1500" />
</collision>
</npc>
<npc id="19424" level="99" type="L2Monster" name="Lindvior" title="Wind Dragon">
<npc id="19424" level="102" type="L2GrandBoss" name="Lindvior" title="Wind Dragon">
<!-- AUTO GENERATED NPC TODO: FIX IT -->
<race>DRAGON</race>
<sex>FEMALE</sex>
<mpReward value="20" type="PER" ticks="10" affects="PARTY" />
<stats str="88" int="79" dex="55" wit="78" con="82" men="78">
<vitals hp="133921719" hpRegen="10.5" mp="47100" mpRegen="3.6" />
<stats str="164" int="188" dex="55" wit="78" con="111" men="149">
<vitals hp="209461939" hpRegen="10.5" mp="47100.0" mpRegen="3.6" />
<speed>
<walk ground="270" />
<walk ground="100" />
<run ground="270" />
</speed>
<attack physical="17349.336782171" magical="5807.1057427324" critical="4" attackSpeed="253" range="40" />
<defence physical="936.17021276596" magical="621.44512323573" />
<attack physical="63862.33880135" magical="11469.742130133" critical="4" attackSpeed="253" range="40" />
<defence physical="7772.0207253886" magical="3235.1068620499" />
<attribute>
<defence fire="20" water="20" wind="20" earth="20" holy="20" dark="20" />
<defence fire="300" water="300" wind="370" earth="250" holy="300" dark="300" />
<attack type="WIND" value="370" />
</attribute>
<abnormalResist physical="0" magical="0" />
</stats>
<status attackable="false" undying="false" />
<status attackable="false" />
<skill_list>
<skill id="15638" level="1" /> <!-- Lindvior -->
<skill id="4416" level="10" /> <!-- Dragons -->
<skill id="4415" level="1" /> <!-- Bare Hands -->
<skill id="4416" level="10"/> <!-- Dragons -->
<skill id="5464" level="1"/> <!-- Wind Attack -->
<skill id="4408" level="1"/> <!-- HP 1x -->
<skill id="4409" level="1"/> <!-- MP 1x -->
<skill id="4410" level="11"/> <!-- P. Atk. Modifiers. -->
<skill id="4411" level="11"/> <!-- M. Atk. Modifiers. -->
<skill id="4412" level="11"/> <!-- P. Def. Modifiers. -->
<skill id="4413" level="11"/> <!-- M. Def. Modifiers. -->
<skill id="4414" level="2"/> <!-- Heavy Armor Type -->
<skill id="4415" level="1"/> <!-- Bare Hands -->
<skill id="14765" level="4"/> <!-- Blood Siphon Resistance -->
<skill id="15638" level="1"/> <!-- Lindvior -->
<skill id="15274" level="1" /> <!-- Mighty Wind Strike -->
<skill id="15279" level="1" /> <!-- Soar -->
</skill_list>
<ai aggroRange="2000" isAggressive="true" />
<collision>
<radius normal="430" />
<height normal="500" />
@ -984,7 +1002,7 @@
</attribute>
<abnormalResist physical="0" magical="0" />
</stats>
<status attackable="false" undying="false" />
<status attackable="false" undying="false" showName="false" targetable="false" />
<skill_list>
<skill id="4416" level="2" /> <!-- Magic Creatures -->
<skill id="4415" level="1" /> <!-- Bare Hands -->
@ -2357,7 +2375,7 @@
<height normal="10" />
</collision>
</npc>
<npc id="19477" level="99" type="L2Monster" name="Generator">
<npc id="19477" level="99" type="FriendlyNpc" name="Generator">
<!-- AUTO GENERATED NPC TODO: FIX IT -->
<race>ETC</race>
<sex>FEMALE</sex>
@ -2373,7 +2391,10 @@
<defence fire="150" water="150" wind="150" earth="150" holy="150" dark="150" />
</attribute>
</stats>
<status attackable="false" />
<status attackable="false" showName="false" canMove="false" />
<skill_list>
<skill id="15605" level="1" /> <!-- Recharge -->
</skill_list>
<collision>
<radius normal="200" />
<height normal="160" />
@ -2401,7 +2422,7 @@
<height normal="21.2" />
</collision>
</npc>
<npc id="19479" level="99" type="L2Npc" name="Generator Guard">
<npc id="19479" level="99" type="FriendlyNpc" name="Generator Guard">
<!-- AUTO GENERATED NPC TODO: FIX IT -->
<race>ETC</race>
<sex>FEMALE</sex>
@ -2412,7 +2433,7 @@
<run ground="180" />
</speed>
<attack physical="1950.2231755595" magical="1331.5869440987" critical="4" attackSpeed="253" range="40" />
<defence physical="405.85106382979" magical="297.0297029703" />
<defence physical="4405.85106382979" magical="5297.0297029703" />
<attribute>
<defence fire="150" water="150" wind="150" earth="150" holy="150" dark="150" />
</attribute>

View File

@ -4791,7 +4791,7 @@
<height normal="54" />
</collision>
</npc>
<npc id="25895" level="99" type="L2Monster" name="Lyn Draco">
<npc id="25895" level="102" type="L2Monster" name="Lyn Draco">
<!-- AUTO GENERATED NPC TODO: FIX IT -->
<race>DRAGON</race>
<sex>FEMALE</sex>
@ -4801,8 +4801,8 @@
<walk ground="60" />
<run ground="120" />
</speed>
<attack physical="1" magical="1" critical="4" attackSpeed="253" range="0" type="FIST" distance="0" width="0" random="0" accuracy="4.75" />
<defence physical="1" magical="1" />
<attack physical="1949.95411856464" magical="1331.56588332443" critical="4" attackSpeed="253" range="40" type="SWORD" distance="80" width="120" random="5" accuracy="5" />
<defence physical="405.66735" magical="296.84976" />
<attribute>
<attack type="WIND" value="430" />
<defence fire="350" water="350" wind="350" earth="300" holy="350" dark="350" />
@ -4822,7 +4822,7 @@
<height normal="22" />
</collision>
</npc>
<npc id="25896" level="99" type="L2Monster" name="Lyn Draco">
<npc id="25896" level="102" type="L2Monster" name="Lyn Draco">
<!-- AUTO GENERATED NPC TODO: FIX IT -->
<race>DRAGON</race>
<sex>FEMALE</sex>
@ -4853,7 +4853,7 @@
<height normal="37" />
</collision>
</npc>
<npc id="25897" level="99" type="L2Monster" name="Lyn Draco">
<npc id="25897" level="102" type="L2Monster" name="Lyn Draco">
<!-- AUTO GENERATED NPC TODO: FIX IT -->
<race>DRAGON</race>
<sex>FEMALE</sex>
@ -4877,6 +4877,12 @@
<skill id="4416" level="10" /> <!-- Dragons -->
<skill id="4415" level="1" /> <!-- Bare Hands -->
<skill id="14765" level="4" /> <!-- Blood Siphon Resistance -->
<skill id="4408" level="1"/> <!-- HP 1x -->
<skill id="4409" level="1"/> <!-- MP 1x -->
<skill id="4410" level="11"/>
<skill id="4411" level="11"/>
<skill id="4412" level="11"/>
<skill id="4413" level="11"/>
</skill_list>
<ai clanHelpRange="300" aggroRange="300" />
<collision>
@ -4884,15 +4890,18 @@
<height normal="50" />
</collision>
</npc>
<npc id="25898" level="99" type="L2Npc" name="Cyclone">
<npc id="25898" level="99" type="L2Monster" name="Cyclone">
<!-- AUTO GENERATED NPC TODO: FIX IT -->
<parameters>
<param name="MoveAroundSocial" value="200" />
</parameters>
<race>DRAGON</race>
<sex>FEMALE</sex>
<stats str="88" int="79" dex="55" wit="78" con="82" men="78">
<vitals hp="8446" hpRegen="8.5" mp="2355" mpRegen="3" />
<speed>
<walk ground="60" />
<run ground="120" />
<walk ground="140" />
<run ground="200" />
</speed>
<attack physical="1949.95411856464" magical="1331.56588332443" critical="4" attackSpeed="253" range="40" type="SWORD" distance="80" width="120" random="5" accuracy="5" />
<defence physical="405.66735" magical="296.84976" />
@ -4910,29 +4919,29 @@
<skill id="15599" level="1" /> <!-- Cyclone -->
<skill id="14765" level="4" /> <!-- Blood Siphon Resistance -->
</skill_list>
<ai aggroRange="300" isAggressive="true" clanHelpRange="300" />
<ex_crt_effect>true</ex_crt_effect>
<ai aggroRange="600" isAggressive="true" clanHelpRange="300" />
<collision>
<radius normal="60" />
<height normal="50" />
</collision>
</npc>
<npc id="25899" level="99" type="L2Monster" name="Lindvior" title="Wind Dragon">
<!-- AUTO GENERATED NPC TODO: FIX IT -->
<npc id="25899" level="102" type="L2GrandBoss" name="Lindvior" title="Wind Dragon">
<race>DRAGON</race>
<sex>FEMALE</sex>
<stats str="88" int="79" dex="55" wit="78" con="82" men="78">
<vitals hp="322249137" hpRegen="8.5" mp="47100" mpRegen="3" />
<equipment rhand="15301" /> <!-- Transparent Pole (NPC) -->
<stats str="164" int="188" dex="55" wit="78" con="111" men="149">
<vitals hp="209461939" hpRegen="10.5" mp="47100.0" mpRegen="3.6" />
<speed>
<walk ground="100" />
<run ground="270" />
</speed>
<attack physical="1949.95411856464" magical="1331.56588332443" critical="4" attackSpeed="253" range="40" type="SWORD" distance="80" width="120" random="5" accuracy="5" />
<defence physical="1605.82654" magical="1423.83569" />
<attack physical="63862.33880135" magical="11469.742130133" critical="4" attackSpeed="253" range="40" />
<defence physical="7772.0207253886" magical="3235.1068620499" />
<attribute>
<attack type="WIND" value="430" />
<defence fire="350" water="350" wind="350" earth="300" holy="350" dark="350" />
<defence fire="300" water="300" wind="370" earth="250" holy="300" dark="300" />
<attack type="WIND" value="370" />
</attribute>
<abnormalResist physical="0" magical="0" />
</stats>
<status attackable="false" />
<skill_list>
@ -4941,11 +4950,16 @@
<skill id="5464" level="1" /> <!-- Wind Attack -->
<skill id="4415" level="1" /> <!-- Bare Hands -->
<skill id="14765" level="4" /> <!-- Blood Siphon Resistance -->
<skill id="15274" level="1" /> <!-- Mighty Wind Strike -->
<skill id="15591" level="1" /> <!-- Wind Pull -->
<skill id="15430" level="1" /> <!-- Lindvior's Jump -->
<skill id="15271" level="1" /> <!-- Body Slam -->
<skill id="15273" level="1" /> <!-- Tail Swipe -->
</skill_list>
<ai clanHelpRange="300" aggroRange="300" />
<collision>
<radius normal="350" />
<height normal="210" />
<radius normal="190" />
<height normal="390" />
</collision>
</npc>
</list>

View File

@ -2018,13 +2018,13 @@
<height normal="90" />
</collision>
</npc>
<npc id="29240" level="104" type="L2RaidBoss" name="Lindvior" title="Wind Dragon">
<!-- AUTO GENERATED NPC TODO: FIX IT -->
<npc id="29240" level="102" type="L2GrandBoss" name="Lindvior" title="Wind Dragon">
<race>DRAGON</race>
<sex>FEMALE</sex>
<equipment rhand="15301" /> <!-- Transparent Pole (NPC) -->
<acquire exp="202583506944" sp="293716117" raidPoints="1000" />
<stats str="164" int="188" dex="55" wit="78" con="111" men="149">
<vitals hp="209461939" hpRegen="10.5" mp="47100" mpRegen="3.6" />
<vitals hp="209461939" hpRegen="10.5" mp="47100.0" mpRegen="3.6" />
<speed>
<walk ground="100" />
<run ground="270" />
@ -2038,9 +2038,19 @@
</stats>
<status attackable="false" />
<skill_list>
<skill id="5464" level="1" /> <!-- Wind Attack -->
<skill id="15638" level="1" /> <!-- Lindvior -->
<skill id="4416" level="10" /> <!-- Dragons -->
<skill id="4415" level="1"/> <!-- Bare Hands -->
<skill id="4416" level="10"/> <!-- Dragons -->
<skill id="5464" level="1"/> <!-- Wind Attack -->
<skill id="14765" level="4"/> <!-- Blood Siphon Resistance -->
<skill id="15638" level="1"/> <!-- Lindvior -->
<skill id="15271" level="1"/> <!-- Body Slam -->
<skill id="15272" level="1"/> <!-- Wind Breath -->
<skill id="15273" level="1"/> <!-- Tail Swipe -->
<skill id="15274" level="1"/> <!-- Mighty Wind Strike -->
<skill id="15430" level="1"/> <!-- Lindvior's Jump -->
<skill id="15591" level="1"/> <!-- Wind Pull -->
<skill id="15275" level="1"/> <!-- Tornado -->
<skill id="15600" level="1"/> <!-- Lindvior's Attack -->
</skill_list>
<ai aggroRange="2000" isAggressive="true" />
<drop_lists>
@ -2135,7 +2145,7 @@
<height normal="210" />
</collision>
</npc>
<npc id="29241" level="99" type="L2Monster" name="Lyn Draco">
<npc id="29241" level="102" type="L2Monster" name="Lyn Draco" title="">
<!-- AUTO GENERATED NPC TODO: FIX IT -->
<race>DRAGON</race>
<sex>FEMALE</sex>

View File

@ -50,22 +50,37 @@
<castRange>1800</castRange>
</skill>
<skill id="15605" toLevel="1" name="Recharge Possible">
<!-- AUTO GENERATED SKILL -->
<!-- Recharge possible. -->
<icon>icon.skill0005</icon>
<abnormalTime>20</abnormalTime>
<operateType>A2</operateType>
<castRange>1000</castRange>
<affectRange>1000</affectRange>
<effectPoint>1</effectPoint>
<hitTime>25000</hitTime>
<hitTime>10000</hitTime> <!-- retail 25000 -->
<targetType>SELF</targetType>
<affectScope>RANGE</affectScope>
<affectObject>NOT_FRIEND</affectObject>
</skill>
<skill id="15606" toLevel="1" name="Recharge">
<!-- AUTO GENERATED SKILL -->
<!-- Recharge. -->
<icon>icon.skill1449</icon>
<icon>icon.skill14444</icon>
<operateType>A1</operateType>
<isDebuff>1</isDebuff>
<castRange>900</castRange>
<hitTime>10000</hitTime>
<effectPoint>-2</effectPoint>
<coolTime>200</coolTime>
<targetType>TARGET</targetType>
<affectScope>SINGLE</affectScope>
<conditions>
<condition name="OpTargetNpc">
<npcIds>
<item>19477</item> <!-- Generator -->
</npcIds>
</condition>
</conditions>
</skill>
<skill id="15607" toLevel="1" name="Depleted">
<!-- AUTO GENERATED SKILL -->

View File

@ -167,4 +167,18 @@
<node X="126188" Y="29775" />
<node X="127178" Y="3979" />
</zone>
<zone name="Lindvior Boss" id="12107" type="NoSummonFriendZone" shape="NPoly" minZ="-1600" maxZ="1400" >
<node X="47032" Y="-29208" />
<node X="47104" Y="-30224" />
<node X="46903" Y="-31227" />
<node X="45186" Y="-31724" />
<node X="41983" Y="-30329" />
<node X="40588" Y="-27021" />
<node X="42113" Y="-23755" />
<node X="45462" Y="-22424" />
<node X="48593" Y="-24010" />
<node X="49873" Y="-27337" />
<node X="49357" Y="-28620" />
<node X="47553" Y="-29161" />
</zone>
</list>

View File

@ -891,6 +891,13 @@ public final class Config
public static int KELBIM_SPAWN_INTERVAL;
public static int KELBIM_SPAWN_RANDOM;
// Lindvior
public static int LINDVIOR_SPAWN_INTERVAL;
public static int LINDVIOR_SPAWN_RANDOM;
public static int LINDVIOR_MIN_PLAYERS;
public static int LINDVIOR_MAX_PLAYERS;
public static int LINDVIOR_MIN_PLAYER_LVL;
// Anakim
public static int ANAKIM_MIN_PLAYERS;
public static int ANAKIM_MAX_PLAYERS;
@ -2223,6 +2230,11 @@ public final class Config
LILITH_SPAWN_RANDOM = GrandBossSettings.getInt("RandomOfLilithSpawn", 148);
LILITH_MIN_PLAYER_LVL = GrandBossSettings.getInt("LilithMinPlayerLvl", 85);
LILITH_MAX_PLAYER_LVL = GrandBossSettings.getInt("LilithMaxPlayerLvl", 89);
LINDVIOR_SPAWN_INTERVAL = GrandBossSettings.getInt("IntervalOfLindviorSpawn", 264);
LINDVIOR_SPAWN_RANDOM = GrandBossSettings.getInt("RandomOfLindviorSpawn", 72);
LINDVIOR_MIN_PLAYERS = GrandBossSettings.getInt("LindviorMinPlayers", 49);
LINDVIOR_MAX_PLAYERS = GrandBossSettings.getInt("LindviorMaxPlayers", 112);
LINDVIOR_MIN_PLAYER_LVL = GrandBossSettings.getInt("LindviorMinPlayerLvl", 99);
// Gracia Seeds
final PropertiesParser GraciaSeedsSettings = new PropertiesParser(GRACIASEEDS_CONFIG_FILE);

View File

@ -20,7 +20,6 @@ What is done
TODO
-Modify all skill levels/sublevels based on client
-Lindvior
-Trasken
-Kamaloka
-Provisional Clan Halls

View File

@ -17,8 +17,9 @@ INSERT IGNORE INTO `grandboss_data` (`boss_id`,`loc_x`,`loc_y`,`loc_z`,`heading`
(29006, 17726, 108915, -6480, 0, 622493.58388, 3793.536), -- Core
(29014, 55024, 17368, -5412, 10126, 622493.58388, 3793.536), -- Orfen
(29020, 116033, 17447, 10107, -25348, 4068372, 39960), -- Baium
(29028, -105200, -253104, -15264, 0, 62041918, 2248572), -- Valakas
(29068, 185708, 114298, -8221,32768, 62802301, 1998000), -- Antharas
(29028, -105200, -253104, -15264, 0, 62041918, 2248572), -- Valakas
(29240, 0, 0, 0, 0, 288282589, 47100), -- Lindvior
(29118, 0, 0, 0, 0, 4109288, 1220547), -- Beleth
(25286, 185080, -12613, -5499, 16550, 556345880, 86847), -- Anakim
(25283, 185062, -9605, -5499, 15640, 486021997, 79600), -- Lilith

View File

@ -145,3 +145,22 @@ LilithMinPlayerLvl = 85
# Maximum players Level for enter to Lilith. Retail: 89
LilithMaxPlayerLvl = 89
# ---------------------------------------------------------------------------
# Lindvior
# ---------------------------------------------------------------------------
# Interval time of Lindvior. Value is hour. Range 1-480. Retail: 264
IntervalOfLindviorSpawn = 264
# Random interval. Range 1-192. Retail: 72
RandomOfLindviorSpawn = 72
# Minimal count of players for enter to Lindvior. Retail: 49
LindviorMinPlayers = 49
# Maximum count of players for enter to Lindvior. Retail: 112
LindviorMaxPlayers = 112
# Minimum players Level for enter to Lindvior. Retail: 99
LindviorMinPlayerLvl = 99

View File

@ -2352,4 +2352,8 @@
<point X="-113715" Y="236304" Z="-3044" delay="1" run="true" />
<point X="-113670" Y="236689" Z="-3044" delay="0" run="true" />
</route>
<route name="Rune_Lionel" repeat="true" repeatStyle="cycle">
<point X="42630" Y="-48231" Z="-792" delay="0" run="true" />
<point X="45069" Y="-48034" Z="-792" delay="0" run="true" />
</route>
</routes>

View File

@ -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);

View File

@ -0,0 +1,3 @@
<html><head><body>Generator:<br>
The generator is now supplying power to the sealed structure.
</body></html>

View 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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View 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>

View 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();
}
}

View 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();
}
}

View 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();
}
}

View 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();
}
}

View 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();
}
}

View File

@ -1954,7 +1954,7 @@
<attack physical="689.07320120658" magical="470.63282486066" critical="4" attackSpeed="253" range="40" />
<defence physical="296.22641509434" magical="216.70091537456" />
</stats>
<status attackable="false" />
<status attackable="false" targetable="false" showName="false" />
<collision>
<radius normal="11" />
<height normal="25" />

View File

@ -825,58 +825,76 @@
<height normal="40" />
</collision>
</npc>
<npc id="19423" level="99" type="L2Npc" name="Lindvior" title="Wind Dragon">
<npc id="19423" level="104" type="L2GrandBoss" name="Lindvior" title="Wind Dragon">
<!-- AUTO GENERATED NPC TODO: FIX IT -->
<race>DRAGON</race>
<sex>FEMALE</sex>
<mpReward value="20" type="PER" ticks="10" affects="PARTY" />
<stats str="88" int="79" dex="55" wit="78" con="82" men="78">
<vitals hp="8446" hpRegen="10.5" mp="2355" mpRegen="3.6" />
<stats str="164" int="188" dex="55" wit="78" con="111" men="149">
<vitals hp="209461939" hpRegen="10.5" mp="47100.0" mpRegen="3.6" />
<speed>
<walk ground="100" />
<run ground="1" />
<run ground="270" />
</speed>
<attack physical="1518.8555746574" magical="695.44490591753" critical="4" attackSpeed="180" range="40" />
<defence physical="335.10638297872" magical="245.06705989748" />
<attack physical="63862.33880135" magical="11469.742130133" critical="4" attackSpeed="253" range="40" />
<defence physical="7772.0207253886" magical="3235.1068620499" />
<attribute>
<defence fire="20" water="20" wind="20" earth="20" holy="20" dark="20" />
<defence fire="300" water="300" wind="370" earth="250" holy="300" dark="300" />
<attack type="WIND" value="370" />
</attribute>
<abnormalResist physical="0" magical="0" />
</stats>
<status attackable="false" undying="false" />
<status attackable="false" />
<skill_list>
<skill id="4416" level="10" /> <!-- Dragons -->
<skill id="4415" level="1" /> <!-- Bare Hands -->
<skill id="4416" level="10"/> <!-- Dragons -->
<skill id="4408" level="1"/> <!-- HP 1x -->
<skill id="4409" level="1"/> <!-- MP 1x -->
<skill id="4410" level="11"/> <!-- P. Atk. Modifiers. -->
<skill id="4411" level="11"/> <!-- M. Atk. Modifiers. -->
<skill id="4412" level="11"/> <!-- P. Def. Modifiers. -->
<skill id="4413" level="11"/> <!-- M. Def. Modifiers. -->
<skill id="4414" level="2"/> <!-- Heavy Armor Type -->
<skill id="4415" level="1"/> <!-- Bare Hands -->
</skill_list>
<ai aggroRange="2000" isAggressive="true" />
<collision>
<radius normal="190" />
<height normal="1500" />
</collision>
</npc>
<npc id="19424" level="99" type="L2Monster" name="Lindvior" title="Wind Dragon">
<npc id="19424" level="104" type="L2GrandBoss" name="Lindvior" title="Wind Dragon">
<!-- AUTO GENERATED NPC TODO: FIX IT -->
<race>DRAGON</race>
<sex>FEMALE</sex>
<mpReward value="20" type="PER" ticks="10" affects="PARTY" />
<stats str="88" int="79" dex="55" wit="78" con="82" men="78">
<vitals hp="133921719" hpRegen="10.5" mp="47100" mpRegen="3.6" />
<stats str="164" int="188" dex="55" wit="78" con="111" men="149">
<vitals hp="209461939" hpRegen="10.5" mp="47100.0" mpRegen="3.6" />
<speed>
<walk ground="270" />
<walk ground="100" />
<run ground="270" />
</speed>
<attack physical="17349.336782171" magical="5807.1057427324" critical="4" attackSpeed="253" range="40" />
<defence physical="936.17021276596" magical="621.44512323573" />
<attack physical="63862.33880135" magical="11469.742130133" critical="4" attackSpeed="253" range="40" />
<defence physical="7772.0207253886" magical="3235.1068620499" />
<attribute>
<defence fire="20" water="20" wind="20" earth="20" holy="20" dark="20" />
<defence fire="300" water="300" wind="370" earth="250" holy="300" dark="300" />
<attack type="WIND" value="370" />
</attribute>
<abnormalResist physical="0" magical="0" />
</stats>
<status attackable="false" undying="false" />
<status attackable="false" />
<skill_list>
<skill id="15638" level="1" /> <!-- Lindvior -->
<skill id="4416" level="10" /> <!-- Dragons -->
<skill id="4415" level="1" /> <!-- Bare Hands -->
<skill id="4416" level="10"/> <!-- Dragons -->
<skill id="5464" level="1"/> <!-- Wind Attack -->
<skill id="4408" level="1"/> <!-- HP 1x -->
<skill id="4409" level="1"/> <!-- MP 1x -->
<skill id="4410" level="11"/> <!-- P. Atk. Modifiers. -->
<skill id="4411" level="11"/> <!-- M. Atk. Modifiers. -->
<skill id="4412" level="11"/> <!-- P. Def. Modifiers. -->
<skill id="4413" level="11"/> <!-- M. Def. Modifiers. -->
<skill id="4414" level="2"/> <!-- Heavy Armor Type -->
<skill id="4415" level="1"/> <!-- Bare Hands -->
<skill id="14765" level="4"/> <!-- Blood Siphon Resistance -->
<skill id="15638" level="1"/> <!-- Lindvior -->
<skill id="15274" level="1" /> <!-- Mighty Wind Strike -->
<skill id="15279" level="1" /> <!-- Soar -->
</skill_list>
<ai aggroRange="2000" isAggressive="true" />
<collision>
<radius normal="430" />
<height normal="500" />
@ -984,7 +1002,7 @@
</attribute>
<abnormalResist physical="0" magical="0" />
</stats>
<status attackable="false" undying="false" />
<status attackable="false" undying="false" showName="false" targetable="false" />
<skill_list>
<skill id="4416" level="2" /> <!-- Magic Creatures -->
<skill id="4415" level="1" /> <!-- Bare Hands -->
@ -2357,7 +2375,7 @@
<height normal="10" />
</collision>
</npc>
<npc id="19477" level="99" type="L2Monster" name="Generator" title="">
<npc id="19477" level="99" type="FriendlyNpc" name="Generator" title="">
<!-- AUTO GENERATED NPC TODO: FIX IT -->
<race>ETC</race>
<sex>FEMALE</sex>
@ -2373,7 +2391,10 @@
<defence fire="150" water="150" wind="150" earth="150" holy="150" dark="150" />
</attribute>
</stats>
<status attackable="false" />
<status attackable="false" showName="false" canMove="false" />
<skill_list>
<skill id="15605" level="1" /> <!-- Recharge -->
</skill_list>
<collision>
<radius normal="200" />
<height normal="160" />
@ -2401,7 +2422,7 @@
<height normal="21.2" />
</collision>
</npc>
<npc id="19479" level="99" type="L2Npc" name="Generator Guard" title="">
<npc id="19479" level="99" type="FriendlyNpc" name="Generator Guard" title="">
<!-- AUTO GENERATED NPC TODO: FIX IT -->
<race>ETC</race>
<sex>FEMALE</sex>
@ -2412,7 +2433,7 @@
<run ground="180" />
</speed>
<attack physical="1950.2231755595" magical="1331.5869440987" critical="4" attackSpeed="253" range="40" />
<defence physical="405.85106382979" magical="297.0297029703" />
<defence physical="4405.85106382979" magical="5297.0297029703" />
<attribute>
<defence fire="150" water="150" wind="150" earth="150" holy="150" dark="150" />
</attribute>

View File

@ -4800,7 +4800,7 @@
<height normal="54" />
</collision>
</npc>
<npc id="25895" level="99" type="L2Monster" name="Lyn Draco" title="">
<npc id="25895" level="104" type="L2Monster" name="Lyn Draco" title="">
<!-- AUTO GENERATED NPC TODO: FIX IT -->
<race>DRAGON</race>
<sex>FEMALE</sex>
@ -4810,8 +4810,8 @@
<walk ground="60" />
<run ground="120" />
</speed>
<attack physical="1" magical="1" critical="4" attackSpeed="253" range="0" type="FIST" distance="0" width="0" random="0" accuracy="4.75" />
<defence physical="1" magical="1" />
<attack physical="1949.95411856464" magical="1331.56588332443" critical="4" attackSpeed="253" range="40" type="SWORD" distance="80" width="120" random="5" accuracy="5" />
<defence physical="405.66735" magical="296.84976" />
<attribute>
<attack type="WIND" value="430" />
<defence fire="350" water="350" wind="350" earth="300" holy="350" dark="350" />
@ -4831,7 +4831,7 @@
<height normal="22" />
</collision>
</npc>
<npc id="25896" level="99" type="L2Monster" name="Lyn Draco" title="">
<npc id="25896" level="104" type="L2Monster" name="Lyn Draco" title="">
<!-- AUTO GENERATED NPC TODO: FIX IT -->
<race>DRAGON</race>
<sex>FEMALE</sex>
@ -4862,7 +4862,7 @@
<height normal="37" />
</collision>
</npc>
<npc id="25897" level="99" type="L2Monster" name="Lyn Draco" title="">
<npc id="25897" level="104" type="L2Monster" name="Lyn Draco" title="">
<!-- AUTO GENERATED NPC TODO: FIX IT -->
<race>DRAGON</race>
<sex>FEMALE</sex>
@ -4886,6 +4886,12 @@
<skill id="4416" level="10" /> <!-- Dragons -->
<skill id="4415" level="1" /> <!-- Bare Hands -->
<skill id="14765" level="4" /> <!-- Blood Siphon Resistance -->
<skill id="4408" level="1"/> <!-- HP 1x -->
<skill id="4409" level="1"/> <!-- MP 1x -->
<skill id="4410" level="11"/>
<skill id="4411" level="11"/>
<skill id="4412" level="11"/>
<skill id="4413" level="11"/>
</skill_list>
<ai clanHelpRange="300" aggroRange="300" />
<collision>
@ -4893,15 +4899,18 @@
<height normal="50" />
</collision>
</npc>
<npc id="25898" level="99" type="L2Npc" name="Cyclone" title="">
<npc id="25898" level="99" type="L2Monster" name="Cyclone" title="">
<!-- AUTO GENERATED NPC TODO: FIX IT -->
<parameters>
<param name="MoveAroundSocial" value="200" />
</parameters>
<race>DRAGON</race>
<sex>FEMALE</sex>
<stats str="88" int="79" dex="55" wit="78" con="82" men="78">
<vitals hp="8446" hpRegen="8.5" mp="2355" mpRegen="3" />
<speed>
<walk ground="60" />
<run ground="120" />
<walk ground="140" />
<run ground="200" />
</speed>
<attack physical="1949.95411856464" magical="1331.56588332443" critical="4" attackSpeed="253" range="40" type="SWORD" distance="80" width="120" random="5" accuracy="5" />
<defence physical="405.66735" magical="296.84976" />
@ -4919,29 +4928,29 @@
<skill id="15599" level="1" /> <!-- Cyclone -->
<skill id="14765" level="4" /> <!-- Blood Siphon Resistance -->
</skill_list>
<ai aggroRange="300" isAggressive="true" clanHelpRange="300" />
<ex_crt_effect>true</ex_crt_effect>
<ai aggroRange="600" isAggressive="true" clanHelpRange="300" />
<collision>
<radius normal="60" />
<height normal="50" />
</collision>
</npc>
<npc id="25899" level="99" type="L2Monster" name="Lindvior" title="Wind Dragon">
<!-- AUTO GENERATED NPC TODO: FIX IT -->
<npc id="25899" level="104" type="L2GrandBoss" name="Lindvior" title="Wind Dragon">
<race>DRAGON</race>
<sex>FEMALE</sex>
<stats str="88" int="79" dex="55" wit="78" con="82" men="78">
<vitals hp="322249137" hpRegen="8.5" mp="47100" mpRegen="3" />
<equipment rhand="15301" /> <!-- Transparent Pole (NPC) -->
<stats str="164" int="188" dex="55" wit="78" con="111" men="149">
<vitals hp="209461939" hpRegen="10.5" mp="47100.0" mpRegen="3.6" />
<speed>
<walk ground="100" />
<run ground="270" />
</speed>
<attack physical="1949.95411856464" magical="1331.56588332443" critical="4" attackSpeed="253" range="40" type="SWORD" distance="80" width="120" random="5" accuracy="5" />
<defence physical="1605.82654" magical="1423.83569" />
<attack physical="63862.33880135" magical="11469.742130133" critical="4" attackSpeed="253" range="40" />
<defence physical="7772.0207253886" magical="3235.1068620499" />
<attribute>
<attack type="WIND" value="430" />
<defence fire="350" water="350" wind="350" earth="300" holy="350" dark="350" />
<defence fire="300" water="300" wind="370" earth="250" holy="300" dark="300" />
<attack type="WIND" value="370" />
</attribute>
<abnormalResist physical="0" magical="0" />
</stats>
<status attackable="false" />
<skill_list>
@ -4950,11 +4959,16 @@
<skill id="5464" level="1" /> <!-- Wind Attack -->
<skill id="4415" level="1" /> <!-- Bare Hands -->
<skill id="14765" level="4" /> <!-- Blood Siphon Resistance -->
<skill id="15274" level="1" /> <!-- Mighty Wind Strike -->
<skill id="15591" level="1" /> <!-- Wind Pull -->
<skill id="15430" level="1" /> <!-- Lindvior's Jump -->
<skill id="15271" level="1" /> <!-- Body Slam -->
<skill id="15273" level="1" /> <!-- Tail Swipe -->
</skill_list>
<ai clanHelpRange="300" aggroRange="300" />
<collision>
<radius normal="350" />
<height normal="210" />
<radius normal="190" />
<height normal="390" />
</collision>
</npc>
</list>

View File

@ -2046,13 +2046,13 @@
<height normal="90" />
</collision>
</npc>
<npc id="29240" level="104" type="L2RaidBoss" name="Lindvior" title="Wind Dragon">
<!-- AUTO GENERATED NPC TODO: FIX IT -->
<npc id="29240" level="104" type="L2GrandBoss" name="Lindvior" title="Wind Dragon">
<race>DRAGON</race>
<sex>FEMALE</sex>
<equipment rhand="15301" /> <!-- Transparent Pole (NPC) -->
<acquire exp="202583506944" sp="293716117" raidPoints="1000" />
<stats str="164" int="188" dex="55" wit="78" con="111" men="149">
<vitals hp="209461939" hpRegen="10.5" mp="47100" mpRegen="3.6" />
<vitals hp="209461939" hpRegen="10.5" mp="47100.0" mpRegen="3.6" />
<speed>
<walk ground="100" />
<run ground="270" />
@ -2066,91 +2066,123 @@
</stats>
<status attackable="false" />
<skill_list>
<skill id="5464" level="1" /> <!-- Wind Attack -->
<skill id="15638" level="1" /> <!-- Lindvior -->
<skill id="4416" level="10" /> <!-- Dragons -->
<skill id="4415" level="1"/> <!-- Bare Hands -->
<skill id="4416" level="10"/> <!-- Dragons -->
<skill id="5464" level="1"/> <!-- Wind Attack -->
<skill id="14765" level="4"/> <!-- Blood Siphon Resistance -->
<skill id="15638" level="1"/> <!-- Lindvior -->
<skill id="15271" level="1"/> <!-- Body Slam -->
<skill id="15272" level="1"/> <!-- Wind Breath -->
<skill id="15273" level="1"/> <!-- Tail Swipe -->
<skill id="15274" level="1"/> <!-- Mighty Wind Strike -->
<skill id="15430" level="1"/> <!-- Lindvior's Jump -->
<skill id="15591" level="1"/> <!-- Wind Pull -->
<skill id="15275" level="1"/> <!-- Tornado -->
<skill id="15600" level="1"/> <!-- Lindvior's Attack -->
</skill_list>
<ai aggroRange="2000" isAggressive="true" />
<drop_lists>
<death>
<group chance="100">
<item id="17435" min="1" max="3" chance="13.943474249" /> <!-- Eternal Shield Heavy Armor -->
<item id="17420" min="1" max="3" chance="7.8261166740713" /> <!-- Amaranthine Fighter -->
<item id="17424" min="1" max="3" chance="7.8175728785756" /> <!-- Amaranthine Buster -->
<item id="17421" min="1" max="3" chance="7.8150097399269" /> <!-- Amaranthine Stormer -->
<item id="17416" min="1" max="3" chance="7.804757185332" /> <!-- Amaranthine Shaper -->
<item id="17417" min="1" max="3" chance="7.7851064556919" /> <!-- Amaranthine Cutter -->
<item id="17422" min="1" max="3" chance="7.7816889374936" /> <!-- Amaranthine Thrower -->
<item id="17419" min="1" max="3" chance="7.7791257988449" /> <!-- Amaranthine Avenger -->
<item id="17426" min="1" max="3" chance="7.7654557260517" /> <!-- Amaranthine Retributer -->
<item id="17418" min="1" max="3" chance="7.7611838283039" /> <!-- Amaranthine Slasher -->
<item id="17425" min="1" max="3" chance="7.7492225146099" /> <!-- Amaranthine Caster -->
<item id="17423" min="1" max="3" chance="7.7227367485732" /> <!-- Amaranthine Shooter -->
<item id="36435" min="1" max="1" chance="0.064078466217833" /> <!-- Lindvior Thrower Fragment -->
<item id="36436" min="1" max="1" chance="0.064078466217833" /> <!-- Lindvior Slasher Fragment -->
<item id="36437" min="1" max="1" chance="0.064078466217833" /> <!-- Lindvior Caster Fragment -->
<item id="36438" min="1" max="1" chance="0.064078466217833" /> <!-- Lindvior Cutter Fragment -->
<item id="36439" min="1" max="1" chance="0.064078466217833" /> <!-- Lindvior Shooter Fragment -->
<item id="36440" min="1" max="1" chance="0.064078466217833" /> <!-- Lindvior Dual Dagger Fragment -->
<item id="36434" min="1" max="1" chance="0.064078466217833" /> <!-- Lindvior Shaper Fragment -->
<item id="17435" min="1" max="3" chance="14.491582377011" /> <!-- Eternal Shield - Heavy Armor -->
<item id="17423" min="1" max="3" chance="7.7770499612934" /> <!-- Amaranthine Shooter -->
<item id="17422" min="1" max="3" chance="7.7761992667013" /> <!-- Amaranthine Thrower -->
<item id="17425" min="1" max="3" chance="7.7761992667013" /> <!-- Amaranthine Caster -->
<item id="17419" min="1" max="3" chance="7.7676923207799" /> <!-- Amaranthine Avenger -->
<item id="17426" min="1" max="3" chance="7.7413207884237" /> <!-- Amaranthine Retributer -->
<item id="17421" min="1" max="3" chance="7.7277096749496" /> <!-- Amaranthine Stormer -->
<item id="17416" min="1" max="3" chance="7.7149492560676" /> <!-- Amaranthine Shaper -->
<item id="17420" min="1" max="3" chance="7.7021888371856" /> <!-- Amaranthine Fighter -->
<item id="17424" min="1" max="3" chance="7.698786058817" /> <!-- Amaranthine Buster -->
<item id="17418" min="1" max="3" chance="7.6936818912642" /> <!-- Amaranthine Slasher -->
<item id="17417" min="1" max="3" chance="7.686025639935" /> <!-- Amaranthine Cutter -->
<item id="36434" min="1" max="1" chance="0.063802094410086" /> <!-- Lindvior Shaper - Fragment -->
<item id="36436" min="1" max="1" chance="0.063802094410086" /> <!-- Lindvior Slasher - Fragment -->
<item id="36437" min="1" max="1" chance="0.063802094410086" /> <!-- Lindvior Caster - Fragment -->
<item id="36438" min="1" max="1" chance="0.063802094410086" /> <!-- Lindvior Cutter - Fragment -->
<item id="36439" min="1" max="1" chance="0.063802094410086" /> <!-- Lindvior Shooter - Fragment -->
<item id="36440" min="1" max="1" chance="0.063802094410086" /> <!-- Lindvior Dual Dagger - Fragment -->
<item id="36435" min="1" max="1" chance="0.063802094410086" /> <!-- Lindvior Thrower - Fragment -->
</group>
<group chance="100">
<item id="17438" min="1" max="3" chance="19.418571831781" /> <!-- Eternal Leather Leggings Light Armor -->
<item id="17437" min="1" max="3" chance="18.882303132938" /> <!-- Eternal Leather Armor Light Armor -->
<item id="17431" min="1" max="3" chance="15.777589613322" /> <!-- Eternal Breastplate Heavy Armor -->
<item id="17432" min="1" max="3" chance="15.580016934801" /> <!-- Eternal Gaiters Heavy Armor -->
<item id="17442" min="1" max="3" chance="15.438893593" /> <!-- Eternal Tunic Robe -->
<item id="17443" min="1" max="3" chance="14.902624894157" /> <!-- Eternal Stockings Robe -->
<item id="17438" min="1" max="3" chance="19.488372093023" /> <!-- Eternal Leather Leggings - Light Armor -->
<item id="17437" min="1" max="3" chance="18.706976744186" /> <!-- Eternal Leather Armor - Light Armor -->
<item id="17431" min="1" max="3" chance="16" /> <!-- Eternal Breastplate - Heavy Armor -->
<item id="17442" min="1" max="3" chance="15.944186046512" /> <!-- Eternal Tunic - Robe -->
<item id="17432" min="1" max="3" chance="14.939534883721" /> <!-- Eternal Gaiters - Heavy Armor -->
<item id="17443" min="1" max="3" chance="14.920930232558" /> <!-- Eternal Stockings - Robe -->
</group>
<group chance="100">
<item id="17439" min="1" max="3" chance="11.346601914493" /> <!-- Eternal Leather Gloves Light Armor -->
<item id="17440" min="1" max="3" chance="11.324144513376" /> <!-- Eternal Leather Boots Light Armor -->
<item id="17436" min="1" max="3" chance="11.04342699941" /> <!-- Eternal Leather Helmet Light Armor -->
<item id="17434" min="1" max="3" chance="9.7408977346097" /> <!-- Eternal Boots Heavy Armor -->
<item id="17446" min="1" max="3" chance="9.7044044577941" /> <!-- Eternal Sigil Robe -->
<item id="17444" min="1" max="3" chance="9.5163237234371" /> <!-- Eternal Gloves Robe -->
<item id="17441" min="1" max="3" chance="9.5107093731578" /> <!-- Eternal Circlet Robe -->
<item id="17433" min="1" max="3" chance="9.3871936670129" /> <!-- Eternal Gauntlets Heavy Armor -->
<item id="17430" min="1" max="3" chance="9.2299918591921" /> <!-- Eternal Helmet Heavy Armor -->
<item id="17445" min="1" max="3" chance="9.1963057575162" /> <!-- Eternal Shoes Robe -->
<item id="17436" min="1" max="3" chance="11.580551322898" /> <!-- Eternal Leather Helmet - Light Armor -->
<item id="17440" min="1" max="3" chance="11.414323313478" /> <!-- Eternal Leather Boots - Light Armor -->
<item id="17439" min="1" max="3" chance="10.738329408505" /> <!-- Eternal Leather Gloves - Light Armor -->
<item id="17441" min="1" max="3" chance="9.6910929491619" /> <!-- Eternal Circlet - Robe -->
<item id="17445" min="1" max="3" chance="9.6855520155146" /> <!-- Eternal Shoes - Robe -->
<item id="17434" min="1" max="3" chance="9.6301426790414" /> <!-- Eternal Boots - Heavy Armor -->
<item id="17430" min="1" max="3" chance="9.5913561435102" /> <!-- Eternal Helmet - Heavy Armor -->
<item id="17446" min="1" max="3" chance="9.4611442027982" /> <!-- Eternal Sigil - Robe -->
<item id="17433" min="1" max="3" chance="9.3032275938496" /> <!-- Eternal Gauntlets - Heavy Armor -->
<item id="17444" min="1" max="3" chance="8.9042803712426" /> <!-- Eternal Gloves - Robe -->
</group>
<group chance="20.3">
<group chance="20.07">
<item id="36946" min="1" max="1" chance="100" /> <!-- Lindvior's Earring -->
</group>
<group chance="100">
<item id="36414" min="1" max="1" chance="12.140931937936" /> <!-- Dragon Claw -->
<item id="37772" min="1" max="1" chance="6.1578806789209" /> <!-- Scroll of Blessing: Weapon (R99-grade) -->
<item id="35568" min="1" max="1" chance="6.1263142558823" /> <!-- Bloody Amaranthine Enhancement Stone -->
<item id="37781" min="1" max="1" chance="6.0449700118981" /> <!-- Scroll of Blessing: Armor (R99-grade) -->
<item id="18562" min="1" max="1" chance="4.0951363426657" /> <!-- Purple Soul Crystal (R99-grade) -->
<item id="18561" min="1" max="1" chance="4.0927081562781" /> <!-- Teal Soul Crystal (R99-grade) -->
<item id="18560" min="1" max="1" chance="4.0259330306194" /> <!-- Yellow Soul Crystal (R99-grade) -->
<item id="36389" min="10" max="10" chance="3.734550664109" /> <!-- Giant's Scroll: Enchant Armor (R-grade) -->
<item id="19448" min="10" max="10" chance="3.6604909792876" /> <!-- Blessed Scroll: Enchant Armor (R-grade) -->
<item id="36162" min="1" max="1" chance="2.5022460724085" /> <!-- Scroll of Blessing (R99-grade) -->
<item id="19447" min="10" max="10" chance="2.4221159216181" /> <!-- Blessed Scroll: Enchant Weapon (R-grade) -->
<item id="36386" min="10" max="10" chance="2.3310589320836" /> <!-- Giant's Scroll: Enchant Weapon (R-grade) -->
<item id="17708" min="1" max="1" chance="2.1100939708132" /> <!-- Lv. 5 Ancient MEN Dye MEN + 5 / Holy Resistance + 25 -->
<item id="17713" min="1" max="1" chance="2.0979530388753" /> <!-- Lv. 5 Legendary WIT Dye WIT + 5 / MEN + 1 / Wind Resistance + 25 -->
<item id="17697" min="1" max="1" chance="2.0955248524877" /> <!-- Lv. 5 Giant STR Dye STR + 5 -->
<item id="17706" min="1" max="1" chance="2.0955248524877" /> <!-- Lv. 5 Ancient INT Dye INT + 5 / Water Resistance + 25 -->
<item id="17704" min="1" max="1" chance="2.0943107592939" /> <!-- Lv. 5 Ancient DEX Dye DEX + 5 / Earth Resistance + 25 -->
<item id="17701" min="1" max="1" chance="2.0845980137435" /> <!-- Lv. 5 Giant WIT Dye Wit + 5 -->
<item id="39483" min="1" max="1" chance="2.063958429449" /> <!-- Alchemic Tome: Enchant Scroll -->
<item id="17699" min="1" max="1" chance="2.063958429449" /> <!-- Lv. 5 Giant CON Dye CON + 5 -->
<item id="17714" min="1" max="1" chance="2.0603161498677" /> <!-- Lv. 5 Legendary MEN Dye MEN + 5 / INT + 1 / Holy Resistance + 25 -->
<item id="17710" min="1" max="1" chance="2.0603161498677" /> <!-- Lv. 5 Legendary DEX Dye DEX + 5 / CON + 1 / Earth Resistance + 25 -->
<item id="17703" min="1" max="1" chance="2.0481752179297" /> <!-- Lv. 5 Ancient STR Dye STR + 5 / Fire Resistance + 25 -->
<item id="17698" min="1" max="1" chance="2.0445329383483" /> <!-- Lv. 5 Giant DEX Dye DEX + 5 -->
<item id="39485" min="1" max="1" chance="2.0166087948911" /> <!-- Alchemic Tome: Dye -->
<item id="17711" min="1" max="1" chance="2.0081101425345" /> <!-- Lv. 5 Legendary CON Dye CON + 5 / STR + 1 / Dark Resistance + 25 -->
<item id="17712" min="1" max="1" chance="1.9850423718525" /> <!-- Lv. 5 Legendary INT Dye INT + 5 / WIT + 1 / Water Resistance + 25 -->
<item id="17707" min="1" max="1" chance="1.9753296263021" /> <!-- Lv. 5 Ancient WIT Dye WIT + 5 / Wind Resistance + 25 -->
<item id="17702" min="1" max="1" chance="1.9668309739456" /> <!-- Lv. 5 Giant MEN Dye Men + 5 -->
<item id="39484" min="1" max="1" chance="1.9631886943642" /> <!-- Alchemic Tome: Life Stone -->
<item id="17700" min="1" max="1" chance="1.9619746011704" /> <!-- Lv. 5 Giant INT Dye INT + 5 -->
<item id="17705" min="1" max="1" chance="1.9425491100697" /> <!-- Lv. 5 Ancient CON Dye CON + 5 / Dark Resistance + 25 -->
<item id="17709" min="1" max="1" chance="1.9267658985504" /> <!-- Lv. 5 Legendary STR Dye STR + 5 / DEX + 1 / Fire Resistance + 25 -->
<item id="36414" min="1" max="1" chance="9.2128877243799" /> <!-- Dragon Claw -->
<item id="37781" min="1" max="1" chance="4.7169985148825" /> <!-- Scroll of Blessing: Armor (R99-grade) -->
<item id="35568" min="1" max="1" chance="4.6156567499143" /> <!-- Bloody Amaranthine Enhancement Stone -->
<item id="37772" min="1" max="1" chance="4.4940466319525" /> <!-- Scroll of Blessing: Weapon (R99-grade) -->
<item id="36389" min="10" max="10" chance="2.8403332854263" /> <!-- Giant's Scroll: Enchant Armor (R-grade) -->
<item id="19448" min="10" max="10" chance="2.7979540018942" /> <!-- Blessed Scroll: Enchant Armor (R-grade) -->
<item id="46492" min="1" max="2" chance="2.1373899520561" /> <!-- Pantheon's Soul Crystal - Stage 4 -->
<item id="46493" min="1" max="1" chance="2.1162003102901" /> <!-- Pantheon's Soul Crystal - Stage 5 -->
<item id="46477" min="1" max="2" chance="2.1088300001106" /> <!-- Leona's Soul Crystal - Stage 4 -->
<item id="46478" min="1" max="1" chance="2.086719069572" /> <!-- Leona's Soul Crystal - Stage 5 -->
<item id="46508" min="1" max="1" chance="2.036048187088" /> <!-- Lionel's Soul Crystal - Stage 5 -->
<item id="46507" min="1" max="2" chance="2.0222288555014" /> <!-- Lionel's Soul Crystal - Stage 4 -->
<item id="36162" min="1" max="1" chance="1.9079890477191" /> <!-- Scroll of Blessing: (R99-grade) -->
<item id="46479" min="1" max="1" chance="1.819545325565" /> <!-- Leona's Soul Crystal - Stage 6 -->
<item id="46509" min="1" max="1" chance="1.8075685715233" /> <!-- Lionel's Soul Crystal - Stage 6 -->
<item id="36386" min="10" max="10" chance="1.8149388817028" /> <!-- Giant's Scroll: Enchant Weapon (R-grade) -->
<item id="46494" min="1" max="1" chance="1.8066472827509" /> <!-- Pantheon's Soul Crystal - Stage 6 -->
<item id="19447" min="10" max="10" chance="1.8029621276611" /> <!-- Blessed Scroll: Enchant Weapon (R-grade) -->
<item id="17708" min="1" max="1" chance="1.6122553517665" /> <!-- Lv. 5 Ancient MEN Dye - MEN + 5 / Holy Resistance + 25 -->
<item id="39484" min="1" max="1" chance="1.6021211752697" /> <!-- Alchemic Tome: Life Stone -->
<item id="17714" min="1" max="1" chance="1.5892231324555" /> <!-- Lv. 5 Legendary MEN Dye - MEN + 5 / INT + 1 / Holy Resistance + 25 -->
<item id="17703" min="1" max="1" chance="1.5643483355997" /> <!-- Lv. 5 Ancient STR Dye - STR + 5 / Fire Resistance + 25 -->
<item id="17709" min="1" max="1" chance="1.5615844692824" /> <!-- Lv. 5 Legendary STR Dye - STR + 5 / DEX + 1 / Fire Resistance + 25 -->
<item id="17706" min="1" max="1" chance="1.5542141591029" /> <!-- Lv. 5 Ancient INT Dye - INT + 5 / Water Resistance + 25 -->
<item id="17702" min="1" max="1" chance="1.5477651376958" /> <!-- Lv. 5 Giant MEN Dye - Men + 5 -->
<item id="39485" min="1" max="1" chance="1.5413161162888" /> <!-- Alchemic Tome: Dye -->
<item id="39483" min="1" max="1" chance="1.5367096724266" /> <!-- Alchemic Tome: Enchant Scroll -->
<item id="17711" min="1" max="1" chance="1.5367096724266" /> <!-- Lv. 5 Legendary CON Dye - CON + 5 / STR + 1 / Dark Resistance + 25 -->
<item id="17697" min="1" max="1" chance="1.5357883836541" /> <!-- Lv. 5 Giant STR Dye - STR + 5 -->
<item id="17712" min="1" max="1" chance="1.5357883836541" /> <!-- Lv. 5 Legendary INT Dye - INT + 5 / WIT + 1 / Water Resistance + 25 -->
<item id="17713" min="1" max="1" chance="1.5265754959297" /> <!-- Lv. 5 Legendary WIT Dye - WIT + 5 / MEN + 1 / Wind Resistance + 25 -->
<item id="17705" min="1" max="1" chance="1.5072284317085" /> <!-- Lv. 5 Ancient CON Dye - CON + 5 / Dark Resistance + 25 -->
<item id="46463" min="1" max="1" chance="1.4952516776669" /> <!-- Mermoden's Soul Crystal - Stage 5 -->
<item id="17707" min="1" max="1" chance="1.5026219878464" /> <!-- Lv. 5 Ancient WIT Dye - WIT + 5 / Wind Resistance + 25 -->
<item id="17699" min="1" max="1" chance="1.4980155439842" /> <!-- Lv. 5 Giant CON Dye - CON + 5 -->
<item id="17704" min="1" max="1" chance="1.4924878113495" /> <!-- Lv. 5 Ancient DEX Dye - DEX + 5 / Earth Resistance + 25 -->
<item id="17701" min="1" max="1" chance="1.4860387899425" /> <!-- Lv. 5 Giant WIT Dye - Wit + 5 -->
<item id="17698" min="1" max="1" chance="1.4759046134457" /> <!-- Lv. 5 Giant DEX Dye - DEX + 5 -->
<item id="46462" min="1" max="2" chance="1.4593214155418" /> <!-- Mermoden's Soul Crystal - Stage 4 -->
<item id="17700" min="1" max="1" chance="1.4685343032662" /> <!-- Lv. 5 Giant INT Dye - INT + 5 -->
<item id="17710" min="1" max="1" chance="1.4620852818591" /> <!-- Lv. 5 Legendary DEX Dye - DEX + 5 / CON + 1 / Earth Resistance + 25 -->
<item id="46448" min="1" max="1" chance="1.4215485758718" /> <!-- Kain's Soul Crystal - Stage 5 -->
<item id="46447" min="1" max="2" chance="1.3874608912916" /> <!-- Kain's Soul Crystal - Stage 4 -->
<item id="46449" min="1" max="1" chance="1.1728006073136" /> <!-- Kain's Soul Crystal - Stage 6 -->
<item id="46464" min="1" max="1" chance="1.1645090083616" /> <!-- Mermoden's Soul Crystal - Stage 6 -->
<item id="46495" min="1" max="1" chance="1.0677736872556" /> <!-- Pantheon's Soul Crystal - Stage 7 -->
<item id="46510" min="1" max="1" chance="1.032764713903" /> <!-- Lionel's Soul Crystal - Stage 7 -->
<item id="46480" min="1" max="1" chance="1.0189453823164" /> <!-- Leona's Soul Crystal - Stage 7 -->
<item id="46450" min="1" max="1" chance="0.71989504678304" /> <!-- Kain's Soul Crystal - Stage 7 -->
<item id="46465" min="1" max="1" chance="0.71630202057054" /> <!-- Mermoden's Soul Crystal - Stage 7 -->
<item id="46511" min="1" max="1" chance="0.71187983446283" /> <!-- Lionel's Soul Crystal - Stage 8 -->
<item id="46481" min="1" max="1" chance="0.70708913284616" /> <!-- Leona's Soul Crystal - Stage 8 -->
<item id="46496" min="1" max="1" chance="0.70220630235223" /> <!-- Pantheon's Soul Crystal - Stage 8 -->
<item id="46451" min="1" max="1" chance="0.47041004720684" /> <!-- Kain's Soul Crystal - Stage 8 -->
<item id="46466" min="1" max="1" chance="0.46958088731164" /> <!-- Mermoden's Soul Crystal - Stage 8 -->
</group>
</death>
<lucky_corpse>
@ -2163,7 +2195,7 @@
<height normal="210" />
</collision>
</npc>
<npc id="29241" level="99" type="L2Monster" name="Lyn Draco" title="">
<npc id="29241" level="104" type="L2Monster" name="Lyn Draco" title="">
<!-- AUTO GENERATED NPC TODO: FIX IT -->
<race>DRAGON</race>
<sex>FEMALE</sex>

View File

@ -50,22 +50,37 @@
<castRange>1800</castRange>
</skill>
<skill id="15605" toLevel="1" name="Recharge Possible">
<!-- AUTO GENERATED SKILL -->
<!-- Recharge possible. -->
<icon>icon.skill0005</icon>
<abnormalTime>20</abnormalTime>
<operateType>A2</operateType>
<castRange>1000</castRange>
<affectRange>1000</affectRange>
<effectPoint>1</effectPoint>
<hitTime>25000</hitTime>
<hitTime>10000</hitTime> <!-- retail 25000 -->
<targetType>SELF</targetType>
<affectScope>RANGE</affectScope>
<affectObject>NOT_FRIEND</affectObject>
</skill>
<skill id="15606" toLevel="1" name="Recharge">
<!-- AUTO GENERATED SKILL -->
<!-- Recharge. -->
<icon>icon.skill1449</icon>
<icon>icon.skill14444</icon>
<operateType>A1</operateType>
<isDebuff>1</isDebuff>
<castRange>900</castRange>
<hitTime>10000</hitTime>
<effectPoint>-2</effectPoint>
<coolTime>200</coolTime>
<targetType>TARGET</targetType>
<affectScope>SINGLE</affectScope>
<conditions>
<condition name="OpTargetNpc">
<npcIds>
<item>19477</item> <!-- Generator -->
</npcIds>
</condition>
</conditions>
</skill>
<skill id="15607" toLevel="1" name="Depleted">
<!-- AUTO GENERATED SKILL -->

View File

@ -167,4 +167,18 @@
<node X="126188" Y="29775" />
<node X="127178" Y="3979" />
</zone>
<zone name="Lindvior Boss" id="12107" type="NoSummonFriendZone" shape="NPoly" minZ="-1600" maxZ="1400" >
<node X="47032" Y="-29208" />
<node X="47104" Y="-30224" />
<node X="46903" Y="-31227" />
<node X="45186" Y="-31724" />
<node X="41983" Y="-30329" />
<node X="40588" Y="-27021" />
<node X="42113" Y="-23755" />
<node X="45462" Y="-22424" />
<node X="48593" Y="-24010" />
<node X="49873" Y="-27337" />
<node X="49357" Y="-28620" />
<node X="47553" Y="-29161" />
</zone>
</list>

View File

@ -893,6 +893,13 @@ public final class Config
public static int KELBIM_SPAWN_INTERVAL;
public static int KELBIM_SPAWN_RANDOM;
// Lindvior
public static int LINDVIOR_SPAWN_INTERVAL;
public static int LINDVIOR_SPAWN_RANDOM;
public static int LINDVIOR_MIN_PLAYERS;
public static int LINDVIOR_MAX_PLAYERS;
public static int LINDVIOR_MIN_PLAYER_LVL;
// Anakim
public static int ANAKIM_MIN_PLAYERS;
public static int ANAKIM_MAX_PLAYERS;
@ -2227,6 +2234,11 @@ public final class Config
LILITH_SPAWN_RANDOM = GrandBossSettings.getInt("RandomOfLilithSpawn", 148);
LILITH_MIN_PLAYER_LVL = GrandBossSettings.getInt("LilithMinPlayerLvl", 85);
LILITH_MAX_PLAYER_LVL = GrandBossSettings.getInt("LilithMaxPlayerLvl", 89);
LINDVIOR_SPAWN_INTERVAL = GrandBossSettings.getInt("IntervalOfLindviorSpawn", 264);
LINDVIOR_SPAWN_RANDOM = GrandBossSettings.getInt("RandomOfLindviorSpawn", 72);
LINDVIOR_MIN_PLAYERS = GrandBossSettings.getInt("LindviorMinPlayers", 49);
LINDVIOR_MAX_PLAYERS = GrandBossSettings.getInt("LindviorMaxPlayers", 112);
LINDVIOR_MIN_PLAYER_LVL = GrandBossSettings.getInt("LindviorMinPlayerLvl", 99);
// Gracia Seeds
final PropertiesParser GraciaSeedsSettings = new PropertiesParser(GRACIASEEDS_CONFIG_FILE);

View File

@ -19,7 +19,6 @@ What is done
-Addition of many retail AIs
TODO list
-Lindvior
-Trasken
-Underground five man dungeons
-Kamaloka

View File

@ -17,8 +17,9 @@ INSERT IGNORE INTO `grandboss_data` (`boss_id`,`loc_x`,`loc_y`,`loc_z`,`heading`
(29006, 17726, 108915, -6480, 0, 622493.58388, 3793.536), -- Core
(29014, 55024, 17368, -5412, 10126, 622493.58388, 3793.536), -- Orfen
(29020, 116033, 17447, 10107, -25348, 4068372, 39960), -- Baium
(29028, -105200, -253104, -15264, 0, 62041918, 2248572), -- Valakas
(29068, 185708, 114298, -8221,32768, 62802301, 1998000), -- Antharas
(29028, -105200, -253104, -15264, 0, 62041918, 2248572), -- Valakas
(29240, 0, 0, 0, 0, 288282589, 47100), -- Lindvior
(29118, 0, 0, 0, 0, 4109288, 1220547), -- Beleth
(25286, 185080, -12613, -5499, 16550, 556345880, 86847), -- Anakim
(25283, 185062, -9605, -5499, 15640, 486021997, 79600), -- Lilith

View File

@ -145,3 +145,22 @@ LilithMinPlayerLvl = 85
# Maximum players Level for enter to Lilith. Retail: 89
LilithMaxPlayerLvl = 89
# ---------------------------------------------------------------------------
# Lindvior
# ---------------------------------------------------------------------------
# Interval time of Lindvior. Value is hour. Range 1-480. Retail: 264
IntervalOfLindviorSpawn = 264
# Random interval. Range 1-192. Retail: 72
RandomOfLindviorSpawn = 72
# Minimal count of players for enter to Lindvior. Retail: 49
LindviorMinPlayers = 49
# Maximum count of players for enter to Lindvior. Retail: 112
LindviorMaxPlayers = 112
# Minimum players Level for enter to Lindvior. Retail: 99
LindviorMinPlayerLvl = 99

View File

@ -2352,4 +2352,8 @@
<point X="-113715" Y="236304" Z="-3044" delay="1" run="true" />
<point X="-113670" Y="236689" Z="-3044" delay="0" run="true" />
</route>
<route name="Rune_Lionel" repeat="true" repeatStyle="cycle">
<point X="42630" Y="-48231" Z="-792" delay="0" run="true" />
<point X="45069" Y="-48034" Z="-792" delay="0" run="true" />
</route>
</routes>

View File

@ -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);

View File

@ -0,0 +1,3 @@
<html><head><body>Generator:<br>
The generator is now supplying power to the sealed structure.
</body></html>

View 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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View 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>

View 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();
}
}

View 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();
}
}

View 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();
}
}

View 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();
}
}

View 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();
}
}

View File

@ -1954,7 +1954,7 @@
<attack physical="689.07320120658" magical="470.63282486066" critical="4" attackSpeed="253" range="40" />
<defence physical="296.22641509434" magical="216.70091537456" />
</stats>
<status attackable="false" />
<status attackable="false" targetable="false" showName="false" />
<collision>
<radius normal="11" />
<height normal="25" />

View File

@ -825,58 +825,76 @@
<height normal="40" />
</collision>
</npc>
<npc id="19423" level="99" type="L2Npc" name="Lindvior" title="Wind Dragon">
<npc id="19423" level="104" type="L2GrandBoss" name="Lindvior" title="Wind Dragon">
<!-- AUTO GENERATED NPC TODO: FIX IT -->
<race>DRAGON</race>
<sex>FEMALE</sex>
<mpReward value="20" type="PER" ticks="10" affects="PARTY" />
<stats str="88" int="79" dex="55" wit="78" con="82" men="78">
<vitals hp="8446" hpRegen="10.5" mp="2355" mpRegen="3.6" />
<stats str="164" int="188" dex="55" wit="78" con="111" men="149">
<vitals hp="209461939" hpRegen="10.5" mp="47100.0" mpRegen="3.6" />
<speed>
<walk ground="100" />
<run ground="1" />
<run ground="270" />
</speed>
<attack physical="1518.8555746574" magical="695.44490591753" critical="4" attackSpeed="180" range="40" />
<defence physical="335.10638297872" magical="245.06705989748" />
<attack physical="63862.33880135" magical="11469.742130133" critical="4" attackSpeed="253" range="40" />
<defence physical="7772.0207253886" magical="3235.1068620499" />
<attribute>
<defence fire="20" water="20" wind="20" earth="20" holy="20" dark="20" />
<defence fire="300" water="300" wind="370" earth="250" holy="300" dark="300" />
<attack type="WIND" value="370" />
</attribute>
<abnormalResist physical="0" magical="0" />
</stats>
<status attackable="false" undying="false" />
<status attackable="false" />
<skill_list>
<skill id="4416" level="10" /> <!-- Dragons -->
<skill id="4415" level="1" /> <!-- Bare Hands -->
<skill id="4416" level="10"/> <!-- Dragons -->
<skill id="4408" level="1"/> <!-- HP 1x -->
<skill id="4409" level="1"/> <!-- MP 1x -->
<skill id="4410" level="11"/> <!-- P. Atk. Modifiers. -->
<skill id="4411" level="11"/> <!-- M. Atk. Modifiers. -->
<skill id="4412" level="11"/> <!-- P. Def. Modifiers. -->
<skill id="4413" level="11"/> <!-- M. Def. Modifiers. -->
<skill id="4414" level="2"/> <!-- Heavy Armor Type -->
<skill id="4415" level="1"/> <!-- Bare Hands -->
</skill_list>
<ai aggroRange="2000" isAggressive="true" />
<collision>
<radius normal="190" />
<height normal="1500" />
</collision>
</npc>
<npc id="19424" level="99" type="L2Monster" name="Lindvior" title="Wind Dragon">
<npc id="19424" level="104" type="L2GrandBoss" name="Lindvior" title="Wind Dragon">
<!-- AUTO GENERATED NPC TODO: FIX IT -->
<race>DRAGON</race>
<sex>FEMALE</sex>
<mpReward value="20" type="PER" ticks="10" affects="PARTY" />
<stats str="88" int="79" dex="55" wit="78" con="82" men="78">
<vitals hp="133921719" hpRegen="10.5" mp="47100" mpRegen="3.6" />
<stats str="164" int="188" dex="55" wit="78" con="111" men="149">
<vitals hp="209461939" hpRegen="10.5" mp="47100.0" mpRegen="3.6" />
<speed>
<walk ground="270" />
<walk ground="100" />
<run ground="270" />
</speed>
<attack physical="17349.336782171" magical="5807.1057427324" critical="4" attackSpeed="253" range="40" />
<defence physical="936.17021276596" magical="621.44512323573" />
<attack physical="63862.33880135" magical="11469.742130133" critical="4" attackSpeed="253" range="40" />
<defence physical="7772.0207253886" magical="3235.1068620499" />
<attribute>
<defence fire="20" water="20" wind="20" earth="20" holy="20" dark="20" />
<defence fire="300" water="300" wind="370" earth="250" holy="300" dark="300" />
<attack type="WIND" value="370" />
</attribute>
<abnormalResist physical="0" magical="0" />
</stats>
<status attackable="false" undying="false" />
<status attackable="false" />
<skill_list>
<skill id="15638" level="1" /> <!-- Lindvior -->
<skill id="4416" level="10" /> <!-- Dragons -->
<skill id="4415" level="1" /> <!-- Bare Hands -->
<skill id="4416" level="10"/> <!-- Dragons -->
<skill id="5464" level="1"/> <!-- Wind Attack -->
<skill id="4408" level="1"/> <!-- HP 1x -->
<skill id="4409" level="1"/> <!-- MP 1x -->
<skill id="4410" level="11"/> <!-- P. Atk. Modifiers. -->
<skill id="4411" level="11"/> <!-- M. Atk. Modifiers. -->
<skill id="4412" level="11"/> <!-- P. Def. Modifiers. -->
<skill id="4413" level="11"/> <!-- M. Def. Modifiers. -->
<skill id="4414" level="2"/> <!-- Heavy Armor Type -->
<skill id="4415" level="1"/> <!-- Bare Hands -->
<skill id="14765" level="4"/> <!-- Blood Siphon Resistance -->
<skill id="15638" level="1"/> <!-- Lindvior -->
<skill id="15274" level="1" /> <!-- Mighty Wind Strike -->
<skill id="15279" level="1" /> <!-- Soar -->
</skill_list>
<ai aggroRange="2000" isAggressive="true" />
<collision>
<radius normal="430" />
<height normal="500" />
@ -984,7 +1002,7 @@
</attribute>
<abnormalResist physical="0" magical="0" />
</stats>
<status attackable="false" undying="false" />
<status attackable="false" undying="false" showName="false" targetable="false" />
<skill_list>
<skill id="4416" level="2" /> <!-- Magic Creatures -->
<skill id="4415" level="1" /> <!-- Bare Hands -->
@ -2307,7 +2325,7 @@
<height normal="10" />
</collision>
</npc>
<npc id="19477" level="99" type="L2Monster" name="Generator" title="">
<npc id="19477" level="99" type="FriendlyNpc" name="Generator" title="">
<!-- AUTO GENERATED NPC TODO: FIX IT -->
<race>ETC</race>
<sex>FEMALE</sex>
@ -2323,7 +2341,10 @@
<defence fire="150" water="150" wind="150" earth="150" holy="150" dark="150" />
</attribute>
</stats>
<status attackable="false" />
<status attackable="false" showName="false" canMove="false" />
<skill_list>
<skill id="15605" level="1" /> <!-- Recharge -->
</skill_list>
<collision>
<radius normal="200" />
<height normal="160" />
@ -2351,7 +2372,7 @@
<height normal="21.2" />
</collision>
</npc>
<npc id="19479" level="99" type="L2Npc" name="Generator Guard" title="">
<npc id="19479" level="99" type="FriendlyNpc" name="Generator Guard" title="">
<!-- AUTO GENERATED NPC TODO: FIX IT -->
<race>ETC</race>
<sex>FEMALE</sex>
@ -2362,7 +2383,7 @@
<run ground="180" />
</speed>
<attack physical="1950.2231755595" magical="1331.5869440987" critical="4" attackSpeed="253" range="40" />
<defence physical="405.85106382979" magical="297.0297029703" />
<defence physical="4405.85106382979" magical="5297.0297029703" />
<attribute>
<defence fire="150" water="150" wind="150" earth="150" holy="150" dark="150" />
</attribute>

View File

@ -4800,7 +4800,7 @@
<height normal="54" />
</collision>
</npc>
<npc id="25895" level="99" type="L2Monster" name="Lyn Draco" title="">
<npc id="25895" level="104" type="L2Monster" name="Lyn Draco" title="">
<!-- AUTO GENERATED NPC TODO: FIX IT -->
<race>DRAGON</race>
<sex>FEMALE</sex>
@ -4810,8 +4810,8 @@
<walk ground="60" />
<run ground="120" />
</speed>
<attack physical="1" magical="1" critical="4" attackSpeed="253" range="0" type="FIST" distance="0" width="0" random="0" accuracy="4.75" />
<defence physical="1" magical="1" />
<attack physical="1949.95411856464" magical="1331.56588332443" critical="4" attackSpeed="253" range="40" type="SWORD" distance="80" width="120" random="5" accuracy="5" />
<defence physical="405.66735" magical="296.84976" />
<attribute>
<attack type="WIND" value="430" />
<defence fire="350" water="350" wind="350" earth="300" holy="350" dark="350" />
@ -4831,7 +4831,7 @@
<height normal="22" />
</collision>
</npc>
<npc id="25896" level="99" type="L2Monster" name="Lyn Draco" title="">
<npc id="25896" level="104" type="L2Monster" name="Lyn Draco" title="">
<!-- AUTO GENERATED NPC TODO: FIX IT -->
<race>DRAGON</race>
<sex>FEMALE</sex>
@ -4862,7 +4862,7 @@
<height normal="37" />
</collision>
</npc>
<npc id="25897" level="99" type="L2Monster" name="Lyn Draco" title="">
<npc id="25897" level="104" type="L2Monster" name="Lyn Draco" title="">
<!-- AUTO GENERATED NPC TODO: FIX IT -->
<race>DRAGON</race>
<sex>FEMALE</sex>
@ -4886,6 +4886,12 @@
<skill id="4416" level="10" /> <!-- Dragons -->
<skill id="4415" level="1" /> <!-- Bare Hands -->
<skill id="14765" level="4" /> <!-- Blood Siphon Resistance -->
<skill id="4408" level="1"/> <!-- HP 1x -->
<skill id="4409" level="1"/> <!-- MP 1x -->
<skill id="4410" level="11"/>
<skill id="4411" level="11"/>
<skill id="4412" level="11"/>
<skill id="4413" level="11"/>
</skill_list>
<ai clanHelpRange="300" aggroRange="300" />
<collision>
@ -4893,15 +4899,18 @@
<height normal="50" />
</collision>
</npc>
<npc id="25898" level="99" type="L2Npc" name="Cyclone" title="">
<npc id="25898" level="99" type="L2Monster" name="Cyclone" title="">
<!-- AUTO GENERATED NPC TODO: FIX IT -->
<parameters>
<param name="MoveAroundSocial" value="200" />
</parameters>
<race>DRAGON</race>
<sex>FEMALE</sex>
<stats str="88" int="79" dex="55" wit="78" con="82" men="78">
<vitals hp="8446" hpRegen="8.5" mp="2355" mpRegen="3" />
<speed>
<walk ground="60" />
<run ground="120" />
<walk ground="140" />
<run ground="200" />
</speed>
<attack physical="1949.95411856464" magical="1331.56588332443" critical="4" attackSpeed="253" range="40" type="SWORD" distance="80" width="120" random="5" accuracy="5" />
<defence physical="405.66735" magical="296.84976" />
@ -4919,29 +4928,29 @@
<skill id="15599" level="1" /> <!-- Cyclone -->
<skill id="14765" level="4" /> <!-- Blood Siphon Resistance -->
</skill_list>
<ai aggroRange="300" isAggressive="true" clanHelpRange="300" />
<ex_crt_effect>true</ex_crt_effect>
<ai aggroRange="600" isAggressive="true" clanHelpRange="300" />
<collision>
<radius normal="60" />
<height normal="50" />
</collision>
</npc>
<npc id="25899" level="99" type="L2Monster" name="Lindvior" title="Wind Dragon">
<!-- AUTO GENERATED NPC TODO: FIX IT -->
<npc id="25899" level="104" type="L2GrandBoss" name="Lindvior" title="Wind Dragon">
<race>DRAGON</race>
<sex>FEMALE</sex>
<stats str="88" int="79" dex="55" wit="78" con="82" men="78">
<vitals hp="322249137" hpRegen="8.5" mp="47100" mpRegen="3" />
<equipment rhand="15301" /> <!-- Transparent Pole (NPC) -->
<stats str="164" int="188" dex="55" wit="78" con="111" men="149">
<vitals hp="209461939" hpRegen="10.5" mp="47100.0" mpRegen="3.6" />
<speed>
<walk ground="100" />
<run ground="270" />
</speed>
<attack physical="1949.95411856464" magical="1331.56588332443" critical="4" attackSpeed="253" range="40" type="SWORD" distance="80" width="120" random="5" accuracy="5" />
<defence physical="1605.82654" magical="1423.83569" />
<attack physical="63862.33880135" magical="11469.742130133" critical="4" attackSpeed="253" range="40" />
<defence physical="7772.0207253886" magical="3235.1068620499" />
<attribute>
<attack type="WIND" value="430" />
<defence fire="350" water="350" wind="350" earth="300" holy="350" dark="350" />
<defence fire="300" water="300" wind="370" earth="250" holy="300" dark="300" />
<attack type="WIND" value="370" />
</attribute>
<abnormalResist physical="0" magical="0" />
</stats>
<status attackable="false" />
<skill_list>
@ -4950,11 +4959,16 @@
<skill id="5464" level="1" /> <!-- Wind Attack -->
<skill id="4415" level="1" /> <!-- Bare Hands -->
<skill id="14765" level="4" /> <!-- Blood Siphon Resistance -->
<skill id="15274" level="1" /> <!-- Mighty Wind Strike -->
<skill id="15591" level="1" /> <!-- Wind Pull -->
<skill id="15430" level="1" /> <!-- Lindvior's Jump -->
<skill id="15271" level="1" /> <!-- Body Slam -->
<skill id="15273" level="1" /> <!-- Tail Swipe -->
</skill_list>
<ai clanHelpRange="300" aggroRange="300" />
<collision>
<radius normal="350" />
<height normal="210" />
<radius normal="190" />
<height normal="390" />
</collision>
</npc>
</list>

View File

@ -2046,13 +2046,13 @@
<height normal="90" />
</collision>
</npc>
<npc id="29240" level="104" type="L2RaidBoss" name="Lindvior" title="Wind Dragon">
<!-- AUTO GENERATED NPC TODO: FIX IT -->
<npc id="29240" level="104" type="L2GrandBoss" name="Lindvior" title="Wind Dragon">
<race>DRAGON</race>
<sex>FEMALE</sex>
<equipment rhand="15301" /> <!-- Transparent Pole (NPC) -->
<acquire exp="202583506944" sp="293716117" raidPoints="1000" />
<stats str="164" int="188" dex="55" wit="78" con="111" men="149">
<vitals hp="209461939" hpRegen="10.5" mp="47100" mpRegen="3.6" />
<vitals hp="209461939" hpRegen="10.5" mp="47100.0" mpRegen="3.6" />
<speed>
<walk ground="100" />
<run ground="270" />
@ -2066,91 +2066,123 @@
</stats>
<status attackable="false" />
<skill_list>
<skill id="5464" level="1" /> <!-- Wind Attack -->
<skill id="15638" level="1" /> <!-- Lindvior -->
<skill id="4416" level="10" /> <!-- Dragons -->
<skill id="4415" level="1"/> <!-- Bare Hands -->
<skill id="4416" level="10"/> <!-- Dragons -->
<skill id="5464" level="1"/> <!-- Wind Attack -->
<skill id="14765" level="4"/> <!-- Blood Siphon Resistance -->
<skill id="15638" level="1"/> <!-- Lindvior -->
<skill id="15271" level="1"/> <!-- Body Slam -->
<skill id="15272" level="1"/> <!-- Wind Breath -->
<skill id="15273" level="1"/> <!-- Tail Swipe -->
<skill id="15274" level="1"/> <!-- Mighty Wind Strike -->
<skill id="15430" level="1"/> <!-- Lindvior's Jump -->
<skill id="15591" level="1"/> <!-- Wind Pull -->
<skill id="15275" level="1"/> <!-- Tornado -->
<skill id="15600" level="1"/> <!-- Lindvior's Attack -->
</skill_list>
<ai aggroRange="2000" isAggressive="true" />
<drop_lists>
<death>
<group chance="100">
<item id="17435" min="1" max="3" chance="13.943474249" /> <!-- Eternal Shield Heavy Armor -->
<item id="17420" min="1" max="3" chance="7.8261166740713" /> <!-- Amaranthine Fighter -->
<item id="17424" min="1" max="3" chance="7.8175728785756" /> <!-- Amaranthine Buster -->
<item id="17421" min="1" max="3" chance="7.8150097399269" /> <!-- Amaranthine Stormer -->
<item id="17416" min="1" max="3" chance="7.804757185332" /> <!-- Amaranthine Shaper -->
<item id="17417" min="1" max="3" chance="7.7851064556919" /> <!-- Amaranthine Cutter -->
<item id="17422" min="1" max="3" chance="7.7816889374936" /> <!-- Amaranthine Thrower -->
<item id="17419" min="1" max="3" chance="7.7791257988449" /> <!-- Amaranthine Avenger -->
<item id="17426" min="1" max="3" chance="7.7654557260517" /> <!-- Amaranthine Retributer -->
<item id="17418" min="1" max="3" chance="7.7611838283039" /> <!-- Amaranthine Slasher -->
<item id="17425" min="1" max="3" chance="7.7492225146099" /> <!-- Amaranthine Caster -->
<item id="17423" min="1" max="3" chance="7.7227367485732" /> <!-- Amaranthine Shooter -->
<item id="36435" min="1" max="1" chance="0.064078466217833" /> <!-- Lindvior Thrower Fragment -->
<item id="36436" min="1" max="1" chance="0.064078466217833" /> <!-- Lindvior Slasher Fragment -->
<item id="36437" min="1" max="1" chance="0.064078466217833" /> <!-- Lindvior Caster Fragment -->
<item id="36438" min="1" max="1" chance="0.064078466217833" /> <!-- Lindvior Cutter Fragment -->
<item id="36439" min="1" max="1" chance="0.064078466217833" /> <!-- Lindvior Shooter Fragment -->
<item id="36440" min="1" max="1" chance="0.064078466217833" /> <!-- Lindvior Dual Dagger Fragment -->
<item id="36434" min="1" max="1" chance="0.064078466217833" /> <!-- Lindvior Shaper Fragment -->
<item id="17435" min="1" max="3" chance="14.491582377011" /> <!-- Eternal Shield - Heavy Armor -->
<item id="17423" min="1" max="3" chance="7.7770499612934" /> <!-- Amaranthine Shooter -->
<item id="17422" min="1" max="3" chance="7.7761992667013" /> <!-- Amaranthine Thrower -->
<item id="17425" min="1" max="3" chance="7.7761992667013" /> <!-- Amaranthine Caster -->
<item id="17419" min="1" max="3" chance="7.7676923207799" /> <!-- Amaranthine Avenger -->
<item id="17426" min="1" max="3" chance="7.7413207884237" /> <!-- Amaranthine Retributer -->
<item id="17421" min="1" max="3" chance="7.7277096749496" /> <!-- Amaranthine Stormer -->
<item id="17416" min="1" max="3" chance="7.7149492560676" /> <!-- Amaranthine Shaper -->
<item id="17420" min="1" max="3" chance="7.7021888371856" /> <!-- Amaranthine Fighter -->
<item id="17424" min="1" max="3" chance="7.698786058817" /> <!-- Amaranthine Buster -->
<item id="17418" min="1" max="3" chance="7.6936818912642" /> <!-- Amaranthine Slasher -->
<item id="17417" min="1" max="3" chance="7.686025639935" /> <!-- Amaranthine Cutter -->
<item id="36434" min="1" max="1" chance="0.063802094410086" /> <!-- Lindvior Shaper - Fragment -->
<item id="36436" min="1" max="1" chance="0.063802094410086" /> <!-- Lindvior Slasher - Fragment -->
<item id="36437" min="1" max="1" chance="0.063802094410086" /> <!-- Lindvior Caster - Fragment -->
<item id="36438" min="1" max="1" chance="0.063802094410086" /> <!-- Lindvior Cutter - Fragment -->
<item id="36439" min="1" max="1" chance="0.063802094410086" /> <!-- Lindvior Shooter - Fragment -->
<item id="36440" min="1" max="1" chance="0.063802094410086" /> <!-- Lindvior Dual Dagger - Fragment -->
<item id="36435" min="1" max="1" chance="0.063802094410086" /> <!-- Lindvior Thrower - Fragment -->
</group>
<group chance="100">
<item id="17438" min="1" max="3" chance="19.418571831781" /> <!-- Eternal Leather Leggings Light Armor -->
<item id="17437" min="1" max="3" chance="18.882303132938" /> <!-- Eternal Leather Armor Light Armor -->
<item id="17431" min="1" max="3" chance="15.777589613322" /> <!-- Eternal Breastplate Heavy Armor -->
<item id="17432" min="1" max="3" chance="15.580016934801" /> <!-- Eternal Gaiters Heavy Armor -->
<item id="17442" min="1" max="3" chance="15.438893593" /> <!-- Eternal Tunic Robe -->
<item id="17443" min="1" max="3" chance="14.902624894157" /> <!-- Eternal Stockings Robe -->
<item id="17438" min="1" max="3" chance="19.488372093023" /> <!-- Eternal Leather Leggings - Light Armor -->
<item id="17437" min="1" max="3" chance="18.706976744186" /> <!-- Eternal Leather Armor - Light Armor -->
<item id="17431" min="1" max="3" chance="16" /> <!-- Eternal Breastplate - Heavy Armor -->
<item id="17442" min="1" max="3" chance="15.944186046512" /> <!-- Eternal Tunic - Robe -->
<item id="17432" min="1" max="3" chance="14.939534883721" /> <!-- Eternal Gaiters - Heavy Armor -->
<item id="17443" min="1" max="3" chance="14.920930232558" /> <!-- Eternal Stockings - Robe -->
</group>
<group chance="100">
<item id="17439" min="1" max="3" chance="11.346601914493" /> <!-- Eternal Leather Gloves Light Armor -->
<item id="17440" min="1" max="3" chance="11.324144513376" /> <!-- Eternal Leather Boots Light Armor -->
<item id="17436" min="1" max="3" chance="11.04342699941" /> <!-- Eternal Leather Helmet Light Armor -->
<item id="17434" min="1" max="3" chance="9.7408977346097" /> <!-- Eternal Boots Heavy Armor -->
<item id="17446" min="1" max="3" chance="9.7044044577941" /> <!-- Eternal Sigil Robe -->
<item id="17444" min="1" max="3" chance="9.5163237234371" /> <!-- Eternal Gloves Robe -->
<item id="17441" min="1" max="3" chance="9.5107093731578" /> <!-- Eternal Circlet Robe -->
<item id="17433" min="1" max="3" chance="9.3871936670129" /> <!-- Eternal Gauntlets Heavy Armor -->
<item id="17430" min="1" max="3" chance="9.2299918591921" /> <!-- Eternal Helmet Heavy Armor -->
<item id="17445" min="1" max="3" chance="9.1963057575162" /> <!-- Eternal Shoes Robe -->
<item id="17436" min="1" max="3" chance="11.580551322898" /> <!-- Eternal Leather Helmet - Light Armor -->
<item id="17440" min="1" max="3" chance="11.414323313478" /> <!-- Eternal Leather Boots - Light Armor -->
<item id="17439" min="1" max="3" chance="10.738329408505" /> <!-- Eternal Leather Gloves - Light Armor -->
<item id="17441" min="1" max="3" chance="9.6910929491619" /> <!-- Eternal Circlet - Robe -->
<item id="17445" min="1" max="3" chance="9.6855520155146" /> <!-- Eternal Shoes - Robe -->
<item id="17434" min="1" max="3" chance="9.6301426790414" /> <!-- Eternal Boots - Heavy Armor -->
<item id="17430" min="1" max="3" chance="9.5913561435102" /> <!-- Eternal Helmet - Heavy Armor -->
<item id="17446" min="1" max="3" chance="9.4611442027982" /> <!-- Eternal Sigil - Robe -->
<item id="17433" min="1" max="3" chance="9.3032275938496" /> <!-- Eternal Gauntlets - Heavy Armor -->
<item id="17444" min="1" max="3" chance="8.9042803712426" /> <!-- Eternal Gloves - Robe -->
</group>
<group chance="20.3">
<group chance="20.07">
<item id="36946" min="1" max="1" chance="100" /> <!-- Lindvior's Earring -->
</group>
<group chance="100">
<item id="36414" min="1" max="1" chance="12.140931937936" /> <!-- Dragon Claw -->
<item id="37772" min="1" max="1" chance="6.1578806789209" /> <!-- Scroll of Blessing: Weapon (R99-grade) -->
<item id="35568" min="1" max="1" chance="6.1263142558823" /> <!-- Bloody Amaranthine Enhancement Stone -->
<item id="37781" min="1" max="1" chance="6.0449700118981" /> <!-- Scroll of Blessing: Armor (R99-grade) -->
<item id="18562" min="1" max="1" chance="4.0951363426657" /> <!-- Purple Soul Crystal (R99-grade) -->
<item id="18561" min="1" max="1" chance="4.0927081562781" /> <!-- Teal Soul Crystal (R99-grade) -->
<item id="18560" min="1" max="1" chance="4.0259330306194" /> <!-- Yellow Soul Crystal (R99-grade) -->
<item id="36389" min="10" max="10" chance="3.734550664109" /> <!-- Giant's Scroll: Enchant Armor (R-grade) -->
<item id="19448" min="10" max="10" chance="3.6604909792876" /> <!-- Blessed Scroll: Enchant Armor (R-grade) -->
<item id="36162" min="1" max="1" chance="2.5022460724085" /> <!-- Scroll of Blessing (R99-grade) -->
<item id="19447" min="10" max="10" chance="2.4221159216181" /> <!-- Blessed Scroll: Enchant Weapon (R-grade) -->
<item id="36386" min="10" max="10" chance="2.3310589320836" /> <!-- Giant's Scroll: Enchant Weapon (R-grade) -->
<item id="17708" min="1" max="1" chance="2.1100939708132" /> <!-- Lv. 5 Ancient MEN Dye MEN + 5 / Holy Resistance + 25 -->
<item id="17713" min="1" max="1" chance="2.0979530388753" /> <!-- Lv. 5 Legendary WIT Dye WIT + 5 / MEN + 1 / Wind Resistance + 25 -->
<item id="17697" min="1" max="1" chance="2.0955248524877" /> <!-- Lv. 5 Giant STR Dye STR + 5 -->
<item id="17706" min="1" max="1" chance="2.0955248524877" /> <!-- Lv. 5 Ancient INT Dye INT + 5 / Water Resistance + 25 -->
<item id="17704" min="1" max="1" chance="2.0943107592939" /> <!-- Lv. 5 Ancient DEX Dye DEX + 5 / Earth Resistance + 25 -->
<item id="17701" min="1" max="1" chance="2.0845980137435" /> <!-- Lv. 5 Giant WIT Dye Wit + 5 -->
<item id="39483" min="1" max="1" chance="2.063958429449" /> <!-- Alchemic Tome: Enchant Scroll -->
<item id="17699" min="1" max="1" chance="2.063958429449" /> <!-- Lv. 5 Giant CON Dye CON + 5 -->
<item id="17714" min="1" max="1" chance="2.0603161498677" /> <!-- Lv. 5 Legendary MEN Dye MEN + 5 / INT + 1 / Holy Resistance + 25 -->
<item id="17710" min="1" max="1" chance="2.0603161498677" /> <!-- Lv. 5 Legendary DEX Dye DEX + 5 / CON + 1 / Earth Resistance + 25 -->
<item id="17703" min="1" max="1" chance="2.0481752179297" /> <!-- Lv. 5 Ancient STR Dye STR + 5 / Fire Resistance + 25 -->
<item id="17698" min="1" max="1" chance="2.0445329383483" /> <!-- Lv. 5 Giant DEX Dye DEX + 5 -->
<item id="39485" min="1" max="1" chance="2.0166087948911" /> <!-- Alchemic Tome: Dye -->
<item id="17711" min="1" max="1" chance="2.0081101425345" /> <!-- Lv. 5 Legendary CON Dye CON + 5 / STR + 1 / Dark Resistance + 25 -->
<item id="17712" min="1" max="1" chance="1.9850423718525" /> <!-- Lv. 5 Legendary INT Dye INT + 5 / WIT + 1 / Water Resistance + 25 -->
<item id="17707" min="1" max="1" chance="1.9753296263021" /> <!-- Lv. 5 Ancient WIT Dye WIT + 5 / Wind Resistance + 25 -->
<item id="17702" min="1" max="1" chance="1.9668309739456" /> <!-- Lv. 5 Giant MEN Dye Men + 5 -->
<item id="39484" min="1" max="1" chance="1.9631886943642" /> <!-- Alchemic Tome: Life Stone -->
<item id="17700" min="1" max="1" chance="1.9619746011704" /> <!-- Lv. 5 Giant INT Dye INT + 5 -->
<item id="17705" min="1" max="1" chance="1.9425491100697" /> <!-- Lv. 5 Ancient CON Dye CON + 5 / Dark Resistance + 25 -->
<item id="17709" min="1" max="1" chance="1.9267658985504" /> <!-- Lv. 5 Legendary STR Dye STR + 5 / DEX + 1 / Fire Resistance + 25 -->
<item id="36414" min="1" max="1" chance="9.2128877243799" /> <!-- Dragon Claw -->
<item id="37781" min="1" max="1" chance="4.7169985148825" /> <!-- Scroll of Blessing: Armor (R99-grade) -->
<item id="35568" min="1" max="1" chance="4.6156567499143" /> <!-- Bloody Amaranthine Enhancement Stone -->
<item id="37772" min="1" max="1" chance="4.4940466319525" /> <!-- Scroll of Blessing: Weapon (R99-grade) -->
<item id="36389" min="10" max="10" chance="2.8403332854263" /> <!-- Giant's Scroll: Enchant Armor (R-grade) -->
<item id="19448" min="10" max="10" chance="2.7979540018942" /> <!-- Blessed Scroll: Enchant Armor (R-grade) -->
<item id="46492" min="1" max="2" chance="2.1373899520561" /> <!-- Pantheon's Soul Crystal - Stage 4 -->
<item id="46493" min="1" max="1" chance="2.1162003102901" /> <!-- Pantheon's Soul Crystal - Stage 5 -->
<item id="46477" min="1" max="2" chance="2.1088300001106" /> <!-- Leona's Soul Crystal - Stage 4 -->
<item id="46478" min="1" max="1" chance="2.086719069572" /> <!-- Leona's Soul Crystal - Stage 5 -->
<item id="46508" min="1" max="1" chance="2.036048187088" /> <!-- Lionel's Soul Crystal - Stage 5 -->
<item id="46507" min="1" max="2" chance="2.0222288555014" /> <!-- Lionel's Soul Crystal - Stage 4 -->
<item id="36162" min="1" max="1" chance="1.9079890477191" /> <!-- Scroll of Blessing: (R99-grade) -->
<item id="46479" min="1" max="1" chance="1.819545325565" /> <!-- Leona's Soul Crystal - Stage 6 -->
<item id="46509" min="1" max="1" chance="1.8075685715233" /> <!-- Lionel's Soul Crystal - Stage 6 -->
<item id="36386" min="10" max="10" chance="1.8149388817028" /> <!-- Giant's Scroll: Enchant Weapon (R-grade) -->
<item id="46494" min="1" max="1" chance="1.8066472827509" /> <!-- Pantheon's Soul Crystal - Stage 6 -->
<item id="19447" min="10" max="10" chance="1.8029621276611" /> <!-- Blessed Scroll: Enchant Weapon (R-grade) -->
<item id="17708" min="1" max="1" chance="1.6122553517665" /> <!-- Lv. 5 Ancient MEN Dye - MEN + 5 / Holy Resistance + 25 -->
<item id="39484" min="1" max="1" chance="1.6021211752697" /> <!-- Alchemic Tome: Life Stone -->
<item id="17714" min="1" max="1" chance="1.5892231324555" /> <!-- Lv. 5 Legendary MEN Dye - MEN + 5 / INT + 1 / Holy Resistance + 25 -->
<item id="17703" min="1" max="1" chance="1.5643483355997" /> <!-- Lv. 5 Ancient STR Dye - STR + 5 / Fire Resistance + 25 -->
<item id="17709" min="1" max="1" chance="1.5615844692824" /> <!-- Lv. 5 Legendary STR Dye - STR + 5 / DEX + 1 / Fire Resistance + 25 -->
<item id="17706" min="1" max="1" chance="1.5542141591029" /> <!-- Lv. 5 Ancient INT Dye - INT + 5 / Water Resistance + 25 -->
<item id="17702" min="1" max="1" chance="1.5477651376958" /> <!-- Lv. 5 Giant MEN Dye - Men + 5 -->
<item id="39485" min="1" max="1" chance="1.5413161162888" /> <!-- Alchemic Tome: Dye -->
<item id="39483" min="1" max="1" chance="1.5367096724266" /> <!-- Alchemic Tome: Enchant Scroll -->
<item id="17711" min="1" max="1" chance="1.5367096724266" /> <!-- Lv. 5 Legendary CON Dye - CON + 5 / STR + 1 / Dark Resistance + 25 -->
<item id="17697" min="1" max="1" chance="1.5357883836541" /> <!-- Lv. 5 Giant STR Dye - STR + 5 -->
<item id="17712" min="1" max="1" chance="1.5357883836541" /> <!-- Lv. 5 Legendary INT Dye - INT + 5 / WIT + 1 / Water Resistance + 25 -->
<item id="17713" min="1" max="1" chance="1.5265754959297" /> <!-- Lv. 5 Legendary WIT Dye - WIT + 5 / MEN + 1 / Wind Resistance + 25 -->
<item id="17705" min="1" max="1" chance="1.5072284317085" /> <!-- Lv. 5 Ancient CON Dye - CON + 5 / Dark Resistance + 25 -->
<item id="46463" min="1" max="1" chance="1.4952516776669" /> <!-- Mermoden's Soul Crystal - Stage 5 -->
<item id="17707" min="1" max="1" chance="1.5026219878464" /> <!-- Lv. 5 Ancient WIT Dye - WIT + 5 / Wind Resistance + 25 -->
<item id="17699" min="1" max="1" chance="1.4980155439842" /> <!-- Lv. 5 Giant CON Dye - CON + 5 -->
<item id="17704" min="1" max="1" chance="1.4924878113495" /> <!-- Lv. 5 Ancient DEX Dye - DEX + 5 / Earth Resistance + 25 -->
<item id="17701" min="1" max="1" chance="1.4860387899425" /> <!-- Lv. 5 Giant WIT Dye - Wit + 5 -->
<item id="17698" min="1" max="1" chance="1.4759046134457" /> <!-- Lv. 5 Giant DEX Dye - DEX + 5 -->
<item id="46462" min="1" max="2" chance="1.4593214155418" /> <!-- Mermoden's Soul Crystal - Stage 4 -->
<item id="17700" min="1" max="1" chance="1.4685343032662" /> <!-- Lv. 5 Giant INT Dye - INT + 5 -->
<item id="17710" min="1" max="1" chance="1.4620852818591" /> <!-- Lv. 5 Legendary DEX Dye - DEX + 5 / CON + 1 / Earth Resistance + 25 -->
<item id="46448" min="1" max="1" chance="1.4215485758718" /> <!-- Kain's Soul Crystal - Stage 5 -->
<item id="46447" min="1" max="2" chance="1.3874608912916" /> <!-- Kain's Soul Crystal - Stage 4 -->
<item id="46449" min="1" max="1" chance="1.1728006073136" /> <!-- Kain's Soul Crystal - Stage 6 -->
<item id="46464" min="1" max="1" chance="1.1645090083616" /> <!-- Mermoden's Soul Crystal - Stage 6 -->
<item id="46495" min="1" max="1" chance="1.0677736872556" /> <!-- Pantheon's Soul Crystal - Stage 7 -->
<item id="46510" min="1" max="1" chance="1.032764713903" /> <!-- Lionel's Soul Crystal - Stage 7 -->
<item id="46480" min="1" max="1" chance="1.0189453823164" /> <!-- Leona's Soul Crystal - Stage 7 -->
<item id="46450" min="1" max="1" chance="0.71989504678304" /> <!-- Kain's Soul Crystal - Stage 7 -->
<item id="46465" min="1" max="1" chance="0.71630202057054" /> <!-- Mermoden's Soul Crystal - Stage 7 -->
<item id="46511" min="1" max="1" chance="0.71187983446283" /> <!-- Lionel's Soul Crystal - Stage 8 -->
<item id="46481" min="1" max="1" chance="0.70708913284616" /> <!-- Leona's Soul Crystal - Stage 8 -->
<item id="46496" min="1" max="1" chance="0.70220630235223" /> <!-- Pantheon's Soul Crystal - Stage 8 -->
<item id="46451" min="1" max="1" chance="0.47041004720684" /> <!-- Kain's Soul Crystal - Stage 8 -->
<item id="46466" min="1" max="1" chance="0.46958088731164" /> <!-- Mermoden's Soul Crystal - Stage 8 -->
</group>
</death>
<lucky_corpse>
@ -2163,7 +2195,7 @@
<height normal="210" />
</collision>
</npc>
<npc id="29241" level="99" type="L2Monster" name="Lyn Draco" title="">
<npc id="29241" level="104" type="L2Monster" name="Lyn Draco" title="">
<!-- AUTO GENERATED NPC TODO: FIX IT -->
<race>DRAGON</race>
<sex>FEMALE</sex>

View File

@ -50,22 +50,37 @@
<castRange>1800</castRange>
</skill>
<skill id="15605" toLevel="1" name="Recharge Possible">
<!-- AUTO GENERATED SKILL -->
<!-- Recharge possible. -->
<icon>icon.skill0005</icon>
<abnormalTime>20</abnormalTime>
<operateType>A2</operateType>
<castRange>1000</castRange>
<affectRange>1000</affectRange>
<effectPoint>1</effectPoint>
<hitTime>25000</hitTime>
<hitTime>10000</hitTime> <!-- retail 25000 -->
<targetType>SELF</targetType>
<affectScope>RANGE</affectScope>
<affectObject>NOT_FRIEND</affectObject>
</skill>
<skill id="15606" toLevel="1" name="Recharge">
<!-- AUTO GENERATED SKILL -->
<!-- Recharge. -->
<icon>icon.skill1449</icon>
<icon>icon.skill14444</icon>
<operateType>A1</operateType>
<isDebuff>1</isDebuff>
<castRange>900</castRange>
<hitTime>10000</hitTime>
<effectPoint>-2</effectPoint>
<coolTime>200</coolTime>
<targetType>TARGET</targetType>
<affectScope>SINGLE</affectScope>
<conditions>
<condition name="OpTargetNpc">
<npcIds>
<item>19477</item> <!-- Generator -->
</npcIds>
</condition>
</conditions>
</skill>
<skill id="15607" toLevel="1" name="Depleted">
<!-- AUTO GENERATED SKILL -->

View File

@ -167,6 +167,20 @@
<node X="126188" Y="29775" />
<node X="127178" Y="3979" />
</zone>
<zone name="Lindvior Boss" id="12107" type="NoSummonFriendZone" shape="NPoly" minZ="-1600" maxZ="1400" >
<node X="47032" Y="-29208" />
<node X="47104" Y="-30224" />
<node X="46903" Y="-31227" />
<node X="45186" Y="-31724" />
<node X="41983" Y="-30329" />
<node X="40588" Y="-27021" />
<node X="42113" Y="-23755" />
<node X="45462" Y="-22424" />
<node X="48593" Y="-24010" />
<node X="49873" Y="-27337" />
<node X="49357" Y="-28620" />
<node X="47553" Y="-29161" />
</zone>
<zone name="Ramona_Room" id="210108" type="NoSummonFriendZone" shape="Cylinder" minZ="-10610" maxZ="-10050" rad="3000" >
<node X="78023" Y="172262" />
</zone>

View File

@ -893,6 +893,13 @@ public final class Config
public static int KELBIM_SPAWN_INTERVAL;
public static int KELBIM_SPAWN_RANDOM;
// Lindvior
public static int LINDVIOR_SPAWN_INTERVAL;
public static int LINDVIOR_SPAWN_RANDOM;
public static int LINDVIOR_MIN_PLAYERS;
public static int LINDVIOR_MAX_PLAYERS;
public static int LINDVIOR_MIN_PLAYER_LVL;
// Anakim
public static int ANAKIM_MIN_PLAYERS;
public static int ANAKIM_MAX_PLAYERS;
@ -2227,6 +2234,11 @@ public final class Config
LILITH_SPAWN_RANDOM = GrandBossSettings.getInt("RandomOfLilithSpawn", 148);
LILITH_MIN_PLAYER_LVL = GrandBossSettings.getInt("LilithMinPlayerLvl", 85);
LILITH_MAX_PLAYER_LVL = GrandBossSettings.getInt("LilithMaxPlayerLvl", 89);
LINDVIOR_SPAWN_INTERVAL = GrandBossSettings.getInt("IntervalOfLindviorSpawn", 264);
LINDVIOR_SPAWN_RANDOM = GrandBossSettings.getInt("RandomOfLindviorSpawn", 72);
LINDVIOR_MIN_PLAYERS = GrandBossSettings.getInt("LindviorMinPlayers", 49);
LINDVIOR_MAX_PLAYERS = GrandBossSettings.getInt("LindviorMaxPlayers", 112);
LINDVIOR_MIN_PLAYER_LVL = GrandBossSettings.getInt("LindviorMinPlayerLvl", 99);
// Gracia Seeds
final PropertiesParser GraciaSeedsSettings = new PropertiesParser(GRACIASEEDS_CONFIG_FILE);

View File

@ -20,7 +20,6 @@ What is done
TODO list
-Helios grandboss
-Lindvior
-Trasken
-Underground five man dungeons
-Check all quests rewards