Free version update 14-12-2023.
This commit is contained in:
@@ -22,6 +22,7 @@ import org.l2jmobius.gameserver.instancemanager.GrandBossManager;
|
||||
import org.l2jmobius.gameserver.model.Location;
|
||||
import org.l2jmobius.gameserver.model.StatSet;
|
||||
import org.l2jmobius.gameserver.model.World;
|
||||
import org.l2jmobius.gameserver.model.actor.Attackable;
|
||||
import org.l2jmobius.gameserver.model.actor.Npc;
|
||||
import org.l2jmobius.gameserver.model.actor.Player;
|
||||
import org.l2jmobius.gameserver.model.actor.instance.GrandBoss;
|
||||
@@ -50,6 +51,10 @@ public class DrChaos extends AbstractNpcAI
|
||||
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 static final int CHAOS_X = 96320;
|
||||
private static final int CHAOS_Y = -110912;
|
||||
private static final int CHAOS_Z = -3328;
|
||||
private static final int CHAOS_HEAD = 8191;
|
||||
|
||||
private long _lastAttackVsGolem = 0;
|
||||
private int _pissedOffTimer;
|
||||
@@ -76,7 +81,7 @@ public class DrChaos extends AbstractNpcAI
|
||||
{
|
||||
// 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);
|
||||
addSpawn(DOCTOR_CHAOS, CHAOS_X, CHAOS_Y, CHAOS_Z, CHAOS_HEAD, false, 0, false);
|
||||
GrandBossManager.getInstance().setStatus(CHAOS_GOLEM, NORMAL);
|
||||
}
|
||||
}
|
||||
@@ -109,84 +114,115 @@ public class DrChaos extends AbstractNpcAI
|
||||
@Override
|
||||
public String onAdvEvent(String event, Npc npc, Player player)
|
||||
{
|
||||
if (event.equalsIgnoreCase("reset_drchaos"))
|
||||
switch (event)
|
||||
{
|
||||
GrandBossManager.getInstance().setStatus(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"))
|
||||
{
|
||||
if ((npc.getId() == CHAOS_GOLEM) && ((_lastAttackVsGolem + 1800000) < System.currentTimeMillis()))
|
||||
case "reset_drchaos":
|
||||
{
|
||||
final Npc chaos = addSpawn(DOCTOR_CHAOS, 96320, -110912, -3328, 8191, false, 0, false); // spawn Dr. Chaos
|
||||
GrandBossManager.getInstance().setStatus(CHAOS_GOLEM, NORMAL); // mark Dr. Chaos is not crazy any more
|
||||
cancelQuestTimer("golem_despawn", chaos, null);
|
||||
GrandBossManager.getInstance().setStatus(CHAOS_GOLEM, NORMAL);
|
||||
addSpawn(DOCTOR_CHAOS, CHAOS_X, CHAOS_Y, CHAOS_Z, CHAOS_HEAD, false, 0, false);
|
||||
break;
|
||||
}
|
||||
case "golem_despawn": // despawn the live Dr. Chaos after 30 minutes of inactivity
|
||||
{
|
||||
if ((npc.getId() == CHAOS_GOLEM) && ((_lastAttackVsGolem + 1800000) < System.currentTimeMillis()))
|
||||
{
|
||||
final Npc chaos = addSpawn(DOCTOR_CHAOS, CHAOS_X, CHAOS_Y, CHAOS_Z, CHAOS_HEAD, false, 0, false); // spawn Dr. Chaos
|
||||
GrandBossManager.getInstance().setStatus(CHAOS_GOLEM, NORMAL); // mark Dr. Chaos is not crazy any more
|
||||
cancelQuestTimer("golem_despawn", chaos, null);
|
||||
cancelQuestTimers("DISTANCE_CHECK");
|
||||
|
||||
// Despawn the war golem.
|
||||
npc.deleteMe();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "1":
|
||||
{
|
||||
npc.broadcastPacket(new SocialAction(npc.getObjectId(), 2));
|
||||
npc.broadcastPacket(new SpecialCamera(npc, 1, -200, 15, 5500, 1000, 13500, 0, 0, 0, 0, 0));
|
||||
break;
|
||||
}
|
||||
case "2":
|
||||
{
|
||||
npc.broadcastPacket(new SocialAction(npc.getObjectId(), 3));
|
||||
break;
|
||||
}
|
||||
case "3":
|
||||
{
|
||||
npc.broadcastPacket(new SocialAction(npc.getObjectId(), 1));
|
||||
break;
|
||||
}
|
||||
case "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));
|
||||
break;
|
||||
}
|
||||
case "5":
|
||||
{
|
||||
final GrandBoss golem = (GrandBoss) addSpawn(CHAOS_GOLEM, 96080, -110822, -3343, 0, false, 0, false);
|
||||
GrandBossManager.getInstance().addBoss(golem);
|
||||
startQuestTimer("DISTANCE_CHECK", 10000, golem, null, true);
|
||||
golem.broadcastPacket(new SpecialCamera(npc, 30, 200, 20, 6000, 700, 8000, 0, 0, 0, 0, 0));
|
||||
golem.broadcastPacket(new SocialAction(npc.getObjectId(), 1));
|
||||
golem.broadcastPacket(new PlaySound(1, "Rm03_A", 0, 0, 0, 0, 0));
|
||||
|
||||
// Despawn the war golem.
|
||||
// start monitoring Dr. Chaos's inactivity
|
||||
_lastAttackVsGolem = System.currentTimeMillis();
|
||||
startQuestTimer("golem_despawn", 60000, golem, null, true);
|
||||
|
||||
// Delete Dr. Chaos after spawned the war golem.
|
||||
npc.deleteMe();
|
||||
break;
|
||||
}
|
||||
}
|
||||
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"))
|
||||
{
|
||||
final GrandBoss golem = (GrandBoss) addSpawn(CHAOS_GOLEM, 96080, -110822, -3343, 0, false, 0, false);
|
||||
GrandBossManager.getInstance().addBoss(golem);
|
||||
|
||||
golem.broadcastPacket(new SpecialCamera(npc, 30, 200, 20, 6000, 700, 8000, 0, 0, 0, 0, 0));
|
||||
golem.broadcastPacket(new SocialAction(npc.getObjectId(), 1));
|
||||
golem.broadcastPacket(new PlaySound(1, "Rm03_A", 0, 0, 0, 0, 0));
|
||||
|
||||
// start monitoring Dr. Chaos's inactivity
|
||||
_lastAttackVsGolem = System.currentTimeMillis();
|
||||
startQuestTimer("golem_despawn", 60000, golem, null, true);
|
||||
|
||||
// Delete Dr. Chaos after spawned the war golem.
|
||||
npc.deleteMe();
|
||||
}
|
||||
// Check every sec if someone is in range, if found, launch one task to decrease the timer.
|
||||
else if (event.equalsIgnoreCase("paranoia_activity") && (GrandBossManager.getInstance().getStatus(CHAOS_GOLEM) == NORMAL))
|
||||
{
|
||||
for (Player obj : World.getInstance().getVisibleObjectsInRange(npc, Player.class, 500))
|
||||
case "paranoia_activity":
|
||||
{
|
||||
if (obj.isDead())
|
||||
if (GrandBossManager.getInstance().getStatus(CHAOS_GOLEM) == NORMAL)
|
||||
{
|
||||
continue;
|
||||
for (Player obj : World.getInstance().getVisibleObjectsInRange(npc, Player.class, 500))
|
||||
{
|
||||
if (obj.isDead())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
_pissedOffTimer -= 1;
|
||||
|
||||
// Make him speak.
|
||||
if (_pissedOffTimer == 15)
|
||||
{
|
||||
npc.broadcastSay(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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_pissedOffTimer -= 1;
|
||||
|
||||
// Make him speak.
|
||||
if (_pissedOffTimer == 15)
|
||||
if (npc.calculateDistance2D(CHAOS_X, CHAOS_Y, CHAOS_Z) > 2000)
|
||||
{
|
||||
npc.broadcastSay(ChatType.NPC_GENERAL, "How dare you trespass into my territory! Have you no fear?");
|
||||
((Attackable) npc).clearAggroList();
|
||||
npc.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, new Location(CHAOS_X, CHAOS_Y, CHAOS_Z, 0));
|
||||
}
|
||||
|
||||
// That was "too much" for that time.
|
||||
if (_pissedOffTimer <= 0)
|
||||
break;
|
||||
}
|
||||
case "DISTANCE_CHECK":
|
||||
{
|
||||
if ((npc == null) || npc.isDead())
|
||||
{
|
||||
crazyMidgetBecomesAngry(npc);
|
||||
cancelQuestTimers("DISTANCE_CHECK");
|
||||
}
|
||||
else if (npc.calculateDistance2D(npc.getSpawn()) > 10000)
|
||||
{
|
||||
((Attackable) npc).clearAggroList();
|
||||
// npc.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, new Location(CHAOS_X, CHAOS_Y, CHAOS_Z, 0));
|
||||
npc.teleToLocation(npc.getSpawn(), false);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return super.onAdvEvent(event, npc, player);
|
||||
}
|
||||
|
||||
@@ -225,6 +261,10 @@ public class DrChaos extends AbstractNpcAI
|
||||
|
||||
// Initialization of the paranoia.
|
||||
startQuestTimer("paranoia_activity", 1000, npc, null, true);
|
||||
|
||||
cancelQuestTimer("DISTANCE_CHECK", npc, null);
|
||||
startQuestTimer("DISTANCE_CHECK", 10000, npc, null, true);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -243,6 +283,10 @@ public class DrChaos extends AbstractNpcAI
|
||||
final StatSet info = GrandBossManager.getInstance().getStatSet(CHAOS_GOLEM);
|
||||
info.set("respawn_time", System.currentTimeMillis() + respawnTime);
|
||||
GrandBossManager.getInstance().setStatSet(CHAOS_GOLEM, info);
|
||||
|
||||
// Stop distance check task.
|
||||
cancelQuestTimers("DISTANCE_CHECK");
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -240,7 +240,7 @@ public class CabaleBuffer extends AbstractNpcAI
|
||||
*/
|
||||
private boolean handleCast(Player player, int skillId)
|
||||
{
|
||||
if (player.isDead() || !player.isSpawned() || !_npc.isInsideRadius2D(player, DISTANCE_TO_WATCH_OBJECT))
|
||||
if (player.isDead() || !player.isSpawned() || !_npc.isInsideRadius3D(player, DISTANCE_TO_WATCH_OBJECT))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -37,6 +37,7 @@ import org.l2jmobius.gameserver.model.actor.Creature;
|
||||
import org.l2jmobius.gameserver.model.actor.Npc;
|
||||
import org.l2jmobius.gameserver.model.actor.Player;
|
||||
import org.l2jmobius.gameserver.model.actor.Summon;
|
||||
import org.l2jmobius.gameserver.model.actor.instance.Door;
|
||||
import org.l2jmobius.gameserver.model.events.EventType;
|
||||
import org.l2jmobius.gameserver.model.events.annotations.RegisterEvent;
|
||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureDeath;
|
||||
@@ -261,6 +262,8 @@ public class TvT extends Event
|
||||
world.setInstance(InstanceManager.getInstance().createDynamicInstance(INSTANCE_ID));
|
||||
InstanceManager.getInstance().addWorld(world);
|
||||
PVP_WORLD = world;
|
||||
// Make sure doors are closed.
|
||||
PVP_WORLD.getDoors().forEach(Door::closeMe);
|
||||
// Randomize player list and separate teams.
|
||||
final List<Player> playerList = new ArrayList<>(PLAYER_LIST.size());
|
||||
playerList.addAll(PLAYER_LIST);
|
||||
|
||||
@@ -17,10 +17,10 @@
|
||||
package quests.Q00604_DaimonTheWhiteEyedPart2;
|
||||
|
||||
import org.l2jmobius.Config;
|
||||
import org.l2jmobius.gameserver.data.SpawnTable;
|
||||
import org.l2jmobius.gameserver.enums.ChatType;
|
||||
import org.l2jmobius.gameserver.enums.QuestSound;
|
||||
import org.l2jmobius.gameserver.model.Location;
|
||||
import org.l2jmobius.gameserver.model.World;
|
||||
import org.l2jmobius.gameserver.model.actor.Npc;
|
||||
import org.l2jmobius.gameserver.model.actor.Player;
|
||||
import org.l2jmobius.gameserver.model.quest.Quest;
|
||||
@@ -265,6 +265,6 @@ public class Q00604_DaimonTheWhiteEyedPart2 extends Quest
|
||||
|
||||
private static boolean isDaimonSpawned()
|
||||
{
|
||||
return SpawnTable.getInstance().getAnySpawn(DAIMON_THE_WHITE_EYED) != null;
|
||||
return World.getInstance().getVisibleObjects().stream().anyMatch(object -> object.getId() == DAIMON_THE_WHITE_EYED);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,9 +17,9 @@
|
||||
package quests.Q00625_TheFinestIngredientsPart2;
|
||||
|
||||
import org.l2jmobius.Config;
|
||||
import org.l2jmobius.gameserver.data.SpawnTable;
|
||||
import org.l2jmobius.gameserver.enums.ChatType;
|
||||
import org.l2jmobius.gameserver.model.Location;
|
||||
import org.l2jmobius.gameserver.model.World;
|
||||
import org.l2jmobius.gameserver.model.actor.Npc;
|
||||
import org.l2jmobius.gameserver.model.actor.Player;
|
||||
import org.l2jmobius.gameserver.model.holders.ItemHolder;
|
||||
@@ -121,7 +121,7 @@ public class Q00625_TheFinestIngredientsPart2 extends Quest
|
||||
{
|
||||
rewardItems(player, GREATER_DYE_OF_DEX_2);
|
||||
}
|
||||
qs.exitQuest(false, true);
|
||||
qs.exitQuest(true, true);
|
||||
htmltext = event;
|
||||
}
|
||||
else
|
||||
@@ -137,12 +137,11 @@ public class Q00625_TheFinestIngredientsPart2 extends Quest
|
||||
{
|
||||
if (hasItem(player, FOOD_FOR_BUMBALUMP))
|
||||
{
|
||||
qs.setCond(2, true);
|
||||
if (!isBumbalumpSpawned())
|
||||
{
|
||||
qs.setCond(2, true);
|
||||
takeItem(player, FOOD_FOR_BUMBALUMP);
|
||||
final Npc umpaloopa = addSpawn(ICICLE_EMPEROR_BUMBALUMP, ICICLE_EMPEROR_BUMBALUMP_LOC);
|
||||
umpaloopa.setSummoner(player);
|
||||
addSpawn(ICICLE_EMPEROR_BUMBALUMP, ICICLE_EMPEROR_BUMBALUMP_LOC);
|
||||
htmltext = event;
|
||||
}
|
||||
else
|
||||
@@ -155,6 +154,18 @@ public class Q00625_TheFinestIngredientsPart2 extends Quest
|
||||
htmltext = "31542-04.html";
|
||||
}
|
||||
}
|
||||
else if (qs.isCond(2))
|
||||
{
|
||||
if (!isBumbalumpSpawned())
|
||||
{
|
||||
addSpawn(ICICLE_EMPEROR_BUMBALUMP, ICICLE_EMPEROR_BUMBALUMP_LOC);
|
||||
htmltext = event;
|
||||
}
|
||||
else
|
||||
{
|
||||
htmltext = "31542-03.html";
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "NPC_TALK":
|
||||
@@ -182,7 +193,7 @@ public class Q00625_TheFinestIngredientsPart2 extends Quest
|
||||
{
|
||||
if (talker.getLevel() >= MIN_LEVEL)
|
||||
{
|
||||
htmltext = (hasItem(talker, SOY_SOURCE_JAR)) ? "31521-01.htm" : "31521-02.htm";
|
||||
htmltext = hasItem(talker, SOY_SOURCE_JAR) ? "31521-01.htm" : "31521-02.htm";
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -222,18 +233,14 @@ public class Q00625_TheFinestIngredientsPart2 extends Quest
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
if (hasItem(talker, FOOD_FOR_BUMBALUMP))
|
||||
{
|
||||
htmltext = "31542-01.html";
|
||||
}
|
||||
htmltext = "31542-01.html";
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
if (!isBumbalumpSpawned())
|
||||
{
|
||||
final Npc umpaloopa = addSpawn(ICICLE_EMPEROR_BUMBALUMP, ICICLE_EMPEROR_BUMBALUMP_LOC);
|
||||
umpaloopa.setSummoner(talker);
|
||||
addSpawn(ICICLE_EMPEROR_BUMBALUMP, ICICLE_EMPEROR_BUMBALUMP_LOC);
|
||||
htmltext = "31542-02.html";
|
||||
}
|
||||
else
|
||||
@@ -265,17 +272,23 @@ public class Q00625_TheFinestIngredientsPart2 extends Quest
|
||||
@Override
|
||||
public String onKill(Npc npc, Player killer, boolean isSummon)
|
||||
{
|
||||
final QuestState qs = getRandomPartyMemberState(killer, 1, 2, npc);
|
||||
if ((qs != null) && Util.checkIfInRange(Config.ALT_PARTY_RANGE, npc, killer, true) && (npc.getSummoner() == killer))
|
||||
executeForEachPlayer(killer, npc, isSummon, true, false);
|
||||
return super.onKill(npc, killer, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionForEachPlayer(Player player, Npc npc, boolean isSummon)
|
||||
{
|
||||
final QuestState qs = getQuestState(player, false);
|
||||
if ((qs != null) && qs.isCond(2) && Util.checkIfInRange(Config.ALT_PARTY_RANGE, npc, player, true))
|
||||
{
|
||||
qs.setCond(3, true);
|
||||
giveItems(qs.getPlayer(), SPECIAL_YETI_MEAT);
|
||||
giveItems(player, SPECIAL_YETI_MEAT);
|
||||
}
|
||||
return super.onKill(npc, killer, isSummon);
|
||||
}
|
||||
|
||||
private static boolean isBumbalumpSpawned()
|
||||
{
|
||||
return SpawnTable.getInstance().getAnySpawn(ICICLE_EMPEROR_BUMBALUMP) != null;
|
||||
return World.getInstance().getVisibleObjects().stream().anyMatch(object -> object.getId() == ICICLE_EMPEROR_BUMBALUMP);
|
||||
}
|
||||
}
|
||||
@@ -218,7 +218,7 @@ public class Q00638_SeekersOfTheHolyGrail extends Quest
|
||||
final DropInfo info = MOBS_DROP_CHANCES.get(npc.getId());
|
||||
if (giveItemRandomly(qs.getPlayer(), npc, info.getId(), 1, 0, info.getChance(), true) && (info.getKeyId() > 0) && (getRandom(100) < info.getKeyChance()))
|
||||
{
|
||||
npc.dropItem(qs.getPlayer(), info.getKeyId(), info.getKeyCount());
|
||||
giveItems(qs.getPlayer(), info.getKeyId(), info.getKeyCount());
|
||||
}
|
||||
}
|
||||
return super.onKill(npc, killer, isSummon);
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
<html><body>Priest Dominic:<br>
|
||||
Do you know of a place called the <font color="LEVEL">Monastery of Silence</font>? It may call itself a monastery, but it is more like a social club; few are admitted, and they are inclined to attack anyone they suspect of intruding upon <font color="LEVEL">that which they protect</font>, that which Saint Solina left behind.<br>
|
||||
<a action="bypass -h Quest Q00639_GuardiansOfTheHolyGrail 31350-03.htm">"What did Saint Solina leave behind?"</a>
|
||||
</body></html>
|
||||
@@ -1,3 +0,0 @@
|
||||
<html><body>Priest Dominic:<br>
|
||||
Ahhh... that mission has been.. satisfied. It's time for a new mission.
|
||||
</body></html>
|
||||
@@ -0,0 +1,5 @@
|
||||
<html><body>Priest Dominic:<br>
|
||||
Have you heard tell of a place called the Monastery of Silence? Well, they are suspicious of strangers and quick to attack intruders. Why? Well, there's a reason...<br>
|
||||
But hold. I think it would be better to tell you this later on, when you have grown stronger and more skillful.<br>
|
||||
(This quest may only be undertaken by a character of level 73 and above.)
|
||||
</body></html>
|
||||
@@ -0,0 +1,4 @@
|
||||
<html><body>Priest Dominic:<br>
|
||||
Well, that's not really important for you to know, is it? I'm sorry, but that's a secret I'm sworn to keep. Suffice it to say that it is something my order needs enough to hire you to get it. Sadly, the monastery is just as intent on keeping it, and their resistance was stronger than we expected. We failed to get it, and so I am here asking you to succeed where we have failed. You will have to defeat them totally; nothing less will allow my order to retrieve what we need from them.<br>
|
||||
<a action="bypass -h Quest Q00639_GuardiansOfTheHolyGrail 31350-04.html">Tell him you will do it.</a>
|
||||
</body></html>
|
||||
@@ -0,0 +1,4 @@
|
||||
<html><body>Priest Dominic:<br>
|
||||
Very good! Then go to the <font color="LEVEL">Monastery of Silence</font> and defeat its monks. I will give you a reward if you bring me the <font color="LEVEL">Scripture of Monk</font> as proof that you eliminated them.<br>
|
||||
Oh, yes...one more thing. We have a man on the inside, an agent named <font color="LEVEL">Gremory</font> who infiltrated the Monastery of Silence. He has done brave work, and if you can help him to escape, that would be best. He can be of great assistance to you.
|
||||
</body></html>
|
||||
@@ -0,0 +1,5 @@
|
||||
<html><body>Priest Dominic:<br>
|
||||
Fine work. Haha! Thank you for eliminating those pesky monks. So, would you like to collect your just reward?<br>
|
||||
<a action="bypass -h Quest Q00639_GuardiansOfTheHolyGrail 31350-07.html">Don't collect the reward now.</a><br>
|
||||
<a action="bypass -h Quest Q00639_GuardiansOfTheHolyGrail 31350-08.html">Get the reward in exchange for the Scripture of Monk you brought.</a>
|
||||
</body></html>
|
||||
@@ -0,0 +1,6 @@
|
||||
<html><body>Priest Dominic:<br>
|
||||
Here's the quest: Go to the <font color="LEVEL">Monastery of Silence</font> and vanquish the monks. I will give you a reward if you bring me the <font color="LEVEL">Scripture of Monk</font> as proof that you have defeated them. I hope, of course, that they surrender to you, but if they do not, you may kill them in good conscience; we will pray for their souls.<br>
|
||||
Oh, here's something that may help you: we have a man on the inside. Our brave <font color="LEVEL">Gremory</font> has managed to infiltrate the monastery, a task many had thought impossible. Please help him to escape if possible; the poor man has done more than enough, and he may be of help to you.<br>
|
||||
<a action="bypass -h Quest Q00639_GuardiansOfTheHolyGrail 31350-07.html">Continue the job.</a><br>
|
||||
<a action="bypass -h Quest Q00639_GuardiansOfTheHolyGrail 31350-09.html">Quit the job.</a>
|
||||
</body></html>
|
||||
@@ -0,0 +1,3 @@
|
||||
<html><body>Priest Dominic:<br>
|
||||
Fine, then. Keep up the good work... until we retake from those pestilent monks what is ours by right!
|
||||
</body></html>
|
||||
@@ -0,0 +1,3 @@
|
||||
<html><body>Priest Dominic:<br>
|
||||
Here, then, is your payment. You have done excellent work.
|
||||
</body></html>
|
||||
@@ -0,0 +1,4 @@
|
||||
<html><body>Priest Dominic:<br>
|
||||
Oh, very well. I can't make you do it. But do be careful, now; I wouldn't want to see you side with those pestilential monks. Who knows what might happen to you if you did? You might just...die, of remorse and shame. Heh.<br>
|
||||
If you change your mind, you know where to find me.
|
||||
</body></html>
|
||||
@@ -0,0 +1,5 @@
|
||||
<html><body>Priest Gremory:<br>
|
||||
Curses! I've been unmasked! How did you find me, damn you? My disguise was perfect. Well, question me all you like; my lips are sealed.<br>
|
||||
What? Dominic sent you? Oh, thank the gods. For a moment I feared the worst!<br>
|
||||
<a action="bypass -h Quest Q00639_GuardiansOfTheHolyGrail 32008-02.html">"Why are you here?"</a>
|
||||
</body></html>
|
||||
@@ -0,0 +1,6 @@
|
||||
<html><body>Priest Gremory:<br>
|
||||
I infiltrated this order to find the <font color="LEVEL">Grail of Splendor</font> they keep hidden here in the Monastery of Silence. Now that's a mission for a man! I wouldn't blame you for envying me.<br>
|
||||
Wait - if you were sent by Dominic, then you report to me now! Hahaha! Yes, I've been expecting this. I have served here so long, so very long... the pressures, you wouldn't understand them. You couldn't. And now he finally recognizes my service and my abilities!<br>
|
||||
Very well, servant. Your first task will be to massage my shoulders. I'm weary from hiding in this narrow space for so long...<br>
|
||||
<a action="bypass -h Quest Q00639_GuardiansOfTheHolyGrail 32008-03.html">"I'm not your underling. I'm here to help you fulfill your mission."</a>
|
||||
</body></html>
|
||||
@@ -0,0 +1,6 @@
|
||||
<html><body>Priest Gremory:<br>
|
||||
What? Damn it all! I have needed an underling for so long...<br>
|
||||
Well, never mind that now. Let's talk business. In my searches within the monastery, I have found a <font color="LEVEL">broken bridge</font>. Across the bridge, there is a chamber called the <font color="LEVEL">Room of Splendor</font>.<br>
|
||||
I don't know what that name means, but... they say the <font color="LEVEL">Holy Grail</font> lies within. That's the place to go.<br>
|
||||
<a action="bypass -h Quest Q00639_GuardiansOfTheHolyGrail 32008-04.html">"A broken bridge? How do I cross it?"</a>
|
||||
</body></html>
|
||||
@@ -0,0 +1,5 @@
|
||||
<html><body>Priest Gremory:<br>
|
||||
The broken bridge? It is simply an optical illusion. Just step out onto it and you'll find the bridge is intact and whole. I have a fear of heights, so I cannot manage the crossing myself. It has been my one and only failure as an agent.<br>
|
||||
Get me that Grail, and I will <font color="LEVEL">trade you some unique items</font> which form a part of the <font color="LEVEL">Scripture of Monk</font> that you are collecting. Do we have a deal?<br>
|
||||
<a action="bypass -h Quest Q00639_GuardiansOfTheHolyGrail 32008-05.html">"OK, what do I have to do?"</a>
|
||||
</body></html>
|
||||
@@ -0,0 +1,4 @@
|
||||
<html><body>Priest Gremory:<br>
|
||||
Then we understand each other. Go to the <font color="LEVEL">Room of Splendor</font> and <font color="LEVEL">pour water into the Holy Grail. Then pour that water back into a jar and bring it to me.</font> Thus can we verify the genuineness of the Holy Grail. Be careful, though; the Grail may be guarded.<br>
|
||||
One more thing: the Room of Splendor is locked. You will need a <font color="LEVEL">key to enter there.</font> Some monks have such keys to perform their duties, so I suggest that you overcome one of them and take his key.
|
||||
</body></html>
|
||||
@@ -0,0 +1,4 @@
|
||||
<html><body>Priest Gremory:<br>
|
||||
Go to the <font color="LEVEL">Room of Splendor</font> and <font color="LEVEL">pour a measure of water into the Holy Grail. Then pour the water back into a jar and bring it to me.</font> We can test the water to determine if the Grail is the real thing or not. Be careful when you do this; the room may be guarded.<br>
|
||||
Oh, another thing. The Room of Splendor is locked, and you'll need a <font color="LEVEL">key to enter it.</font> Some of the monks carry a key to that room; I suggest that you overcome of one of them and take his key.
|
||||
</body></html>
|
||||
@@ -0,0 +1,6 @@
|
||||
<html><body>Priest Gremory:<br>
|
||||
Nice! You got away clean, did you? Well, let's test the water.<br>
|
||||
Alas! The water fails the test. <font color="LEVEL">They must keep the real Grail somewhere else!</font><br>
|
||||
Well, thank you, I suppose. It was worth knowing about the false lead. Now leave me; I must return to my task of finding the real Grail. Go quickly, before they discover us!<br>
|
||||
<a action="bypass -h Quest Q00639_GuardiansOfTheHolyGrail 32008-09.html">"That wasn't the deal. You promised us a part of the Scripture of Monk in exchange for what we found."</a>
|
||||
</body></html>
|
||||
@@ -0,0 +1,4 @@
|
||||
<html><body>Priest Gremory:<br>
|
||||
Ah, that's true, that's true. Such forgetfulness is rare in a spy of my caliber, I assure you! Well, I am a man of my word, so here you go. I assume that takes care of our deal, yes?<br>
|
||||
What's more, I'll make another deal with you: If you bring me <font color="LEVEL">4000 or 400 Monk Scriptures, I will exchange them for an S-grade Enchant Weapon Scroll or an S-grade Enchant Armor Scroll, respectively</font>. Come back after you slay those bothersome monks.
|
||||
</body></html>
|
||||
@@ -0,0 +1,6 @@
|
||||
<html><body>Priest Gremory:<br>
|
||||
The Grail, the Grail...o, where is the blasted thing? A spy of my stature should surely have found it by now! Does it even exist?<br>
|
||||
...Huh? Ah, it's you again! Did you bring me any Monk Scriptures?<br>
|
||||
<a action="bypass -h Quest Q00639_GuardiansOfTheHolyGrail 32008-12.html">Exchange 4000 Monk Scriptures for an S-grade Enchant Weapon Scroll.</a><br>
|
||||
<a action="bypass -h Quest Q00639_GuardiansOfTheHolyGrail 32008-14.html">Exchange 400 Monk Scriptures for an S-grade Enchant Armor Scroll.</a>
|
||||
</body></html>
|
||||
@@ -0,0 +1,4 @@
|
||||
<html><body>Priest Gremory:<br>
|
||||
Here you go: one S-grade Enchant Weapon Scroll. Do you like it? You'd better appreciate it; it's a gift from me, after all! Hahaha!<br>
|
||||
And here are my Scriptures. Once I show Dominic all of the Scriptures, he'll finally appreciate my abilities properly. Of course, he'll think I collected them myself... but in a sense I did, didn't I?
|
||||
</body></html>
|
||||
@@ -0,0 +1,4 @@
|
||||
<html><body>Priest Gremory:<br>
|
||||
Huh? You need more of the Monk Scriptures to meet my terms! What is this, some sort of con game? You'll never fool me that easily.<br>
|
||||
Kill the monks, as many as you need to, and bring me more scriptures. Understood?
|
||||
</body></html>
|
||||
@@ -0,0 +1,4 @@
|
||||
<html><body>Priest Gremory:<br>
|
||||
Here is the S-grade Enchant Armor Scroll I promised you, then. Do you like it? You'd better appreciate it, fellow; it's a gift from Gremory the spy! Hahaha!<br>
|
||||
And here are my Scriptures. Once I show Dominic my collection of Scriptures, he'll properly appreciate my abilities. He'll think I collected them myself... but in a sense I did, didn't I?
|
||||
</body></html>
|
||||
@@ -0,0 +1,4 @@
|
||||
<html><body>Priest Gremory:<br>
|
||||
Oh, nonsense. You know very well that these aren't enough Scriptures. What is this, some sort of inept con game? You'll need more than that to trick me, my friend. You're dealing with Gremory, understand?<br>
|
||||
Go kill the monks and bring me more Scriptures. Understood?
|
||||
</body></html>
|
||||
@@ -0,0 +1,4 @@
|
||||
<html><body>The Grail of Splendor:<br>
|
||||
Gremory's instructions were to pour some water into the Grail, then pour that water into a bottle and bring it to him.<br>
|
||||
<a action="bypass -h Quest Q00639_GuardiansOfTheHolyGrail 32028-02.html">Pour the water.</a>
|
||||
</body></html>
|
||||
@@ -0,0 +1,3 @@
|
||||
<html><body>The Grail of Splendor:<br>
|
||||
I pour the water into the Grail. I see no change... Now, I'll pour the water into this bottle and return to Gremory.
|
||||
</body></html>
|
||||
@@ -0,0 +1,3 @@
|
||||
<html><body>The Grail of Splendor:<br>
|
||||
I have completed what Gremory asked of me, so now I will go to see him.
|
||||
</body></html>
|
||||
@@ -16,33 +16,230 @@
|
||||
*/
|
||||
package quests.Q00639_GuardiansOfTheHolyGrail;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.l2jmobius.commons.util.Rnd;
|
||||
import org.l2jmobius.gameserver.enums.QuestSound;
|
||||
import org.l2jmobius.gameserver.model.actor.Npc;
|
||||
import org.l2jmobius.gameserver.model.actor.Player;
|
||||
import org.l2jmobius.gameserver.model.quest.Quest;
|
||||
import org.l2jmobius.gameserver.model.quest.QuestState;
|
||||
import org.l2jmobius.gameserver.model.quest.State;
|
||||
|
||||
/**
|
||||
* Guardians of the Holy Grail (639)<br>
|
||||
* NOTE: This quest is no longer available since Freya(CT2.5)
|
||||
* @author corbin12
|
||||
*/
|
||||
public class Q00639_GuardiansOfTheHolyGrail extends Quest
|
||||
{
|
||||
// NPC
|
||||
// NPCs
|
||||
private static final int DOMINIC = 31350;
|
||||
private static final int GREMORY = 32008;
|
||||
private static final int HOLY_GRAIL = 32028;
|
||||
// Items
|
||||
private static final int SCRIPTURE = 8069;
|
||||
private static final int WATER_BOTTLE = 8070;
|
||||
private static final int HOLY_WATER_BOTTLE = 8071;
|
||||
private static final Map<Integer, Integer> CHANCES = new HashMap<>();
|
||||
static
|
||||
{
|
||||
CHANCES.put(22122, 760000);
|
||||
CHANCES.put(22123, 750000);
|
||||
CHANCES.put(22124, 590000);
|
||||
CHANCES.put(22125, 580000);
|
||||
CHANCES.put(22126, 590000);
|
||||
CHANCES.put(22127, 580000);
|
||||
CHANCES.put(22128, 170000);
|
||||
CHANCES.put(22129, 590000);
|
||||
CHANCES.put(22130, 850000);
|
||||
CHANCES.put(22131, 920000);
|
||||
CHANCES.put(22132, 580000);
|
||||
CHANCES.put(22133, 930000);
|
||||
CHANCES.put(22134, 230000);
|
||||
CHANCES.put(22135, 580000);
|
||||
}
|
||||
|
||||
public Q00639_GuardiansOfTheHolyGrail()
|
||||
{
|
||||
super(639);
|
||||
registerQuestItems(SCRIPTURE, WATER_BOTTLE, HOLY_WATER_BOTTLE);
|
||||
addStartNpc(DOMINIC);
|
||||
addTalkId(DOMINIC);
|
||||
addTalkId(DOMINIC, GREMORY, HOLY_GRAIL);
|
||||
addKillId(CHANCES.keySet());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAdvEvent(String event, Npc npc, Player player)
|
||||
{
|
||||
final QuestState qs = getQuestState(player, false);
|
||||
String htmltext = null;
|
||||
if (qs == null)
|
||||
{
|
||||
return htmltext;
|
||||
}
|
||||
|
||||
switch (event)
|
||||
{
|
||||
case "31350-03.htm":
|
||||
case "31350-07.html":
|
||||
case "32008-02.html":
|
||||
case "32008-03.html":
|
||||
case "32008-04.html":
|
||||
{
|
||||
htmltext = event;
|
||||
break;
|
||||
}
|
||||
case "31350-04.html":
|
||||
{
|
||||
qs.startQuest();
|
||||
htmltext = event;
|
||||
break;
|
||||
}
|
||||
case "31350-08.html":
|
||||
{
|
||||
final long count = getQuestItemsCount(player, SCRIPTURE);
|
||||
takeItems(player, SCRIPTURE, -1);
|
||||
rewardItems(player, 57, (1625 * count) + ((count >= 10) ? 33940 : 0));
|
||||
htmltext = event;
|
||||
break;
|
||||
}
|
||||
case "31350-09.html":
|
||||
{
|
||||
qs.exitQuest(true, true);
|
||||
htmltext = event;
|
||||
break;
|
||||
}
|
||||
case "32008-05.html":
|
||||
{
|
||||
qs.setCond(2, true);
|
||||
giveItems(player, WATER_BOTTLE, 1);
|
||||
htmltext = event;
|
||||
break;
|
||||
}
|
||||
case "32008-09.html":
|
||||
{
|
||||
qs.setCond(4, true);
|
||||
takeItems(player, HOLY_WATER_BOTTLE, 1);
|
||||
htmltext = event;
|
||||
break;
|
||||
}
|
||||
case "32008-12.html":
|
||||
{
|
||||
if (getQuestItemsCount(player, SCRIPTURE) >= 4000)
|
||||
{
|
||||
takeItems(player, SCRIPTURE, 4000);
|
||||
rewardItems(player, 959, 1);
|
||||
htmltext = "32008-11.html";
|
||||
}
|
||||
else
|
||||
{
|
||||
htmltext = event;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "32008-14.html":
|
||||
{
|
||||
if (getQuestItemsCount(player, SCRIPTURE) >= 400)
|
||||
{
|
||||
takeItems(player, SCRIPTURE, 400);
|
||||
rewardItems(player, 960, 1);
|
||||
htmltext = "32008-13.html";
|
||||
}
|
||||
else
|
||||
{
|
||||
htmltext = event;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "32028-02.html":
|
||||
{
|
||||
qs.setCond(3, true);
|
||||
takeItems(player, WATER_BOTTLE, 1);
|
||||
giveItems(player, HOLY_WATER_BOTTLE, 1);
|
||||
htmltext = event;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return htmltext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onTalk(Npc npc, Player player)
|
||||
{
|
||||
final QuestState qs = getQuestState(player, true);
|
||||
qs.exitQuest(true);
|
||||
return "31350-01.html";
|
||||
String htmltext = getNoQuestMsg(player);
|
||||
|
||||
switch (qs.getState())
|
||||
{
|
||||
case State.CREATED:
|
||||
{
|
||||
htmltext = player.getLevel() < 73 ? "31350-02.htm" : "31350-01.htm";
|
||||
break;
|
||||
}
|
||||
case State.STARTED:
|
||||
{
|
||||
switch (npc.getId())
|
||||
{
|
||||
case DOMINIC:
|
||||
{
|
||||
htmltext = hasQuestItems(player, SCRIPTURE) ? "31350-05.html" : "31350-06.html";
|
||||
break;
|
||||
}
|
||||
case GREMORY:
|
||||
{
|
||||
switch (qs.getCond())
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
htmltext = "32008-01.html";
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
htmltext = "32008-06.html";
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
htmltext = "32008-08.html";
|
||||
break;
|
||||
}
|
||||
case 4:
|
||||
{
|
||||
htmltext = "32008-10.html";
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case HOLY_GRAIL:
|
||||
{
|
||||
if (qs.isCond(2))
|
||||
{
|
||||
htmltext = "32028-01.html";
|
||||
}
|
||||
else if (qs.getCond() > 2)
|
||||
{
|
||||
htmltext = "32028-03.html";
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return htmltext;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onKill(Npc npc, Player killer, boolean isSummon)
|
||||
{
|
||||
final QuestState qs = getRandomPartyMemberState(killer, 4, 3, npc);
|
||||
if ((qs != null) && (Rnd.get(1000000) < CHANCES.get(npc.getId())))
|
||||
{
|
||||
playSound(killer, QuestSound.ITEMSOUND_QUEST_ITEMGET);
|
||||
giveItems(qs.getPlayer(), SCRIPTURE, 1);
|
||||
}
|
||||
|
||||
return super.onKill(npc, killer, isSummon);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package quests.Q00655_AGrandPlanForTamingWildBeasts;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Calendar;
|
||||
|
||||
import org.l2jmobius.gameserver.cache.HtmCache;
|
||||
import org.l2jmobius.gameserver.enums.QuestSound;
|
||||
@@ -181,7 +182,15 @@ public class Q00655_AGrandPlanForTamingWildBeasts extends Quest
|
||||
private static String getSiegeDate()
|
||||
{
|
||||
final SiegableHall hall = CHSiegeManager.getInstance().getSiegableHall(ClanHallSiegeEngine.BEAST_FARM);
|
||||
return hall != null ? new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(hall.getSiegeDate()) : "Error in date.";
|
||||
if (hall != null)
|
||||
{
|
||||
final Calendar calendar = hall.getSiegeDate();
|
||||
if (calendar != null)
|
||||
{
|
||||
return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(calendar.getTime());
|
||||
}
|
||||
}
|
||||
return "Unknown date.";
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -564,6 +564,7 @@
|
||||
<set name="material" val="PAPER" />
|
||||
<set name="weight" val="120" />
|
||||
<set name="price" val="100" />
|
||||
<set name="is_stackable" val="true" />
|
||||
</item>
|
||||
<item id="1048" type="EtcItem" name="Spellbook: Might">
|
||||
<!-- Spellbook needed to learn Might. Used by Human Mystics, Elven Mystics and Dark Mystics. Required level: 7 -->
|
||||
@@ -653,6 +654,7 @@
|
||||
<set name="material" val="PAPER" />
|
||||
<set name="weight" val="120" />
|
||||
<set name="price" val="500" />
|
||||
<set name="is_stackable" val="true" />
|
||||
</item>
|
||||
<item id="1058" type="EtcItem" name="Spellbook: Shield">
|
||||
<!-- Spellbook needed to learn Shield. Used by Human Mystics, Elven Mystics and Dark Mystics. Required level: 7 -->
|
||||
@@ -670,6 +672,7 @@
|
||||
<set name="material" val="PAPER" />
|
||||
<set name="weight" val="120" />
|
||||
<set name="price" val="500" />
|
||||
<set name="is_stackable" val="true" />
|
||||
</item>
|
||||
<item id="1060" type="EtcItem" name="Lesser Healing Potion">
|
||||
<!-- A magical potion that slowly restores HP. Low endurance. -->
|
||||
|
||||
@@ -1349,6 +1349,7 @@
|
||||
<set name="material" val="PAPER" />
|
||||
<set name="weight" val="120" />
|
||||
<set name="price" val="1250" />
|
||||
<set name="is_stackable" val="true" />
|
||||
</item>
|
||||
<item id="1396" type="EtcItem" name="Spellbook: Surrender to Wind">
|
||||
<!-- Spellbook needed to learn Surrender to Water -->
|
||||
@@ -1357,6 +1358,7 @@
|
||||
<set name="material" val="PAPER" />
|
||||
<set name="weight" val="120" />
|
||||
<set name="price" val="1250" />
|
||||
<set name="is_stackable" val="true" />
|
||||
</item>
|
||||
<item id="1397" type="EtcItem" name="Spellbook: Peace">
|
||||
<!-- Spellbook needed to learn Peace. Used by Clerics. Required level: 35 -->
|
||||
|
||||
Reference in New Issue
Block a user