Removed several scripts.
This commit is contained in:
@@ -1,243 +0,0 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package instances.CastleDungeon;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import com.l2jmobius.commons.util.CommonUtil;
|
||||
import com.l2jmobius.gameserver.ThreadPoolManager;
|
||||
import com.l2jmobius.gameserver.enums.QuestSound;
|
||||
import com.l2jmobius.gameserver.model.Location;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.entity.Castle;
|
||||
import com.l2jmobius.gameserver.model.instancezone.Instance;
|
||||
import com.l2jmobius.gameserver.model.instancezone.InstanceTemplate;
|
||||
import com.l2jmobius.gameserver.model.quest.QuestState;
|
||||
|
||||
import instances.AbstractInstance;
|
||||
import quests.Q00512_BladeUnderFoot.Q00512_BladeUnderFoot;
|
||||
|
||||
/**
|
||||
* <b>Castle dungeon</b> instance for quest <b>BladeUnderFoot (512)</b>
|
||||
* @author Mobius
|
||||
*/
|
||||
public final class CastleDungeon extends AbstractInstance
|
||||
{
|
||||
// NPCs
|
||||
private static final Map<Integer, Integer> NPCS = new HashMap<>();
|
||||
static
|
||||
{
|
||||
NPCS.put(36403, 13); // Gludio
|
||||
NPCS.put(36404, 14); // Dion
|
||||
NPCS.put(36405, 15); // Giran
|
||||
NPCS.put(36406, 16); // Oren
|
||||
NPCS.put(36407, 17); // Aden
|
||||
NPCS.put(36408, 18); // Innadril
|
||||
NPCS.put(36409, 19); // Goddard
|
||||
NPCS.put(36410, 20); // Rune
|
||||
NPCS.put(36411, 21); // Schuttgart
|
||||
}
|
||||
// Monsters
|
||||
private static final int[] RAIDS1 =
|
||||
{
|
||||
25546,
|
||||
25549,
|
||||
25552
|
||||
};
|
||||
private static final int[] RAIDS2 =
|
||||
{
|
||||
25553,
|
||||
25554,
|
||||
25557,
|
||||
25560
|
||||
};
|
||||
private static final int[] RAIDS3 =
|
||||
{
|
||||
25563,
|
||||
25566,
|
||||
25569
|
||||
};
|
||||
// Item
|
||||
private static final int MARK = 9798;
|
||||
// Locations
|
||||
private static final Location SPAWN_LOC = new Location(12230, -49139, -3013);
|
||||
// Misc
|
||||
private static final int MARK_COUNT = 2520;
|
||||
private static final long REENTER = 24 * 3600000; // 24 hours
|
||||
private static final Map<Integer, Long> REENETER_HOLDER = new ConcurrentHashMap<>();
|
||||
|
||||
public CastleDungeon()
|
||||
{
|
||||
super(NPCS.values().stream().mapToInt(Integer::valueOf).toArray());
|
||||
// NPCs
|
||||
addStartNpc(NPCS.keySet());
|
||||
addTalkId(NPCS.keySet());
|
||||
// Monsters
|
||||
addKillId(RAIDS1);
|
||||
addKillId(RAIDS2);
|
||||
addKillId(RAIDS3);
|
||||
// Instance
|
||||
addInstanceCreatedId(NPCS.values());
|
||||
addInstanceDestroyId(NPCS.values());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onTalk(L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
final int npcId = npc.getId();
|
||||
if (NPCS.containsKey(npcId))
|
||||
{
|
||||
enterInstance(player, npc, NPCS.get(npcId));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onKill(L2Npc npc, L2PcInstance player, boolean isSummon)
|
||||
{
|
||||
final Instance world = npc.getInstanceWorld();
|
||||
if (world != null)
|
||||
{
|
||||
if (CommonUtil.contains(RAIDS3, npc.getId()))
|
||||
{
|
||||
// Get players with active quest
|
||||
final List<L2PcInstance> members = new ArrayList<>();
|
||||
for (L2PcInstance member : world.getPlayers())
|
||||
{
|
||||
final QuestState qs = member.getQuestState(Q00512_BladeUnderFoot.class.getSimpleName());
|
||||
if ((qs != null) && qs.isCond(1))
|
||||
{
|
||||
members.add(member);
|
||||
}
|
||||
}
|
||||
|
||||
// Distribute marks between them
|
||||
if (!members.isEmpty())
|
||||
{
|
||||
final long itemCount = MARK_COUNT / members.size();
|
||||
for (L2PcInstance member : members)
|
||||
{
|
||||
giveItems(member, MARK, itemCount);
|
||||
playSound(member, QuestSound.ITEMSOUND_QUEST_ITEMGET);
|
||||
}
|
||||
}
|
||||
world.finishInstance();
|
||||
}
|
||||
else
|
||||
{
|
||||
world.incStatus();
|
||||
spawnRaid(world);
|
||||
}
|
||||
}
|
||||
return super.onKill(npc, player, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInstanceCreated(Instance instance, L2PcInstance player)
|
||||
{
|
||||
// Put re-enter for instance
|
||||
REENETER_HOLDER.put(instance.getTemplateId(), System.currentTimeMillis() + REENTER);
|
||||
// Schedule spawn of first raid
|
||||
spawnRaid(instance);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean validateConditions(List<L2PcInstance> group, L2Npc npc, InstanceTemplate template)
|
||||
{
|
||||
final L2PcInstance groupLeader = group.get(0);
|
||||
final Castle castle = npc.getCastle();
|
||||
if (castle == null)
|
||||
{
|
||||
showHtmlFile(groupLeader, "noProperPledge.html");
|
||||
return false;
|
||||
}
|
||||
else if (REENETER_HOLDER.containsKey(template.getId()))
|
||||
{
|
||||
final long time = REENETER_HOLDER.get(template.getId());
|
||||
if (time > System.currentTimeMillis())
|
||||
{
|
||||
showHtmlFile(groupLeader, "enterRestricted.html");
|
||||
return false;
|
||||
}
|
||||
REENETER_HOLDER.remove(template.getId());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInstanceDestroy(Instance instance)
|
||||
{
|
||||
// Stop running spawn task
|
||||
final ScheduledFuture<?> task = instance.getParameters().getObject("spawnTask", ScheduledFuture.class);
|
||||
if ((task != null) && !task.isDone())
|
||||
{
|
||||
task.cancel(true);
|
||||
}
|
||||
instance.setParameter("spawnTask", null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Spawn raid boss according to instance status.
|
||||
* @param instance instance world where instance should be spawned
|
||||
*/
|
||||
private void spawnRaid(Instance instance)
|
||||
{
|
||||
final ScheduledFuture<?> spawnTask = ThreadPoolManager.getInstance().scheduleGeneral(() ->
|
||||
{
|
||||
// Get template id of raid
|
||||
final int npcId;
|
||||
switch (instance.getStatus())
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
npcId = RAIDS1[getRandom(RAIDS1.length)];
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
npcId = RAIDS2[getRandom(RAIDS2.length)];
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
npcId = RAIDS3[getRandom(RAIDS3.length)];
|
||||
}
|
||||
}
|
||||
|
||||
// Spawn raid
|
||||
addSpawn(npcId, SPAWN_LOC, false, 0, false, instance.getId());
|
||||
|
||||
// Unset spawn task reference
|
||||
instance.setParameter("spawnTask", null);
|
||||
}, 2, TimeUnit.MINUTES);
|
||||
|
||||
// Save timer to instance world
|
||||
instance.setParameter("spawnTask", spawnTask);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new CastleDungeon();
|
||||
}
|
||||
}
|
@@ -1,4 +0,0 @@
|
||||
<html><body>Prison is currently closed.<br>
|
||||
You can visit the prison once every 24 hours with your clan.<br>
|
||||
If prison is closed, check with your clan members to see when the last session started.
|
||||
</body></html>
|
@@ -1,3 +0,0 @@
|
||||
<html><body>
|
||||
Only a party may enter the prison. Once you visit the prison, you may not attend another one for at least 24 hours.
|
||||
</body></html>
|
@@ -1,3 +0,0 @@
|
||||
<html><body>
|
||||
To enter the prison, your party must include at least 2 people.
|
||||
</body></html>
|
@@ -1,3 +0,0 @@
|
||||
<html><body>
|
||||
The clan does not possess this castle.
|
||||
</body></html>
|
@@ -1,4 +0,0 @@
|
||||
<html><body>Kain Van Halter:<br>
|
||||
Took you long enough. I thought you'd be as swift as the wind, but you're slow as molasses. I got here first with <font color="LEVEL">Ferin</font>. She's the daughter of... Venir, was it? We're finally going to find the Grail. Let's get going.<br>
|
||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest ChamberOfProphecies teleport">"Let's go."</button>
|
||||
</body></html>
|
@@ -1,7 +0,0 @@
|
||||
<html><body>Kain Van Halter:<br>
|
||||
The Grail was literally just a simple grail. it was not what I was looking for.<br>
|
||||
But, I have no regrets about taking this journey with you.<br>
|
||||
If it's not the Grail, I'm not interested in it. Do whatever you wish with it.<br>
|
||||
Let us part ways now.<br>
|
||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest ChamberOfProphecies exit">"Good bye."</button>
|
||||
</body></html>
|
@@ -1,4 +0,0 @@
|
||||
<html><body>Kain Van Halter:<br>
|
||||
I hope that the Grail it's talking about is the same one I'm looking for.<br>
|
||||
<Button ALIGN=LEFT ICON="QUEST" action="bypass -h Quest ChamberOfProphecies status">Quest</button>
|
||||
</body></html>
|
@@ -1,7 +0,0 @@
|
||||
<html><body>
|
||||
Mysterious Wizard:<br>
|
||||
<font color="LEVEL">Nidrah</font>? I have no idea what you're talking about. Oh, you mean thr vampire shouted at me?<br>
|
||||
She was cursed with dark magic and was not herself. You believe her?<br>
|
||||
More importantly, I want to talk about the object you have.<br>
|
||||
<Button ALIGN="LEFT" ICON="Normal" action="bypass -h Quest ChamberOfProphecies 33980-02.html">"Do you know what this is?"</button>
|
||||
</body></html>
|
@@ -1,6 +0,0 @@
|
||||
<html><body>
|
||||
Mysterious Wizard:<br>
|
||||
This is a extremely rare gem called <font color="LEVEL">Atelia</font>. To my knowledge, it's only found in the Wind Spirit Realm.<br>
|
||||
I heard that an Atelia can recognize its owner. You see how it turned back to its original form when you touched it? That means you are the rightful owner.<br>
|
||||
<Button ALIGN="LEFT" ICON="Normal" action="bypass -h Quest ChamberOfProphecies 33980-03.html">"Why are You telling me this?"</button>
|
||||
</body></html>
|
@@ -1,5 +0,0 @@
|
||||
<html><body>Mysterious Wizard:<br>
|
||||
Do You still suspect me? I'm just helping you so that you won't lose what is yours. The Atelia will only end up in Queen's hands back in town, wich means ir will be the Queen's power. Don't you want the power for yourself?<br>
|
||||
<Button ALIGN="LEFT" ICON="Normal" action="bypass -h Quest ChamberOfProphecies 33980-04.html">"Don't lie to me. This is not mine."</button>
|
||||
<Button ALIGN="LEFT" ICON="Normal" action="bypass -h Quest ChamberOfProphecies 33980-04.html">"This is the power I will have?"</button>
|
||||
</body></html>
|
@@ -1,5 +0,0 @@
|
||||
<html><body>Mysterious Wizard:<br>
|
||||
Really? Having Atelia's power will make you powerful beyond your imagination. You want to give up your last chance to use this power for yourself?<br>
|
||||
<Button ALIGN="LEFT" ICON="Normal" action="bypass -h Quest ChamberOfProphecies 33980-05.html">"Do not tempt me to covet what is not mine!"</button>
|
||||
<Button ALIGN="LEFT" ICON="Normal" action="bypass -h Quest ChamberOfProphecies 33980-05.html">"Well, if you say it's mine, then...hehe"</button>
|
||||
</body></html>
|
@@ -1,3 +0,0 @@
|
||||
<html><body>Mysterious Wizard:<br>
|
||||
I'm sorry to hear that. I wanted to see you become more powerful. That's all time has permitted us. Perhaps I will see you later?
|
||||
</body></html>
|
@@ -1,5 +0,0 @@
|
||||
<html><body>
|
||||
Mysterious Wizard:<br>
|
||||
Long time no see. How do you do?<br>
|
||||
<Button ALIGN="LEFT" ICON="Normal" action="bypass -h Quest ChamberOfProphecies 33980-01.html">"You are... Nidhar, was it?"</button>
|
||||
</body></html>
|
@@ -1,5 +0,0 @@
|
||||
<html><body>Grail:<br>
|
||||
This is the grail the Prophecy Machine was referring to.<br>
|
||||
Do you think this is THE grail?<br>
|
||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest ChamberOfProphecies 33996-02.html">Can I touch it?</button>
|
||||
</body></html>
|
@@ -1,3 +0,0 @@
|
||||
<html><body>Grail:<br>
|
||||
The grail disappeared, leaving behind a gem.
|
||||
</body></html>
|
@@ -1,6 +0,0 @@
|
||||
<html><body>Grail:<br>
|
||||
<center>The Atelias's powers are sealed here.</center><br1>
|
||||
It will regan its from, when the masters of its power comes.<br1>
|
||||
<center>-Zepharon, King of Ertheia</center><br>
|
||||
<Button ALIGN=LEFT ICON="QUEST" action="bypass -h Quest ChamberOfProphecies 33996-01.html">Quest</button>
|
||||
</body></html>
|
@@ -1,468 +0,0 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package instances.ChamberOfProphecies;
|
||||
|
||||
import com.l2jmobius.commons.util.CommonUtil;
|
||||
import com.l2jmobius.gameserver.ai.CtrlIntention;
|
||||
import com.l2jmobius.gameserver.enums.ChatType;
|
||||
import com.l2jmobius.gameserver.model.L2World;
|
||||
import com.l2jmobius.gameserver.model.Location;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Attackable;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Character;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.instancezone.Instance;
|
||||
import com.l2jmobius.gameserver.model.quest.QuestState;
|
||||
import com.l2jmobius.gameserver.network.NpcStringId;
|
||||
import com.l2jmobius.gameserver.network.SystemMessageId;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ExShowScreenMessage;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ExShowUsm;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.NpcSay;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.PlaySound;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.SystemMessage;
|
||||
|
||||
import instances.AbstractInstance;
|
||||
import quests.Q10753_WindsOfFateChoices.Q10753_WindsOfFateChoices;
|
||||
|
||||
/**
|
||||
* Chamber of Propercies instance.
|
||||
* @author Gigi
|
||||
*/
|
||||
public final class ChamberOfProphecies extends AbstractInstance
|
||||
{
|
||||
// NPCs
|
||||
private static final int KAIN_VAN_HALTER = 33979;
|
||||
private static final int VAN_HALTER = 33999;
|
||||
private static final int FERIN = 34001;
|
||||
private static final int GRAIL = 33996;
|
||||
private static final int MYSTERIOUS_WIZARD = 33980;
|
||||
// Misc
|
||||
private static final int TEMPLATE_ID = 255;
|
||||
private static final int PROPHECY_MACHINE = 39540;
|
||||
private static final int ATELIA = 39542;
|
||||
private static final Location FIRST_ROOM_LOC = new Location(-88503, 184754, -10440, 48891);
|
||||
// Monsters
|
||||
private static final int[] ATTACABLE_MONSTERS =
|
||||
{
|
||||
19568, // Sacred Wizard
|
||||
19569, // Sacred Soldier
|
||||
19570, // Sacred Slayer
|
||||
19571, // Makkum
|
||||
19572, // Abyssal Shadow
|
||||
19573, // Secluded Shadow
|
||||
};
|
||||
|
||||
public ChamberOfProphecies()
|
||||
{
|
||||
super(TEMPLATE_ID);
|
||||
addStartNpc(KAIN_VAN_HALTER);
|
||||
addFirstTalkId(KAIN_VAN_HALTER, GRAIL, MYSTERIOUS_WIZARD);
|
||||
addTalkId(KAIN_VAN_HALTER, GRAIL, MYSTERIOUS_WIZARD);
|
||||
addSeeCreatureId(FERIN);
|
||||
addSeeCreatureId(VAN_HALTER);
|
||||
addKillId(ATTACABLE_MONSTERS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
String htmltext = null;
|
||||
final QuestState qs = player.getQuestState(Q10753_WindsOfFateChoices.class.getSimpleName());
|
||||
if (event.equals("enterInstance"))
|
||||
{
|
||||
enterInstance(player, npc, TEMPLATE_ID);
|
||||
if (hasQuestItems(player, PROPHECY_MACHINE))
|
||||
{
|
||||
takeItems(player, PROPHECY_MACHINE, 1);
|
||||
}
|
||||
qs.setCond(16, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
final Instance world = npc.getInstanceWorld();
|
||||
if (isInInstance(world))
|
||||
{
|
||||
switch (event)
|
||||
{
|
||||
case "33979-01.html":
|
||||
case "33996-01.html":
|
||||
case "33980-01.html":
|
||||
case "33980-02.html":
|
||||
{
|
||||
htmltext = event;
|
||||
break;
|
||||
}
|
||||
case "33996-02.html":
|
||||
{
|
||||
world.broadcastPacket(ExShowUsm.USM_Q015_E); // TODO not show usim movie
|
||||
world.despawnGroup("q10753_16_instance_grail");
|
||||
world.spawnGroup("q10753_16_instance_wizard");
|
||||
giveItems(player, ATELIA, 1);
|
||||
showOnScreenMsg(player, NpcStringId.TALK_TO_THE_MYSTERIOUS_WIZARD, ExShowScreenMessage.TOP_CENTER, 6000);
|
||||
htmltext = event;
|
||||
break;
|
||||
}
|
||||
case "33980-03.html":
|
||||
{
|
||||
showOnScreenMsg(player, NpcStringId.THIS_CHOICE_CANNOT_BE_REVERSED, ExShowScreenMessage.TOP_CENTER, 6000);
|
||||
htmltext = event;
|
||||
break;
|
||||
}
|
||||
case "33980-04.html":
|
||||
{
|
||||
showOnScreenMsg(player, NpcStringId.THIS_CHOICE_CANNOT_BE_REVERSED, ExShowScreenMessage.TOP_CENTER, 6000);
|
||||
htmltext = event;
|
||||
break;
|
||||
}
|
||||
case "33980-05.html":
|
||||
{
|
||||
world.spawnGroup("q10753_16_instance_halter_2");
|
||||
world.setStatus(6);
|
||||
startQuestTimer("DESPAWN_WIZARD", 2000, npc, player);
|
||||
htmltext = event;
|
||||
break;
|
||||
}
|
||||
case "status":
|
||||
{
|
||||
if (world.isStatus(0))
|
||||
{
|
||||
htmltext = "33979-01.html";
|
||||
break;
|
||||
}
|
||||
htmltext = "33979-02.html";
|
||||
break;
|
||||
}
|
||||
case "teleport":
|
||||
{
|
||||
player.teleToLocation(FIRST_ROOM_LOC);
|
||||
world.spawnGroup("q10753_16_instance_halter_1_1");
|
||||
world.spawnGroup("wof_room1");
|
||||
break;
|
||||
}
|
||||
case "ATTACK":
|
||||
case "ATTACK1":
|
||||
case "ATTACK2":
|
||||
{
|
||||
npc.setIsRunning(true);
|
||||
((L2Attackable) npc).setCanReturnToSpawnPoint(false);
|
||||
((L2Attackable) npc).setCanStopAttackByTime(false);
|
||||
if (npc.isScriptValue(0) && world.getAliveNpcs(ATTACABLE_MONSTERS).isEmpty())
|
||||
{
|
||||
npc.setTarget(player);
|
||||
npc.getAI().setIntention(CtrlIntention.AI_INTENTION_FOLLOW, player);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (npc.getAI().getIntention() != CtrlIntention.AI_INTENTION_ATTACK)
|
||||
{
|
||||
L2World.getInstance().forEachVisibleObjectInRange(npc, L2Npc.class, 3000, chars ->
|
||||
{
|
||||
if (CommonUtil.contains(ATTACABLE_MONSTERS, chars.getId()))
|
||||
{
|
||||
addAttackDesire(npc, chars);
|
||||
return;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "OPEN_DOOR1":
|
||||
{
|
||||
cancelQuestTimers("ATTACK");
|
||||
world.setStatus(1);
|
||||
world.openCloseDoor(17230102, true);
|
||||
world.spawnGroup("wof_room2");
|
||||
break;
|
||||
}
|
||||
case "OPEN_DOOR2":
|
||||
{
|
||||
cancelQuestTimers("ATTACK1");
|
||||
final int halter = world.getTemplateParameters().getInt("vanhalter");
|
||||
final L2Npc npcss = world.getNpc(halter);
|
||||
startQuestTimer("ATTACK2", 200, npcss, player, true);
|
||||
world.setStatus(3);
|
||||
world.spawnGroup("wof_room3");
|
||||
world.openCloseDoor(17230103, true);
|
||||
break;
|
||||
}
|
||||
case "BROADCAST_TEXT":
|
||||
{
|
||||
npc.setTarget(player);
|
||||
npc.setRunning();
|
||||
npc.getAI().setIntention(CtrlIntention.AI_INTENTION_FOLLOW, player);
|
||||
npc.broadcastPacket(new NpcSay(npc.getObjectId(), ChatType.NPC_GENERAL, npc.getId(), NpcStringId.THAT_GUY_KAIN_HAS_A_SMARMY_FACE));
|
||||
player.sendPacket(new PlaySound(3, "Npcdialog1.apple_quest_7", 0, 0, 0, 0, 0));
|
||||
break;
|
||||
}
|
||||
case "SEY2":
|
||||
{
|
||||
if (npc.getId() == FERIN)
|
||||
{
|
||||
npc.broadcastPacket(new NpcSay(npc.getObjectId(), ChatType.NPC_GENERAL, npc.getId(), NpcStringId.YOU_CAN_T_DIE_HERE_I_DIDN_T_LEARN_RESURRECT_YET));
|
||||
player.sendPacket(new PlaySound(3, "Npcdialog1.apple_quest_4", 0, 0, 0, 0, 0));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "SEY_KAIN":
|
||||
{
|
||||
if (npc.getId() == VAN_HALTER)
|
||||
{
|
||||
startQuestTimer("ATTACK1", 200, npc, player, true);
|
||||
npc.broadcastPacket(new NpcSay(npc.getObjectId(), ChatType.NPC_GENERAL, npc.getId(), NpcStringId.GISELLE_WAS_SUCH_A_SWEET_CHILD));
|
||||
player.sendPacket(new PlaySound(3, "Npcdialog1.holter_quest_1", 0, 0, 0, 0, 0));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "SEY3":
|
||||
{
|
||||
if (npc.getId() == FERIN)
|
||||
{
|
||||
npc.broadcastPacket(new NpcSay(npc.getObjectId(), ChatType.NPC_GENERAL, npc.getId(), NpcStringId.DO_YOU_THINK_I_LL_GROW_TALLER_IF_I_EAT_LOTS_AND_LOTS));
|
||||
player.sendPacket(new PlaySound(3, "Npcdialog1.apple_quest_6", 0, 0, 0, 0, 0));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "SEY_KAIN_1":
|
||||
{
|
||||
if (npc.getId() == VAN_HALTER)
|
||||
{
|
||||
npc.broadcastPacket(new NpcSay(npc.getObjectId(), ChatType.NPC_GENERAL, npc.getId(), NpcStringId.SUCH_MONSTERS_IN_A_PLACE_LIKE_THIS_UNBELIEVABLE));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "SEY_KAIN_2":
|
||||
{
|
||||
if (npc.getId() == VAN_HALTER)
|
||||
{
|
||||
npc.broadcastPacket(new NpcSay(npc.getObjectId(), ChatType.NPC_GENERAL, npc.getId(), NpcStringId.THAT_S_THE_MONSTER_THAT_ATTACKED_FAERON_YOU_RE_OUTMATCHED_HERE_GO_AHEAD_I_LL_CATCH_UP));
|
||||
player.sendPacket(new PlaySound(3, "Npcdialog1.holter_quest_6", 0, 0, 0, 0, 0));
|
||||
startQuestTimer("SEY_KAIN_3", 7000, npc, player);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "SEY4":
|
||||
{
|
||||
if (npc.getId() == FERIN)
|
||||
{
|
||||
npc.broadcastPacket(new NpcSay(npc.getObjectId(), ChatType.NPC_GENERAL, npc.getId(), NpcStringId.GO_NOW_KAIN_CAN_HANDLE_THIS));
|
||||
startQuestTimer("REST", 5000, npc, player);
|
||||
npc.setScriptValue(1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "SEY_KAIN_3":
|
||||
{
|
||||
if (npc.getId() == VAN_HALTER)
|
||||
{
|
||||
npc.broadcastPacket(new NpcSay(npc.getObjectId(), ChatType.NPC_GENERAL, npc.getId(), NpcStringId.LEAVE_THIS_TO_ME_GO));
|
||||
startQuestTimer("SEY_KAIN_4", 1000, npc, player);
|
||||
npc.setScriptValue(1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "REST":
|
||||
{
|
||||
if (npc.getId() == FERIN)
|
||||
{
|
||||
npc.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE, player);
|
||||
cancelQuestTimers("BROADCAST_TEXT");
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "SEY_KAIN_4":
|
||||
{
|
||||
world.setStatus(5);
|
||||
world.spawnGroup("q10753_16_instance_grail");
|
||||
showOnScreenMsg(player, NpcStringId.LEAVE_THIS_PLACE_TO_KAIN_NGO_TO_THE_NEXT_ROOM, ExShowScreenMessage.TOP_CENTER, 6000);
|
||||
world.openCloseDoor(17230104, true);
|
||||
cancelQuestTimers("ATTACK2");
|
||||
npc.getAI().setIntention(CtrlIntention.AI_INTENTION_ACTIVE, player);
|
||||
startQuestTimer("CLOSE", 15000, npc, player);
|
||||
break;
|
||||
}
|
||||
case "CLOSE":
|
||||
{
|
||||
world.openCloseDoor(17230104, false);
|
||||
world.despawnGroup("q10753_16_instance_halter_1_1");
|
||||
world.despawnGroup("wof_room4");
|
||||
break;
|
||||
}
|
||||
case "DESPAWN_WIZARD":
|
||||
{
|
||||
world.despawnGroup("q10753_16_instance_wizard");
|
||||
break;
|
||||
}
|
||||
case "exit":
|
||||
{
|
||||
startQuestTimer("finish", 3000, npc, player);
|
||||
player.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.THIS_DUNGEON_WILL_EXPIRE_IN_S1_MINUTE_S_YOU_WILL_BE_FORCED_OUT_OF_THE_DUNGEON_WHEN_THE_TIME_EXPIRES).addInt((int) 1.0D));
|
||||
qs.setCond(17, true);
|
||||
break;
|
||||
}
|
||||
case "finish":
|
||||
{
|
||||
world.finishInstance(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return htmltext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onKill(L2Npc npc, L2PcInstance player, boolean isSummon)
|
||||
{
|
||||
final Instance world = npc.getInstanceWorld();
|
||||
if (world != null)
|
||||
{
|
||||
switch (world.getStatus())
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
if (world.getAliveNpcs(ATTACABLE_MONSTERS).isEmpty())
|
||||
{
|
||||
final int ferin = world.getTemplateParameters().getInt("ferin");
|
||||
final int halter = world.getTemplateParameters().getInt("vanhalter");
|
||||
final L2Npc npcs = world.getNpc(ferin);
|
||||
final L2Npc npcss = world.getNpc(halter);
|
||||
startQuestTimer("SEY2", 14000, npcs, player);
|
||||
startQuestTimer("SEY_KAIN", 24000, npcss, player);
|
||||
startQuestTimer("OPEN_DOOR1", 5000, npc, player);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
if (world.getAliveNpcs(ATTACABLE_MONSTERS).isEmpty())
|
||||
{
|
||||
world.spawnGroup("wof_room2_1");
|
||||
world.setStatus(2);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
if (world.getAliveNpcs(ATTACABLE_MONSTERS).isEmpty())
|
||||
{
|
||||
final int ferin = world.getTemplateParameters().getInt("ferin");
|
||||
final L2Npc npcs = world.getNpc(ferin);
|
||||
startQuestTimer("SEY3", 8000, npcs, player);
|
||||
startQuestTimer("OPEN_DOOR2", 5000, npc, player);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
if (world.getAliveNpcs(ATTACABLE_MONSTERS).isEmpty())
|
||||
{
|
||||
world.setStatus(4);
|
||||
world.spawnGroup("wof_room3_2");
|
||||
world.openCloseDoor(17230103, false);
|
||||
final int halter = world.getTemplateParameters().getInt("vanhalter");
|
||||
final L2Npc npcss = world.getNpc(halter);
|
||||
startQuestTimer("SEY_KAIN_1", 5000, npcss, player);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 4:
|
||||
{
|
||||
if (world.getAliveNpcs(ATTACABLE_MONSTERS).isEmpty())
|
||||
{
|
||||
world.setStatus(5);
|
||||
world.spawnGroup("wof_room4"); // TODO spawn animation
|
||||
final int halter = world.getTemplateParameters().getInt("vanhalter");
|
||||
final int ferin = world.getTemplateParameters().getInt("ferin");
|
||||
final L2Npc npcss = world.getNpc(halter);
|
||||
final L2Npc npcs = world.getNpc(ferin);
|
||||
startQuestTimer("SEY_KAIN_2", 3000, npcss, player);
|
||||
startQuestTimer("SEY4", 7000, npcs, player);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onFirstTalk(L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
final QuestState qs = player.getQuestState(Q10753_WindsOfFateChoices.class.getSimpleName());
|
||||
String htmltext = null;
|
||||
switch (npc.getId())
|
||||
{
|
||||
case KAIN_VAN_HALTER:
|
||||
{
|
||||
if ((qs != null) && qs.isCond(16))
|
||||
{
|
||||
htmltext = "33979.html";
|
||||
}
|
||||
break;
|
||||
}
|
||||
case GRAIL:
|
||||
{
|
||||
htmltext = "33996.html";
|
||||
break;
|
||||
}
|
||||
case MYSTERIOUS_WIZARD:
|
||||
{
|
||||
if ((qs != null) && qs.isCond(16))
|
||||
{
|
||||
htmltext = "33980.html";
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return htmltext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSeeCreature(L2Npc npc, L2Character creature, boolean isSummon)
|
||||
{
|
||||
final Instance world = npc.getInstanceWorld();
|
||||
if (world != null)
|
||||
{
|
||||
switch (npc.getId())
|
||||
{
|
||||
case FERIN:
|
||||
{
|
||||
if (creature.isPlayer() && !creature.isDead() && npc.isScriptValue(0))
|
||||
{
|
||||
startQuestTimer("BROADCAST_TEXT", 12000, npc, (L2PcInstance) creature);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case VAN_HALTER:
|
||||
{
|
||||
if (creature.isPlayer() && !creature.isDead() && world.isStatus(0))
|
||||
{
|
||||
startQuestTimer("ATTACK", 2000, npc, (L2PcInstance) creature, true);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return super.onSeeCreature(npc, creature, isSummon);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new ChamberOfProphecies();
|
||||
}
|
||||
}
|
@@ -1,450 +0,0 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package instances.ChambersOfDelusion;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.logging.Level;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
import com.l2jmobius.Config;
|
||||
import com.l2jmobius.commons.util.CommonUtil;
|
||||
import com.l2jmobius.gameserver.ThreadPoolManager;
|
||||
import com.l2jmobius.gameserver.enums.ChatType;
|
||||
import com.l2jmobius.gameserver.model.L2Object;
|
||||
import com.l2jmobius.gameserver.model.L2World;
|
||||
import com.l2jmobius.gameserver.model.Location;
|
||||
import com.l2jmobius.gameserver.model.StatsSet;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.holders.SkillHolder;
|
||||
import com.l2jmobius.gameserver.model.instancezone.Instance;
|
||||
import com.l2jmobius.gameserver.model.skills.Skill;
|
||||
import com.l2jmobius.gameserver.network.NpcStringId;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.Earthquake;
|
||||
|
||||
import instances.AbstractInstance;
|
||||
|
||||
/**
|
||||
* Chambers of Delusion.
|
||||
* @author GKR
|
||||
*/
|
||||
public final class ChamberOfDelusion extends AbstractInstance
|
||||
{
|
||||
// NPCs
|
||||
private static final Map<Integer, Integer> ENTRANCE_GATEKEEPER = new HashMap<>();
|
||||
private static final int[] ROOM_GATEKEEPERS = IntStream.range(32664, 32702).toArray();
|
||||
private static final int[] AENKINEL =
|
||||
{
|
||||
25690, // East
|
||||
25691, // West
|
||||
25692, // South
|
||||
25693, // North
|
||||
25694, // Square
|
||||
25695, // Tower
|
||||
};
|
||||
private static final int[] BOX =
|
||||
{
|
||||
18838, // East, West, South, North
|
||||
18820, // Square
|
||||
18823, // Tower
|
||||
};
|
||||
// Items
|
||||
private static final int ENRIA = 4042;
|
||||
private static final int ASOFE = 4043;
|
||||
private static final int THONS = 4044;
|
||||
private static final int LEONARD = 9628;
|
||||
private static final int DELUSION_MARK = 15311;
|
||||
// Skills
|
||||
private static final SkillHolder SUCCESS_SKILL = new SkillHolder(5758, 1);
|
||||
private static final SkillHolder FAIL_SKILL = new SkillHolder(5376, 4);
|
||||
// Timers
|
||||
private static final int ROOM_CHANGE_INTERVAL = 480; // 8 min
|
||||
private static final int ROOM_CHANGE_RANDOM_TIME = 120; // 2 min
|
||||
|
||||
static
|
||||
{
|
||||
ENTRANCE_GATEKEEPER.put(32658, 127); // East
|
||||
ENTRANCE_GATEKEEPER.put(32659, 128); // West
|
||||
ENTRANCE_GATEKEEPER.put(32660, 129); // South
|
||||
ENTRANCE_GATEKEEPER.put(32661, 130); // North
|
||||
ENTRANCE_GATEKEEPER.put(32662, 131); // Square
|
||||
ENTRANCE_GATEKEEPER.put(32663, 132); // Tower
|
||||
}
|
||||
|
||||
public ChamberOfDelusion()
|
||||
{
|
||||
super(ENTRANCE_GATEKEEPER.values().stream().mapToInt(Integer::valueOf).toArray());
|
||||
addStartNpc(ENTRANCE_GATEKEEPER.keySet());
|
||||
addStartNpc(ROOM_GATEKEEPERS);
|
||||
addTalkId(ENTRANCE_GATEKEEPER.keySet());
|
||||
addTalkId(ROOM_GATEKEEPERS);
|
||||
addKillId(AENKINEL);
|
||||
addAttackId(BOX);
|
||||
addSpellFinishedId(BOX);
|
||||
addEventReceivedId(BOX);
|
||||
addInstanceCreatedId(ENTRANCE_GATEKEEPER.values());
|
||||
addInstanceDestroyId(ENTRANCE_GATEKEEPER.values());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInstanceCreated(Instance instance, L2PcInstance player)
|
||||
{
|
||||
// Choose start room
|
||||
changeRoom(instance);
|
||||
|
||||
// Start banish task
|
||||
final ScheduledFuture<?> banishTask = ThreadPoolManager.getInstance().scheduleGeneralAtFixedRate(() ->
|
||||
{
|
||||
if (instance.getRemainingTime() < 60000)
|
||||
{
|
||||
final ScheduledFuture<?> task = instance.getParameters().getObject("banishTask", ScheduledFuture.class);
|
||||
task.cancel(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int objId : instance.getAllowed())
|
||||
{
|
||||
final L2PcInstance pl = L2World.getInstance().getPlayer(objId);
|
||||
if ((pl != null) && pl.isOnline() && !pl.isInParty())
|
||||
{
|
||||
instance.finishInstance(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}, 60000, 60000);
|
||||
instance.setParameter("banishTask", banishTask);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInstanceDestroy(Instance instance)
|
||||
{
|
||||
// Stop room change task
|
||||
stopRoomChangeTask(instance);
|
||||
|
||||
// Stop banish task
|
||||
final ScheduledFuture<?> banish = instance.getParameters().getObject("banishTask", ScheduledFuture.class);
|
||||
if (banish != null)
|
||||
{
|
||||
banish.cancel(true);
|
||||
instance.setParameter("banishTask", null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onEnter(L2PcInstance player, Instance instance, boolean firstEnter)
|
||||
{
|
||||
// Teleport player to instance
|
||||
super.onEnter(player, instance, firstEnter);
|
||||
|
||||
// Take items
|
||||
if (firstEnter)
|
||||
{
|
||||
if (hasQuestItems(player, DELUSION_MARK))
|
||||
{
|
||||
takeItems(player, DELUSION_MARK, -1);
|
||||
}
|
||||
|
||||
if (player.getParty().isLeader(player))
|
||||
{
|
||||
giveItems(player, DELUSION_MARK, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void teleportPlayerIn(L2PcInstance player, Instance instance)
|
||||
{
|
||||
final int room = instance.getParameters().getInt("currentRoom");
|
||||
final Location loc = instance.getEnterLocations().get(room);
|
||||
player.teleToLocation(loc, instance);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
String htmltext = null;
|
||||
|
||||
final Instance world = npc.getInstanceWorld();
|
||||
if ((player != null) && (world != null) && CommonUtil.contains(ROOM_GATEKEEPERS, npc.getId()))
|
||||
{
|
||||
switch (event)
|
||||
{
|
||||
case "next_room":
|
||||
{
|
||||
if (player.isInParty())
|
||||
{
|
||||
htmltext = "no_party.html";
|
||||
}
|
||||
else if (player.getParty().isLeader(player))
|
||||
{
|
||||
htmltext = "no_leader.html";
|
||||
}
|
||||
else if (!hasQuestItems(player, DELUSION_MARK))
|
||||
{
|
||||
htmltext = "no_item.html";
|
||||
}
|
||||
else
|
||||
{
|
||||
takeItems(player, DELUSION_MARK, 1);
|
||||
stopRoomChangeTask(world);
|
||||
changeRoom(world);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "go_out":
|
||||
{
|
||||
if (player.isInParty())
|
||||
{
|
||||
htmltext = "no_party.html";
|
||||
}
|
||||
else if (player.getParty().isLeader(player))
|
||||
{
|
||||
htmltext = "no_leader.html";
|
||||
}
|
||||
else
|
||||
{
|
||||
world.finishInstance(0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "look_party":
|
||||
{
|
||||
if (player.isInParty() && world.isAllowed(player))
|
||||
{
|
||||
teleportPlayerIn(player, world);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return htmltext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onTalk(L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
final int npcId = npc.getId();
|
||||
if (ENTRANCE_GATEKEEPER.containsKey(npcId))
|
||||
{
|
||||
enterInstance(player, npc, ENTRANCE_GATEKEEPER.get(npcId));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSpellFinished(L2Npc npc, L2PcInstance player, Skill skill)
|
||||
{
|
||||
if (!npc.isDead() && CommonUtil.contains(BOX, npc.getId()) && ((skill.getId() == FAIL_SKILL.getSkillId()) || (skill.getId() == SUCCESS_SKILL.getSkillId())))
|
||||
{
|
||||
npc.doDie(player);
|
||||
}
|
||||
return super.onSpellFinished(npc, player, skill);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onEventReceived(String eventName, L2Npc sender, L2Npc receiver, L2Object reference)
|
||||
{
|
||||
switch (eventName)
|
||||
{
|
||||
case "SCE_LUCKY":
|
||||
receiver.setBusy(true);
|
||||
receiver.doCast(SUCCESS_SKILL.getSkill());
|
||||
break;
|
||||
case "SCE_DREAM_FIRE_IN_THE_HOLE":
|
||||
receiver.setBusy(true);
|
||||
receiver.doCast(FAIL_SKILL.getSkill());
|
||||
break;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAttack(L2Npc npc, L2PcInstance attacker, int damage, boolean isPet, Skill skill)
|
||||
{
|
||||
if (!npc.isBusy() && (npc.getCurrentHp() < (npc.getMaxHp() / 10)))
|
||||
{
|
||||
npc.setBusy(true);
|
||||
if (getRandom(100) < 25) // 25% chance to reward
|
||||
{
|
||||
if (getRandom(100) < 33)
|
||||
{
|
||||
npc.dropItem(attacker, ENRIA, (int) (3 * Config.RATE_QUEST_DROP));
|
||||
}
|
||||
if (getRandom(100) < 50)
|
||||
{
|
||||
npc.dropItem(attacker, THONS, (int) (4 * Config.RATE_QUEST_DROP));
|
||||
}
|
||||
if (getRandom(100) < 50)
|
||||
{
|
||||
npc.dropItem(attacker, ASOFE, (int) (4 * Config.RATE_QUEST_DROP));
|
||||
}
|
||||
if (getRandom(100) < 16)
|
||||
{
|
||||
npc.dropItem(attacker, LEONARD, (int) (2 * Config.RATE_QUEST_DROP));
|
||||
}
|
||||
npc.broadcastEvent("SCE_LUCKY", 2000, null);
|
||||
npc.doCast(SUCCESS_SKILL.getSkill());
|
||||
}
|
||||
else
|
||||
{
|
||||
npc.broadcastEvent("SCE_DREAM_FIRE_IN_THE_HOLE", 2000, null);
|
||||
}
|
||||
}
|
||||
return super.onAttack(npc, attacker, damage, isPet, skill);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onKill(L2Npc npc, L2PcInstance player, boolean isPet)
|
||||
{
|
||||
final Instance world = player.getInstanceWorld();
|
||||
if (world != null)
|
||||
{
|
||||
if (isBigChamber(world))
|
||||
{
|
||||
world.setReenterTime();
|
||||
if (world.getRemainingTime() > (Config.INSTANCE_FINISH_TIME * 60000))
|
||||
{
|
||||
world.finishInstance();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
stopRoomChangeTask(world);
|
||||
scheduleRoomChange(world, true);
|
||||
}
|
||||
world.spawnGroup("boxes");
|
||||
}
|
||||
return super.onKill(npc, player, isPet);
|
||||
}
|
||||
|
||||
private boolean isBigChamber(Instance world)
|
||||
{
|
||||
return world.getTemplateParameters().getBoolean("isBigRoom");
|
||||
}
|
||||
|
||||
private boolean isBossRoom(Instance world, int room)
|
||||
{
|
||||
return room == (world.getEnterLocations().size() - 1);
|
||||
}
|
||||
|
||||
protected void changeRoom(Instance world)
|
||||
{
|
||||
final StatsSet params = world.getParameters();
|
||||
final List<Location> locations = world.getEnterLocations();
|
||||
|
||||
int newRoom = params.getInt("currentRoom", 0);
|
||||
if (isBigChamber(world))
|
||||
{
|
||||
// Do nothing, if there are raid room of Sqare or Tower Chamber
|
||||
if (isBossRoom(world, newRoom))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Teleport to raid room 10 min or lesser before instance end time for Tower and Square Chambers
|
||||
else if (world.getRemainingTime() < 600000)
|
||||
{
|
||||
newRoom = locations.size() - 1;
|
||||
}
|
||||
}
|
||||
// 10% chance for teleport to raid room if not here already for Northern, Southern, Western and Eastern Chambers
|
||||
else if (!isBossRoom(world, newRoom) && (getRandom(100) < 10))
|
||||
{
|
||||
newRoom = locations.size() - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// otherwise teleport to another room, except current
|
||||
while (newRoom == params.getInt("currentRoom", 0))
|
||||
{
|
||||
newRoom = getRandom(locations.size() - 1);
|
||||
}
|
||||
}
|
||||
world.setParameter("currentRoom", newRoom);
|
||||
|
||||
// Teleport players into new room
|
||||
world.getPlayers().forEach(p -> teleportPlayerIn(p, world));
|
||||
|
||||
// Do not schedule room change for Square and Tower Chambers, if raid room is reached
|
||||
if (isBigChamber(world) && isBossRoom(world, newRoom))
|
||||
{
|
||||
// Add 20 min to instance time if raid room is reached
|
||||
world.setDuration((int) (TimeUnit.MILLISECONDS.toMinutes(world.getRemainingTime() + 1200000)));
|
||||
|
||||
// Broadcast instance duration change (NPC message)
|
||||
final int raidGatekeeper = world.getTemplateParameters().getInt("raidGatekeeper");
|
||||
final L2Npc gatekeeper = world.getNpc(raidGatekeeper);
|
||||
if (gatekeeper != null)
|
||||
{
|
||||
gatekeeper.broadcastSay(ChatType.NPC_GENERAL, NpcStringId.MINUTES_ARE_ADDED_TO_THE_REMAINING_TIME_IN_THE_INSTANT_ZONE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
scheduleRoomChange(world, false);
|
||||
}
|
||||
}
|
||||
|
||||
protected void scheduleRoomChange(Instance world, boolean bossRoom)
|
||||
{
|
||||
// Schedule next room change only if remaining time is enough
|
||||
final long nextInterval = (bossRoom) ? 60000L : (ROOM_CHANGE_INTERVAL + getRandom(ROOM_CHANGE_RANDOM_TIME)) * 1000L;
|
||||
if (world.getRemainingTime() > nextInterval)
|
||||
{
|
||||
final ScheduledFuture<?> roomChangeTask = ThreadPoolManager.getInstance().scheduleGeneral(() ->
|
||||
{
|
||||
try
|
||||
{
|
||||
// Send earthquake packet
|
||||
for (L2PcInstance player : world.getPlayers())
|
||||
{
|
||||
player.sendPacket(new Earthquake(player, 20, 10));
|
||||
}
|
||||
// Wait for a while
|
||||
Thread.sleep(5000);
|
||||
// Change room
|
||||
changeRoom(world);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_log.log(Level.WARNING, "Error occured in room change task: ", e);
|
||||
}
|
||||
}, nextInterval - 5000);
|
||||
world.setParameter("roomChangeTask", roomChangeTask);
|
||||
}
|
||||
}
|
||||
|
||||
protected void stopRoomChangeTask(Instance world)
|
||||
{
|
||||
final ScheduledFuture<?> task = world.getParameters().getObject("roomChangeTask", ScheduledFuture.class);
|
||||
if (task != null)
|
||||
{
|
||||
task.cancel(true);
|
||||
world.setParameter("roomChangeTask", null);
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new ChamberOfDelusion();
|
||||
}
|
||||
}
|
@@ -1,3 +0,0 @@
|
||||
<html><body>Manager:<br>
|
||||
You have already used an opportunity. There are no more.
|
||||
</body></html>
|
@@ -1,3 +0,0 @@
|
||||
<html><body>Manager:<br>
|
||||
You're not a party leader. Please bring the party leader here.
|
||||
</body></html>
|
@@ -1,3 +0,0 @@
|
||||
<html><body>Manager:<br>
|
||||
You're not a member of a party. Please join one quickly.
|
||||
</body></html>
|
@@ -1,444 +0,0 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package instances.DarkCloudMansion;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.l2jmobius.commons.util.CommonUtil;
|
||||
import com.l2jmobius.gameserver.enums.ChatType;
|
||||
import com.l2jmobius.gameserver.model.StatsSet;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.holders.SkillHolder;
|
||||
import com.l2jmobius.gameserver.model.instancezone.Instance;
|
||||
import com.l2jmobius.gameserver.network.NpcStringId;
|
||||
|
||||
import instances.AbstractInstance;
|
||||
|
||||
/**
|
||||
* Dark Cloud Mansion instance.
|
||||
* @author malyelfik
|
||||
*/
|
||||
public final class DarkCloudMansion extends AbstractInstance
|
||||
{
|
||||
// NPCs
|
||||
private static final int YIYEN = 32282;
|
||||
private static final int FAITH = 32288; // Symbol of Faith
|
||||
private static final int ADVERSITY = 32289; // Symbol of Adversity
|
||||
private static final int ADVENTURE = 32290; // Symbol of Adventure
|
||||
private static final int TRUTH = 32291; // Symbol of Truth
|
||||
private static final int MONOLITH = 32324; // Black Stone Monolith
|
||||
private static final int COLUMN = 22402; // Shadow Column
|
||||
// Mobs
|
||||
private static final int PARME_HEALER = 22400;
|
||||
private static final int[] BELETH_SUBORDINATE =
|
||||
{
|
||||
22272,
|
||||
22273,
|
||||
22274
|
||||
};
|
||||
private static final int[] MONOLITH_PRIVATES =
|
||||
{
|
||||
18369,
|
||||
18370
|
||||
};
|
||||
private static final int[] BELETH_SAMPLE =
|
||||
{
|
||||
18371,
|
||||
18372,
|
||||
18373,
|
||||
18374,
|
||||
18375,
|
||||
18376,
|
||||
18377
|
||||
};
|
||||
// Skill
|
||||
private static final SkillHolder INCARNATION = new SkillHolder(5441, 1);
|
||||
// Items
|
||||
private static final int CC = 9690; // Contaminated Crystal
|
||||
// Doors
|
||||
private static final int START_DOOR = 24230001; // Starting Room
|
||||
private static final int ROOM_A_DOOR = 24230002; // First Room
|
||||
private static final int ROOM_B_DOOR = 24230005; // Second Room
|
||||
private static final int ROOM_C_DOOR = 24230003; // Third Room
|
||||
private static final int ROOM_D_DOOR = 24230004; // Forth Room
|
||||
private static final int ROOM_E_DOOR = 24230006; // Fifth Room
|
||||
// Messages
|
||||
private static final NpcStringId[] SPAWN_CHAT =
|
||||
{
|
||||
NpcStringId.I_M_THE_REAL_ONE,
|
||||
NpcStringId.PICK_ME,
|
||||
NpcStringId.TRUST_ME,
|
||||
NpcStringId.NOT_THAT_DUDE_I_M_THE_REAL_ONE,
|
||||
NpcStringId.DON_T_BE_FOOLED_DON_T_BE_FOOLED_I_M_THE_REAL_ONE
|
||||
};
|
||||
private static final NpcStringId[] DECAY_CHAT =
|
||||
{
|
||||
NpcStringId.I_M_THE_REAL_ONE_PHEW,
|
||||
NpcStringId.CAN_T_YOU_EVEN_FIND_OUT,
|
||||
NpcStringId.FIND_ME
|
||||
};
|
||||
private static final NpcStringId[] SUCCESS_CHAT =
|
||||
{
|
||||
NpcStringId.HUH_HOW_DID_YOU_KNOW_IT_WAS_ME,
|
||||
NpcStringId.EXCELLENT_CHOICE_TEEHEE,
|
||||
NpcStringId.YOU_VE_DONE_WELL,
|
||||
NpcStringId.OH_VERY_SENSIBLE
|
||||
};
|
||||
private static final NpcStringId[] FAIL_CHAT =
|
||||
{
|
||||
NpcStringId.YOU_VE_BEEN_FOOLED,
|
||||
NpcStringId.SORRY_BUT_I_M_THE_FAKE_ONE
|
||||
};
|
||||
|
||||
// Misc
|
||||
private static final int TEMPLATE_ID = 9;
|
||||
|
||||
public DarkCloudMansion()
|
||||
{
|
||||
super(TEMPLATE_ID);
|
||||
addStartNpc(YIYEN);
|
||||
addFirstTalkId(MONOLITH, TRUTH, FAITH, ADVERSITY, ADVENTURE);
|
||||
addTalkId(YIYEN, TRUTH);
|
||||
addAttackId(COLUMN, PARME_HEALER);
|
||||
addAttackId(BELETH_SAMPLE);
|
||||
addKillId(COLUMN, PARME_HEALER);
|
||||
addKillId(BELETH_SAMPLE);
|
||||
addKillId(BELETH_SUBORDINATE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
final Instance world = npc.getInstanceWorld();
|
||||
if (world != null)
|
||||
{
|
||||
switch (event)
|
||||
{
|
||||
case "DELETE_ONE":
|
||||
npc.deleteMe();
|
||||
break;
|
||||
case "DELETE":
|
||||
{
|
||||
world.getNpcs(BELETH_SAMPLE).stream().filter(n -> n != npc).forEach(L2Npc::deleteMe);
|
||||
world.setParameter("blocked", false);
|
||||
spawnRoomE(world);
|
||||
break;
|
||||
}
|
||||
case "CHAT":
|
||||
world.getNpcs(BELETH_SAMPLE).stream().filter(n -> n.isScriptValue(1)).forEach(n -> n.broadcastSay(ChatType.NPC_GENERAL, DECAY_CHAT[getRandom(DECAY_CHAT.length)]));
|
||||
break;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onTalk(L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
if (npc.getId() == YIYEN)
|
||||
{
|
||||
enterInstance(player, npc, TEMPLATE_ID);
|
||||
}
|
||||
else
|
||||
{
|
||||
final Instance world = npc.getInstanceWorld();
|
||||
if (world != null)
|
||||
{
|
||||
teleportPlayerOut(player, world);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onFirstTalk(L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
final Instance world = npc.getInstanceWorld();
|
||||
if (world != null)
|
||||
{
|
||||
switch (npc.getId())
|
||||
{
|
||||
case FAITH:
|
||||
{
|
||||
world.openCloseDoor(ROOM_A_DOOR, true);
|
||||
npc.showChatWindow(player);
|
||||
break;
|
||||
}
|
||||
case MONOLITH:
|
||||
{
|
||||
if (world.isStatus(4) && !npc.isScriptValue(-1))
|
||||
{
|
||||
int current = world.getParameters().getInt("current", 0);
|
||||
if (npc.isScriptValue(current))
|
||||
{
|
||||
npc.setScriptValue(-1);
|
||||
npc.doCast(INCARNATION.getSkill());
|
||||
world.setParameter("current", ++current);
|
||||
|
||||
if (current == 6)
|
||||
{
|
||||
world.setStatus(5);
|
||||
world.spawnGroup("roomBClear");
|
||||
world.spawnGroup("hall");
|
||||
world.getNpcs(MONOLITH).forEach(L2Npc::deleteMe);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
addSpawn(MONOLITH_PRIVATES[getRandom(MONOLITH_PRIVATES.length)], npc, false, 0, false, world.getId());
|
||||
}
|
||||
world.openCloseDoor(ROOM_B_DOOR, false);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ADVERSITY:
|
||||
{
|
||||
world.openCloseDoor(ROOM_B_DOOR, true);
|
||||
npc.showChatWindow(player);
|
||||
break;
|
||||
}
|
||||
case ADVENTURE:
|
||||
{
|
||||
if (world.isStatus(7))
|
||||
{
|
||||
world.spawnGroup("roomC").forEach(n -> n.setScriptValue(8));
|
||||
world.setStatus(8);
|
||||
world.openCloseDoor(ROOM_D_DOOR, true);
|
||||
}
|
||||
npc.showChatWindow(player);
|
||||
break;
|
||||
}
|
||||
case TRUTH:
|
||||
{
|
||||
if (!hasQuestItems(player, CC))
|
||||
{
|
||||
giveItems(player, CC, 1);
|
||||
}
|
||||
npc.showChatWindow(player);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAttack(L2Npc npc, L2PcInstance attacker, int damage, boolean isSummon)
|
||||
{
|
||||
final Instance world = npc.getInstanceWorld();
|
||||
if (world != null)
|
||||
{
|
||||
switch (npc.getId())
|
||||
{
|
||||
case PARME_HEALER:
|
||||
{
|
||||
if (world.isStatus(2) && (attacker.getY() < 179986))
|
||||
{
|
||||
world.openCloseDoor(ROOM_A_DOOR, false);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case COLUMN:
|
||||
{
|
||||
if (world.isStatus(7))
|
||||
{
|
||||
world.openCloseDoor(ROOM_D_DOOR, false);
|
||||
if (npc.isHpBlocked() && (getRandom(100) < 12))
|
||||
{
|
||||
addSpawn(BELETH_SUBORDINATE[getRandom(BELETH_SUBORDINATE.length)], npc, false, 0, false, world.getId());
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
if (world.isStatus(9))
|
||||
{
|
||||
handleRoomE(world, npc);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return super.onAttack(npc, attacker, damage, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onKill(L2Npc npc, L2PcInstance player, boolean isSummon)
|
||||
{
|
||||
final Instance world = npc.getInstanceWorld();
|
||||
if (world != null)
|
||||
{
|
||||
switch (world.getStatus())
|
||||
{
|
||||
case 0: // Start room
|
||||
{
|
||||
if (world.getAliveNpcs().isEmpty())
|
||||
{
|
||||
world.setStatus(1);
|
||||
world.spawnGroup("hall");
|
||||
world.openCloseDoor(START_DOOR, true);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 1: // Hall
|
||||
{
|
||||
if (world.getAliveNpcs().isEmpty())
|
||||
{
|
||||
world.setStatus(2);
|
||||
world.spawnGroup("roomA");
|
||||
world.openCloseDoor(ROOM_A_DOOR, true);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 2: // Room A - cleared
|
||||
{
|
||||
if (world.getAliveNpcs().isEmpty())
|
||||
{
|
||||
world.setStatus(3);
|
||||
world.spawnGroup("roomAClear");
|
||||
world.spawnGroup("hall");
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 3: // Hall
|
||||
{
|
||||
if (world.getAliveNpcs(BELETH_SUBORDINATE).isEmpty())
|
||||
{
|
||||
world.setStatus(4);
|
||||
world.openCloseDoor(ROOM_B_DOOR, true);
|
||||
|
||||
int current = 0;
|
||||
final List<L2Npc> desks = world.spawnGroup("roomB");
|
||||
while (!desks.isEmpty())
|
||||
{
|
||||
final L2Npc desk = desks.remove(getRandom(desks.size()));
|
||||
desk.setScriptValue(current++);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 5: // Hall
|
||||
{
|
||||
if (world.getAliveNpcs(BELETH_SUBORDINATE).isEmpty())
|
||||
{
|
||||
world.setStatus(6);
|
||||
world.spawnGroup("roomC");
|
||||
world.openCloseDoor(ROOM_C_DOOR, true);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 6: // Room C
|
||||
{
|
||||
if (world.getAliveNpcs(BELETH_SUBORDINATE).isEmpty())
|
||||
{
|
||||
world.setStatus(7);
|
||||
world.spawnGroup("roomD");
|
||||
world.openCloseDoor(ROOM_D_DOOR, true);
|
||||
for (int i = 1; i <= 7; i++)
|
||||
{
|
||||
final List<L2Npc> row = world.spawnGroup("roomD" + i);
|
||||
for (int x = 0; x < 2; x++)
|
||||
{
|
||||
final L2Npc col = row.remove(getRandom(row.size()));
|
||||
col.setIsInvul(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 8: // Room C
|
||||
{
|
||||
final long roomClear = world.getAliveNpcs(BELETH_SUBORDINATE).stream().filter(n -> n.isScriptValue(8)).count();
|
||||
if (roomClear == 0)
|
||||
{
|
||||
world.setStatus(9);
|
||||
world.openCloseDoor(ROOM_E_DOOR, true);
|
||||
spawnRoomE(world);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 9:
|
||||
{
|
||||
handleRoomE(world, npc);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void spawnRoomE(Instance world)
|
||||
{
|
||||
final List<L2Npc> npcs = world.spawnGroup("roomE");
|
||||
for (L2Npc n : npcs)
|
||||
{
|
||||
n.broadcastSay(ChatType.NPC_GENERAL, SPAWN_CHAT[getRandom(SPAWN_CHAT.length)]);
|
||||
}
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
final L2Npc n = npcs.remove(getRandom(npcs.size()));
|
||||
n.setScriptValue(1);
|
||||
}
|
||||
}
|
||||
|
||||
private void handleRoomE(Instance world, L2Npc npc)
|
||||
{
|
||||
if (CommonUtil.contains(BELETH_SAMPLE, npc.getId()))
|
||||
{
|
||||
final StatsSet params = world.getParameters();
|
||||
if (!params.getBoolean("blocked", false))
|
||||
{
|
||||
if (npc.isScriptValue(1))
|
||||
{
|
||||
final int found = params.getInt("found", 0) + 1;
|
||||
world.setParameter("found", found);
|
||||
|
||||
npc.setScriptValue(-1);
|
||||
npc.broadcastSay(ChatType.NPC_GENERAL, SUCCESS_CHAT[getRandom(SUCCESS_CHAT.length)]);
|
||||
|
||||
if (found != 3)
|
||||
{
|
||||
startQuestTimer("DELETE_ONE", 1500, npc, null);
|
||||
}
|
||||
else
|
||||
{
|
||||
world.setStatus(10);
|
||||
world.getNpcs().forEach(L2Npc::deleteMe);
|
||||
world.spawnGroup("roomEClear");
|
||||
}
|
||||
}
|
||||
else if (!npc.isScriptValue(-1))
|
||||
{
|
||||
world.setParameter("blocked", true);
|
||||
world.setParameter("found", 0);
|
||||
|
||||
npc.broadcastSay(ChatType.NPC_GENERAL, FAIL_CHAT[getRandom(FAIL_CHAT.length)]);
|
||||
npc.setScriptValue(-1);
|
||||
startQuestTimer("CHAT", 4000, npc, null);
|
||||
startQuestTimer("DELETE", 4500, npc, null);
|
||||
}
|
||||
world.openCloseDoor(ROOM_E_DOOR, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new DarkCloudMansion();
|
||||
}
|
||||
}
|
@@ -1,4 +0,0 @@
|
||||
<html><body>Priest Cerenas:<br>
|
||||
You are learning, adventurer. I will pray for your illumination.<br>
|
||||
(You have already completed this quest.)
|
||||
</body></html>
|
@@ -1,3 +0,0 @@
|
||||
<html><body>Priest Cerenas:<br>
|
||||
No, no, this will not do. You have not proven yourself worthy. (You must have started the "Soul Testing" quest to enter.)
|
||||
</body></html>
|
@@ -1,5 +0,0 @@
|
||||
<html><body>Eva's Avatar:<br>
|
||||
The Goddess of Destruction has finally resurrected! The energy of water continues to be contaminated....<br>
|
||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest EvasHiddenSpace exitInstance">Back</Button>
|
||||
<Button ALIGN=LEFT ICON="QUEST" action="bypass -h npc_%objectId%_Quest">Quest</Button>
|
||||
</body></html>
|
@@ -1,93 +0,0 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package instances.EvasHiddenSpace;
|
||||
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.instancezone.Instance;
|
||||
import com.l2jmobius.gameserver.model.quest.QuestState;
|
||||
|
||||
import instances.AbstractInstance;
|
||||
import quests.Q10369_NoblesseSoulTesting.Q10369_NoblesseSoulTesting;
|
||||
|
||||
/**
|
||||
* Eva's Hidden Space instance zone.
|
||||
* @author Gladicek, St3eT
|
||||
*/
|
||||
public final class EvasHiddenSpace extends AbstractInstance
|
||||
{
|
||||
// NPCs
|
||||
private static final int CERENAS = 31281;
|
||||
private static final int EVAS_AVATAR = 33686;
|
||||
// Misc
|
||||
private static final int TEMPLATE_ID = 217;
|
||||
|
||||
public EvasHiddenSpace()
|
||||
{
|
||||
super(TEMPLATE_ID);
|
||||
addStartNpc(CERENAS);
|
||||
addTalkId(CERENAS, EVAS_AVATAR);
|
||||
addFirstTalkId(EVAS_AVATAR);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
String htmltext = null;
|
||||
|
||||
final QuestState qs = player.getQuestState(Q10369_NoblesseSoulTesting.class.getSimpleName());
|
||||
|
||||
if (event.equals("enterInstance"))
|
||||
{
|
||||
if ((qs != null) && qs.isStarted())
|
||||
{
|
||||
enterInstance(player, npc, TEMPLATE_ID);
|
||||
|
||||
if (qs.isCond(14))
|
||||
{
|
||||
qs.setCond(15);
|
||||
}
|
||||
else if (qs.isCond(17))
|
||||
{
|
||||
qs.setCond(18);
|
||||
}
|
||||
}
|
||||
else if ((qs != null) && qs.isCompleted())
|
||||
{
|
||||
htmltext = "31281-01.html";
|
||||
}
|
||||
else
|
||||
{
|
||||
htmltext = "31281.html";
|
||||
}
|
||||
}
|
||||
else if (event.equals("exitInstance"))
|
||||
{
|
||||
final Instance world = getPlayerInstance(player);
|
||||
if (world != null)
|
||||
{
|
||||
teleportPlayerOut(player, world);
|
||||
}
|
||||
}
|
||||
return htmltext;
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new EvasHiddenSpace();
|
||||
}
|
||||
}
|
@@ -1,3 +0,0 @@
|
||||
<html><body>Aden Vanguard Member:<br>
|
||||
Go ahead and speak with the Captain and help the Aden Vanguard out!
|
||||
</body></html>
|
@@ -1,4 +0,0 @@
|
||||
<html><body>Aden Vanguard Captain Adolph:<br>
|
||||
You've caught me resting after a particularly tough battle. So, you're the soldier Orven has sent? Good! You can help my squad with that never-ending stream of monsters. Got any questions?<br>
|
||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest EvilIncubator 33170-02.html">"I'm ready."</Button>
|
||||
</body></html>
|
@@ -1,4 +0,0 @@
|
||||
<html><body>Aden Vanguard Captain Adolph:<br>
|
||||
See my subordinates there? They are elite veterans who have known many victories. Two of them will wait here, while you, me, and the other two enter the enemy base.<br>
|
||||
Go and talk to my squad and pick out two you'd like to have at your side.
|
||||
</body></html>
|
@@ -1,6 +0,0 @@
|
||||
<html><body>Aden Vanguard Captain Adolph:<br>
|
||||
I see you've chosen strong allies.<br1>
|
||||
This battle will be fierce, and if you see me go down, do not hesitate to run. We can't afford to lose any more people, and if that happens, you will need time to regroup.<br1>
|
||||
Now, I hope you're ready to take this fight to the enemy, because we're going into their base.<br>
|
||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest EvilIncubator teamSelected">"I'm ready."</Button>
|
||||
</body></html>
|
@@ -1,3 +0,0 @@
|
||||
<html><body>Aden Vanguard Captain Adolph:<br>
|
||||
Focus on the enemies in front of you. Looking away in battle is suicide.
|
||||
</body></html>
|
@@ -1,5 +0,0 @@
|
||||
<html><body>Aden Vanguard Captain Adolph:<br>
|
||||
Phew! What a fight, eh? Now, there is a boss beyond that door, so let's take a short break. We must call him out and defeat him before we can leave.<br>
|
||||
I was worried, but I think I will be able to bring out your full potential. I will lend you this temporarily.<br>
|
||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest EvilIncubator giveItem">"Thank you."</Button>
|
||||
</body></html>
|
@@ -1,4 +0,0 @@
|
||||
<html><body>Aden Vanguard Captain Adolph:<br>
|
||||
The kingdom gave me this ring, and I've been holding onto it for someone worthy. Now I've seen you in action, I think you should borrow it for the coming fight.<br>
|
||||
It is imbued with a magic that allows the wearer to draw upon power that they will some day come to possess. With this, you will be formidable indeed.
|
||||
</body></html>
|
@@ -1,4 +0,0 @@
|
||||
<html><body>Aden Vanguard Captain Adolph:<br>
|
||||
When you're rested, let's take on those monsters. Are you ready?<br>
|
||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest EvilIncubator resumeFight">"I'm ready."</Button>
|
||||
</body></html>
|
@@ -1,3 +0,0 @@
|
||||
<html><body>Aden Vanguard Captain Adolph:<br>
|
||||
I don't know where you came from, but Aden Castle is certainly glad of your help. Now, go back to your master for further instructions. I'm sure you need to report on what happened here, and I think we have things under control now.
|
||||
</body></html>
|
@@ -1,4 +0,0 @@
|
||||
<html><body>Aden Vanguard Captain Adolph:<br>
|
||||
As Shilen grows in power, more monsters will emerge from here. We can't just let this happen without fighting back!<br>
|
||||
<Button ALIGN=LEFT ICON="QUEST" action="bypass -h Quest EvilIncubator">Quest</Button>
|
||||
</body></html>
|
@@ -1,3 +0,0 @@
|
||||
<html><body>Priest Alice:<br>
|
||||
Speak with Adolph first.
|
||||
</body></html>
|
@@ -1,4 +0,0 @@
|
||||
<html><body>Priest Alice:<br>
|
||||
Do you need my help? I can heal, and provide support in combat.<br>
|
||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest EvilIncubator selectHelper">Select</Button>
|
||||
</body></html>
|
@@ -1,3 +0,0 @@
|
||||
<html><body>Alice:<br>
|
||||
This is dangerous. Quit fidgeting and concentrate.
|
||||
</body></html>
|
@@ -1,4 +0,0 @@
|
||||
<html><body>Priest Alice:<br>
|
||||
Even the strongest soldier will fall if they cannot be healed in battle. My healing power will lead us to victory.<br>
|
||||
<Button ALIGN=LEFT ICON="QUEST" action="bypass -h Quest EvilIncubator">Quest</Button>
|
||||
</body></html>
|
@@ -1,3 +0,0 @@
|
||||
<html><body>Officer Barton:<br>
|
||||
Speak with Adolph.
|
||||
</body></html>
|
@@ -1,4 +0,0 @@
|
||||
<html><body>Officer Barton:<br>
|
||||
You need my help? Well, you look like a capable sort. I need someone like you to watch my back.<br>
|
||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest EvilIncubator selectHelper">Select</Button>
|
||||
</body></html>
|
@@ -1,3 +0,0 @@
|
||||
<html><body>Officer Barton:<br>
|
||||
I hope to see you on the battlefield again, but for now I must observe the enemy from here.
|
||||
</body></html>
|
@@ -1,4 +0,0 @@
|
||||
<html><body>Officer Barton:<br>
|
||||
Not to brag, but a star soldier such as myself can make the difference between winning and losing.<br>
|
||||
<Button ALIGN=LEFT ICON="QUEST" action="bypass -h Quest EvilIncubator">Quest</Button>
|
||||
</body></html>
|
@@ -1,3 +0,0 @@
|
||||
<html><body>Sniper Hayuk:<br>
|
||||
You don't want to talk to me, you want Captain Adolph.
|
||||
</body></html>
|
@@ -1,4 +0,0 @@
|
||||
<html><body>Sniper Hayuk:<br>
|
||||
Do you need my help? Of course! I will cover your back! You can trust me.<br>
|
||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest EvilIncubator selectHelper">"Yes, I could use some help."</Button>
|
||||
</body></html>
|
@@ -1,3 +0,0 @@
|
||||
<html><body>Hayuk:<br>
|
||||
We are in the middle of a battle. Let's deal with the enemies first.
|
||||
</body></html>
|
@@ -1,4 +0,0 @@
|
||||
<html><body>Sniper Hayuk:<br>
|
||||
If you can defeat your enemy before they get close, you can annihilate their forces without incurring any damage to your own team. Heh! That there is what's called strategy!<br>
|
||||
<Button ALIGN=LEFT ICON="QUEST" action="bypass -h Quest EvilIncubator">Quest</Button>
|
||||
</body></html>
|
@@ -1,2 +0,0 @@
|
||||
<html><body>Magus Eliyah:<br>
|
||||
Instead of talking to me, perhaps you should speak with Adolph first?</body></html>
|
@@ -1,4 +0,0 @@
|
||||
<html><body>Magus Eliyah:<br>
|
||||
You need my help? Well, if you protect me from the monsters, I suppose I can help.<br>
|
||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest EvilIncubator selectHelper">Select</Button>
|
||||
</body></html>
|
@@ -1,3 +0,0 @@
|
||||
<html><body>Magus Eliyah:<br>
|
||||
What is it? I don't think you have any business with me, do you? Now get out there and concentrate on living to fight another day.
|
||||
</body></html>
|
@@ -1,4 +0,0 @@
|
||||
<html><body>Magus Eliyah:<br>
|
||||
The Ivory Tower's magic is much too powerful for these monsters. We have no need to skulk on the sidelines!<br>
|
||||
<Button ALIGN=LEFT ICON="QUEST" action="bypass -h Quest EvilIncubator">Quest</Button>
|
||||
</body></html>
|
@@ -1,567 +0,0 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package instances.EvilIncubator;
|
||||
|
||||
import java.util.EnumMap;
|
||||
import java.util.List;
|
||||
|
||||
import com.l2jmobius.commons.util.CommonUtil;
|
||||
import com.l2jmobius.gameserver.enums.ChatType;
|
||||
import com.l2jmobius.gameserver.enums.Race;
|
||||
import com.l2jmobius.gameserver.model.L2World;
|
||||
import com.l2jmobius.gameserver.model.Location;
|
||||
import com.l2jmobius.gameserver.model.StatsSet;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Attackable;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.FriendlyNpcInstance;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.base.ClassId;
|
||||
import com.l2jmobius.gameserver.model.events.impl.character.OnCreatureDeath;
|
||||
import com.l2jmobius.gameserver.model.instancezone.Instance;
|
||||
import com.l2jmobius.gameserver.model.quest.QuestState;
|
||||
import com.l2jmobius.gameserver.model.quest.State;
|
||||
import com.l2jmobius.gameserver.network.NpcStringId;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.Earthquake;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ExShowScreenMessage;
|
||||
|
||||
import instances.AbstractInstance;
|
||||
import quests.Q10341_DayOfDestinyHumansFate.Q10341_DayOfDestinyHumansFate;
|
||||
import quests.Q10342_DayOfDestinyElvenFate.Q10342_DayOfDestinyElvenFate;
|
||||
import quests.Q10343_DayOfDestinyDarkElfsFate.Q10343_DayOfDestinyDarkElfsFate;
|
||||
import quests.Q10344_DayOfDestinyOrcsFate.Q10344_DayOfDestinyOrcsFate;
|
||||
import quests.Q10345_DayOfDestinyDwarfsFate.Q10345_DayOfDestinyDwarfsFate;
|
||||
import quests.Q10346_DayOfDestinyKamaelsFate.Q10346_DayOfDestinyKamaelsFate;
|
||||
|
||||
/**
|
||||
* Evil Incubator instance zone.
|
||||
* @author St3eT
|
||||
*/
|
||||
public final class EvilIncubator extends AbstractInstance
|
||||
{
|
||||
// NPCs
|
||||
private static final int VANGUARD_MEMBER = 33165;
|
||||
private static final int ADOLPH = 33170;
|
||||
private static final int ALICE = 33171;
|
||||
private static final int BARTON = 33172;
|
||||
private static final int HAYUK = 33173;
|
||||
private static final int ELIYAH = 33174;
|
||||
private static final int[] MONSTERS =
|
||||
{
|
||||
27431, // Slayer
|
||||
27432, // Tracker
|
||||
27433, // Priest of Darkness
|
||||
27434, // Guardian of Darkness
|
||||
27430, // Screaming Shaman
|
||||
};
|
||||
private static final int[] BOSSES =
|
||||
{
|
||||
27425, // Death Wound
|
||||
27426, // Death Wound
|
||||
27427, // Death Wound
|
||||
27428, // Death Wound
|
||||
27429, // Death Wound
|
||||
};
|
||||
private static final int[] HELPERS =
|
||||
{
|
||||
33170, // Adolph
|
||||
// 33171, // Priest Alice
|
||||
33172, // Officer Barton
|
||||
33173, // Sniper Hayuk
|
||||
33174, // Magus Eliyah
|
||||
33414, // Van Archer
|
||||
33415, // Van Infantry
|
||||
};
|
||||
// Items
|
||||
private static final int SOE = 736; // Scroll of Escape
|
||||
// Locations
|
||||
private static final Location PLAYER_BATTLE_LOC = new Location(56167, -175615, -7944);
|
||||
private static final Location BATTLE_LOC_2 = new Location(56005, -175536, -7952);
|
||||
private static final Location BATTLE_LOC_3 = new Location(56325, -175536, -7952);
|
||||
private static final Location BOSS_LOC = new Location(56165, -177550, -7944);
|
||||
// Misc
|
||||
private static final int TEMPLATE_ID = 185;
|
||||
//@formatter:off
|
||||
private static final EnumMap<Race, String> RACE_QUESTS = new EnumMap<>(Race.class);
|
||||
static
|
||||
{
|
||||
RACE_QUESTS.put(Race.HUMAN, Q10341_DayOfDestinyHumansFate.class.getSimpleName());
|
||||
RACE_QUESTS.put(Race.ELF, Q10342_DayOfDestinyElvenFate.class.getSimpleName());
|
||||
RACE_QUESTS.put(Race.DARK_ELF, Q10343_DayOfDestinyDarkElfsFate.class.getSimpleName());
|
||||
RACE_QUESTS.put(Race.ORC, Q10344_DayOfDestinyOrcsFate.class.getSimpleName());
|
||||
RACE_QUESTS.put(Race.DWARF, Q10345_DayOfDestinyDwarfsFate.class.getSimpleName());
|
||||
RACE_QUESTS.put(Race.KAMAEL, Q10346_DayOfDestinyKamaelsFate.class.getSimpleName());
|
||||
}
|
||||
private static final EnumMap<ClassId, Integer> CLASS_BOSS = new EnumMap<>(ClassId.class);
|
||||
static
|
||||
{
|
||||
CLASS_BOSS.put(ClassId.GLADIATOR, 27426);
|
||||
CLASS_BOSS.put(ClassId.WARLORD, 27426);
|
||||
CLASS_BOSS.put(ClassId.PALADIN, 27425);
|
||||
CLASS_BOSS.put(ClassId.DARK_AVENGER, 27425);
|
||||
CLASS_BOSS.put(ClassId.TREASURE_HUNTER, 27426);
|
||||
CLASS_BOSS.put(ClassId.HAWKEYE, 27428);
|
||||
CLASS_BOSS.put(ClassId.SORCERER, 27428);
|
||||
CLASS_BOSS.put(ClassId.NECROMANCER, 27428);
|
||||
CLASS_BOSS.put(ClassId.WARLOCK, 27428);
|
||||
CLASS_BOSS.put(ClassId.BISHOP, 27427);
|
||||
CLASS_BOSS.put(ClassId.PROPHET, 27429);
|
||||
CLASS_BOSS.put(ClassId.TEMPLE_KNIGHT, 27425);
|
||||
CLASS_BOSS.put(ClassId.SWORDSINGER, 27429);
|
||||
CLASS_BOSS.put(ClassId.PLAINS_WALKER, 27426);
|
||||
CLASS_BOSS.put(ClassId.SILVER_RANGER, 27428);
|
||||
CLASS_BOSS.put(ClassId.SPELLSINGER, 27428);
|
||||
CLASS_BOSS.put(ClassId.ELEMENTAL_SUMMONER, 27428);
|
||||
CLASS_BOSS.put(ClassId.ELDER, 27427);
|
||||
CLASS_BOSS.put(ClassId.SHILLIEN_KNIGHT, 27425);
|
||||
CLASS_BOSS.put(ClassId.BLADEDANCER, 27429);
|
||||
CLASS_BOSS.put(ClassId.ABYSS_WALKER, 27426);
|
||||
CLASS_BOSS.put(ClassId.PHANTOM_RANGER, 27428);
|
||||
CLASS_BOSS.put(ClassId.SPELLHOWLER, 27428);
|
||||
CLASS_BOSS.put(ClassId.PHANTOM_SUMMONER, 27428);
|
||||
CLASS_BOSS.put(ClassId.SHILLIEN_ELDER, 27427);
|
||||
CLASS_BOSS.put(ClassId.DESTROYER, 27426);
|
||||
CLASS_BOSS.put(ClassId.TYRANT, 27426);
|
||||
CLASS_BOSS.put(ClassId.OVERLORD, 27429);
|
||||
CLASS_BOSS.put(ClassId.WARCRYER, 27429);
|
||||
CLASS_BOSS.put(ClassId.BOUNTY_HUNTER, 27426);
|
||||
CLASS_BOSS.put(ClassId.WARSMITH, 27426);
|
||||
CLASS_BOSS.put(ClassId.BERSERKER, 27426);
|
||||
CLASS_BOSS.put(ClassId.MALE_SOULBREAKER, 27426);
|
||||
CLASS_BOSS.put(ClassId.FEMALE_SOULBREAKER, 27426);
|
||||
CLASS_BOSS.put(ClassId.ARBALESTER, 27428);
|
||||
}
|
||||
private static final EnumMap<ClassId, Integer> CLASS_ITEMS = new EnumMap<>(ClassId.class);
|
||||
static
|
||||
{
|
||||
CLASS_ITEMS.put(ClassId.GLADIATOR, 17484);
|
||||
CLASS_ITEMS.put(ClassId.WARLORD, 17485);
|
||||
CLASS_ITEMS.put(ClassId.PALADIN, 17486);
|
||||
CLASS_ITEMS.put(ClassId.DARK_AVENGER, 17487);
|
||||
CLASS_ITEMS.put(ClassId.TREASURE_HUNTER, 17488);
|
||||
CLASS_ITEMS.put(ClassId.HAWKEYE, 17489);
|
||||
CLASS_ITEMS.put(ClassId.SORCERER, 17490);
|
||||
CLASS_ITEMS.put(ClassId.NECROMANCER, 17491);
|
||||
CLASS_ITEMS.put(ClassId.WARLOCK, 17492);
|
||||
CLASS_ITEMS.put(ClassId.BISHOP, 17493);
|
||||
CLASS_ITEMS.put(ClassId.PROPHET, 17494);
|
||||
CLASS_ITEMS.put(ClassId.TEMPLE_KNIGHT, 17495);
|
||||
CLASS_ITEMS.put(ClassId.SWORDSINGER, 17496);
|
||||
CLASS_ITEMS.put(ClassId.PLAINS_WALKER, 17497);
|
||||
CLASS_ITEMS.put(ClassId.SILVER_RANGER, 17498);
|
||||
CLASS_ITEMS.put(ClassId.SPELLSINGER, 17499);
|
||||
CLASS_ITEMS.put(ClassId.ELEMENTAL_SUMMONER, 17500);
|
||||
CLASS_ITEMS.put(ClassId.ELDER, 17501);
|
||||
CLASS_ITEMS.put(ClassId.SHILLIEN_KNIGHT, 17502);
|
||||
CLASS_ITEMS.put(ClassId.BLADEDANCER, 17503);
|
||||
CLASS_ITEMS.put(ClassId.ABYSS_WALKER, 17504);
|
||||
CLASS_ITEMS.put(ClassId.PHANTOM_RANGER, 17505);
|
||||
CLASS_ITEMS.put(ClassId.SPELLHOWLER, 17506);
|
||||
CLASS_ITEMS.put(ClassId.PHANTOM_SUMMONER, 17507);
|
||||
CLASS_ITEMS.put(ClassId.SHILLIEN_ELDER, 17508);
|
||||
CLASS_ITEMS.put(ClassId.DESTROYER, 17509);
|
||||
CLASS_ITEMS.put(ClassId.TYRANT, 17510);
|
||||
CLASS_ITEMS.put(ClassId.OVERLORD, 17511);
|
||||
CLASS_ITEMS.put(ClassId.WARCRYER, 17512);
|
||||
CLASS_ITEMS.put(ClassId.BOUNTY_HUNTER, 17513);
|
||||
CLASS_ITEMS.put(ClassId.WARSMITH, 17514);
|
||||
CLASS_ITEMS.put(ClassId.BERSERKER, 17515);
|
||||
CLASS_ITEMS.put(ClassId.MALE_SOULBREAKER, 17516);
|
||||
CLASS_ITEMS.put(ClassId.FEMALE_SOULBREAKER, 17516);
|
||||
CLASS_ITEMS.put(ClassId.ARBALESTER, 17517);
|
||||
}
|
||||
//@formatter:on
|
||||
|
||||
public EvilIncubator()
|
||||
{
|
||||
super(TEMPLATE_ID);
|
||||
addStartNpc(VANGUARD_MEMBER);
|
||||
addTalkId(VANGUARD_MEMBER, ADOLPH, ALICE, BARTON, HAYUK, ELIYAH);
|
||||
addFirstTalkId(ADOLPH, ALICE, BARTON, HAYUK, ELIYAH);
|
||||
setCreatureKillId(this::onCreatureKill, MONSTERS);
|
||||
setCreatureKillId(this::onCreatureKill, BOSSES);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
final QuestState st = getQuestState(player);
|
||||
if ((st == null) || !st.isStarted())
|
||||
{
|
||||
return super.onAdvEvent(event, npc, player);
|
||||
}
|
||||
String htmltext = null;
|
||||
|
||||
if (event.equals("enterInstance"))
|
||||
{
|
||||
enterInstance(player, npc, TEMPLATE_ID);
|
||||
st.setCond(5);
|
||||
htmltext = "33165-01.html";
|
||||
}
|
||||
else
|
||||
{
|
||||
final Instance world = npc.getInstanceWorld();
|
||||
if (world != null)
|
||||
{
|
||||
switch (event)
|
||||
{
|
||||
case "33170-02.html":
|
||||
{
|
||||
if (st.isCond(5))
|
||||
{
|
||||
st.setCond(6, true);
|
||||
htmltext = event;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "selectHelper":
|
||||
{
|
||||
int helperCount = world.getParameters().getInt("HELPER_COUNT", 0);
|
||||
if ((helperCount < 2) && st.isCond(6))
|
||||
{
|
||||
helperCount++;
|
||||
world.setParameter("HELPER_COUNT", helperCount);
|
||||
npc.teleToLocation(helperCount == 1 ? BATTLE_LOC_2 : BATTLE_LOC_3);
|
||||
|
||||
if (helperCount == 2)
|
||||
{
|
||||
st.setCond(7, true);
|
||||
L2World.getInstance().getVisibleObjects(world.getNpc(ADOLPH), FriendlyNpcInstance.class, 1000).forEach(c -> c.deleteMe());
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "teamSelected":
|
||||
{
|
||||
int helperCount = world.getParameters().getInt("HELPER_COUNT", 0);
|
||||
if ((helperCount == 2) && st.isCond(7))
|
||||
{
|
||||
helperCount++;
|
||||
world.setParameter("HELPER_COUNT", helperCount);
|
||||
st.setCond(8, true);
|
||||
npc.teleToLocation(PLAYER_BATTLE_LOC);
|
||||
player.teleToLocation(PLAYER_BATTLE_LOC);
|
||||
getTimers().addTimer("SPAWN_WAVE", 5000, e -> manageWaveSpawn(world));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "giveItem":
|
||||
{
|
||||
if (st.isCond(9))
|
||||
{
|
||||
st.setCond(10, true);
|
||||
final int classItemId = CLASS_ITEMS.getOrDefault(player.getClassId(), -1);
|
||||
if ((classItemId != -1) && !hasQuestItems(player, classItemId))
|
||||
{
|
||||
giveItems(player, classItemId, 1);
|
||||
}
|
||||
npc.broadcastSay(ChatType.NPC_GENERAL, NpcStringId.THE_CRY_OF_DESTINY_PENDANT_WILL_BE_HELPFUL_TO_YOU_PLEASE_EQUIP_IT_AND_BRING_OUT_THE_POWER_OF_THE_PENDANT_TO_PREPARE_FOR_THE_NEXT_FIGHT);
|
||||
htmltext = "33170-06.html";
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "resumeFight":
|
||||
{
|
||||
if (st.isCond(10))
|
||||
{
|
||||
st.setCond(11, true);
|
||||
manageWaveSpawn(world);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return htmltext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onTalk(L2Npc npc, L2PcInstance player, boolean isSimulated)
|
||||
{
|
||||
String htmltext = getNoQuestMsg(player);
|
||||
final QuestState st = getQuestState(player);
|
||||
|
||||
if ((st == null) || !st.isStarted())
|
||||
{
|
||||
return super.onTalk(npc, player, isSimulated);
|
||||
}
|
||||
|
||||
if (st.getState() == State.STARTED)
|
||||
{
|
||||
switch (npc.getId())
|
||||
{
|
||||
case ADOLPH:
|
||||
{
|
||||
switch (st.getCond())
|
||||
{
|
||||
case 5:
|
||||
{
|
||||
htmltext = npc.getId() + "-01.html";
|
||||
break;
|
||||
}
|
||||
case 6:
|
||||
{
|
||||
htmltext = "33170-02.html";
|
||||
break;
|
||||
}
|
||||
case 7:
|
||||
{
|
||||
htmltext = "33170-03.html";
|
||||
break;
|
||||
}
|
||||
case 9:
|
||||
{
|
||||
htmltext = "33170-05.html";
|
||||
break;
|
||||
}
|
||||
case 10:
|
||||
{
|
||||
htmltext = "33170-07.html";
|
||||
break;
|
||||
}
|
||||
case 12:
|
||||
{
|
||||
st.setCond(13, true);
|
||||
giveItems(player, SOE, 1);
|
||||
}
|
||||
case 13:
|
||||
{
|
||||
htmltext = "33170-08.html";
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ALICE:
|
||||
case BARTON:
|
||||
case ELIYAH:
|
||||
case HAYUK:
|
||||
{
|
||||
switch (st.getCond())
|
||||
{
|
||||
case 5:
|
||||
{
|
||||
htmltext = npc.getId() + "-01.html";
|
||||
break;
|
||||
}
|
||||
case 6:
|
||||
{
|
||||
htmltext = npc.getId() + "-02.html";
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return htmltext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onFirstTalk(L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
String htmltext = null;
|
||||
final QuestState st = getQuestState(player);
|
||||
|
||||
if ((st == null) || !st.isStarted())
|
||||
{
|
||||
return htmltext;
|
||||
}
|
||||
|
||||
switch (npc.getId())
|
||||
{
|
||||
case ADOLPH:
|
||||
{
|
||||
switch (st.getCond())
|
||||
{
|
||||
case 5:
|
||||
case 6:
|
||||
case 7:
|
||||
case 9:
|
||||
case 10:
|
||||
case 12:
|
||||
case 13:
|
||||
{
|
||||
htmltext = "33170.html";
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
htmltext = "33170-04.html";
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ALICE:
|
||||
case BARTON:
|
||||
case ELIYAH:
|
||||
case HAYUK:
|
||||
{
|
||||
htmltext = st.getCond() > 7 ? (npc.getId() + "-03.html") : (npc.getId() + ".html");
|
||||
break;
|
||||
}
|
||||
}
|
||||
return htmltext;
|
||||
}
|
||||
|
||||
public void onCreatureKill(OnCreatureDeath event)
|
||||
{
|
||||
final L2Npc npc = (L2Npc) event.getTarget();
|
||||
|
||||
final Instance world = npc.getInstanceWorld();
|
||||
if (world != null)
|
||||
{
|
||||
final int waveId = world.getParameters().getInt("WORLD_WAVE", 1);
|
||||
|
||||
if (CommonUtil.contains(BOSSES, npc.getId()))
|
||||
{
|
||||
final QuestState st = getQuestState(world.getFirstPlayer());
|
||||
if ((st == null) || !st.isStarted())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
st.setCond(12, true);
|
||||
}
|
||||
else if (waveId < 8)
|
||||
{
|
||||
if (world.getAliveNpcs(MONSTERS).isEmpty())
|
||||
{
|
||||
getTimers().addTimer("SPAWN_WAVE", 5000, e -> manageWaveSpawn(world));
|
||||
}
|
||||
}
|
||||
getTimers().addTimer("WORLD_ATTACK", 1000, e -> managerWorldAttack(world, null));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTimerEvent(String event, StatsSet params, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private void manageWaveSpawn(Instance world)
|
||||
{
|
||||
final QuestState st = getQuestState(world.getFirstPlayer());
|
||||
if ((st == null) || !st.isStarted())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
List<L2Npc> spawnedNpcs = null;
|
||||
int waveId = world.getParameters().getInt("WORLD_WAVE", 1);
|
||||
switch (waveId)
|
||||
{
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
case 5:
|
||||
case 6:
|
||||
{
|
||||
spawnedNpcs = world.spawnGroup("wave_" + waveId);
|
||||
waveId++;
|
||||
world.setParameter("WORLD_WAVE", waveId);
|
||||
showOnScreenMsg(world, NpcStringId.CREATURES_RESURRECTED_DEFEND_YOURSELF, ExShowScreenMessage.TOP_CENTER, 5000, true);
|
||||
break;
|
||||
}
|
||||
case 7:
|
||||
{
|
||||
waveId++;
|
||||
world.setParameter("WORLD_WAVE", waveId);
|
||||
showOnScreenMsg(world, NpcStringId.CREATURES_HAVE_STOPPED_THEIR_ATTACK_REST_AND_THEN_SPEAK_WITH_ADOLPH, ExShowScreenMessage.TOP_CENTER, 5000, true);
|
||||
st.setCond(9, true);
|
||||
break;
|
||||
}
|
||||
case 8:
|
||||
case 9:
|
||||
case 10:
|
||||
case 11:
|
||||
case 12:
|
||||
case 13:
|
||||
case 14:
|
||||
{
|
||||
spawnedNpcs = world.spawnGroup("wave_" + waveId);
|
||||
waveId++;
|
||||
world.setParameter("WORLD_WAVE", waveId);
|
||||
showOnScreenMsg(world, NpcStringId.CREATURES_RESURRECTED_DEFEND_YOURSELF, ExShowScreenMessage.TOP_CENTER, 5000, true);
|
||||
getTimers().addTimer("SPAWN_WAVE", 20000, e -> manageWaveSpawn(world));
|
||||
break;
|
||||
}
|
||||
case 15:
|
||||
{
|
||||
spawnedNpcs = world.spawnGroup("wave_" + waveId);
|
||||
waveId++;
|
||||
world.setParameter("WORLD_WAVE", waveId);
|
||||
showOnScreenMsg(world, NpcStringId.I_DEATH_WOUND_CHAMPION_OF_SHILEN_SHALL_END_YOUR_WORLD, ExShowScreenMessage.TOP_CENTER, 5000, true);
|
||||
getTimers().addTimer("SPAWN_WAVE", 20000, e -> manageWaveSpawn(world));
|
||||
final L2Npc boss = addSpawn(CLASS_BOSS.get(world.getFirstPlayer().getClassId()), BOSS_LOC, false, 0, false, world.getId());
|
||||
world.broadcastPacket(new Earthquake(boss, 50, 10));
|
||||
break;
|
||||
}
|
||||
}
|
||||
managerWorldAttack(world, spawnedNpcs);
|
||||
}
|
||||
|
||||
private void managerWorldAttack(Instance world, List<L2Npc> spawnedNpcs)
|
||||
{
|
||||
final List<FriendlyNpcInstance> helperList = L2World.getInstance().getVisibleObjects(world.getFirstPlayer(), FriendlyNpcInstance.class);
|
||||
|
||||
if ((spawnedNpcs != null) && !spawnedNpcs.isEmpty())
|
||||
{
|
||||
for (L2Npc npc : spawnedNpcs)
|
||||
{
|
||||
if (!helperList.isEmpty())
|
||||
{
|
||||
final FriendlyNpcInstance helper = helperList.get(getRandom(helperList.size()));
|
||||
|
||||
if (CommonUtil.contains(HELPERS, helper.getId()))
|
||||
{
|
||||
npc.reduceCurrentHp(1, helper, null);
|
||||
helper.reduceCurrentHp(1, npc, null);
|
||||
addAttackDesire(helper, npc);
|
||||
helperList.remove(helper);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (FriendlyNpcInstance helper : helperList)
|
||||
{
|
||||
for (L2Attackable monster : L2World.getInstance().getVisibleObjects(helper, L2Attackable.class))
|
||||
{
|
||||
if (!(monster instanceof FriendlyNpcInstance))
|
||||
{
|
||||
addAttackDesire(helper, monster);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private QuestState getQuestState(L2PcInstance player)
|
||||
{
|
||||
if (player == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return RACE_QUESTS.containsKey(player.getRace()) ? player.getQuestState(RACE_QUESTS.get(player.getRace())) : null;
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new EvilIncubator();
|
||||
}
|
||||
}
|
@@ -1,3 +0,0 @@
|
||||
<html><body>Magister Ayanthe:<br>
|
||||
The monsters are coming. Concentrate and attack!
|
||||
</body></html>
|
@@ -1,4 +0,0 @@
|
||||
<html><body>Magister Ayanthe:<br>
|
||||
Focus on the fight!<br>
|
||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest FaeronTrainingGrounds1 33944-03.html">"Create more monsters so I can train."</Button>
|
||||
</body></html>
|
@@ -1,4 +0,0 @@
|
||||
<html><body>Magister Ayanthe:<br>
|
||||
Good. It pleases me that you're taking your training so seriously.<br>
|
||||
But bear in mind that this is training, and not the real world. We will limit the number of monsters you face in a single encounter.
|
||||
</body></html>
|
@@ -1,7 +0,0 @@
|
||||
<html><body>Magister Ayanthe:<br>
|
||||
You're better than I expected. Feels different from training with a dummy, right?<br>
|
||||
Here, take these <font color="LEVEL">Spiritshots</font>. Right now, your weapon has no grade, but as you become stronger, you'll be using D-grade, C-grade, and even R-grade weapons. They're proving to be very valuable in the Material Realm.<br>
|
||||
Go ahead and <font color="LEVEL">activate the Spiritshots</font>.<br>
|
||||
I'll go prepare more monsters for your next training session, so let me know when the Spiritshots have been activated.<br>
|
||||
(You can conveniently automate your Spiritshots by creating a <font color="LEVEL">shortcut</font> and then <font color="LEVEL">right-clicking</font> on it.)
|
||||
</body></html>
|
@@ -1,3 +0,0 @@
|
||||
<html><head><body>Magister Ayanthe:<br>
|
||||
All right, now your training begins again!
|
||||
</body></html>
|
@@ -1,6 +0,0 @@
|
||||
<html><body>Mastery Ayanthe:<br>
|
||||
I see you're a quick study. I'm impressed. I can't wait to see how much you'll have improved in the future. You have recovered some of your power that has been sealed while passing through the Dimensional Rift. These are called <font color="LEVEL">Skills</font>.<br>
|
||||
The more abilities you recover, the stronger you'll grow.<br>
|
||||
Now that you've recovered some of your power, shall we face tougher enemies? Are you ready?<br>
|
||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest FaeronTrainingGrounds1 33944-07.html">"My body is ready."</Button>
|
||||
</body></html>
|
@@ -1,3 +0,0 @@
|
||||
<html><body>Magister Ayanthe:<br>
|
||||
If you don't use your <font color="LEVEL">skills</font>, this next battle will be difficult!
|
||||
</body></html>
|
@@ -1,4 +0,0 @@
|
||||
<html><body>Magister Ayanthe:<br>
|
||||
Great work. You've made me very proud. You must be exhausted. Shall we step outside?<br>
|
||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest FaeronTrainingGrounds1 exit_instance">"I'd like to go outside."</button>
|
||||
</body></html>
|
@@ -1,5 +0,0 @@
|
||||
<html><body>Magister Ayanthe:<br>
|
||||
Don't underestimate the enemy you see before you.<br>
|
||||
While in battle, you must never lose focus.<br>
|
||||
<Button ALIGN=LEFT ICON="QUEST" action="bypass -h npc_%objectId%_Quest FaeronTrainingGrounds1">Quest</Button>
|
||||
</body></html>
|
@@ -1,310 +0,0 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package instances.FaeronTrainingGrounds1;
|
||||
|
||||
import com.l2jmobius.gameserver.enums.QuestSound;
|
||||
import com.l2jmobius.gameserver.model.Location;
|
||||
import com.l2jmobius.gameserver.model.StatsSet;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.holders.ItemHolder;
|
||||
import com.l2jmobius.gameserver.model.instancezone.Instance;
|
||||
import com.l2jmobius.gameserver.model.quest.QuestState;
|
||||
import com.l2jmobius.gameserver.model.skills.Skill;
|
||||
import com.l2jmobius.gameserver.network.NpcStringId;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ExShowScreenMessage;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.TutorialShowHtml;
|
||||
|
||||
import instances.AbstractInstance;
|
||||
import quests.Q10735_ASpecialPower.Q10735_ASpecialPower;
|
||||
|
||||
/**
|
||||
* Fearon Training Grounds Instance Zone.
|
||||
* @author Sdw, malyelfik
|
||||
*/
|
||||
public final class FaeronTrainingGrounds1 extends AbstractInstance
|
||||
{
|
||||
// NPCs
|
||||
private static final int AYANTHE = 33942;
|
||||
private static final int AYANTHE_2 = 33944;
|
||||
// Monsters
|
||||
private static final int FLOATO = 27526;
|
||||
private static final int FLOATO2 = 27531;
|
||||
private static final int RATEL = 27527;
|
||||
// Items
|
||||
private static final ItemHolder SPIRITSHOTS_TRAINING = new ItemHolder(2509, 150);
|
||||
// Locations
|
||||
private static final Location[] MOB_SPAWNS =
|
||||
{
|
||||
new Location(-74721, 240513, -3584),
|
||||
new Location(-74760, 240773, -3560)
|
||||
};
|
||||
// Misc
|
||||
private static final int TEMPLATE_ID = 251;
|
||||
private static final double DAMAGE_BY_SKILL = 0.5d; // Percent
|
||||
|
||||
public FaeronTrainingGrounds1()
|
||||
{
|
||||
super(TEMPLATE_ID);
|
||||
addStartNpc(AYANTHE, AYANTHE_2);
|
||||
addFirstTalkId(AYANTHE_2);
|
||||
addTalkId(AYANTHE, AYANTHE_2);
|
||||
addKillId(FLOATO, FLOATO2, RATEL);
|
||||
addSkillSeeId(RATEL);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
final QuestState qs = player.getQuestState(Q10735_ASpecialPower.class.getSimpleName());
|
||||
String htmltext = null;
|
||||
if (qs == null)
|
||||
{
|
||||
return htmltext;
|
||||
}
|
||||
|
||||
switch (event)
|
||||
{
|
||||
case "enter_instance":
|
||||
enterInstance(player, npc, TEMPLATE_ID);
|
||||
break;
|
||||
case "exit_instance":
|
||||
finishInstance(player, 0);
|
||||
break;
|
||||
case "33944-03.html":
|
||||
{
|
||||
if (qs.isCond(6))
|
||||
{
|
||||
spawnMonsters(RATEL, player);
|
||||
showOnScreenMsg(player, NpcStringId.FIGHT_USING_SKILLS, ExShowScreenMessage.TOP_CENTER, 10000);
|
||||
}
|
||||
else
|
||||
{
|
||||
final int npcId = (qs.isCond(4)) ? FLOATO2 : FLOATO;
|
||||
spawnMonsters(npcId, player);
|
||||
showOnScreenMsg(player, NpcStringId.ATTACK_THE_MONSTER, ExShowScreenMessage.TOP_CENTER, 10000);
|
||||
}
|
||||
htmltext = event;
|
||||
break;
|
||||
}
|
||||
case "33944-07.html":
|
||||
{
|
||||
if (qs.isCond(5))
|
||||
{
|
||||
qs.setCond(6, true);
|
||||
showOnScreenMsg(player, NpcStringId.FIGHT_USING_SKILLS, ExShowScreenMessage.TOP_CENTER, 10000);
|
||||
spawnMonsters(RATEL, player);
|
||||
htmltext = event;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return htmltext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onTalk(L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
final QuestState qs = player.getQuestState(Q10735_ASpecialPower.class.getSimpleName());
|
||||
String htmltext = getNoQuestMsg(player);
|
||||
if (qs == null)
|
||||
{
|
||||
return htmltext;
|
||||
}
|
||||
|
||||
if ((npc.getId() == AYANTHE_2) && qs.isStarted())
|
||||
{
|
||||
switch (qs.getCond())
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
qs.setCond(2, true);
|
||||
spawnMonsters(FLOATO, player);
|
||||
showOnScreenMsg(player, NpcStringId.ATTACK_THE_MONSTER, ExShowScreenMessage.TOP_CENTER, 10000);
|
||||
htmltext = "33944-01.html";
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
case 4:
|
||||
case 6:
|
||||
{
|
||||
htmltext = "33944-02.html";
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
if (qs.getInt("ss") == 1)
|
||||
{
|
||||
spawnMonsters(FLOATO2, player);
|
||||
showOnScreenMsg(player, NpcStringId.ATTACK_THE_MONSTER, ExShowScreenMessage.TOP_CENTER, 10000);
|
||||
qs.setCond(4, true);
|
||||
htmltext = "33944-05.html";
|
||||
}
|
||||
else
|
||||
{
|
||||
qs.set("ss", 1);
|
||||
giveItems(player, SPIRITSHOTS_TRAINING);
|
||||
showOnScreenMsg(player, NpcStringId.AUTOMATE_SPIRITSHOT_AS_SHOWN_IN_THE_TUTORIAL, ExShowScreenMessage.TOP_CENTER, 10000);
|
||||
player.sendPacket(new TutorialShowHtml(npc.getObjectId(), "..\\L2Text\\QT_003_bullet_01.htm", TutorialShowHtml.LARGE_WINDOW));
|
||||
htmltext = "33944-04.html";
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 5:
|
||||
{
|
||||
player.sendPacket(new TutorialShowHtml(npc.getObjectId(), "..\\L2Text\\QT_004_skill_01.htm", TutorialShowHtml.LARGE_WINDOW));
|
||||
htmltext = "33944-06.html";
|
||||
break;
|
||||
}
|
||||
case 7:
|
||||
{
|
||||
htmltext = "33944-08.html";
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return htmltext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
|
||||
{
|
||||
// Check if monster is inside instance
|
||||
final Instance world = npc.getInstanceWorld();
|
||||
if (world == null)
|
||||
{
|
||||
return super.onKill(npc, killer, isSummon);
|
||||
}
|
||||
|
||||
// Remove monster from instance spawn holder
|
||||
world.setParameter("Mob" + npc.getScriptValue(), null);
|
||||
|
||||
// Handle quest state
|
||||
final QuestState qs = killer.getQuestState(Q10735_ASpecialPower.class.getSimpleName());
|
||||
if (qs != null)
|
||||
{
|
||||
switch (npc.getId())
|
||||
{
|
||||
case FLOATO:
|
||||
case FLOATO2:
|
||||
{
|
||||
if ((qs.isCond(2) || qs.isCond(4)) && onKillQuestChange(killer, qs))
|
||||
{
|
||||
despawnMonsters(killer);
|
||||
if (qs.isCond(5) && (killer.getLevel() < 5))
|
||||
{
|
||||
addExpAndSp(killer, 1716, 0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case RATEL:
|
||||
{
|
||||
if (qs.isCond(6) && onKillQuestChange(killer, qs))
|
||||
{
|
||||
despawnMonsters(killer);
|
||||
showOnScreenMsg(killer, NpcStringId.TALK_TO_AYANTHE_TO_LEAVE_THE_TRAINING_GROUNDS, ExShowScreenMessage.TOP_CENTER, 10000);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return super.onKill(npc, killer, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSkillSee(L2Npc npc, L2PcInstance player, Skill skill, com.l2jmobius.gameserver.model.L2Object[] targets, boolean isSummon)
|
||||
{
|
||||
if (!npc.isDead() && (player.getTarget() == npc))
|
||||
{
|
||||
final double dmg = npc.getMaxHp() * DAMAGE_BY_SKILL;
|
||||
npc.reduceCurrentHp(dmg, player, null);
|
||||
}
|
||||
return super.onSkillSee(npc, player, skill, targets, isSummon);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle death of training monster. When all monsters are killed, quest cond is increased.
|
||||
* @param killer player who killed monster
|
||||
* @param qs quest state of killer
|
||||
* @return {@code true} when all monsters are killed, otherwise {@code false}
|
||||
*/
|
||||
private boolean onKillQuestChange(L2PcInstance killer, QuestState qs)
|
||||
{
|
||||
final int value = qs.getMemoStateEx(Q10735_ASpecialPower.KILL_COUNT_VAR) + 1;
|
||||
if (value >= 2)
|
||||
{
|
||||
qs.setCond(qs.getCond() + 1, true);
|
||||
qs.setMemoStateEx(Q10735_ASpecialPower.KILL_COUNT_VAR, 0);
|
||||
return true;
|
||||
}
|
||||
playSound(killer, QuestSound.ITEMSOUND_QUEST_ITEMGET);
|
||||
qs.setMemoStateEx(Q10735_ASpecialPower.KILL_COUNT_VAR, value);
|
||||
qs.getQuest().sendNpcLogList(killer);
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Spawn training monsters inside instance
|
||||
* @param npcId template id of training monster
|
||||
* @param player player that owns instance
|
||||
*/
|
||||
private void spawnMonsters(int npcId, L2PcInstance player)
|
||||
{
|
||||
final Instance world = player.getInstanceWorld();
|
||||
if (world != null)
|
||||
{
|
||||
final StatsSet params = world.getParameters();
|
||||
for (int i = 0; i < MOB_SPAWNS.length; i++)
|
||||
{
|
||||
if (params.getObject("Mob" + i, L2Npc.class) == null)
|
||||
{
|
||||
final L2Npc npc = addSpawn(npcId, MOB_SPAWNS[i], false, 0, false, world.getId());
|
||||
npc.setScriptValue(i);
|
||||
params.set("Mob" + i, npc);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Despawn training monsters inside instance
|
||||
* @param player player that owns instance
|
||||
*/
|
||||
private void despawnMonsters(L2PcInstance player)
|
||||
{
|
||||
final Instance world = player.getInstanceWorld();
|
||||
if (world != null)
|
||||
{
|
||||
final StatsSet params = world.getParameters();
|
||||
for (int i = 0; i < MOB_SPAWNS.length; i++)
|
||||
{
|
||||
final L2Npc mob = params.getObject("Mob" + i, L2Npc.class);
|
||||
if (mob != null)
|
||||
{
|
||||
mob.deleteMe();
|
||||
params.remove("Mob" + i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new FaeronTrainingGrounds1();
|
||||
}
|
||||
}
|
@@ -1,4 +0,0 @@
|
||||
<html><body>Master Katalin:<br>
|
||||
The monsters are here.<br>
|
||||
Stay focused in battle and take care not to get hurt.
|
||||
</body></html>
|
@@ -1,4 +0,0 @@
|
||||
<html><body>Master Katalin:<br>
|
||||
Focus on your battle!<br>
|
||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest FaeronTrainingGrounds2 33945-03.html">"More monsters please."</button>
|
||||
</body></html>
|
@@ -1,4 +0,0 @@
|
||||
<html><body>Master Katalin:<br>
|
||||
It's good to see you train hard.<br>
|
||||
But for your safety, there's a limit to the number of monsters at once.
|
||||
</body></html>
|
@@ -1,7 +0,0 @@
|
||||
<html><body>Master Katalin:<br>
|
||||
Different from the Training Dummies?<br>
|
||||
Take these <font color="LEVEL">Soulshots</font>. They have no grade, but as you get stronger and get better weapons, you can use Grade D, C, B, A, S, S-80, and eventually R. It's very important in the Material Realm.<br>
|
||||
<font color="LEVEL">Activate Soulshots</font>.<br>
|
||||
I will prepare the next set of monsters. Tell me when you have activated the Soulshots.<br>
|
||||
(How to Enable Auto-Use Soulshot or Spiritshot: Open your <font color="LEVEL">Inventory</font>. <font color="LEVEL">Click and Drag</font> Soulshot/Spiritshot into your Shortcut Bar. Right Click the Soulshot/Spiritshot Shortcut Icon to use it automatically.)
|
||||
</body></html>
|
@@ -1,3 +0,0 @@
|
||||
<html><body>Master Katalin:<br>
|
||||
Okay, here we go again.
|
||||
</body></html>
|
@@ -1,7 +0,0 @@
|
||||
<html><body>Master Katalin:<br>
|
||||
Do you know what just happened? You were able to use a lot of abilities when you were in the Wind Spirit Realm. But as you came through the Dimensional Rift, your abilities were locked.<br>
|
||||
But you just unlocked one of those abilities. They call them <font color="LEVEL">Skills</font> here.<br>
|
||||
As you train more, you will be able to get more skills back.<br>
|
||||
Shall we fight a more powerful enemy with your new skill?<br>
|
||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest FaeronTrainingGrounds2 33945-07.html">"Okay."</button>
|
||||
</body></html>
|
@@ -1,3 +0,0 @@
|
||||
<html><body>Master Katalin:<br>
|
||||
This battle won't be easy without your <font color="LEVEL">Skills</font>!
|
||||
</body></html>
|
@@ -1,5 +0,0 @@
|
||||
<html><body>Master Katalin:<br>
|
||||
Good work! I am proud of you.<br>
|
||||
We're done. Let's get out.<br>
|
||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest FaeronTrainingGrounds2 exit_instance">"Okay."</button>
|
||||
</body></html>
|
@@ -1,5 +0,0 @@
|
||||
<html><body>Master Katalin:<br>
|
||||
You can't let your guard down with your enemy in front of you.<br>
|
||||
You must always focus during battle.<br>
|
||||
<Button ALIGN=LEFT ICON="QUEST" action="bypass -h npc_%objectId%_Quest FaeronTrainingGrounds2">Quest</Button>
|
||||
</body></html>
|
@@ -1,311 +0,0 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package instances.FaeronTrainingGrounds2;
|
||||
|
||||
import com.l2jmobius.gameserver.enums.QuestSound;
|
||||
import com.l2jmobius.gameserver.model.Location;
|
||||
import com.l2jmobius.gameserver.model.StatsSet;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.holders.ItemHolder;
|
||||
import com.l2jmobius.gameserver.model.instancezone.Instance;
|
||||
import com.l2jmobius.gameserver.model.quest.QuestState;
|
||||
import com.l2jmobius.gameserver.model.skills.Skill;
|
||||
import com.l2jmobius.gameserver.network.NpcStringId;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ExShowScreenMessage;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.TutorialShowHtml;
|
||||
|
||||
import instances.AbstractInstance;
|
||||
import quests.Q10736_ASpecialPower.Q10736_ASpecialPower;
|
||||
|
||||
/**
|
||||
* Fearon Training Grounds Instance Zone.
|
||||
* @author Sdw, malyelfik
|
||||
*/
|
||||
public final class FaeronTrainingGrounds2 extends AbstractInstance
|
||||
{
|
||||
// NPCs
|
||||
private static final int KATALIN = 33943;
|
||||
private static final int KATALIN_2 = 33945;
|
||||
// Monsters
|
||||
private static final int FLOATO = 27526;
|
||||
private static final int FLOATO2 = 27531;
|
||||
private static final int RATEL = 27527;
|
||||
// Item
|
||||
private static final ItemHolder SOULSHOTS_TRAINING = new ItemHolder(1835, 150);
|
||||
// Locations
|
||||
private static final Location[] MOB_SPAWNS =
|
||||
{
|
||||
new Location(-74760, 240773, -3560),
|
||||
new Location(-74721, 240513, -3584)
|
||||
};
|
||||
// Misc
|
||||
private static final int TEMPLATE_ID = 252;
|
||||
private static final double DAMAGE_BY_SKILL = 0.5d; // Percent
|
||||
|
||||
public FaeronTrainingGrounds2()
|
||||
{
|
||||
super(TEMPLATE_ID);
|
||||
addStartNpc(KATALIN, KATALIN_2);
|
||||
addFirstTalkId(KATALIN_2);
|
||||
addTalkId(KATALIN, KATALIN_2);
|
||||
addKillId(FLOATO, FLOATO2, RATEL);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
final QuestState qs = player.getQuestState(Q10736_ASpecialPower.class.getSimpleName());
|
||||
String htmltext = null;
|
||||
if (qs == null)
|
||||
{
|
||||
return htmltext;
|
||||
}
|
||||
|
||||
switch (event)
|
||||
{
|
||||
case "enter_instance":
|
||||
{
|
||||
enterInstance(player, npc, TEMPLATE_ID);
|
||||
break;
|
||||
}
|
||||
case "exit_instance":
|
||||
{
|
||||
finishInstance(player, 0);
|
||||
break;
|
||||
}
|
||||
case "33945-03.html":
|
||||
{
|
||||
if (qs.isCond(6))
|
||||
{
|
||||
spawnMonsters(RATEL, player);
|
||||
showOnScreenMsg(player, NpcStringId.FIGHT_USING_SKILLS, ExShowScreenMessage.TOP_CENTER, 10000);
|
||||
}
|
||||
else
|
||||
{
|
||||
final int npcId = (qs.isCond(4)) ? FLOATO2 : FLOATO;
|
||||
spawnMonsters(npcId, player);
|
||||
showOnScreenMsg(player, NpcStringId.ATTACK_THE_MONSTER, ExShowScreenMessage.TOP_CENTER, 10000);
|
||||
}
|
||||
htmltext = event;
|
||||
break;
|
||||
}
|
||||
case "33945-07.html":
|
||||
{
|
||||
if (qs.isCond(5))
|
||||
{
|
||||
qs.setCond(6, true);
|
||||
showOnScreenMsg(player, NpcStringId.FIGHT_USING_SKILLS, ExShowScreenMessage.TOP_CENTER, 10000);
|
||||
spawnMonsters(RATEL, player);
|
||||
htmltext = event;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return htmltext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onTalk(L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
final QuestState qs = player.getQuestState(Q10736_ASpecialPower.class.getSimpleName());
|
||||
String htmltext = getNoQuestMsg(player);
|
||||
if (qs == null)
|
||||
{
|
||||
return htmltext;
|
||||
}
|
||||
|
||||
if ((npc.getId() == KATALIN_2) && qs.isStarted())
|
||||
{
|
||||
switch (qs.getCond())
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
qs.setCond(2, true);
|
||||
spawnMonsters(FLOATO, player);
|
||||
htmltext = "33945-01.html";
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
case 4:
|
||||
case 6:
|
||||
{
|
||||
htmltext = "33945-02.html";
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
if (qs.getInt("ss") == 1)
|
||||
{
|
||||
spawnMonsters(FLOATO2, player);
|
||||
qs.setCond(4, true);
|
||||
htmltext = "33945-05.html";
|
||||
}
|
||||
else
|
||||
{
|
||||
qs.set("ss", 1);
|
||||
giveItems(player, SOULSHOTS_TRAINING);
|
||||
showOnScreenMsg(player, NpcStringId.AUTOMATE_SOULSHOT_AS_SHOWN_IN_THE_TUTORIAL, ExShowScreenMessage.TOP_CENTER, 10000);
|
||||
player.sendPacket(new TutorialShowHtml(npc.getObjectId(), "..\\L2Text\\QT_003_bullet_01.htm", TutorialShowHtml.LARGE_WINDOW));
|
||||
htmltext = "33945-04.html";
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 5:
|
||||
{
|
||||
player.sendPacket(new TutorialShowHtml(npc.getObjectId(), "..\\L2Text\\QT_004_skill_01.htm", TutorialShowHtml.LARGE_WINDOW));
|
||||
htmltext = "33945-06.html";
|
||||
break;
|
||||
}
|
||||
case 7:
|
||||
{
|
||||
htmltext = "33945-08.html";
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return htmltext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
|
||||
{
|
||||
// Check if monster is inside instance
|
||||
final Instance world = npc.getInstanceWorld();
|
||||
if (world == null)
|
||||
{
|
||||
return super.onKill(npc, killer, isSummon);
|
||||
}
|
||||
|
||||
// Remove monster from instance spawn holder
|
||||
world.setParameter("Mob" + npc.getScriptValue(), null);
|
||||
|
||||
// Handle quest state
|
||||
final QuestState qs = killer.getQuestState(Q10736_ASpecialPower.class.getSimpleName());
|
||||
if (qs != null)
|
||||
{
|
||||
switch (npc.getId())
|
||||
{
|
||||
case FLOATO:
|
||||
case FLOATO2:
|
||||
{
|
||||
if ((qs.isCond(2) || qs.isCond(4)) && onKillQuestChange(killer, qs))
|
||||
{
|
||||
despawnMonsters(killer);
|
||||
if (qs.isCond(5) && (killer.getLevel() < 5))
|
||||
{
|
||||
addExpAndSp(killer, 1716, 0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case RATEL:
|
||||
{
|
||||
if (qs.isCond(6) && onKillQuestChange(killer, qs))
|
||||
{
|
||||
despawnMonsters(killer);
|
||||
showOnScreenMsg(killer, NpcStringId.TALK_TO_KATALIN_TO_LEAVE_THE_TRAINING_GROUNDS, ExShowScreenMessage.TOP_CENTER, 10000);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return super.onKill(npc, killer, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSkillSee(L2Npc npc, L2PcInstance player, Skill skill, com.l2jmobius.gameserver.model.L2Object[] targets, boolean isSummon)
|
||||
{
|
||||
if (!npc.isDead() && (player.getTarget() == npc))
|
||||
{
|
||||
final double dmg = npc.getMaxHp() * DAMAGE_BY_SKILL;
|
||||
npc.reduceCurrentHp(dmg, player, null);
|
||||
}
|
||||
return super.onSkillSee(npc, player, skill, targets, isSummon);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle death of training monster. When all monsters are killed, quest cond is increased.
|
||||
* @param killer player who killed monster
|
||||
* @param qs quest state of killer
|
||||
* @return {@code true} when all monsters are killed, otherwise {@code false}
|
||||
*/
|
||||
private boolean onKillQuestChange(L2PcInstance killer, QuestState qs)
|
||||
{
|
||||
final int value = qs.getMemoStateEx(Q10736_ASpecialPower.KILL_COUNT_VAR) + 1;
|
||||
if (value >= 2)
|
||||
{
|
||||
qs.setCond(qs.getCond() + 1, true);
|
||||
qs.setMemoStateEx(Q10736_ASpecialPower.KILL_COUNT_VAR, 0);
|
||||
return true;
|
||||
}
|
||||
playSound(killer, QuestSound.ITEMSOUND_QUEST_ITEMGET);
|
||||
qs.setMemoStateEx(Q10736_ASpecialPower.KILL_COUNT_VAR, value);
|
||||
qs.getQuest().sendNpcLogList(killer);
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Spawn training monsters inside instance
|
||||
* @param npcId template id of training monster
|
||||
* @param player player that owns instance
|
||||
*/
|
||||
private void spawnMonsters(int npcId, L2PcInstance player)
|
||||
{
|
||||
final Instance world = player.getInstanceWorld();
|
||||
if (world != null)
|
||||
{
|
||||
final StatsSet params = world.getParameters();
|
||||
for (int i = 0; i < MOB_SPAWNS.length; i++)
|
||||
{
|
||||
if (params.getObject("Mob" + i, L2Npc.class) == null)
|
||||
{
|
||||
final L2Npc npc = addSpawn(npcId, MOB_SPAWNS[i], false, 0, false, world.getId());
|
||||
npc.setScriptValue(i);
|
||||
params.set("Mob" + i, npc);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Despawn training monsters inside instance
|
||||
* @param player player that owns instance
|
||||
*/
|
||||
private void despawnMonsters(L2PcInstance player)
|
||||
{
|
||||
final Instance world = player.getInstanceWorld();
|
||||
if (world != null)
|
||||
{
|
||||
final StatsSet params = world.getParameters();
|
||||
for (int i = 0; i < MOB_SPAWNS.length; i++)
|
||||
{
|
||||
final L2Npc mob = params.getObject("Mob" + i, L2Npc.class);
|
||||
if (mob != null)
|
||||
{
|
||||
mob.deleteMe();
|
||||
params.remove("Mob" + i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new FaeronTrainingGrounds2();
|
||||
}
|
||||
}
|
@@ -1,260 +0,0 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package instances.FortressDungeon;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import com.l2jmobius.commons.util.CommonUtil;
|
||||
import com.l2jmobius.gameserver.ThreadPoolManager;
|
||||
import com.l2jmobius.gameserver.enums.QuestSound;
|
||||
import com.l2jmobius.gameserver.model.Location;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.entity.Fort;
|
||||
import com.l2jmobius.gameserver.model.instancezone.Instance;
|
||||
import com.l2jmobius.gameserver.model.instancezone.InstanceTemplate;
|
||||
import com.l2jmobius.gameserver.model.quest.QuestState;
|
||||
|
||||
import instances.AbstractInstance;
|
||||
import quests.Q00511_AwlUnderFoot.Q00511_AwlUnderFoot;
|
||||
|
||||
/**
|
||||
* <b>Fortress dungeon</b> instance for quest <b>Awl Under Foot (511)</b>
|
||||
* @author malyelfik
|
||||
*/
|
||||
public final class FortressDungeon extends AbstractInstance
|
||||
{
|
||||
// NPCs
|
||||
private static final Map<Integer, Integer> NPCS = new HashMap<>();
|
||||
static
|
||||
{
|
||||
NPCS.put(35666, 22); // Shanty
|
||||
NPCS.put(35698, 23); // Southern
|
||||
NPCS.put(35735, 24); // Hive
|
||||
NPCS.put(35767, 25); // Valley
|
||||
NPCS.put(35804, 26); // Ivory
|
||||
NPCS.put(35835, 27); // Narsell
|
||||
NPCS.put(35867, 28); // Bayou
|
||||
NPCS.put(35904, 29); // White Sands
|
||||
NPCS.put(35936, 30); // Borderland
|
||||
NPCS.put(35974, 31); // Swamp
|
||||
NPCS.put(36011, 32); // Archaic
|
||||
NPCS.put(36043, 33); // Floran
|
||||
NPCS.put(36081, 34); // Cloud Mountain
|
||||
NPCS.put(36118, 35); // Tanor
|
||||
NPCS.put(36149, 36); // Dragonspine
|
||||
NPCS.put(36181, 37); // Antharas
|
||||
NPCS.put(36219, 38); // Western
|
||||
NPCS.put(36257, 39); // Hunter
|
||||
NPCS.put(36294, 40); // Aaru
|
||||
NPCS.put(36326, 41); // Demon
|
||||
NPCS.put(36364, 42); // Monastic
|
||||
}
|
||||
|
||||
// Monsters
|
||||
private static final int[] RAIDS1 =
|
||||
{
|
||||
25572,
|
||||
25575,
|
||||
25578
|
||||
};
|
||||
private static final int[] RAIDS2 =
|
||||
{
|
||||
25579,
|
||||
25582,
|
||||
25585,
|
||||
25588
|
||||
};
|
||||
private static final int[] RAIDS3 =
|
||||
{
|
||||
25589,
|
||||
25592,
|
||||
25593
|
||||
};
|
||||
// Item
|
||||
private static final int MARK = 9797;
|
||||
// Locations
|
||||
private static final Location SPAWN_LOC = new Location(53319, 245814, -6576);
|
||||
// Misc
|
||||
private static final int MARK_COUNT = 2520;
|
||||
private static final long REENTER = 24 * 3600000; // 24 hours
|
||||
private static final Map<Integer, Long> REENETER_HOLDER = new ConcurrentHashMap<>();
|
||||
|
||||
public FortressDungeon()
|
||||
{
|
||||
super(NPCS.values().stream().mapToInt(Integer::valueOf).toArray());
|
||||
// NPCs
|
||||
addStartNpc(NPCS.keySet());
|
||||
addTalkId(NPCS.keySet());
|
||||
// Monsters
|
||||
addKillId(RAIDS1);
|
||||
addKillId(RAIDS2);
|
||||
addKillId(RAIDS3);
|
||||
// Instance
|
||||
addInstanceCreatedId(NPCS.values());
|
||||
addInstanceDestroyId(NPCS.values());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onTalk(L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
final int npcId = npc.getId();
|
||||
if (NPCS.containsKey(npcId))
|
||||
{
|
||||
enterInstance(player, npc, NPCS.get(npcId));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onKill(L2Npc npc, L2PcInstance player, boolean isSummon)
|
||||
{
|
||||
final Instance world = npc.getInstanceWorld();
|
||||
if (world != null)
|
||||
{
|
||||
if (CommonUtil.contains(RAIDS3, npc.getId()))
|
||||
{
|
||||
// Get players with active quest
|
||||
final List<L2PcInstance> members = new ArrayList<>();
|
||||
for (L2PcInstance member : world.getPlayers())
|
||||
{
|
||||
final QuestState qs = member.getQuestState(Q00511_AwlUnderFoot.class.getSimpleName());
|
||||
if ((qs != null) && qs.isCond(1))
|
||||
{
|
||||
members.add(member);
|
||||
}
|
||||
}
|
||||
|
||||
// Distribute marks between them
|
||||
if (!members.isEmpty())
|
||||
{
|
||||
final long itemCount = MARK_COUNT / members.size();
|
||||
for (L2PcInstance member : members)
|
||||
{
|
||||
giveItems(member, MARK, itemCount);
|
||||
playSound(member, QuestSound.ITEMSOUND_QUEST_ITEMGET);
|
||||
}
|
||||
}
|
||||
world.finishInstance();
|
||||
}
|
||||
else
|
||||
{
|
||||
world.incStatus();
|
||||
spawnRaid(world);
|
||||
}
|
||||
}
|
||||
return super.onKill(npc, player, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInstanceCreated(Instance instance, L2PcInstance player)
|
||||
{
|
||||
// Put re-enter for instance
|
||||
REENETER_HOLDER.put(instance.getTemplateId(), System.currentTimeMillis() + REENTER);
|
||||
// Schedule spawn of first raid
|
||||
spawnRaid(instance);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean validateConditions(List<L2PcInstance> group, L2Npc npc, InstanceTemplate template)
|
||||
{
|
||||
final L2PcInstance groupLeader = group.get(0);
|
||||
final Fort fort = npc.getFort();
|
||||
if (fort == null)
|
||||
{
|
||||
showHtmlFile(groupLeader, "noProperPledge.html");
|
||||
return false;
|
||||
}
|
||||
else if (fort.getFortState() == 0)
|
||||
{
|
||||
showHtmlFile(groupLeader, "noContractYet.html");
|
||||
return false;
|
||||
}
|
||||
else if (fort.getFortState() == 2)
|
||||
{
|
||||
showHtmlFile(groupLeader, "noCastleContract.html");
|
||||
return false;
|
||||
}
|
||||
else if (REENETER_HOLDER.containsKey(template.getId()))
|
||||
{
|
||||
final long time = REENETER_HOLDER.get(template.getId());
|
||||
if (time > System.currentTimeMillis())
|
||||
{
|
||||
showHtmlFile(groupLeader, "enterRestricted.html");
|
||||
return false;
|
||||
}
|
||||
REENETER_HOLDER.remove(template.getId());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInstanceDestroy(Instance instance)
|
||||
{
|
||||
// Stop running spawn task
|
||||
final ScheduledFuture<?> task = instance.getParameters().getObject("spawnTask", ScheduledFuture.class);
|
||||
if ((task != null) && !task.isDone())
|
||||
{
|
||||
task.cancel(true);
|
||||
}
|
||||
instance.setParameter("spawnTask", null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Spawn raid boss according to instance status.
|
||||
* @param instance instance world where instance should be spawned
|
||||
*/
|
||||
private void spawnRaid(Instance instance)
|
||||
{
|
||||
final ScheduledFuture<?> spawnTask = ThreadPoolManager.getInstance().scheduleGeneral(() ->
|
||||
{
|
||||
// Get template id of raid
|
||||
final int npcId;
|
||||
switch (instance.getStatus())
|
||||
{
|
||||
case 0:
|
||||
npcId = RAIDS1[getRandom(RAIDS1.length)];
|
||||
break;
|
||||
case 1:
|
||||
npcId = RAIDS2[getRandom(RAIDS2.length)];
|
||||
break;
|
||||
default:
|
||||
npcId = RAIDS3[getRandom(RAIDS3.length)];
|
||||
}
|
||||
|
||||
// Spawn raid
|
||||
addSpawn(npcId, SPAWN_LOC, false, 0, false, instance.getId());
|
||||
|
||||
// Unset spawn task reference
|
||||
instance.setParameter("spawnTask", null);
|
||||
}, 2, TimeUnit.MINUTES);
|
||||
|
||||
// Save timer to instance world
|
||||
instance.setParameter("spawnTask", spawnTask);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new FortressDungeon();
|
||||
}
|
||||
}
|
@@ -1,4 +0,0 @@
|
||||
<html><body>Training is currently closed.<br>
|
||||
You can undertake training once every 24 hours with your clan.<br>
|
||||
If training is closed, check with your clan members to see when the last training session started.
|
||||
</body></html>
|
@@ -1,3 +0,0 @@
|
||||
<html><body>
|
||||
Only a party may enter the camp. Once you begin the training session, you may not attend another one for at least 24 hours.
|
||||
</body></html>
|
@@ -1,3 +0,0 @@
|
||||
<html><body>Off limits! Lord's orders.<br>
|
||||
(You cannot enter the camp with a contract related to the castle.)
|
||||
</body></html>
|
@@ -1,4 +0,0 @@
|
||||
<html><body>
|
||||
The fortress is currently in an unsettled state because our relationship with the castle lord must be clearly determined.<br>
|
||||
(Entry into the camps is only possible after gaining independence from the main castle.)
|
||||
</body></html>
|
@@ -1,3 +0,0 @@
|
||||
<html><body>
|
||||
To enter the Detention Camp, your party must include at least 2 people.
|
||||
</body></html>
|
@@ -1,3 +0,0 @@
|
||||
<html><body>
|
||||
The clan does not possess this fortress.
|
||||
</body></html>
|
@@ -1,4 +0,0 @@
|
||||
<html><body>Kain Van Halter:<br>
|
||||
You're Ertheia. Child of the wind. Why would you try to kill Giselle all the way out here?<br>
|
||||
<Button ALIGN=LEFT ICON="Normal" action="bypass -h Quest FortressOfTheDead 33979-02.html">"I didn't know that it was Giselle. She attacked first!"</button>
|
||||
</body></html>
|
@@ -1,5 +0,0 @@
|
||||
<html><body>Kain Van Halter:<br>
|
||||
That's not a good reason. The fact that you came all the way here alone is suspicious.<br>
|
||||
You were after Giselle's life in the first place!<br>
|
||||
<Button ALIGN=LEFT ICON="Normal" action="bypass -h Quest FortressOfTheDead 33979-03.html">"I have Queen Navari's Mark."</button>
|
||||
</body></html>
|
@@ -1,6 +0,0 @@
|
||||
<html><body>Kain Van Halter:<br>
|
||||
The Queen of Ertheia sent you?<br>
|
||||
All right, then. Since Giselle became very aggressive after becoming a vampire, I will take your word on your dispute.<br>
|
||||
But what brings you all the way here? Why were you looking for Giselle? I can't imagine Ertheia having business with her.<br>
|
||||
<Button ALIGN=LEFT ICON="Normal" action="bypass -h Quest FortressOfTheDead 33979-04.html">"I was looking for you."</button>
|
||||
</body></html>
|
@@ -1,5 +0,0 @@
|
||||
<html><body>Kain Van Halter:<br>
|
||||
Me?<br>
|
||||
What do you want with a wanderer like me? And I don't see why I should even help you. You tried to harm my sister! Good thing I stopped by to check on her.<br>
|
||||
<Button ALIGN=LEFT ICON="Normal" action="bypass -h Quest FortressOfTheDead 33979-05.html">"It's about the Prophecy Machine."</button>
|
||||
</body></html>
|
@@ -1,5 +0,0 @@
|
||||
<html><body>Kain Van Halter:<br>
|
||||
Prophecy Machine?<br>
|
||||
What about the Prophecy Machine?<br>
|
||||
<Button ALIGN=LEFT ICON="Normal" action="bypass -h Quest FortressOfTheDead 33979-06.html">"Here, take a look."</button>
|
||||
</body></html>
|
@@ -1,9 +0,0 @@
|
||||
<html><body>Kain Van Halter:<br>
|
||||
<center><font color="LEVEL">A red river flows...hard frost upon the earth...<br1>
|
||||
One of half-noble blood,<br1>
|
||||
descending with the winds to deliver from...<br1>
|
||||
When joined by one...<br1>
|
||||
The path will open to the Grail.</font></center><br1>
|
||||
So why are you showing me this?<br>
|
||||
<Button ALIGN=LEFT ICON="Normal" action="bypass -h Quest FortressOfTheDead 33979-07.html">"I know that you're interested in the Grail."</button>
|
||||
</body></html>
|
@@ -1,5 +0,0 @@
|
||||
<html><body>Kain Van Halter:<br>
|
||||
I see. Did Karla tell you? So she still remembers me mentioning the Grail that day.<br>
|
||||
Check this out first.<br>
|
||||
<Button ALIGN=LEFT ICON="Normal" action="bypass -h Quest FortressOfTheDead 33979-08.html">"This?"</button>
|
||||
</body></html>
|
@@ -1,6 +0,0 @@
|
||||
<html><body>Kain Van Halter:<br>
|
||||
Surprised? I found it while passing Goddard Territory.<br>
|
||||
This looks similar to the Prophecy Machine that you showed me. It's probably a part of the whole.<br>
|
||||
And about what's written on your machine... I think I know what it's saying.<br>
|
||||
<Button ALIGN=LEFT ICON="Normal" action="bypass -h Quest FortressOfTheDead 33979-09.html">"Do tell."</button>
|
||||
</body></html>
|
@@ -1,6 +0,0 @@
|
||||
<html><body>Kain Van Halter:<br>
|
||||
<font color="LEVEL">A red river flows...Hm. I think I can see where this is going.</font><br>
|
||||
It's talking about this continent. A red river flows...hard frost upon the earth. You see, <font color="LEVEL">Elmore</font> rules over a cold part of the land, which it once shared with Aden as Elmoreden. Now the whole continent is swarming with Shilen's bloody works.<br>
|
||||
But this part is surprising. When joined by one...the path will open to the Grail. Truly?<br>
|
||||
<Button ALIGN=LEFT ICON="Normal" action="bypass -h Quest FortressOfTheDead 33979-10.html">"Who is this one?"</button>
|
||||
</body></html>
|
@@ -1,8 +0,0 @@
|
||||
<html><body>Kain Van Halter:<br>
|
||||
<font color="LEVEL">One of half-noble blood...</font><br>
|
||||
Ha! Even the prophecy of Ertheia describes me so, huh? Well, it's right. My mother was a commoner. A tragic farce, to be loved by the king! So here I am, a prince only in name. And descending with the winds to deliver from...yes, that is me. I happened to save Faeron once. <font color="LEVEL">Kain</font> is your man!<br>
|
||||
The <font color="LEVEL">Grail</font>...if it's the same <font color="LEVEL">Grail</font>, then...anyway, you can read the rest of the prophecy with the fragment that I found, right?<br>
|
||||
Take it. Your village needs it more than I.<br>
|
||||
Hmm? Wait...<br>
|
||||
<Button ALIGN=LEFT ICON="Normal" action="bypass -h Quest FortressOfTheDead spawnWizard">"What?"</button>
|
||||
</body></html>
|
@@ -1,2 +0,0 @@
|
||||
<html><body>Kain Van Halter:<br>
|
||||
Who is that person standing there?</body></html>
|
@@ -1,5 +0,0 @@
|
||||
<html><body>Kain Van Halter:<br>
|
||||
You trespass on the land of death. Who are you?<br1>
|
||||
No matter. You threatened Giselle with harm, and you will answer to me!<br>
|
||||
<Button ALIGN=LEFT ICON="QUEST" action="bypass -h Quest FortressOfTheDead 33979-01.html">Quest</button>
|
||||
</body></html>
|
@@ -1,176 +0,0 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package instances.FortressOfTheDead;
|
||||
|
||||
import com.l2jmobius.gameserver.enums.Movie;
|
||||
import com.l2jmobius.gameserver.model.Location;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.instancezone.Instance;
|
||||
import com.l2jmobius.gameserver.model.quest.QuestState;
|
||||
import com.l2jmobius.gameserver.network.NpcStringId;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ExShowScreenMessage;
|
||||
|
||||
import instances.AbstractInstance;
|
||||
import quests.Q10752_WindsOfFateAPromise.Q10752_WindsOfFateAPromise;
|
||||
|
||||
/**
|
||||
* Fortress of the Dead instance zone.
|
||||
* @author Gladicek
|
||||
*/
|
||||
public final class FortressOfTheDead extends AbstractInstance
|
||||
{
|
||||
// NPCs
|
||||
private static final int BROKEN_BOOKSHELF = 31526;
|
||||
private static final int VAMPIRIC_SOLDIER = 19567;
|
||||
private static final int VON_HELLMAN = 19566;
|
||||
private static final int MYSTERIOUS_WIZARD = 33980;
|
||||
private static final int KAIN_VAN_HALTER = 33979;
|
||||
// Items
|
||||
private static final int KAIN_PROPHECY_MACHINE_FRAGMENT = 39538;
|
||||
// Location
|
||||
private static final Location VON_HELLMAN_LOC = new Location(57963, -28676, 568, 49980);
|
||||
private static final Location MYSTERIOUS_WIZARD_LOC = new Location(57982, -28645, 568);
|
||||
private static final Location KAIN_VAN_HALTER_LOC = new Location(57963, -28676, 568, 49980);
|
||||
// Misc
|
||||
private static final int TEMPLATE_ID = 254;
|
||||
|
||||
public FortressOfTheDead()
|
||||
{
|
||||
super(TEMPLATE_ID);
|
||||
addStartNpc(BROKEN_BOOKSHELF);
|
||||
addFirstTalkId(KAIN_VAN_HALTER);
|
||||
addTalkId(BROKEN_BOOKSHELF, KAIN_VAN_HALTER, MYSTERIOUS_WIZARD);
|
||||
addKillId(VAMPIRIC_SOLDIER, VON_HELLMAN);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
String htmltext = null;
|
||||
|
||||
if (event.equals("enterInstance"))
|
||||
{
|
||||
enterInstance(player, npc, TEMPLATE_ID);
|
||||
}
|
||||
else
|
||||
{
|
||||
final Instance world = npc.getInstanceWorld();
|
||||
if (isInInstance(world))
|
||||
{
|
||||
switch (event)
|
||||
{
|
||||
case "33979-01.html":
|
||||
case "33979-02.html":
|
||||
case "33979-03.html":
|
||||
case "33979-04.html":
|
||||
case "33979-05.html":
|
||||
case "33979-06.html":
|
||||
case "33979-07.html":
|
||||
case "33979-08.html":
|
||||
case "33979-09.html":
|
||||
case "33979-10.html":
|
||||
{
|
||||
htmltext = event;
|
||||
break;
|
||||
}
|
||||
case "exitInstance":
|
||||
{
|
||||
world.finishInstance(0);
|
||||
break;
|
||||
}
|
||||
case "vampire_dead":
|
||||
{
|
||||
addSpawn(VON_HELLMAN, VON_HELLMAN_LOC, false, 0, false, world.getId());
|
||||
break;
|
||||
}
|
||||
case "hellman_dead":
|
||||
{
|
||||
addSpawn(KAIN_VAN_HALTER, KAIN_VAN_HALTER_LOC, false, 0, false, world.getId());
|
||||
break;
|
||||
}
|
||||
case "spawnWizard":
|
||||
{
|
||||
showOnScreenMsg(player, NpcStringId.TALK_TO_THE_MYSTERIOUS_WIZARD, ExShowScreenMessage.TOP_CENTER, 5000);
|
||||
final L2Npc wizzard = addSpawn(MYSTERIOUS_WIZARD, MYSTERIOUS_WIZARD_LOC, true, 0, false, world.getId());
|
||||
wizzard.setSummoner(player);
|
||||
wizzard.setTitle(player.getAppearance().getVisibleName());
|
||||
wizzard.broadcastInfo();
|
||||
htmltext = "33979-11.html";
|
||||
break;
|
||||
}
|
||||
case "endCinematic":
|
||||
{
|
||||
final QuestState qs = player.getQuestState(Q10752_WindsOfFateAPromise.class.getSimpleName());
|
||||
|
||||
if ((qs != null) && qs.isCond(8))
|
||||
{
|
||||
qs.setCond(9, true);
|
||||
giveItems(player, KAIN_PROPHECY_MACHINE_FRAGMENT, 1);
|
||||
}
|
||||
world.getNpc(KAIN_VAN_HALTER).deleteMe();
|
||||
world.getNpc(MYSTERIOUS_WIZARD).deleteMe();
|
||||
playMovie(player, Movie.ERT_QUEST_B);
|
||||
startQuestTimer("exitInstance", 25000, npc, player);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return htmltext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onKill(L2Npc npc, L2PcInstance player, boolean isSummon)
|
||||
{
|
||||
final Instance world = npc.getInstanceWorld();
|
||||
|
||||
if (isInInstance(world))
|
||||
{
|
||||
if (npc.getId() == VAMPIRIC_SOLDIER)
|
||||
{
|
||||
if (world.getAliveNpcs(VAMPIRIC_SOLDIER).isEmpty())
|
||||
{
|
||||
startQuestTimer("vampire_dead", 3000, npc, player);
|
||||
}
|
||||
}
|
||||
else if (npc.getId() == VON_HELLMAN)
|
||||
{
|
||||
npc.deleteMe();
|
||||
playMovie(player, Movie.ERT_QUEST_A);
|
||||
startQuestTimer("hellman_dead", 6000, npc, player);
|
||||
}
|
||||
}
|
||||
return super.onKill(npc, player, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onFirstTalk(L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
final QuestState qs = player.getQuestState(Q10752_WindsOfFateAPromise.class.getSimpleName());
|
||||
if (qs.isCond(8))
|
||||
{
|
||||
return "33979.html";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new FortressOfTheDead();
|
||||
}
|
||||
}
|
@@ -1,4 +0,0 @@
|
||||
<html><body>Seal Control Device:<br>
|
||||
This device controls the seals imprisoning the soul of Hermuncus.<br>
|
||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest HarnakUndergroundRuins activate_seal">Release the seal.</Button>
|
||||
</body></html>
|
@@ -1,658 +0,0 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package instances.HarnakUndergroundRuins;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import com.l2jmobius.gameserver.ai.CtrlIntention;
|
||||
import com.l2jmobius.gameserver.enums.CategoryType;
|
||||
import com.l2jmobius.gameserver.enums.ChatType;
|
||||
import com.l2jmobius.gameserver.enums.Movie;
|
||||
import com.l2jmobius.gameserver.model.Location;
|
||||
import com.l2jmobius.gameserver.model.StatsSet;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Character;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.holders.SkillHolder;
|
||||
import com.l2jmobius.gameserver.model.instancezone.Instance;
|
||||
import com.l2jmobius.gameserver.model.variables.NpcVariables;
|
||||
import com.l2jmobius.gameserver.model.zone.L2ZoneType;
|
||||
import com.l2jmobius.gameserver.network.NpcStringId;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ExSendUIEvent;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ExShowScreenMessage;
|
||||
|
||||
import instances.AbstractInstance;
|
||||
|
||||
/**
|
||||
* Harnak Underground Ruins Instance Zone.
|
||||
* @author Sdw
|
||||
*/
|
||||
public final class HarnakUndergroundRuins extends AbstractInstance
|
||||
{
|
||||
// NPCs
|
||||
private static final int HADEL = 33344;
|
||||
private static final int KRAKIA_BATHUS = 27437;
|
||||
private static final int KRAKIA_CARCASS = 27438;
|
||||
private static final int KRAKIA_LOTUS = 27439;
|
||||
private static final int RAKZAN = 27440;
|
||||
private static final int WEISS_KHAN = 27441;
|
||||
private static final int BAMONTI = 27442;
|
||||
private static final int SEKNUS = 27443;
|
||||
private static final int WEISS_ELE = 27454;
|
||||
private static final int HARNAKS_WRAITH = 27445;
|
||||
private static final int SEAL_CONTROL_DEVICE = 33548;
|
||||
private static final int POWER_SOURCE = 33501;
|
||||
private static final int[] POWER_SOURCES =
|
||||
{
|
||||
33501,
|
||||
33556,
|
||||
33557
|
||||
};
|
||||
// Locations
|
||||
private static final Location NPC_ROOM1_LOC = new Location(-107930, 206328, -10872);
|
||||
// Skills
|
||||
private static final SkillHolder RELEASE_OF_POWER = new SkillHolder(14625, 1);
|
||||
private static final SkillHolder MAXIMUM_DEFENSE = new SkillHolder(14700, 1);
|
||||
private static final SkillHolder LIGHT_HEAL = new SkillHolder(14736, 1);
|
||||
private static final SkillHolder ULTIMATE_BUFF = new SkillHolder(4318, 1);
|
||||
// Misc
|
||||
private static final int TEMPLATE_ID = 195;
|
||||
private static final int ZONE_ROOM_2 = 200032;
|
||||
private static final int ZONE_ROOM_3 = 200033;
|
||||
private static final int DOOR_ONE = 16240100;
|
||||
private static final int DOOR_TWO = 16240102;
|
||||
private static final Map<CategoryType, Integer> MOB_CATEGORY = new HashMap<>();
|
||||
|
||||
static
|
||||
{
|
||||
MOB_CATEGORY.put(CategoryType.SIGEL_CANDIDATE, RAKZAN);
|
||||
MOB_CATEGORY.put(CategoryType.TYRR_CANDIDATE, KRAKIA_BATHUS);
|
||||
MOB_CATEGORY.put(CategoryType.OTHELL_CANDIDATE, BAMONTI);
|
||||
MOB_CATEGORY.put(CategoryType.YUL_CANDIDATE, KRAKIA_CARCASS);
|
||||
MOB_CATEGORY.put(CategoryType.FEOH_CANDIDATE, WEISS_KHAN);
|
||||
MOB_CATEGORY.put(CategoryType.ISS_CANDIDATE, SEKNUS);
|
||||
MOB_CATEGORY.put(CategoryType.WYNN_CANDIDATE, KRAKIA_LOTUS);
|
||||
MOB_CATEGORY.put(CategoryType.AEORE_CANDIDATE, WEISS_ELE);
|
||||
}
|
||||
|
||||
public HarnakUndergroundRuins()
|
||||
{
|
||||
super(TEMPLATE_ID);
|
||||
registerMobs(KRAKIA_BATHUS, KRAKIA_CARCASS, KRAKIA_LOTUS, RAKZAN, WEISS_KHAN, BAMONTI, SEKNUS, WEISS_ELE, HARNAKS_WRAITH);
|
||||
addSeeCreatureId(POWER_SOURCES);
|
||||
addEnterZoneId(ZONE_ROOM_2, ZONE_ROOM_3);
|
||||
addFirstTalkId(SEAL_CONTROL_DEVICE);
|
||||
addTalkId(HADEL);
|
||||
addStartNpc(HADEL);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onEnter(L2PcInstance player, Instance instance, boolean firstEnter)
|
||||
{
|
||||
super.onEnter(player, instance, firstEnter);
|
||||
if (firstEnter)
|
||||
{
|
||||
startQuestTimer("fail_instance", 1260000, null, player);
|
||||
startQuestTimer("message1", 2500, null, player);
|
||||
startQuestTimer("message2", 5000, null, player);
|
||||
startQuestTimer("message3", 8500, null, player);
|
||||
startQuestTimer("spawn_npc1", 10000, null, player);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
switch (event)
|
||||
{
|
||||
case "enter_instance":
|
||||
enterInstance(player, npc, TEMPLATE_ID);
|
||||
break;
|
||||
case "message1":
|
||||
showOnScreenMsg(player, NpcStringId.AN_INTRUDER_INTERESTING, ExShowScreenMessage.TOP_CENTER, 5000);
|
||||
break;
|
||||
case "message2":
|
||||
showOnScreenMsg(player, NpcStringId.PROVE_YOUR_WORTH, ExShowScreenMessage.TOP_CENTER, 5000);
|
||||
break;
|
||||
case "message3":
|
||||
showOnScreenMsg(player, NpcStringId.ONLY_THOSE_STRONG_ENOUGH_SHALL_PROCEED, ExShowScreenMessage.TOP_CENTER, 5000);
|
||||
break;
|
||||
case "message4":
|
||||
showOnScreenMsg(player, NpcStringId.THOUGH_SMALL_THIS_POWER_WILL_HELP_YOU_GREATLY, ExShowScreenMessage.TOP_CENTER, 5000);
|
||||
break;
|
||||
case "message5":
|
||||
showOnScreenMsg(player, NpcStringId.ARE_YOU_STRONG_OR_WEAK_OF_THE_LIGHT_OR_DARKNESS, ExShowScreenMessage.TOP_CENTER, 5000);
|
||||
break;
|
||||
case "message6":
|
||||
showOnScreenMsg(player, NpcStringId.ONLY_THOSE_OF_LIGHT_MAY_PASS_OTHERS_MUST_PROVE_THEIR_STRENGTH, ExShowScreenMessage.TOP_CENTER, 5000);
|
||||
break;
|
||||
case "razkan_say":
|
||||
npc.broadcastSay(ChatType.NPC_GENERAL, NpcStringId.COME_ATTACK_ME_IF_YOU_DARE);
|
||||
break;
|
||||
case "bathus_say":
|
||||
npc.broadcastSay(ChatType.NPC_GENERAL, NpcStringId.IT_S_THE_END_FOR_YOU_TRAITOR);
|
||||
break;
|
||||
case "bamonti_say":
|
||||
npc.broadcastSay(ChatType.NPC_GENERAL, NpcStringId.I_WANT_TO_HEAR_YOU_CRY);
|
||||
break;
|
||||
case "carcass_say":
|
||||
npc.broadcastSay(ChatType.NPC_GENERAL, NpcStringId.I_WANT_TO_HEAR_YOU_CRY);
|
||||
break;
|
||||
case "khan_say":
|
||||
npc.broadcastSay(ChatType.NPC_GENERAL, NpcStringId.YOU_LL_HAVE_TO_KILL_US_FIRST);
|
||||
break;
|
||||
case "seknus_say":
|
||||
npc.broadcastSay(ChatType.NPC_GENERAL, NpcStringId.LETS_SEE_WHAT_YOU_ARE_MADE_OF);
|
||||
break;
|
||||
case "lotus_say":
|
||||
npc.broadcastSay(ChatType.NPC_GENERAL, NpcStringId.REPENT_AND_YOUR_DEATH_WILL_BE_QUICK);
|
||||
break;
|
||||
case "ele_say":
|
||||
npc.broadcastSay(ChatType.NPC_GENERAL, NpcStringId.DIE_TRAITOR);
|
||||
break;
|
||||
case "spawn_npc1":
|
||||
{
|
||||
final Instance world = player.getInstanceWorld();
|
||||
if (world != null)
|
||||
{
|
||||
world.setStatus(1);
|
||||
world.spawnGroup("first_room");
|
||||
moveNpcRoom1(RAKZAN, NpcStringId.ARE_YOU_AGAINST_THE_WILL_OF_LIGHT, "razkan_say", world);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "spawn_npc2":
|
||||
{
|
||||
final Instance world = player.getInstanceWorld();
|
||||
if (world != null)
|
||||
{
|
||||
world.openCloseDoor(DOOR_ONE, true);
|
||||
world.spawnGroup("power_sources");
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "spawn_npc3":
|
||||
{
|
||||
final Instance world = player.getInstanceWorld();
|
||||
if (world != null)
|
||||
{
|
||||
world.incStatus();
|
||||
final List<L2Npc> npcs = world.spawnGroup("third_room");
|
||||
final L2Npc powerSource = npcs.stream().filter(n -> n.getId() == POWER_SOURCE).findFirst().orElse(null);
|
||||
if (powerSource != null)
|
||||
{
|
||||
powerSource.setTarget(player);
|
||||
startQuestTimer("cast_light_heal", 3000, powerSource, player);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "spawn_wave1":
|
||||
{
|
||||
final Instance world = player.getInstanceWorld();
|
||||
if (world != null)
|
||||
{
|
||||
for (Entry<CategoryType, Integer> entry : MOB_CATEGORY.entrySet())
|
||||
{
|
||||
if (player.isInCategory(entry.getKey()))
|
||||
{
|
||||
world.setStatus(2);
|
||||
world.setParameter("wave", 1);
|
||||
world.setParameter("waveNpcId", entry.getValue());
|
||||
final List<L2Npc> npcs = world.spawnGroup("second_room_wave_1_" + entry.getValue());
|
||||
for (L2Npc n : npcs)
|
||||
{
|
||||
addAttackPlayerDesire(n, player);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "spawn_wave2":
|
||||
{
|
||||
final Instance world = player.getInstanceWorld();
|
||||
if (world != null)
|
||||
{
|
||||
final int waveNpcId = world.getParameters().getInt("waveNpcId");
|
||||
final List<L2Npc> npcs = world.spawnGroup("second_room_wave_2_" + waveNpcId);
|
||||
for (L2Npc n : npcs)
|
||||
{
|
||||
addAttackPlayerDesire(n, player);
|
||||
}
|
||||
world.setParameter("wave", 2);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "spawn_wave3":
|
||||
{
|
||||
showOnScreenMsg(player, NpcStringId.I_MUST_GO_HELP_SOME_MORE, ExShowScreenMessage.TOP_CENTER, 5000);
|
||||
|
||||
final Instance world = player.getInstanceWorld();
|
||||
if (world != null)
|
||||
{
|
||||
final int waveNpcId = world.getParameters().getInt("waveNpcId");
|
||||
List<L2Npc> npcs = world.spawnGroup("second_room_wave_3_" + waveNpcId);
|
||||
for (L2Npc n : npcs)
|
||||
{
|
||||
addAttackPlayerDesire(n, player);
|
||||
}
|
||||
|
||||
npcs = world.spawnGroup("power_source");
|
||||
for (L2Npc n : npcs)
|
||||
{
|
||||
n.setTarget(player);
|
||||
startQuestTimer("cast_defense_maximum", 1, n, player);
|
||||
}
|
||||
world.setParameter("wave", 3);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "cast_defense_maximum":
|
||||
{
|
||||
final Instance world = player.getInstanceWorld();
|
||||
if (world != null)
|
||||
{
|
||||
if (npc.calculateDistance(player, true, false) < MAXIMUM_DEFENSE.getSkill().getCastRange())
|
||||
{
|
||||
npc.doCast(MAXIMUM_DEFENSE.getSkill());
|
||||
|
||||
final int defenseCounter = world.getParameters().getInt("defenseCounter", 0) + 1;
|
||||
world.setParameter("defenseCounter", defenseCounter);
|
||||
if (defenseCounter < 3)
|
||||
{
|
||||
startQuestTimer("cast_defense_maximum", 60000, npc, player);
|
||||
}
|
||||
else
|
||||
{
|
||||
npc.deleteMe();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
startQuestTimer("cast_defense_maximum", 1, npc, player);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "cast_light_heal":
|
||||
{
|
||||
if (npc != null)
|
||||
{
|
||||
final Instance world = player.getInstanceWorld();
|
||||
if ((world != null) && (world.isStatus(3) || world.isStatus(4)))
|
||||
{
|
||||
if (npc.calculateDistance(player, true, false) < LIGHT_HEAL.getSkill().getCastRange())
|
||||
{
|
||||
npc.doCast(LIGHT_HEAL.getSkill());
|
||||
}
|
||||
startQuestTimer("cast_light_heal", 3000, npc, player);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "fail_instance":
|
||||
{
|
||||
final Instance world = player.getInstanceWorld();
|
||||
if (world != null)
|
||||
{
|
||||
world.removeNpcs();
|
||||
playMovie(player, Movie.SC_AWAKENING_BOSS_ENDING_B);
|
||||
startQuestTimer("exit", 13500, npc, player);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "exit":
|
||||
finishInstance(player, 0);
|
||||
break;
|
||||
case "spawn_npc4":
|
||||
{
|
||||
final Instance world = player.getInstanceWorld();
|
||||
if (world != null)
|
||||
{
|
||||
final int waveNpcId = world.getParameters().getInt("waveNpcId");
|
||||
List<L2Npc> npcs = world.spawnGroup("third_room_" + waveNpcId);
|
||||
for (L2Npc n : npcs)
|
||||
{
|
||||
addAttackPlayerDesire(n, player);
|
||||
}
|
||||
|
||||
npcs = world.spawnGroup("seal");
|
||||
for (L2Npc n : npcs)
|
||||
{
|
||||
n.broadcastSay(ChatType.NPC_GENERAL, NpcStringId.DISABLE_DEVICE_WILL_GO_OUT_OF_CONTROL_IN_1_MINUTE);
|
||||
startQuestTimer("seal_say", 10000, n, player);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "activate_seal":
|
||||
{
|
||||
final Instance world = player.getInstanceWorld();
|
||||
if ((world != null) && npc.isScriptValue(0))
|
||||
{
|
||||
npc.setScriptValue(1);
|
||||
|
||||
final int enabledSeal = world.getParameters().getInt("enabledSeal", 0) + 1;
|
||||
world.setParameter("enabledSeal", enabledSeal);
|
||||
if (enabledSeal == 2)
|
||||
{
|
||||
cancelQuestTimer("fail_instance", null, player);
|
||||
world.removeNpcs();
|
||||
playMovie(player, Movie.SC_AWAKENING_BOSS_ENDING_A);
|
||||
startQuestTimer("spawn_hermuncus", 25050, npc, player);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "seal_say":
|
||||
{
|
||||
final Instance world = player.getInstanceWorld();
|
||||
if (world != null)
|
||||
{
|
||||
final int timerCount = world.getParameters().getInt("timerCount", 0);
|
||||
switch (timerCount)
|
||||
{
|
||||
case 0:
|
||||
npc.broadcastSay(ChatType.NPC_SHOUT, NpcStringId.SECONDS_ARE_REMAINING41);
|
||||
break;
|
||||
case 1:
|
||||
npc.broadcastSay(ChatType.NPC_SHOUT, NpcStringId.SECONDS_ARE_REMAINING42);
|
||||
break;
|
||||
case 2:
|
||||
npc.broadcastSay(ChatType.NPC_SHOUT, NpcStringId.SECONDS_ARE_REMAINING43);
|
||||
break;
|
||||
case 3:
|
||||
npc.broadcastSay(ChatType.NPC_SHOUT, NpcStringId.SECONDS_ARE_REMAINING44);
|
||||
break;
|
||||
case 4:
|
||||
npc.broadcastSay(ChatType.NPC_SHOUT, NpcStringId.SECONDS_ARE_REMAINING45);
|
||||
break;
|
||||
case 5:
|
||||
npc.broadcastSay(ChatType.NPC_SHOUT, NpcStringId.SECONDS);
|
||||
break;
|
||||
case 6:
|
||||
npc.broadcastSay(ChatType.NPC_SHOUT, NpcStringId.SECONDS2);
|
||||
break;
|
||||
case 7:
|
||||
npc.broadcastSay(ChatType.NPC_SHOUT, NpcStringId.SECONDS3);
|
||||
break;
|
||||
case 8:
|
||||
npc.broadcastSay(ChatType.NPC_SHOUT, NpcStringId.SECONDS4);
|
||||
break;
|
||||
case 9:
|
||||
npc.broadcastSay(ChatType.NPC_SHOUT, NpcStringId.SECOND);
|
||||
break;
|
||||
}
|
||||
if (timerCount <= 4)
|
||||
{
|
||||
startQuestTimer("seal_say", 10000, npc, player);
|
||||
}
|
||||
else if ((timerCount > 4) && (timerCount <= 9))
|
||||
{
|
||||
startQuestTimer("seal_say", 1000, npc, player);
|
||||
}
|
||||
world.setParameter("timerCount", timerCount);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "spawn_hermuncus":
|
||||
{
|
||||
final Instance inst = player.getInstanceWorld();
|
||||
if (inst != null)
|
||||
{
|
||||
inst.spawnGroup("hermuncus");
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "cast_release_power":
|
||||
{
|
||||
npc.setTarget(player);
|
||||
npc.doCast(RELEASE_OF_POWER.getSkill());
|
||||
break;
|
||||
}
|
||||
case "whisper_to_player":
|
||||
{
|
||||
showOnScreenMsg(player, NpcStringId.I_HERMUNCUS_GIVE_MY_POWER_TO_THOSE_WHO_FIGHT_FOR_ME, ExShowScreenMessage.TOP_CENTER, 5000);
|
||||
|
||||
npc.broadcastSay(ChatType.WHISPER, NpcStringId.RECEIVE_THIS_POWER_FORM_THE_ANCIENT_GIANT);
|
||||
npc.broadcastSay(ChatType.WHISPER, NpcStringId.USE_THIS_NEW_POWER_WHEN_THE_TIME_IS_RIGHT);
|
||||
|
||||
startQuestTimer("message4", 3000, npc, player);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
|
||||
{
|
||||
final Instance world = killer.getInstanceWorld();
|
||||
if (world != null)
|
||||
{
|
||||
switch (world.getStatus())
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
if (world.getAliveNpcs().isEmpty())
|
||||
{
|
||||
startQuestTimer("spawn_npc2", 100, npc, killer);
|
||||
world.setStatus(1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
switch (npc.getId())
|
||||
{
|
||||
case RAKZAN:
|
||||
moveNpcRoom1(KRAKIA_BATHUS, NpcStringId.ARE_YOU_PLANNING_TO_BETRAY_THE_GODS_AND_FOLLOW_A_GIANT, "bathus_say", world);
|
||||
break;
|
||||
case KRAKIA_BATHUS:
|
||||
moveNpcRoom1(BAMONTI, NpcStringId.HAHA, "bamonti_say", world);
|
||||
break;
|
||||
case BAMONTI:
|
||||
moveNpcRoom1(KRAKIA_CARCASS, NpcStringId.HAHA, "carcass_say", world);
|
||||
break;
|
||||
case KRAKIA_CARCASS:
|
||||
moveNpcRoom1(WEISS_KHAN, NpcStringId.YOU_WILL_NOT_FREE_HERMUNCUS, "khan_say", world);
|
||||
break;
|
||||
case WEISS_KHAN:
|
||||
moveNpcRoom1(SEKNUS, NpcStringId.MORTAL, "seknus_say", world);
|
||||
break;
|
||||
case SEKNUS:
|
||||
moveNpcRoom1(KRAKIA_LOTUS, NpcStringId.TRYING_TO_FREE_HERMUNCUS, "lotus_say", world);
|
||||
break;
|
||||
case KRAKIA_LOTUS:
|
||||
moveNpcRoom1(WEISS_ELE, NpcStringId.YOU_WILL_NEVER_BREAK_THE_SEAL, "ele_say", world);
|
||||
break;
|
||||
case WEISS_ELE:
|
||||
startQuestTimer("spawn_npc2", 100, npc, killer);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
final StatsSet params = world.getParameters();
|
||||
final int waveNpc = params.getInt("waveNpcId");
|
||||
if (world.getAliveNpcs(waveNpc).isEmpty())
|
||||
{
|
||||
switch (params.getInt("wave"))
|
||||
{
|
||||
case 1:
|
||||
startQuestTimer("spawn_wave2", 100, npc, killer);
|
||||
break;
|
||||
case 2:
|
||||
startQuestTimer("spawn_wave3", 100, npc, killer);
|
||||
break;
|
||||
case 3:
|
||||
world.openCloseDoor(DOOR_TWO, true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
if (npc.getId() == HARNAKS_WRAITH)
|
||||
{
|
||||
cancelQuestTimer("fail_instance", null, killer);
|
||||
world.removeNpcs();
|
||||
playMovie(killer, Movie.SC_AWAKENING_BOSS_ENDING_A);
|
||||
startQuestTimer("spawn_hermuncus", 25050, npc, killer);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return super.onKill(npc, killer, isSummon);
|
||||
}
|
||||
|
||||
private void moveNpcRoom1(int npcId, NpcStringId message, String timer, Instance world)
|
||||
{
|
||||
final L2Npc npc = world.getNpc(npcId);
|
||||
if (npc != null)
|
||||
{
|
||||
npc.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, NPC_ROOM1_LOC);
|
||||
npc.broadcastSay(ChatType.NPC_GENERAL, message);
|
||||
startQuestTimer("timer", 2600, npc, null);
|
||||
world.setParameter("currentNpc", npcId);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAttack(L2Npc npc, L2PcInstance player, int damage, boolean isSummon)
|
||||
{
|
||||
final Instance world = player.getInstanceWorld();
|
||||
if (world != null)
|
||||
{
|
||||
if (world.isStatus(1))
|
||||
{
|
||||
final int currentNpc = world.getParameters().getInt("currentNpc");
|
||||
if (npc.getId() != currentNpc)
|
||||
{
|
||||
world.setStatus(0);
|
||||
for (L2Npc n : world.getAliveNpcs())
|
||||
{
|
||||
addAttackPlayerDesire(n, player);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (world.isStatus(2))
|
||||
{
|
||||
if (((npc.getCurrentHp() / npc.getMaxHp()) * 100) < 80)
|
||||
{
|
||||
npc.doCast(ULTIMATE_BUFF.getSkill());
|
||||
}
|
||||
}
|
||||
else if (world.isStatus(3) && (npc.getId() == HARNAKS_WRAITH))
|
||||
{
|
||||
final NpcVariables vars = npc.getVariables();
|
||||
if (!vars.getBoolean("message1", false) && (((npc.getCurrentHp() / npc.getMaxHp()) * 100) > 80))
|
||||
{
|
||||
showOnScreenMsg(player, NpcStringId.FREE_ME_FROM_THIS_BINDING_OF_LIGHT, ExShowScreenMessage.TOP_CENTER, 5000);
|
||||
vars.set("message1", true);
|
||||
}
|
||||
else if (!vars.getBoolean("message2", false) && (((npc.getCurrentHp() / npc.getMaxHp()) * 100) <= 80))
|
||||
{
|
||||
showOnScreenMsg(player, NpcStringId.DESTROY_THE_GHOST_OF_HARNAK_THIS_CORRUPTED_CREATURE, ExShowScreenMessage.TOP_CENTER, 5000);
|
||||
vars.set("message2", true);
|
||||
}
|
||||
else if (!vars.getBoolean("message3", false) && (((npc.getCurrentHp() / npc.getMaxHp()) * 100) <= 60))
|
||||
{
|
||||
showOnScreenMsg(player, NpcStringId.FREE_ME_AND_I_PROMISE_YOU_THE_POWER_OF_GIANTS, ExShowScreenMessage.TOP_CENTER, 5000);
|
||||
vars.set("message3", true);
|
||||
}
|
||||
else if (((npc.getCurrentHp() / npc.getMaxHp()) * 100) <= 50)
|
||||
{
|
||||
world.incStatus();
|
||||
player.sendPacket(new ExSendUIEvent(player, false, false, 60, 0, NpcStringId.REMAINING_TIME));
|
||||
showOnScreenMsg(player, NpcStringId.NO_THE_SEAL_CONTROLS_HAVE_BEEN_EXPOSED_GUARDS_PROTECT_THE_SEAL_CONTROLS, ExShowScreenMessage.TOP_CENTER, 10000);
|
||||
startQuestTimer("spawn_npc4", 1, npc, player);
|
||||
cancelQuestTimer("fail_instance", null, player);
|
||||
startQuestTimer("fail_instance", 60000, null, player);
|
||||
}
|
||||
}
|
||||
}
|
||||
return super.onAttack(npc, player, damage, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSeeCreature(L2Npc npc, L2Character creature, boolean isSummon)
|
||||
{
|
||||
if (creature.isPlayer())
|
||||
{
|
||||
startQuestTimer("cast_release_power", 2000, npc, creature.getActingPlayer());
|
||||
if (npc.getId() == POWER_SOURCE)
|
||||
{
|
||||
startQuestTimer("whisper_to_player", 2000, npc, creature.getActingPlayer());
|
||||
}
|
||||
}
|
||||
return super.onSeeCreature(npc, creature, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onEnterZone(L2Character character, L2ZoneType zone)
|
||||
{
|
||||
if (!character.isPlayer())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
final L2PcInstance player = character.getActingPlayer();
|
||||
final Instance world = player.getInstanceWorld();
|
||||
if (world != null)
|
||||
{
|
||||
switch (zone.getId())
|
||||
{
|
||||
case ZONE_ROOM_2:
|
||||
{
|
||||
if (world.isStatus(1))
|
||||
{
|
||||
world.incStatus();
|
||||
|
||||
startQuestTimer("message2", 100, null, player);
|
||||
startQuestTimer("message5", 2600, null, player);
|
||||
startQuestTimer("message6", 5100, null, player);
|
||||
startQuestTimer("spawn_wave1", 5100, null, player);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ZONE_ROOM_3:
|
||||
{
|
||||
if (!world.getParameters().getBoolean("openingPlayed", false))
|
||||
{
|
||||
world.setParameter("openingPlayed", true);
|
||||
startQuestTimer("spawn_npc3", 29950, null, player);
|
||||
playMovie(player, Movie.SC_AWAKENING_BOSS_OPENING);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return super.onEnterZone(character, zone);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new HarnakUndergroundRuins();
|
||||
}
|
||||
}
|
@@ -1,70 +0,0 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package instances.JiniaGuildHideout1;
|
||||
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.instancezone.Instance;
|
||||
import com.l2jmobius.gameserver.model.quest.QuestState;
|
||||
|
||||
import instances.AbstractInstance;
|
||||
import quests.Q10284_AcquisitionOfDivineSword.Q10284_AcquisitionOfDivineSword;
|
||||
|
||||
/**
|
||||
* Jinia Guild Hideout instance zone.
|
||||
* @author Adry_85
|
||||
*/
|
||||
public final class JiniaGuildHideout1 extends AbstractInstance
|
||||
{
|
||||
// NPC
|
||||
private static final int RAFFORTY = 32020;
|
||||
// Misc
|
||||
private static final int TEMPLATE_ID = 140;
|
||||
|
||||
public JiniaGuildHideout1()
|
||||
{
|
||||
super(TEMPLATE_ID);
|
||||
addStartNpc(RAFFORTY);
|
||||
addTalkId(RAFFORTY);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onEnter(L2PcInstance player, Instance instance, boolean firstEnter)
|
||||
{
|
||||
super.onEnter(player, instance, firstEnter);
|
||||
if (firstEnter)
|
||||
{
|
||||
final QuestState qs = player.getQuestState(Q10284_AcquisitionOfDivineSword.class.getSimpleName());
|
||||
if (qs != null)
|
||||
{
|
||||
qs.setCond(2, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onTalk(L2Npc npc, L2PcInstance talker)
|
||||
{
|
||||
enterInstance(talker, npc, TEMPLATE_ID);
|
||||
return super.onTalk(npc, talker);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new JiniaGuildHideout1();
|
||||
}
|
||||
}
|
@@ -1,70 +0,0 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package instances.JiniaGuildHideout2;
|
||||
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.instancezone.Instance;
|
||||
import com.l2jmobius.gameserver.model.quest.QuestState;
|
||||
|
||||
import instances.AbstractInstance;
|
||||
import quests.Q10285_MeetingSirra.Q10285_MeetingSirra;
|
||||
|
||||
/**
|
||||
* Jinia Guild Hideout instance zone.
|
||||
* @author Adry_85
|
||||
*/
|
||||
public final class JiniaGuildHideout2 extends AbstractInstance
|
||||
{
|
||||
// NPC
|
||||
private static final int RAFFORTY = 32020;
|
||||
// Misc
|
||||
private static final int TEMPLATE_ID = 141;
|
||||
|
||||
public JiniaGuildHideout2()
|
||||
{
|
||||
super(TEMPLATE_ID);
|
||||
addStartNpc(RAFFORTY);
|
||||
addTalkId(RAFFORTY);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onEnter(L2PcInstance player, Instance instance, boolean firstEnter)
|
||||
{
|
||||
super.onEnter(player, instance, firstEnter);
|
||||
if (firstEnter)
|
||||
{
|
||||
final QuestState qs = player.getQuestState(Q10285_MeetingSirra.class.getSimpleName());
|
||||
if (qs != null)
|
||||
{
|
||||
qs.setCond(2, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onTalk(L2Npc npc, L2PcInstance talker)
|
||||
{
|
||||
enterInstance(talker, npc, TEMPLATE_ID);
|
||||
return super.onTalk(npc, talker);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new JiniaGuildHideout2();
|
||||
}
|
||||
}
|
@@ -1,70 +0,0 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package instances.JiniaGuildHideout3;
|
||||
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.instancezone.Instance;
|
||||
import com.l2jmobius.gameserver.model.quest.QuestState;
|
||||
|
||||
import instances.AbstractInstance;
|
||||
import quests.Q10286_ReunionWithSirra.Q10286_ReunionWithSirra;
|
||||
|
||||
/**
|
||||
* Jinia Guild Hideout instance zone.
|
||||
* @author Adry_85
|
||||
*/
|
||||
public final class JiniaGuildHideout3 extends AbstractInstance
|
||||
{
|
||||
// NPC
|
||||
private static final int RAFFORTY = 32020;
|
||||
// Misc
|
||||
private static final int TEMPLATE_ID = 145;
|
||||
|
||||
public JiniaGuildHideout3()
|
||||
{
|
||||
super(TEMPLATE_ID);
|
||||
addStartNpc(RAFFORTY);
|
||||
addTalkId(RAFFORTY);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onEnter(L2PcInstance player, Instance instance, boolean firstEnter)
|
||||
{
|
||||
super.onEnter(player, instance, firstEnter);
|
||||
if (firstEnter)
|
||||
{
|
||||
final QuestState qs = player.getQuestState(Q10286_ReunionWithSirra.class.getSimpleName());
|
||||
if (qs != null)
|
||||
{
|
||||
qs.setCond(2, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onTalk(L2Npc npc, L2PcInstance talker)
|
||||
{
|
||||
enterInstance(talker, npc, TEMPLATE_ID);
|
||||
return super.onTalk(npc, talker);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new JiniaGuildHideout3();
|
||||
}
|
||||
}
|
@@ -1,70 +0,0 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package instances.JiniaGuildHideout4;
|
||||
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.instancezone.Instance;
|
||||
import com.l2jmobius.gameserver.model.quest.QuestState;
|
||||
|
||||
import instances.AbstractInstance;
|
||||
import quests.Q10287_StoryOfThoseLeft.Q10287_StoryOfThoseLeft;
|
||||
|
||||
/**
|
||||
* Jinia Guild Hideout instance zone.
|
||||
* @author Adry_85
|
||||
*/
|
||||
public final class JiniaGuildHideout4 extends AbstractInstance
|
||||
{
|
||||
// NPC
|
||||
private static final int RAFFORTY = 32020;
|
||||
// Misc
|
||||
private static final int TEMPLATE_ID = 146;
|
||||
|
||||
public JiniaGuildHideout4()
|
||||
{
|
||||
super(TEMPLATE_ID);
|
||||
addStartNpc(RAFFORTY);
|
||||
addTalkId(RAFFORTY);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onEnter(L2PcInstance player, Instance instance, boolean firstEnter)
|
||||
{
|
||||
super.onEnter(player, instance, firstEnter);
|
||||
if (firstEnter)
|
||||
{
|
||||
final QuestState qs = player.getQuestState(Q10287_StoryOfThoseLeft.class.getSimpleName());
|
||||
if (qs != null)
|
||||
{
|
||||
qs.setCond(2, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onTalk(L2Npc npc, L2PcInstance talker)
|
||||
{
|
||||
enterInstance(talker, npc, TEMPLATE_ID);
|
||||
return super.onTalk(npc, talker);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new JiniaGuildHideout4();
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user