[Classic] Addition/Removal of NPC XMLs.
This commit is contained in:
@@ -6,7 +6,7 @@
|
|||||||
<td align=center><button value="Back" action="bypass -h admin_html teleports/WorldAreas.htm" width=40 height=21 back="L2UI_CT1.Button_DF_Down" fore="L2UI_CT1.Button_DF"></td>
|
<td align=center><button value="Back" action="bypass -h admin_html teleports/WorldAreas.htm" width=40 height=21 back="L2UI_CT1.Button_DF_Down" fore="L2UI_CT1.Button_DF"></td>
|
||||||
</tr></table><br>
|
</tr></table><br>
|
||||||
<font color="LEVEL">Fields</font><br1>
|
<font color="LEVEL">Fields</font><br1>
|
||||||
<button action="bypass -h admin_move_to 45010 148000 -3694" value="Guilotine Fortress" width=210 height=21 back="L2UI_CT1.Button_DF_Down" fore="L2UI_CT1.Button_DF"><br1>
|
<button action="bypass -h admin_move_to 45010 148000 -3694" value="Execution Grounds" width=210 height=21 back="L2UI_CT1.Button_DF_Down" fore="L2UI_CT1.Button_DF"><br1>
|
||||||
<button action="bypass -h admin_move_to 50081 116859 -2176" value="Partisan's Hideaway" width=210 height=21 back="L2UI_CT1.Button_DF_Down" fore="L2UI_CT1.Button_DF"><br1>
|
<button action="bypass -h admin_move_to 50081 116859 -2176" value="Partisan's Hideaway" width=210 height=21 back="L2UI_CT1.Button_DF_Down" fore="L2UI_CT1.Button_DF"><br1>
|
||||||
<button action="bypass -h admin_move_to 5106 126916 -3664" value="Cruma Marshlands" width=210 height=21 back="L2UI_CT1.Button_DF_Down" fore="L2UI_CT1.Button_DF"><br1>
|
<button action="bypass -h admin_move_to 5106 126916 -3664" value="Cruma Marshlands" width=210 height=21 back="L2UI_CT1.Button_DF_Down" fore="L2UI_CT1.Button_DF"><br1>
|
||||||
<button action="bypass -h admin_move_to 38291 148029 -3696" value="Mandragora Farm" width=210 height=21 back="L2UI_CT1.Button_DF_Down" fore="L2UI_CT1.Button_DF"><br1>
|
<button action="bypass -h admin_move_to 38291 148029 -3696" value="Mandragora Farm" width=210 height=21 back="L2UI_CT1.Button_DF_Down" fore="L2UI_CT1.Button_DF"><br1>
|
||||||
|
@@ -1,13 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<instance name="Grassy Arena" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../xsd/instance.xsd">
|
|
||||||
<doorlist>
|
|
||||||
<door doorId="17100001" />
|
|
||||||
<door doorId="17100002" />
|
|
||||||
</doorlist>
|
|
||||||
<spawnlist>
|
|
||||||
<group name="general">
|
|
||||||
<spawn npcId="36402" x="-89400" y="-252843" z="-3341" heading="0" respawn="60" />
|
|
||||||
<spawn npcId="36402" x="-86763" y="-252843" z="-3341" heading="0" respawn="60" />
|
|
||||||
</group>
|
|
||||||
</spawnlist>
|
|
||||||
</instance>
|
|
@@ -1,13 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<instance name="Heros's Vestiges Arena" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../xsd/instance.xsd">
|
|
||||||
<doorlist>
|
|
||||||
<door doorId="17100201" />
|
|
||||||
<door doorId="17100202" />
|
|
||||||
</doorlist>
|
|
||||||
<spawnlist>
|
|
||||||
<group name="general">
|
|
||||||
<spawn npcId="36402" x="-89192" y="-239351" z="-8475" heading="0" respawn="60" />
|
|
||||||
<spawn npcId="36402" x="-86998" y="-239351" z="-8475" heading="0" respawn="60" />
|
|
||||||
</group>
|
|
||||||
</spawnlist>
|
|
||||||
</instance>
|
|
@@ -1,13 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<instance name="Orbis Arena" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../xsd/instance.xsd">
|
|
||||||
<doorlist>
|
|
||||||
<door doorId="17100301" />
|
|
||||||
<door doorId="17100302" />
|
|
||||||
</doorlist>
|
|
||||||
<spawnlist>
|
|
||||||
<group name="general">
|
|
||||||
<spawn npcId="36402" x="-76655" y="-239182" z="-8218" heading="0" respawn="60" />
|
|
||||||
<spawn npcId="36402" x="-74258" y="-239182" z="-8218" heading="0" respawn="60" />
|
|
||||||
</group>
|
|
||||||
</spawnlist>
|
|
||||||
</instance>
|
|
@@ -1,13 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<instance name="Three Bridges Arena" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../xsd/instance.xsd">
|
|
||||||
<doorlist>
|
|
||||||
<door doorId="17100101" />
|
|
||||||
<door doorId="17100102" />
|
|
||||||
</doorlist>
|
|
||||||
<spawnlist>
|
|
||||||
<group name="general">
|
|
||||||
<spawn npcId="36402" x="-76760" y="-252461" z="-7741" heading="0" respawn="60" />
|
|
||||||
<spawn npcId="36402" x="-74170" y="-252459" z="-7741" heading="0" respawn="60" />
|
|
||||||
</group>
|
|
||||||
</spawnlist>
|
|
||||||
</instance>
|
|
42
trunk/dist/game/data_classic/scripts.cfg
vendored
42
trunk/dist/game/data_classic/scripts.cfg
vendored
@@ -11,7 +11,6 @@ handlers/MasterHandler.java
|
|||||||
# AI Section
|
# AI Section
|
||||||
|
|
||||||
# Npc
|
# Npc
|
||||||
ai/npc/AdventurersGuide/AdventurersGuide.java
|
|
||||||
ai/npc/Alexandria/Alexandria.java
|
ai/npc/Alexandria/Alexandria.java
|
||||||
ai/npc/ArenaManager/ArenaManager.java
|
ai/npc/ArenaManager/ArenaManager.java
|
||||||
ai/npc/AvantGarde/AvantGarde.java
|
ai/npc/AvantGarde/AvantGarde.java
|
||||||
@@ -27,18 +26,13 @@ ai/npc/CastleTeleporter/CastleTeleporter.java
|
|||||||
ai/npc/CastleWarehouse/CastleWarehouse.java
|
ai/npc/CastleWarehouse/CastleWarehouse.java
|
||||||
ai/npc/ClanTrader/ClanTrader.java
|
ai/npc/ClanTrader/ClanTrader.java
|
||||||
ai/npc/FameManager/FameManager.java
|
ai/npc/FameManager/FameManager.java
|
||||||
ai/npc/ForgeOfTheGods/ForgeOfTheGods.java
|
|
||||||
ai/npc/ForgeOfTheGods/Rooney.java
|
|
||||||
ai/npc/ForgeOfTheGods/TarBeetle.java
|
|
||||||
ai/npc/FortressArcherCaptain/FortressArcherCaptain.java
|
ai/npc/FortressArcherCaptain/FortressArcherCaptain.java
|
||||||
ai/npc/FortressSiegeManager/FortressSiegeManager.java
|
ai/npc/FortressSiegeManager/FortressSiegeManager.java
|
||||||
ai/npc/KetraOrcSupport/KetraOrcSupport.java
|
ai/npc/KetraOrcSupport/KetraOrcSupport.java
|
||||||
ai/npc/Mammons/Mammons.java
|
|
||||||
ai/npc/ManorManager/ManorManager.java
|
ai/npc/ManorManager/ManorManager.java
|
||||||
ai/npc/Minigame/Minigame.java
|
ai/npc/Minigame/Minigame.java
|
||||||
ai/npc/MonumentOfHeroes/MonumentOfHeroes.java
|
ai/npc/MonumentOfHeroes/MonumentOfHeroes.java
|
||||||
ai/npc/NpcBuffers/NpcBuffers.java
|
ai/npc/NpcBuffers/NpcBuffers.java
|
||||||
ai/npc/Rignos/Rignos.java
|
|
||||||
ai/npc/Rafforty/Rafforty.java
|
ai/npc/Rafforty/Rafforty.java
|
||||||
ai/npc/RemembranceTower/RemembranceTower.java
|
ai/npc/RemembranceTower/RemembranceTower.java
|
||||||
ai/npc/Summons/MerchantGolem/GolemTrader.java
|
ai/npc/Summons/MerchantGolem/GolemTrader.java
|
||||||
@@ -57,47 +51,26 @@ ai/npc/VillageMasters/FirstClassTransferTalk/FirstClassTransferTalk.java
|
|||||||
ai/npc/WyvernManager/WyvernManager.java
|
ai/npc/WyvernManager/WyvernManager.java
|
||||||
|
|
||||||
# Group Template
|
# Group Template
|
||||||
ai/group_template/BeastFarm.java
|
|
||||||
ai/group_template/DenOfEvil.java
|
|
||||||
ai/group_template/FairyTrees.java
|
ai/group_template/FairyTrees.java
|
||||||
ai/group_template/FeedableBeasts.java
|
|
||||||
ai/group_template/FleeMonsters.java
|
ai/group_template/FleeMonsters.java
|
||||||
ai/group_template/FrozenLabyrinth.java
|
|
||||||
ai/group_template/GiantsCave.java
|
|
||||||
ai/group_template/HotSprings.java
|
|
||||||
ai/group_template/MinionSpawnManager.java
|
ai/group_template/MinionSpawnManager.java
|
||||||
ai/group_template/MonasteryOfSilence.java
|
|
||||||
ai/group_template/NonLethalableNpcs.java
|
ai/group_template/NonLethalableNpcs.java
|
||||||
ai/group_template/PaganTemple.java
|
|
||||||
ai/group_template/PavelArchaic.java
|
|
||||||
ai/group_template/PlainsOfDion.java
|
ai/group_template/PlainsOfDion.java
|
||||||
ai/group_template/PlainsOfLizardman.java
|
|
||||||
ai/group_template/PolymorphingAngel.java
|
ai/group_template/PolymorphingAngel.java
|
||||||
ai/group_template/PolymorphingOnAttack.java
|
ai/group_template/PolymorphingOnAttack.java
|
||||||
ai/group_template/PrisonGuards.java
|
|
||||||
ai/group_template/RandomSpawn.java
|
|
||||||
ai/group_template/SeeThroughSilentMove.java
|
|
||||||
ai/group_template/SilentValley.java
|
ai/group_template/SilentValley.java
|
||||||
ai/group_template/StakatoNest.java
|
|
||||||
ai/group_template/SummonPc.java
|
ai/group_template/SummonPc.java
|
||||||
ai/group_template/TurekOrcs.java
|
ai/group_template/TurekOrcs.java
|
||||||
ai/group_template/WarriorFishingBlock.java
|
ai/group_template/WarriorFishingBlock.java
|
||||||
|
|
||||||
# Individual
|
# Individual
|
||||||
ai/individual/CrimsonHatuOtis.java
|
|
||||||
ai/individual/DarkWaterDragon.java
|
|
||||||
ai/individual/DivineBeast.java
|
|
||||||
ai/individual/DrChaos.java
|
|
||||||
ai/individual/EvasGiftBox.java
|
ai/individual/EvasGiftBox.java
|
||||||
ai/individual/FrightenedRagnaOrc.java
|
|
||||||
ai/individual/GraveRobbers.java
|
|
||||||
ai/individual/Orfen.java
|
ai/individual/Orfen.java
|
||||||
ai/individual/QueenAnt.java
|
ai/individual/QueenAnt.java
|
||||||
ai/individual/RagnaOrcCommander.java
|
ai/individual/RagnaOrcCommander.java
|
||||||
ai/individual/RagnaOrcSeer.java
|
ai/individual/RagnaOrcSeer.java
|
||||||
ai/individual/RagnaOrcHero.java
|
ai/individual/RagnaOrcHero.java
|
||||||
ai/individual/SinEater.java
|
ai/individual/SinEater.java
|
||||||
ai/individual/SinWardens.java
|
|
||||||
|
|
||||||
# Village Master
|
# Village Master
|
||||||
village_master/Clan/Clan.java
|
village_master/Clan/Clan.java
|
||||||
@@ -131,20 +104,5 @@ vehicles/BoatInnadrilTour.java
|
|||||||
vehicles/BoatGludinRune.java
|
vehicles/BoatGludinRune.java
|
||||||
vehicles/BoatTalkingGludin.java
|
vehicles/BoatTalkingGludin.java
|
||||||
|
|
||||||
# Conquerable Clan Halls
|
|
||||||
conquerablehalls/flagwar/BanditStronghold/BanditStronghold.java
|
|
||||||
conquerablehalls/flagwar/WildBeastReserve/WildBeastReserve.java
|
|
||||||
conquerablehalls/DevastatedCastle/DevastatedCastle.java
|
|
||||||
conquerablehalls/FortressOfResistance/FortressOfResistance.java
|
|
||||||
conquerablehalls/FortressOfTheDead/FortressOfTheDead.java
|
|
||||||
conquerablehalls/RainbowSpringsChateau/RainbowSpringsChateau.java
|
|
||||||
|
|
||||||
# Events
|
# Events
|
||||||
events/CharacterBirthday/CharacterBirthday.java
|
events/CharacterBirthday/CharacterBirthday.java
|
||||||
|
|
||||||
# Disabled by default events
|
|
||||||
#events/GiftOfVitality/GiftOfVitality.java
|
|
||||||
#events/HeavyMedal/HeavyMedal.java
|
|
||||||
#events/TheValentineEvent/TheValentineEvent.java
|
|
||||||
#events/MasterOfEnchanting/MasterOfEnchanting.java
|
|
||||||
#events/LoveYourGatekeeper/LoveYourGatekeeper.java
|
|
||||||
|
@@ -1,483 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2004-2015 L2J DataPack
|
|
||||||
*
|
|
||||||
* This file is part of L2J DataPack.
|
|
||||||
*
|
|
||||||
* L2J DataPack 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.
|
|
||||||
*
|
|
||||||
* L2J DataPack 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.group_template;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
|
||||||
|
|
||||||
import ai.npc.AbstractNpcAI;
|
|
||||||
|
|
||||||
import com.l2jserver.gameserver.ai.CtrlIntention;
|
|
||||||
import com.l2jserver.gameserver.datatables.SkillData;
|
|
||||||
import com.l2jserver.gameserver.model.L2Object;
|
|
||||||
import com.l2jserver.gameserver.model.actor.L2Attackable;
|
|
||||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
|
||||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
|
||||||
import com.l2jserver.gameserver.model.actor.instance.L2TamedBeastInstance;
|
|
||||||
import com.l2jserver.gameserver.model.holders.SkillHolder;
|
|
||||||
import com.l2jserver.gameserver.model.skills.Skill;
|
|
||||||
import com.l2jserver.gameserver.network.serverpackets.NpcInfo;
|
|
||||||
import com.l2jserver.gameserver.util.Util;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Growth-capable mobs: Polymorphing upon successful feeding.<br>
|
|
||||||
* Updated to Freya.
|
|
||||||
* @author Fulminus, Gigiikun
|
|
||||||
*/
|
|
||||||
public final class BeastFarm extends AbstractNpcAI
|
|
||||||
{
|
|
||||||
private static final int GOLDEN_SPICE = 15474;
|
|
||||||
private static final int CRYSTAL_SPICE = 15475;
|
|
||||||
private static final int SKILL_GOLDEN_SPICE = 9049;
|
|
||||||
private static final int SKILL_CRYSTAL_SPICE = 9050;
|
|
||||||
private static final int SKILL_BLESSED_GOLDEN_SPICE = 9051;
|
|
||||||
private static final int SKILL_BLESSED_CRYSTAL_SPICE = 9052;
|
|
||||||
private static final int SKILL_SGRADE_GOLDEN_SPICE = 9053;
|
|
||||||
private static final int SKILL_SGRADE_CRYSTAL_SPICE = 9054;
|
|
||||||
private static final int[] TAMED_BEASTS =
|
|
||||||
{
|
|
||||||
18869,
|
|
||||||
18870,
|
|
||||||
18871,
|
|
||||||
18872
|
|
||||||
};
|
|
||||||
private static final int TAME_CHANCE = 20;
|
|
||||||
protected static final int[] SPECIAL_SPICE_CHANCES =
|
|
||||||
{
|
|
||||||
33,
|
|
||||||
75
|
|
||||||
};
|
|
||||||
|
|
||||||
// all mobs that can eat...
|
|
||||||
private static final int[] FEEDABLE_BEASTS =
|
|
||||||
{
|
|
||||||
// Kookaburras
|
|
||||||
18873,
|
|
||||||
18874,
|
|
||||||
18875,
|
|
||||||
18876,
|
|
||||||
18877,
|
|
||||||
18878,
|
|
||||||
18879,
|
|
||||||
// Cougars
|
|
||||||
18880,
|
|
||||||
18881,
|
|
||||||
18882,
|
|
||||||
18883,
|
|
||||||
18884,
|
|
||||||
18885,
|
|
||||||
18886,
|
|
||||||
// Buffalos
|
|
||||||
18887,
|
|
||||||
18888,
|
|
||||||
18889,
|
|
||||||
18890,
|
|
||||||
18891,
|
|
||||||
18892,
|
|
||||||
18893,
|
|
||||||
// Grendels
|
|
||||||
18894,
|
|
||||||
18895,
|
|
||||||
18896,
|
|
||||||
18897,
|
|
||||||
18898,
|
|
||||||
18899,
|
|
||||||
18900
|
|
||||||
};
|
|
||||||
|
|
||||||
private static final Map<Integer, Integer> FEED_INFO = new ConcurrentHashMap<>();
|
|
||||||
private static final Map<Integer, GrowthCapableMob> GROWTH_CAPABLE_MONSTERS = new HashMap<>();
|
|
||||||
private static List<TamedBeast> TAMED_BEAST_DATA = new ArrayList<>();
|
|
||||||
|
|
||||||
private BeastFarm()
|
|
||||||
{
|
|
||||||
super(BeastFarm.class.getSimpleName(), "ai/group_template");
|
|
||||||
addSkillSeeId(FEEDABLE_BEASTS);
|
|
||||||
addKillId(FEEDABLE_BEASTS);
|
|
||||||
|
|
||||||
GrowthCapableMob temp;
|
|
||||||
|
|
||||||
// Kookabura
|
|
||||||
temp = new GrowthCapableMob(100, 0, 18869);
|
|
||||||
temp.addNpcIdForSkillId(SKILL_GOLDEN_SPICE, 18874);
|
|
||||||
temp.addNpcIdForSkillId(SKILL_CRYSTAL_SPICE, 18875);
|
|
||||||
temp.addNpcIdForSkillId(SKILL_BLESSED_GOLDEN_SPICE, 18869);
|
|
||||||
temp.addNpcIdForSkillId(SKILL_BLESSED_CRYSTAL_SPICE, 18869);
|
|
||||||
temp.addNpcIdForSkillId(SKILL_SGRADE_GOLDEN_SPICE, 18878);
|
|
||||||
temp.addNpcIdForSkillId(SKILL_SGRADE_CRYSTAL_SPICE, 18879);
|
|
||||||
GROWTH_CAPABLE_MONSTERS.put(18873, temp);
|
|
||||||
|
|
||||||
temp = new GrowthCapableMob(40, 1, 18869);
|
|
||||||
temp.addNpcIdForSkillId(SKILL_GOLDEN_SPICE, 18876);
|
|
||||||
GROWTH_CAPABLE_MONSTERS.put(18874, temp);
|
|
||||||
|
|
||||||
temp = new GrowthCapableMob(40, 1, 18869);
|
|
||||||
temp.addNpcIdForSkillId(SKILL_CRYSTAL_SPICE, 18877);
|
|
||||||
GROWTH_CAPABLE_MONSTERS.put(18875, temp);
|
|
||||||
|
|
||||||
temp = new GrowthCapableMob(25, 2, 18869);
|
|
||||||
temp.addNpcIdForSkillId(SKILL_GOLDEN_SPICE, 18878);
|
|
||||||
GROWTH_CAPABLE_MONSTERS.put(18876, temp);
|
|
||||||
|
|
||||||
temp = new GrowthCapableMob(25, 2, 18869);
|
|
||||||
temp.addNpcIdForSkillId(SKILL_CRYSTAL_SPICE, 18879);
|
|
||||||
GROWTH_CAPABLE_MONSTERS.put(18877, temp);
|
|
||||||
|
|
||||||
// Cougar
|
|
||||||
temp = new GrowthCapableMob(100, 0, 18870);
|
|
||||||
temp.addNpcIdForSkillId(SKILL_GOLDEN_SPICE, 18881);
|
|
||||||
temp.addNpcIdForSkillId(SKILL_CRYSTAL_SPICE, 18882);
|
|
||||||
temp.addNpcIdForSkillId(SKILL_BLESSED_GOLDEN_SPICE, 18870);
|
|
||||||
temp.addNpcIdForSkillId(SKILL_BLESSED_CRYSTAL_SPICE, 18870);
|
|
||||||
temp.addNpcIdForSkillId(SKILL_SGRADE_GOLDEN_SPICE, 18885);
|
|
||||||
temp.addNpcIdForSkillId(SKILL_SGRADE_CRYSTAL_SPICE, 18886);
|
|
||||||
GROWTH_CAPABLE_MONSTERS.put(18880, temp);
|
|
||||||
|
|
||||||
temp = new GrowthCapableMob(40, 1, 18870);
|
|
||||||
temp.addNpcIdForSkillId(SKILL_GOLDEN_SPICE, 18883);
|
|
||||||
GROWTH_CAPABLE_MONSTERS.put(18881, temp);
|
|
||||||
|
|
||||||
temp = new GrowthCapableMob(40, 1, 18870);
|
|
||||||
temp.addNpcIdForSkillId(SKILL_CRYSTAL_SPICE, 18884);
|
|
||||||
GROWTH_CAPABLE_MONSTERS.put(18882, temp);
|
|
||||||
|
|
||||||
temp = new GrowthCapableMob(25, 2, 18870);
|
|
||||||
temp.addNpcIdForSkillId(SKILL_GOLDEN_SPICE, 18885);
|
|
||||||
GROWTH_CAPABLE_MONSTERS.put(18883, temp);
|
|
||||||
|
|
||||||
temp = new GrowthCapableMob(25, 2, 18870);
|
|
||||||
temp.addNpcIdForSkillId(SKILL_CRYSTAL_SPICE, 18886);
|
|
||||||
GROWTH_CAPABLE_MONSTERS.put(18884, temp);
|
|
||||||
|
|
||||||
// Buffalo
|
|
||||||
temp = new GrowthCapableMob(100, 0, 18871);
|
|
||||||
temp.addNpcIdForSkillId(SKILL_GOLDEN_SPICE, 18888);
|
|
||||||
temp.addNpcIdForSkillId(SKILL_CRYSTAL_SPICE, 18889);
|
|
||||||
temp.addNpcIdForSkillId(SKILL_BLESSED_GOLDEN_SPICE, 18871);
|
|
||||||
temp.addNpcIdForSkillId(SKILL_BLESSED_CRYSTAL_SPICE, 18871);
|
|
||||||
temp.addNpcIdForSkillId(SKILL_SGRADE_GOLDEN_SPICE, 18892);
|
|
||||||
temp.addNpcIdForSkillId(SKILL_SGRADE_CRYSTAL_SPICE, 18893);
|
|
||||||
GROWTH_CAPABLE_MONSTERS.put(18887, temp);
|
|
||||||
|
|
||||||
temp = new GrowthCapableMob(40, 1, 18871);
|
|
||||||
temp.addNpcIdForSkillId(SKILL_GOLDEN_SPICE, 18890);
|
|
||||||
GROWTH_CAPABLE_MONSTERS.put(18888, temp);
|
|
||||||
|
|
||||||
temp = new GrowthCapableMob(40, 1, 18871);
|
|
||||||
temp.addNpcIdForSkillId(SKILL_CRYSTAL_SPICE, 18891);
|
|
||||||
GROWTH_CAPABLE_MONSTERS.put(18889, temp);
|
|
||||||
|
|
||||||
temp = new GrowthCapableMob(25, 2, 18871);
|
|
||||||
temp.addNpcIdForSkillId(SKILL_GOLDEN_SPICE, 18892);
|
|
||||||
GROWTH_CAPABLE_MONSTERS.put(18890, temp);
|
|
||||||
|
|
||||||
temp = new GrowthCapableMob(25, 2, 18871);
|
|
||||||
temp.addNpcIdForSkillId(SKILL_CRYSTAL_SPICE, 18893);
|
|
||||||
GROWTH_CAPABLE_MONSTERS.put(18891, temp);
|
|
||||||
|
|
||||||
// Grendel
|
|
||||||
temp = new GrowthCapableMob(100, 0, 18872);
|
|
||||||
temp.addNpcIdForSkillId(SKILL_GOLDEN_SPICE, 18895);
|
|
||||||
temp.addNpcIdForSkillId(SKILL_CRYSTAL_SPICE, 18896);
|
|
||||||
temp.addNpcIdForSkillId(SKILL_BLESSED_GOLDEN_SPICE, 18872);
|
|
||||||
temp.addNpcIdForSkillId(SKILL_BLESSED_CRYSTAL_SPICE, 18872);
|
|
||||||
temp.addNpcIdForSkillId(SKILL_SGRADE_GOLDEN_SPICE, 18899);
|
|
||||||
temp.addNpcIdForSkillId(SKILL_SGRADE_CRYSTAL_SPICE, 18900);
|
|
||||||
GROWTH_CAPABLE_MONSTERS.put(18894, temp);
|
|
||||||
|
|
||||||
temp = new GrowthCapableMob(40, 1, 18872);
|
|
||||||
temp.addNpcIdForSkillId(SKILL_GOLDEN_SPICE, 18897);
|
|
||||||
GROWTH_CAPABLE_MONSTERS.put(18895, temp);
|
|
||||||
|
|
||||||
temp = new GrowthCapableMob(40, 1, 18872);
|
|
||||||
temp.addNpcIdForSkillId(SKILL_CRYSTAL_SPICE, 18898);
|
|
||||||
GROWTH_CAPABLE_MONSTERS.put(18896, temp);
|
|
||||||
|
|
||||||
temp = new GrowthCapableMob(25, 2, 18872);
|
|
||||||
temp.addNpcIdForSkillId(SKILL_GOLDEN_SPICE, 18899);
|
|
||||||
GROWTH_CAPABLE_MONSTERS.put(18897, temp);
|
|
||||||
|
|
||||||
temp = new GrowthCapableMob(25, 2, 18872);
|
|
||||||
temp.addNpcIdForSkillId(SKILL_CRYSTAL_SPICE, 18900);
|
|
||||||
GROWTH_CAPABLE_MONSTERS.put(18898, temp);
|
|
||||||
|
|
||||||
// Tamed beasts data
|
|
||||||
TAMED_BEAST_DATA.add(new TamedBeast("%name% of Focus", new SkillHolder(6432, 1), new SkillHolder(6668, 1)));
|
|
||||||
TAMED_BEAST_DATA.add(new TamedBeast("%name% of Guiding", new SkillHolder(6433, 1), new SkillHolder(6670, 1)));
|
|
||||||
TAMED_BEAST_DATA.add(new TamedBeast("%name% of Swifth", new SkillHolder(6434, 1), new SkillHolder(6667, 1)));
|
|
||||||
TAMED_BEAST_DATA.add(new TamedBeast("Berserker %name%", new SkillHolder(6671, 1)));
|
|
||||||
TAMED_BEAST_DATA.add(new TamedBeast("%name% of Protect", new SkillHolder(6669, 1), new SkillHolder(6672, 1)));
|
|
||||||
TAMED_BEAST_DATA.add(new TamedBeast("%name% of Vigor", new SkillHolder(6431, 1), new SkillHolder(6666, 1)));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void spawnNext(L2Npc npc, L2PcInstance player, int nextNpcId, int food)
|
|
||||||
{
|
|
||||||
// remove the feedinfo of the mob that got despawned, if any
|
|
||||||
if (FEED_INFO.containsKey(npc.getObjectId()))
|
|
||||||
{
|
|
||||||
if (FEED_INFO.get(npc.getObjectId()) == player.getObjectId())
|
|
||||||
{
|
|
||||||
FEED_INFO.remove(npc.getObjectId());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// despawn the old mob
|
|
||||||
// TODO: same code? FIXED?
|
|
||||||
/*
|
|
||||||
* if (_GrowthCapableMobs.get(npc.getNpcId()).getGrowthLevel() == 0) { npc.deleteMe(); } else {
|
|
||||||
*/
|
|
||||||
npc.deleteMe();
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if this is finally a trained mob, then despawn any other trained mobs that the
|
|
||||||
// player might have and initialize the Tamed Beast.
|
|
||||||
if (Util.contains(TAMED_BEASTS, nextNpcId))
|
|
||||||
{
|
|
||||||
final L2TamedBeastInstance nextNpc = new L2TamedBeastInstance(nextNpcId, player, food, npc.getX(), npc.getY(), npc.getZ(), true);
|
|
||||||
|
|
||||||
TamedBeast beast = TAMED_BEAST_DATA.get(getRandom(TAMED_BEAST_DATA.size()));
|
|
||||||
String name = beast.getName();
|
|
||||||
switch (nextNpcId)
|
|
||||||
{
|
|
||||||
case 18869:
|
|
||||||
name = name.replace("%name%", "Alpine Kookaburra");
|
|
||||||
break;
|
|
||||||
case 18870:
|
|
||||||
name = name.replace("%name%", "Alpine Cougar");
|
|
||||||
break;
|
|
||||||
case 18871:
|
|
||||||
name = name.replace("%name%", "Alpine Buffalo");
|
|
||||||
break;
|
|
||||||
case 18872:
|
|
||||||
name = name.replace("%name%", "Alpine Grendel");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
nextNpc.setName(name);
|
|
||||||
nextNpc.broadcastPacket(new NpcInfo(nextNpc));
|
|
||||||
nextNpc.setRunning();
|
|
||||||
|
|
||||||
SkillData st = SkillData.getInstance();
|
|
||||||
for (SkillHolder sh : beast.getSkills())
|
|
||||||
{
|
|
||||||
nextNpc.addBeastSkill(st.getSkill(sh.getSkillId(), sh.getSkillLvl()));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Q00020_BringUpWithLove.checkJewelOfInnocence(player);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// if not trained, the newly spawned mob will automatically be agro against its feeder
|
|
||||||
// (what happened to "never bite the hand that feeds you" anyway?!)
|
|
||||||
L2Attackable nextNpc = (L2Attackable) addSpawn(nextNpcId, npc);
|
|
||||||
|
|
||||||
// register the player in the feedinfo for the mob that just spawned
|
|
||||||
FEED_INFO.put(nextNpc.getObjectId(), player.getObjectId());
|
|
||||||
nextNpc.setRunning();
|
|
||||||
nextNpc.addDamageHate(player, 0, 99999);
|
|
||||||
nextNpc.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, player);
|
|
||||||
|
|
||||||
player.setTarget(nextNpc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String onSkillSee(L2Npc npc, L2PcInstance caster, Skill skill, L2Object[] targets, boolean isSummon)
|
|
||||||
{
|
|
||||||
// this behavior is only run when the target of skill is the passed npc (chest)
|
|
||||||
// i.e. when the player is attempting to open the chest using a skill
|
|
||||||
if (!Util.contains(targets, npc))
|
|
||||||
{
|
|
||||||
return super.onSkillSee(npc, caster, skill, targets, isSummon);
|
|
||||||
}
|
|
||||||
// gather some values on local variables
|
|
||||||
int npcId = npc.getId();
|
|
||||||
int skillId = skill.getId();
|
|
||||||
// check if the npc and skills used are valid for this script. Exit if invalid.
|
|
||||||
if (!Util.contains(FEEDABLE_BEASTS, npcId) || ((skillId != SKILL_GOLDEN_SPICE) && (skillId != SKILL_CRYSTAL_SPICE) && (skillId != SKILL_BLESSED_GOLDEN_SPICE) && (skillId != SKILL_BLESSED_CRYSTAL_SPICE) && (skillId != SKILL_SGRADE_GOLDEN_SPICE) && (skillId != SKILL_SGRADE_CRYSTAL_SPICE)))
|
|
||||||
{
|
|
||||||
return super.onSkillSee(npc, caster, skill, targets, isSummon);
|
|
||||||
}
|
|
||||||
|
|
||||||
// first gather some values on local variables
|
|
||||||
int objectId = npc.getObjectId();
|
|
||||||
int growthLevel = 3; // if a mob is in FEEDABLE_BEASTS but not in _GrowthCapableMobs, then it's at max growth (3)
|
|
||||||
if (GROWTH_CAPABLE_MONSTERS.containsKey(npcId))
|
|
||||||
{
|
|
||||||
growthLevel = GROWTH_CAPABLE_MONSTERS.get(npcId).getGrowthLevel();
|
|
||||||
}
|
|
||||||
|
|
||||||
// prevent exploit which allows 2 players to simultaneously raise the same 0-growth beast
|
|
||||||
// If the mob is at 0th level (when it still listens to all feeders) lock it to the first feeder!
|
|
||||||
if ((growthLevel == 0) && FEED_INFO.containsKey(objectId))
|
|
||||||
{
|
|
||||||
return super.onSkillSee(npc, caster, skill, targets, isSummon);
|
|
||||||
}
|
|
||||||
|
|
||||||
FEED_INFO.put(objectId, caster.getObjectId());
|
|
||||||
|
|
||||||
// display the social action of the beast eating the food.
|
|
||||||
npc.broadcastSocialAction(2);
|
|
||||||
|
|
||||||
int food = 0;
|
|
||||||
if ((skillId == SKILL_GOLDEN_SPICE) || (skillId == SKILL_BLESSED_GOLDEN_SPICE))
|
|
||||||
{
|
|
||||||
food = GOLDEN_SPICE;
|
|
||||||
}
|
|
||||||
else if ((skillId == SKILL_CRYSTAL_SPICE) || (skillId == SKILL_BLESSED_CRYSTAL_SPICE))
|
|
||||||
{
|
|
||||||
food = CRYSTAL_SPICE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// if this pet can't grow, it's all done.
|
|
||||||
if (GROWTH_CAPABLE_MONSTERS.containsKey(npcId))
|
|
||||||
{
|
|
||||||
// do nothing if this mob doesn't eat the specified food (food gets consumed but has no effect).
|
|
||||||
int newNpcId = GROWTH_CAPABLE_MONSTERS.get(npcId).getLeveledNpcId(skillId);
|
|
||||||
if (newNpcId == -1)
|
|
||||||
{
|
|
||||||
if (growthLevel == 0)
|
|
||||||
{
|
|
||||||
FEED_INFO.remove(objectId);
|
|
||||||
npc.setRunning();
|
|
||||||
((L2Attackable) npc).addDamageHate(caster, 0, 1);
|
|
||||||
npc.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, caster);
|
|
||||||
}
|
|
||||||
return super.onSkillSee(npc, caster, skill, targets, isSummon);
|
|
||||||
}
|
|
||||||
else if ((growthLevel > 0) && (FEED_INFO.get(objectId) != caster.getObjectId()))
|
|
||||||
{
|
|
||||||
// check if this is the same player as the one who raised it from growth 0.
|
|
||||||
// if no, then do not allow a chance to raise the pet (food gets consumed but has no effect).
|
|
||||||
return super.onSkillSee(npc, caster, skill, targets, isSummon);
|
|
||||||
}
|
|
||||||
spawnNext(npc, caster, newNpcId, food);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
caster.sendMessage("The beast spit out the feed instead of eating it.");
|
|
||||||
npc.dropItem(caster, food, 1);
|
|
||||||
}
|
|
||||||
return super.onSkillSee(npc, caster, skill, targets, isSummon);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
|
|
||||||
{
|
|
||||||
// remove the feedinfo of the mob that got killed, if any
|
|
||||||
if (FEED_INFO.containsKey(npc.getObjectId()))
|
|
||||||
{
|
|
||||||
FEED_INFO.remove(npc.getObjectId());
|
|
||||||
}
|
|
||||||
return super.onKill(npc, killer, isSummon);
|
|
||||||
}
|
|
||||||
|
|
||||||
// all mobs that grow by eating
|
|
||||||
private static class GrowthCapableMob
|
|
||||||
{
|
|
||||||
private final int _chance;
|
|
||||||
private final int _growthLevel;
|
|
||||||
private final int _tameNpcId;
|
|
||||||
private final Map<Integer, Integer> _skillSuccessNpcIdList = new HashMap<>();
|
|
||||||
|
|
||||||
public GrowthCapableMob(int chance, int growthLevel, int tameNpcId)
|
|
||||||
{
|
|
||||||
_chance = chance;
|
|
||||||
_growthLevel = growthLevel;
|
|
||||||
_tameNpcId = tameNpcId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addNpcIdForSkillId(int skillId, int npcId)
|
|
||||||
{
|
|
||||||
_skillSuccessNpcIdList.put(skillId, npcId);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getGrowthLevel()
|
|
||||||
{
|
|
||||||
return _growthLevel;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getLeveledNpcId(int skillId)
|
|
||||||
{
|
|
||||||
if (!_skillSuccessNpcIdList.containsKey(skillId))
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
else if ((skillId == SKILL_BLESSED_GOLDEN_SPICE) || (skillId == SKILL_BLESSED_CRYSTAL_SPICE) || (skillId == SKILL_SGRADE_GOLDEN_SPICE) || (skillId == SKILL_SGRADE_CRYSTAL_SPICE))
|
|
||||||
{
|
|
||||||
if (getRandom(100) < SPECIAL_SPICE_CHANCES[0])
|
|
||||||
{
|
|
||||||
if (getRandom(100) < SPECIAL_SPICE_CHANCES[1])
|
|
||||||
{
|
|
||||||
return _skillSuccessNpcIdList.get(skillId);
|
|
||||||
}
|
|
||||||
else if ((skillId == SKILL_BLESSED_GOLDEN_SPICE) || (skillId == SKILL_SGRADE_GOLDEN_SPICE))
|
|
||||||
{
|
|
||||||
return _skillSuccessNpcIdList.get(SKILL_GOLDEN_SPICE);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return _skillSuccessNpcIdList.get(SKILL_CRYSTAL_SPICE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
else if ((_growthLevel == 2) && (getRandom(100) < TAME_CHANCE))
|
|
||||||
{
|
|
||||||
return _tameNpcId;
|
|
||||||
}
|
|
||||||
else if (getRandom(100) < _chance)
|
|
||||||
{
|
|
||||||
return _skillSuccessNpcIdList.get(skillId);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class TamedBeast
|
|
||||||
{
|
|
||||||
private final String name;
|
|
||||||
private final SkillHolder[] sh;
|
|
||||||
|
|
||||||
public TamedBeast(String beastName, SkillHolder... holders)
|
|
||||||
{
|
|
||||||
name = beastName;
|
|
||||||
sh = holders;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getName()
|
|
||||||
{
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SkillHolder[] getSkills()
|
|
||||||
{
|
|
||||||
return sh;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void main(String[] args)
|
|
||||||
{
|
|
||||||
new BeastFarm();
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,246 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2004-2015 L2J DataPack
|
|
||||||
*
|
|
||||||
* This file is part of L2J DataPack.
|
|
||||||
*
|
|
||||||
* L2J DataPack 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.
|
|
||||||
*
|
|
||||||
* L2J DataPack 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.group_template;
|
|
||||||
|
|
||||||
import ai.npc.AbstractNpcAI;
|
|
||||||
|
|
||||||
import com.l2jserver.gameserver.ThreadPoolManager;
|
|
||||||
import com.l2jserver.gameserver.datatables.SkillData;
|
|
||||||
import com.l2jserver.gameserver.instancemanager.ZoneManager;
|
|
||||||
import com.l2jserver.gameserver.model.Location;
|
|
||||||
import com.l2jserver.gameserver.model.actor.L2Character;
|
|
||||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
|
||||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
|
||||||
import com.l2jserver.gameserver.model.skills.Skill;
|
|
||||||
import com.l2jserver.gameserver.model.zone.type.L2EffectZone;
|
|
||||||
import com.l2jserver.gameserver.network.SystemMessageId;
|
|
||||||
import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
|
|
||||||
import com.l2jserver.gameserver.util.Util;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Dummy AI for spawns/respawns only for testing.
|
|
||||||
* @author Gnacik
|
|
||||||
*/
|
|
||||||
public final class DenOfEvil extends AbstractNpcAI
|
|
||||||
{
|
|
||||||
// private static final int _buffer_id = 32656;
|
|
||||||
protected static final int[] EYE_IDS =
|
|
||||||
{
|
|
||||||
18812,
|
|
||||||
18813,
|
|
||||||
18814
|
|
||||||
};
|
|
||||||
private static final int SKILL_ID = 6150; // others +2
|
|
||||||
|
|
||||||
private static final Location[] EYE_SPAWNS =
|
|
||||||
{
|
|
||||||
new Location(71544, -129400, -3360, 16472),
|
|
||||||
new Location(70954, -128854, -3360, 16),
|
|
||||||
new Location(72145, -128847, -3368, 32832),
|
|
||||||
new Location(76147, -128372, -3144, 16152),
|
|
||||||
new Location(71573, -128309, -3360, 49152),
|
|
||||||
new Location(75211, -127441, -3152, 0),
|
|
||||||
new Location(77005, -127406, -3144, 32784),
|
|
||||||
new Location(75965, -126486, -3144, 49120),
|
|
||||||
new Location(70972, -126429, -3016, 19208),
|
|
||||||
new Location(69916, -125838, -3024, 2840),
|
|
||||||
new Location(71658, -125459, -3016, 35136),
|
|
||||||
new Location(70605, -124646, -3040, 52104),
|
|
||||||
new Location(67283, -123237, -2912, 12376),
|
|
||||||
new Location(68383, -122754, -2912, 27904),
|
|
||||||
new Location(74137, -122733, -3024, 13272),
|
|
||||||
new Location(66736, -122007, -2896, 60576),
|
|
||||||
new Location(73289, -121769, -3024, 1024),
|
|
||||||
new Location(67894, -121491, -2912, 43872),
|
|
||||||
new Location(75530, -121477, -3008, 34424),
|
|
||||||
new Location(74117, -120459, -3024, 52344),
|
|
||||||
new Location(69608, -119855, -2534, 17251),
|
|
||||||
new Location(71014, -119027, -2520, 31904),
|
|
||||||
new Location(68944, -118964, -2527, 59874),
|
|
||||||
new Location(62261, -118263, -3072, 12888),
|
|
||||||
new Location(70300, -117942, -2528, 46208),
|
|
||||||
new Location(74312, -117583, -2272, 15280),
|
|
||||||
new Location(63276, -117409, -3064, 24760),
|
|
||||||
new Location(68104, -117192, -2168, 15888),
|
|
||||||
new Location(73758, -116945, -2216, 0),
|
|
||||||
new Location(74944, -116858, -2220, 30892),
|
|
||||||
new Location(61715, -116623, -3064, 59888),
|
|
||||||
new Location(69140, -116464, -2168, 28952),
|
|
||||||
new Location(67311, -116374, -2152, 1280),
|
|
||||||
new Location(62459, -116370, -3064, 48624),
|
|
||||||
new Location(74475, -116260, -2216, 47456),
|
|
||||||
new Location(68333, -115015, -2168, 45136),
|
|
||||||
new Location(68280, -108129, -1160, 17992),
|
|
||||||
new Location(62983, -107259, -2384, 12552),
|
|
||||||
new Location(67062, -107125, -1144, 64008),
|
|
||||||
new Location(68893, -106954, -1160, 36704),
|
|
||||||
new Location(63848, -106771, -2384, 32784),
|
|
||||||
new Location(62372, -106514, -2384, 0),
|
|
||||||
new Location(67838, -106143, -1160, 51232),
|
|
||||||
new Location(62905, -106109, -2384, 51288)
|
|
||||||
};
|
|
||||||
|
|
||||||
private final static boolean DEBUG = false;
|
|
||||||
|
|
||||||
private DenOfEvil()
|
|
||||||
{
|
|
||||||
super(DenOfEvil.class.getSimpleName(), "ai/group_template");
|
|
||||||
addKillId(EYE_IDS);
|
|
||||||
addSpawnId(EYE_IDS);
|
|
||||||
for (Location loc : EYE_SPAWNS)
|
|
||||||
{
|
|
||||||
addSpawn(EYE_IDS[getRandom(EYE_IDS.length)], loc, false, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private int getSkillIdByNpcId(int npcId)
|
|
||||||
{
|
|
||||||
int diff = npcId - EYE_IDS[0];
|
|
||||||
diff *= 2;
|
|
||||||
return SKILL_ID + diff;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String onSpawn(L2Npc npc)
|
|
||||||
{
|
|
||||||
npc.disableCoreAI(true);
|
|
||||||
npc.setIsImmobilized(true);
|
|
||||||
L2EffectZone zone = ZoneManager.getInstance().getZone(npc, L2EffectZone.class);
|
|
||||||
if (zone == null)
|
|
||||||
{
|
|
||||||
if (DEBUG)
|
|
||||||
{
|
|
||||||
_log.warning("NPC " + npc + " spawned outside of L2EffectZone, check your zone coords! X:" + npc.getX() + " Y:" + npc.getY() + " Z:" + npc.getZ());
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
int skillId = getSkillIdByNpcId(npc.getId());
|
|
||||||
int skillLevel = zone.getSkillLevel(skillId);
|
|
||||||
zone.addSkill(skillId, skillLevel + 1);
|
|
||||||
if (skillLevel == 3) // 3+1=4
|
|
||||||
{
|
|
||||||
ThreadPoolManager.getInstance().scheduleAi(new KashaDestruction(zone), 2 * 60 * 1000l);
|
|
||||||
zone.broadcastPacket(SystemMessage.getSystemMessage(SystemMessageId.DEFEAT_KASHA_S_EYES_TO_LIFT_THE_GREAT_CURSE));
|
|
||||||
}
|
|
||||||
else if (skillLevel == 2)
|
|
||||||
{
|
|
||||||
zone.broadcastPacket(SystemMessage.getSystemMessage(SystemMessageId.A_GREAT_CURSE_CAN_BE_FELT_FROM_KASHA_S_EYES));
|
|
||||||
}
|
|
||||||
return super.onSpawn(npc);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
|
|
||||||
{
|
|
||||||
ThreadPoolManager.getInstance().scheduleAi(new RespawnNewEye(npc.getLocation()), 15000);
|
|
||||||
L2EffectZone zone = ZoneManager.getInstance().getZone(npc, L2EffectZone.class);
|
|
||||||
if (zone == null)
|
|
||||||
{
|
|
||||||
if (DEBUG)
|
|
||||||
{
|
|
||||||
_log.warning("NPC " + npc + " killed outside of L2EffectZone, check your zone coords! X:" + npc.getX() + " Y:" + npc.getY() + " Z:" + npc.getZ());
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
int skillId = getSkillIdByNpcId(npc.getId());
|
|
||||||
int skillLevel = zone.getSkillLevel(skillId);
|
|
||||||
zone.addSkill(skillId, skillLevel - 1);
|
|
||||||
return super.onKill(npc, killer, isSummon);
|
|
||||||
}
|
|
||||||
|
|
||||||
private class RespawnNewEye implements Runnable
|
|
||||||
{
|
|
||||||
private final Location _loc;
|
|
||||||
|
|
||||||
public RespawnNewEye(Location loc)
|
|
||||||
{
|
|
||||||
_loc = loc;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run()
|
|
||||||
{
|
|
||||||
addSpawn(EYE_IDS[getRandom(EYE_IDS.length)], _loc, false, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class KashaDestruction implements Runnable
|
|
||||||
{
|
|
||||||
L2EffectZone _zone;
|
|
||||||
|
|
||||||
public KashaDestruction(L2EffectZone zone)
|
|
||||||
{
|
|
||||||
_zone = zone;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run()
|
|
||||||
{
|
|
||||||
for (int i = SKILL_ID; i <= (SKILL_ID + 4); i = i + 2)
|
|
||||||
{
|
|
||||||
// test 3 skills if some is lvl 4
|
|
||||||
if (_zone.getSkillLevel(i) > 3)
|
|
||||||
{
|
|
||||||
destroyZone();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void destroyZone()
|
|
||||||
{
|
|
||||||
for (L2Character character : _zone.getCharactersInside())
|
|
||||||
{
|
|
||||||
if (character == null)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (character.isPlayable())
|
|
||||||
{
|
|
||||||
Skill skill = SkillData.getInstance().getSkill(6149, 1);
|
|
||||||
skill.applyEffects(character, character);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (character.doDie(null)) // mobs die
|
|
||||||
{
|
|
||||||
if (character.isNpc())
|
|
||||||
{
|
|
||||||
// respawn eye
|
|
||||||
L2Npc npc = (L2Npc) character;
|
|
||||||
if (Util.contains(EYE_IDS, npc.getId()))
|
|
||||||
{
|
|
||||||
ThreadPoolManager.getInstance().scheduleAi(new RespawnNewEye(npc.getLocation()), 15000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (int i = SKILL_ID; i <= (SKILL_ID + 4); i = i + 2)
|
|
||||||
{
|
|
||||||
_zone.removeSkill(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void main(String[] args)
|
|
||||||
{
|
|
||||||
new DenOfEvil();
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,627 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2004-2015 L2J DataPack
|
|
||||||
*
|
|
||||||
* This file is part of L2J DataPack.
|
|
||||||
*
|
|
||||||
* L2J DataPack 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.
|
|
||||||
*
|
|
||||||
* L2J DataPack 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.group_template;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
|
||||||
|
|
||||||
import ai.npc.AbstractNpcAI;
|
|
||||||
|
|
||||||
import com.l2jserver.gameserver.ai.CtrlIntention;
|
|
||||||
import com.l2jserver.gameserver.enums.ChatType;
|
|
||||||
import com.l2jserver.gameserver.model.L2Object;
|
|
||||||
import com.l2jserver.gameserver.model.actor.L2Attackable;
|
|
||||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
|
||||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
|
||||||
import com.l2jserver.gameserver.model.actor.instance.L2TamedBeastInstance;
|
|
||||||
import com.l2jserver.gameserver.model.skills.Skill;
|
|
||||||
import com.l2jserver.gameserver.network.NpcStringId;
|
|
||||||
import com.l2jserver.gameserver.network.serverpackets.NpcSay;
|
|
||||||
import com.l2jserver.gameserver.util.Util;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Growth-capable mobs: Polymorphing upon successful feeding.
|
|
||||||
* @author Fulminus
|
|
||||||
*/
|
|
||||||
public final class FeedableBeasts extends AbstractNpcAI
|
|
||||||
{
|
|
||||||
private static final int GOLDEN_SPICE = 6643;
|
|
||||||
private static final int CRYSTAL_SPICE = 6644;
|
|
||||||
private static final int SKILL_GOLDEN_SPICE = 2188;
|
|
||||||
private static final int SKILL_CRYSTAL_SPICE = 2189;
|
|
||||||
private static final int FOODSKILLDIFF = GOLDEN_SPICE - SKILL_GOLDEN_SPICE;
|
|
||||||
// Tamed Wild Beasts
|
|
||||||
private static final int TRAINED_BUFFALO1 = 16013;
|
|
||||||
private static final int TRAINED_BUFFALO2 = 16014;
|
|
||||||
private static final int TRAINED_COUGAR1 = 16015;
|
|
||||||
private static final int TRAINED_COUGAR2 = 16016;
|
|
||||||
private static final int TRAINED_KOOKABURRA1 = 16017;
|
|
||||||
private static final int TRAINED_KOOKABURRA2 = 16018;
|
|
||||||
// private static final int TRAINED_TINY_BABY_BUFFALO = 16020; // TODO: Implement.
|
|
||||||
// private static final int TRAINED_TINY_BABY_COUGAR = 16022; // TODO: Implement.
|
|
||||||
// private static final int TRAINED_TINY_BABY_KOOKABURRA = 16024; // TODO: Implement.
|
|
||||||
// @formatter:off
|
|
||||||
private static final int[] TAMED_BEASTS =
|
|
||||||
{
|
|
||||||
TRAINED_BUFFALO1, TRAINED_BUFFALO2, TRAINED_COUGAR1, TRAINED_COUGAR2, TRAINED_KOOKABURRA1, TRAINED_KOOKABURRA2
|
|
||||||
};
|
|
||||||
// all mobs that can eat...
|
|
||||||
private static final int[] FEEDABLE_BEASTS =
|
|
||||||
{
|
|
||||||
21451, 21452, 21453, 21454, 21455, 21456, 21457, 21458, 21459, 21460,
|
|
||||||
21461, 21462, 21463, 21464, 21465, 21466, 21467, 21468, 21469, 21470,
|
|
||||||
21471, 21472, 21473, 21474, 21475, 21476, 21477, 21478, 21479, 21480,
|
|
||||||
21481, 21482, 21483, 21484, 21485, 21486, 21487, 21488, 21489, 21490,
|
|
||||||
21491, 21492, 21493, 21494, 21495, 21496, 21497, 21498, 21499, 21500,
|
|
||||||
21501, 21502, 21503, 21504, 21505, 21506, 21507, 21824, 21825, 21826,
|
|
||||||
21827, 21828, 21829, TRAINED_BUFFALO1, TRAINED_BUFFALO2, TRAINED_COUGAR1, TRAINED_COUGAR2, TRAINED_KOOKABURRA1, TRAINED_KOOKABURRA2
|
|
||||||
};
|
|
||||||
// @formatter:on
|
|
||||||
|
|
||||||
private static final Map<Integer, Integer> MAD_COW_POLYMORPH = new HashMap<>();
|
|
||||||
static
|
|
||||||
{
|
|
||||||
MAD_COW_POLYMORPH.put(21824, 21468);
|
|
||||||
MAD_COW_POLYMORPH.put(21825, 21469);
|
|
||||||
MAD_COW_POLYMORPH.put(21826, 21487);
|
|
||||||
MAD_COW_POLYMORPH.put(21827, 21488);
|
|
||||||
MAD_COW_POLYMORPH.put(21828, 21506);
|
|
||||||
MAD_COW_POLYMORPH.put(21829, 21507);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final NpcStringId[][] TEXT =
|
|
||||||
{
|
|
||||||
{
|
|
||||||
NpcStringId.WHAT_DID_YOU_JUST_DO_TO_ME,
|
|
||||||
NpcStringId.ARE_YOU_TRYING_TO_TAME_ME_DON_T_DO_THAT,
|
|
||||||
NpcStringId.DON_T_GIVE_SUCH_A_THING_YOU_CAN_ENDANGER_YOURSELF,
|
|
||||||
NpcStringId.YUCK_WHAT_IS_THIS_IT_TASTES_TERRIBLE,
|
|
||||||
NpcStringId.I_M_HUNGRY_GIVE_ME_A_LITTLE_MORE_PLEASE,
|
|
||||||
NpcStringId.WHAT_IS_THIS_IS_THIS_EDIBLE,
|
|
||||||
NpcStringId.DON_T_WORRY_ABOUT_ME,
|
|
||||||
NpcStringId.THANK_YOU_THAT_WAS_DELICIOUS,
|
|
||||||
NpcStringId.I_THINK_I_AM_STARTING_TO_LIKE_YOU,
|
|
||||||
NpcStringId.EEEEEK_EEEEEK
|
|
||||||
},
|
|
||||||
{
|
|
||||||
NpcStringId.DON_T_KEEP_TRYING_TO_TAME_ME_I_DON_T_WANT_TO_BE_TAMED,
|
|
||||||
NpcStringId.IT_IS_JUST_FOOD_TO_ME_ALTHOUGH_IT_MAY_ALSO_BE_YOUR_HAND,
|
|
||||||
NpcStringId.IF_I_KEEP_EATING_LIKE_THIS_WON_T_I_BECOME_FAT_CHOMP_CHOMP,
|
|
||||||
NpcStringId.WHY_DO_YOU_KEEP_FEEDING_ME,
|
|
||||||
NpcStringId.DON_T_TRUST_ME_I_M_AFRAID_I_MAY_BETRAY_YOU_LATER
|
|
||||||
},
|
|
||||||
{
|
|
||||||
NpcStringId.GRRRRR,
|
|
||||||
NpcStringId.YOU_BROUGHT_THIS_UPON_YOURSELF,
|
|
||||||
NpcStringId.I_FEEL_STRANGE_I_KEEP_HAVING_THESE_EVIL_THOUGHTS,
|
|
||||||
NpcStringId.ALAS_SO_THIS_IS_HOW_IT_ALL_ENDS,
|
|
||||||
NpcStringId.I_DON_T_FEEL_SO_GOOD_OH_MY_MIND_IS_VERY_TROUBLED
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
private static final NpcStringId[] TAMED_TEXT =
|
|
||||||
{
|
|
||||||
NpcStringId.S1_SO_WHAT_DO_YOU_THINK_IT_IS_LIKE_TO_BE_TAMED,
|
|
||||||
NpcStringId.S1_WHENEVER_I_SEE_SPICE_I_THINK_I_WILL_MISS_YOUR_HAND_THAT_USED_TO_FEED_IT_TO_ME,
|
|
||||||
NpcStringId.S1_DON_T_GO_TO_THE_VILLAGE_I_DON_T_HAVE_THE_STRENGTH_TO_FOLLOW_YOU,
|
|
||||||
NpcStringId.THANK_YOU_FOR_TRUSTING_ME_S1_I_HOPE_I_WILL_BE_HELPFUL_TO_YOU,
|
|
||||||
NpcStringId.S1_WILL_I_BE_ABLE_TO_HELP_YOU,
|
|
||||||
NpcStringId.I_GUESS_IT_S_JUST_MY_ANIMAL_MAGNETISM,
|
|
||||||
NpcStringId.TOO_MUCH_SPICY_FOOD_MAKES_ME_SWEAT_LIKE_A_BEAST,
|
|
||||||
NpcStringId.ANIMALS_NEED_LOVE_TOO
|
|
||||||
};
|
|
||||||
|
|
||||||
private static final Map<Integer, Integer> FEED_INFO = new ConcurrentHashMap<>();
|
|
||||||
private static final Map<Integer, GrowthCapableMob> GROWTH_CAPABLE_MONSTERS = new HashMap<>();
|
|
||||||
|
|
||||||
// all mobs that grow by eating
|
|
||||||
private static class GrowthCapableMob
|
|
||||||
{
|
|
||||||
private final int _growthLevel;
|
|
||||||
private final int _chance;
|
|
||||||
|
|
||||||
private final Map<Integer, int[][]> _spiceToMob = new HashMap<>();
|
|
||||||
|
|
||||||
public GrowthCapableMob(int growthLevel, int chance)
|
|
||||||
{
|
|
||||||
_growthLevel = growthLevel;
|
|
||||||
_chance = chance;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addMobs(int spice, int[][] Mobs)
|
|
||||||
{
|
|
||||||
_spiceToMob.put(spice, Mobs);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Integer getMob(int spice, int mobType, int classType)
|
|
||||||
{
|
|
||||||
if (_spiceToMob.containsKey(spice))
|
|
||||||
{
|
|
||||||
return _spiceToMob.get(spice)[mobType][classType];
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Integer getRandomMob(int spice)
|
|
||||||
{
|
|
||||||
int[][] temp;
|
|
||||||
temp = _spiceToMob.get(spice);
|
|
||||||
int rand = getRandom(temp[0].length);
|
|
||||||
return temp[0][rand];
|
|
||||||
}
|
|
||||||
|
|
||||||
public Integer getChance()
|
|
||||||
{
|
|
||||||
return _chance;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Integer getGrowthLevel()
|
|
||||||
{
|
|
||||||
return _growthLevel;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private FeedableBeasts()
|
|
||||||
{
|
|
||||||
super(FeedableBeasts.class.getSimpleName(), "ai/group_template");
|
|
||||||
addKillId(FEEDABLE_BEASTS);
|
|
||||||
addSkillSeeId(FEEDABLE_BEASTS);
|
|
||||||
|
|
||||||
// TODO: no grendels?
|
|
||||||
GrowthCapableMob temp;
|
|
||||||
|
|
||||||
//@formatter:off
|
|
||||||
final int[][] Kookabura_0_Gold = {{ 21452, 21453, 21454, 21455 }};
|
|
||||||
final int[][] Kookabura_0_Crystal = {{ 21456, 21457, 21458, 21459 }};
|
|
||||||
final int[][] Kookabura_1_Gold_1= {{ 21460, 21462 }};
|
|
||||||
final int[][] Kookabura_1_Gold_2 = {{ 21461, 21463 }};
|
|
||||||
final int[][] Kookabura_1_Crystal_1 = {{ 21464, 21466 }};
|
|
||||||
final int[][] Kookabura_1_Crystal_2 = {{ 21465, 21467 }};
|
|
||||||
final int[][] Kookabura_2_1 = {{ 21468, 21824}, { TRAINED_KOOKABURRA1, TRAINED_KOOKABURRA2 }};
|
|
||||||
final int[][] Kookabura_2_2 = {{ 21469, 21825}, { TRAINED_KOOKABURRA1, TRAINED_KOOKABURRA2 }};
|
|
||||||
|
|
||||||
final int[][] Buffalo_0_Gold = {{ 21471, 21472, 21473, 21474 }};
|
|
||||||
final int[][] Buffalo_0_Crystal = {{ 21475, 21476, 21477, 21478 }};
|
|
||||||
final int[][] Buffalo_1_Gold_1 = {{ 21479, 21481 }};
|
|
||||||
final int[][] Buffalo_1_Gold_2 = {{ 21481, 21482 }};
|
|
||||||
final int[][] Buffalo_1_Crystal_1 = {{ 21483, 21485 }};
|
|
||||||
final int[][] Buffalo_1_Crystal_2 = {{ 21484, 21486 }};
|
|
||||||
final int[][] Buffalo_2_1 = {{ 21487, 21826}, {TRAINED_BUFFALO1, TRAINED_BUFFALO2 }};
|
|
||||||
final int[][] Buffalo_2_2 = {{ 21488, 21827}, {TRAINED_BUFFALO1, TRAINED_BUFFALO2 }};
|
|
||||||
|
|
||||||
final int[][] Cougar_0_Gold = {{ 21490, 21491, 21492, 21493 }};
|
|
||||||
final int[][] Cougar_0_Crystal = {{ 21494, 21495, 21496, 21497 }};
|
|
||||||
final int[][] Cougar_1_Gold_1 = {{ 21498, 21500 }};
|
|
||||||
final int[][] Cougar_1_Gold_2 = {{ 21499, 21501 }};
|
|
||||||
final int[][] Cougar_1_Crystal_1 = {{ 21502, 21504 }};
|
|
||||||
final int[][] Cougar_1_Crystal_2 = {{ 21503, 21505 }};
|
|
||||||
final int[][] Cougar_2_1 = {{ 21506, 21828 }, { TRAINED_COUGAR1, TRAINED_COUGAR2 }};
|
|
||||||
final int[][] Cougar_2_2 = {{ 21507, 21829 }, { TRAINED_COUGAR1, TRAINED_COUGAR2 }};
|
|
||||||
//@formatter:on
|
|
||||||
|
|
||||||
// Alpen Kookabura
|
|
||||||
temp = new GrowthCapableMob(0, 100);
|
|
||||||
temp.addMobs(GOLDEN_SPICE, Kookabura_0_Gold);
|
|
||||||
temp.addMobs(CRYSTAL_SPICE, Kookabura_0_Crystal);
|
|
||||||
GROWTH_CAPABLE_MONSTERS.put(21451, temp);
|
|
||||||
|
|
||||||
temp = new GrowthCapableMob(1, 40);
|
|
||||||
temp.addMobs(GOLDEN_SPICE, Kookabura_1_Gold_1);
|
|
||||||
GROWTH_CAPABLE_MONSTERS.put(21452, temp);
|
|
||||||
GROWTH_CAPABLE_MONSTERS.put(21454, temp);
|
|
||||||
|
|
||||||
temp = new GrowthCapableMob(1, 40);
|
|
||||||
temp.addMobs(GOLDEN_SPICE, Kookabura_1_Gold_2);
|
|
||||||
GROWTH_CAPABLE_MONSTERS.put(21453, temp);
|
|
||||||
GROWTH_CAPABLE_MONSTERS.put(21455, temp);
|
|
||||||
|
|
||||||
temp = new GrowthCapableMob(1, 40);
|
|
||||||
temp.addMobs(CRYSTAL_SPICE, Kookabura_1_Crystal_1);
|
|
||||||
GROWTH_CAPABLE_MONSTERS.put(21456, temp);
|
|
||||||
GROWTH_CAPABLE_MONSTERS.put(21458, temp);
|
|
||||||
|
|
||||||
temp = new GrowthCapableMob(1, 40);
|
|
||||||
temp.addMobs(CRYSTAL_SPICE, Kookabura_1_Crystal_2);
|
|
||||||
GROWTH_CAPABLE_MONSTERS.put(21457, temp);
|
|
||||||
GROWTH_CAPABLE_MONSTERS.put(21459, temp);
|
|
||||||
|
|
||||||
temp = new GrowthCapableMob(2, 25);
|
|
||||||
temp.addMobs(GOLDEN_SPICE, Kookabura_2_1);
|
|
||||||
GROWTH_CAPABLE_MONSTERS.put(21460, temp);
|
|
||||||
GROWTH_CAPABLE_MONSTERS.put(21462, temp);
|
|
||||||
|
|
||||||
temp = new GrowthCapableMob(2, 25);
|
|
||||||
temp.addMobs(GOLDEN_SPICE, Kookabura_2_2);
|
|
||||||
GROWTH_CAPABLE_MONSTERS.put(21461, temp);
|
|
||||||
GROWTH_CAPABLE_MONSTERS.put(21463, temp);
|
|
||||||
|
|
||||||
temp = new GrowthCapableMob(2, 25);
|
|
||||||
temp.addMobs(CRYSTAL_SPICE, Kookabura_2_1);
|
|
||||||
GROWTH_CAPABLE_MONSTERS.put(21464, temp);
|
|
||||||
GROWTH_CAPABLE_MONSTERS.put(21466, temp);
|
|
||||||
|
|
||||||
temp = new GrowthCapableMob(2, 25);
|
|
||||||
temp.addMobs(CRYSTAL_SPICE, Kookabura_2_2);
|
|
||||||
GROWTH_CAPABLE_MONSTERS.put(21465, temp);
|
|
||||||
GROWTH_CAPABLE_MONSTERS.put(21467, temp);
|
|
||||||
|
|
||||||
// Alpen Buffalo
|
|
||||||
temp = new GrowthCapableMob(0, 100);
|
|
||||||
temp.addMobs(GOLDEN_SPICE, Buffalo_0_Gold);
|
|
||||||
temp.addMobs(CRYSTAL_SPICE, Buffalo_0_Crystal);
|
|
||||||
GROWTH_CAPABLE_MONSTERS.put(21470, temp);
|
|
||||||
|
|
||||||
temp = new GrowthCapableMob(1, 40);
|
|
||||||
temp.addMobs(GOLDEN_SPICE, Buffalo_1_Gold_1);
|
|
||||||
GROWTH_CAPABLE_MONSTERS.put(21471, temp);
|
|
||||||
GROWTH_CAPABLE_MONSTERS.put(21473, temp);
|
|
||||||
|
|
||||||
temp = new GrowthCapableMob(1, 40);
|
|
||||||
temp.addMobs(GOLDEN_SPICE, Buffalo_1_Gold_2);
|
|
||||||
GROWTH_CAPABLE_MONSTERS.put(21472, temp);
|
|
||||||
GROWTH_CAPABLE_MONSTERS.put(21474, temp);
|
|
||||||
|
|
||||||
temp = new GrowthCapableMob(1, 40);
|
|
||||||
temp.addMobs(CRYSTAL_SPICE, Buffalo_1_Crystal_1);
|
|
||||||
GROWTH_CAPABLE_MONSTERS.put(21475, temp);
|
|
||||||
GROWTH_CAPABLE_MONSTERS.put(21477, temp);
|
|
||||||
|
|
||||||
temp = new GrowthCapableMob(1, 40);
|
|
||||||
temp.addMobs(CRYSTAL_SPICE, Buffalo_1_Crystal_2);
|
|
||||||
GROWTH_CAPABLE_MONSTERS.put(21476, temp);
|
|
||||||
GROWTH_CAPABLE_MONSTERS.put(21478, temp);
|
|
||||||
|
|
||||||
temp = new GrowthCapableMob(2, 25);
|
|
||||||
temp.addMobs(GOLDEN_SPICE, Buffalo_2_1);
|
|
||||||
GROWTH_CAPABLE_MONSTERS.put(21479, temp);
|
|
||||||
GROWTH_CAPABLE_MONSTERS.put(21481, temp);
|
|
||||||
|
|
||||||
temp = new GrowthCapableMob(2, 25);
|
|
||||||
temp.addMobs(GOLDEN_SPICE, Buffalo_2_2);
|
|
||||||
GROWTH_CAPABLE_MONSTERS.put(21480, temp);
|
|
||||||
GROWTH_CAPABLE_MONSTERS.put(21482, temp);
|
|
||||||
|
|
||||||
temp = new GrowthCapableMob(2, 25);
|
|
||||||
temp.addMobs(CRYSTAL_SPICE, Buffalo_2_1);
|
|
||||||
GROWTH_CAPABLE_MONSTERS.put(21483, temp);
|
|
||||||
GROWTH_CAPABLE_MONSTERS.put(21485, temp);
|
|
||||||
|
|
||||||
temp = new GrowthCapableMob(2, 25);
|
|
||||||
temp.addMobs(CRYSTAL_SPICE, Buffalo_2_2);
|
|
||||||
GROWTH_CAPABLE_MONSTERS.put(21484, temp);
|
|
||||||
GROWTH_CAPABLE_MONSTERS.put(21486, temp);
|
|
||||||
|
|
||||||
// Alpen Cougar
|
|
||||||
temp = new GrowthCapableMob(0, 100);
|
|
||||||
temp.addMobs(GOLDEN_SPICE, Cougar_0_Gold);
|
|
||||||
temp.addMobs(CRYSTAL_SPICE, Cougar_0_Crystal);
|
|
||||||
GROWTH_CAPABLE_MONSTERS.put(21489, temp);
|
|
||||||
|
|
||||||
temp = new GrowthCapableMob(1, 40);
|
|
||||||
temp.addMobs(GOLDEN_SPICE, Cougar_1_Gold_1);
|
|
||||||
GROWTH_CAPABLE_MONSTERS.put(21490, temp);
|
|
||||||
GROWTH_CAPABLE_MONSTERS.put(21492, temp);
|
|
||||||
|
|
||||||
temp = new GrowthCapableMob(1, 40);
|
|
||||||
temp.addMobs(GOLDEN_SPICE, Cougar_1_Gold_2);
|
|
||||||
GROWTH_CAPABLE_MONSTERS.put(21491, temp);
|
|
||||||
GROWTH_CAPABLE_MONSTERS.put(21493, temp);
|
|
||||||
|
|
||||||
temp = new GrowthCapableMob(1, 40);
|
|
||||||
temp.addMobs(CRYSTAL_SPICE, Cougar_1_Crystal_1);
|
|
||||||
GROWTH_CAPABLE_MONSTERS.put(21494, temp);
|
|
||||||
GROWTH_CAPABLE_MONSTERS.put(21496, temp);
|
|
||||||
|
|
||||||
temp = new GrowthCapableMob(1, 40);
|
|
||||||
temp.addMobs(CRYSTAL_SPICE, Cougar_1_Crystal_2);
|
|
||||||
GROWTH_CAPABLE_MONSTERS.put(21495, temp);
|
|
||||||
GROWTH_CAPABLE_MONSTERS.put(21497, temp);
|
|
||||||
|
|
||||||
temp = new GrowthCapableMob(2, 25);
|
|
||||||
temp.addMobs(GOLDEN_SPICE, Cougar_2_1);
|
|
||||||
GROWTH_CAPABLE_MONSTERS.put(21498, temp);
|
|
||||||
GROWTH_CAPABLE_MONSTERS.put(21500, temp);
|
|
||||||
|
|
||||||
temp = new GrowthCapableMob(2, 25);
|
|
||||||
temp.addMobs(GOLDEN_SPICE, Cougar_2_2);
|
|
||||||
GROWTH_CAPABLE_MONSTERS.put(21499, temp);
|
|
||||||
GROWTH_CAPABLE_MONSTERS.put(21501, temp);
|
|
||||||
|
|
||||||
temp = new GrowthCapableMob(2, 25);
|
|
||||||
temp.addMobs(CRYSTAL_SPICE, Cougar_2_1);
|
|
||||||
GROWTH_CAPABLE_MONSTERS.put(21502, temp);
|
|
||||||
GROWTH_CAPABLE_MONSTERS.put(21504, temp);
|
|
||||||
|
|
||||||
temp = new GrowthCapableMob(2, 25);
|
|
||||||
temp.addMobs(CRYSTAL_SPICE, Cougar_2_2);
|
|
||||||
GROWTH_CAPABLE_MONSTERS.put(21503, temp);
|
|
||||||
GROWTH_CAPABLE_MONSTERS.put(21505, temp);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void spawnNext(L2Npc npc, int growthLevel, L2PcInstance player, int food)
|
|
||||||
{
|
|
||||||
int npcId = npc.getId();
|
|
||||||
int nextNpcId = 0;
|
|
||||||
|
|
||||||
// find the next mob to spawn, based on the current npcId, growthlevel, and food.
|
|
||||||
if (growthLevel == 2)
|
|
||||||
{
|
|
||||||
// if tamed, the mob that will spawn depends on the class type (fighter/mage) of the player!
|
|
||||||
if (getRandom(2) == 0)
|
|
||||||
{
|
|
||||||
if (player.getClassId().isMage())
|
|
||||||
{
|
|
||||||
nextNpcId = GROWTH_CAPABLE_MONSTERS.get(npcId).getMob(food, 1, 1);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
nextNpcId = GROWTH_CAPABLE_MONSTERS.get(npcId).getMob(food, 1, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// if not tamed, there is a small chance that have "mad cow" disease.
|
|
||||||
// that is a stronger-than-normal animal that attacks its feeder
|
|
||||||
if (getRandom(5) == 0)
|
|
||||||
{
|
|
||||||
nextNpcId = GROWTH_CAPABLE_MONSTERS.get(npcId).getMob(food, 0, 1);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
nextNpcId = GROWTH_CAPABLE_MONSTERS.get(npcId).getMob(food, 0, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// all other levels of growth are straight-forward
|
|
||||||
nextNpcId = GROWTH_CAPABLE_MONSTERS.get(npcId).getRandomMob(food);
|
|
||||||
}
|
|
||||||
|
|
||||||
// remove the feedinfo of the mob that got despawned, if any
|
|
||||||
if (FEED_INFO.containsKey(npc.getObjectId()))
|
|
||||||
{
|
|
||||||
if (FEED_INFO.get(npc.getObjectId()) == player.getObjectId())
|
|
||||||
{
|
|
||||||
FEED_INFO.remove(npc.getObjectId());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// despawn the old mob
|
|
||||||
// TODO: same code? FIXED?
|
|
||||||
// @formatter:off
|
|
||||||
/*
|
|
||||||
* if (_GrowthCapableMobs.get(npcId).getGrowthLevel() == 0)
|
|
||||||
{
|
|
||||||
npc.deleteMe();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
*/
|
|
||||||
npc.deleteMe();
|
|
||||||
// }
|
|
||||||
// @formatter:on
|
|
||||||
|
|
||||||
// if this is finally a trained mob, then despawn any other trained mobs that the
|
|
||||||
// player might have and initialize the Tamed Beast.
|
|
||||||
if (Util.contains(TAMED_BEASTS, nextNpcId))
|
|
||||||
{
|
|
||||||
if ((player.getTrainedBeasts() != null) && !player.getTrainedBeasts().isEmpty())
|
|
||||||
{
|
|
||||||
for (L2TamedBeastInstance oldTrained : player.getTrainedBeasts())
|
|
||||||
{
|
|
||||||
oldTrained.deleteMe();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
final L2TamedBeastInstance nextNpc = new L2TamedBeastInstance(nextNpcId, player, food - FOODSKILLDIFF, npc.getX(), npc.getY(), npc.getZ());
|
|
||||||
nextNpc.setRunning();
|
|
||||||
// Q00020_BringUpWithLove.checkJewelOfInnocence(player);
|
|
||||||
|
|
||||||
// Support for A Grand Plan for Taming Wild Beasts (655) quest.
|
|
||||||
// Q00655_AGrandPlanForTamingWildBeasts.reward(player, nextNpc);
|
|
||||||
|
|
||||||
// also, perform a rare random chat
|
|
||||||
if (getRandom(20) == 0)
|
|
||||||
{
|
|
||||||
NpcStringId message = NpcStringId.getNpcStringId(getRandom(2024, 2029));
|
|
||||||
NpcSay packet = new NpcSay(nextNpc, ChatType.NPC_GENERAL, message);
|
|
||||||
if (message.getParamCount() > 0) // player name, $s1
|
|
||||||
{
|
|
||||||
packet.addStringParameter(player.getName());
|
|
||||||
}
|
|
||||||
npc.broadcastPacket(packet);
|
|
||||||
}
|
|
||||||
// @formatter:off
|
|
||||||
/*
|
|
||||||
TODO: The tamed beast consumes one golden/crystal spice
|
|
||||||
every 60 seconds with an initial delay of 60 seconds
|
|
||||||
if (tamed beast exists and is alive)
|
|
||||||
{
|
|
||||||
if (player has 1+ golden/crystal spice)
|
|
||||||
{
|
|
||||||
take one golden/crystal spice;
|
|
||||||
say random NpcString(getRandom(2029, 2038));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
// @formatter:on
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// if not trained, the newly spawned mob will automatically be aggro against its feeder
|
|
||||||
// (what happened to "never bite the hand that feeds you" anyway?!)
|
|
||||||
L2Attackable nextNpc = (L2Attackable) addSpawn(nextNpcId, npc);
|
|
||||||
|
|
||||||
if (MAD_COW_POLYMORPH.containsKey(nextNpcId))
|
|
||||||
{
|
|
||||||
this.startQuestTimer("polymorph Mad Cow", 10000, nextNpc, player);
|
|
||||||
}
|
|
||||||
|
|
||||||
// register the player in the feedinfo for the mob that just spawned
|
|
||||||
FEED_INFO.put(nextNpc.getObjectId(), player.getObjectId());
|
|
||||||
nextNpc.setRunning();
|
|
||||||
nextNpc.addDamageHate(player, 0, 99999);
|
|
||||||
nextNpc.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, player);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
|
||||||
{
|
|
||||||
if (event.equalsIgnoreCase("polymorph Mad Cow") && (npc != null) && (player != null))
|
|
||||||
{
|
|
||||||
if (MAD_COW_POLYMORPH.containsKey(npc.getId()))
|
|
||||||
{
|
|
||||||
// remove the feed info from the previous mob
|
|
||||||
if (FEED_INFO.get(npc.getObjectId()) == player.getObjectId())
|
|
||||||
{
|
|
||||||
FEED_INFO.remove(npc.getObjectId());
|
|
||||||
}
|
|
||||||
// despawn the mad cow
|
|
||||||
npc.deleteMe();
|
|
||||||
// spawn the new mob
|
|
||||||
L2Attackable nextNpc = (L2Attackable) addSpawn(MAD_COW_POLYMORPH.get(npc.getId()), npc);
|
|
||||||
|
|
||||||
// register the player in the feedinfo for the mob that just spawned
|
|
||||||
FEED_INFO.put(nextNpc.getObjectId(), player.getObjectId());
|
|
||||||
nextNpc.setRunning();
|
|
||||||
nextNpc.addDamageHate(player, 0, 99999);
|
|
||||||
nextNpc.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, player);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return super.onAdvEvent(event, npc, player);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String onSkillSee(L2Npc npc, L2PcInstance caster, Skill skill, L2Object[] targets, boolean isSummon)
|
|
||||||
{
|
|
||||||
// this behavior is only run when the target of skill is the passed npc (chest)
|
|
||||||
// i.e. when the player is attempting to open the chest using a skill
|
|
||||||
if (!Util.contains(targets, npc))
|
|
||||||
{
|
|
||||||
return super.onSkillSee(npc, caster, skill, targets, isSummon);
|
|
||||||
}
|
|
||||||
// gather some values on local variables
|
|
||||||
int npcId = npc.getId();
|
|
||||||
int skillId = skill.getId();
|
|
||||||
// check if the npc and skills used are valid for this script. Exit if invalid.
|
|
||||||
if ((skillId != SKILL_GOLDEN_SPICE) && (skillId != SKILL_CRYSTAL_SPICE))
|
|
||||||
{
|
|
||||||
return super.onSkillSee(npc, caster, skill, targets, isSummon);
|
|
||||||
}
|
|
||||||
|
|
||||||
// first gather some values on local variables
|
|
||||||
int objectId = npc.getObjectId();
|
|
||||||
int growthLevel = 3; // if a mob is in FEEDABLE_BEASTS but not in _GrowthCapableMobs, then it's at max growth (3)
|
|
||||||
if (GROWTH_CAPABLE_MONSTERS.containsKey(npcId))
|
|
||||||
{
|
|
||||||
growthLevel = GROWTH_CAPABLE_MONSTERS.get(npcId).getGrowthLevel();
|
|
||||||
}
|
|
||||||
|
|
||||||
// prevent exploit which allows 2 players to simultaneously raise the same 0-growth beast
|
|
||||||
// If the mob is at 0th level (when it still listens to all feeders) lock it to the first feeder!
|
|
||||||
if ((growthLevel == 0) && FEED_INFO.containsKey(objectId))
|
|
||||||
{
|
|
||||||
return super.onSkillSee(npc, caster, skill, targets, isSummon);
|
|
||||||
}
|
|
||||||
|
|
||||||
FEED_INFO.put(objectId, caster.getObjectId());
|
|
||||||
|
|
||||||
int food = 0;
|
|
||||||
if (skillId == SKILL_GOLDEN_SPICE)
|
|
||||||
{
|
|
||||||
food = GOLDEN_SPICE;
|
|
||||||
}
|
|
||||||
else if (skillId == SKILL_CRYSTAL_SPICE)
|
|
||||||
{
|
|
||||||
food = CRYSTAL_SPICE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// display the social action of the beast eating the food.
|
|
||||||
npc.broadcastSocialAction(2);
|
|
||||||
|
|
||||||
// if this pet can't grow, it's all done.
|
|
||||||
if (GROWTH_CAPABLE_MONSTERS.containsKey(npcId))
|
|
||||||
{
|
|
||||||
// do nothing if this mob doesn't eat the specified food (food gets consumed but has no effect).
|
|
||||||
if (GROWTH_CAPABLE_MONSTERS.get(npcId).getMob(food, 0, 0) == null)
|
|
||||||
{
|
|
||||||
return super.onSkillSee(npc, caster, skill, targets, isSummon);
|
|
||||||
}
|
|
||||||
|
|
||||||
// rare random talk...
|
|
||||||
if (getRandom(20) == 0)
|
|
||||||
{
|
|
||||||
NpcStringId message = TEXT[growthLevel][getRandom(TEXT[growthLevel].length)];
|
|
||||||
NpcSay packet = new NpcSay(npc, ChatType.NPC_GENERAL, message);
|
|
||||||
if (message.getParamCount() > 0) // player name, $s1
|
|
||||||
{
|
|
||||||
packet.addStringParameter(caster.getName());
|
|
||||||
}
|
|
||||||
npc.broadcastPacket(packet);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((growthLevel > 0) && (FEED_INFO.get(objectId) != caster.getObjectId()))
|
|
||||||
{
|
|
||||||
// check if this is the same player as the one who raised it from growth 0.
|
|
||||||
// if no, then do not allow a chance to raise the pet (food gets consumed but has no effect).
|
|
||||||
return super.onSkillSee(npc, caster, skill, targets, isSummon);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Polymorph the mob, with a certain chance, given its current growth level
|
|
||||||
if (getRandom(100) < GROWTH_CAPABLE_MONSTERS.get(npcId).getChance())
|
|
||||||
{
|
|
||||||
spawnNext(npc, growthLevel, caster, food);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (Util.contains(TAMED_BEASTS, npcId) && (npc instanceof L2TamedBeastInstance))
|
|
||||||
{
|
|
||||||
L2TamedBeastInstance beast = ((L2TamedBeastInstance) npc);
|
|
||||||
if (skillId == beast.getFoodType())
|
|
||||||
{
|
|
||||||
beast.onReceiveFood();
|
|
||||||
NpcStringId message = TAMED_TEXT[getRandom(TAMED_TEXT.length)];
|
|
||||||
NpcSay packet = new NpcSay(npc, ChatType.NPC_GENERAL, message);
|
|
||||||
if (message.getParamCount() > 0)
|
|
||||||
{
|
|
||||||
packet.addStringParameter(caster.getName());
|
|
||||||
}
|
|
||||||
beast.broadcastPacket(packet);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return super.onSkillSee(npc, caster, skill, targets, isSummon);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
|
|
||||||
{
|
|
||||||
// remove the feedinfo of the mob that got killed, if any
|
|
||||||
if (FEED_INFO.containsKey(npc.getObjectId()))
|
|
||||||
{
|
|
||||||
FEED_INFO.remove(npc.getObjectId());
|
|
||||||
}
|
|
||||||
return super.onKill(npc, killer, isSummon);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void main(String[] args)
|
|
||||||
{
|
|
||||||
new FeedableBeasts();
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,71 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2004-2015 L2J DataPack
|
|
||||||
*
|
|
||||||
* This file is part of L2J DataPack.
|
|
||||||
*
|
|
||||||
* L2J DataPack 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.
|
|
||||||
*
|
|
||||||
* L2J DataPack 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.group_template;
|
|
||||||
|
|
||||||
import ai.npc.AbstractNpcAI;
|
|
||||||
|
|
||||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
|
||||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
|
||||||
import com.l2jserver.gameserver.model.skills.Skill;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Frozen Labyrinth AI.
|
|
||||||
* @author malyelfik
|
|
||||||
*/
|
|
||||||
public final class FrozenLabyrinth extends AbstractNpcAI
|
|
||||||
{
|
|
||||||
// Monsters
|
|
||||||
private static final int PRONGHORN_SPIRIT = 22087;
|
|
||||||
private static final int PRONGHORN = 22088;
|
|
||||||
private static final int LOST_BUFFALO = 22093;
|
|
||||||
private static final int FROST_BUFFALO = 22094;
|
|
||||||
|
|
||||||
private FrozenLabyrinth()
|
|
||||||
{
|
|
||||||
super(FrozenLabyrinth.class.getSimpleName(), "ai/group_template");
|
|
||||||
addAttackId(PRONGHORN, FROST_BUFFALO);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String onAttack(L2Npc npc, L2PcInstance attacker, int damage, boolean isSummon, Skill skill)
|
|
||||||
{
|
|
||||||
if (npc.isScriptValue(0) && (skill != null) && !skill.isMagic())
|
|
||||||
{
|
|
||||||
final int spawnId = (npc.getId() == PRONGHORN) ? PRONGHORN_SPIRIT : LOST_BUFFALO;
|
|
||||||
int diff = 0;
|
|
||||||
for (int i = 0; i < 6; i++)
|
|
||||||
{
|
|
||||||
final int x = diff < 60 ? npc.getX() + diff : npc.getX();
|
|
||||||
final int y = diff >= 60 ? npc.getY() + (diff - 40) : npc.getY();
|
|
||||||
|
|
||||||
final L2Npc monster = addSpawn(spawnId, x, y, npc.getZ(), npc.getHeading(), false, 0);
|
|
||||||
addAttackPlayerDesire(monster, attacker);
|
|
||||||
diff += 20;
|
|
||||||
}
|
|
||||||
npc.setScriptValue(1);
|
|
||||||
npc.deleteMe();
|
|
||||||
}
|
|
||||||
return super.onAttack(npc, attacker, damage, isSummon, skill);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void main(String[] args)
|
|
||||||
{
|
|
||||||
new FrozenLabyrinth();
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,114 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2004-2015 L2J DataPack
|
|
||||||
*
|
|
||||||
* This file is part of L2J DataPack.
|
|
||||||
*
|
|
||||||
* L2J DataPack 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.
|
|
||||||
*
|
|
||||||
* L2J DataPack 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.group_template;
|
|
||||||
|
|
||||||
import ai.npc.AbstractNpcAI;
|
|
||||||
|
|
||||||
import com.l2jserver.gameserver.enums.ChatType;
|
|
||||||
import com.l2jserver.gameserver.model.actor.L2Character;
|
|
||||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
|
||||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
|
||||||
import com.l2jserver.gameserver.network.NpcStringId;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Giant's Cave AI.
|
|
||||||
* @author Gnacik, St3eT
|
|
||||||
*/
|
|
||||||
public final class GiantsCave extends AbstractNpcAI
|
|
||||||
{
|
|
||||||
// NPC
|
|
||||||
private static final int[] SCOUTS =
|
|
||||||
{
|
|
||||||
22668, // Gamlin (Scout)
|
|
||||||
22669, // Leogul (Scout)
|
|
||||||
};
|
|
||||||
|
|
||||||
private GiantsCave()
|
|
||||||
{
|
|
||||||
super(GiantsCave.class.getSimpleName(), "ai/group_template");
|
|
||||||
addAttackId(SCOUTS);
|
|
||||||
addAggroRangeEnterId(SCOUTS);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
|
||||||
{
|
|
||||||
if (event.equals("ATTACK") && (player != null) && (npc != null) && !npc.isDead())
|
|
||||||
{
|
|
||||||
if (npc.getId() == SCOUTS[0]) // Gamlin
|
|
||||||
{
|
|
||||||
broadcastNpcSay(npc, ChatType.NPC_SHOUT, NpcStringId.INTRUDER_DETECTED);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
broadcastNpcSay(npc, ChatType.NPC_SHOUT, NpcStringId.OH_GIANTS_AN_INTRUDER_HAS_BEEN_DISCOVERED);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (L2Character characters : npc.getKnownList().getKnownCharactersInRadius(450))
|
|
||||||
{
|
|
||||||
if ((characters != null) && (characters.isAttackable()) && (getRandomBoolean()))
|
|
||||||
{
|
|
||||||
addAttackPlayerDesire((L2Npc) characters, player);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (event.equals("CLEAR") && (npc != null) && !npc.isDead())
|
|
||||||
{
|
|
||||||
npc.setScriptValue(0);
|
|
||||||
}
|
|
||||||
return super.onAdvEvent(event, npc, player);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String onAttack(L2Npc npc, L2PcInstance attacker, int damage, boolean isSummon)
|
|
||||||
{
|
|
||||||
if (npc.isScriptValue(0))
|
|
||||||
{
|
|
||||||
npc.setScriptValue(1);
|
|
||||||
startQuestTimer("ATTACK", 6000, npc, attacker);
|
|
||||||
startQuestTimer("CLEAR", 120000, npc, null);
|
|
||||||
}
|
|
||||||
return super.onAttack(npc, attacker, damage, isSummon);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String onAggroRangeEnter(L2Npc npc, L2PcInstance player, boolean isSummon)
|
|
||||||
{
|
|
||||||
if (npc.isScriptValue(0))
|
|
||||||
{
|
|
||||||
npc.setScriptValue(1);
|
|
||||||
if (getRandomBoolean())
|
|
||||||
{
|
|
||||||
broadcastNpcSay(npc, ChatType.NPC_GENERAL, NpcStringId.YOU_GUYS_ARE_DETECTED);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
broadcastNpcSay(npc, ChatType.NPC_GENERAL, NpcStringId.WHAT_KIND_OF_CREATURES_ARE_YOU);
|
|
||||||
}
|
|
||||||
startQuestTimer("ATTACK", 6000, npc, player);
|
|
||||||
startQuestTimer("CLEAR", 120000, npc, null);
|
|
||||||
}
|
|
||||||
return super.onAggroRangeEnter(npc, player, isSummon);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void main(String[] args)
|
|
||||||
{
|
|
||||||
new GiantsCave();
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,109 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2004-2015 L2J DataPack
|
|
||||||
*
|
|
||||||
* This file is part of L2J DataPack.
|
|
||||||
*
|
|
||||||
* L2J DataPack 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.
|
|
||||||
*
|
|
||||||
* L2J DataPack 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.group_template;
|
|
||||||
|
|
||||||
import ai.npc.AbstractNpcAI;
|
|
||||||
|
|
||||||
import com.l2jserver.gameserver.datatables.SkillData;
|
|
||||||
import com.l2jserver.gameserver.model.actor.L2Character;
|
|
||||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
|
||||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
|
||||||
import com.l2jserver.gameserver.model.skills.BuffInfo;
|
|
||||||
import com.l2jserver.gameserver.model.skills.Skill;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Hot Springs AI.
|
|
||||||
* @author Pandragon
|
|
||||||
*/
|
|
||||||
public final class HotSprings extends AbstractNpcAI
|
|
||||||
{
|
|
||||||
// NPCs
|
|
||||||
private static final int BANDERSNATCHLING = 21314;
|
|
||||||
private static final int FLAVA = 21316;
|
|
||||||
private static final int ATROXSPAWN = 21317;
|
|
||||||
private static final int NEPENTHES = 21319;
|
|
||||||
private static final int ATROX = 21321;
|
|
||||||
private static final int BANDERSNATCH = 21322;
|
|
||||||
// Skills
|
|
||||||
private static final int RHEUMATISM = 4551;
|
|
||||||
private static final int CHOLERA = 4552;
|
|
||||||
private static final int FLU = 4553;
|
|
||||||
private static final int MALARIA = 4554;
|
|
||||||
// Misc
|
|
||||||
private static final int DISEASE_CHANCE = 10;
|
|
||||||
|
|
||||||
private HotSprings()
|
|
||||||
{
|
|
||||||
super(HotSprings.class.getSimpleName(), "ai/group_template");
|
|
||||||
addAttackId(BANDERSNATCHLING, FLAVA, ATROXSPAWN, NEPENTHES, ATROX, BANDERSNATCH);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String onAttack(L2Npc npc, L2PcInstance attacker, int damage, boolean isSummon)
|
|
||||||
{
|
|
||||||
if (getRandom(100) < DISEASE_CHANCE)
|
|
||||||
{
|
|
||||||
tryToInfect(npc, attacker, MALARIA);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (getRandom(100) < DISEASE_CHANCE)
|
|
||||||
{
|
|
||||||
switch (npc.getId())
|
|
||||||
{
|
|
||||||
case BANDERSNATCHLING:
|
|
||||||
case ATROX:
|
|
||||||
{
|
|
||||||
tryToInfect(npc, attacker, RHEUMATISM);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case FLAVA:
|
|
||||||
case NEPENTHES:
|
|
||||||
{
|
|
||||||
tryToInfect(npc, attacker, CHOLERA);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case ATROXSPAWN:
|
|
||||||
case BANDERSNATCH:
|
|
||||||
{
|
|
||||||
tryToInfect(npc, attacker, FLU);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return super.onAttack(npc, attacker, damage, isSummon);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void tryToInfect(L2Npc npc, L2Character player, int diseaseId)
|
|
||||||
{
|
|
||||||
final BuffInfo info = player.getEffectList().getBuffInfoBySkillId(diseaseId);
|
|
||||||
final int skillLevel = (info == null) ? 1 : (info.getSkill().getLevel() < 10) ? info.getSkill().getLevel() + 1 : 10;
|
|
||||||
final Skill skill = SkillData.getInstance().getSkill(diseaseId, skillLevel);
|
|
||||||
|
|
||||||
if ((skill != null) && !npc.isCastingNow() && npc.checkDoCastConditions(skill))
|
|
||||||
{
|
|
||||||
npc.setTarget(player);
|
|
||||||
npc.doCast(skill);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void main(String[] args)
|
|
||||||
{
|
|
||||||
new HotSprings();
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,296 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2004-2015 L2J DataPack
|
|
||||||
*
|
|
||||||
* This file is part of L2J DataPack.
|
|
||||||
*
|
|
||||||
* L2J DataPack 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.
|
|
||||||
*
|
|
||||||
* L2J DataPack 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.group_template;
|
|
||||||
|
|
||||||
import ai.npc.AbstractNpcAI;
|
|
||||||
|
|
||||||
import com.l2jserver.gameserver.ai.CtrlIntention;
|
|
||||||
import com.l2jserver.gameserver.enums.ChatType;
|
|
||||||
import com.l2jserver.gameserver.model.L2Object;
|
|
||||||
import com.l2jserver.gameserver.model.actor.L2Attackable;
|
|
||||||
import com.l2jserver.gameserver.model.actor.L2Character;
|
|
||||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
|
||||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
|
||||||
import com.l2jserver.gameserver.model.effects.L2EffectType;
|
|
||||||
import com.l2jserver.gameserver.model.holders.SkillHolder;
|
|
||||||
import com.l2jserver.gameserver.model.skills.Skill;
|
|
||||||
import com.l2jserver.gameserver.network.NpcStringId;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Monastery of Silence AI.
|
|
||||||
* @author Kerberos, nonom
|
|
||||||
*/
|
|
||||||
public final class MonasteryOfSilence extends AbstractNpcAI
|
|
||||||
{
|
|
||||||
// NPCs
|
|
||||||
private static final int CAPTAIN = 18910; // Solina Knight Captain
|
|
||||||
private static final int KNIGHT = 18909; // Solina Knights
|
|
||||||
private static final int SCARECROW = 18912; // Scarecrow
|
|
||||||
private static final int GUIDE = 22789; // Guide Solina
|
|
||||||
private static final int SEEKER = 22790; // Seeker Solina
|
|
||||||
private static final int SAVIOR = 22791; // Savior Solina
|
|
||||||
private static final int ASCETIC = 22793; // Ascetic Solina
|
|
||||||
private static final int[] DIVINITY_CLAN =
|
|
||||||
{
|
|
||||||
22794, // Divinity Judge
|
|
||||||
22795, // Divinity Manager
|
|
||||||
};
|
|
||||||
// Skills
|
|
||||||
private static final SkillHolder ORDEAL_STRIKE = new SkillHolder(6303, 1); // Trial of the Coup
|
|
||||||
private static final SkillHolder LEADER_STRIKE = new SkillHolder(6304, 1); // Shock
|
|
||||||
private static final SkillHolder SAVER_STRIKE = new SkillHolder(6305, 1); // Sacred Gnosis
|
|
||||||
private static final SkillHolder SAVER_BLEED = new SkillHolder(6306, 1); // Solina Strike
|
|
||||||
private static final SkillHolder LEARNING_MAGIC = new SkillHolder(6308, 1); // Opus of the Wave
|
|
||||||
private static final SkillHolder STUDENT_CANCEL = new SkillHolder(6310, 1); // Loss of Quest
|
|
||||||
private static final SkillHolder WARRIOR_THRUSTING = new SkillHolder(6311, 1); // Solina Thrust
|
|
||||||
private static final SkillHolder KNIGHT_BLESS = new SkillHolder(6313, 1); // Solina Bless
|
|
||||||
// Misc
|
|
||||||
private static final NpcStringId[] DIVINITY_MSG =
|
|
||||||
{
|
|
||||||
NpcStringId.S1_WHY_WOULD_YOU_CHOOSE_THE_PATH_OF_DARKNESS,
|
|
||||||
NpcStringId.S1_HOW_DARE_YOU_DEFY_THE_WILL_OF_EINHASAD
|
|
||||||
};
|
|
||||||
private static final NpcStringId[] SOLINA_KNIGHTS_MSG =
|
|
||||||
{
|
|
||||||
NpcStringId.PUNISH_ALL_THOSE_WHO_TREAD_FOOTSTEPS_IN_THIS_PLACE,
|
|
||||||
NpcStringId.WE_ARE_THE_SWORD_OF_TRUTH_THE_SWORD_OF_SOLINA,
|
|
||||||
NpcStringId.WE_RAISE_OUR_BLADES_FOR_THE_GLORY_OF_SOLINA
|
|
||||||
};
|
|
||||||
|
|
||||||
private MonasteryOfSilence()
|
|
||||||
{
|
|
||||||
super(MonasteryOfSilence.class.getSimpleName(), "ai/group_template");
|
|
||||||
addSkillSeeId(DIVINITY_CLAN);
|
|
||||||
addAttackId(KNIGHT, CAPTAIN, GUIDE, SEEKER, ASCETIC);
|
|
||||||
addNpcHateId(GUIDE, SEEKER, SAVIOR, ASCETIC);
|
|
||||||
addAggroRangeEnterId(GUIDE, SEEKER, SAVIOR, ASCETIC);
|
|
||||||
addSpawnId(SCARECROW);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
|
||||||
{
|
|
||||||
switch (event)
|
|
||||||
{
|
|
||||||
case "TRAINING":
|
|
||||||
{
|
|
||||||
for (L2Character character : npc.getKnownList().getKnownCharactersInRadius(400))
|
|
||||||
{
|
|
||||||
if ((getRandom(100) < 30) && character.isNpc() && !character.isDead() && !character.isInCombat())
|
|
||||||
{
|
|
||||||
if ((character.getId() == CAPTAIN) && (getRandom(100) < 10) && npc.isScriptValue(0))
|
|
||||||
{
|
|
||||||
final L2Npc captain = (L2Npc) character;
|
|
||||||
broadcastNpcSay(captain, ChatType.NPC_GENERAL, SOLINA_KNIGHTS_MSG[getRandom(SOLINA_KNIGHTS_MSG.length)]);
|
|
||||||
captain.setScriptValue(1);
|
|
||||||
startQuestTimer("TIMER", 10000, captain, null);
|
|
||||||
}
|
|
||||||
else if (character.getId() == KNIGHT)
|
|
||||||
{
|
|
||||||
character.setRunning();
|
|
||||||
((L2Attackable) character).addDamageHate(npc, 0, 100);
|
|
||||||
character.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, npc, null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case "DO_CAST":
|
|
||||||
{
|
|
||||||
if ((npc != null) && (player != null) && (getRandom(100) < 3))
|
|
||||||
{
|
|
||||||
if (npc.checkDoCastConditions(STUDENT_CANCEL.getSkill()))
|
|
||||||
{
|
|
||||||
npc.setTarget(player);
|
|
||||||
npc.doCast(STUDENT_CANCEL.getSkill());
|
|
||||||
}
|
|
||||||
npc.setScriptValue(0);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case "TIMER":
|
|
||||||
{
|
|
||||||
if (npc != null)
|
|
||||||
{
|
|
||||||
npc.setScriptValue(0);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return super.onAdvEvent(event, npc, player);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String onAttack(L2Npc npc, L2PcInstance player, int damage, boolean isSummon)
|
|
||||||
{
|
|
||||||
final L2Attackable mob = (L2Attackable) npc;
|
|
||||||
|
|
||||||
switch (npc.getId())
|
|
||||||
{
|
|
||||||
case KNIGHT:
|
|
||||||
{
|
|
||||||
if ((getRandom(100) < 10) && (mob.getMostHated() == player) && mob.checkDoCastConditions(WARRIOR_THRUSTING.getSkill()))
|
|
||||||
{
|
|
||||||
npc.setTarget(player);
|
|
||||||
npc.doCast(WARRIOR_THRUSTING.getSkill());
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case CAPTAIN:
|
|
||||||
{
|
|
||||||
if ((getRandom(100) < 20) && (npc.getCurrentHp() < (npc.getMaxHp() * 0.5)) && npc.isScriptValue(0))
|
|
||||||
{
|
|
||||||
if (npc.checkDoCastConditions(KNIGHT_BLESS.getSkill()))
|
|
||||||
{
|
|
||||||
npc.setTarget(npc);
|
|
||||||
npc.doCast(KNIGHT_BLESS.getSkill());
|
|
||||||
}
|
|
||||||
npc.setScriptValue(1);
|
|
||||||
broadcastNpcSay(npc, ChatType.NPC_GENERAL, NpcStringId.FOR_THE_GLORY_OF_SOLINA);
|
|
||||||
addAttackPlayerDesire(addSpawn(KNIGHT, npc), player);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case GUIDE:
|
|
||||||
{
|
|
||||||
if ((getRandom(100) < 3) && (mob.getMostHated() == player) && npc.checkDoCastConditions(ORDEAL_STRIKE.getSkill()))
|
|
||||||
{
|
|
||||||
npc.setTarget(player);
|
|
||||||
npc.doCast(ORDEAL_STRIKE.getSkill());
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case SEEKER:
|
|
||||||
{
|
|
||||||
if ((getRandom(100) < 33) && (mob.getMostHated() == player) && npc.checkDoCastConditions(SAVER_STRIKE.getSkill()))
|
|
||||||
{
|
|
||||||
npc.setTarget(npc);
|
|
||||||
npc.doCast(SAVER_STRIKE.getSkill());
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case ASCETIC:
|
|
||||||
{
|
|
||||||
if ((mob.getMostHated() == player) && npc.isScriptValue(0))
|
|
||||||
{
|
|
||||||
npc.setScriptValue(1);
|
|
||||||
startQuestTimer("DO_CAST", 20000, npc, player);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return super.onAttack(npc, player, damage, isSummon);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onNpcHate(L2Attackable mob, L2PcInstance player, boolean isSummon)
|
|
||||||
{
|
|
||||||
return player.getActiveWeaponInstance() != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String onAggroRangeEnter(L2Npc npc, L2PcInstance player, boolean isSummon)
|
|
||||||
{
|
|
||||||
if (player.getActiveWeaponInstance() != null)
|
|
||||||
{
|
|
||||||
SkillHolder skill = null;
|
|
||||||
switch (npc.getId())
|
|
||||||
{
|
|
||||||
case GUIDE:
|
|
||||||
{
|
|
||||||
if (getRandom(100) < 3)
|
|
||||||
{
|
|
||||||
skill = LEADER_STRIKE;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case SEEKER:
|
|
||||||
{
|
|
||||||
skill = SAVER_BLEED;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case SAVIOR:
|
|
||||||
{
|
|
||||||
skill = LEARNING_MAGIC;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case ASCETIC:
|
|
||||||
{
|
|
||||||
if (getRandom(100) < 3)
|
|
||||||
{
|
|
||||||
skill = STUDENT_CANCEL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (npc.isScriptValue(0))
|
|
||||||
{
|
|
||||||
npc.setScriptValue(1);
|
|
||||||
startQuestTimer("DO_CAST", 20000, npc, player);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((skill != null) && npc.checkDoCastConditions(skill.getSkill()))
|
|
||||||
{
|
|
||||||
npc.setTarget(player);
|
|
||||||
npc.doCast(skill.getSkill());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!npc.isInCombat())
|
|
||||||
{
|
|
||||||
broadcastNpcSay(npc, ChatType.NPC_GENERAL, NpcStringId.YOU_CANNOT_CARRY_A_WEAPON_WITHOUT_AUTHORIZATION);
|
|
||||||
}
|
|
||||||
|
|
||||||
addAttackPlayerDesire(npc, player);
|
|
||||||
}
|
|
||||||
return super.onAggroRangeEnter(npc, player, isSummon);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String onSkillSee(L2Npc npc, L2PcInstance caster, Skill skill, L2Object[] targets, boolean isSummon)
|
|
||||||
{
|
|
||||||
if (skill.hasEffectType(L2EffectType.AGGRESSION) && (targets.length != 0))
|
|
||||||
{
|
|
||||||
for (L2Object obj : targets)
|
|
||||||
{
|
|
||||||
if (obj.equals(npc))
|
|
||||||
{
|
|
||||||
broadcastNpcSay(npc, ChatType.NPC_GENERAL, DIVINITY_MSG[getRandom(DIVINITY_MSG.length)], caster.getName());
|
|
||||||
addAttackPlayerDesire(npc, caster);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return super.onSkillSee(npc, caster, skill, targets, isSummon);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String onSpawn(L2Npc npc)
|
|
||||||
{
|
|
||||||
npc.setIsInvul(true);
|
|
||||||
npc.disableCoreAI(true);
|
|
||||||
startQuestTimer("TRAINING", 30000, npc, null, true);
|
|
||||||
return super.onSpawn(npc);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void main(String[] args)
|
|
||||||
{
|
|
||||||
new MonasteryOfSilence();
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,51 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2004-2015 L2J DataPack
|
|
||||||
*
|
|
||||||
* This file is part of L2J DataPack.
|
|
||||||
*
|
|
||||||
* L2J DataPack 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.
|
|
||||||
*
|
|
||||||
* L2J DataPack 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.group_template;
|
|
||||||
|
|
||||||
import ai.npc.AbstractNpcAI;
|
|
||||||
|
|
||||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Pagan Temple AI.
|
|
||||||
* @author Mobius
|
|
||||||
*/
|
|
||||||
public class PaganTemple extends AbstractNpcAI
|
|
||||||
{
|
|
||||||
// Npc
|
|
||||||
private static final int CHAPEL_GATEKEEPER = 22138;
|
|
||||||
|
|
||||||
public PaganTemple()
|
|
||||||
{
|
|
||||||
super(PaganTemple.class.getSimpleName(), "ai/group_template");
|
|
||||||
addSpawnId(CHAPEL_GATEKEEPER);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String onSpawn(L2Npc npc)
|
|
||||||
{
|
|
||||||
npc.setIsNoRndWalk(true);
|
|
||||||
return super.onSpawn(npc);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void main(String[] args)
|
|
||||||
{
|
|
||||||
new PaganTemple();
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,62 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2004-2015 L2J DataPack
|
|
||||||
*
|
|
||||||
* This file is part of L2J DataPack.
|
|
||||||
*
|
|
||||||
* L2J DataPack 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.
|
|
||||||
*
|
|
||||||
* L2J DataPack 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.group_template;
|
|
||||||
|
|
||||||
import ai.npc.AbstractNpcAI;
|
|
||||||
|
|
||||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
|
||||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Pavel Archaic AI.
|
|
||||||
* @author Gnacik, St3eT
|
|
||||||
*/
|
|
||||||
public final class PavelArchaic extends AbstractNpcAI
|
|
||||||
{
|
|
||||||
private static final int SAFETY_DEVICE = 18917; // Pavel Safety Device
|
|
||||||
private static final int PINCER_GOLEM = 22801; // Cruel Pincer Golem
|
|
||||||
private static final int PINCER_GOLEM2 = 22802; // Cruel Pincer Golem
|
|
||||||
private static final int PINCER_GOLEM3 = 22803; // Cruel Pincer Golem
|
|
||||||
private static final int JACKHAMMER_GOLEM = 22804; // Horrifying Jackhammer Golem
|
|
||||||
|
|
||||||
private PavelArchaic()
|
|
||||||
{
|
|
||||||
super(PavelArchaic.class.getSimpleName(), "ai/group_template");
|
|
||||||
addKillId(SAFETY_DEVICE, PINCER_GOLEM, JACKHAMMER_GOLEM);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
|
|
||||||
{
|
|
||||||
if (getRandom(100) < 70)
|
|
||||||
{
|
|
||||||
final L2Npc golem1 = addSpawn(PINCER_GOLEM2, npc.getX(), npc.getY(), npc.getZ() + 10, npc.getHeading(), false, 0, false);
|
|
||||||
addAttackPlayerDesire(golem1, killer);
|
|
||||||
|
|
||||||
final L2Npc golem2 = addSpawn(PINCER_GOLEM3, npc.getX(), npc.getY(), npc.getZ() + 10, npc.getHeading(), false, 0, false);
|
|
||||||
addAttackPlayerDesire(golem2, killer);
|
|
||||||
}
|
|
||||||
return super.onKill(npc, killer, isSummon);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void main(String[] args)
|
|
||||||
{
|
|
||||||
new PavelArchaic();
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,244 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2004-2015 L2J DataPack
|
|
||||||
*
|
|
||||||
* This file is part of L2J DataPack.
|
|
||||||
*
|
|
||||||
* L2J DataPack 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.
|
|
||||||
*
|
|
||||||
* L2J DataPack 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.group_template;
|
|
||||||
|
|
||||||
import ai.npc.AbstractNpcAI;
|
|
||||||
|
|
||||||
import com.l2jserver.gameserver.ai.CtrlIntention;
|
|
||||||
import com.l2jserver.gameserver.model.Location;
|
|
||||||
import com.l2jserver.gameserver.model.actor.L2Attackable;
|
|
||||||
import com.l2jserver.gameserver.model.actor.L2Character;
|
|
||||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
|
||||||
import com.l2jserver.gameserver.model.actor.L2Playable;
|
|
||||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
|
||||||
import com.l2jserver.gameserver.model.holders.SkillHolder;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Plains of Lizardmen AI.
|
|
||||||
* @author Gnacik, malyelfik
|
|
||||||
*/
|
|
||||||
public final class PlainsOfLizardman extends AbstractNpcAI
|
|
||||||
{
|
|
||||||
// NPCs
|
|
||||||
private static final int INVISIBLE_NPC = 18919;
|
|
||||||
private static final int TANTA_GUARD = 18862;
|
|
||||||
private static final int FANTASY_MUSHROOM = 18864;
|
|
||||||
private static final int STICKY_MUSHROOM = 18865;
|
|
||||||
private static final int RAINBOW_FROG = 18866;
|
|
||||||
private static final int ENERGY_PLANT = 18868;
|
|
||||||
private static final int TANTA_SCOUT = 22768;
|
|
||||||
private static final int TANTA_MAGICIAN = 22773;
|
|
||||||
private static final int TANTA_SUMMONER = 22774;
|
|
||||||
private static final int[] TANTA_LIZARDMEN =
|
|
||||||
{
|
|
||||||
22768, // Tanta Lizardman Scout
|
|
||||||
22769, // Tanta Lizardman Warrior
|
|
||||||
22770, // Tanta Lizardman Soldier
|
|
||||||
22771, // Tanta Lizardman Berserker
|
|
||||||
22772, // Tanta Lizardman Archer
|
|
||||||
22773, // Tanta Lizardman Magician
|
|
||||||
22774, // Tanta Lizardman Summoner
|
|
||||||
};
|
|
||||||
// Skills
|
|
||||||
private static final SkillHolder STUN_EFFECT = new SkillHolder(6622, 1);
|
|
||||||
private static final SkillHolder DEMOTIVATION_HEX = new SkillHolder(6425, 1);
|
|
||||||
private static final SkillHolder FANTASY_MUSHROOM_SKILL = new SkillHolder(6427, 1);
|
|
||||||
private static final SkillHolder RAINBOW_FROG_SKILL = new SkillHolder(6429, 1);
|
|
||||||
private static final SkillHolder STICKY_MUSHROOM_SKILL = new SkillHolder(6428, 1);
|
|
||||||
private static final SkillHolder ENERGY_PLANT_SKILL = new SkillHolder(6430, 1);
|
|
||||||
// Buffs
|
|
||||||
private static final SkillHolder[] BUFFS =
|
|
||||||
{
|
|
||||||
new SkillHolder(6625, 1), // Energy of Life
|
|
||||||
new SkillHolder(6626, 2), // Energy of Life's Power
|
|
||||||
new SkillHolder(6627, 3), // Energy of Life's Highest Power
|
|
||||||
new SkillHolder(6628, 1), // Energy of Mana
|
|
||||||
new SkillHolder(6629, 2), // Energy of Mana's Power
|
|
||||||
new SkillHolder(6630, 3), // Energy of Mana's Highest Power
|
|
||||||
new SkillHolder(6631, 1), // Energy of Power
|
|
||||||
new SkillHolder(6633, 1), // Energy of Attack Speed
|
|
||||||
new SkillHolder(6635, 1), // Energy of Crt Rate
|
|
||||||
new SkillHolder(6636, 1), // Energy of Moving Speed
|
|
||||||
new SkillHolder(6638, 1), // Aura of Mystery
|
|
||||||
new SkillHolder(6639, 1), // Bane of Auras - Damage
|
|
||||||
new SkillHolder(6640, 1), // Energizing Aura
|
|
||||||
new SkillHolder(6674, 1), // Energy of Range Increment
|
|
||||||
};
|
|
||||||
// Misc
|
|
||||||
// @formatter:off
|
|
||||||
private static final int[] BUFF_LIST =
|
|
||||||
{
|
|
||||||
6, 7, 8, 11, 13
|
|
||||||
};
|
|
||||||
// @formatter:on
|
|
||||||
|
|
||||||
private PlainsOfLizardman()
|
|
||||||
{
|
|
||||||
super(PlainsOfLizardman.class.getSimpleName(), "ai/group_template");
|
|
||||||
addAttackId(FANTASY_MUSHROOM, RAINBOW_FROG, STICKY_MUSHROOM, ENERGY_PLANT, TANTA_SUMMONER);
|
|
||||||
addKillId(TANTA_LIZARDMEN);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
|
||||||
{
|
|
||||||
if (event.equals("fantasy_mushroom") && (npc != null) && (player != null))
|
|
||||||
{
|
|
||||||
npc.doCast(FANTASY_MUSHROOM_SKILL.getSkill());
|
|
||||||
for (L2Character target : npc.getKnownList().getKnownCharactersInRadius(200))
|
|
||||||
{
|
|
||||||
if ((target != null) && target.isAttackable())
|
|
||||||
{
|
|
||||||
final L2Npc monster = (L2Npc) target;
|
|
||||||
npc.setTarget(monster);
|
|
||||||
npc.doCast(STUN_EFFECT.getSkill());
|
|
||||||
addAttackPlayerDesire(monster, player);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
npc.doDie(player);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String onAttack(L2Npc npc, L2PcInstance attacker, int damage, boolean isSummon)
|
|
||||||
{
|
|
||||||
switch (npc.getId())
|
|
||||||
{
|
|
||||||
case TANTA_SUMMONER:
|
|
||||||
if (!npc.isAffectedBySkill(DEMOTIVATION_HEX.getSkillId()))
|
|
||||||
{
|
|
||||||
npc.doCast(DEMOTIVATION_HEX.getSkill());
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case RAINBOW_FROG:
|
|
||||||
castSkill(npc, attacker, RAINBOW_FROG_SKILL);
|
|
||||||
break;
|
|
||||||
case ENERGY_PLANT:
|
|
||||||
castSkill(npc, attacker, ENERGY_PLANT_SKILL);
|
|
||||||
break;
|
|
||||||
case STICKY_MUSHROOM:
|
|
||||||
castSkill(npc, attacker, STICKY_MUSHROOM_SKILL);
|
|
||||||
break;
|
|
||||||
case FANTASY_MUSHROOM:
|
|
||||||
if (npc.isScriptValue(0))
|
|
||||||
{
|
|
||||||
npc.setScriptValue(1);
|
|
||||||
npc.setIsInvul(true);
|
|
||||||
for (L2Character target : npc.getKnownList().getKnownCharactersInRadius(1000))
|
|
||||||
{
|
|
||||||
if ((target != null) && target.isAttackable())
|
|
||||||
{
|
|
||||||
final L2Attackable monster = (L2Attackable) target;
|
|
||||||
if ((monster.getId() == TANTA_MAGICIAN) || (monster.getId() == TANTA_SCOUT))
|
|
||||||
{
|
|
||||||
target.setIsRunning(true);
|
|
||||||
target.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, new Location(npc.getX(), npc.getY(), npc.getZ(), 0));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
startQuestTimer("fantasy_mushroom", 4000, npc, attacker);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return super.onAttack(npc, attacker, damage, isSummon);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
|
|
||||||
{
|
|
||||||
// Tanta Guard
|
|
||||||
if (getRandom(1000) == 0)
|
|
||||||
{
|
|
||||||
addAttackPlayerDesire(addSpawn(TANTA_GUARD, npc), killer);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Invisible buff npc
|
|
||||||
final int random = getRandom(100);
|
|
||||||
final L2Npc buffer = addSpawn(INVISIBLE_NPC, npc.getLocation(), false, 6000);
|
|
||||||
buffer.setTarget(killer);
|
|
||||||
|
|
||||||
if (random <= 42)
|
|
||||||
{
|
|
||||||
castRandomBuff(buffer, 7, 45, BUFFS[0], BUFFS[1], BUFFS[2]);
|
|
||||||
}
|
|
||||||
if (random <= 11)
|
|
||||||
{
|
|
||||||
castRandomBuff(buffer, 8, 60, BUFFS[3], BUFFS[4], BUFFS[5]);
|
|
||||||
castRandomBuff(buffer, 3, 6, BUFFS[9], BUFFS[10], BUFFS[12]);
|
|
||||||
}
|
|
||||||
if (random <= 25)
|
|
||||||
{
|
|
||||||
buffer.doCast(BUFFS[BUFF_LIST[getRandom(BUFF_LIST.length)]].getSkill());
|
|
||||||
}
|
|
||||||
if (random <= 10)
|
|
||||||
{
|
|
||||||
buffer.doCast(BUFFS[13].getSkill());
|
|
||||||
}
|
|
||||||
if (random <= 1)
|
|
||||||
{
|
|
||||||
final int i = getRandom(100);
|
|
||||||
if (i <= 34)
|
|
||||||
{
|
|
||||||
buffer.doCast(BUFFS[6].getSkill());
|
|
||||||
buffer.doCast(BUFFS[7].getSkill());
|
|
||||||
buffer.doCast(BUFFS[8].getSkill());
|
|
||||||
}
|
|
||||||
else if (i < 67)
|
|
||||||
{
|
|
||||||
buffer.doCast(BUFFS[13].getSkill());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
buffer.doCast(BUFFS[2].getSkill());
|
|
||||||
buffer.doCast(BUFFS[5].getSkill());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return super.onKill(npc, killer, isSummon);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void castRandomBuff(L2Npc npc, int chance1, int chance2, SkillHolder... buffs)
|
|
||||||
{
|
|
||||||
final int rand = getRandom(100);
|
|
||||||
if (rand <= chance1)
|
|
||||||
{
|
|
||||||
npc.doCast(buffs[2].getSkill());
|
|
||||||
}
|
|
||||||
else if (rand <= chance2)
|
|
||||||
{
|
|
||||||
npc.doCast(buffs[1].getSkill());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
npc.doCast(buffs[0].getSkill());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void castSkill(L2Npc npc, L2Playable target, SkillHolder skill)
|
|
||||||
{
|
|
||||||
npc.doDie(target);
|
|
||||||
super.castSkill(addSpawn(INVISIBLE_NPC, npc, false, 6000), target, skill);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void main(String[] args)
|
|
||||||
{
|
|
||||||
new PlainsOfLizardman();
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,161 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2004-2015 L2J DataPack
|
|
||||||
*
|
|
||||||
* This file is part of L2J DataPack.
|
|
||||||
*
|
|
||||||
* L2J DataPack 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.
|
|
||||||
*
|
|
||||||
* L2J DataPack 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.group_template;
|
|
||||||
|
|
||||||
import ai.npc.AbstractNpcAI;
|
|
||||||
|
|
||||||
import com.l2jserver.gameserver.enums.ChatType;
|
|
||||||
import com.l2jserver.gameserver.model.L2Object;
|
|
||||||
import com.l2jserver.gameserver.model.actor.L2Attackable;
|
|
||||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
|
||||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
|
||||||
import com.l2jserver.gameserver.model.holders.SkillHolder;
|
|
||||||
import com.l2jserver.gameserver.model.skills.Skill;
|
|
||||||
import com.l2jserver.gameserver.network.NpcStringId;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Prison Guards AI.
|
|
||||||
* @author St3eT
|
|
||||||
*/
|
|
||||||
public final class PrisonGuards extends AbstractNpcAI
|
|
||||||
{
|
|
||||||
// NPCs
|
|
||||||
private static final int GUARD_HEAD = 18367; // Prison Guard
|
|
||||||
private static final int GUARD = 18368; // Prison Guard
|
|
||||||
// Item
|
|
||||||
private static final int STAMP = 10013; // Race Stamp
|
|
||||||
// Skills
|
|
||||||
private static final int TIMER = 5239; // Event Timer
|
|
||||||
private static final SkillHolder STONE = new SkillHolder(4578, 1); // Petrification
|
|
||||||
private static final SkillHolder SILENCE = new SkillHolder(4098, 9); // Silence
|
|
||||||
|
|
||||||
private PrisonGuards()
|
|
||||||
{
|
|
||||||
super(PrisonGuards.class.getSimpleName(), "ai/group_template");
|
|
||||||
addAttackId(GUARD_HEAD, GUARD);
|
|
||||||
addSpawnId(GUARD_HEAD, GUARD);
|
|
||||||
addNpcHateId(GUARD);
|
|
||||||
addSkillSeeId(GUARD);
|
|
||||||
addSpellFinishedId(GUARD_HEAD, GUARD);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
|
||||||
{
|
|
||||||
if (event.equals("CLEAR_STATUS"))
|
|
||||||
{
|
|
||||||
npc.setScriptValue(0);
|
|
||||||
}
|
|
||||||
else if (event.equals("CHECK_HOME"))
|
|
||||||
{
|
|
||||||
if ((npc.calculateDistance(npc.getSpawn().getLocation(), false, false) > 10) && !npc.isInCombat() && !npc.isDead())
|
|
||||||
{
|
|
||||||
npc.teleToLocation(npc.getSpawn().getLocation());
|
|
||||||
}
|
|
||||||
startQuestTimer("CHECK_HOME", 30000, npc, null);
|
|
||||||
}
|
|
||||||
return super.onAdvEvent(event, npc, player);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String onAttack(L2Npc npc, L2PcInstance player, int damage, boolean isSummon)
|
|
||||||
{
|
|
||||||
if (npc.getId() == GUARD_HEAD)
|
|
||||||
{
|
|
||||||
if (player.isAffectedBySkill(TIMER))
|
|
||||||
{
|
|
||||||
if ((getRandom(100) < 10) && (npc.calculateDistance(player, true, false) < 100))
|
|
||||||
{
|
|
||||||
if ((getQuestItemsCount(player, STAMP) <= 3) && npc.isScriptValue(0))
|
|
||||||
{
|
|
||||||
giveItems(player, STAMP, 1);
|
|
||||||
npc.setScriptValue(1);
|
|
||||||
startQuestTimer("CLEAR_STATUS", 600000, npc, null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
npc.setTarget(player);
|
|
||||||
npc.doCast(STONE.getSkill());
|
|
||||||
broadcastNpcSay(npc, ChatType.NPC_GENERAL, NpcStringId.IT_S_NOT_EASY_TO_OBTAIN);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!player.isAffectedBySkill(TIMER) && (npc.calculateDistance(npc.getSpawn().getLocation(), false, false) < 2000))
|
|
||||||
{
|
|
||||||
npc.setTarget(player);
|
|
||||||
npc.doCast(STONE.getSkill());
|
|
||||||
broadcastNpcSay(npc, ChatType.NPC_GENERAL, NpcStringId.YOU_RE_OUT_OF_YOUR_MIND_COMING_HERE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return super.onAttack(npc, player, damage, isSummon);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String onSkillSee(L2Npc npc, L2PcInstance caster, Skill skill, L2Object[] targets, boolean isSummon)
|
|
||||||
{
|
|
||||||
if (!caster.isAffectedBySkill(TIMER))
|
|
||||||
{
|
|
||||||
npc.setTarget(caster);
|
|
||||||
npc.doCast(SILENCE.getSkill());
|
|
||||||
}
|
|
||||||
return super.onSkillSee(npc, caster, skill, targets, isSummon);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String onSpellFinished(L2Npc npc, L2PcInstance player, Skill skill)
|
|
||||||
{
|
|
||||||
if ((skill == SILENCE.getSkill()) || (skill == STONE.getSkill()))
|
|
||||||
{
|
|
||||||
((L2Attackable) npc).clearAggroList();
|
|
||||||
npc.setTarget(npc);
|
|
||||||
}
|
|
||||||
return super.onSpellFinished(npc, player, skill);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onNpcHate(L2Attackable mob, L2PcInstance player, boolean isSummon)
|
|
||||||
{
|
|
||||||
return player.isAffectedBySkill(TIMER);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String onSpawn(L2Npc npc)
|
|
||||||
{
|
|
||||||
if (npc.getId() == GUARD_HEAD)
|
|
||||||
{
|
|
||||||
npc.setIsImmobilized(true);
|
|
||||||
npc.setIsInvul(true);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
npc.setIsNoRndWalk(true);
|
|
||||||
cancelQuestTimer("CHECK_HOME", npc, null);
|
|
||||||
startQuestTimer("CHECK_HOME", 30000, npc, null);
|
|
||||||
}
|
|
||||||
return super.onSpawn(npc);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void main(String[] args)
|
|
||||||
{
|
|
||||||
new PrisonGuards();
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,123 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2004-2015 L2J DataPack
|
|
||||||
*
|
|
||||||
* This file is part of L2J DataPack.
|
|
||||||
*
|
|
||||||
* L2J DataPack 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.
|
|
||||||
*
|
|
||||||
* L2J DataPack 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.group_template;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import ai.npc.AbstractNpcAI;
|
|
||||||
|
|
||||||
import com.l2jserver.gameserver.ThreadPoolManager;
|
|
||||||
import com.l2jserver.gameserver.model.Location;
|
|
||||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Manages spawn of NPCs having several random spawn points.
|
|
||||||
* @author GKR
|
|
||||||
*/
|
|
||||||
public final class RandomSpawn extends AbstractNpcAI
|
|
||||||
{
|
|
||||||
private static final Map<Integer, Location[]> SPAWN_POINTS = new HashMap<>();
|
|
||||||
static
|
|
||||||
{
|
|
||||||
// Keltas
|
|
||||||
SPAWN_POINTS.put(22341, new Location[]
|
|
||||||
{
|
|
||||||
new Location(-27136, 250938, -3523),
|
|
||||||
new Location(-29658, 252897, -3523),
|
|
||||||
new Location(-27237, 251943, -3527),
|
|
||||||
new Location(-28868, 250113, -3479)
|
|
||||||
});
|
|
||||||
// Keymaster
|
|
||||||
SPAWN_POINTS.put(22361, new Location[]
|
|
||||||
{
|
|
||||||
new Location(14091, 250533, -1940),
|
|
||||||
new Location(15762, 252440, -2015),
|
|
||||||
new Location(19836, 256212, -2090),
|
|
||||||
new Location(21940, 254107, -2010),
|
|
||||||
new Location(17299, 252943, -2015),
|
|
||||||
});
|
|
||||||
// Typhoon
|
|
||||||
SPAWN_POINTS.put(25539, new Location[]
|
|
||||||
{
|
|
||||||
new Location(-20641, 255370, -3235),
|
|
||||||
new Location(-16157, 250993, -3058),
|
|
||||||
new Location(-18269, 250721, -3151),
|
|
||||||
new Location(-16532, 254864, -3223),
|
|
||||||
new Location(-19055, 253489, -3440),
|
|
||||||
new Location(-9684, 254256, -3148),
|
|
||||||
new Location(-6209, 251924, -3189),
|
|
||||||
new Location(-10547, 251359, -2929),
|
|
||||||
new Location(-7254, 254997, -3261),
|
|
||||||
new Location(-4883, 253171, -3322)
|
|
||||||
});
|
|
||||||
// Mutated Elpy
|
|
||||||
SPAWN_POINTS.put(25604, new Location[]
|
|
||||||
{
|
|
||||||
new Location(-46080, 246368, -14183),
|
|
||||||
new Location(-44816, 246368, -14183),
|
|
||||||
new Location(-44224, 247440, -14184),
|
|
||||||
new Location(-44896, 248464, -14183),
|
|
||||||
new Location(-46064, 248544, -14183),
|
|
||||||
new Location(-46720, 247424, -14183)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public RandomSpawn()
|
|
||||||
{
|
|
||||||
super(RandomSpawn.class.getSimpleName(), "ai/group_template");
|
|
||||||
addSpawnId(SPAWN_POINTS.keySet());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public final String onSpawn(L2Npc npc)
|
|
||||||
{
|
|
||||||
final Location[] spawnlist = SPAWN_POINTS.get(npc.getId());
|
|
||||||
final Location loc = spawnlist[getRandom(spawnlist.length)];
|
|
||||||
if (!npc.isInsideRadius(loc, 200, false, false))
|
|
||||||
{
|
|
||||||
npc.getSpawn().setLocation(loc);
|
|
||||||
ThreadPoolManager.getInstance().scheduleGeneral(new Teleport(npc, loc), 100);
|
|
||||||
}
|
|
||||||
return super.onSpawn(npc);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class Teleport implements Runnable
|
|
||||||
{
|
|
||||||
private final L2Npc _npc;
|
|
||||||
private final Location _loc;
|
|
||||||
|
|
||||||
public Teleport(L2Npc npc, Location loc)
|
|
||||||
{
|
|
||||||
_npc = npc;
|
|
||||||
_loc = loc;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run()
|
|
||||||
{
|
|
||||||
_npc.teleToLocation(_loc, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void main(String[] args)
|
|
||||||
{
|
|
||||||
new RandomSpawn();
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,63 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2004-2015 L2J DataPack
|
|
||||||
*
|
|
||||||
* This file is part of L2J DataPack.
|
|
||||||
*
|
|
||||||
* L2J DataPack 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.
|
|
||||||
*
|
|
||||||
* L2J DataPack 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.group_template;
|
|
||||||
|
|
||||||
import ai.npc.AbstractNpcAI;
|
|
||||||
|
|
||||||
import com.l2jserver.gameserver.model.actor.L2Attackable;
|
|
||||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* See Through Silent Move AI.
|
|
||||||
* @author Gigiikun
|
|
||||||
*/
|
|
||||||
public class SeeThroughSilentMove extends AbstractNpcAI
|
|
||||||
{
|
|
||||||
//@formatter:off
|
|
||||||
private static final int[] MONSTERS =
|
|
||||||
{
|
|
||||||
18001, 18002, 22199, 22215, 22216, 22217, 22327, 22746, 22747, 22748,
|
|
||||||
22749, 22750, 22751, 22752, 22753, 22754, 22755, 22756, 22757, 22758,
|
|
||||||
22759, 22760, 22761, 22762, 22763, 22764, 22765, 22794, 22795, 22796,
|
|
||||||
22797, 22798, 22799, 22800, 22843, 22857, 25725, 25726, 25727, 29009,
|
|
||||||
29010, 29011, 29012, 29013
|
|
||||||
};
|
|
||||||
//@formatter:on
|
|
||||||
|
|
||||||
private SeeThroughSilentMove()
|
|
||||||
{
|
|
||||||
super(SeeThroughSilentMove.class.getSimpleName(), "ai/group_template");
|
|
||||||
addSpawnId(MONSTERS);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String onSpawn(L2Npc npc)
|
|
||||||
{
|
|
||||||
if (npc.isAttackable())
|
|
||||||
{
|
|
||||||
((L2Attackable) npc).setSeeThroughSilentMove(true);
|
|
||||||
}
|
|
||||||
return super.onSpawn(npc);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void main(String[] args)
|
|
||||||
{
|
|
||||||
new SeeThroughSilentMove();
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,244 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2004-2015 L2J DataPack
|
|
||||||
*
|
|
||||||
* This file is part of L2J DataPack.
|
|
||||||
*
|
|
||||||
* L2J DataPack 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.
|
|
||||||
*
|
|
||||||
* L2J DataPack 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.group_template;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import ai.npc.AbstractNpcAI;
|
|
||||||
|
|
||||||
import com.l2jserver.gameserver.datatables.SkillData;
|
|
||||||
import com.l2jserver.gameserver.model.L2Object;
|
|
||||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
|
||||||
import com.l2jserver.gameserver.model.actor.instance.L2MonsterInstance;
|
|
||||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
|
||||||
import com.l2jserver.gameserver.model.skills.Skill;
|
|
||||||
import com.l2jserver.gameserver.network.serverpackets.MagicSkillUse;
|
|
||||||
import com.l2jserver.gameserver.util.Broadcast;
|
|
||||||
import com.l2jserver.gameserver.util.Util;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Stakato Nest AI.
|
|
||||||
* @author Gnacik
|
|
||||||
*/
|
|
||||||
public final class StakatoNest extends AbstractNpcAI
|
|
||||||
{
|
|
||||||
// @formatter:off
|
|
||||||
// List of all mobs just for register
|
|
||||||
private static final int[] STAKATO_MOBS =
|
|
||||||
{
|
|
||||||
18793, 18794, 18795, 18796, 18797, 18798, 22617, 22618, 22619, 22620,
|
|
||||||
22621, 22622, 22623, 22624, 22625, 22626, 22627, 22628, 22629, 22630,
|
|
||||||
22631, 22632, 22633, 25667
|
|
||||||
};
|
|
||||||
// Coocons
|
|
||||||
private static final int[] COCOONS =
|
|
||||||
{
|
|
||||||
18793, 18794, 18795, 18796, 18797, 18798
|
|
||||||
};
|
|
||||||
// @formatter:on
|
|
||||||
// Cannibalistic Stakato Leader
|
|
||||||
private static final int STAKATO_LEADER = 22625;
|
|
||||||
|
|
||||||
// Spike Stakato Nurse
|
|
||||||
private static final int STAKATO_NURSE = 22630;
|
|
||||||
// Spike Stakato Nurse (Changed)
|
|
||||||
private static final int STAKATO_NURSE_2 = 22631;
|
|
||||||
// Spiked Stakato Baby
|
|
||||||
private static final int STAKATO_BABY = 22632;
|
|
||||||
// Spiked Stakato Captain
|
|
||||||
private static final int STAKATO_CAPTAIN = 22629;
|
|
||||||
|
|
||||||
// Female Spiked Stakato
|
|
||||||
private static final int STAKATO_FEMALE = 22620;
|
|
||||||
// Male Spiked Stakato
|
|
||||||
private static final int STAKATO_MALE = 22621;
|
|
||||||
// Male Spiked Stakato (Changed)
|
|
||||||
private static final int STAKATO_MALE_2 = 22622;
|
|
||||||
// Spiked Stakato Guard
|
|
||||||
private static final int STAKATO_GUARD = 22619;
|
|
||||||
|
|
||||||
// Cannibalistic Stakato Chief
|
|
||||||
private static final int STAKATO_CHIEF = 25667;
|
|
||||||
// Growth Accelerator
|
|
||||||
private static final int GROWTH_ACCELERATOR = 2905;
|
|
||||||
// Small Stakato Cocoon
|
|
||||||
private static final int SMALL_COCOON = 14833;
|
|
||||||
// Large Stakato Cocoon
|
|
||||||
private static final int LARGE_COCOON = 14834;
|
|
||||||
|
|
||||||
private StakatoNest()
|
|
||||||
{
|
|
||||||
super(StakatoNest.class.getSimpleName(), "ai/group_template");
|
|
||||||
registerMobs(STAKATO_MOBS);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String onAttack(L2Npc npc, L2PcInstance attacker, int damage, boolean isSummon)
|
|
||||||
{
|
|
||||||
final L2MonsterInstance mob = (L2MonsterInstance) npc;
|
|
||||||
|
|
||||||
if ((mob.getId() == STAKATO_LEADER) && (getRandom(1000) < 100) && (mob.getCurrentHp() < (mob.getMaxHp() * 0.3)))
|
|
||||||
{
|
|
||||||
final L2MonsterInstance _follower = checkMinion(npc);
|
|
||||||
|
|
||||||
if (_follower != null)
|
|
||||||
{
|
|
||||||
double _hp = _follower.getCurrentHp();
|
|
||||||
|
|
||||||
if (_hp > (_follower.getMaxHp() * 0.3))
|
|
||||||
{
|
|
||||||
mob.abortAttack();
|
|
||||||
mob.abortCast();
|
|
||||||
mob.setHeading(Util.calculateHeadingFrom(mob, _follower));
|
|
||||||
mob.doCast(SkillData.getInstance().getSkill(4484, 1));
|
|
||||||
mob.setCurrentHp(mob.getCurrentHp() + _hp);
|
|
||||||
_follower.doDie(_follower);
|
|
||||||
_follower.deleteMe();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return super.onAttack(npc, attacker, damage, isSummon);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
|
|
||||||
{
|
|
||||||
final L2MonsterInstance monster;
|
|
||||||
switch (npc.getId())
|
|
||||||
{
|
|
||||||
case STAKATO_NURSE:
|
|
||||||
monster = checkMinion(npc);
|
|
||||||
if (monster != null)
|
|
||||||
{
|
|
||||||
Broadcast.toSelfAndKnownPlayers(npc, new MagicSkillUse(npc, 2046, 1, 1000, 0));
|
|
||||||
for (int i = 0; i < 3; i++)
|
|
||||||
{
|
|
||||||
L2Npc spawned = addSpawn(STAKATO_CAPTAIN, monster, true);
|
|
||||||
addAttackPlayerDesire(spawned, killer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case STAKATO_BABY:
|
|
||||||
monster = ((L2MonsterInstance) npc).getLeader();
|
|
||||||
if ((monster != null) && !monster.isDead())
|
|
||||||
{
|
|
||||||
startQuestTimer("nurse_change", 5000, monster, killer);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case STAKATO_MALE:
|
|
||||||
monster = checkMinion(npc);
|
|
||||||
if (monster != null)
|
|
||||||
{
|
|
||||||
Broadcast.toSelfAndKnownPlayers(npc, new MagicSkillUse(npc, 2046, 1, 1000, 0));
|
|
||||||
for (int i = 0; i < 3; i++)
|
|
||||||
{
|
|
||||||
L2Npc spawned = addSpawn(STAKATO_GUARD, monster, true);
|
|
||||||
addAttackPlayerDesire(spawned, killer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case STAKATO_FEMALE:
|
|
||||||
monster = ((L2MonsterInstance) npc).getLeader();
|
|
||||||
if ((monster != null) && !monster.isDead())
|
|
||||||
{
|
|
||||||
startQuestTimer("male_change", 5000, monster, killer);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case STAKATO_CHIEF:
|
|
||||||
if (killer.isInParty())
|
|
||||||
{
|
|
||||||
List<L2PcInstance> party = killer.getParty().getMembers();
|
|
||||||
for (L2PcInstance member : party)
|
|
||||||
{
|
|
||||||
giveCocoon(member, npc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
giveCocoon(killer, npc);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return super.onKill(npc, killer, isSummon);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String onSkillSee(L2Npc npc, L2PcInstance caster, Skill skill, L2Object[] targets, boolean isSummon)
|
|
||||||
{
|
|
||||||
if (Util.contains(COCOONS, npc.getId()) && Util.contains(targets, npc) && (skill.getId() == GROWTH_ACCELERATOR))
|
|
||||||
{
|
|
||||||
npc.doDie(caster);
|
|
||||||
final L2Npc spawned = addSpawn(STAKATO_CHIEF, npc.getX(), npc.getY(), npc.getZ(), Util.calculateHeadingFrom(npc, caster), false, 0, true);
|
|
||||||
addAttackPlayerDesire(spawned, caster);
|
|
||||||
}
|
|
||||||
return super.onSkillSee(npc, caster, skill, targets, isSummon);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public final String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
|
||||||
{
|
|
||||||
if ((npc == null) || (player == null) || npc.isDead())
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
int npcId = 0;
|
|
||||||
switch (event)
|
|
||||||
{
|
|
||||||
case "nurse_change":
|
|
||||||
npcId = STAKATO_NURSE_2;
|
|
||||||
break;
|
|
||||||
case "male_change":
|
|
||||||
npcId = STAKATO_MALE_2;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (npcId > 0)
|
|
||||||
{
|
|
||||||
npc.getSpawn().decreaseCount(npc);
|
|
||||||
npc.deleteMe();
|
|
||||||
final L2Npc spawned = addSpawn(npcId, npc.getX(), npc.getY(), npc.getZ(), npc.getHeading(), false, 0, true);
|
|
||||||
addAttackPlayerDesire(spawned, player);
|
|
||||||
}
|
|
||||||
return super.onAdvEvent(event, npc, player);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static L2MonsterInstance checkMinion(L2Npc npc)
|
|
||||||
{
|
|
||||||
final L2MonsterInstance mob = (L2MonsterInstance) npc;
|
|
||||||
if (mob.hasMinions())
|
|
||||||
{
|
|
||||||
final List<L2MonsterInstance> minion = mob.getMinionList().getSpawnedMinions();
|
|
||||||
if ((minion != null) && !minion.isEmpty() && (minion.get(0) != null) && !minion.get(0).isDead())
|
|
||||||
{
|
|
||||||
return minion.get(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void giveCocoon(L2PcInstance player, L2Npc npc)
|
|
||||||
{
|
|
||||||
player.addItem("StakatoCocoon", ((getRandom(100) > 80) ? LARGE_COCOON : SMALL_COCOON), 1, npc, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void main(String[] args)
|
|
||||||
{
|
|
||||||
new StakatoNest();
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,107 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2004-2015 L2J DataPack
|
|
||||||
*
|
|
||||||
* This file is part of L2J DataPack.
|
|
||||||
*
|
|
||||||
* L2J DataPack 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.
|
|
||||||
*
|
|
||||||
* L2J DataPack 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.individual;
|
|
||||||
|
|
||||||
import ai.npc.AbstractNpcAI;
|
|
||||||
|
|
||||||
import com.l2jserver.gameserver.enums.ChatType;
|
|
||||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
|
||||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
|
||||||
import com.l2jserver.gameserver.model.holders.SkillHolder;
|
|
||||||
import com.l2jserver.gameserver.network.NpcStringId;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* AI for Kamaloka (33) - Crimson Hatu Otis
|
|
||||||
* @author Gladicek
|
|
||||||
*/
|
|
||||||
public final class CrimsonHatuOtis extends AbstractNpcAI
|
|
||||||
{
|
|
||||||
// Npc
|
|
||||||
private static final int CRIMSON_HATU_OTIS = 18558;
|
|
||||||
// Skills
|
|
||||||
private static SkillHolder BOSS_SPINING_SLASH = new SkillHolder(4737, 1);
|
|
||||||
private static SkillHolder BOSS_HASTE = new SkillHolder(4175, 1);
|
|
||||||
|
|
||||||
private CrimsonHatuOtis()
|
|
||||||
{
|
|
||||||
super(CrimsonHatuOtis.class.getSimpleName(), "ai/individual");
|
|
||||||
addAttackId(CRIMSON_HATU_OTIS);
|
|
||||||
addKillId(CRIMSON_HATU_OTIS);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public final String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
|
||||||
{
|
|
||||||
switch (event)
|
|
||||||
{
|
|
||||||
case "SKILL":
|
|
||||||
{
|
|
||||||
if (npc.isDead())
|
|
||||||
{
|
|
||||||
cancelQuestTimer("SKILL", npc, null);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
npc.setTarget(player);
|
|
||||||
npc.doCast(BOSS_SPINING_SLASH.getSkill());
|
|
||||||
startQuestTimer("SKILL", 60000, npc, null);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case "BUFF":
|
|
||||||
{
|
|
||||||
if (npc.isScriptValue(2))
|
|
||||||
{
|
|
||||||
npc.setTarget(npc);
|
|
||||||
npc.doCast(BOSS_HASTE.getSkill());
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return super.onAdvEvent(event, npc, player);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String onAttack(L2Npc npc, L2PcInstance attacker, int damage, boolean isSummon)
|
|
||||||
{
|
|
||||||
if (npc.isScriptValue(0))
|
|
||||||
{
|
|
||||||
npc.setScriptValue(1);
|
|
||||||
startQuestTimer("SKILL", 5000, npc, null);
|
|
||||||
}
|
|
||||||
else if (npc.isScriptValue(1) && (npc.getCurrentHp() < (npc.getMaxHp() * 0.3)))
|
|
||||||
{
|
|
||||||
broadcastNpcSay(npc, ChatType.NPC_GENERAL, NpcStringId.I_VE_HAD_IT_UP_TO_HERE_WITH_YOU_I_LL_TAKE_CARE_OF_YOU);
|
|
||||||
npc.setScriptValue(2);
|
|
||||||
startQuestTimer("BUFF", 1000, npc, null);
|
|
||||||
}
|
|
||||||
return super.onAttack(npc, attacker, damage, isSummon);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String onKill(L2Npc npc, L2PcInstance player, boolean isSummon)
|
|
||||||
{
|
|
||||||
cancelQuestTimer("SKILL", npc, null);
|
|
||||||
cancelQuestTimer("BUFF", npc, null);
|
|
||||||
return super.onKill(npc, player, isSummon);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void main(String[] args)
|
|
||||||
{
|
|
||||||
new CrimsonHatuOtis();
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,247 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2004-2015 L2J DataPack
|
|
||||||
*
|
|
||||||
* This file is part of L2J DataPack.
|
|
||||||
*
|
|
||||||
* L2J DataPack 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.
|
|
||||||
*
|
|
||||||
* L2J DataPack 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.individual;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
|
||||||
|
|
||||||
import ai.npc.AbstractNpcAI;
|
|
||||||
|
|
||||||
import com.l2jserver.gameserver.ai.CtrlIntention;
|
|
||||||
import com.l2jserver.gameserver.data.xml.impl.NpcData;
|
|
||||||
import com.l2jserver.gameserver.model.actor.L2Attackable;
|
|
||||||
import com.l2jserver.gameserver.model.actor.L2Character;
|
|
||||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
|
||||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Dark Water Dragon's AI.
|
|
||||||
*/
|
|
||||||
public final class DarkWaterDragon extends AbstractNpcAI
|
|
||||||
{
|
|
||||||
private static final int DRAGON = 22267;
|
|
||||||
private static final int SHADE1 = 22268;
|
|
||||||
private static final int SHADE2 = 22269;
|
|
||||||
private static final int FAFURION = 18482;
|
|
||||||
private static final int DETRACTOR1 = 22270;
|
|
||||||
private static final int DETRACTOR2 = 22271;
|
|
||||||
private static final Set<Integer> SECOND_SPAWN = ConcurrentHashMap.newKeySet(); // Used to track if second Shades were already spawned
|
|
||||||
private static Set<Integer> MY_TRACKING_SET = ConcurrentHashMap.newKeySet(); // Used to track instances of npcs
|
|
||||||
private static Map<Integer, L2PcInstance> ID_MAP = new ConcurrentHashMap<>(); // Used to track instances of npcs
|
|
||||||
|
|
||||||
private DarkWaterDragon()
|
|
||||||
{
|
|
||||||
super(DarkWaterDragon.class.getSimpleName(), "ai/individual");
|
|
||||||
int[] mobs =
|
|
||||||
{
|
|
||||||
DRAGON,
|
|
||||||
SHADE1,
|
|
||||||
SHADE2,
|
|
||||||
FAFURION,
|
|
||||||
DETRACTOR1,
|
|
||||||
DETRACTOR2
|
|
||||||
};
|
|
||||||
addKillId(mobs);
|
|
||||||
addAttackId(mobs);
|
|
||||||
addSpawnId(mobs);
|
|
||||||
MY_TRACKING_SET.clear();
|
|
||||||
SECOND_SPAWN.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
|
||||||
{
|
|
||||||
if (npc != null)
|
|
||||||
{
|
|
||||||
if (event.equalsIgnoreCase("first_spawn")) // timer to start timer "1"
|
|
||||||
{
|
|
||||||
startQuestTimer("1", 40000, npc, null, true); // spawns detractor every 40 seconds
|
|
||||||
}
|
|
||||||
else if (event.equalsIgnoreCase("second_spawn")) // timer to start timer "2"
|
|
||||||
{
|
|
||||||
startQuestTimer("2", 40000, npc, null, true); // spawns detractor every 40 seconds
|
|
||||||
}
|
|
||||||
else if (event.equalsIgnoreCase("third_spawn")) // timer to start timer "3"
|
|
||||||
{
|
|
||||||
startQuestTimer("3", 40000, npc, null, true); // spawns detractor every 40 seconds
|
|
||||||
}
|
|
||||||
else if (event.equalsIgnoreCase("fourth_spawn")) // timer to start timer "4"
|
|
||||||
{
|
|
||||||
startQuestTimer("4", 40000, npc, null, true); // spawns detractor every 40 seconds
|
|
||||||
}
|
|
||||||
else if (event.equalsIgnoreCase("1")) // spawns a detractor
|
|
||||||
{
|
|
||||||
addSpawn(DETRACTOR1, (npc.getX() + 100), (npc.getY() + 100), npc.getZ(), 0, false, 40000);
|
|
||||||
}
|
|
||||||
else if (event.equalsIgnoreCase("2")) // spawns a detractor
|
|
||||||
{
|
|
||||||
addSpawn(DETRACTOR2, (npc.getX() + 100), (npc.getY() - 100), npc.getZ(), 0, false, 40000);
|
|
||||||
}
|
|
||||||
else if (event.equalsIgnoreCase("3")) // spawns a detractor
|
|
||||||
{
|
|
||||||
addSpawn(DETRACTOR1, (npc.getX() - 100), (npc.getY() + 100), npc.getZ(), 0, false, 40000);
|
|
||||||
}
|
|
||||||
else if (event.equalsIgnoreCase("4")) // spawns a detractor
|
|
||||||
{
|
|
||||||
addSpawn(DETRACTOR2, (npc.getX() - 100), (npc.getY() - 100), npc.getZ(), 0, false, 40000);
|
|
||||||
}
|
|
||||||
else if (event.equalsIgnoreCase("fafurion_despawn")) // Fafurion Kindred disappears and drops reward
|
|
||||||
{
|
|
||||||
cancelQuestTimer("fafurion_poison", npc, null);
|
|
||||||
cancelQuestTimer("1", npc, null);
|
|
||||||
cancelQuestTimer("2", npc, null);
|
|
||||||
cancelQuestTimer("3", npc, null);
|
|
||||||
cancelQuestTimer("4", npc, null);
|
|
||||||
|
|
||||||
MY_TRACKING_SET.remove(npc.getObjectId());
|
|
||||||
player = ID_MAP.remove(npc.getObjectId());
|
|
||||||
if (player != null)
|
|
||||||
{
|
|
||||||
((L2Attackable) npc).doItemDrop(NpcData.getInstance().getTemplate(18485), player);
|
|
||||||
}
|
|
||||||
|
|
||||||
npc.deleteMe();
|
|
||||||
}
|
|
||||||
else if (event.equalsIgnoreCase("fafurion_poison")) // Reduces Fafurions hp like it is poisoned
|
|
||||||
{
|
|
||||||
if (npc.getCurrentHp() <= 500)
|
|
||||||
{
|
|
||||||
cancelQuestTimer("fafurion_despawn", npc, null);
|
|
||||||
cancelQuestTimer("first_spawn", npc, null);
|
|
||||||
cancelQuestTimer("second_spawn", npc, null);
|
|
||||||
cancelQuestTimer("third_spawn", npc, null);
|
|
||||||
cancelQuestTimer("fourth_spawn", npc, null);
|
|
||||||
cancelQuestTimer("1", npc, null);
|
|
||||||
cancelQuestTimer("2", npc, null);
|
|
||||||
cancelQuestTimer("3", npc, null);
|
|
||||||
cancelQuestTimer("4", npc, null);
|
|
||||||
MY_TRACKING_SET.remove(npc.getObjectId());
|
|
||||||
ID_MAP.remove(npc.getObjectId());
|
|
||||||
}
|
|
||||||
npc.reduceCurrentHp(500, npc, null); // poison kills Fafurion if he is not healed
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return super.onAdvEvent(event, npc, player);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String onAttack(L2Npc npc, L2PcInstance attacker, int damage, boolean isSummon)
|
|
||||||
{
|
|
||||||
int npcId = npc.getId();
|
|
||||||
int npcObjId = npc.getObjectId();
|
|
||||||
if (npcId == DRAGON)
|
|
||||||
{
|
|
||||||
if (!MY_TRACKING_SET.contains(npcObjId)) // this allows to handle multiple instances of npc
|
|
||||||
{
|
|
||||||
MY_TRACKING_SET.add(npcObjId);
|
|
||||||
// Spawn first 5 shades on first attack on Dark Water Dragon
|
|
||||||
L2Character originalAttacker = isSummon ? attacker.getServitors().values().stream().findFirst().orElse(attacker.getPet()) : attacker;
|
|
||||||
spawnShade(originalAttacker, SHADE1, npc.getX() + 100, npc.getY() + 100, npc.getZ());
|
|
||||||
spawnShade(originalAttacker, SHADE2, npc.getX() + 100, npc.getY() - 100, npc.getZ());
|
|
||||||
spawnShade(originalAttacker, SHADE1, npc.getX() - 100, npc.getY() + 100, npc.getZ());
|
|
||||||
spawnShade(originalAttacker, SHADE2, npc.getX() - 100, npc.getY() - 100, npc.getZ());
|
|
||||||
spawnShade(originalAttacker, SHADE1, npc.getX() - 150, npc.getY() + 150, npc.getZ());
|
|
||||||
}
|
|
||||||
else if ((npc.getCurrentHp() < (npc.getMaxHp() / 2.0)) && !(SECOND_SPAWN.contains(npcObjId)))
|
|
||||||
{
|
|
||||||
SECOND_SPAWN.add(npcObjId);
|
|
||||||
// Spawn second 5 shades on half hp of on Dark Water Dragon
|
|
||||||
L2Character originalAttacker = isSummon ? attacker.getServitors().values().stream().findFirst().orElse(attacker.getPet()) : attacker;
|
|
||||||
spawnShade(originalAttacker, SHADE2, npc.getX() + 100, npc.getY() + 100, npc.getZ());
|
|
||||||
spawnShade(originalAttacker, SHADE1, npc.getX() + 100, npc.getY() - 100, npc.getZ());
|
|
||||||
spawnShade(originalAttacker, SHADE2, npc.getX() - 100, npc.getY() + 100, npc.getZ());
|
|
||||||
spawnShade(originalAttacker, SHADE1, npc.getX() - 100, npc.getY() - 100, npc.getZ());
|
|
||||||
spawnShade(originalAttacker, SHADE2, npc.getX() - 150, npc.getY() + 150, npc.getZ());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return super.onAttack(npc, attacker, damage, isSummon);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
|
|
||||||
{
|
|
||||||
int npcId = npc.getId();
|
|
||||||
int npcObjId = npc.getObjectId();
|
|
||||||
if (npcId == DRAGON)
|
|
||||||
{
|
|
||||||
MY_TRACKING_SET.remove(npcObjId);
|
|
||||||
SECOND_SPAWN.remove(npcObjId);
|
|
||||||
L2Attackable faf = (L2Attackable) addSpawn(FAFURION, npc.getX(), npc.getY(), npc.getZ(), 0, false, 0); // spawns Fafurion Kindred when Dard Water Dragon is dead
|
|
||||||
ID_MAP.put(faf.getObjectId(), killer);
|
|
||||||
}
|
|
||||||
else if (npcId == FAFURION)
|
|
||||||
{
|
|
||||||
cancelQuestTimer("fafurion_poison", npc, null);
|
|
||||||
cancelQuestTimer("fafurion_despawn", npc, null);
|
|
||||||
cancelQuestTimer("first_spawn", npc, null);
|
|
||||||
cancelQuestTimer("second_spawn", npc, null);
|
|
||||||
cancelQuestTimer("third_spawn", npc, null);
|
|
||||||
cancelQuestTimer("fourth_spawn", npc, null);
|
|
||||||
cancelQuestTimer("1", npc, null);
|
|
||||||
cancelQuestTimer("2", npc, null);
|
|
||||||
cancelQuestTimer("3", npc, null);
|
|
||||||
cancelQuestTimer("4", npc, null);
|
|
||||||
MY_TRACKING_SET.remove(npcObjId);
|
|
||||||
ID_MAP.remove(npcObjId);
|
|
||||||
}
|
|
||||||
return super.onKill(npc, killer, isSummon);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String onSpawn(L2Npc npc)
|
|
||||||
{
|
|
||||||
int npcId = npc.getId();
|
|
||||||
int npcObjId = npc.getObjectId();
|
|
||||||
if (npcId == FAFURION)
|
|
||||||
{
|
|
||||||
if (!MY_TRACKING_SET.contains(npcObjId))
|
|
||||||
{
|
|
||||||
MY_TRACKING_SET.add(npcObjId);
|
|
||||||
// Spawn 4 Detractors on spawn of Fafurion
|
|
||||||
int x = npc.getX();
|
|
||||||
int y = npc.getY();
|
|
||||||
addSpawn(DETRACTOR2, x + 100, y + 100, npc.getZ(), 0, false, 40000);
|
|
||||||
addSpawn(DETRACTOR1, x + 100, y - 100, npc.getZ(), 0, false, 40000);
|
|
||||||
addSpawn(DETRACTOR2, x - 100, y + 100, npc.getZ(), 0, false, 40000);
|
|
||||||
addSpawn(DETRACTOR1, x - 100, y - 100, npc.getZ(), 0, false, 40000);
|
|
||||||
startQuestTimer("first_spawn", 2000, npc, null); // timer to delay timer "1"
|
|
||||||
startQuestTimer("second_spawn", 4000, npc, null); // timer to delay timer "2"
|
|
||||||
startQuestTimer("third_spawn", 8000, npc, null); // timer to delay timer "3"
|
|
||||||
startQuestTimer("fourth_spawn", 10000, npc, null); // timer to delay timer "4"
|
|
||||||
startQuestTimer("fafurion_poison", 3000, npc, null, true); // Every three seconds reduces Fafurions hp like it is poisoned
|
|
||||||
startQuestTimer("fafurion_despawn", 120000, npc, null); // Fafurion Kindred disappears after two minutes
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return super.onSpawn(npc);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void spawnShade(L2Character attacker, int npcId, int x, int y, int z)
|
|
||||||
{
|
|
||||||
final L2Npc shade = addSpawn(npcId, x, y, z, 0, false, 0);
|
|
||||||
shade.setRunning();
|
|
||||||
((L2Attackable) shade).addDamageHate(attacker, 0, 999);
|
|
||||||
shade.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, attacker);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void main(String[] args)
|
|
||||||
{
|
|
||||||
new DarkWaterDragon();
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,69 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2004-2015 L2J DataPack
|
|
||||||
*
|
|
||||||
* This file is part of L2J DataPack.
|
|
||||||
*
|
|
||||||
* L2J DataPack 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.
|
|
||||||
*
|
|
||||||
* L2J DataPack 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.individual;
|
|
||||||
|
|
||||||
import ai.npc.AbstractNpcAI;
|
|
||||||
|
|
||||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
|
||||||
import com.l2jserver.gameserver.model.actor.L2Summon;
|
|
||||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Simple AI that manages special conditions for Divine Beast summon.
|
|
||||||
* @author UnAfraid
|
|
||||||
*/
|
|
||||||
public final class DivineBeast extends AbstractNpcAI
|
|
||||||
{
|
|
||||||
private static final int DIVINE_BEAST = 14870;
|
|
||||||
private static final int TRANSFORMATION_ID = 258;
|
|
||||||
private static final int CHECK_TIME = 2 * 1000;
|
|
||||||
|
|
||||||
private DivineBeast()
|
|
||||||
{
|
|
||||||
super(DivineBeast.class.getSimpleName(), "ai");
|
|
||||||
addSummonSpawnId(DIVINE_BEAST);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onSummonSpawn(L2Summon summon)
|
|
||||||
{
|
|
||||||
startQuestTimer("VALIDATE_TRANSFORMATION", CHECK_TIME, null, summon.getActingPlayer(), true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
|
||||||
{
|
|
||||||
if ((player == null) || !player.hasServitors())
|
|
||||||
{
|
|
||||||
cancelQuestTimer(event, npc, player);
|
|
||||||
}
|
|
||||||
else if (player.getTransformationId() != TRANSFORMATION_ID)
|
|
||||||
{
|
|
||||||
cancelQuestTimer(event, npc, player);
|
|
||||||
player.getServitors().values().forEach(summon -> summon.unSummon(player));
|
|
||||||
}
|
|
||||||
|
|
||||||
return super.onAdvEvent(event, npc, player);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void main(String[] args)
|
|
||||||
{
|
|
||||||
new DivineBeast();
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,329 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2004-2015 L2J DataPack
|
|
||||||
*
|
|
||||||
* This file is part of L2J DataPack.
|
|
||||||
*
|
|
||||||
* L2J DataPack 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.
|
|
||||||
*
|
|
||||||
* L2J DataPack 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.individual;
|
|
||||||
|
|
||||||
import ai.npc.AbstractNpcAI;
|
|
||||||
|
|
||||||
import com.l2jserver.gameserver.ai.CtrlIntention;
|
|
||||||
import com.l2jserver.gameserver.enums.ChatType;
|
|
||||||
import com.l2jserver.gameserver.instancemanager.GrandBossManager;
|
|
||||||
import com.l2jserver.gameserver.model.Location;
|
|
||||||
import com.l2jserver.gameserver.model.StatsSet;
|
|
||||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
|
||||||
import com.l2jserver.gameserver.model.actor.instance.L2GrandBossInstance;
|
|
||||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
|
||||||
import com.l2jserver.gameserver.network.serverpackets.PlaySound;
|
|
||||||
import com.l2jserver.gameserver.network.serverpackets.SocialAction;
|
|
||||||
import com.l2jserver.gameserver.network.serverpackets.SpecialCamera;
|
|
||||||
import com.l2jserver.util.Rnd;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Dr. Chaos is a boss @ Pavel's Ruins. Some things to know :
|
|
||||||
* <ul>
|
|
||||||
* <li>As a mad scientist, he thinks all are spies, and for so if you stand too much longer near him you're considered as an "assassin from Black Anvil Guild".</li>
|
|
||||||
* <li>You can chat with him, but if you try too much he will become angry.</li>
|
|
||||||
* <li>That adaptation sends a decent cinematic made with the different social actions too.</li>
|
|
||||||
* <li>The status of the RB is saved under GBs table, in order to retrieve the state if server restarts.</li>
|
|
||||||
* <li>The spawn of the different NPCs (Dr. Chaos / War golem) is handled by that script aswell.</li>
|
|
||||||
* </ul>
|
|
||||||
* @author Kerberos, Tryskell.
|
|
||||||
*/
|
|
||||||
public class DrChaos extends AbstractNpcAI
|
|
||||||
{
|
|
||||||
private static final int DOCTOR_CHAOS = 32033;
|
|
||||||
private static final int CHAOS_GOLEM = 25512;
|
|
||||||
|
|
||||||
private static final byte NORMAL = 0; // Dr. Chaos is in NPC form.
|
|
||||||
private static final byte CRAZY = 1; // Dr. Chaos entered on golem form.
|
|
||||||
private static final byte DEAD = 2; // Dr. Chaos has been killed and has not yet spawned.
|
|
||||||
|
|
||||||
private long _lastAttackVsGolem = 0;
|
|
||||||
private int _pissedOffTimer;
|
|
||||||
|
|
||||||
public DrChaos()
|
|
||||||
{
|
|
||||||
super(DrChaos.class.getSimpleName(), "ai");
|
|
||||||
|
|
||||||
addFirstTalkId(DOCTOR_CHAOS); // Different HTMs following actual humor.
|
|
||||||
addSpawnId(DOCTOR_CHAOS); // Timer activation at 30sec + paranoia activity.
|
|
||||||
|
|
||||||
addKillId(CHAOS_GOLEM); // Message + despawn.
|
|
||||||
addAttackId(CHAOS_GOLEM); // Random messages when he attacks.
|
|
||||||
|
|
||||||
StatsSet info = GrandBossManager.getInstance().getStatsSet(CHAOS_GOLEM);
|
|
||||||
int status = GrandBossManager.getInstance().getBossStatus(CHAOS_GOLEM);
|
|
||||||
|
|
||||||
// Load the reset date and time for Dr. Chaos from DB.
|
|
||||||
if (status == DEAD)
|
|
||||||
{
|
|
||||||
long temp = (info.getLong("respawn_time") - System.currentTimeMillis());
|
|
||||||
if (temp > 0)
|
|
||||||
{
|
|
||||||
startQuestTimer("reset_drchaos", temp, null, null, false);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// The time has already expired while the server was offline. Delete the saved time and
|
|
||||||
// immediately spawn Dr. Chaos. Also the state need to be changed for NORMAL
|
|
||||||
addSpawn(DOCTOR_CHAOS, 96320, -110912, -3328, 8191, false, 0, false);
|
|
||||||
GrandBossManager.getInstance().setBossStatus(CHAOS_GOLEM, NORMAL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Spawn the war golem.
|
|
||||||
else if (status == CRAZY)
|
|
||||||
{
|
|
||||||
int loc_x = info.getInt("loc_x");
|
|
||||||
int loc_y = info.getInt("loc_y");
|
|
||||||
int loc_z = info.getInt("loc_z");
|
|
||||||
int heading = info.getInt("heading");
|
|
||||||
final int hp = info.getInt("currentHP");
|
|
||||||
final int mp = info.getInt("currentMP");
|
|
||||||
|
|
||||||
L2GrandBossInstance golem = (L2GrandBossInstance) addSpawn(CHAOS_GOLEM, loc_x, loc_y, loc_z, heading, false, 0, false);
|
|
||||||
GrandBossManager.getInstance().addBoss(golem);
|
|
||||||
|
|
||||||
final L2Npc _golem = golem;
|
|
||||||
|
|
||||||
_golem.setCurrentHpMp(hp, mp);
|
|
||||||
_golem.setRunning();
|
|
||||||
|
|
||||||
// start monitoring Dr. Chaos's inactivity
|
|
||||||
_lastAttackVsGolem = System.currentTimeMillis();
|
|
||||||
startQuestTimer("golem_despawn", 60000, _golem, null, true);
|
|
||||||
}
|
|
||||||
// Spawn the regular NPC.
|
|
||||||
else
|
|
||||||
{
|
|
||||||
addSpawn(DOCTOR_CHAOS, 96320, -110912, -3328, 8191, false, 0, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
|
||||||
{
|
|
||||||
if (event.equalsIgnoreCase("reset_drchaos"))
|
|
||||||
{
|
|
||||||
GrandBossManager.getInstance().setBossStatus(CHAOS_GOLEM, NORMAL);
|
|
||||||
addSpawn(DOCTOR_CHAOS, 96320, -110912, -3328, 8191, false, 0, false);
|
|
||||||
}
|
|
||||||
// despawn the live Dr. Chaos after 30 minutes of inactivity
|
|
||||||
else if (event.equalsIgnoreCase("golem_despawn") && (npc != null))
|
|
||||||
{
|
|
||||||
if (npc.getId() == CHAOS_GOLEM)
|
|
||||||
{
|
|
||||||
if ((_lastAttackVsGolem + 1800000) < System.currentTimeMillis())
|
|
||||||
{
|
|
||||||
// Despawn the war golem.
|
|
||||||
npc.deleteMe();
|
|
||||||
|
|
||||||
addSpawn(DOCTOR_CHAOS, 96320, -110912, -3328, 8191, false, 0, false); // spawn Dr. Chaos
|
|
||||||
GrandBossManager.getInstance().setBossStatus(CHAOS_GOLEM, NORMAL); // mark Dr. Chaos is not crazy any more
|
|
||||||
cancelQuestTimer("golem_despawn", npc, null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (event.equalsIgnoreCase("1"))
|
|
||||||
{
|
|
||||||
npc.broadcastPacket(new SocialAction(npc.getObjectId(), 2));
|
|
||||||
npc.broadcastPacket(new SpecialCamera(npc, 1, -200, 15, 5500, 1000, 13500, 0, 0, 0, 0, 0));
|
|
||||||
}
|
|
||||||
else if (event.equalsIgnoreCase("2"))
|
|
||||||
{
|
|
||||||
npc.broadcastPacket(new SocialAction(npc.getObjectId(), 3));
|
|
||||||
}
|
|
||||||
else if (event.equalsIgnoreCase("3"))
|
|
||||||
{
|
|
||||||
npc.broadcastPacket(new SocialAction(npc.getObjectId(), 1));
|
|
||||||
}
|
|
||||||
else if (event.equalsIgnoreCase("4"))
|
|
||||||
{
|
|
||||||
npc.broadcastPacket(new SpecialCamera(npc, 1, -150, 10, 3500, 1000, 5000, 0, 0, 0, 0, 0));
|
|
||||||
npc.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, new Location(95928, -110671, -3340, 0));
|
|
||||||
}
|
|
||||||
else if (event.equalsIgnoreCase("5"))
|
|
||||||
{
|
|
||||||
// Delete Dr. Chaos && spawn the war golem.
|
|
||||||
npc.deleteMe();
|
|
||||||
L2GrandBossInstance golem = (L2GrandBossInstance) addSpawn(CHAOS_GOLEM, 96080, -110822, -3343, 0, false, 0, false);
|
|
||||||
GrandBossManager.getInstance().addBoss(golem);
|
|
||||||
|
|
||||||
// The "npc" variable attribution is now for the golem.
|
|
||||||
npc = golem;
|
|
||||||
npc.broadcastPacket(new SpecialCamera(npc, 30, 200, 20, 6000, 700, 8000, 0, 0, 0, 0, 0));
|
|
||||||
npc.broadcastPacket(new SocialAction(npc.getObjectId(), 1));
|
|
||||||
npc.broadcastPacket(new PlaySound(1, "Rm03_A", 0, 0, 0, 0, 0));
|
|
||||||
|
|
||||||
// start monitoring Dr. Chaos's inactivity
|
|
||||||
_lastAttackVsGolem = System.currentTimeMillis();
|
|
||||||
startQuestTimer("golem_despawn", 60000, npc, null, true);
|
|
||||||
}
|
|
||||||
// Check every sec if someone is in range, if found, launch one task to decrease the timer.
|
|
||||||
else if (event.equalsIgnoreCase("paranoia_activity"))
|
|
||||||
{
|
|
||||||
if (GrandBossManager.getInstance().getBossStatus(CHAOS_GOLEM) == NORMAL)
|
|
||||||
{
|
|
||||||
for (L2PcInstance obj : npc.getKnownList().getKnownPlayersInRadius(500))
|
|
||||||
{
|
|
||||||
if (obj.isDead())
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
_pissedOffTimer -= 1;
|
|
||||||
|
|
||||||
// Make him speak.
|
|
||||||
if (_pissedOffTimer == 15)
|
|
||||||
{
|
|
||||||
broadcastNpcSay(npc, ChatType.NPC_GENERAL, "How dare you trespass into my territory! Have you no fear?");
|
|
||||||
}
|
|
||||||
|
|
||||||
// That was "too much" for that time.
|
|
||||||
if (_pissedOffTimer <= 0)
|
|
||||||
{
|
|
||||||
crazyMidgetBecomesAngry(npc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return super.onAdvEvent(event, npc, player);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String onFirstTalk(L2Npc npc, L2PcInstance player)
|
|
||||||
{
|
|
||||||
String htmltext = "";
|
|
||||||
|
|
||||||
if (GrandBossManager.getInstance().getBossStatus(CHAOS_GOLEM) == NORMAL)
|
|
||||||
{
|
|
||||||
_pissedOffTimer -= 1 + Rnd.get(5); // remove 1-5 secs.
|
|
||||||
|
|
||||||
if ((_pissedOffTimer > 20) && (_pissedOffTimer <= 30))
|
|
||||||
{
|
|
||||||
htmltext = "<html><body>Doctor Chaos:<br>What?! Who are you? How did you come here?<br>You really look suspicious... Aren't those filthy members of Black Anvil guild send you? No? Mhhhhh... I don't trust you!</body></html>";
|
|
||||||
}
|
|
||||||
else if ((_pissedOffTimer > 10) && (_pissedOffTimer <= 20))
|
|
||||||
{
|
|
||||||
htmltext = "<html><body>Doctor Chaos:<br>Why are you standing here? Don't you see it's a private propertie? Don't look at him with those eyes... Did you smile?! Don't make fun of me! He will ... destroy ... you ... if you continue!</body></html>";
|
|
||||||
}
|
|
||||||
else if ((_pissedOffTimer > 0) && (_pissedOffTimer <= 10))
|
|
||||||
{
|
|
||||||
htmltext = "<html><body>Doctor Chaos:<br>I know why you are here, traitor! He discovered your plans! You are assassin ... sent by the Black Anvil guild! But you won't kill the Emperor of Evil!</body></html>";
|
|
||||||
}
|
|
||||||
else if (_pissedOffTimer <= 0)
|
|
||||||
{
|
|
||||||
crazyMidgetBecomesAngry(npc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return htmltext;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String onSpawn(L2Npc npc)
|
|
||||||
{
|
|
||||||
// 30 seconds timer at initialization.
|
|
||||||
_pissedOffTimer = 30;
|
|
||||||
|
|
||||||
// Initialization of the paranoia.
|
|
||||||
startQuestTimer("paranoia_activity", 1000, npc, null, true);
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String onKill(L2Npc npc, L2PcInstance player, boolean isPet)
|
|
||||||
{
|
|
||||||
cancelQuestTimer("golem_despawn", npc, null);
|
|
||||||
broadcastNpcSay(npc, ChatType.NPC_GENERAL, "Urggh! You will pay dearly for this insult.");
|
|
||||||
|
|
||||||
// "lock" Dr. Chaos for regular RB time (36H fixed +- 24H random)
|
|
||||||
long respawnTime = (36 + Rnd.get(-24, 24)) * 3600000;
|
|
||||||
|
|
||||||
GrandBossManager.getInstance().setBossStatus(CHAOS_GOLEM, DEAD);
|
|
||||||
startQuestTimer("reset_drchaos", respawnTime, null, null, false);
|
|
||||||
|
|
||||||
// also save the respawn time so that the info is maintained past reboots
|
|
||||||
StatsSet info = GrandBossManager.getInstance().getStatsSet(CHAOS_GOLEM);
|
|
||||||
info.set("respawn_time", System.currentTimeMillis() + respawnTime);
|
|
||||||
GrandBossManager.getInstance().setStatsSet(CHAOS_GOLEM, info);
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String onAttack(L2Npc npc, L2PcInstance victim, int damage, boolean isPet)
|
|
||||||
{
|
|
||||||
int chance = Rnd.get(300);
|
|
||||||
|
|
||||||
// Choose a message from 3 choices (1/100)
|
|
||||||
if (chance < 3)
|
|
||||||
{
|
|
||||||
String message = "";
|
|
||||||
switch (chance)
|
|
||||||
{
|
|
||||||
case 0:
|
|
||||||
message = "Bwah-ha-ha! Your doom is at hand! Behold the Ultra Secret Super Weapon!";
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
message = "Foolish, insignificant creatures! How dare you challenge me!";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
message = "I see that none will challenge me now!";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make him speak.
|
|
||||||
broadcastNpcSay(npc, ChatType.NPC_GENERAL, message);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Launches the complete animation.
|
|
||||||
* @param npc the midget.
|
|
||||||
*/
|
|
||||||
private void crazyMidgetBecomesAngry(L2Npc npc)
|
|
||||||
{
|
|
||||||
if (GrandBossManager.getInstance().getBossStatus(CHAOS_GOLEM) == NORMAL)
|
|
||||||
{
|
|
||||||
// Set the status to "crazy".
|
|
||||||
GrandBossManager.getInstance().setBossStatus(CHAOS_GOLEM, CRAZY);
|
|
||||||
|
|
||||||
// Cancels the paranoia timer.
|
|
||||||
cancelQuestTimer("paranoia_activity", npc, null);
|
|
||||||
|
|
||||||
// Makes the NPC moves near the Strange Box speaking.
|
|
||||||
npc.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, new Location(96323, -110914, -3328, 0));
|
|
||||||
broadcastNpcSay(npc, ChatType.NPC_GENERAL, "Fools! Why haven't you fled yet? Prepare to learn a lesson!");
|
|
||||||
|
|
||||||
// Delayed animation timers.
|
|
||||||
startQuestTimer("1", 2000, npc, null, false); // 2 secs, time to launch dr.C anim 2. Cam 1 on.
|
|
||||||
startQuestTimer("2", 4000, npc, null, false); // 2,5 secs, time to launch dr.C anim 3.
|
|
||||||
startQuestTimer("3", 6500, npc, null, false); // 6 secs, time to launch dr.C anim 1.
|
|
||||||
startQuestTimer("4", 12500, npc, null, false); // 4,5 secs to make the NPC moves to the grotto. Cam 2 on.
|
|
||||||
startQuestTimer("5", 17000, npc, null, false); // 4 secs for golem spawn, and golem anim. Cam 3 on.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void main(String[] args)
|
|
||||||
{
|
|
||||||
new DrChaos();
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,149 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2004-2015 L2J DataPack
|
|
||||||
*
|
|
||||||
* This file is part of L2J DataPack.
|
|
||||||
*
|
|
||||||
* L2J DataPack 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.
|
|
||||||
*
|
|
||||||
* L2J DataPack 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.individual;
|
|
||||||
|
|
||||||
import ai.npc.AbstractNpcAI;
|
|
||||||
|
|
||||||
import com.l2jserver.gameserver.ai.CtrlIntention;
|
|
||||||
import com.l2jserver.gameserver.enums.ChatType;
|
|
||||||
import com.l2jserver.gameserver.model.Location;
|
|
||||||
import com.l2jserver.gameserver.model.actor.L2Attackable;
|
|
||||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
|
||||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
|
||||||
import com.l2jserver.gameserver.model.holders.SkillHolder;
|
|
||||||
import com.l2jserver.gameserver.model.itemcontainer.Inventory;
|
|
||||||
import com.l2jserver.gameserver.network.NpcStringId;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Frightened Ragna Orc AI.
|
|
||||||
* @author Gladicek, malyelfik
|
|
||||||
*/
|
|
||||||
public final class FrightenedRagnaOrc extends AbstractNpcAI
|
|
||||||
{
|
|
||||||
// NPC ID
|
|
||||||
private static final int MOB_ID = 18807;
|
|
||||||
// Chances
|
|
||||||
private static final int ADENA = 10000;
|
|
||||||
private static final int CHANCE = 1000;
|
|
||||||
private static final int ADENA2 = 1000000;
|
|
||||||
private static final int CHANCE2 = 10;
|
|
||||||
// Skill
|
|
||||||
private static final SkillHolder SKILL = new SkillHolder(6234, 1);
|
|
||||||
|
|
||||||
private FrightenedRagnaOrc()
|
|
||||||
{
|
|
||||||
super(FrightenedRagnaOrc.class.getSimpleName(), "ai/individual");
|
|
||||||
addAttackId(MOB_ID);
|
|
||||||
addKillId(MOB_ID);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String onAttack(L2Npc npc, L2PcInstance attacker, int damage, boolean isSummon)
|
|
||||||
{
|
|
||||||
if (npc.isScriptValue(0))
|
|
||||||
{
|
|
||||||
npc.setScriptValue(1);
|
|
||||||
startQuestTimer("say", (getRandom(5) + 3) * 1000, npc, null, true);
|
|
||||||
}
|
|
||||||
else if ((npc.getCurrentHp() < (npc.getMaxHp() * 0.2)) && npc.isScriptValue(1))
|
|
||||||
{
|
|
||||||
startQuestTimer("reward", 10000, npc, attacker);
|
|
||||||
broadcastNpcSay(npc, ChatType.NPC_GENERAL, NpcStringId.WAIT_WAIT_STOP_SAVE_ME_AND_I_LL_GIVE_YOU_10_000_000_ADENA);
|
|
||||||
npc.setScriptValue(2);
|
|
||||||
}
|
|
||||||
return super.onAttack(npc, attacker, damage, isSummon);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String onKill(L2Npc npc, L2PcInstance player, boolean isSummon)
|
|
||||||
{
|
|
||||||
final NpcStringId msg = getRandomBoolean() ? NpcStringId.UGH_A_CURSE_UPON_YOU : NpcStringId.I_REALLY_DIDN_T_WANT_TO_FIGHT;
|
|
||||||
broadcastNpcSay(npc, ChatType.NPC_GENERAL, msg);
|
|
||||||
cancelQuestTimer("say", npc, null);
|
|
||||||
cancelQuestTimer("reward", npc, player);
|
|
||||||
return super.onKill(npc, player, isSummon);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
|
||||||
{
|
|
||||||
switch (event)
|
|
||||||
{
|
|
||||||
case "say":
|
|
||||||
{
|
|
||||||
if (npc.isDead() || !npc.isScriptValue(1))
|
|
||||||
{
|
|
||||||
cancelQuestTimer("say", npc, null);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
final NpcStringId msg = getRandomBoolean() ? NpcStringId.I_DON_T_WANT_TO_FIGHT : NpcStringId.IS_THIS_REALLY_NECESSARY;
|
|
||||||
broadcastNpcSay(npc, ChatType.NPC_GENERAL, msg);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case "reward":
|
|
||||||
{
|
|
||||||
if (!npc.isDead() && npc.isScriptValue(2))
|
|
||||||
{
|
|
||||||
if (getRandom(100000) < CHANCE2)
|
|
||||||
{
|
|
||||||
final NpcStringId msg = getRandomBoolean() ? NpcStringId.TH_THANKS_I_COULD_HAVE_BECOME_GOOD_FRIENDS_WITH_YOU : NpcStringId.I_LL_GIVE_YOU_10_000_000_ADENA_LIKE_I_PROMISED_I_MIGHT_BE_AN_ORC_WHO_KEEPS_MY_PROMISES;
|
|
||||||
broadcastNpcSay(npc, ChatType.NPC_GENERAL, msg);
|
|
||||||
npc.setScriptValue(3);
|
|
||||||
npc.doCast(SKILL.getSkill());
|
|
||||||
for (int i = 0; i < 10; i++)
|
|
||||||
{
|
|
||||||
npc.dropItem(player, Inventory.ADENA_ID, ADENA2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (getRandom(100000) < CHANCE)
|
|
||||||
{
|
|
||||||
final NpcStringId msg = getRandomBoolean() ? NpcStringId.TH_THANKS_I_COULD_HAVE_BECOME_GOOD_FRIENDS_WITH_YOU : NpcStringId.SORRY_BUT_THIS_IS_ALL_I_HAVE_GIVE_ME_A_BREAK;
|
|
||||||
broadcastNpcSay(npc, ChatType.NPC_GENERAL, msg);
|
|
||||||
npc.setScriptValue(3);
|
|
||||||
npc.doCast(SKILL.getSkill());
|
|
||||||
for (int i = 0; i < 10; i++)
|
|
||||||
{
|
|
||||||
((L2Attackable) npc).dropItem(player, Inventory.ADENA_ID, ADENA);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
final NpcStringId msg = getRandomBoolean() ? NpcStringId.THANKS_BUT_THAT_THING_ABOUT_10_000_000_ADENA_WAS_A_LIE_SEE_YA : NpcStringId.YOU_RE_PRETTY_DUMB_TO_BELIEVE_ME;
|
|
||||||
broadcastNpcSay(npc, ChatType.NPC_GENERAL, msg);
|
|
||||||
}
|
|
||||||
startQuestTimer("despawn", 1000, npc, null);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case "despawn":
|
|
||||||
{
|
|
||||||
npc.setRunning();
|
|
||||||
npc.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, new Location((npc.getX() + getRandom(-800, 800)), (npc.getY() + getRandom(-800, 800)), npc.getZ(), npc.getHeading()));
|
|
||||||
npc.deleteMe();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void main(String[] args)
|
|
||||||
{
|
|
||||||
new FrightenedRagnaOrc();
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,55 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2004-2015 L2J DataPack
|
|
||||||
*
|
|
||||||
* This file is part of L2J DataPack.
|
|
||||||
*
|
|
||||||
* L2J DataPack 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.
|
|
||||||
*
|
|
||||||
* L2J DataPack 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.individual;
|
|
||||||
|
|
||||||
import ai.npc.AbstractNpcAI;
|
|
||||||
|
|
||||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Grove Robber's AI.<br>
|
|
||||||
* <ul>
|
|
||||||
* <li>Grove Robber Summoner</li>
|
|
||||||
* <li>Grove Robber Megician</li>
|
|
||||||
* </ul>
|
|
||||||
* @author Zealar
|
|
||||||
*/
|
|
||||||
public final class GraveRobbers extends AbstractNpcAI
|
|
||||||
{
|
|
||||||
private static final int GRAVE_ROBBER_SUMMONER = 22678;
|
|
||||||
private static final int GRAVE_ROBBER_MEGICIAN = 22679;
|
|
||||||
|
|
||||||
private GraveRobbers()
|
|
||||||
{
|
|
||||||
super(GraveRobbers.class.getSimpleName(), "ai/individual");
|
|
||||||
addSpawnId(GRAVE_ROBBER_SUMMONER, GRAVE_ROBBER_MEGICIAN);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String onSpawn(L2Npc npc)
|
|
||||||
{
|
|
||||||
spawnMinions(npc, "Privates" + getRandom(1, 2));
|
|
||||||
return super.onSpawn(npc);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void main(String[] args)
|
|
||||||
{
|
|
||||||
new GraveRobbers();
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,95 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2004-2015 L2J DataPack
|
|
||||||
*
|
|
||||||
* This file is part of L2J DataPack.
|
|
||||||
*
|
|
||||||
* L2J DataPack 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.
|
|
||||||
*
|
|
||||||
* L2J DataPack 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.individual;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
|
||||||
|
|
||||||
import ai.npc.AbstractNpcAI;
|
|
||||||
|
|
||||||
import com.l2jserver.gameserver.enums.ChatType;
|
|
||||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
|
||||||
import com.l2jserver.gameserver.model.actor.instance.L2MonsterInstance;
|
|
||||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
|
||||||
import com.l2jserver.gameserver.network.NpcStringId;
|
|
||||||
import com.l2jserver.gameserver.network.serverpackets.NpcSay;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Manages Sin Wardens disappearing and chat.
|
|
||||||
* @author GKR
|
|
||||||
*/
|
|
||||||
public final class SinWardens extends AbstractNpcAI
|
|
||||||
{
|
|
||||||
private static final int[] SIN_WARDEN_MINIONS =
|
|
||||||
{
|
|
||||||
22424,
|
|
||||||
22425,
|
|
||||||
22426,
|
|
||||||
22427,
|
|
||||||
22428,
|
|
||||||
22429,
|
|
||||||
22430,
|
|
||||||
22432,
|
|
||||||
22433,
|
|
||||||
22434,
|
|
||||||
22435,
|
|
||||||
22436,
|
|
||||||
22437,
|
|
||||||
22438
|
|
||||||
};
|
|
||||||
|
|
||||||
private final Map<Integer, Integer> killedMinionsCount = new ConcurrentHashMap<>();
|
|
||||||
|
|
||||||
private SinWardens()
|
|
||||||
{
|
|
||||||
super(SinWardens.class.getSimpleName(), "ai/individual");
|
|
||||||
addKillId(SIN_WARDEN_MINIONS);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
|
|
||||||
{
|
|
||||||
if (npc.isMinion())
|
|
||||||
{
|
|
||||||
final L2MonsterInstance master = ((L2MonsterInstance) npc).getLeader();
|
|
||||||
if ((master != null) && !master.isDead())
|
|
||||||
{
|
|
||||||
int killedCount = killedMinionsCount.containsKey(master.getObjectId()) ? killedMinionsCount.get(master.getObjectId()) : 0;
|
|
||||||
killedCount++;
|
|
||||||
|
|
||||||
if ((killedCount) == 5)
|
|
||||||
{
|
|
||||||
master.broadcastPacket(new NpcSay(master.getObjectId(), ChatType.NPC_GENERAL, master.getId(), NpcStringId.WE_MIGHT_NEED_NEW_SLAVES_I_LL_BE_BACK_SOON_SO_WAIT));
|
|
||||||
master.doDie(killer);
|
|
||||||
killedMinionsCount.remove(master.getObjectId());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
killedMinionsCount.put(master.getObjectId(), killedCount);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return super.onKill(npc, killer, isSummon);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void main(String[] args)
|
|
||||||
{
|
|
||||||
new SinWardens();
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,142 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2004-2015 L2J DataPack
|
|
||||||
*
|
|
||||||
* This file is part of L2J DataPack.
|
|
||||||
*
|
|
||||||
* L2J DataPack 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.
|
|
||||||
*
|
|
||||||
* L2J DataPack 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.npc.AdventurersGuide;
|
|
||||||
|
|
||||||
import ai.npc.AbstractNpcAI;
|
|
||||||
|
|
||||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
|
||||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
|
||||||
import com.l2jserver.gameserver.model.holders.SkillHolder;
|
|
||||||
import com.l2jserver.gameserver.model.skills.Skill;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adventurers Guide AI.
|
|
||||||
* @author St3eT
|
|
||||||
*/
|
|
||||||
public final class AdventurersGuide extends AbstractNpcAI
|
|
||||||
{
|
|
||||||
// NPCs
|
|
||||||
private static final int[] ADVENTURERS_GUIDE =
|
|
||||||
{
|
|
||||||
32327,
|
|
||||||
33454, // Newbie Helper
|
|
||||||
};
|
|
||||||
// Skills
|
|
||||||
private static final SkillHolder BLESS_PROTECTION = new SkillHolder(5182, 1); // Blessing of Protection
|
|
||||||
private static final SkillHolder KNIGHT = new SkillHolder(15648, 1); // Knight's Harmony (Adventurer)
|
|
||||||
private static final SkillHolder WARRIOR = new SkillHolder(15649, 1); // Warrior's Harmony (Adventurer)
|
|
||||||
private static final SkillHolder WIZARD = new SkillHolder(15650, 1); // Wizard's Harmony (Adventurer)
|
|
||||||
private static final SkillHolder[] GROUP_BUFFS =
|
|
||||||
{
|
|
||||||
new SkillHolder(15642, 1), // Horn Melody (Adventurer)
|
|
||||||
new SkillHolder(15643, 1), // Drum Melody (Adventurer)
|
|
||||||
new SkillHolder(15644, 1), // Pipe Organ Melody (Adventurer)
|
|
||||||
new SkillHolder(15645, 1), // Guitar Melody (Adventurer)
|
|
||||||
new SkillHolder(15646, 1), // Harp Melody (Adventurer)
|
|
||||||
new SkillHolder(15647, 1), // Lute Melody (Adventurer)
|
|
||||||
new SkillHolder(15651, 1), // Prevailing Sonata (Adventurer)
|
|
||||||
new SkillHolder(15652, 1), // Daring Sonata (Adventurer)
|
|
||||||
new SkillHolder(15653, 1), // Refreshing Sonata (Adventurer)
|
|
||||||
};
|
|
||||||
|
|
||||||
private AdventurersGuide()
|
|
||||||
{
|
|
||||||
super(AdventurersGuide.class.getSimpleName(), "ai/npc");
|
|
||||||
addStartNpc(ADVENTURERS_GUIDE);
|
|
||||||
addTalkId(ADVENTURERS_GUIDE);
|
|
||||||
addFirstTalkId(ADVENTURERS_GUIDE);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
|
||||||
{
|
|
||||||
String htmltext = null;
|
|
||||||
|
|
||||||
switch (event)
|
|
||||||
{
|
|
||||||
case "guide-01.html":
|
|
||||||
case "guide-02.html":
|
|
||||||
case "guide-03.html":
|
|
||||||
case "guide-04.html":
|
|
||||||
{
|
|
||||||
htmltext = event;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case "weakenBreath":
|
|
||||||
{
|
|
||||||
if (player.getShilensBreathDebuffLevel() < 3)
|
|
||||||
{
|
|
||||||
htmltext = "guide-noBreath.html";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
player.setShilensBreathDebuffLevel(2);
|
|
||||||
htmltext = ""; // TODO: Any success html?
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case "knight":
|
|
||||||
{
|
|
||||||
htmltext = applyBuffs(npc, player, KNIGHT.getSkill());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case "warrior":
|
|
||||||
{
|
|
||||||
htmltext = applyBuffs(npc, player, WARRIOR.getSkill());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case "wizard":
|
|
||||||
{
|
|
||||||
htmltext = applyBuffs(npc, player, WIZARD.getSkill());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return htmltext;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String onFirstTalk(L2Npc npc, L2PcInstance player)
|
|
||||||
{
|
|
||||||
return "guide.html";
|
|
||||||
}
|
|
||||||
|
|
||||||
private String applyBuffs(L2Npc npc, L2PcInstance player, Skill skill)
|
|
||||||
{
|
|
||||||
if (player.getLevel() > 90)
|
|
||||||
{
|
|
||||||
return "guide-noBuffs.html";
|
|
||||||
}
|
|
||||||
|
|
||||||
for (SkillHolder holder : GROUP_BUFFS)
|
|
||||||
{
|
|
||||||
holder.getSkill().applyEffects(npc, player);
|
|
||||||
}
|
|
||||||
skill.applyEffects(npc, player);
|
|
||||||
|
|
||||||
if ((player.getLevel() < 40) && (player.getClassId().level() <= 1))
|
|
||||||
{
|
|
||||||
BLESS_PROTECTION.getSkill().applyEffects(npc, player);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void main(String[] args)
|
|
||||||
{
|
|
||||||
new AdventurersGuide();
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,11 +0,0 @@
|
|||||||
<html><body>
|
|
||||||
I can offer you the following buffs, if you're below Lv. 91.<br>
|
|
||||||
Horn Melody / Drum Melody / Pipe Organ Melody<br1>
|
|
||||||
Guitar Melody / Harp Melody / Lute Melody<br1>
|
|
||||||
Prevailing Sonata / Daring Sonata / Refreshing Sonata<br1>
|
|
||||||
You can receive the above buffs as a group.<br>
|
|
||||||
For Knight's Harmony / Warrior's Harmony / Wizard's Harmony, you will have to choose one.<br>
|
|
||||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h npc_%objectId%_Quest AdventurersGuide knight">"I want the Knight's Harmony."</Button>
|
|
||||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h npc_%objectId%_Quest AdventurersGuide warrior">"Warrior's Harmony, please."</Button>
|
|
||||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h npc_%objectId%_Quest AdventurersGuide wizard">"Wizard's Harmony, of course!"</Button>
|
|
||||||
</body></html>
|
|
@@ -1,6 +0,0 @@
|
|||||||
<html><body>Adventurers' Guide:<br>
|
|
||||||
The Steel Door Guild tops all Dwarven guilds in power and prestige. As such, it is our duty to aid adventurers who work to restore peace unto this war-torn land. We will be happy to offer special assistance if you have Steel Door Guild Coins.<br>
|
|
||||||
Well?<br>
|
|
||||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h npc_%objectId%_Quest AdventurersGuide guide-03.html">"How do I use Steel Door Guild Coins?"</Button>
|
|
||||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h npc_%objectId%_Quest AdventurersGuide guide-04.html">"Here, I have some Steel Door Guild Coins..."</Button>
|
|
||||||
</body></html>
|
|
@@ -1,5 +0,0 @@
|
|||||||
<html><body>Adventurers' Guide:<br>
|
|
||||||
You can use Steel Door Guild Coins to purchase <font color="LEVEL">weapons, armor, and accessories of each grade</font>. These items may be restricted in terms of augmentations or attribute options, but they will be more than enough to help you on your journey.<br>
|
|
||||||
Once you outgrow the equipment, <font color="LEVEL">you can trade them back for Steel Door Guild Coins again</font>! You can also invest in the Aden Reconstruction project if it suits your fancy, or even gamble. Don't forget that Steel Weapon Packs and Steel Armor Packs have a chance of yielding Requiem, Apocalypse, or Specter equipment!<br>
|
|
||||||
<Button ALIGN=LEFT ICON="RETURN" action="bypass -h npc_%objectId%_Quest AdventurersGuide guide-02.html">Back</Button>
|
|
||||||
</body></html>
|
|
@@ -1,14 +0,0 @@
|
|||||||
<html><body>Adventurers' Guide:<br>
|
|
||||||
You can use Steel Door Guild Coins to receive equipment, and trade them back for coins again. Just remember, <font color="LEVEL">you cannot bring us junk to exchange for coins!</font><br>
|
|
||||||
So, what would you like to do?<br>
|
|
||||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h npc_%objectId%_multisell 893">"I'd like a weapon or a shield / Sigil."</Button>
|
|
||||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h npc_%objectId%_multisell 894">"I want to buy a top."</Button>
|
|
||||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h npc_%objectId%_multisell 895">"I am looking for some pants."</Button>
|
|
||||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h npc_%objectId%_multisell 896">"Do you have any good helmets?"</Button>
|
|
||||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h npc_%objectId%_multisell 897">"Gloves would be nice."</Button>
|
|
||||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h npc_%objectId%_multisell 898">"Give me the best boots you got."</Button>
|
|
||||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h npc_%objectId%_multisell 899">"Can I take a look at your necklaces?"</Button>
|
|
||||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h npc_%objectId%_multisell 900">"I'm up for a ring..."</Button>
|
|
||||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h npc_%objectId%_multisell 901">"I want some earrings."</Button>
|
|
||||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h npc_%objectId%_exc_multisell 903">"I want to return my Steel equipment."</Button>
|
|
||||||
</body></html>
|
|
@@ -1,4 +0,0 @@
|
|||||||
<html><body>Adventurers' Guide<br>
|
|
||||||
I can only weaken Shilen's Breath Lv. 3 or above.<br>
|
|
||||||
There is nothing I can do for you.
|
|
||||||
</body></html>
|
|
@@ -1,3 +0,0 @@
|
|||||||
<html><body>
|
|
||||||
Characters who are Lv. 91 or above cannot receive Newbie Buffs.
|
|
||||||
</body></html>
|
|
@@ -1,9 +0,0 @@
|
|||||||
<html><body>Adventurers' Guide:<br>
|
|
||||||
Greetings, traveler! How may I be of assistance?<br>
|
|
||||||
My job is to offer what little assistance I can as you charge into all this endless evil and intense fighting!<br>
|
|
||||||
Even now, the monster attacks on this village grow stronger each day; it is only due to your tireless efforts that we have remained safe this long.<br>
|
|
||||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h npc_%objectId%_Quest AdventurersGuide guide-01.html"><font color="LEVEL">"Can I see the list of available buffs?"</font></Button>
|
|
||||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h npc_%objectId%_Quest AdventurersGuide guide-02.html">"Here, I have some Steel Door Guild Coins..."</Button>
|
|
||||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h npc_%objectId%_Quest AdventurersGuide weakenBreath">"I heard you could weaken Shilen's Breath Lv.3 or above."</Button>
|
|
||||||
<Button ALIGN=LEFT ICON="QUEST" action="bypass -h npc_%objectId%_Quest">Quest</Button>
|
|
||||||
</body></html>
|
|
@@ -1,204 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2004-2015 L2J DataPack
|
|
||||||
*
|
|
||||||
* This file is part of L2J DataPack.
|
|
||||||
*
|
|
||||||
* L2J DataPack 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.
|
|
||||||
*
|
|
||||||
* L2J DataPack 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.npc.ForgeOfTheGods;
|
|
||||||
|
|
||||||
import ai.npc.AbstractNpcAI;
|
|
||||||
|
|
||||||
import com.l2jserver.gameserver.ai.CtrlIntention;
|
|
||||||
import com.l2jserver.gameserver.model.actor.L2Attackable;
|
|
||||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
|
||||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Forge of the Gods AI
|
|
||||||
* @author nonom, malyelfik
|
|
||||||
*/
|
|
||||||
public final class ForgeOfTheGods extends AbstractNpcAI
|
|
||||||
{
|
|
||||||
// NPCs
|
|
||||||
private static final int[] FOG_MOBS =
|
|
||||||
{
|
|
||||||
22634, // Scarlet Stakato Worker
|
|
||||||
22635, // Scarlet Stakato Soldier
|
|
||||||
22636, // Scarlet Stakato Noble
|
|
||||||
22637, // Tepra Scorpion
|
|
||||||
22638, // Tepra Scarab
|
|
||||||
22639, // Assassin Beetle
|
|
||||||
22640, // Mercenary of Destruction
|
|
||||||
22641, // Knight of Destruction
|
|
||||||
22642, // Lavastone Golem
|
|
||||||
22643, // Magma Golem
|
|
||||||
22644, // Arimanes of Destruction
|
|
||||||
22645, // Balor of Destruction
|
|
||||||
22646, // Ashuras of Destruction
|
|
||||||
22647, // Lavasillisk
|
|
||||||
22648, // Blazing Ifrit
|
|
||||||
22649, // Magma Drake
|
|
||||||
};
|
|
||||||
|
|
||||||
private static final int[] LAVASAURUSES =
|
|
||||||
{
|
|
||||||
18799, // Newborn Lavasaurus
|
|
||||||
18800, // Fledgling Lavasaurus
|
|
||||||
18801, // Adult Lavasaurus
|
|
||||||
18802, // Elderly Lavasaurus
|
|
||||||
18803, // Ancient Lavasaurus
|
|
||||||
};
|
|
||||||
|
|
||||||
private static final int REFRESH = 15;
|
|
||||||
|
|
||||||
private static final int MOBCOUNT_BONUS_MIN = 3;
|
|
||||||
|
|
||||||
private static final int BONUS_UPPER_LV01 = 5;
|
|
||||||
private static final int BONUS_UPPER_LV02 = 10;
|
|
||||||
private static final int BONUS_UPPER_LV03 = 15;
|
|
||||||
private static final int BONUS_UPPER_LV04 = 20;
|
|
||||||
private static final int BONUS_UPPER_LV05 = 35;
|
|
||||||
|
|
||||||
private static final int BONUS_LOWER_LV01 = 5;
|
|
||||||
private static final int BONUS_LOWER_LV02 = 10;
|
|
||||||
private static final int BONUS_LOWER_LV03 = 15;
|
|
||||||
|
|
||||||
private static final int FORGE_BONUS01 = 20;
|
|
||||||
private static final int FORGE_BONUS02 = 40;
|
|
||||||
|
|
||||||
private static int _npcCount = 0;
|
|
||||||
|
|
||||||
// private static int _npcsAlive = 0; TODO: Require zone spawn support
|
|
||||||
|
|
||||||
private ForgeOfTheGods()
|
|
||||||
{
|
|
||||||
super(ForgeOfTheGods.class.getSimpleName(), "ai/npc");
|
|
||||||
addKillId(FOG_MOBS);
|
|
||||||
addSpawnId(LAVASAURUSES);
|
|
||||||
startQuestTimer("refresh", REFRESH * 1000, null, null, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
|
||||||
{
|
|
||||||
switch (event)
|
|
||||||
{
|
|
||||||
case "suicide":
|
|
||||||
if (npc != null)
|
|
||||||
{
|
|
||||||
npc.doDie(null);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "refresh":
|
|
||||||
_npcCount = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
|
|
||||||
{
|
|
||||||
int rand = getRandom(100);
|
|
||||||
L2Npc mob = null;
|
|
||||||
_npcCount++;
|
|
||||||
|
|
||||||
// For monsters at Forge of the Gods - Lower level
|
|
||||||
if (npc.getSpawn().getZ() < -5000) // && (_npcsAlive < 48))
|
|
||||||
{
|
|
||||||
if ((_npcCount > BONUS_LOWER_LV03) && (rand <= FORGE_BONUS02))
|
|
||||||
{
|
|
||||||
mob = addSpawn(LAVASAURUSES[4], npc, true);
|
|
||||||
}
|
|
||||||
else if (_npcCount > BONUS_LOWER_LV02)
|
|
||||||
{
|
|
||||||
mob = spawnLavasaurus(npc, rand, LAVASAURUSES[4], LAVASAURUSES[3]);
|
|
||||||
}
|
|
||||||
else if (_npcCount > BONUS_LOWER_LV01)
|
|
||||||
{
|
|
||||||
mob = spawnLavasaurus(npc, rand, LAVASAURUSES[3], LAVASAURUSES[2]);
|
|
||||||
}
|
|
||||||
else if (_npcCount >= MOBCOUNT_BONUS_MIN)
|
|
||||||
{
|
|
||||||
mob = spawnLavasaurus(npc, rand, LAVASAURUSES[2], LAVASAURUSES[1]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
// if (_npcsAlive < 32)
|
|
||||||
{
|
|
||||||
if ((_npcCount > BONUS_UPPER_LV05) && (rand <= FORGE_BONUS02))
|
|
||||||
{
|
|
||||||
mob = addSpawn(LAVASAURUSES[1], npc, true);
|
|
||||||
}
|
|
||||||
else if (_npcCount > BONUS_UPPER_LV04)
|
|
||||||
{
|
|
||||||
mob = spawnLavasaurus(npc, rand, LAVASAURUSES[4], LAVASAURUSES[3]);
|
|
||||||
}
|
|
||||||
else if (_npcCount > BONUS_UPPER_LV03)
|
|
||||||
{
|
|
||||||
mob = spawnLavasaurus(npc, rand, LAVASAURUSES[3], LAVASAURUSES[2]);
|
|
||||||
}
|
|
||||||
else if (_npcCount > BONUS_UPPER_LV02)
|
|
||||||
{
|
|
||||||
mob = spawnLavasaurus(npc, rand, LAVASAURUSES[2], LAVASAURUSES[1]);
|
|
||||||
}
|
|
||||||
else if (_npcCount > BONUS_UPPER_LV01)
|
|
||||||
{
|
|
||||||
mob = spawnLavasaurus(npc, rand, LAVASAURUSES[1], LAVASAURUSES[0]);
|
|
||||||
}
|
|
||||||
else if ((_npcCount >= MOBCOUNT_BONUS_MIN) && (rand <= FORGE_BONUS01))
|
|
||||||
{
|
|
||||||
mob = addSpawn(LAVASAURUSES[0], npc, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (mob != null)
|
|
||||||
{
|
|
||||||
((L2Attackable) mob).addDamageHate(killer, 0, 9999);
|
|
||||||
mob.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK);
|
|
||||||
}
|
|
||||||
return super.onKill(npc, killer, isSummon);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public final String onSpawn(L2Npc npc)
|
|
||||||
{
|
|
||||||
startQuestTimer("suicide", 60000, npc, null);
|
|
||||||
return super.onSpawn(npc);
|
|
||||||
}
|
|
||||||
|
|
||||||
private L2Npc spawnLavasaurus(L2Npc npc, int rand, int... mobs)
|
|
||||||
{
|
|
||||||
if (mobs.length < 2)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
L2Npc mob = null;
|
|
||||||
if (rand <= FORGE_BONUS01)
|
|
||||||
{
|
|
||||||
mob = addSpawn(mobs[0], npc, true);
|
|
||||||
}
|
|
||||||
else if (rand <= FORGE_BONUS02)
|
|
||||||
{
|
|
||||||
mob = addSpawn(mobs[1], npc, true);
|
|
||||||
}
|
|
||||||
return mob;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void main(String[] args)
|
|
||||||
{
|
|
||||||
new ForgeOfTheGods();
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,136 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2004-2015 L2J DataPack
|
|
||||||
*
|
|
||||||
* This file is part of L2J DataPack.
|
|
||||||
*
|
|
||||||
* L2J DataPack 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.
|
|
||||||
*
|
|
||||||
* L2J DataPack 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.npc.ForgeOfTheGods;
|
|
||||||
|
|
||||||
import ai.npc.AbstractNpcAI;
|
|
||||||
|
|
||||||
import com.l2jserver.gameserver.enums.ChatType;
|
|
||||||
import com.l2jserver.gameserver.model.Location;
|
|
||||||
import com.l2jserver.gameserver.model.actor.L2Character;
|
|
||||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
|
||||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
|
||||||
import com.l2jserver.gameserver.network.NpcStringId;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Rooney AI
|
|
||||||
* @author malyelfik
|
|
||||||
*/
|
|
||||||
public final class Rooney extends AbstractNpcAI
|
|
||||||
{
|
|
||||||
// NPC
|
|
||||||
private static final int ROONEY = 32049;
|
|
||||||
// Locations
|
|
||||||
private static final Location[] LOCATIONS =
|
|
||||||
{
|
|
||||||
new Location(175937, -112167, -5550),
|
|
||||||
new Location(178896, -112425, -5860),
|
|
||||||
new Location(180628, -115992, -6135),
|
|
||||||
new Location(183010, -114753, -6135),
|
|
||||||
new Location(184496, -116773, -6135),
|
|
||||||
new Location(181857, -109491, -5865),
|
|
||||||
new Location(178917, -107633, -5853),
|
|
||||||
new Location(178804, -110080, -5853),
|
|
||||||
new Location(182221, -106806, -6025),
|
|
||||||
new Location(186488, -109715, -5915),
|
|
||||||
new Location(183847, -119231, -3113),
|
|
||||||
new Location(185193, -120342, -3113),
|
|
||||||
new Location(188047, -120867, -3113),
|
|
||||||
new Location(189734, -120471, -3113),
|
|
||||||
new Location(188754, -118940, -3313),
|
|
||||||
new Location(190022, -116803, -3313),
|
|
||||||
new Location(188443, -115814, -3313),
|
|
||||||
new Location(186421, -114614, -3313),
|
|
||||||
new Location(185188, -113307, -3313),
|
|
||||||
new Location(187378, -112946, -3313),
|
|
||||||
new Location(189815, -113425, -3313),
|
|
||||||
new Location(189301, -111327, -3313),
|
|
||||||
new Location(190289, -109176, -3313),
|
|
||||||
new Location(187783, -110478, -3313),
|
|
||||||
new Location(185889, -109990, -3313),
|
|
||||||
new Location(181881, -109060, -3695),
|
|
||||||
new Location(183570, -111344, -3675),
|
|
||||||
new Location(182077, -112567, -3695),
|
|
||||||
new Location(180127, -112776, -3698),
|
|
||||||
new Location(179155, -108629, -3695),
|
|
||||||
new Location(176282, -109510, -3698),
|
|
||||||
new Location(176071, -113163, -3515),
|
|
||||||
new Location(179376, -117056, -3640),
|
|
||||||
new Location(179760, -115385, -3640),
|
|
||||||
new Location(177950, -119691, -4140),
|
|
||||||
new Location(177037, -120820, -4340),
|
|
||||||
new Location(181125, -120148, -3702),
|
|
||||||
new Location(182212, -117969, -3352),
|
|
||||||
new Location(186074, -118154, -3312)
|
|
||||||
};
|
|
||||||
|
|
||||||
private Rooney()
|
|
||||||
{
|
|
||||||
super(Rooney.class.getSimpleName(), "ai/npc");
|
|
||||||
addSeeCreatureId(ROONEY);
|
|
||||||
addSpawn(ROONEY, LOCATIONS[getRandom(LOCATIONS.length)], false, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
|
||||||
{
|
|
||||||
if (event.equals("teleport") && !npc.isDecayed())
|
|
||||||
{
|
|
||||||
final int aiVal = npc.getScriptValue();
|
|
||||||
switch (aiVal)
|
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
broadcastNpcSay(npc, ChatType.NPC_GENERAL, NpcStringId.HURRY_HURRY);
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
broadcastNpcSay(npc, ChatType.NPC_GENERAL, NpcStringId.I_AM_NOT_THAT_TYPE_OF_PERSON_WHO_STAYS_IN_ONE_PLACE_FOR_A_LONG_TIME);
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
broadcastNpcSay(npc, ChatType.NPC_GENERAL, NpcStringId.IT_S_HARD_FOR_ME_TO_KEEP_STANDING_LIKE_THIS);
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
broadcastNpcSay(npc, ChatType.NPC_GENERAL, NpcStringId.WHY_DON_T_I_GO_THAT_WAY_THIS_TIME);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
npc.teleToLocation(LOCATIONS[getRandom(LOCATIONS.length)], false);
|
|
||||||
npc.setScriptValue(0);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
npc.setScriptValue(aiVal + 1);
|
|
||||||
startQuestTimer("teleport", 60000, npc, null);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String onSeeCreature(L2Npc npc, L2Character creature, boolean isSummon)
|
|
||||||
{
|
|
||||||
if (creature.isPlayer() && npc.isScriptValue(0))
|
|
||||||
{
|
|
||||||
broadcastNpcSay(npc, ChatType.NPC_GENERAL, NpcStringId.WELCOME);
|
|
||||||
startQuestTimer("teleport", 60000, npc, null);
|
|
||||||
npc.setScriptValue(1);
|
|
||||||
}
|
|
||||||
return super.onSeeCreature(npc, creature, isSummon);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void main(String[] args)
|
|
||||||
{
|
|
||||||
new Rooney();
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,104 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2004-2015 L2J DataPack
|
|
||||||
*
|
|
||||||
* This file is part of L2J DataPack.
|
|
||||||
*
|
|
||||||
* L2J DataPack 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.
|
|
||||||
*
|
|
||||||
* L2J DataPack 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.npc.ForgeOfTheGods;
|
|
||||||
|
|
||||||
import ai.npc.AbstractNpcAI;
|
|
||||||
|
|
||||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
|
||||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
|
||||||
import com.l2jserver.gameserver.model.holders.SkillHolder;
|
|
||||||
import com.l2jserver.gameserver.model.skills.BuffInfo;
|
|
||||||
import com.l2jserver.gameserver.model.skills.Skill;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tar Beetle AI
|
|
||||||
* @author nonom, malyelfik
|
|
||||||
*/
|
|
||||||
public final class TarBeetle extends AbstractNpcAI
|
|
||||||
{
|
|
||||||
// NPC
|
|
||||||
private static final int TAR_BEETLE = 18804;
|
|
||||||
// Skills
|
|
||||||
private static final int TAR_SPITE = 6142;
|
|
||||||
private static SkillHolder[] SKILLS =
|
|
||||||
{
|
|
||||||
new SkillHolder(TAR_SPITE, 1),
|
|
||||||
new SkillHolder(TAR_SPITE, 2),
|
|
||||||
new SkillHolder(TAR_SPITE, 3)
|
|
||||||
};
|
|
||||||
|
|
||||||
private static final TarBeetleSpawn spawn = new TarBeetleSpawn();
|
|
||||||
|
|
||||||
private TarBeetle()
|
|
||||||
{
|
|
||||||
super(TarBeetle.class.getSimpleName(), "ai/npc");
|
|
||||||
addAggroRangeEnterId(TAR_BEETLE);
|
|
||||||
addSpellFinishedId(TAR_BEETLE);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String onAggroRangeEnter(L2Npc npc, L2PcInstance player, boolean isSummon)
|
|
||||||
{
|
|
||||||
if (npc.getScriptValue() > 0)
|
|
||||||
{
|
|
||||||
final BuffInfo info = player.getEffectList().getBuffInfoBySkillId(TAR_SPITE);
|
|
||||||
final int level = (info != null) ? info.getSkill().getAbnormalLvl() : 0;
|
|
||||||
if (level < 3)
|
|
||||||
{
|
|
||||||
final Skill skill = SKILLS[level].getSkill();
|
|
||||||
if (!npc.isSkillDisabled(skill))
|
|
||||||
{
|
|
||||||
npc.setTarget(player);
|
|
||||||
npc.doCast(skill);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return super.onAggroRangeEnter(npc, player, isSummon);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String onSpellFinished(L2Npc npc, L2PcInstance player, Skill skill)
|
|
||||||
{
|
|
||||||
if ((skill != null) && (skill.getId() == TAR_SPITE))
|
|
||||||
{
|
|
||||||
final int val = npc.getScriptValue() - 1;
|
|
||||||
if ((val <= 0) || (SKILLS[0].getSkill().getMpConsume() > npc.getCurrentMp()))
|
|
||||||
{
|
|
||||||
spawn.removeBeetle(npc);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
npc.setScriptValue(val);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return super.onSpellFinished(npc, player, skill);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean unload()
|
|
||||||
{
|
|
||||||
spawn.unload();
|
|
||||||
return super.unload();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void main(String[] args)
|
|
||||||
{
|
|
||||||
new TarBeetle();
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,272 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2004-2015 L2J DataPack
|
|
||||||
*
|
|
||||||
* This file is part of L2J DataPack.
|
|
||||||
*
|
|
||||||
* L2J DataPack 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.
|
|
||||||
*
|
|
||||||
* L2J DataPack 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.npc.ForgeOfTheGods;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
|
||||||
import java.util.concurrent.ScheduledFuture;
|
|
||||||
|
|
||||||
import org.w3c.dom.Document;
|
|
||||||
import org.w3c.dom.NamedNodeMap;
|
|
||||||
import org.w3c.dom.Node;
|
|
||||||
|
|
||||||
import com.l2jserver.gameserver.GeoData;
|
|
||||||
import com.l2jserver.gameserver.ThreadPoolManager;
|
|
||||||
import com.l2jserver.gameserver.model.L2Spawn;
|
|
||||||
import com.l2jserver.gameserver.model.L2Territory;
|
|
||||||
import com.l2jserver.gameserver.model.Location;
|
|
||||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
|
||||||
import com.l2jserver.util.Rnd;
|
|
||||||
import com.l2jserver.util.data.xml.IXmlReader;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tar Beetle zone spawn
|
|
||||||
* @author malyelfik
|
|
||||||
*/
|
|
||||||
public class TarBeetleSpawn implements IXmlReader
|
|
||||||
{
|
|
||||||
private final List<SpawnZone> zones = new ArrayList<>();
|
|
||||||
private ScheduledFuture<?> spawnTask;
|
|
||||||
private ScheduledFuture<?> shotTask;
|
|
||||||
|
|
||||||
public TarBeetleSpawn()
|
|
||||||
{
|
|
||||||
load();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void load()
|
|
||||||
{
|
|
||||||
parseDatapackFile("spawnZones/tar_beetle.xml");
|
|
||||||
if (!zones.isEmpty())
|
|
||||||
{
|
|
||||||
spawnTask = ThreadPoolManager.getInstance().scheduleGeneralAtFixedRate(() -> zones.forEach(SpawnZone::refreshSpawn), 1000, 60000);
|
|
||||||
shotTask = ThreadPoolManager.getInstance().scheduleGeneralAtFixedRate(() -> zones.forEach(SpawnZone::refreshShots), 300000, 300000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void parseDocument(Document doc)
|
|
||||||
{
|
|
||||||
int i = 0;
|
|
||||||
for (Node d = doc.getFirstChild(); d != null; d = d.getNextSibling())
|
|
||||||
{
|
|
||||||
if (d.getNodeName().equals("list"))
|
|
||||||
{
|
|
||||||
for (Node r = d.getFirstChild(); r != null; r = r.getNextSibling())
|
|
||||||
{
|
|
||||||
if (r.getNodeName().equals("spawnZone"))
|
|
||||||
{
|
|
||||||
NamedNodeMap attrs = r.getAttributes();
|
|
||||||
final int npcCount = parseInteger(attrs, "maxNpcCount");
|
|
||||||
final SpawnZone sp = new SpawnZone(npcCount, i);
|
|
||||||
for (Node b = r.getFirstChild(); b != null; b = b.getNextSibling())
|
|
||||||
{
|
|
||||||
if (b.getNodeName().equals("zone"))
|
|
||||||
{
|
|
||||||
attrs = b.getAttributes();
|
|
||||||
final int minZ = parseInteger(attrs, "minZ");
|
|
||||||
final int maxZ = parseInteger(attrs, "maxZ");
|
|
||||||
final Zone zone = new Zone();
|
|
||||||
for (Node c = b.getFirstChild(); c != null; c = c.getNextSibling())
|
|
||||||
{
|
|
||||||
attrs = c.getAttributes();
|
|
||||||
if (c.getNodeName().equals("point"))
|
|
||||||
{
|
|
||||||
final int x = parseInteger(attrs, "x");
|
|
||||||
final int y = parseInteger(attrs, "y");
|
|
||||||
zone.add(x, y, minZ, maxZ, 0);
|
|
||||||
}
|
|
||||||
else if (c.getNodeName().equals("bannedZone"))
|
|
||||||
{
|
|
||||||
final Zone bannedZone = new Zone();
|
|
||||||
final int bMinZ = parseInteger(attrs, "minZ");
|
|
||||||
final int bMaxZ = parseInteger(attrs, "maxZ");
|
|
||||||
for (Node f = c.getFirstChild(); f != null; f = f.getNextSibling())
|
|
||||||
{
|
|
||||||
if (f.getNodeName().equals("point"))
|
|
||||||
{
|
|
||||||
attrs = f.getAttributes();
|
|
||||||
int x = parseInteger(attrs, "x");
|
|
||||||
int y = parseInteger(attrs, "y");
|
|
||||||
bannedZone.add(x, y, bMinZ, bMaxZ, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
zone.addBannedZone(bannedZone);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sp.addZone(zone);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
zones.add(i++, sp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public final void unload()
|
|
||||||
{
|
|
||||||
if (spawnTask != null)
|
|
||||||
{
|
|
||||||
spawnTask.cancel(false);
|
|
||||||
}
|
|
||||||
if (shotTask != null)
|
|
||||||
{
|
|
||||||
shotTask.cancel(false);
|
|
||||||
}
|
|
||||||
zones.forEach(SpawnZone::unload);
|
|
||||||
zones.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
public final void removeBeetle(L2Npc npc)
|
|
||||||
{
|
|
||||||
zones.get(npc.getVariables().getInt("zoneIndex", 0)).removeSpawn(npc);
|
|
||||||
npc.deleteMe();
|
|
||||||
}
|
|
||||||
|
|
||||||
private final class Zone extends L2Territory
|
|
||||||
{
|
|
||||||
private List<Zone> _bannedZones;
|
|
||||||
|
|
||||||
public Zone()
|
|
||||||
{
|
|
||||||
super(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Location getRandomPoint()
|
|
||||||
{
|
|
||||||
Location location = super.getRandomPoint();
|
|
||||||
while ((location != null) && isInsideBannedZone(location))
|
|
||||||
{
|
|
||||||
location = super.getRandomPoint();
|
|
||||||
}
|
|
||||||
return location;
|
|
||||||
}
|
|
||||||
|
|
||||||
public final void addBannedZone(Zone bZone)
|
|
||||||
{
|
|
||||||
if (_bannedZones == null)
|
|
||||||
{
|
|
||||||
_bannedZones = new ArrayList<>();
|
|
||||||
}
|
|
||||||
_bannedZones.add(bZone);
|
|
||||||
}
|
|
||||||
|
|
||||||
private final boolean isInsideBannedZone(Location location)
|
|
||||||
{
|
|
||||||
if (_bannedZones != null)
|
|
||||||
{
|
|
||||||
for (Zone z : _bannedZones)
|
|
||||||
{
|
|
||||||
if (z.isInside(location.getX(), location.getY()))
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private final class SpawnZone
|
|
||||||
{
|
|
||||||
private final List<Zone> _zones = new ArrayList<>();
|
|
||||||
private final List<L2Npc> _spawn = new CopyOnWriteArrayList<>();
|
|
||||||
private final int _maxNpcCount;
|
|
||||||
private final int _index;
|
|
||||||
|
|
||||||
public SpawnZone(int maxNpcCount, int index)
|
|
||||||
{
|
|
||||||
_maxNpcCount = maxNpcCount;
|
|
||||||
_index = index;
|
|
||||||
}
|
|
||||||
|
|
||||||
public final void addZone(Zone zone)
|
|
||||||
{
|
|
||||||
_zones.add(zone);
|
|
||||||
}
|
|
||||||
|
|
||||||
public final void removeSpawn(L2Npc obj)
|
|
||||||
{
|
|
||||||
_spawn.remove(obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
public final void unload()
|
|
||||||
{
|
|
||||||
_spawn.forEach(L2Npc::deleteMe);
|
|
||||||
_spawn.clear();
|
|
||||||
_zones.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
public final void refreshSpawn()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
while (_spawn.size() < _maxNpcCount)
|
|
||||||
{
|
|
||||||
final Location location = _zones.get(Rnd.get(_zones.size())).getRandomPoint();
|
|
||||||
if (location != null)
|
|
||||||
{
|
|
||||||
final L2Spawn spawn = new L2Spawn(18804);
|
|
||||||
spawn.setHeading(Rnd.get(65535));
|
|
||||||
spawn.setX(location.getX());
|
|
||||||
spawn.setY(location.getY());
|
|
||||||
spawn.setZ(GeoData.getInstance().getSpawnHeight(location));
|
|
||||||
|
|
||||||
final L2Npc npc = spawn.doSpawn();
|
|
||||||
npc.setIsNoRndWalk(true);
|
|
||||||
npc.setIsImmobilized(true);
|
|
||||||
npc.setIsInvul(true);
|
|
||||||
npc.disableCoreAI(true);
|
|
||||||
npc.setScriptValue(5);
|
|
||||||
npc.getVariables().set("zoneIndex", _index);
|
|
||||||
_spawn.add(npc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public final void refreshShots()
|
|
||||||
{
|
|
||||||
if (_spawn.size() > 0)
|
|
||||||
{
|
|
||||||
for (L2Npc npc : _spawn)
|
|
||||||
{
|
|
||||||
final int val = npc.getScriptValue();
|
|
||||||
if (val == 5)
|
|
||||||
{
|
|
||||||
npc.deleteMe();
|
|
||||||
_spawn.remove(npc);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
npc.setScriptValue(val + 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,6 +0,0 @@
|
|||||||
<html><body>Blacksmith of Mammon:<br>
|
|
||||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h npc_%objectId%_multisell 778">Craft R-Grade Dual Weapon</Button>
|
|
||||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h npc_%objectId%_exc_multisell 779">Bestow Special Ability on R-Grade Weapon</Button>
|
|
||||||
<!--<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h npc_%objectId%_exc_multisell 311262517">Change Special Ability of R-Grade Weapon</Button>-->
|
|
||||||
<!--<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h npc_%objectId%_exc_multisell 311262518">Change Special Ability of R95-Grade Weapon</Button>-->
|
|
||||||
</body></html>
|
|
@@ -1,8 +0,0 @@
|
|||||||
<html><body>Blacksmith of Mammon:<br>
|
|
||||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h npc_%objectId%_multisell 216">Craft S-Grade Dual Weapon</Button>
|
|
||||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h npc_%objectId%_exc_multisell 311262501">Bestow Special Ability on S-Grade Weapon</Button>
|
|
||||||
<!--<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h npc_%objectId%_exc_multisell 311262514">Change Special Ability of S-Grade Weapon</Button>-->
|
|
||||||
<!--<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h npc_%objectId%_exc_multisell 311262515">Change Special Ability of S80-Grade Weapon</Button>-->
|
|
||||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h npc_%objectId%_exc_multisell 311262504">Remove Seal from S-Grade Armor</Button>
|
|
||||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h npc_%objectId%_exc_multisell 311262505">Remove Seal from S-Grade Accessory</Button>
|
|
||||||
</body></html>
|
|
@@ -1,5 +0,0 @@
|
|||||||
<html><body>Blacksmith of Mammon:<br>
|
|
||||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h npc_%objectId%_multisell 311262502">Craft A-Grade Dual Weapon</Button>
|
|
||||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h npc_%objectId%_exc_multisell 311262510">Bestow Special Ability on A-Grade Weapon</Button>
|
|
||||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h npc_%objectId%_Quest Mammons 31126-03.html">Change Special Ability of A-Grade Weapon</Button>
|
|
||||||
</body></html>
|
|
@@ -1,6 +0,0 @@
|
|||||||
<html><body>Blacksmith of Mammon:<br>
|
|
||||||
I'll exchange the weapon that you've been using for a weapon that is one level stronger. Pay me the difference in Ancient Adena.<br>
|
|
||||||
There's something you should know. <font color="LEVEL">Special abilities</font> don't transfer. And if you transfer <font color="LEVEL">enchantments</font>, the new weapon will not be enchanted.<br>
|
|
||||||
<Button ALIGN=LEFT ICON="normal" action="bypass -h npc_%objectId%_exc_multisell 311262511">Replace a weapon with an even stronger weapon</Button>
|
|
||||||
<Button ALIGN=LEFT ICON="return" action="bypass -h npc_%objectId%_Quest Mammons 31126.html">Back</Button>
|
|
||||||
</body></html>
|
|
@@ -1,8 +0,0 @@
|
|||||||
<html><head><body>Blacksmith of Mammon:<br>
|
|
||||||
I will exchange the weapon for another type of the same grade. For example, you can exchange a mithril dagger for a two-handed claymore of the same grade. But, I have to warn you.<br>
|
|
||||||
First, weapons with <font color="LEVEL">special abilities</font> cannot be exchanged.<br>
|
|
||||||
Second, when exchanging a weapon that has been <font color="LEVEL">enchanted</font> the exchanged weapon will have the same enchantment.<br>
|
|
||||||
<Button ALIGN=LEFT ICON="normal" action="bypass -h npc_%objectId%_exc_multisell 311262512">Exchange a weapon of D-grade to B-grade for a different type</Button>
|
|
||||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h npc_%objectId%_exc_multisell 311262519">Exchange an A-grade weapon for a different type</Button>
|
|
||||||
<Button ALIGN=LEFT ICON="return" action="bypass -h npc_%objectId%_Quest Mammons 31126.html">Back</Button>
|
|
||||||
</body></html>
|
|
@@ -1,8 +0,0 @@
|
|||||||
<html><head><body>Blacksmith of Mammon:<br>
|
|
||||||
Do you know about the Foundation Items? Even we blacksmiths see them only infrequently.<br>
|
|
||||||
These uncommon items are brought into being by a power than goes beyond mere chance. We Dwarves say that it is the blessing of Maphr.<br>
|
|
||||||
That perfect craftsmanship is beyond the Human race's capacity.<br>
|
|
||||||
It is not, however, beyond mine. Bring me <font color="LEVEL">Mammon's Varnish Enhancer, which is sold by the Merchant of Mammon</font>. Then I will use techniques known only to me to transform the item into something accessible to mortals.<br>
|
|
||||||
Be sure to select a helmet among the rare items that provides you with a useful power. Don't worry if you make the wrong choice, though. You will have another chance to make a selection.<br>
|
|
||||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h npc_%objectId%_multisell 311262513">Complete a Foundation Item</Button>
|
|
||||||
</body></html>
|
|
@@ -1,17 +0,0 @@
|
|||||||
<html><body>Blacksmith of Mammon:<br>
|
|
||||||
May Mammon bless you! I, the Blacksmith of Mammon, have come to offer you arms of the highest quality.<br>
|
|
||||||
I shall mend your weapons and armor with skills that no novice blacksmith could ever hope to imitate.<br>
|
|
||||||
Yet there are a few things I must tell you. Although we Dwarves of Mammon didn't deal in coins of the outside world before, we have changed with the times and now accept them. Also remember that you can only remove seals from A-grade items with village blacksmiths now. Lastly, I can change the status of Bound items for you, if you provide an Unbind Scroll for me.<br>
|
|
||||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h npc_%objectId%_Quest Mammons 31126-01.html">R-grade</Button>
|
|
||||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h npc_%objectId%_Quest Mammons 31126-02.html">S-grade</Button>
|
|
||||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h npc_%objectId%_Quest Mammons 31126-03.html">A-grade</Button>
|
|
||||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h npc_%objectId%_exc_multisell 311262509">Remove the special ability from a weapon</Button>
|
|
||||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h npc_%objectId%_Quest Mammons 31126-04.html">Replace a weapon with an even stronger weapon</Button>
|
|
||||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h npc_%objectId%_Quest Mammons 31126-05.html">Replace a weapon with another type of the same grade</Button>
|
|
||||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h npc_%objectId%_Quest Mammons 31126-06.html">Finish a chaotic masterwork item</Button>
|
|
||||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h npc_%objectId%_exc_multisell 311262516">Exchange masterwork upper armor for common upper armor.</Button>
|
|
||||||
<!--<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h npc_%objectId%_exc_multisell 311262520">Remove the curse contained in an item or upgrade the item to a blessed item</Button>-->
|
|
||||||
<!--<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h npc_%objectId%_exc_multisell 311262521">Upgrade Amaranthine/Eternal equipment</Button>-->
|
|
||||||
<!--<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h npc_%objectId%_exc_multisell 311262522">Switch Amaranthine/Eternal equipment</Button>-->
|
|
||||||
<Button ALIGN=LEFT ICON="QUEST" action="bypass -h npc_%objectId%_Quest">Quest</Button>
|
|
||||||
</body></html>
|
|
@@ -1,6 +0,0 @@
|
|||||||
<html><body>Priest of Mammon:<br>
|
|
||||||
The door to the Necropolis and Catacombs is closed. I heard that the monsters inside were cleaned out by the Goddess of Destruction but... hmm... I don't know.<br>
|
|
||||||
No matter, both the Dawn and Dusk were caught horribly unprepared by Shilen's resurrection. Haha... Because of this, I started taking on the work normally done by the priests of Dawn and Dusk.<br>
|
|
||||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h npc_%objectId%_multisell 208">"I want to buy some supplies."</Button>
|
|
||||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h npc_%objectId%_multisell 2021">"I'd like to exchange a seal stone for an item."</Button>
|
|
||||||
</body></html>
|
|
@@ -1,6 +0,0 @@
|
|||||||
<html><body>Merchant of Mammon:<br>
|
|
||||||
Elcyum is a mineral found by the Gray Pillar dwarves in the deepest part of the Spine Mountains.<br>
|
|
||||||
Its energies increase an item's upgrade chances. It can also be exchanged for a <font color="LEVEL">Giant's Augmenting Stone</font> that provides advanced augmentation.<br>
|
|
||||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h npc_%objectId%_multisell 2030">"I want to exchange Elcyum for something."</Button>
|
|
||||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h npc_%objectId%_multisell 2031">"I want to exchange a Giant's Augmenting Stone for something."</Button>
|
|
||||||
</body></html>
|
|
@@ -1,9 +0,0 @@
|
|||||||
<html><body>Merchant of Mammon:<br>
|
|
||||||
May Mammon's blessings be upon you! Mammon's guild is here to present our special collection of rare items.<br>
|
|
||||||
Before you start shopping, there's a few things you should know. While we dealt only in Ancient Adena in the past, now we take Adena like any other merchant. Also, you must bring a <font color="LEVEL">Blank Scroll</font> if you plan to purchase an Enchant Scroll. If you bring us Soul Crystal Fragments, we can make them into whole Soul Crystals. We also have <font color="LEVEL">Elcyum</font> upgrade items. And don't forget to check out our Augmenting Stones!.<br>
|
|
||||||
Remember, local tax rates apply! <br>
|
|
||||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h npc_%objectId%_multisell 207">"I want to buy something."</Button>
|
|
||||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h npc_%objectId%_multisell 777">"I want to exchange a Rare Soul Crystal for something else."</Button>
|
|
||||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h npc_%objectId%_TerritoryStatus">"Can you tell me about the local lord and tax rate?"</Button>
|
|
||||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h npc_%objectId%_Quest Mammons 33739-01.html">"I want to take a look at some Elcyum."</Button>
|
|
||||||
</body></html>
|
|
@@ -1,140 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2004-2015 L2J DataPack
|
|
||||||
*
|
|
||||||
* This file is part of L2J DataPack.
|
|
||||||
*
|
|
||||||
* L2J DataPack 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.
|
|
||||||
*
|
|
||||||
* L2J DataPack 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.npc.Mammons;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
import ai.npc.AbstractNpcAI;
|
|
||||||
|
|
||||||
import com.l2jserver.Config;
|
|
||||||
import com.l2jserver.gameserver.enums.ChatType;
|
|
||||||
import com.l2jserver.gameserver.model.Location;
|
|
||||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
|
||||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
|
||||||
import com.l2jserver.gameserver.network.NpcStringId;
|
|
||||||
import com.l2jserver.gameserver.util.Broadcast;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Mammons AI.
|
|
||||||
* @author St3eT
|
|
||||||
*/
|
|
||||||
public final class Mammons extends AbstractNpcAI
|
|
||||||
{
|
|
||||||
// NPCs
|
|
||||||
private static final int MAMMONS[] =
|
|
||||||
{
|
|
||||||
31126, // Blacksmith of Mammon
|
|
||||||
33739, // Priest of Mammon
|
|
||||||
33511, // Merchant of Mammon
|
|
||||||
};
|
|
||||||
// Locations
|
|
||||||
private static final Location[] BLACKSMITH_LOC =
|
|
||||||
{
|
|
||||||
new Location(146873, 29448, -2264, 0), // Aden
|
|
||||||
new Location(81266, 150091, -3528, 891), // Giran
|
|
||||||
new Location(42825, -41337, -2184), // Rune
|
|
||||||
};
|
|
||||||
private static Location[] MERCHANT_LOC =
|
|
||||||
{
|
|
||||||
new Location(146872, 29569, -2264, 0), // Aden
|
|
||||||
new Location(81272, 150041, -3528, 891), // Giran
|
|
||||||
new Location(42803, -41283, -2184, 37972), // Rune
|
|
||||||
};
|
|
||||||
private static Location[] PRIEST_LOC =
|
|
||||||
{
|
|
||||||
new Location(146882, 29665, -2264, 0), // Aden
|
|
||||||
new Location(81284, 150155, -3528, 891), // Giran
|
|
||||||
new Location(42784, -41236, -2192, 37972), // Rune
|
|
||||||
};
|
|
||||||
// Misc
|
|
||||||
private static String[] TOWN_NAME =
|
|
||||||
{
|
|
||||||
"Town of Aden",
|
|
||||||
"Town of Giran",
|
|
||||||
"Town of Rune",
|
|
||||||
};
|
|
||||||
private static final int TELEPORT_DELAY = 1800000; // 30min
|
|
||||||
private static final List<L2Npc> _mammons = new ArrayList<>();
|
|
||||||
|
|
||||||
private Mammons()
|
|
||||||
{
|
|
||||||
super(Mammons.class.getSimpleName(), "ai/npc");
|
|
||||||
addStartNpc(MAMMONS);
|
|
||||||
addTalkId(MAMMONS);
|
|
||||||
addFirstTalkId(MAMMONS);
|
|
||||||
|
|
||||||
onAdvEvent("RESPAWN_MAMMONS", null, null);
|
|
||||||
startQuestTimer("RESPAWN_MAMMONS", TELEPORT_DELAY, null, null, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
|
||||||
{
|
|
||||||
String htmltext = null;
|
|
||||||
|
|
||||||
switch (event)
|
|
||||||
{
|
|
||||||
case "31126.html":
|
|
||||||
case "31126-01.html":
|
|
||||||
case "31126-02.html":
|
|
||||||
case "31126-03.html":
|
|
||||||
case "31126-04.html":
|
|
||||||
case "31126-05.html":
|
|
||||||
case "31126-06.html":
|
|
||||||
case "33739-01.html":
|
|
||||||
{
|
|
||||||
htmltext = event;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case "RESPAWN_MAMMONS":
|
|
||||||
{
|
|
||||||
if (!_mammons.isEmpty())
|
|
||||||
{
|
|
||||||
_mammons.stream().filter(Objects::nonNull).forEach(L2Npc::deleteMe);
|
|
||||||
_mammons.clear();
|
|
||||||
}
|
|
||||||
final int town = getRandom(3);
|
|
||||||
final L2Npc blacksmith = addSpawn(MAMMONS[0], BLACKSMITH_LOC[town]);
|
|
||||||
final L2Npc merchant = addSpawn(MAMMONS[1], MERCHANT_LOC[town]);
|
|
||||||
final L2Npc priest = addSpawn(MAMMONS[2], PRIEST_LOC[town]);
|
|
||||||
_mammons.addAll(Arrays.asList(blacksmith, merchant, priest));
|
|
||||||
|
|
||||||
if (blacksmith != null)
|
|
||||||
{
|
|
||||||
broadcastNpcSay(blacksmith, ChatType.NPC_GENERAL, NpcStringId.I_HAVE_SOME_EXCELLENT_WEAPONS_TO_SHOW_YOU);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Config.ANNOUNCE_MAMMON_SPAWN)
|
|
||||||
{
|
|
||||||
Broadcast.toAllOnlinePlayers("Mammon's has been spawned in " + TOWN_NAME[town] + ".", false);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return htmltext;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void main(String[] args)
|
|
||||||
{
|
|
||||||
new Mammons();
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,4 +0,0 @@
|
|||||||
<html><body>Rignos:<br>
|
|
||||||
Marvellous! So, have you collected all 4 Race Stamps? You haven't taken any shortcuts or copied any of them, have you? Excellent! Then take this key -- it will prove useful when rescuing Parme!<br>
|
|
||||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest Rignos exchange">Exchange Race Stamps for the Secret Garden Key.</Button>
|
|
||||||
</body></html>
|
|
@@ -1,5 +0,0 @@
|
|||||||
<html><body>Rignos:<br>
|
|
||||||
Welcome, welcome! I am Rignos. Parme and I are old friends, so I've come here to help. It's been a long time since I've traveled this far, but beautiful Isle of Prayer always makes me feel like I'm on vacation. Now then, how can I help? A race! You know what I always say, "Joy and energy, all the time and in every way!" I call it the <font color="LEVEL">Grand Isle of Prayer Race</font>!<br>
|
|
||||||
You're a little late, though -- the race is already underway!<br>
|
|
||||||
Come back another time.
|
|
||||||
</body></html>
|
|
@@ -1,5 +0,0 @@
|
|||||||
<html><body>Rignos:<br>
|
|
||||||
You have 30 minutes to find three other structures just like the one behind me. They are scattered around the island. Once you find them, go inside and battle the opponents you find there. One of these combatants will drop a Race Stamp. Bring 4 Race Stamps to me within the allotted time, and I will give you a reward that will aid you in your endeavor to rescue Parme.<br>
|
|
||||||
Don't forget to include the building behind me!<br>
|
|
||||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest Rignos startRace">I'm ready! Let's start the race.</Button>
|
|
||||||
</body></html>
|
|
@@ -1,6 +0,0 @@
|
|||||||
<html><body>Rignos:<br>
|
|
||||||
Welcome, welcome! I am Rignos. Parme and I are old friends, so I've come here to help. It's been a long time since I've traveled this far, but the beautiful Isle of Prayer always makes me feel like I'm on vacation. Now then, how can I help? A race! You know what I always say, "Joy and energy, all the time and in every way!" I call it the <font color="LEVEL">Grand Isle of Prayer Race</font>!<br>
|
|
||||||
You do know what this means, don't you?<br>
|
|
||||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest Rignos 32349-03.html">Ask about the Grand Isle of Prayer Race.</Button>
|
|
||||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest Rignos startRace">Start the Race.</Button>
|
|
||||||
</body></html>
|
|
@@ -1,118 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2004-2015 L2J DataPack
|
|
||||||
*
|
|
||||||
* This file is part of L2J DataPack.
|
|
||||||
*
|
|
||||||
* L2J DataPack 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.
|
|
||||||
*
|
|
||||||
* L2J DataPack 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.npc.Rignos;
|
|
||||||
|
|
||||||
import ai.npc.AbstractNpcAI;
|
|
||||||
|
|
||||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
|
||||||
import com.l2jserver.gameserver.model.actor.L2Summon;
|
|
||||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
|
||||||
import com.l2jserver.gameserver.model.holders.SkillHolder;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Rignos AI.
|
|
||||||
* @author St3eT
|
|
||||||
*/
|
|
||||||
public class Rignos extends AbstractNpcAI
|
|
||||||
{
|
|
||||||
// NPC
|
|
||||||
private static final int RIGNOS = 32349; // Rignos
|
|
||||||
// Item
|
|
||||||
private static final int STAMP = 10013; // Race Stamp
|
|
||||||
private static final int KEY = 9694; // Secret Key
|
|
||||||
// Skill
|
|
||||||
private static final SkillHolder TIMER = new SkillHolder(5239, 5); // Event Timer
|
|
||||||
// Misc
|
|
||||||
private static final int MIN_LV = 78;
|
|
||||||
|
|
||||||
private Rignos()
|
|
||||||
{
|
|
||||||
super(Rignos.class.getSimpleName(), "ai/npc");
|
|
||||||
addStartNpc(RIGNOS);
|
|
||||||
addTalkId(RIGNOS);
|
|
||||||
addFirstTalkId(RIGNOS);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
|
||||||
{
|
|
||||||
switch (event)
|
|
||||||
{
|
|
||||||
case "32349-03.html":
|
|
||||||
{
|
|
||||||
return event;
|
|
||||||
}
|
|
||||||
case "startRace":
|
|
||||||
{
|
|
||||||
if (npc.isScriptValue(0))
|
|
||||||
{
|
|
||||||
npc.setScriptValue(1);
|
|
||||||
startQuestTimer("TIME_OUT", 1800000, npc, null);
|
|
||||||
TIMER.getSkill().applyEffects(player, player);
|
|
||||||
final L2Summon pet = player.getPet();
|
|
||||||
if (pet != null)
|
|
||||||
{
|
|
||||||
TIMER.getSkill().applyEffects(pet, pet);
|
|
||||||
}
|
|
||||||
player.getServitors().values().forEach(s ->
|
|
||||||
{
|
|
||||||
TIMER.getSkill().applyEffects(s, s);
|
|
||||||
});
|
|
||||||
|
|
||||||
if (hasQuestItems(player, STAMP))
|
|
||||||
{
|
|
||||||
takeItems(player, STAMP, -1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case "exchange":
|
|
||||||
{
|
|
||||||
if (getQuestItemsCount(player, STAMP) >= 4)
|
|
||||||
{
|
|
||||||
giveItems(player, KEY, 3);
|
|
||||||
takeItems(player, STAMP, -1);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case "TIME_OUT":
|
|
||||||
{
|
|
||||||
npc.setScriptValue(0);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return super.onAdvEvent(event, npc, player);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String onFirstTalk(L2Npc npc, L2PcInstance player)
|
|
||||||
{
|
|
||||||
String htmltext = (npc.isScriptValue(0) && (player.getLevel() >= MIN_LV)) ? "32349.html" : "32349-02.html";
|
|
||||||
if (getQuestItemsCount(player, STAMP) >= 4)
|
|
||||||
{
|
|
||||||
htmltext = "32349-01.html";
|
|
||||||
}
|
|
||||||
return htmltext;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void main(String[] args)
|
|
||||||
{
|
|
||||||
new Rignos();
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,151 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2004-2015 L2J DataPack
|
|
||||||
*
|
|
||||||
* This file is part of L2J DataPack.
|
|
||||||
*
|
|
||||||
* L2J DataPack 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.
|
|
||||||
*
|
|
||||||
* L2J DataPack 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 conquerablehalls.DevastatedCastle;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Map.Entry;
|
|
||||||
|
|
||||||
import com.l2jserver.gameserver.ai.CtrlIntention;
|
|
||||||
import com.l2jserver.gameserver.data.sql.impl.ClanTable;
|
|
||||||
import com.l2jserver.gameserver.data.xml.impl.NpcData;
|
|
||||||
import com.l2jserver.gameserver.datatables.SkillData;
|
|
||||||
import com.l2jserver.gameserver.enums.ChatType;
|
|
||||||
import com.l2jserver.gameserver.model.L2Clan;
|
|
||||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
|
||||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
|
||||||
import com.l2jserver.gameserver.model.entity.clanhall.ClanHallSiegeEngine;
|
|
||||||
import com.l2jserver.gameserver.network.NpcStringId;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Devastated Castle clan hall siege script.
|
|
||||||
* @author BiggBoss
|
|
||||||
*/
|
|
||||||
public final class DevastatedCastle extends ClanHallSiegeEngine
|
|
||||||
{
|
|
||||||
private static final int GUSTAV = 35410;
|
|
||||||
private static final int MIKHAIL = 35409;
|
|
||||||
private static final int DIETRICH = 35408;
|
|
||||||
private static final double GUSTAV_TRIGGER_HP = NpcData.getInstance().getTemplate(GUSTAV).getBaseHpMax() / 12;
|
|
||||||
|
|
||||||
private static Map<Integer, Integer> _damageToGustav = new HashMap<>();
|
|
||||||
|
|
||||||
private DevastatedCastle()
|
|
||||||
{
|
|
||||||
super(DevastatedCastle.class.getSimpleName(), "conquerablehalls", DEVASTATED_CASTLE);
|
|
||||||
addKillId(GUSTAV);
|
|
||||||
addSpawnId(MIKHAIL);
|
|
||||||
addSpawnId(DIETRICH);
|
|
||||||
addAttackId(GUSTAV);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String onSpawn(L2Npc npc)
|
|
||||||
{
|
|
||||||
if (npc.getId() == MIKHAIL)
|
|
||||||
{
|
|
||||||
broadcastNpcSay(npc, ChatType.NPC_SHOUT, NpcStringId.GLORY_TO_ADEN_THE_KINGDOM_OF_THE_LION_GLORY_TO_SIR_GUSTAV_OUR_IMMORTAL_LORD);
|
|
||||||
}
|
|
||||||
else if (npc.getId() == DIETRICH)
|
|
||||||
{
|
|
||||||
broadcastNpcSay(npc, ChatType.NPC_SHOUT, NpcStringId.SOLDIERS_OF_GUSTAV_GO_FORTH_AND_DESTROY_THE_INVADERS);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String onAttack(L2Npc npc, L2PcInstance attacker, int damage, boolean isSummon)
|
|
||||||
{
|
|
||||||
if (!_hall.isInSiege())
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
synchronized (this)
|
|
||||||
{
|
|
||||||
final L2Clan clan = attacker.getClan();
|
|
||||||
|
|
||||||
if ((clan != null) && checkIsAttacker(clan))
|
|
||||||
{
|
|
||||||
final int id = clan.getId();
|
|
||||||
if (_damageToGustav.containsKey(id))
|
|
||||||
{
|
|
||||||
int newDamage = _damageToGustav.get(id);
|
|
||||||
newDamage += damage;
|
|
||||||
_damageToGustav.put(id, newDamage);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_damageToGustav.put(id, damage);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((npc.getCurrentHp() < GUSTAV_TRIGGER_HP) && (npc.getAI().getIntention() != CtrlIntention.AI_INTENTION_CAST))
|
|
||||||
{
|
|
||||||
broadcastNpcSay(npc, ChatType.NPC_GENERAL, NpcStringId.THIS_IS_UNBELIEVABLE_HAVE_I_REALLY_BEEN_DEFEATED_I_SHALL_RETURN_AND_TAKE_YOUR_HEAD);
|
|
||||||
npc.getAI().setIntention(CtrlIntention.AI_INTENTION_CAST, SkillData.getInstance().getSkill(4235, 1), npc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return super.onAttack(npc, attacker, damage, isSummon);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
|
|
||||||
{
|
|
||||||
if (!_hall.isInSiege())
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
_missionAccomplished = true;
|
|
||||||
|
|
||||||
if (npc.getId() == GUSTAV)
|
|
||||||
{
|
|
||||||
synchronized (this)
|
|
||||||
{
|
|
||||||
cancelSiegeTask();
|
|
||||||
endSiege();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return super.onKill(npc, killer, isSummon);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public L2Clan getWinner()
|
|
||||||
{
|
|
||||||
int counter = 0;
|
|
||||||
int damagest = 0;
|
|
||||||
for (Entry<Integer, Integer> e : _damageToGustav.entrySet())
|
|
||||||
{
|
|
||||||
final int damage = e.getValue();
|
|
||||||
if (damage > counter)
|
|
||||||
{
|
|
||||||
counter = damage;
|
|
||||||
damagest = e.getKey();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ClanTable.getInstance().getClan(damagest);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void main(String[] args)
|
|
||||||
{
|
|
||||||
new DevastatedCastle();
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,184 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2004-2015 L2J DataPack
|
|
||||||
*
|
|
||||||
* This file is part of L2J DataPack.
|
|
||||||
*
|
|
||||||
* L2J DataPack 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.
|
|
||||||
*
|
|
||||||
* L2J DataPack 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 conquerablehalls.FortressOfResistance;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Map.Entry;
|
|
||||||
|
|
||||||
import com.l2jserver.gameserver.cache.HtmCache;
|
|
||||||
import com.l2jserver.gameserver.data.sql.impl.ClanTable;
|
|
||||||
import com.l2jserver.gameserver.model.L2Clan;
|
|
||||||
import com.l2jserver.gameserver.model.L2Spawn;
|
|
||||||
import com.l2jserver.gameserver.model.Location;
|
|
||||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
|
||||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
|
||||||
import com.l2jserver.gameserver.model.entity.clanhall.ClanHallSiegeEngine;
|
|
||||||
import com.l2jserver.gameserver.network.serverpackets.NpcHtmlMessage;
|
|
||||||
import com.l2jserver.gameserver.util.Util;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Fortress of Resistance clan hall siege Script.
|
|
||||||
* @author BiggBoss
|
|
||||||
*/
|
|
||||||
public final class FortressOfResistance extends ClanHallSiegeEngine
|
|
||||||
{
|
|
||||||
private final int MESSENGER = 35382;
|
|
||||||
private final int BLOODY_LORD_NURKA = 35375;
|
|
||||||
|
|
||||||
private final Location[] NURKA_COORDS =
|
|
||||||
{
|
|
||||||
new Location(45109, 112124, -1900), // 30%
|
|
||||||
new Location(47653, 110816, -2110), // 40%
|
|
||||||
new Location(47247, 109396, -2000)
|
|
||||||
// 30%
|
|
||||||
};
|
|
||||||
|
|
||||||
private L2Spawn _nurka;
|
|
||||||
private final Map<Integer, Long> _damageToNurka = new HashMap<>();
|
|
||||||
private NpcHtmlMessage _messengerMsg;
|
|
||||||
|
|
||||||
private FortressOfResistance()
|
|
||||||
{
|
|
||||||
super(FortressOfResistance.class.getSimpleName(), "conquerablehalls", FORTRESS_RESSISTANCE);
|
|
||||||
addFirstTalkId(MESSENGER);
|
|
||||||
addKillId(BLOODY_LORD_NURKA);
|
|
||||||
addAttackId(BLOODY_LORD_NURKA);
|
|
||||||
buildMessengerMessage();
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
_nurka = new L2Spawn(BLOODY_LORD_NURKA);
|
|
||||||
_nurka.setAmount(1);
|
|
||||||
_nurka.setRespawnDelay(10800);
|
|
||||||
// @formatter:off
|
|
||||||
// int chance = getRandom(100) + 1;
|
|
||||||
// if (chance <= 30)
|
|
||||||
// {
|
|
||||||
// coords = NURKA_COORDS[0];
|
|
||||||
// }
|
|
||||||
// else if ((chance > 30) && (chance <= 70))
|
|
||||||
// {
|
|
||||||
// coords = NURKA_COORDS[1];
|
|
||||||
// }
|
|
||||||
// else
|
|
||||||
// {
|
|
||||||
// coords = NURKA_COORDS[2];
|
|
||||||
// }
|
|
||||||
// @formatter:on
|
|
||||||
_nurka.setLocation(NURKA_COORDS[0]);
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
_log.warning(getName() + ": Couldnt set the Bloody Lord Nurka spawn");
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private final void buildMessengerMessage()
|
|
||||||
{
|
|
||||||
String html = HtmCache.getInstance().getHtm(null, "scripts/conquerablehalls/FortressOfResistance/partisan_ordery_brakel001.htm");
|
|
||||||
if (html != null)
|
|
||||||
{
|
|
||||||
// FIXME: We don't have an object id to put in here :(
|
|
||||||
_messengerMsg = new NpcHtmlMessage();
|
|
||||||
_messengerMsg.setHtml(html);
|
|
||||||
_messengerMsg.replace("%nextSiege%", Util.formatDate(_hall.getSiegeDate().getTime(), "yyyy-MM-dd HH:mm:ss"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String onFirstTalk(L2Npc npc, L2PcInstance player)
|
|
||||||
{
|
|
||||||
player.sendPacket(_messengerMsg);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String onAttack(L2Npc npc, L2PcInstance player, int damage, boolean isSummon)
|
|
||||||
{
|
|
||||||
if (!_hall.isInSiege())
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
int clanId = player.getClanId();
|
|
||||||
if (clanId > 0)
|
|
||||||
{
|
|
||||||
long clanDmg = (_damageToNurka.containsKey(clanId)) ? _damageToNurka.get(clanId) + damage : damage;
|
|
||||||
_damageToNurka.put(clanId, clanDmg);
|
|
||||||
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
|
|
||||||
{
|
|
||||||
if (!_hall.isInSiege())
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
_missionAccomplished = true;
|
|
||||||
|
|
||||||
synchronized (this)
|
|
||||||
{
|
|
||||||
npc.getSpawn().stopRespawn();
|
|
||||||
npc.deleteMe();
|
|
||||||
cancelSiegeTask();
|
|
||||||
endSiege();
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public L2Clan getWinner()
|
|
||||||
{
|
|
||||||
int winnerId = 0;
|
|
||||||
long counter = 0;
|
|
||||||
for (Entry<Integer, Long> e : _damageToNurka.entrySet())
|
|
||||||
{
|
|
||||||
long dam = e.getValue();
|
|
||||||
if (dam > counter)
|
|
||||||
{
|
|
||||||
winnerId = e.getKey();
|
|
||||||
counter = dam;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ClanTable.getInstance().getClan(winnerId);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onSiegeStarts()
|
|
||||||
{
|
|
||||||
_nurka.init();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onSiegeEnds()
|
|
||||||
{
|
|
||||||
buildMessengerMessage();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void main(String[] args)
|
|
||||||
{
|
|
||||||
new FortressOfResistance();
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,4 +0,0 @@
|
|||||||
<html><body>
|
|
||||||
I shouldn't be telling you this... but our master, Nurka, visits this clan hall on a regular basis.<br>
|
|
||||||
I think his next visit will be around %nextSiege%...
|
|
||||||
</body></html>
|
|
@@ -1,176 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2004-2015 L2J DataPack
|
|
||||||
*
|
|
||||||
* This file is part of L2J DataPack.
|
|
||||||
*
|
|
||||||
* L2J DataPack 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.
|
|
||||||
*
|
|
||||||
* L2J DataPack 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 conquerablehalls.FortressOfTheDead;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Map.Entry;
|
|
||||||
|
|
||||||
import com.l2jserver.gameserver.GameTimeController;
|
|
||||||
import com.l2jserver.gameserver.ThreadPoolManager;
|
|
||||||
import com.l2jserver.gameserver.data.sql.impl.ClanTable;
|
|
||||||
import com.l2jserver.gameserver.enums.ChatType;
|
|
||||||
import com.l2jserver.gameserver.model.L2Clan;
|
|
||||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
|
||||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
|
||||||
import com.l2jserver.gameserver.model.entity.clanhall.ClanHallSiegeEngine;
|
|
||||||
import com.l2jserver.gameserver.network.NpcStringId;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Fortress of the Dead clan hall siege script.
|
|
||||||
* @author BiggBoss
|
|
||||||
*/
|
|
||||||
public final class FortressOfTheDead extends ClanHallSiegeEngine
|
|
||||||
{
|
|
||||||
private static final int LIDIA = 35629;
|
|
||||||
private static final int ALFRED = 35630;
|
|
||||||
private static final int GISELLE = 35631;
|
|
||||||
|
|
||||||
private static Map<Integer, Integer> _damageToLidia = new HashMap<>();
|
|
||||||
|
|
||||||
public FortressOfTheDead()
|
|
||||||
{
|
|
||||||
super(FortressOfTheDead.class.getSimpleName(), "conquerablehalls", FORTRESS_OF_DEAD);
|
|
||||||
addKillId(LIDIA);
|
|
||||||
addKillId(ALFRED);
|
|
||||||
addKillId(GISELLE);
|
|
||||||
|
|
||||||
addSpawnId(LIDIA);
|
|
||||||
addSpawnId(ALFRED);
|
|
||||||
addSpawnId(GISELLE);
|
|
||||||
|
|
||||||
addAttackId(LIDIA);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String onSpawn(L2Npc npc)
|
|
||||||
{
|
|
||||||
if (npc.getId() == LIDIA)
|
|
||||||
{
|
|
||||||
broadcastNpcSay(npc, ChatType.NPC_SHOUT, NpcStringId.HMM_THOSE_WHO_ARE_NOT_OF_THE_BLOODLINE_ARE_COMING_THIS_WAY_TO_TAKE_OVER_THE_CASTLE_HUMPH_THE_BITTER_GRUDGES_OF_THE_DEAD_YOU_MUST_NOT_MAKE_LIGHT_OF_THEIR_POWER);
|
|
||||||
}
|
|
||||||
else if (npc.getId() == ALFRED)
|
|
||||||
{
|
|
||||||
broadcastNpcSay(npc, ChatType.NPC_SHOUT, NpcStringId.HEH_HEH_I_SEE_THAT_THE_FEAST_HAS_BEGUN_BE_WARY_THE_CURSE_OF_THE_HELLMANN_FAMILY_HAS_POISONED_THIS_LAND);
|
|
||||||
}
|
|
||||||
else if (npc.getId() == GISELLE)
|
|
||||||
{
|
|
||||||
broadcastNpcSay(npc, ChatType.NPC_SHOUT, NpcStringId.ARISE_MY_FAITHFUL_SERVANTS_YOU_MY_PEOPLE_WHO_HAVE_INHERITED_THE_BLOOD_IT_IS_THE_CALLING_OF_MY_DAUGHTER_THE_FEAST_OF_BLOOD_WILL_NOW_BEGIN);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String onAttack(L2Npc npc, L2PcInstance attacker, int damage, boolean isSummon)
|
|
||||||
{
|
|
||||||
if (!_hall.isInSiege())
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
synchronized (this)
|
|
||||||
{
|
|
||||||
final L2Clan clan = attacker.getClan();
|
|
||||||
|
|
||||||
if ((clan != null) && checkIsAttacker(clan))
|
|
||||||
{
|
|
||||||
final int id = clan.getId();
|
|
||||||
if ((id > 0) && _damageToLidia.containsKey(id))
|
|
||||||
{
|
|
||||||
int newDamage = _damageToLidia.get(id);
|
|
||||||
newDamage += damage;
|
|
||||||
_damageToLidia.put(id, newDamage);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_damageToLidia.put(id, damage);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
|
|
||||||
{
|
|
||||||
if (!_hall.isInSiege())
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
final int npcId = npc.getId();
|
|
||||||
|
|
||||||
if ((npcId == ALFRED) || (npcId == GISELLE))
|
|
||||||
{
|
|
||||||
broadcastNpcSay(npc, ChatType.NPC_SHOUT, NpcStringId.AARGH_IF_I_DIE_THEN_THE_MAGIC_FORCE_FIELD_OF_BLOOD_WILL);
|
|
||||||
}
|
|
||||||
if (npcId == LIDIA)
|
|
||||||
{
|
|
||||||
broadcastNpcSay(npc, ChatType.NPC_SHOUT, NpcStringId.GRARR_FOR_THE_NEXT_2_MINUTES_OR_SO_THE_GAME_ARENA_ARE_WILL_BE_CLEANED_THROW_ANY_ITEMS_YOU_DON_T_NEED_TO_THE_FLOOR_NOW);
|
|
||||||
_missionAccomplished = true;
|
|
||||||
synchronized (this)
|
|
||||||
{
|
|
||||||
cancelSiegeTask();
|
|
||||||
endSiege();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public L2Clan getWinner()
|
|
||||||
{
|
|
||||||
int counter = 0;
|
|
||||||
int damagest = 0;
|
|
||||||
for (Entry<Integer, Integer> e : _damageToLidia.entrySet())
|
|
||||||
{
|
|
||||||
final int damage = e.getValue();
|
|
||||||
if (damage > counter)
|
|
||||||
{
|
|
||||||
counter = damage;
|
|
||||||
damagest = e.getKey();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ClanTable.getInstance().getClan(damagest);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void startSiege()
|
|
||||||
{
|
|
||||||
// Siege must start at night
|
|
||||||
int hoursLeft = (GameTimeController.getInstance().getGameTime() / 60) % 24;
|
|
||||||
|
|
||||||
if ((hoursLeft < 0) || (hoursLeft > 6))
|
|
||||||
{
|
|
||||||
cancelSiegeTask();
|
|
||||||
long scheduleTime = (24 - hoursLeft) * 10 * 60000;
|
|
||||||
_siegeTask = ThreadPoolManager.getInstance().scheduleGeneral(new SiegeStarts(), scheduleTime);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
super.startSiege();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void main(String[] args)
|
|
||||||
{
|
|
||||||
new FortressOfTheDead();
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,939 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2004-2015 L2J DataPack
|
|
||||||
*
|
|
||||||
* This file is part of L2J DataPack.
|
|
||||||
*
|
|
||||||
* L2J DataPack 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.
|
|
||||||
*
|
|
||||||
* L2J DataPack 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 conquerablehalls.RainbowSpringsChateau;
|
|
||||||
|
|
||||||
import java.sql.Connection;
|
|
||||||
import java.sql.PreparedStatement;
|
|
||||||
import java.sql.ResultSet;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Calendar;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.concurrent.ScheduledFuture;
|
|
||||||
|
|
||||||
import com.l2jserver.Config;
|
|
||||||
import com.l2jserver.L2DatabaseFactory;
|
|
||||||
import com.l2jserver.gameserver.ThreadPoolManager;
|
|
||||||
import com.l2jserver.gameserver.cache.HtmCache;
|
|
||||||
import com.l2jserver.gameserver.data.sql.impl.ClanTable;
|
|
||||||
import com.l2jserver.gameserver.datatables.SpawnTable;
|
|
||||||
import com.l2jserver.gameserver.enums.ChatType;
|
|
||||||
import com.l2jserver.gameserver.instancemanager.CHSiegeManager;
|
|
||||||
import com.l2jserver.gameserver.instancemanager.ZoneManager;
|
|
||||||
import com.l2jserver.gameserver.model.L2Clan;
|
|
||||||
import com.l2jserver.gameserver.model.L2Object;
|
|
||||||
import com.l2jserver.gameserver.model.L2Party;
|
|
||||||
import com.l2jserver.gameserver.model.L2Spawn;
|
|
||||||
import com.l2jserver.gameserver.model.Location;
|
|
||||||
import com.l2jserver.gameserver.model.TeleportWhereType;
|
|
||||||
import com.l2jserver.gameserver.model.actor.L2Character;
|
|
||||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
|
||||||
import com.l2jserver.gameserver.model.actor.L2Summon;
|
|
||||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
|
||||||
import com.l2jserver.gameserver.model.entity.clanhall.ClanHallSiegeEngine;
|
|
||||||
import com.l2jserver.gameserver.model.entity.clanhall.SiegableHall;
|
|
||||||
import com.l2jserver.gameserver.model.entity.clanhall.SiegeStatus;
|
|
||||||
import com.l2jserver.gameserver.model.items.L2Item;
|
|
||||||
import com.l2jserver.gameserver.model.items.instance.L2ItemInstance;
|
|
||||||
import com.l2jserver.gameserver.model.skills.Skill;
|
|
||||||
import com.l2jserver.gameserver.network.serverpackets.NpcSay;
|
|
||||||
import com.l2jserver.gameserver.util.Broadcast;
|
|
||||||
import com.l2jserver.gameserver.util.Util;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Rainbow Springs Chateau clan hall siege script.
|
|
||||||
* @author BiggBoss
|
|
||||||
*/
|
|
||||||
public final class RainbowSpringsChateau extends ClanHallSiegeEngine
|
|
||||||
{
|
|
||||||
protected static class SetFinalAttackers implements Runnable
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public void run()
|
|
||||||
{
|
|
||||||
if (_rainbow == null)
|
|
||||||
{
|
|
||||||
_rainbow = CHSiegeManager.getInstance().getSiegableHall(RAINBOW_SPRINGS);
|
|
||||||
}
|
|
||||||
|
|
||||||
int spotLeft = 4;
|
|
||||||
if (_rainbow.getOwnerId() > 0)
|
|
||||||
{
|
|
||||||
L2Clan owner = ClanTable.getInstance().getClan(_rainbow.getOwnerId());
|
|
||||||
if (owner != null)
|
|
||||||
{
|
|
||||||
_rainbow.free();
|
|
||||||
owner.setHideoutId(0);
|
|
||||||
_acceptedClans.add(owner);
|
|
||||||
--spotLeft;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < spotLeft; i++)
|
|
||||||
{
|
|
||||||
long counter = 0;
|
|
||||||
L2Clan clan = null;
|
|
||||||
for (int clanId : _warDecreesCount.keySet())
|
|
||||||
{
|
|
||||||
L2Clan actingClan = ClanTable.getInstance().getClan(clanId);
|
|
||||||
if ((actingClan == null) || (actingClan.getDissolvingExpiryTime() > 0))
|
|
||||||
{
|
|
||||||
_warDecreesCount.remove(clanId);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
final long count = _warDecreesCount.get(clanId);
|
|
||||||
if (count > counter)
|
|
||||||
{
|
|
||||||
counter = count;
|
|
||||||
clan = actingClan;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ((clan != null) && (_acceptedClans.size() < 4))
|
|
||||||
{
|
|
||||||
_acceptedClans.add(clan);
|
|
||||||
L2PcInstance leader = clan.getLeader().getPlayerInstance();
|
|
||||||
if (leader != null)
|
|
||||||
{
|
|
||||||
leader.sendMessage("Your clan has been accepted to join the RainBow Srpings Chateau siege!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (_acceptedClans.size() >= 2)
|
|
||||||
{
|
|
||||||
_nextSiege = ThreadPoolManager.getInstance().scheduleGeneral(new SiegeStart(), 3600000);
|
|
||||||
_rainbow.updateSiegeStatus(SiegeStatus.WAITING_BATTLE);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Broadcast.toAllOnlinePlayers("Rainbow Springs Chateau siege aborted due lack of population");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected static class SiegeStart implements Runnable
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public void run()
|
|
||||||
{
|
|
||||||
if (_rainbow == null)
|
|
||||||
{
|
|
||||||
_rainbow = CHSiegeManager.getInstance().getSiegableHall(RAINBOW_SPRINGS);
|
|
||||||
}
|
|
||||||
|
|
||||||
// XXX _rainbow.siegeStarts();
|
|
||||||
|
|
||||||
spawnGourds();
|
|
||||||
_siegeEnd = ThreadPoolManager.getInstance().scheduleGeneral(new SiegeEnd(null), _rainbow.getSiegeLenght() - 120000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static L2Clan _winner;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public L2Clan getWinner()
|
|
||||||
{
|
|
||||||
return _winner;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class SiegeEnd implements Runnable
|
|
||||||
{
|
|
||||||
private final L2Clan _winner;
|
|
||||||
|
|
||||||
protected SiegeEnd(L2Clan winner)
|
|
||||||
{
|
|
||||||
_winner = winner;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run()
|
|
||||||
{
|
|
||||||
if (_rainbow == null)
|
|
||||||
{
|
|
||||||
_rainbow = CHSiegeManager.getInstance().getSiegableHall(RAINBOW_SPRINGS);
|
|
||||||
}
|
|
||||||
|
|
||||||
unSpawnGourds();
|
|
||||||
|
|
||||||
if (_winner != null)
|
|
||||||
{
|
|
||||||
_rainbow.setOwner(_winner);
|
|
||||||
}
|
|
||||||
|
|
||||||
// XXX _rainbow.siegeEnds();
|
|
||||||
|
|
||||||
ThreadPoolManager.getInstance().scheduleGeneral(new SetFinalAttackers(), _rainbow.getNextSiegeTime());
|
|
||||||
setRegistrationEndString((_rainbow.getNextSiegeTime() + System.currentTimeMillis()) - 3600000);
|
|
||||||
// Teleport out of the arenas is made 2 mins after game ends
|
|
||||||
ThreadPoolManager.getInstance().scheduleGeneral(new TeleportBack(), 120000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected static class TeleportBack implements Runnable
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public void run()
|
|
||||||
{
|
|
||||||
for (int arenaId : ARENA_ZONES)
|
|
||||||
{
|
|
||||||
final Collection<L2Character> chars = ZoneManager.getInstance().getZoneById(arenaId).getCharactersInside();
|
|
||||||
for (L2Character chr : chars)
|
|
||||||
{
|
|
||||||
if (chr != null)
|
|
||||||
{
|
|
||||||
chr.teleToLocation(TeleportWhereType.TOWN);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final int RAINBOW_SPRINGS = 62;
|
|
||||||
|
|
||||||
private static final int WAR_DECREES = 8034;
|
|
||||||
private static final int RAINBOW_NECTAR = 8030;
|
|
||||||
private static final int RAINBOW_MWATER = 8031;
|
|
||||||
private static final int RAINBOW_WATER = 8032;
|
|
||||||
private static final int RAINBOW_SULFUR = 8033;
|
|
||||||
|
|
||||||
private static final int MESSENGER = 35604;
|
|
||||||
private static final int CARETAKER = 35603;
|
|
||||||
private static final int CHEST = 35593;
|
|
||||||
|
|
||||||
private static final int[] GOURDS =
|
|
||||||
{
|
|
||||||
35588,
|
|
||||||
35589,
|
|
||||||
35590,
|
|
||||||
35591
|
|
||||||
};
|
|
||||||
private static L2Spawn[] _gourds = new L2Spawn[4];
|
|
||||||
|
|
||||||
private static final int[] YETIS =
|
|
||||||
{
|
|
||||||
35596,
|
|
||||||
35597,
|
|
||||||
35598,
|
|
||||||
35599
|
|
||||||
};
|
|
||||||
|
|
||||||
private static final Location[] ARENAS = new Location[]
|
|
||||||
{
|
|
||||||
new Location(151562, -127080, -2214), // Arena 1
|
|
||||||
new Location(153141, -125335, -2214), // Arena 2
|
|
||||||
new Location(153892, -127530, -2214), // Arena 3
|
|
||||||
new Location(155657, -125752, -2214), // Arena 4
|
|
||||||
};
|
|
||||||
|
|
||||||
protected static final int[] ARENA_ZONES =
|
|
||||||
{
|
|
||||||
112081,
|
|
||||||
112082,
|
|
||||||
112083,
|
|
||||||
112084
|
|
||||||
};
|
|
||||||
|
|
||||||
private static final String[] _textPassages =
|
|
||||||
{
|
|
||||||
"Fight for Rainbow Springs!",
|
|
||||||
"Are you a match for the Yetti?",
|
|
||||||
"Did somebody order a knuckle sandwich?"
|
|
||||||
};
|
|
||||||
|
|
||||||
private static final Skill[] DEBUFFS = {};
|
|
||||||
|
|
||||||
protected static Map<Integer, Long> _warDecreesCount = new HashMap<>();
|
|
||||||
protected static List<L2Clan> _acceptedClans = new ArrayList<>(4);
|
|
||||||
private static Map<String, ArrayList<L2Clan>> _usedTextPassages = new HashMap<>();
|
|
||||||
private static Map<L2Clan, Integer> _pendingItemToGet = new HashMap<>();
|
|
||||||
|
|
||||||
protected static SiegableHall _rainbow;
|
|
||||||
protected static ScheduledFuture<?> _nextSiege, _siegeEnd;
|
|
||||||
private static String _registrationEnds;
|
|
||||||
|
|
||||||
public RainbowSpringsChateau()
|
|
||||||
{
|
|
||||||
super(RainbowSpringsChateau.class.getSimpleName(), "conquerablehalls", RAINBOW_SPRINGS);
|
|
||||||
|
|
||||||
addFirstTalkId(MESSENGER);
|
|
||||||
addTalkId(MESSENGER);
|
|
||||||
addFirstTalkId(CARETAKER);
|
|
||||||
addTalkId(CARETAKER);
|
|
||||||
addFirstTalkId(YETIS);
|
|
||||||
addTalkId(YETIS);
|
|
||||||
|
|
||||||
loadAttackers();
|
|
||||||
|
|
||||||
_rainbow = CHSiegeManager.getInstance().getSiegableHall(RAINBOW_SPRINGS);
|
|
||||||
if (_rainbow != null)
|
|
||||||
{
|
|
||||||
long delay = _rainbow.getNextSiegeTime();
|
|
||||||
if (delay > -1)
|
|
||||||
{
|
|
||||||
setRegistrationEndString(delay - 3600000);
|
|
||||||
_nextSiege = ThreadPoolManager.getInstance().scheduleGeneral(new SetFinalAttackers(), delay);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_log.warning("CHSiegeManager: No Date setted for RainBow Springs Chateau Clan hall siege!. SIEGE CANCELED!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String onFirstTalk(L2Npc npc, L2PcInstance player)
|
|
||||||
{
|
|
||||||
String html = "";
|
|
||||||
final int npcId = npc.getId();
|
|
||||||
if (npcId == MESSENGER)
|
|
||||||
{
|
|
||||||
final String main = (_rainbow.getOwnerId() > 0) ? "messenger_yetti001.htm" : "messenger_yetti001a.htm";
|
|
||||||
html = HtmCache.getInstance().getHtm(player.getHtmlPrefix(), "scripts/conquerablehalls/RainbowSpringsChateau/" + main);
|
|
||||||
html = html.replace("%time%", _registrationEnds);
|
|
||||||
if (_rainbow.getOwnerId() > 0)
|
|
||||||
{
|
|
||||||
html = html.replace("%owner%", ClanTable.getInstance().getClan(_rainbow.getOwnerId()).getName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (npcId == CARETAKER)
|
|
||||||
{
|
|
||||||
if (_rainbow.isInSiege())
|
|
||||||
{
|
|
||||||
html = "game_manager003.htm";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
html = "game_manager001.htm";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (Util.contains(YETIS, npcId))
|
|
||||||
{
|
|
||||||
// TODO: Review.
|
|
||||||
if (_rainbow.isInSiege())
|
|
||||||
{
|
|
||||||
if (!player.isClanLeader())
|
|
||||||
{
|
|
||||||
html = "no_clan_leader.htm";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
L2Clan clan = player.getClan();
|
|
||||||
if (_acceptedClans.contains(clan))
|
|
||||||
{
|
|
||||||
int index = _acceptedClans.indexOf(clan);
|
|
||||||
if (npcId == YETIS[index])
|
|
||||||
{
|
|
||||||
html = "yeti_main.htm";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
player.setLastQuestNpcObject(npc.getObjectId());
|
|
||||||
return html;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
|
||||||
{
|
|
||||||
String html = event;
|
|
||||||
final L2Clan clan = player.getClan();
|
|
||||||
switch (npc.getId())
|
|
||||||
{
|
|
||||||
case MESSENGER:
|
|
||||||
switch (event)
|
|
||||||
{
|
|
||||||
case "register":
|
|
||||||
if (!player.isClanLeader())
|
|
||||||
{
|
|
||||||
html = "messenger_yetti010.htm";
|
|
||||||
}
|
|
||||||
else if ((clan.getCastleId() > 0) || (clan.getFortId() > 0) || (clan.getHideoutId() > 0))
|
|
||||||
{
|
|
||||||
html = "messenger_yetti012.htm";
|
|
||||||
}
|
|
||||||
else if (!_rainbow.isRegistering())
|
|
||||||
{
|
|
||||||
html = "messenger_yetti014.htm";
|
|
||||||
}
|
|
||||||
else if (_warDecreesCount.containsKey(clan.getId()))
|
|
||||||
{
|
|
||||||
html = "messenger_yetti013.htm";
|
|
||||||
}
|
|
||||||
else if ((clan.getLevel() < 3) || (clan.getMembersCount() < 5))
|
|
||||||
{
|
|
||||||
html = "messenger_yetti011.htm";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
final L2ItemInstance warDecrees = player.getInventory().getItemByItemId(WAR_DECREES);
|
|
||||||
if (warDecrees == null)
|
|
||||||
{
|
|
||||||
html = "messenger_yetti008.htm";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
long count = warDecrees.getCount();
|
|
||||||
_warDecreesCount.put(clan.getId(), count);
|
|
||||||
player.destroyItem("Rainbow Springs Registration", warDecrees, npc, true);
|
|
||||||
updateAttacker(clan.getId(), count, false);
|
|
||||||
html = "messenger_yetti009.htm";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "cancel":
|
|
||||||
if (!player.isClanLeader())
|
|
||||||
{
|
|
||||||
html = "messenger_yetti010.htm";
|
|
||||||
}
|
|
||||||
else if (!_warDecreesCount.containsKey(clan.getId()))
|
|
||||||
{
|
|
||||||
html = "messenger_yetti016.htm";
|
|
||||||
}
|
|
||||||
else if (!_rainbow.isRegistering())
|
|
||||||
{
|
|
||||||
html = "messenger_yetti017.htm";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
updateAttacker(clan.getId(), 0, true);
|
|
||||||
html = "messenger_yetti018.htm";
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "unregister":
|
|
||||||
if (_rainbow.isRegistering())
|
|
||||||
{
|
|
||||||
if (_warDecreesCount.containsKey(clan.getId()))
|
|
||||||
{
|
|
||||||
player.addItem("Rainbow Spring unregister", WAR_DECREES, _warDecreesCount.get(clan.getId()) / 2, npc, true);
|
|
||||||
_warDecreesCount.remove(clan.getId());
|
|
||||||
html = "messenger_yetti019.htm";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
html = "messenger_yetti020.htm";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (_rainbow.isWaitingBattle())
|
|
||||||
{
|
|
||||||
_acceptedClans.remove(clan);
|
|
||||||
html = "messenger_yetti020.htm";
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case CARETAKER:
|
|
||||||
if (event.equals("portToArena"))
|
|
||||||
{
|
|
||||||
final L2Party party = player.getParty();
|
|
||||||
if (clan == null)
|
|
||||||
{
|
|
||||||
html = "game_manager009.htm";
|
|
||||||
}
|
|
||||||
else if (!player.isClanLeader())
|
|
||||||
{
|
|
||||||
html = "game_manager004.htm";
|
|
||||||
}
|
|
||||||
else if (!player.isInParty())
|
|
||||||
{
|
|
||||||
html = "game_manager005.htm";
|
|
||||||
}
|
|
||||||
else if (party.getLeaderObjectId() != player.getObjectId())
|
|
||||||
{
|
|
||||||
html = "game_manager006.htm";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
final int clanId = player.getClanId();
|
|
||||||
boolean nonClanMemberInParty = false;
|
|
||||||
for (L2PcInstance member : party.getMembers())
|
|
||||||
{
|
|
||||||
if (member.getClanId() != clanId)
|
|
||||||
{
|
|
||||||
nonClanMemberInParty = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nonClanMemberInParty)
|
|
||||||
{
|
|
||||||
html = "game_manager007.htm";
|
|
||||||
}
|
|
||||||
else if (party.getMemberCount() < 5)
|
|
||||||
{
|
|
||||||
html = "game_manager008.htm";
|
|
||||||
}
|
|
||||||
else if ((clan.getCastleId() > 0) || (clan.getFortId() > 0) || (clan.getHideoutId() > 0))
|
|
||||||
{
|
|
||||||
html = "game_manager010.htm";
|
|
||||||
}
|
|
||||||
else if (clan.getLevel() < Config.CHS_CLAN_MINLEVEL)
|
|
||||||
{
|
|
||||||
html = "game_manager011.htm";
|
|
||||||
}
|
|
||||||
// else if () // Something about the rules.
|
|
||||||
// {
|
|
||||||
// html = "game_manager012.htm";
|
|
||||||
// }
|
|
||||||
// else if () // Already registered.
|
|
||||||
// {
|
|
||||||
// html = "game_manager013.htm";
|
|
||||||
// }
|
|
||||||
else if (!_acceptedClans.contains(clan))
|
|
||||||
{
|
|
||||||
html = "game_manager014.htm";
|
|
||||||
}
|
|
||||||
// else if () // Not have enough cards to register.
|
|
||||||
// {
|
|
||||||
// html = "game_manager015.htm";
|
|
||||||
// }
|
|
||||||
else
|
|
||||||
{
|
|
||||||
portToArena(player, _acceptedClans.indexOf(clan));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (event.startsWith("enterText"))
|
|
||||||
{
|
|
||||||
// Shouldn't happen
|
|
||||||
if (!_acceptedClans.contains(clan))
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
String[] split = event.split("_ ");
|
|
||||||
if (split.length < 2)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
final String passage = split[1];
|
|
||||||
|
|
||||||
if (!isValidPassage(passage))
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_usedTextPassages.containsKey(passage))
|
|
||||||
{
|
|
||||||
ArrayList<L2Clan> list = _usedTextPassages.get(passage);
|
|
||||||
|
|
||||||
if (list.contains(clan))
|
|
||||||
{
|
|
||||||
html = "yeti_passage_used.htm";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
list.add(clan);
|
|
||||||
synchronized (_pendingItemToGet)
|
|
||||||
{
|
|
||||||
if (_pendingItemToGet.containsKey(clan))
|
|
||||||
{
|
|
||||||
int left = _pendingItemToGet.get(clan);
|
|
||||||
++left;
|
|
||||||
_pendingItemToGet.put(clan, left);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_pendingItemToGet.put(clan, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
html = "yeti_item_exchange.htm";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (event.startsWith("getItem"))
|
|
||||||
{
|
|
||||||
if (!_pendingItemToGet.containsKey(clan))
|
|
||||||
{
|
|
||||||
html = "yeti_cannot_exchange.htm";
|
|
||||||
}
|
|
||||||
|
|
||||||
int left = _pendingItemToGet.get(clan);
|
|
||||||
if (left > 0)
|
|
||||||
{
|
|
||||||
int itemId = Integer.parseInt(event.split("_")[1]);
|
|
||||||
player.addItem("Rainbow Spring Chateau Siege", itemId, 1, npc, true);
|
|
||||||
--left;
|
|
||||||
_pendingItemToGet.put(clan, left);
|
|
||||||
html = "yeti_main.htm";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
html = "yeti_cannot_exchange.htm";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return html;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
|
|
||||||
{
|
|
||||||
if (!_rainbow.isInSiege())
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
final L2Clan clan = killer.getClan();
|
|
||||||
if ((clan == null) || !_acceptedClans.contains(clan))
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
final int npcId = npc.getId();
|
|
||||||
final int index = _acceptedClans.indexOf(clan);
|
|
||||||
|
|
||||||
if (npcId == CHEST)
|
|
||||||
{
|
|
||||||
shoutRandomText(npc);
|
|
||||||
}
|
|
||||||
else if (npcId == GOURDS[index])
|
|
||||||
{
|
|
||||||
synchronized (this)
|
|
||||||
{
|
|
||||||
if (_siegeEnd != null)
|
|
||||||
{
|
|
||||||
_siegeEnd.cancel(false);
|
|
||||||
}
|
|
||||||
ThreadPoolManager.getInstance().executeGeneral(new SiegeEnd(clan));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String onItemUse(L2Item item, L2PcInstance player)
|
|
||||||
{
|
|
||||||
if (!_rainbow.isInSiege())
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
L2Object target = player.getTarget();
|
|
||||||
|
|
||||||
if ((target == null) || !(target instanceof L2Npc))
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
int yeti = target.getId();
|
|
||||||
if (!isYetiTarget(yeti))
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
final L2Clan clan = player.getClan();
|
|
||||||
if ((clan == null) || !_acceptedClans.contains(clan))
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Nectar must spawn the enraged yeti. Dunno if it makes any other thing
|
|
||||||
// Also, the items must execute:
|
|
||||||
// - Reduce gourd hpb ( reduceGourdHp(int, L2PcInstance) )
|
|
||||||
// - Cast debuffs on enemy clans ( castDebuffsOnEnemies(int) )
|
|
||||||
// - Change arena gourds ( moveGourds() )
|
|
||||||
// - Increase gourd hp ( increaseGourdHp(int) )
|
|
||||||
|
|
||||||
final int itemId = item.getId();
|
|
||||||
if (itemId == RAINBOW_NECTAR)
|
|
||||||
{
|
|
||||||
// Spawn enraged (where?)
|
|
||||||
reduceGourdHp(_acceptedClans.indexOf(clan), player);
|
|
||||||
}
|
|
||||||
else if (itemId == RAINBOW_MWATER)
|
|
||||||
{
|
|
||||||
increaseGourdHp(_acceptedClans.indexOf(clan));
|
|
||||||
}
|
|
||||||
else if (itemId == RAINBOW_WATER)
|
|
||||||
{
|
|
||||||
moveGourds();
|
|
||||||
}
|
|
||||||
else if (itemId == RAINBOW_SULFUR)
|
|
||||||
{
|
|
||||||
castDebuffsOnEnemies(_acceptedClans.indexOf(clan));
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void portToArena(L2PcInstance leader, int arena)
|
|
||||||
{
|
|
||||||
if ((arena < 0) || (arena > 3))
|
|
||||||
{
|
|
||||||
_log.warning("RainbowSptringChateau siege: Wrong arena id passed: " + arena);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
for (L2PcInstance pc : leader.getParty().getMembers())
|
|
||||||
{
|
|
||||||
if (pc != null)
|
|
||||||
{
|
|
||||||
pc.stopAllEffects();
|
|
||||||
final L2Summon pet = pc.getPet();
|
|
||||||
if (pet != null)
|
|
||||||
{
|
|
||||||
pet.unSummon(pc);
|
|
||||||
}
|
|
||||||
pc.getServitors().values().forEach(s ->
|
|
||||||
{
|
|
||||||
s.unSummon(pc);
|
|
||||||
});
|
|
||||||
pc.teleToLocation(ARENAS[arena]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected static void spawnGourds()
|
|
||||||
{
|
|
||||||
for (int i = 0; i < _acceptedClans.size(); i++)
|
|
||||||
{
|
|
||||||
if (_gourds[i] == null)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
_gourds[i] = new L2Spawn(GOURDS[i]);
|
|
||||||
_gourds[i].setX(ARENAS[i].getX() + 150);
|
|
||||||
_gourds[i].setY(ARENAS[i].getY() + 150);
|
|
||||||
_gourds[i].setZ(ARENAS[i].getZ());
|
|
||||||
_gourds[i].setHeading(1);
|
|
||||||
_gourds[i].setAmount(1);
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
SpawnTable.getInstance().addNewSpawn(_gourds[i], false);
|
|
||||||
_gourds[i].init();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected static void unSpawnGourds()
|
|
||||||
{
|
|
||||||
for (int i = 0; i < _acceptedClans.size(); i++)
|
|
||||||
{
|
|
||||||
_gourds[i].getLastSpawn().deleteMe();
|
|
||||||
SpawnTable.getInstance().deleteSpawn(_gourds[i], false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void moveGourds()
|
|
||||||
{
|
|
||||||
L2Spawn[] tempArray = _gourds;
|
|
||||||
int iterator = _acceptedClans.size();
|
|
||||||
for (int i = 0; i < iterator; i++)
|
|
||||||
{
|
|
||||||
L2Spawn oldSpawn = _gourds[(iterator - 1) - i];
|
|
||||||
L2Spawn curSpawn = tempArray[i];
|
|
||||||
|
|
||||||
_gourds[(iterator - 1) - i] = curSpawn;
|
|
||||||
|
|
||||||
curSpawn.getLastSpawn().teleToLocation(oldSpawn.getLocation());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void reduceGourdHp(int index, L2PcInstance player)
|
|
||||||
{
|
|
||||||
L2Spawn gourd = _gourds[index];
|
|
||||||
gourd.getLastSpawn().reduceCurrentHp(1000, player, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void increaseGourdHp(int index)
|
|
||||||
{
|
|
||||||
L2Spawn gourd = _gourds[index];
|
|
||||||
L2Npc gourdNpc = gourd.getLastSpawn();
|
|
||||||
gourdNpc.setCurrentHp(gourdNpc.getCurrentHp() + 1000);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void castDebuffsOnEnemies(int myArena)
|
|
||||||
{
|
|
||||||
for (int id : ARENA_ZONES)
|
|
||||||
{
|
|
||||||
if (id == myArena)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
final Collection<L2Character> chars = ZoneManager.getInstance().getZoneById(id).getCharactersInside();
|
|
||||||
for (L2Character chr : chars)
|
|
||||||
{
|
|
||||||
if (chr != null)
|
|
||||||
{
|
|
||||||
for (Skill sk : DEBUFFS)
|
|
||||||
{
|
|
||||||
sk.applyEffects(chr, chr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void shoutRandomText(L2Npc npc)
|
|
||||||
{
|
|
||||||
int length = _textPassages.length;
|
|
||||||
|
|
||||||
if (_usedTextPassages.size() >= length)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
int randomPos = getRandom(length);
|
|
||||||
String message = _textPassages[randomPos];
|
|
||||||
|
|
||||||
if (_usedTextPassages.containsKey(message))
|
|
||||||
{
|
|
||||||
shoutRandomText(npc);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_usedTextPassages.put(message, new ArrayList<L2Clan>());
|
|
||||||
final NpcSay say = new NpcSay(npc.getObjectId(), ChatType.NPC_SHOUT, npc.getId(), message);
|
|
||||||
npc.broadcastPacket(say);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean isValidPassage(String text)
|
|
||||||
{
|
|
||||||
for (String st : _textPassages)
|
|
||||||
{
|
|
||||||
if (st.equalsIgnoreCase(text))
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean isYetiTarget(int npcId)
|
|
||||||
{
|
|
||||||
for (int yeti : YETIS)
|
|
||||||
{
|
|
||||||
if (yeti == npcId)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void updateAttacker(int clanId, long count, boolean remove)
|
|
||||||
{
|
|
||||||
try (Connection con = L2DatabaseFactory.getInstance().getConnection())
|
|
||||||
{
|
|
||||||
PreparedStatement statement;
|
|
||||||
if (remove)
|
|
||||||
{
|
|
||||||
statement = con.prepareStatement("DELETE FROM rainbowsprings_attacker_list WHERE clanId = ?");
|
|
||||||
statement.setInt(1, clanId);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
statement = con.prepareStatement("INSERT INTO rainbowsprings_attacker_list VALUES (?,?)");
|
|
||||||
statement.setInt(1, clanId);
|
|
||||||
statement.setLong(2, count);
|
|
||||||
}
|
|
||||||
statement.execute();
|
|
||||||
statement.close();
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void loadAttackers()
|
|
||||||
{
|
|
||||||
try (Connection con = L2DatabaseFactory.getInstance().getConnection())
|
|
||||||
{
|
|
||||||
PreparedStatement statement = con.prepareStatement("SELECT * FROM rainbowsprings_attacker_list");
|
|
||||||
ResultSet rset = statement.executeQuery();
|
|
||||||
while (rset.next())
|
|
||||||
{
|
|
||||||
int clanId = rset.getInt("clan_id");
|
|
||||||
long count = rset.getLong("decrees_count");
|
|
||||||
_warDecreesCount.put(clanId, count);
|
|
||||||
}
|
|
||||||
rset.close();
|
|
||||||
statement.close();
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected static void setRegistrationEndString(long time)
|
|
||||||
{
|
|
||||||
Calendar c = Calendar.getInstance();
|
|
||||||
c.setTime(new Date(time));
|
|
||||||
int year = c.get(Calendar.YEAR);
|
|
||||||
int month = c.get(Calendar.MONTH) + 1;
|
|
||||||
int day = c.get(Calendar.DAY_OF_MONTH);
|
|
||||||
int hour = c.get(Calendar.HOUR);
|
|
||||||
int mins = c.get(Calendar.MINUTE);
|
|
||||||
|
|
||||||
_registrationEnds = year + "-" + month + "-" + day + " " + hour + (mins < 10 ? ":0" : ":") + mins;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void launchSiege()
|
|
||||||
{
|
|
||||||
_nextSiege.cancel(false);
|
|
||||||
ThreadPoolManager.getInstance().executeGeneral(new SiegeStart());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void endSiege()
|
|
||||||
{
|
|
||||||
if (_siegeEnd != null)
|
|
||||||
{
|
|
||||||
_siegeEnd.cancel(false);
|
|
||||||
}
|
|
||||||
ThreadPoolManager.getInstance().executeGeneral(new SiegeEnd(null));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void updateAdminDate(long date)
|
|
||||||
{
|
|
||||||
if (_rainbow == null)
|
|
||||||
{
|
|
||||||
_rainbow = CHSiegeManager.getInstance().getSiegableHall(RAINBOW_SPRINGS);
|
|
||||||
}
|
|
||||||
|
|
||||||
_rainbow.setNextSiegeDate(date);
|
|
||||||
if (_nextSiege != null)
|
|
||||||
{
|
|
||||||
_nextSiege.cancel(true);
|
|
||||||
}
|
|
||||||
date -= 3600000;
|
|
||||||
setRegistrationEndString(date);
|
|
||||||
_nextSiege = ThreadPoolManager.getInstance().scheduleGeneral(new SetFinalAttackers(), _rainbow.getNextSiegeTime());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void main(String[] args)
|
|
||||||
{
|
|
||||||
new RainbowSpringsChateau();
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,4 +0,0 @@
|
|||||||
<html><body>Caretaker:<br>
|
|
||||||
Is everyone ready? Well, let's get moving! Whoever's late doesn't deserve to enjoy the game!<br>
|
|
||||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest RainbowSpringsChateau portToArena">Enter the arena.</Button>
|
|
||||||
</body></html>
|
|
@@ -1,7 +0,0 @@
|
|||||||
<html><body>Caretaker:<br>
|
|
||||||
You must follow the rules to play the game. Entry denied!<br>
|
|
||||||
(1) Are there more than 5 in the party?<br>
|
|
||||||
(2) Is the applicant the Clan Leader?<br>
|
|
||||||
(3) Does the party include non-clan members?<br>
|
|
||||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest RainbowSpringsChateau portToArena">Try to enter again.</Button>
|
|
||||||
</body></html>
|
|
@@ -1,3 +0,0 @@
|
|||||||
<html><body>Caretaker:<br>
|
|
||||||
The arena is closed at this time. Have you applied to participate in the game?
|
|
||||||
</body></html>
|
|
@@ -1,7 +0,0 @@
|
|||||||
<html><body>Caretaker:<br>
|
|
||||||
You must abide by the rules in order to participate in the game.<br>
|
|
||||||
Requirements for Participation: <font color="LEVEL">A party of more than five clan members with a Clan Leader.</font><br><br>
|
|
||||||
The Clan Leader must be the one to apply for entry to the game.<br>
|
|
||||||
Entry denied!<br>
|
|
||||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest RainbowSpringsChateau portToArena">Try to enter again.</Button>
|
|
||||||
</body></html>
|
|
@@ -1,7 +0,0 @@
|
|||||||
<html><body>Caretaker:<br>
|
|
||||||
You must abide by the following rules in order to participate in the game.<br>
|
|
||||||
Rules of Participation: <font color="LEVEL">A party of more than five clan members with a Clan Leader.</font><br><br>
|
|
||||||
You need more members in your party.<br>
|
|
||||||
Entry denied!<br><br>
|
|
||||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest RainbowSpringsChateau portToArena">Try to enter again.</Button>
|
|
||||||
</body></html>
|
|
@@ -1,7 +0,0 @@
|
|||||||
<html><body>Caretaker:<br>
|
|
||||||
You must abide by the following rules in order to participate in the game.<br>
|
|
||||||
Rules of Participation: <font color="LEVEL">A party of more than five clan members with a Clan Leader.</font><br><br>
|
|
||||||
Your Clan Leader must apply as the party leader.<br>
|
|
||||||
Entry denied!<br>
|
|
||||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest RainbowSpringsChateau portToArena">Try to enter again.</Button>
|
|
||||||
</body></html>
|
|
@@ -1,7 +0,0 @@
|
|||||||
<html><body>Caretaker:<br>
|
|
||||||
You must abide by the rules in order to participate in the game.<br>
|
|
||||||
Rules of Participation: <font color="LEVEL">A party of more than five clan members with a Clan Leader.</font><br>
|
|
||||||
Entry denied!<br>
|
|
||||||
You have a non-clan member in your midst.<br><br>
|
|
||||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest RainbowSpringsChateau portToArena">Try to enter again.</Button>
|
|
||||||
</body></html>
|
|
@@ -1,7 +0,0 @@
|
|||||||
<html><body>Caretaker:<br>
|
|
||||||
You must abide by the following rules in order to participate in the game.<br>
|
|
||||||
Rules of Participation: <font color="LEVEL">A party of more than five clan members with a Clan Leader.</font>
|
|
||||||
Entry denied!<br><br>
|
|
||||||
You need at least five people in order to play the game... Why don't you contact some friends?<br>
|
|
||||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest RainbowSpringsChateau portToArena">Try to enter again.</Button>
|
|
||||||
</body></html>
|
|
@@ -1,7 +0,0 @@
|
|||||||
<html><body>Caretaker:<br>
|
|
||||||
You must abide by the following rules in order to participate in the game.<br>
|
|
||||||
Rules of Participation: <font color="LEVEL">A party of more than five clan members with a Clan Leader.</font><br>
|
|
||||||
Entry denied!<br>
|
|
||||||
You're not a member of a clan.<br><br>
|
|
||||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest RainbowSpringsChateau portToArena">Try to enter again.</Button>
|
|
||||||
</body></html>
|
|
@@ -1,7 +0,0 @@
|
|||||||
<html><body>Caretaker:<br>
|
|
||||||
You must abide by the following rules in order to participate in the game.<br>
|
|
||||||
Rules of Participation: <font color="LEVEL">A party of more than five clan members with a Clan Leader.</font><br>
|
|
||||||
Entry denied!<br>
|
|
||||||
You're an ambitious one! One may own only one Clan Hall!<br>
|
|
||||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest RainbowSpringsChateau portToArena">Try to enter again.</Button>
|
|
||||||
</body></html>
|
|
@@ -1,7 +0,0 @@
|
|||||||
<html><body>Caretaker:<br>
|
|
||||||
You must abide by the rules in order to participate in the game.<br>
|
|
||||||
Rules of Participation: <font color="LEVEL">A party of more than five clan members with a Clan Leader.</font><br><br>
|
|
||||||
You must be a Clan Leader above Clan level 3 in order to apply.<br>
|
|
||||||
Entry denied!<br>
|
|
||||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest RainbowSpringsChateau portToArena">Try to enter again.</Button>
|
|
||||||
</body></html>
|
|
@@ -1,7 +0,0 @@
|
|||||||
<html><body>Caretaker:<br>
|
|
||||||
You must abide by the following rules in order to participate in the game.<br>
|
|
||||||
Rules of Participation: <font color="LEVEL">A party of more than five clan members with a Clan Leader.</font><br>
|
|
||||||
Entry denied!<br>
|
|
||||||
Read the rules again.<br><br>
|
|
||||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest RainbowSpringsChateau portToArena">Try to enter again.</Button>
|
|
||||||
</body></html>
|
|
@@ -1,7 +0,0 @@
|
|||||||
<html><body>Caretaker:<br>
|
|
||||||
You must abide by the following rules in order to participate in the game. It appears that you don't meet the requirements.<br>
|
|
||||||
Rules of Participation: <font color="LEVEL">A party of more than five clan members with a Clan Leader.</font><br>
|
|
||||||
Entry denied!<br>
|
|
||||||
Let's see... You're already registered.<br>
|
|
||||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest RainbowSpringsChateau portToArena">Try to enter again.</Button>
|
|
||||||
</body></html>
|
|
@@ -1,6 +0,0 @@
|
|||||||
<html><body>Caretaker:<br>
|
|
||||||
To participate in the game, you must abide by the rules. I'm afraid that I must deny your entry because you do not meet the following requirement:<br>
|
|
||||||
Participation - <font color="LEVEL">You must have a party of at least 5 clan members with a clan leader as the leader of the party.</font><br><br>
|
|
||||||
Have you registered for the game?<br><br>
|
|
||||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest RainbowSpringsChateau portToArena">Attempt re-entry.</Button>
|
|
||||||
</body></html>
|
|
@@ -1,6 +0,0 @@
|
|||||||
<html><body>Entrance Manager:<br>
|
|
||||||
To participate in the game, you must abide by the rules. I'm afraid that I must deny your entry because you do not meet the following requirement:<br>
|
|
||||||
Participation - <font color="LEVEL">You must have a party of at least 5 clan members with a clan leader as the leader of the party.</font><br><br>
|
|
||||||
I'm sorry, but your name seems to have been removed from the participants' list. Apparently you didn't have enough cards to register.<br><br>
|
|
||||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest RainbowSpringsChateau portToArena">Attempt re-entry.</Button>
|
|
||||||
</body></html>
|
|
@@ -1,9 +0,0 @@
|
|||||||
<html><body>Messenger Yetti:<br>
|
|
||||||
Pettite~ the transparent and energetic building behind me is <font color="LEVEL">Rainbow Spring</font>. Not my type, but very high class nonetheless. It's a place so nice, it's simply overlooked by ignorant adventurers. The winner gets ultimate bragging rights.<br>
|
|
||||||
The last winner was <font color="LEVEL">%owner%</font>, challenge him if you think you can defeat a clan!<br><br>
|
|
||||||
Registration finished at: <font color="LEVEL">%time%</font><br><br>
|
|
||||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest RainbowSpringsChateau messenger_yetti002.htm">Hideout battle game instruction</Button>
|
|
||||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest RainbowSpringsChateau register">Hideout battle game registration</Button>
|
|
||||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest RainbowSpringsChateau messenger_yetti015.htm">Cancel registration</Button>
|
|
||||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest RainbowSpringsChateau messenger_yetti018.htm">Get a refund during game</Button>
|
|
||||||
</body></html>
|
|
@@ -1,8 +0,0 @@
|
|||||||
<html><body>Messenger Yetti:<br>
|
|
||||||
Pettite~ the transparent and lively building behind me is called <font color="LEVEL">Rainbow Spring</font>. It's not your ordinary hideout. You won't see a horde of peasants spilling blood for it. This one is special. Very high class...<br>
|
|
||||||
Registration finished at: <font color="LEVEL">%time%</font><br><br>
|
|
||||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest RainbowSpringsChateau messenger_yetti002.htm">Hideout battle game instruction</Button>
|
|
||||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest RainbowSpringsChateau register">Hideout battle game registration</Button>
|
|
||||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest RainbowSpringsChateau messenger_yetti015.htm">Cancel registration</Button>
|
|
||||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest RainbowSpringsChateau messenger_yetti018.htm">Get a refund during game</Button>
|
|
||||||
</body></html>
|
|
@@ -1,5 +0,0 @@
|
|||||||
<html><body>Messenger Yeti:<br>
|
|
||||||
To register for a Clan Hall War, you must first go fishing in Goddard Territory and obtain Clan Hall War Decrees. They compare the number of decrees submitted and select the four finalists one hour before the game starts. Those selected determine the owner of the Clan Hall by playing the game.<br>
|
|
||||||
Submit as many decrees as possible! There's only one opportunity for registration!<br>
|
|
||||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest RainbowSpringsChateau messenger_yetti003.htm">"How do I play the game?"</Button>
|
|
||||||
</body></html>
|
|
@@ -1,6 +0,0 @@
|
|||||||
<html><body>Messenger Yeti:<br>
|
|
||||||
Have you ever played a high stakes event? If so, you'll understand quickly. Once you enter the arena, my good friend, the Game Coordinator, will provide instructions on how the game is played. He will then call out some words, which you must spell by breaking the treasure boxes in the four circles. Combine the letters you find into words, and take them to the Coordinator! You will then get an item for use in the game!<br>
|
|
||||||
You can use this item against the Coordinator, depending on the situation. You may hit a jackpot or impede others, or sometimes my jerk friend...ehh... Well, you'll find out soon enough.<br>
|
|
||||||
Oh, I almost forgot the most important thing! The only way to open the Treasure Boxes is by hitting them with your <font color="LEVEL">bare hands</font>. Don't forget!<br>
|
|
||||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest RainbowSpringsChateau messenger_yetti004.htm">"How many people can participate in the game?"</Button>
|
|
||||||
</body></html>
|
|
@@ -1,4 +0,0 @@
|
|||||||
<html><body>Messenger Yeti:<br>
|
|
||||||
It's not a game where you fight, but a game played for fun, so only like-minded people are allowed to participate. You need a fair amount of people... If you have more than five, it will work.<br>
|
|
||||||
(You can participate if your party is composed of more than five members and your Clan level is 3 or above.)
|
|
||||||
</body></html>
|
|
@@ -1,3 +0,0 @@
|
|||||||
<html><body>Messenger Yeti:<br>
|
|
||||||
It would be fun to play together... Grarr... Too bad.
|
|
||||||
</body></html>
|
|
@@ -1,3 +0,0 @@
|
|||||||
<html><body>Messenger Yeti:<br>
|
|
||||||
Grarr! I am sorry but there is a requirement to participate in the game. In order to apply, you must have Rainbow Springs Clan Hall War Decrees, and you can submit these only once. Players are ranked depending on the number of decrees submitted, so gather as many of them as you can.
|
|
||||||
</body></html>
|
|
@@ -1,3 +0,0 @@
|
|||||||
<html><body>Messenger Yeti:<br>
|
|
||||||
Your application was received. We plan to make an announcement one hour before the game starts as to whether you were successfully registered or not. Don't forget to check back.
|
|
||||||
</body></html>
|
|
@@ -1,3 +0,0 @@
|
|||||||
<html><body>Messenger Yeti:<br>
|
|
||||||
The Clan Leader has to come here himself in order to apply to participate in the game, or to cancel it.
|
|
||||||
</body></html>
|
|
@@ -1,4 +0,0 @@
|
|||||||
<html><body>Messenger Yeti:<br>
|
|
||||||
You need many people to have a fun game. You need leaders and also players...<br>
|
|
||||||
(You must be a Clan Leader of a Clan composed of more than five members and be above Clan level 3 in order to apply.)
|
|
||||||
</body></html>
|
|
@@ -1,3 +0,0 @@
|
|||||||
<html><body>Messenger Yeti:<br>
|
|
||||||
You already own a Clan Hall. You're greedy! You not allowed to participate in the game!
|
|
||||||
</body></html>
|
|
@@ -1,3 +0,0 @@
|
|||||||
<html><body>Messenger Yeti:<br>
|
|
||||||
You're already registered. You can register only once per game! Grarr!
|
|
||||||
</body></html>
|
|
@@ -1,3 +0,0 @@
|
|||||||
<html><body>Messenger Yeti:<br>
|
|
||||||
Registration for the Clan Hall war game is finished, please try the next game. To participate in a game, you must apply one hour before the game starts.
|
|
||||||
</body></html>
|
|
@@ -1,4 +0,0 @@
|
|||||||
<html><body>Messenger Yeti:<br>
|
|
||||||
Do you absolutely have to cancel? If you cancel your registration now, we can only return half the decrees you submitted to us.<br>
|
|
||||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest RainbowSpringsChateau cancel">Cancel</Button>
|
|
||||||
</body></html>
|
|
@@ -1,3 +0,0 @@
|
|||||||
<html><body>Messenger Yeti:<br>
|
|
||||||
Grarr! I can't find your name on the applicant list.
|
|
||||||
</body></html>
|
|
@@ -1,3 +0,0 @@
|
|||||||
<html><body>Messenger Yeti:<br>
|
|
||||||
Check back one hour before the game starts when the participating teams are selected in case of a cancellation.
|
|
||||||
</body></html>
|
|
@@ -1,4 +0,0 @@
|
|||||||
<html><body>Messenger Yetti:<br>
|
|
||||||
The game is cancelled? Okay, so you get all the applications back.<br>
|
|
||||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest RainbowSpringsChateau unregister">Receive it back</Button>
|
|
||||||
</body></html>
|
|
@@ -1,3 +0,0 @@
|
|||||||
<html><body>Messenger Yetti:<br>
|
|
||||||
Pettite~ here is your application!
|
|
||||||
</body></html>
|
|
@@ -1,3 +0,0 @@
|
|||||||
<html><body>Messenger Yetti:<br>
|
|
||||||
The returning application function is how you give back an application to a participant when the game is cancelled.
|
|
||||||
</body></html>
|
|
@@ -1,3 +0,0 @@
|
|||||||
<html><body>
|
|
||||||
I'm only authorized to talk with the clan leader.
|
|
||||||
</body></html>
|
|
@@ -1,3 +0,0 @@
|
|||||||
<html><body>Yeti:<br>
|
|
||||||
I cannot exchange any item with you!
|
|
||||||
</body></html>
|
|
@@ -1,3 +0,0 @@
|
|||||||
<html><body>
|
|
||||||
No data for this html.
|
|
||||||
</body></html>
|
|
@@ -1,5 +0,0 @@
|
|||||||
<html><body>
|
|
||||||
No data for this html<br>
|
|
||||||
<edit var="passage" width = 60><br1>
|
|
||||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest RainbowSpringsChateau enterText_ $passage">Register for Siege</Button>
|
|
||||||
</body></html>
|
|
@@ -1,3 +0,0 @@
|
|||||||
<html><body>
|
|
||||||
That passage have been already used for your clan.
|
|
||||||
</body></html>
|
|
@@ -1,153 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2004-2015 L2J DataPack
|
|
||||||
*
|
|
||||||
* This file is part of L2J DataPack.
|
|
||||||
*
|
|
||||||
* L2J DataPack 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.
|
|
||||||
*
|
|
||||||
* L2J DataPack 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 conquerablehalls.flagwar.BanditStronghold;
|
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
|
|
||||||
import com.l2jserver.gameserver.instancemanager.ZoneManager;
|
|
||||||
import com.l2jserver.gameserver.model.Location;
|
|
||||||
import com.l2jserver.gameserver.model.zone.type.L2ResidenceHallTeleportZone;
|
|
||||||
|
|
||||||
import conquerablehalls.flagwar.FlagWar;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author BiggBoss
|
|
||||||
*/
|
|
||||||
public final class BanditStronghold extends FlagWar
|
|
||||||
{
|
|
||||||
static
|
|
||||||
{
|
|
||||||
ROYAL_FLAG = 35422;
|
|
||||||
FLAG_RED = 35423;
|
|
||||||
FLAG_YELLOW = 35424;
|
|
||||||
FLAG_GREEN = 35425;
|
|
||||||
FLAG_BLUE = 35426;
|
|
||||||
FLAG_PURPLE = 35427;
|
|
||||||
|
|
||||||
ALLY_1 = 35428;
|
|
||||||
ALLY_2 = 35429;
|
|
||||||
ALLY_3 = 35430;
|
|
||||||
ALLY_4 = 35431;
|
|
||||||
ALLY_5 = 35432;
|
|
||||||
|
|
||||||
TELEPORT_1 = 35560;
|
|
||||||
|
|
||||||
MESSENGER = 35437;
|
|
||||||
|
|
||||||
OUTTER_DOORS_TO_OPEN[0] = 22170001;
|
|
||||||
OUTTER_DOORS_TO_OPEN[1] = 22170002;
|
|
||||||
|
|
||||||
INNER_DOORS_TO_OPEN[0] = 22170003;
|
|
||||||
INNER_DOORS_TO_OPEN[1] = 22170004;
|
|
||||||
|
|
||||||
FLAG_COORDS[0] = new Location(83699, -17468, -1774, 19048);
|
|
||||||
FLAG_COORDS[1] = new Location(82053, -17060, -1784, 5432);
|
|
||||||
FLAG_COORDS[2] = new Location(82142, -15528, -1799, 58792);
|
|
||||||
FLAG_COORDS[3] = new Location(83544, -15266, -1770, 44976);
|
|
||||||
FLAG_COORDS[4] = new Location(84609, -16041, -1769, 35816);
|
|
||||||
FLAG_COORDS[5] = new Location(81981, -15708, -1858, 60392);
|
|
||||||
FLAG_COORDS[6] = new Location(84375, -17060, -1860, 27712);
|
|
||||||
|
|
||||||
Collection<L2ResidenceHallTeleportZone> zoneList = ZoneManager.getInstance().getAllZones(L2ResidenceHallTeleportZone.class);
|
|
||||||
|
|
||||||
for (L2ResidenceHallTeleportZone teleZone : zoneList)
|
|
||||||
{
|
|
||||||
if (teleZone.getResidenceId() != BANDIT_STRONGHOLD)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
int id = teleZone.getResidenceZoneId();
|
|
||||||
|
|
||||||
if ((id < 0) || (id >= 6))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
TELE_ZONES[id] = teleZone;
|
|
||||||
}
|
|
||||||
|
|
||||||
QUEST_REWARD = 5009;
|
|
||||||
CENTER = new Location(82882, -16280, -1894, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
private BanditStronghold()
|
|
||||||
{
|
|
||||||
super(BanditStronghold.class.getSimpleName(), BANDIT_STRONGHOLD);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getFlagHtml(int flag)
|
|
||||||
{
|
|
||||||
String result = null;
|
|
||||||
|
|
||||||
switch (flag)
|
|
||||||
{
|
|
||||||
case 35423:
|
|
||||||
result = "messenger_flag1.htm";
|
|
||||||
break;
|
|
||||||
case 35424:
|
|
||||||
result = "messenger_flag2.htm";
|
|
||||||
break;
|
|
||||||
case 35425:
|
|
||||||
result = "messenger_flag3.htm";
|
|
||||||
break;
|
|
||||||
case 35426:
|
|
||||||
result = "messenger_flag4.htm";
|
|
||||||
break;
|
|
||||||
case 35427:
|
|
||||||
result = "messenger_flag5.htm";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getAllyHtml(int ally)
|
|
||||||
{
|
|
||||||
String result = null;
|
|
||||||
|
|
||||||
switch (ally)
|
|
||||||
{
|
|
||||||
case 35428:
|
|
||||||
result = "messenger_ally1result.htm";
|
|
||||||
break;
|
|
||||||
case 35429:
|
|
||||||
result = "messenger_ally2result.htm";
|
|
||||||
break;
|
|
||||||
case 35430:
|
|
||||||
result = "messenger_ally3result.htm";
|
|
||||||
break;
|
|
||||||
case 35431:
|
|
||||||
result = "messenger_ally4result.htm";
|
|
||||||
break;
|
|
||||||
case 35432:
|
|
||||||
result = "messenger_ally5result.htm";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void main(String[] args)
|
|
||||||
{
|
|
||||||
new BanditStronghold();
|
|
||||||
}
|
|
||||||
}
|
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user