[Classic] Addition/Removal of NPC XMLs.

This commit is contained in:
MobiusDev
2015-05-02 16:41:56 +00:00
parent 739a4cf6cb
commit e6a5cf87a1
405 changed files with 7707 additions and 416803 deletions

View File

@@ -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>
</tr></table><br>
<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 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>

View File

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

View File

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

View File

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

View File

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

View File

@@ -11,7 +11,6 @@ handlers/MasterHandler.java
# AI Section
# Npc
ai/npc/AdventurersGuide/AdventurersGuide.java
ai/npc/Alexandria/Alexandria.java
ai/npc/ArenaManager/ArenaManager.java
ai/npc/AvantGarde/AvantGarde.java
@@ -27,18 +26,13 @@ ai/npc/CastleTeleporter/CastleTeleporter.java
ai/npc/CastleWarehouse/CastleWarehouse.java
ai/npc/ClanTrader/ClanTrader.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/FortressSiegeManager/FortressSiegeManager.java
ai/npc/KetraOrcSupport/KetraOrcSupport.java
ai/npc/Mammons/Mammons.java
ai/npc/ManorManager/ManorManager.java
ai/npc/Minigame/Minigame.java
ai/npc/MonumentOfHeroes/MonumentOfHeroes.java
ai/npc/NpcBuffers/NpcBuffers.java
ai/npc/Rignos/Rignos.java
ai/npc/Rafforty/Rafforty.java
ai/npc/RemembranceTower/RemembranceTower.java
ai/npc/Summons/MerchantGolem/GolemTrader.java
@@ -57,47 +51,26 @@ ai/npc/VillageMasters/FirstClassTransferTalk/FirstClassTransferTalk.java
ai/npc/WyvernManager/WyvernManager.java
# Group Template
ai/group_template/BeastFarm.java
ai/group_template/DenOfEvil.java
ai/group_template/FairyTrees.java
ai/group_template/FeedableBeasts.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/MonasteryOfSilence.java
ai/group_template/NonLethalableNpcs.java
ai/group_template/PaganTemple.java
ai/group_template/PavelArchaic.java
ai/group_template/PlainsOfDion.java
ai/group_template/PlainsOfLizardman.java
ai/group_template/PolymorphingAngel.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/StakatoNest.java
ai/group_template/SummonPc.java
ai/group_template/TurekOrcs.java
ai/group_template/WarriorFishingBlock.java
# Individual
ai/individual/CrimsonHatuOtis.java
ai/individual/DarkWaterDragon.java
ai/individual/DivineBeast.java
ai/individual/DrChaos.java
ai/individual/EvasGiftBox.java
ai/individual/FrightenedRagnaOrc.java
ai/individual/GraveRobbers.java
ai/individual/Orfen.java
ai/individual/QueenAnt.java
ai/individual/RagnaOrcCommander.java
ai/individual/RagnaOrcSeer.java
ai/individual/RagnaOrcHero.java
ai/individual/SinEater.java
ai/individual/SinWardens.java
# Village Master
village_master/Clan/Clan.java
@@ -131,20 +104,5 @@ vehicles/BoatInnadrilTour.java
vehicles/BoatGludinRune.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/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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,3 +0,0 @@
<html><body>
Characters who are Lv. 91 or above cannot receive Newbie Buffs.
</body></html>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,3 +0,0 @@
<html><body>Messenger Yeti:<br>
It would be fun to play together... Grarr... Too bad.
</body></html>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,3 +0,0 @@
<html><body>Messenger Yeti:<br>
You're already registered. You can register only once per game! Grarr!
</body></html>

View File

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

View File

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

View File

@@ -1,3 +0,0 @@
<html><body>Messenger Yeti:<br>
Grarr! I can't find your name on the applicant list.
</body></html>

View File

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

View File

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

View File

@@ -1,3 +0,0 @@
<html><body>Messenger Yetti:<br>
Pettite~ here is your application!
</body></html>

View File

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

View File

@@ -1,3 +0,0 @@
<html><body>
I'm only authorized to talk with the clan leader.
</body></html>

View File

@@ -1,3 +0,0 @@
<html><body>Yeti:<br>
I cannot exchange any item with you!
</body></html>

View File

@@ -1,3 +0,0 @@
<html><body>
No data for this html.
</body></html>

View File

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

View File

@@ -1,3 +0,0 @@
<html><body>
That passage have been already used for your clan.
</body></html>

View File

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