Helios branch.
This commit is contained in:
264
L2J_Mobius_Helios/dist/game/data/scripts/instances/AbstractInstance.java
vendored
Normal file
264
L2J_Mobius_Helios/dist/game/data/scripts/instances/AbstractInstance.java
vendored
Normal file
@@ -0,0 +1,264 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.l2jmobius.commons.util.CommonUtil;
|
||||
import com.l2jmobius.gameserver.enums.InstanceReenterType;
|
||||
import com.l2jmobius.gameserver.instancemanager.InstanceManager;
|
||||
import com.l2jmobius.gameserver.model.Location;
|
||||
import com.l2jmobius.gameserver.model.PcCondOverride;
|
||||
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.instancezone.InstanceTemplate;
|
||||
import com.l2jmobius.gameserver.network.NpcStringId;
|
||||
import com.l2jmobius.gameserver.network.SystemMessageId;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ExShowScreenMessage;
|
||||
|
||||
import ai.AbstractNpcAI;
|
||||
|
||||
/**
|
||||
* Abstract class for Instances.
|
||||
* @author FallenAngel
|
||||
*/
|
||||
public abstract class AbstractInstance extends AbstractNpcAI
|
||||
{
|
||||
private final int[] _templateIds;
|
||||
|
||||
public AbstractInstance(int... templateId)
|
||||
{
|
||||
if (templateId.length == 0)
|
||||
{
|
||||
throw new IllegalStateException("No template ids were provided!");
|
||||
}
|
||||
_templateIds = templateId;
|
||||
}
|
||||
|
||||
public int[] getTemplateId()
|
||||
{
|
||||
return _templateIds;
|
||||
}
|
||||
|
||||
public boolean isInInstance(Instance instance)
|
||||
{
|
||||
return (instance != null) && CommonUtil.contains(_templateIds, instance.getTemplateId());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get instance world associated with {@code player}.<br>
|
||||
* @param player player who wants get instance world
|
||||
* @return instance world if found, otherwise null
|
||||
*/
|
||||
public Instance getPlayerInstance(L2PcInstance player)
|
||||
{
|
||||
return InstanceManager.getInstance().getPlayerInstance(player, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show an on screen message to each player inside instance.
|
||||
* @param instance instance where message should be broadcasted
|
||||
* @param npcStringId the NPC string to display
|
||||
* @param position the position of the message on the screen
|
||||
* @param time the duration of the message in milliseconds
|
||||
* @param params values of parameters to replace in the NPC String (like S1, C1 etc.)
|
||||
*/
|
||||
public void showOnScreenMsg(Instance instance, NpcStringId npcStringId, int position, int time, String... params)
|
||||
{
|
||||
instance.broadcastPacket(new ExShowScreenMessage(npcStringId, position, time, params));
|
||||
}
|
||||
|
||||
/**
|
||||
* Show an on screen message to each player inside instance.
|
||||
* @param instance instance where message should be broadcasted
|
||||
* @param npcStringId the NPC string to display
|
||||
* @param position the position of the message on the screen
|
||||
* @param time the duration of the message in milliseconds
|
||||
* @param showEffect show visual effect near text
|
||||
* @param params values of parameters to replace in the NPC String (like S1, C1 etc.)
|
||||
*/
|
||||
public void showOnScreenMsg(Instance instance, NpcStringId npcStringId, int position, int time, boolean showEffect, String... params)
|
||||
{
|
||||
instance.broadcastPacket(new ExShowScreenMessage(npcStringId, position, time, showEffect, params));
|
||||
}
|
||||
|
||||
/**
|
||||
* Put player into instance world.<br>
|
||||
* If instance world doesn't found for player then try to create new one.
|
||||
* @param player player who wants to enter into instance
|
||||
* @param npc NPC which allows to enter into instance
|
||||
* @param templateId template ID of instance where player wants to enter
|
||||
*/
|
||||
protected final void enterInstance(L2PcInstance player, L2Npc npc, int templateId)
|
||||
{
|
||||
Instance instance = getPlayerInstance(player);
|
||||
if (instance != null) // Player has already any instance active
|
||||
{
|
||||
if (instance.getTemplateId() != templateId)
|
||||
{
|
||||
player.sendPacket(SystemMessageId.YOU_HAVE_ENTERED_ANOTHER_INSTANT_ZONE_THEREFORE_YOU_CANNOT_ENTER_CORRESPONDING_DUNGEON);
|
||||
return;
|
||||
}
|
||||
onEnter(player, instance, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Get instance template
|
||||
final InstanceManager manager = InstanceManager.getInstance();
|
||||
final InstanceTemplate template = manager.getInstanceTemplate(templateId);
|
||||
if (template == null)
|
||||
{
|
||||
_log.warning("Player " + player.getName() + " (" + player.getObjectId() + ") wants to create instance with unknown template id " + templateId + "!");
|
||||
return;
|
||||
}
|
||||
|
||||
// Get instance enter scope
|
||||
final List<L2PcInstance> enterGroup = template.getEnterGroup(player);
|
||||
// When nobody can enter
|
||||
if (enterGroup == null)
|
||||
{
|
||||
_log.warning("Instance " + template.getName() + " (" + templateId + ") has invalid group size limits!");
|
||||
return;
|
||||
}
|
||||
|
||||
// Validate conditions for group
|
||||
if (!player.canOverrideCond(PcCondOverride.INSTANCE_CONDITIONS) && (!template.validateConditions(enterGroup, npc, this::showHtmlFile) || !validateConditions(enterGroup, npc, template)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if maximum world count limit is exceeded
|
||||
if ((template.getMaxWorlds() != -1) && (manager.getWorldCount(templateId) >= template.getMaxWorlds()))
|
||||
{
|
||||
player.sendPacket(SystemMessageId.THE_NUMBER_OF_INSTANT_ZONES_THAT_CAN_BE_CREATED_HAS_BEEN_EXCEEDED_PLEASE_TRY_AGAIN_LATER);
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if any player from enter group has active instance
|
||||
for (L2PcInstance member : enterGroup)
|
||||
{
|
||||
if (getPlayerInstance(member) != null)
|
||||
{
|
||||
enterGroup.forEach(p -> p.sendPacket(SystemMessageId.YOU_HAVE_ENTERED_ANOTHER_INSTANT_ZONE_THEREFORE_YOU_CANNOT_ENTER_CORRESPONDING_DUNGEON));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Create new instance for enter player group
|
||||
instance = manager.createInstance(template, player);
|
||||
|
||||
// Move each player from enter group to instance
|
||||
for (L2PcInstance member : enterGroup)
|
||||
{
|
||||
instance.addAllowed(member);
|
||||
onEnter(member, instance, true);
|
||||
}
|
||||
|
||||
// Apply condition success effects
|
||||
template.applyConditionEffects(enterGroup);
|
||||
|
||||
// Set re-enter for instances with re-enter on start
|
||||
if (instance.getReenterType().equals(InstanceReenterType.ON_ENTER))
|
||||
{
|
||||
instance.setReenterTime();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is called when player enter into instance trough NPC.
|
||||
* @param player player who enter
|
||||
* @param instance instance world where player enter
|
||||
* @param firstEnter when {@code true} player enter first time, otherwise player entered multiple times
|
||||
*/
|
||||
protected void onEnter(L2PcInstance player, Instance instance, boolean firstEnter)
|
||||
{
|
||||
teleportPlayerIn(player, instance);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is used to teleport player into instance by start NPC.<br>
|
||||
* When you override whole method, XML teleport data won't be applied.
|
||||
* @param player player which should be teleported
|
||||
* @param instance instance where player should be teleported
|
||||
*/
|
||||
protected void teleportPlayerIn(L2PcInstance player, Instance instance)
|
||||
{
|
||||
final Location loc = instance.getEnterLocation();
|
||||
if (loc != null)
|
||||
{
|
||||
player.teleToLocation(loc, instance);
|
||||
}
|
||||
else
|
||||
{
|
||||
_log.warning("Missing start location for instance instance.getName() (" + instance.getId() + ")");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is used to teleport player from instance world by NPC.
|
||||
* @param player player which should be ejected
|
||||
* @param instance instance from player should be removed
|
||||
*/
|
||||
protected void teleportPlayerOut(L2PcInstance player, Instance instance)
|
||||
{
|
||||
instance.ejectPlayer(player);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets instance to finish state. <br>
|
||||
* See {@link Instance#finishInstance()} for more details.
|
||||
* @param player player used for determine current instance world
|
||||
*/
|
||||
protected void finishInstance(L2PcInstance player)
|
||||
{
|
||||
final Instance inst = player.getInstanceWorld();
|
||||
if (inst != null)
|
||||
{
|
||||
inst.finishInstance();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets instance to finish state.<br>
|
||||
* See {@link Instance#finishInstance(int)} for more details.
|
||||
* @param player player used for determine current instance world
|
||||
* @param delay finish delay in minutes
|
||||
*/
|
||||
protected void finishInstance(L2PcInstance player, int delay)
|
||||
{
|
||||
final Instance inst = player.getInstanceWorld();
|
||||
if (inst != null)
|
||||
{
|
||||
inst.finishInstance(delay);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is supposed to be used for validation of additional conditions that are too much specific to instance world (to avoid useless core conditions).<br>
|
||||
* These conditions are validated after conditions defined in XML template.
|
||||
* @param group group of players which wants to enter (first player inside list is player who make enter request)
|
||||
* @param npc NPC used for enter
|
||||
* @param template template of instance world which should be created
|
||||
* @return {@code true} when conditions are valid, otherwise {@code false}
|
||||
*/
|
||||
protected boolean validateConditions(List<L2PcInstance> group, L2Npc npc, InstanceTemplate template)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
243
L2J_Mobius_Helios/dist/game/data/scripts/instances/CastleDungeon/CastleDungeon.java
vendored
Normal file
243
L2J_Mobius_Helios/dist/game/data/scripts/instances/CastleDungeon/CastleDungeon.java
vendored
Normal file
@@ -0,0 +1,243 @@
|
||||
/*
|
||||
* 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();
|
||||
}
|
||||
}
|
4
L2J_Mobius_Helios/dist/game/data/scripts/instances/CastleDungeon/enterRestricted.html
vendored
Normal file
4
L2J_Mobius_Helios/dist/game/data/scripts/instances/CastleDungeon/enterRestricted.html
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
<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>
|
3
L2J_Mobius_Helios/dist/game/data/scripts/instances/CastleDungeon/hasReenter.html
vendored
Normal file
3
L2J_Mobius_Helios/dist/game/data/scripts/instances/CastleDungeon/hasReenter.html
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
<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>
|
3
L2J_Mobius_Helios/dist/game/data/scripts/instances/CastleDungeon/noParty.html
vendored
Normal file
3
L2J_Mobius_Helios/dist/game/data/scripts/instances/CastleDungeon/noParty.html
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
<html><body>
|
||||
To enter the prison, your party must include at least 2 people.
|
||||
</body></html>
|
3
L2J_Mobius_Helios/dist/game/data/scripts/instances/CastleDungeon/noProperPledge.html
vendored
Normal file
3
L2J_Mobius_Helios/dist/game/data/scripts/instances/CastleDungeon/noProperPledge.html
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
<html><body>
|
||||
The clan does not possess this castle.
|
||||
</body></html>
|
4
L2J_Mobius_Helios/dist/game/data/scripts/instances/ChamberOfProphecies/33979-01.html
vendored
Normal file
4
L2J_Mobius_Helios/dist/game/data/scripts/instances/ChamberOfProphecies/33979-01.html
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
<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>
|
7
L2J_Mobius_Helios/dist/game/data/scripts/instances/ChamberOfProphecies/33979-02.html
vendored
Normal file
7
L2J_Mobius_Helios/dist/game/data/scripts/instances/ChamberOfProphecies/33979-02.html
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
<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>
|
4
L2J_Mobius_Helios/dist/game/data/scripts/instances/ChamberOfProphecies/33979.html
vendored
Normal file
4
L2J_Mobius_Helios/dist/game/data/scripts/instances/ChamberOfProphecies/33979.html
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
<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>
|
7
L2J_Mobius_Helios/dist/game/data/scripts/instances/ChamberOfProphecies/33980-01.html
vendored
Normal file
7
L2J_Mobius_Helios/dist/game/data/scripts/instances/ChamberOfProphecies/33980-01.html
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
<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>
|
6
L2J_Mobius_Helios/dist/game/data/scripts/instances/ChamberOfProphecies/33980-02.html
vendored
Normal file
6
L2J_Mobius_Helios/dist/game/data/scripts/instances/ChamberOfProphecies/33980-02.html
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
<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>
|
5
L2J_Mobius_Helios/dist/game/data/scripts/instances/ChamberOfProphecies/33980-03.html
vendored
Normal file
5
L2J_Mobius_Helios/dist/game/data/scripts/instances/ChamberOfProphecies/33980-03.html
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
<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>
|
5
L2J_Mobius_Helios/dist/game/data/scripts/instances/ChamberOfProphecies/33980-04.html
vendored
Normal file
5
L2J_Mobius_Helios/dist/game/data/scripts/instances/ChamberOfProphecies/33980-04.html
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
<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>
|
3
L2J_Mobius_Helios/dist/game/data/scripts/instances/ChamberOfProphecies/33980-05.html
vendored
Normal file
3
L2J_Mobius_Helios/dist/game/data/scripts/instances/ChamberOfProphecies/33980-05.html
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
<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>
|
5
L2J_Mobius_Helios/dist/game/data/scripts/instances/ChamberOfProphecies/33980.html
vendored
Normal file
5
L2J_Mobius_Helios/dist/game/data/scripts/instances/ChamberOfProphecies/33980.html
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
<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>
|
5
L2J_Mobius_Helios/dist/game/data/scripts/instances/ChamberOfProphecies/33996-01.html
vendored
Normal file
5
L2J_Mobius_Helios/dist/game/data/scripts/instances/ChamberOfProphecies/33996-01.html
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
<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>
|
3
L2J_Mobius_Helios/dist/game/data/scripts/instances/ChamberOfProphecies/33996-02.html
vendored
Normal file
3
L2J_Mobius_Helios/dist/game/data/scripts/instances/ChamberOfProphecies/33996-02.html
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
<html><body>Grail:<br>
|
||||
The grail disappeared, leaving behind a gem.
|
||||
</body></html>
|
6
L2J_Mobius_Helios/dist/game/data/scripts/instances/ChamberOfProphecies/33996.html
vendored
Normal file
6
L2J_Mobius_Helios/dist/game/data/scripts/instances/ChamberOfProphecies/33996.html
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
<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>
|
468
L2J_Mobius_Helios/dist/game/data/scripts/instances/ChamberOfProphecies/ChamberOfProphecies.java
vendored
Normal file
468
L2J_Mobius_Helios/dist/game/data/scripts/instances/ChamberOfProphecies/ChamberOfProphecies.java
vendored
Normal file
@@ -0,0 +1,468 @@
|
||||
/*
|
||||
* 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();
|
||||
}
|
||||
}
|
450
L2J_Mobius_Helios/dist/game/data/scripts/instances/ChambersOfDelusion/ChamberOfDelusion.java
vendored
Normal file
450
L2J_Mobius_Helios/dist/game/data/scripts/instances/ChambersOfDelusion/ChamberOfDelusion.java
vendored
Normal file
@@ -0,0 +1,450 @@
|
||||
/*
|
||||
* 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();
|
||||
}
|
||||
}
|
3
L2J_Mobius_Helios/dist/game/data/scripts/instances/ChambersOfDelusion/no_item.html
vendored
Normal file
3
L2J_Mobius_Helios/dist/game/data/scripts/instances/ChambersOfDelusion/no_item.html
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
<html><body>Manager:<br>
|
||||
You have already used an opportunity. There are no more.
|
||||
</body></html>
|
3
L2J_Mobius_Helios/dist/game/data/scripts/instances/ChambersOfDelusion/no_leader.html
vendored
Normal file
3
L2J_Mobius_Helios/dist/game/data/scripts/instances/ChambersOfDelusion/no_leader.html
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
<html><body>Manager:<br>
|
||||
You're not a party leader. Please bring the party leader here.
|
||||
</body></html>
|
3
L2J_Mobius_Helios/dist/game/data/scripts/instances/ChambersOfDelusion/no_party.html
vendored
Normal file
3
L2J_Mobius_Helios/dist/game/data/scripts/instances/ChambersOfDelusion/no_party.html
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
<html><body>Manager:<br>
|
||||
You're not a member of a party. Please join one quickly.
|
||||
</body></html>
|
444
L2J_Mobius_Helios/dist/game/data/scripts/instances/DarkCloudMansion/DarkCloudMansion.java
vendored
Normal file
444
L2J_Mobius_Helios/dist/game/data/scripts/instances/DarkCloudMansion/DarkCloudMansion.java
vendored
Normal file
@@ -0,0 +1,444 @@
|
||||
/*
|
||||
* 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();
|
||||
}
|
||||
}
|
4
L2J_Mobius_Helios/dist/game/data/scripts/instances/EvasHiddenSpace/31281-01.html
vendored
Normal file
4
L2J_Mobius_Helios/dist/game/data/scripts/instances/EvasHiddenSpace/31281-01.html
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
<html><body>Priest Cerenas:<br>
|
||||
You are learning, adventurer. I will pray for your illumination.<br>
|
||||
(You have already completed this quest.)
|
||||
</body></html>
|
3
L2J_Mobius_Helios/dist/game/data/scripts/instances/EvasHiddenSpace/31281.html
vendored
Normal file
3
L2J_Mobius_Helios/dist/game/data/scripts/instances/EvasHiddenSpace/31281.html
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
<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>
|
5
L2J_Mobius_Helios/dist/game/data/scripts/instances/EvasHiddenSpace/33686.html
vendored
Normal file
5
L2J_Mobius_Helios/dist/game/data/scripts/instances/EvasHiddenSpace/33686.html
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
<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>
|
93
L2J_Mobius_Helios/dist/game/data/scripts/instances/EvasHiddenSpace/EvasHiddenSpace.java
vendored
Normal file
93
L2J_Mobius_Helios/dist/game/data/scripts/instances/EvasHiddenSpace/EvasHiddenSpace.java
vendored
Normal file
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* 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();
|
||||
}
|
||||
}
|
3
L2J_Mobius_Helios/dist/game/data/scripts/instances/EvilIncubator/33165-01.html
vendored
Normal file
3
L2J_Mobius_Helios/dist/game/data/scripts/instances/EvilIncubator/33165-01.html
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
<html><body>Aden Vanguard Member:<br>
|
||||
Go ahead and speak with the Captain and help the Aden Vanguard out!
|
||||
</body></html>
|
4
L2J_Mobius_Helios/dist/game/data/scripts/instances/EvilIncubator/33170-01.html
vendored
Normal file
4
L2J_Mobius_Helios/dist/game/data/scripts/instances/EvilIncubator/33170-01.html
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
<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>
|
4
L2J_Mobius_Helios/dist/game/data/scripts/instances/EvilIncubator/33170-02.html
vendored
Normal file
4
L2J_Mobius_Helios/dist/game/data/scripts/instances/EvilIncubator/33170-02.html
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
<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>
|
6
L2J_Mobius_Helios/dist/game/data/scripts/instances/EvilIncubator/33170-03.html
vendored
Normal file
6
L2J_Mobius_Helios/dist/game/data/scripts/instances/EvilIncubator/33170-03.html
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
<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>
|
3
L2J_Mobius_Helios/dist/game/data/scripts/instances/EvilIncubator/33170-04.html
vendored
Normal file
3
L2J_Mobius_Helios/dist/game/data/scripts/instances/EvilIncubator/33170-04.html
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
<html><body>Aden Vanguard Captain Adolph:<br>
|
||||
Focus on the enemies in front of you. Looking away in battle is suicide.
|
||||
</body></html>
|
5
L2J_Mobius_Helios/dist/game/data/scripts/instances/EvilIncubator/33170-05.html
vendored
Normal file
5
L2J_Mobius_Helios/dist/game/data/scripts/instances/EvilIncubator/33170-05.html
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
<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>
|
4
L2J_Mobius_Helios/dist/game/data/scripts/instances/EvilIncubator/33170-06.html
vendored
Normal file
4
L2J_Mobius_Helios/dist/game/data/scripts/instances/EvilIncubator/33170-06.html
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
<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>
|
4
L2J_Mobius_Helios/dist/game/data/scripts/instances/EvilIncubator/33170-07.html
vendored
Normal file
4
L2J_Mobius_Helios/dist/game/data/scripts/instances/EvilIncubator/33170-07.html
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
<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>
|
3
L2J_Mobius_Helios/dist/game/data/scripts/instances/EvilIncubator/33170-08.html
vendored
Normal file
3
L2J_Mobius_Helios/dist/game/data/scripts/instances/EvilIncubator/33170-08.html
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
<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>
|
4
L2J_Mobius_Helios/dist/game/data/scripts/instances/EvilIncubator/33170.html
vendored
Normal file
4
L2J_Mobius_Helios/dist/game/data/scripts/instances/EvilIncubator/33170.html
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
<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>
|
3
L2J_Mobius_Helios/dist/game/data/scripts/instances/EvilIncubator/33171-01.html
vendored
Normal file
3
L2J_Mobius_Helios/dist/game/data/scripts/instances/EvilIncubator/33171-01.html
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
<html><body>Priest Alice:<br>
|
||||
Speak with Adolph first.
|
||||
</body></html>
|
4
L2J_Mobius_Helios/dist/game/data/scripts/instances/EvilIncubator/33171-02.html
vendored
Normal file
4
L2J_Mobius_Helios/dist/game/data/scripts/instances/EvilIncubator/33171-02.html
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
<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>
|
3
L2J_Mobius_Helios/dist/game/data/scripts/instances/EvilIncubator/33171-03.html
vendored
Normal file
3
L2J_Mobius_Helios/dist/game/data/scripts/instances/EvilIncubator/33171-03.html
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
<html><body>Alice:<br>
|
||||
This is dangerous. Quit fidgeting and concentrate.
|
||||
</body></html>
|
4
L2J_Mobius_Helios/dist/game/data/scripts/instances/EvilIncubator/33171.html
vendored
Normal file
4
L2J_Mobius_Helios/dist/game/data/scripts/instances/EvilIncubator/33171.html
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
<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>
|
3
L2J_Mobius_Helios/dist/game/data/scripts/instances/EvilIncubator/33172-01.html
vendored
Normal file
3
L2J_Mobius_Helios/dist/game/data/scripts/instances/EvilIncubator/33172-01.html
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
<html><body>Officer Barton:<br>
|
||||
Speak with Adolph.
|
||||
</body></html>
|
4
L2J_Mobius_Helios/dist/game/data/scripts/instances/EvilIncubator/33172-02.html
vendored
Normal file
4
L2J_Mobius_Helios/dist/game/data/scripts/instances/EvilIncubator/33172-02.html
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
<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>
|
3
L2J_Mobius_Helios/dist/game/data/scripts/instances/EvilIncubator/33172-03.html
vendored
Normal file
3
L2J_Mobius_Helios/dist/game/data/scripts/instances/EvilIncubator/33172-03.html
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
<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>
|
4
L2J_Mobius_Helios/dist/game/data/scripts/instances/EvilIncubator/33172.html
vendored
Normal file
4
L2J_Mobius_Helios/dist/game/data/scripts/instances/EvilIncubator/33172.html
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
<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>
|
3
L2J_Mobius_Helios/dist/game/data/scripts/instances/EvilIncubator/33173-01.html
vendored
Normal file
3
L2J_Mobius_Helios/dist/game/data/scripts/instances/EvilIncubator/33173-01.html
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
<html><body>Sniper Hayuk:<br>
|
||||
You don't want to talk to me, you want Captain Adolph.
|
||||
</body></html>
|
4
L2J_Mobius_Helios/dist/game/data/scripts/instances/EvilIncubator/33173-02.html
vendored
Normal file
4
L2J_Mobius_Helios/dist/game/data/scripts/instances/EvilIncubator/33173-02.html
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
<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>
|
3
L2J_Mobius_Helios/dist/game/data/scripts/instances/EvilIncubator/33173-03.html
vendored
Normal file
3
L2J_Mobius_Helios/dist/game/data/scripts/instances/EvilIncubator/33173-03.html
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
<html><body>Hayuk:<br>
|
||||
We are in the middle of a battle. Let's deal with the enemies first.
|
||||
</body></html>
|
4
L2J_Mobius_Helios/dist/game/data/scripts/instances/EvilIncubator/33173.html
vendored
Normal file
4
L2J_Mobius_Helios/dist/game/data/scripts/instances/EvilIncubator/33173.html
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
<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>
|
2
L2J_Mobius_Helios/dist/game/data/scripts/instances/EvilIncubator/33174-01.html
vendored
Normal file
2
L2J_Mobius_Helios/dist/game/data/scripts/instances/EvilIncubator/33174-01.html
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
<html><body>Magus Eliyah:<br>
|
||||
Instead of talking to me, perhaps you should speak with Adolph first?</body></html>
|
4
L2J_Mobius_Helios/dist/game/data/scripts/instances/EvilIncubator/33174-02.html
vendored
Normal file
4
L2J_Mobius_Helios/dist/game/data/scripts/instances/EvilIncubator/33174-02.html
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
<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>
|
3
L2J_Mobius_Helios/dist/game/data/scripts/instances/EvilIncubator/33174-03.html
vendored
Normal file
3
L2J_Mobius_Helios/dist/game/data/scripts/instances/EvilIncubator/33174-03.html
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
<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>
|
4
L2J_Mobius_Helios/dist/game/data/scripts/instances/EvilIncubator/33174.html
vendored
Normal file
4
L2J_Mobius_Helios/dist/game/data/scripts/instances/EvilIncubator/33174.html
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
<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>
|
567
L2J_Mobius_Helios/dist/game/data/scripts/instances/EvilIncubator/EvilIncubator.java
vendored
Normal file
567
L2J_Mobius_Helios/dist/game/data/scripts/instances/EvilIncubator/EvilIncubator.java
vendored
Normal file
@@ -0,0 +1,567 @@
|
||||
/*
|
||||
* 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();
|
||||
}
|
||||
}
|
3
L2J_Mobius_Helios/dist/game/data/scripts/instances/FaeronTrainingGrounds1/33944-01.html
vendored
Normal file
3
L2J_Mobius_Helios/dist/game/data/scripts/instances/FaeronTrainingGrounds1/33944-01.html
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
<html><body>Magister Ayanthe:<br>
|
||||
The monsters are coming. Concentrate and attack!
|
||||
</body></html>
|
4
L2J_Mobius_Helios/dist/game/data/scripts/instances/FaeronTrainingGrounds1/33944-02.html
vendored
Normal file
4
L2J_Mobius_Helios/dist/game/data/scripts/instances/FaeronTrainingGrounds1/33944-02.html
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
<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>
|
4
L2J_Mobius_Helios/dist/game/data/scripts/instances/FaeronTrainingGrounds1/33944-03.html
vendored
Normal file
4
L2J_Mobius_Helios/dist/game/data/scripts/instances/FaeronTrainingGrounds1/33944-03.html
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
<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>
|
7
L2J_Mobius_Helios/dist/game/data/scripts/instances/FaeronTrainingGrounds1/33944-04.html
vendored
Normal file
7
L2J_Mobius_Helios/dist/game/data/scripts/instances/FaeronTrainingGrounds1/33944-04.html
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
<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>
|
3
L2J_Mobius_Helios/dist/game/data/scripts/instances/FaeronTrainingGrounds1/33944-05.html
vendored
Normal file
3
L2J_Mobius_Helios/dist/game/data/scripts/instances/FaeronTrainingGrounds1/33944-05.html
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
<html><head><body>Magister Ayanthe:<br>
|
||||
All right, now your training begins again!
|
||||
</body></html>
|
6
L2J_Mobius_Helios/dist/game/data/scripts/instances/FaeronTrainingGrounds1/33944-06.html
vendored
Normal file
6
L2J_Mobius_Helios/dist/game/data/scripts/instances/FaeronTrainingGrounds1/33944-06.html
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
<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>
|
3
L2J_Mobius_Helios/dist/game/data/scripts/instances/FaeronTrainingGrounds1/33944-07.html
vendored
Normal file
3
L2J_Mobius_Helios/dist/game/data/scripts/instances/FaeronTrainingGrounds1/33944-07.html
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
<html><body>Magister Ayanthe:<br>
|
||||
If you don't use your <font color="LEVEL">skills</font>, this next battle will be difficult!
|
||||
</body></html>
|
4
L2J_Mobius_Helios/dist/game/data/scripts/instances/FaeronTrainingGrounds1/33944-08.html
vendored
Normal file
4
L2J_Mobius_Helios/dist/game/data/scripts/instances/FaeronTrainingGrounds1/33944-08.html
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
<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>
|
5
L2J_Mobius_Helios/dist/game/data/scripts/instances/FaeronTrainingGrounds1/33944.html
vendored
Normal file
5
L2J_Mobius_Helios/dist/game/data/scripts/instances/FaeronTrainingGrounds1/33944.html
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
<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>
|
@@ -0,0 +1,310 @@
|
||||
/*
|
||||
* 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();
|
||||
}
|
||||
}
|
4
L2J_Mobius_Helios/dist/game/data/scripts/instances/FaeronTrainingGrounds2/33945-01.html
vendored
Normal file
4
L2J_Mobius_Helios/dist/game/data/scripts/instances/FaeronTrainingGrounds2/33945-01.html
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
<html><body>Master Katalin:<br>
|
||||
The monsters are here.<br>
|
||||
Stay focused in battle and take care not to get hurt.
|
||||
</body></html>
|
4
L2J_Mobius_Helios/dist/game/data/scripts/instances/FaeronTrainingGrounds2/33945-02.html
vendored
Normal file
4
L2J_Mobius_Helios/dist/game/data/scripts/instances/FaeronTrainingGrounds2/33945-02.html
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
<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>
|
4
L2J_Mobius_Helios/dist/game/data/scripts/instances/FaeronTrainingGrounds2/33945-03.html
vendored
Normal file
4
L2J_Mobius_Helios/dist/game/data/scripts/instances/FaeronTrainingGrounds2/33945-03.html
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
<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>
|
7
L2J_Mobius_Helios/dist/game/data/scripts/instances/FaeronTrainingGrounds2/33945-04.html
vendored
Normal file
7
L2J_Mobius_Helios/dist/game/data/scripts/instances/FaeronTrainingGrounds2/33945-04.html
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
<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>
|
3
L2J_Mobius_Helios/dist/game/data/scripts/instances/FaeronTrainingGrounds2/33945-05.html
vendored
Normal file
3
L2J_Mobius_Helios/dist/game/data/scripts/instances/FaeronTrainingGrounds2/33945-05.html
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
<html><body>Master Katalin:<br>
|
||||
Okay, here we go again.
|
||||
</body></html>
|
7
L2J_Mobius_Helios/dist/game/data/scripts/instances/FaeronTrainingGrounds2/33945-06.html
vendored
Normal file
7
L2J_Mobius_Helios/dist/game/data/scripts/instances/FaeronTrainingGrounds2/33945-06.html
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
<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>
|
3
L2J_Mobius_Helios/dist/game/data/scripts/instances/FaeronTrainingGrounds2/33945-07.html
vendored
Normal file
3
L2J_Mobius_Helios/dist/game/data/scripts/instances/FaeronTrainingGrounds2/33945-07.html
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
<html><body>Master Katalin:<br>
|
||||
This battle won't be easy without your <font color="LEVEL">Skills</font>!
|
||||
</body></html>
|
5
L2J_Mobius_Helios/dist/game/data/scripts/instances/FaeronTrainingGrounds2/33945-08.html
vendored
Normal file
5
L2J_Mobius_Helios/dist/game/data/scripts/instances/FaeronTrainingGrounds2/33945-08.html
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
<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>
|
5
L2J_Mobius_Helios/dist/game/data/scripts/instances/FaeronTrainingGrounds2/33945.html
vendored
Normal file
5
L2J_Mobius_Helios/dist/game/data/scripts/instances/FaeronTrainingGrounds2/33945.html
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
<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>
|
@@ -0,0 +1,311 @@
|
||||
/*
|
||||
* 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();
|
||||
}
|
||||
}
|
260
L2J_Mobius_Helios/dist/game/data/scripts/instances/FortressDungeon/FortressDungeon.java
vendored
Normal file
260
L2J_Mobius_Helios/dist/game/data/scripts/instances/FortressDungeon/FortressDungeon.java
vendored
Normal file
@@ -0,0 +1,260 @@
|
||||
/*
|
||||
* 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();
|
||||
}
|
||||
}
|
4
L2J_Mobius_Helios/dist/game/data/scripts/instances/FortressDungeon/enterRestricted.html
vendored
Normal file
4
L2J_Mobius_Helios/dist/game/data/scripts/instances/FortressDungeon/enterRestricted.html
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
<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>
|
3
L2J_Mobius_Helios/dist/game/data/scripts/instances/FortressDungeon/hasReenter.html
vendored
Normal file
3
L2J_Mobius_Helios/dist/game/data/scripts/instances/FortressDungeon/hasReenter.html
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
<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>
|
3
L2J_Mobius_Helios/dist/game/data/scripts/instances/FortressDungeon/noCastleContract.html
vendored
Normal file
3
L2J_Mobius_Helios/dist/game/data/scripts/instances/FortressDungeon/noCastleContract.html
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
<html><body>Off limits! Lord's orders.<br>
|
||||
(You cannot enter the camp with a contract related to the castle.)
|
||||
</body></html>
|
4
L2J_Mobius_Helios/dist/game/data/scripts/instances/FortressDungeon/noContractYet.html
vendored
Normal file
4
L2J_Mobius_Helios/dist/game/data/scripts/instances/FortressDungeon/noContractYet.html
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
<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>
|
3
L2J_Mobius_Helios/dist/game/data/scripts/instances/FortressDungeon/noParty.html
vendored
Normal file
3
L2J_Mobius_Helios/dist/game/data/scripts/instances/FortressDungeon/noParty.html
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
<html><body>
|
||||
To enter the Detention Camp, your party must include at least 2 people.
|
||||
</body></html>
|
3
L2J_Mobius_Helios/dist/game/data/scripts/instances/FortressDungeon/noProperPledge.html
vendored
Normal file
3
L2J_Mobius_Helios/dist/game/data/scripts/instances/FortressDungeon/noProperPledge.html
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
<html><body>
|
||||
The clan does not possess this fortress.
|
||||
</body></html>
|
4
L2J_Mobius_Helios/dist/game/data/scripts/instances/FortressOfTheDead/33979-01.html
vendored
Normal file
4
L2J_Mobius_Helios/dist/game/data/scripts/instances/FortressOfTheDead/33979-01.html
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
<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>
|
5
L2J_Mobius_Helios/dist/game/data/scripts/instances/FortressOfTheDead/33979-02.html
vendored
Normal file
5
L2J_Mobius_Helios/dist/game/data/scripts/instances/FortressOfTheDead/33979-02.html
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
<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>
|
6
L2J_Mobius_Helios/dist/game/data/scripts/instances/FortressOfTheDead/33979-03.html
vendored
Normal file
6
L2J_Mobius_Helios/dist/game/data/scripts/instances/FortressOfTheDead/33979-03.html
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
<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>
|
5
L2J_Mobius_Helios/dist/game/data/scripts/instances/FortressOfTheDead/33979-04.html
vendored
Normal file
5
L2J_Mobius_Helios/dist/game/data/scripts/instances/FortressOfTheDead/33979-04.html
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
<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>
|
5
L2J_Mobius_Helios/dist/game/data/scripts/instances/FortressOfTheDead/33979-05.html
vendored
Normal file
5
L2J_Mobius_Helios/dist/game/data/scripts/instances/FortressOfTheDead/33979-05.html
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
<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>
|
9
L2J_Mobius_Helios/dist/game/data/scripts/instances/FortressOfTheDead/33979-06.html
vendored
Normal file
9
L2J_Mobius_Helios/dist/game/data/scripts/instances/FortressOfTheDead/33979-06.html
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
<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>
|
5
L2J_Mobius_Helios/dist/game/data/scripts/instances/FortressOfTheDead/33979-07.html
vendored
Normal file
5
L2J_Mobius_Helios/dist/game/data/scripts/instances/FortressOfTheDead/33979-07.html
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
<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>
|
6
L2J_Mobius_Helios/dist/game/data/scripts/instances/FortressOfTheDead/33979-08.html
vendored
Normal file
6
L2J_Mobius_Helios/dist/game/data/scripts/instances/FortressOfTheDead/33979-08.html
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
<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>
|
6
L2J_Mobius_Helios/dist/game/data/scripts/instances/FortressOfTheDead/33979-09.html
vendored
Normal file
6
L2J_Mobius_Helios/dist/game/data/scripts/instances/FortressOfTheDead/33979-09.html
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
<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>
|
8
L2J_Mobius_Helios/dist/game/data/scripts/instances/FortressOfTheDead/33979-10.html
vendored
Normal file
8
L2J_Mobius_Helios/dist/game/data/scripts/instances/FortressOfTheDead/33979-10.html
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
<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>
|
2
L2J_Mobius_Helios/dist/game/data/scripts/instances/FortressOfTheDead/33979-11.html
vendored
Normal file
2
L2J_Mobius_Helios/dist/game/data/scripts/instances/FortressOfTheDead/33979-11.html
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
<html><body>Kain Van Halter:<br>
|
||||
Who is that person standing there?</body></html>
|
5
L2J_Mobius_Helios/dist/game/data/scripts/instances/FortressOfTheDead/33979.html
vendored
Normal file
5
L2J_Mobius_Helios/dist/game/data/scripts/instances/FortressOfTheDead/33979.html
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
<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>
|
165
L2J_Mobius_Helios/dist/game/data/scripts/instances/FortressOfTheDead/FortressOfTheDead.java
vendored
Normal file
165
L2J_Mobius_Helios/dist/game/data/scripts/instances/FortressOfTheDead/FortressOfTheDead.java
vendored
Normal file
@@ -0,0 +1,165 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new FortressOfTheDead();
|
||||
}
|
||||
}
|
4
L2J_Mobius_Helios/dist/game/data/scripts/instances/HarnakUndergroundRuins/33548.html
vendored
Normal file
4
L2J_Mobius_Helios/dist/game/data/scripts/instances/HarnakUndergroundRuins/33548.html
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
<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>
|
@@ -0,0 +1,658 @@
|
||||
/*
|
||||
* 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();
|
||||
}
|
||||
}
|
70
L2J_Mobius_Helios/dist/game/data/scripts/instances/JiniaGuildHideout1/JiniaGuildHideout1.java
vendored
Normal file
70
L2J_Mobius_Helios/dist/game/data/scripts/instances/JiniaGuildHideout1/JiniaGuildHideout1.java
vendored
Normal file
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* 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();
|
||||
}
|
||||
}
|
70
L2J_Mobius_Helios/dist/game/data/scripts/instances/JiniaGuildHideout2/JiniaGuildHideout2.java
vendored
Normal file
70
L2J_Mobius_Helios/dist/game/data/scripts/instances/JiniaGuildHideout2/JiniaGuildHideout2.java
vendored
Normal file
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* 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();
|
||||
}
|
||||
}
|
70
L2J_Mobius_Helios/dist/game/data/scripts/instances/JiniaGuildHideout3/JiniaGuildHideout3.java
vendored
Normal file
70
L2J_Mobius_Helios/dist/game/data/scripts/instances/JiniaGuildHideout3/JiniaGuildHideout3.java
vendored
Normal file
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* 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();
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user