Addition of Heavenly Rift.

Contributed by Brutallis.
This commit is contained in:
MobiusDevelopment 2020-08-15 22:08:55 +00:00
parent c67e5f29e2
commit 5566586837
120 changed files with 5936 additions and 40 deletions

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<list applyTaxes="true" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../xsd/multisell.xsd">
<npcs>
<npc>30952</npc> <!-- Dimensional Vortex -->
</npcs>
<item>
<!-- Broken Celestial Shard -->
<ingredient count="1" id="49767" />
<!-- Scroll of Heavenly Protection -->
<production count="1" id="49768" />
</item>
</list>

View File

@ -0,0 +1,12 @@
<html><body>Arushinai:<br>
Baium spent hundreds of years imprisoned. He was forced to watch how slowly his empire died...
Baium's anger was so great that the <font color="LEVEL">Heavenly Rift</font> itself began yo change under his influence.
I'll give you a little clue... So that you can imagine what can happen in the fault.
Or you will be attacked by <font color="LEVEL">40 Divine Angels</font> (kill them as soon as you notice),
or the will be <font color="LEVEL">20 Bombs</font> (their explosions will summon the Divine Angels, who will also have to be killed).
And be careful: from an exploding bomb can drop anything valuable! Either you need <font color="LEVEL">to protect the Tower</font> from 20 Divine Angels who will try to destroy it.
If you do this, you will receive a reward. Be extremely attentive!<br>
Fight shoulder to shoulder with you members. And remember: if you leave the Heavenly Rift before the due time, you can not return here.
Gather with strength - and go!<br>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest Arushinai proceed">Proceed to the task</button>
</body></html>

View File

@ -0,0 +1,4 @@
<html><body>Arushinai:<br>
It's not easy to get into the Heavenly Rift. When are you ready, I will send you <font color="LEVEL">back to Dimensional Vortex</font>.<br>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h npc_%objectId%_finish">Move all party</button>
</body></html>

View File

@ -0,0 +1,6 @@
<html><body>Arushinai:<br>
Do you know how the Heavenly Rift came about? The ego of the emperor Baium split the heaven.
Inside the fault, you can stay <font color="LEVEL">not longer than 30 minutes</font>. In such a dangerous place, mutual assistance and teamwork are especially important.
And remember: if you leave the rift prematurely, you will not be able to return here!<br>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest Arushinai 30401-1.htm">Learn more</button>
</body></html>

View File

@ -0,0 +1,155 @@
/*
* 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 ai.areas.TowerOfInsolence.Arushinai;
import org.l2jmobius.Config;
import org.l2jmobius.commons.util.Rnd;
import org.l2jmobius.gameserver.instancemanager.GlobalVariablesManager;
import org.l2jmobius.gameserver.instancemanager.HeavenlyRiftManager;
import org.l2jmobius.gameserver.model.Party;
import org.l2jmobius.gameserver.model.actor.Npc;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.network.SystemMessageId;
import org.l2jmobius.gameserver.network.serverpackets.SystemMessage;
import ai.AbstractNpcAI;
/**
* @author Brutallis
*/
public class Arushinai extends AbstractNpcAI
{
// NPC
private static final int ARUSHINAI = 30401;
private Arushinai()
{
addStartNpc(ARUSHINAI);
addTalkId(ARUSHINAI);
addFirstTalkId(ARUSHINAI);
}
@Override
public String onFirstTalk(Npc npc, PlayerInstance player)
{
return npc.getId() + ".htm";
}
@Override
public String onAdvEvent(String event, Npc npc, PlayerInstance player)
{
if (event.equals("30401-1.htm") || event.equals("30401-2.htm"))
{
return event;
}
if (event.equals("proceed"))
{
if (!player.isGM())
{
Party party = player.getParty();
if (party == null)
{
player.sendPacket(SystemMessageId.YOU_ARE_NOT_CURRENTLY_IN_A_PARTY_SO_YOU_CANNOT_ENTER);
player.teleToLocation(114264, 13352, -5104);
return null;
}
if (!party.isLeader(player))
{
player.sendPacket(SystemMessageId.ONLY_A_PARTY_LEADER_CAN_MAKE_THE_REQUEST_TO_ENTER);
return null;
}
}
if (GlobalVariablesManager.getInstance().getInt("heavenly_rift_complete", 0) != 0)
{
return null; // TODO: Find html?
}
final int riftLevel = Rnd.get(1, 3);
GlobalVariablesManager.getInstance().set("heavenly_rift_level", riftLevel);
GlobalVariablesManager.getInstance().set("heavenly_rift_complete", 4);
switch (riftLevel)
{
case 1:
{
HeavenlyRiftManager.startEvent20Bomb(player);
return null;
}
case 2:
{
HeavenlyRiftManager.startEventTower(player);
return null;
}
case 3:
{
HeavenlyRiftManager.startEvent40Angels(player);
break;
}
}
return null;
}
if (!event.equals("finish"))
{
return null;
}
if (player.isInParty())
{
Party party = player.getParty();
if (!party.isLeader(player))
{
player.sendPacket(SystemMessageId.YOU_CANNOT_PROCEED_AS_YOU_ARE_NOT_A_PARTY_LEADER);
return null;
}
for (PlayerInstance partyMember : party.getMembers())
{
if (player.calculateDistance2D(partyMember) > Config.ALT_PARTY_RANGE)
{
continue;
}
final SystemMessage sm = new SystemMessage(SystemMessageId.C1_IS_IN_A_LOCATION_WHICH_CANNOT_BE_ENTERED_THEREFORE_IT_CANNOT_BE_PROCESSED);
sm.addPcName(partyMember);
player.sendPacket(sm);
party.broadcastToPartyMembers(player, sm);
return null;
}
GlobalVariablesManager.getInstance().set("heavenly_rift_reward", 0);
for (PlayerInstance partyMember : party.getMembers())
{
partyMember.teleToLocation(114264, 13352, -5104);
}
return null;
}
if (player.isGM())
{
GlobalVariablesManager.getInstance().set("heavenly_rift_complete", 0);
player.teleToLocation(114264, 13352, -5104);
return null;
}
player.sendPacket(SystemMessageId.YOU_ARE_NOT_IN_A_PARTY);
return null;
}
public static void main(String[] args)
{
new Arushinai();
}
}

View File

@ -0,0 +1,6 @@
<html><head><body>
Dimensional Vortex:<br>
The energy of Emperor Baium's Rage caused by his imprisoning cracked the skies forming a rift. This rift leads to a new dimension. In order to get there, you will need a <font color=LEVEL>Celestial Shard</font>. You can extract it from the <font color=LEVEL>Unidentified Stone</font> after you kill all the monsters at the 6th floor or at higher floors of the Tower of Insolence.
<br>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest DimensionalVortex tryenter">Use Celestial Shard</Button>
</body></html>

View File

@ -0,0 +1,5 @@
<html><body>Dimensional Vortex:<br>
Eliminate all the monsters at the 6th floor or higher floors of the Tower of Insolence and use the <font color="LEVEL">Unidentified Stone</font> to extract <font color="LEVEL">Broken Celestial Shards</font> from it. You can exchange them for a special scroll, which might be useful during your hunt in the Tower of Insolence.<br>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h npc_%objectId%_Multisell 30952">Exchange Broken Celestial Shard</Button>
<Button ALIGN=LEFT ICON="RETURN" action="bypass -h Quest DimensionalVortex 30952.htm">Home</Button>
</body></html>

View File

@ -0,0 +1,4 @@
<html><body>Dimensional Vortex:<br>
You need an <font color="LEVEL">Airborne Fragment</font> from defeating the monsters on the sixth floor of the Tower of Insolence to enter the Airborne Rift.<br>
<Button ALIGN=LEFT ICON="RETURN" action="bypass -h Quest DimensionalVortex 30952.htm">Back</button>
</body></html>

View File

@ -0,0 +1,6 @@
<html><body>Dimensional Vortex:<br>
Baium was the emperor of Elmoreden, but angered the Gods and was put into solitude for years. He resented Einhasad for cursing him. A small rift appeared in the skies because of the ominous energy surrounding Baium.
<br>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest DimensionalVortex 30952-1.htm">Tell me about the Heavenly Rift.</button>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest DimensionalVortex 30952-2.htm">I want to exchange Broken Celestial Shards.</button>
</body></html>

View File

@ -0,0 +1,135 @@
/*
* 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 ai.areas.TowerOfInsolence.DimensionalVortex;
import org.l2jmobius.Config;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.gameserver.instancemanager.GlobalVariablesManager;
import org.l2jmobius.gameserver.instancemanager.HeavenlyRiftManager;
import org.l2jmobius.gameserver.model.Party;
import org.l2jmobius.gameserver.model.actor.Npc;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.network.SystemMessageId;
import org.l2jmobius.gameserver.network.serverpackets.SystemMessage;
import ai.AbstractNpcAI;
/**
* @author Brutallis
*/
public class DimensionalVortex extends AbstractNpcAI
{
// NPC
private static final int DIMENTIONAL_VORTEX = 30952;
// Items
private static final int CELESTIAL_SHARD = 49759;
private static final int BROKEN_CELESTIAL_SHARD = 49767;
private DimensionalVortex()
{
addStartNpc(DIMENTIONAL_VORTEX);
addTalkId(DIMENTIONAL_VORTEX);
addFirstTalkId(DIMENTIONAL_VORTEX);
}
@Override
public String onAdvEvent(String event, Npc npc, PlayerInstance player)
{
if (event.equals("30952-1.htm") || event.equals("30952-2.htm") || event.equals("30952-3.htm"))
{
return event;
}
if (event.equals("tryenter"))
{
if (getQuestItemsCount(player, CELESTIAL_SHARD) >= 1)
{
if (player.isGM())
{
player.destroyItemByItemId("Rift", CELESTIAL_SHARD, 1, npc, true);
GlobalVariablesManager.getInstance().set("heavenly_rift_complete", 0);
GlobalVariablesManager.getInstance().set("heavenly_rift_level", 0);
player.teleToLocation(112685, 13362, 10966);
ThreadPool.schedule(new HeavenlyRiftManager.ClearZoneTask(npc), 180000);
return null;
}
if (!player.isInParty())
{
player.sendPacket(SystemMessageId.YOU_ARE_NOT_CURRENTLY_IN_A_PARTY_SO_YOU_CANNOT_ENTER);
return null;
}
final Party party = player.getParty();
if ((party == null) || !party.isLeader(player))
{
player.sendPacket(SystemMessageId.ONLY_A_PARTY_LEADER_CAN_MAKE_THE_REQUEST_TO_ENTER);
return null;
}
for (PlayerInstance partyMember : party.getMembers())
{
if (player.calculateDistance2D(partyMember) > Config.ALT_PARTY_RANGE)
{
continue;
}
final SystemMessage sm = new SystemMessage(SystemMessageId.C1_IS_IN_A_LOCATION_WHICH_CANNOT_BE_ENTERED_THEREFORE_IT_CANNOT_BE_PROCESSED);
sm.addPcName(partyMember);
player.sendPacket(sm);
party.broadcastToPartyMembers(player, sm);
return null;
}
player.destroyItemByItemId("Rift", CELESTIAL_SHARD, 1, npc, true);
GlobalVariablesManager.getInstance().set("heavenly_rift_complete", 0);
GlobalVariablesManager.getInstance().set("heavenly_rift_level", 0);
for (PlayerInstance partyMember : party.getMembers())
{
partyMember.teleToLocation(112685, 13362, 10966);
}
ThreadPool.schedule(new HeavenlyRiftManager.ClearZoneTask(npc), 1200000);
}
else
{
return "30952-3.htm";
}
}
else if (event.equals("exchange"))
{
long count = getQuestItemsCount(player, BROKEN_CELESTIAL_SHARD);
if (count < 10)
{
return "30952-2.htm";
}
if ((count % 10) != 0)
{
count -= count % 10;
}
final long reward = count / 10;
player.destroyItemByItemId("Rift", BROKEN_CELESTIAL_SHARD, count, npc, true);
player.addItem("Rift", CELESTIAL_SHARD, reward, npc, true);
}
return null;
}
@Override
public String onFirstTalk(Npc npc, PlayerInstance player)
{
return npc.getId() + ".htm";
}
public static void main(String[] args)
{
new DimensionalVortex();
}
}

View File

@ -0,0 +1,233 @@
/*
* 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 ai.areas.TowerOfInsolence;
import java.util.List;
import java.util.concurrent.ScheduledFuture;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.commons.util.CommonUtil;
import org.l2jmobius.commons.util.Rnd;
import org.l2jmobius.gameserver.data.xml.impl.SpawnData;
import org.l2jmobius.gameserver.enums.ChatType;
import org.l2jmobius.gameserver.model.ChanceLocation;
import org.l2jmobius.gameserver.model.Location;
import org.l2jmobius.gameserver.model.Spawn;
import org.l2jmobius.gameserver.model.actor.Npc;
import org.l2jmobius.gameserver.model.actor.instance.MonsterInstance;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.model.skills.AbnormalVisualEffect;
import org.l2jmobius.gameserver.model.spawns.NpcSpawnTemplate;
import org.l2jmobius.gameserver.network.NpcStringId;
import ai.AbstractNpcAI;
/**
* @author Brutallis
*/
public class EnergyOfInsolence extends AbstractNpcAI
{
private static final int LEVEL_MAX_DIFF = 9;
private static final int TIME_UNTIL_MOVE = 1800000;
private static final int ELMOREDEN_LADY = 20977;
private static final int POWER_ANGEL_AMON = 21081;
private static final int ENERGY_OF_INSOLENCE_DROP_RATE = 70;
private static final int ENERGY_OF_INSOLENCE_ITEM_ID = 49685;
private static final int ENERGY_OF_INSOLENCE_DROP_COUNT = 1;
private static final int UNIDENTIFIED_STONE_DROP_RATE = 4;
private static final int UNIDENTIFIED_STONE_ITEM_ID = 49766;
private static final int[] ENERGY_OF_INSOLENCE_NPC_IDS = new int[]
{
ELMOREDEN_LADY,
POWER_ANGEL_AMON
};
private static final int[] ENERGY_OF_INSOLENCE_MINIONS = new int[]
{
20978,
20979,
21073,
21082,
21083
};
private static final int[] UNIDENTIFIED_STONE_NPC_IDS = new int[]
{
20980,
20981,
20982,
20983,
20984,
20985,
21074,
21075,
21076,
21077,
21080
};
private static ScheduledFuture<?> _scheduleTaskElmoreden;
private static ScheduledFuture<?> _scheduleTaskAmon;
private EnergyOfInsolence()
{
addSpawnId(ENERGY_OF_INSOLENCE_NPC_IDS);
addKillId(ENERGY_OF_INSOLENCE_NPC_IDS);
addKillId(UNIDENTIFIED_STONE_NPC_IDS);
addKillId(ENERGY_OF_INSOLENCE_MINIONS);
}
private void makeInvul(Npc npc)
{
npc.getEffectList().startAbnormalVisualEffect(new AbnormalVisualEffect[]
{
AbnormalVisualEffect.INVINCIBILITY
});
npc.setInvul(true);
}
private void makeMortal(Npc npc)
{
npc.getEffectList().stopAbnormalVisualEffect(new AbnormalVisualEffect[]
{
AbnormalVisualEffect.INVINCIBILITY
});
npc.setInvul(false);
}
private void makeTalk(Npc npc, boolean spawning)
{
NpcStringId npcStringId = null;
switch (npc.getId())
{
case ELMOREDEN_LADY:
{
npcStringId = spawning ? NpcStringId.MY_SERVANTS_CAN_KEEP_ME_SAFE_I_HAVE_NOTHING_TO_FEAR : NpcStringId.CAN_T_DIE_IN_A_PLACE_LIKE_THIS;
break;
}
case POWER_ANGEL_AMON:
{
npcStringId = spawning ? NpcStringId.I_WONDER_WHO_IT_IS_THAT_IS_LURKING_ABOUT : NpcStringId.WHY_WOULD_YOU_BUILD_A_TOWER_IN_OUR_TERRITORY;
}
}
npc.broadcastSay(ChatType.NPC_SHOUT, npcStringId);
}
@Override
public String onSpawn(Npc npc)
{
if (CommonUtil.contains(ENERGY_OF_INSOLENCE_NPC_IDS, npc.getId()))
{
makeTalk(npc, true);
switch (npc.getId())
{
case ELMOREDEN_LADY:
{
makeInvul(npc);
_scheduleTaskElmoreden = ThreadPool.schedule(new ScheduleAITask(npc, ELMOREDEN_LADY), TIME_UNTIL_MOVE);
break;
}
case POWER_ANGEL_AMON:
{
_scheduleTaskAmon = ThreadPool.schedule(new ScheduleAITask(npc, POWER_ANGEL_AMON), TIME_UNTIL_MOVE);
}
}
}
return super.onSpawn(npc);
}
@Override
public String onKill(Npc npc, PlayerInstance killer, boolean isSummon)
{
if (CommonUtil.contains(UNIDENTIFIED_STONE_NPC_IDS, npc.getId()) && ((killer.getLevel() - npc.getLevel()) <= LEVEL_MAX_DIFF) && (Rnd.get(100) <= UNIDENTIFIED_STONE_DROP_RATE))
{
npc.dropItem(killer, UNIDENTIFIED_STONE_ITEM_ID, ENERGY_OF_INSOLENCE_DROP_COUNT);
}
if (CommonUtil.contains(ENERGY_OF_INSOLENCE_NPC_IDS, npc.getId()))
{
makeTalk(npc, false);
switch (npc.getId())
{
case ELMOREDEN_LADY:
{
_scheduleTaskElmoreden.cancel(true);
_scheduleTaskElmoreden = ThreadPool.schedule(new ScheduleAITask(null, ELMOREDEN_LADY), TIME_UNTIL_MOVE);
break;
}
case POWER_ANGEL_AMON:
{
_scheduleTaskAmon.cancel(true);
_scheduleTaskAmon = ThreadPool.schedule(new ScheduleAITask(null, POWER_ANGEL_AMON), TIME_UNTIL_MOVE);
}
}
if (((killer.getLevel() - npc.getLevel()) <= LEVEL_MAX_DIFF) && (Rnd.get(100) <= ENERGY_OF_INSOLENCE_DROP_RATE))
{
npc.dropItem(killer, ENERGY_OF_INSOLENCE_ITEM_ID, ENERGY_OF_INSOLENCE_DROP_COUNT);
}
}
if (CommonUtil.contains(ENERGY_OF_INSOLENCE_MINIONS, npc.getId()))
{
final MonsterInstance leader = ((MonsterInstance) npc).getLeader();
if ((leader != null) && (leader.getMinionList().getSpawnedMinions().size() == 0) && !leader.isDead())
{
makeMortal(leader);
}
}
return super.onKill(npc, killer, isSummon);
}
public static AbstractNpcAI provider()
{
return new EnergyOfInsolence();
}
public class ScheduleAITask implements Runnable
{
private final Npc _npc;
private final int _npcId;
public ScheduleAITask(Npc npc, int npcId)
{
_npc = npc;
_npcId = npcId;
}
@Override
public void run()
{
if (_npc != null)
{
_npc.deleteMe();
}
try
{
final Spawn spawn = new Spawn(_npcId);
final List<NpcSpawnTemplate> spawns = SpawnData.getInstance().getNpcSpawns(npcSpawnTemplate -> npcSpawnTemplate.getId() == _npcId);
final List<ChanceLocation> locations = spawns.get(0).getLocation();
final Location location = locations.get(Rnd.get(locations.size()));
spawn.setLocation(location);
spawn.doSpawn();
}
catch (Exception e)
{
}
}
}
public static void main(String[] args)
{
new EnergyOfInsolence();
}
}

View File

@ -0,0 +1,106 @@
/*
* 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 ai.areas.TowerOfInsolence.HeavenlyRift;
import org.l2jmobius.commons.util.Rnd;
import org.l2jmobius.gameserver.instancemanager.GlobalVariablesManager;
import org.l2jmobius.gameserver.instancemanager.HeavenlyRiftManager;
import org.l2jmobius.gameserver.model.World;
import org.l2jmobius.gameserver.model.WorldObject;
import org.l2jmobius.gameserver.model.actor.Npc;
import org.l2jmobius.gameserver.model.actor.Playable;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.model.events.AbstractScript;
import org.l2jmobius.gameserver.network.serverpackets.ExChangeNpcState;
import ai.AbstractNpcAI;
/**
* @author Brutallis
*/
public class Bomb extends AbstractNpcAI
{
// NPCs
private static final int BOMB = 18003;
private static final int DIVINE_ANGEL = 20139;
// Items
private static final int[] ITEM_DROP_1 = new int[]
{
49756,
49762,
49763
};
private static final int[] ITEM_DROP_2 = new int[]
{
49760,
49761
};
public Bomb()
{
addKillId(BOMB);
addSpawnId(BOMB);
}
@Override
public String onSpawn(Npc npc)
{
npc.broadcastPacket(new ExChangeNpcState(npc.getObjectId(), 1));
return super.onSpawn(npc);
}
@Override
public String onKill(Npc npc, PlayerInstance killer, boolean isSummon)
{
if (Rnd.get(100) < 33)
{
AbstractScript.addSpawn(DIVINE_ANGEL, npc, false, 1800000);
}
else
{
World.getInstance().forEachVisibleObjectInRange((WorldObject) npc, Playable.class, 200, creature ->
{
if ((creature != null) && !creature.isDead())
{
creature.reduceCurrentHp(Rnd.get(300, 400), npc, null);
}
});
if (Rnd.get(100) < 50)
{
if (Rnd.get(100) < 90)
{
npc.dropItem(killer.getActingPlayer(), ITEM_DROP_1[Rnd.get(ITEM_DROP_1.length)], 1);
}
else
{
npc.dropItem(killer.getActingPlayer(), ITEM_DROP_2[Rnd.get(ITEM_DROP_2.length)], 1);
}
}
}
if (HeavenlyRiftManager.getAliveNpcCount(npc.getId()) == 0)
{
GlobalVariablesManager.getInstance().set("heavenly_rift_complete", GlobalVariablesManager.getInstance().getInt("heavenly_rift_level", 0));
GlobalVariablesManager.getInstance().set("heavenly_rift_level", 0);
}
return super.onKill(npc, killer, isSummon);
}
public static void main(String[] args)
{
new Bomb();
}
}

View File

@ -0,0 +1,79 @@
/*
* 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 ai.areas.TowerOfInsolence.HeavenlyRift;
import org.l2jmobius.gameserver.ai.AttackableAI;
import org.l2jmobius.gameserver.enums.ChatType;
import org.l2jmobius.gameserver.instancemanager.GlobalVariablesManager;
import org.l2jmobius.gameserver.instancemanager.HeavenlyRiftManager;
import org.l2jmobius.gameserver.model.actor.Creature;
import org.l2jmobius.gameserver.model.actor.Npc;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.network.NpcStringId;
import ai.AbstractNpcAI;
/**
* @author Brutallis
*/
public class DivineAngel extends AbstractNpcAI
{
// NPCs
private static final int TOWER = 18004;
private static final int DIVINE_ANGEL = 20139;
public DivineAngel()
{
addSpawnId(DIVINE_ANGEL);
addKillId(DIVINE_ANGEL);
}
@Override
public String onKill(Npc npc, PlayerInstance killer, boolean isSummon)
{
if ((GlobalVariablesManager.getInstance().getInt("heavenly_rift_level", 0) > 1) && (HeavenlyRiftManager.getAliveNpcCount(npc.getId()) == 0))
{
GlobalVariablesManager.getInstance().set("heavenly_rift_complete", GlobalVariablesManager.getInstance().getInt("heavenly_rift_level", 0));
GlobalVariablesManager.getInstance().set("heavenly_rift_level", 0);
GlobalVariablesManager.getInstance().set("heavenly_rift_reward", 1);
for (Creature creature : HeavenlyRiftManager.getZone().getCharactersInside())
{
if (creature.isMonster() && (creature.getId() == TOWER) && !creature.isDead())
{
((Npc) creature).broadcastSay(ChatType.NPC_SHOUT, NpcStringId.DIVINE_ANGELS_ARE_NOWHERE_TO_BE_SEEN_I_WANT_TO_TALK_TO_THE_PARTY_LEADER);
}
}
}
return super.onKill(npc, killer, isSummon);
}
@Override
public String onSpawn(Npc npc)
{
if (GlobalVariablesManager.getInstance().getInt("heavenly_rift_level", 0) == 2)
{
((AttackableAI) npc.getAI()).setGlobalAggro(0);
}
return super.onSpawn(npc);
}
public static void main(String[] args)
{
new DivineAngel();
}
}

View File

@ -0,0 +1,64 @@
/*
* 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 ai.areas.TowerOfInsolence.HeavenlyRift;
import org.l2jmobius.gameserver.instancemanager.GlobalVariablesManager;
import org.l2jmobius.gameserver.instancemanager.HeavenlyRiftManager;
import org.l2jmobius.gameserver.model.actor.Creature;
import org.l2jmobius.gameserver.model.actor.Npc;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.network.NpcStringId;
import org.l2jmobius.gameserver.network.serverpackets.ExShowScreenMessage;
import ai.AbstractNpcAI;
/**
* @author Brutallis
*/
public class Tower extends AbstractNpcAI
{
// NPCs
private static final int TOWER = 18004;
private static final int DIVINE_ANGEL = 20139;
public Tower()
{
addKillId(TOWER);
}
@Override
public String onKill(Npc npc, PlayerInstance killer, boolean isSummon)
{
HeavenlyRiftManager.getZone().broadcastPacket(new ExShowScreenMessage(NpcStringId.YOU_HAVE_FAILED, 2, 5000));
for (Creature creature : HeavenlyRiftManager.getZone().getCharactersInside())
{
if (creature.isMonster() && !creature.isDead() && (creature.getId() == DIVINE_ANGEL))
{
creature.decayMe();
}
}
GlobalVariablesManager.getInstance().set("heavenly_rift_complete", GlobalVariablesManager.getInstance().getInt("heavenly_rift_level", 0));
GlobalVariablesManager.getInstance().set("heavenly_rift_level", 0);
GlobalVariablesManager.getInstance().set("heavenly_rift_reward", 0);
return super.onKill(npc, killer, isSummon);
}
public static void main(String[] args)
{
new Tower();
}
}

View File

@ -3,8 +3,6 @@
<spawn name="Aden">
<group>
<npc id="30949" x="110831" y="15973" z="-4368" heading="412" respawnTime="60sec" />
<npc id="30950" x="114112" y="20042" z="944" heading="50148" respawnTime="60sec" />
<npc id="30951" x="118644" y="16680" z="6000" heading="42000" respawnTime="60sec" />
<npc id="31646" x="120112" y="30912" z="-3616" heading="49000" respawnTime="60sec" />
<npc id="30747" x="110395" y="41625" z="-4619" heading="0" respawnTime="60sec" />
<npc id="30764" x="117380" y="75616" z="-2664" heading="26000" respawnTime="60sec" />

View File

@ -1609,10 +1609,9 @@
</spawn>
<spawn name="23_18">
<group>
<npc id="30952" x="114220" y="13320" z="-5096" heading="228" respawnTime="60sec" /> <!-- Saviors -->
<npc id="30953" x="114048" y="20048" z="928" heading="49444" respawnTime="60sec" /> <!-- Saviors -->
<npc id="30954" x="118600" y="16724" z="5984" heading="42000" respawnTime="60sec" /> <!-- Saviors -->
<npc id="31862" x="112747" y="14163" z="10075" heading="0" respawnTime="60sec" /> <!-- Saviors -->
<npc id="30952" x="114220" y="13320" z="-5096" heading="228" respawnTime="60sec" /> <!-- Dimensional Vortex -->
<npc id="31862" x="112747" y="14163" z="10075" heading="0" respawnTime="60sec" /> <!-- Angelic Vortex -->
<npc id="30401" x="112634" y="13364" z="2445" heading="8021" /> <!--Arushinai-->
</group>
</spawn>
</list>

View File

@ -141,7 +141,7 @@
<sex>MALE</sex>
<acquire exp="44" sp="2" />
<stats str="40" int="21" dex="30" wit="20" con="43" men="10">
<vitals hp="2578" hpRegen="2" mp="1345" mpRegen="0.9" />
<vitals hp="39" hpRegen="2" mp="1345" mpRegen="0.9" />
<attack physical="4" magical="5.79" random="30" critical="8" accuracy="0" attackSpeed="253" type="FIST" range="40" distance="80" width="120" />
<defence physical="44.44" magical="32.52" />
<speed>
@ -175,7 +175,7 @@
<sex>MALE</sex>
<acquire sp="1" />
<stats str="40" int="21" dex="30" wit="20" con="43" men="10">
<vitals hp="2578" hpRegen="5.5" mp="1345" mpRegen="2.1" />
<vitals hp="1372" hpRegen="5.5" mp="1345" mpRegen="2.1" />
<attack physical="290.45" magical="198.34" random="30" critical="4" accuracy="20" attackSpeed="257" type="BOW" range="50" distance="80" width="120" />
<defence physical="195.66" magical="143.18" />
<speed>
@ -185,7 +185,7 @@
<hitTime>520</hitTime>
<abnormalResist physical="10" magical="10" />
</stats>
<status undying="false" />
<status undying="false" attackable="true" canMove="false"/>
<skillList>
<skill id="4273" level="3" /> <!-- Resist Daggers/Rapier Weapon -->
<skill id="4274" level="1" /> <!-- Blunt Weapon Weak Point -->
@ -305,6 +305,7 @@
<race>DEMONIC</race>
<sex>FEMALE</sex>
<acquire exp="18379865" sp="551395" />
<equipment rhand="5800" lhand="5799"/>
<stats str="40" int="21" dex="30" wit="20" con="43" men="10">
<vitals hp="1241578.01903" hpRegen="7.5" mp="1190.325" mpRegen="2.7" />
<attack physical="734.25" magical="501.4" random="30" critical="4" accuracy="4.75" attackSpeed="253" type="FIST" range="40" distance="80" width="120" />

View File

@ -1778,6 +1778,7 @@
<race>DIVINE</race>
<sex>MALE</sex>
<acquire exp="243344" sp="7300" />
<equipment rhand="148"/> <!-- rhand: Sword of Valhalla -->
<stats str="40" int="21" dex="30" wit="20" con="43" men="10">
<vitals hp="1719.9123557143" hpRegen="8.5" mp="1466.445" mpRegen="3" />
<attack physical="32.16396" magical="21.96382" random="30" critical="4" accuracy="4.75" attackSpeed="253" type="SWORD" range="40" distance="80" width="120" />
@ -1803,7 +1804,11 @@
</skillList>
<shots shotChance="30" spiritChance="30" />
<exCrtEffect>false</exCrtEffect>
<ai aggroRange="500" clanHelpRange="300" isAggressive="false" />
<ai aggroRange="2000" clanHelpRange="300" isAggressive="true">
<clanList>
<clan>ALL</clan>
</clanList>
</ai>
<collision>
<radius normal="13.5" />
<height normal="36.5" />

View File

@ -322,6 +322,16 @@
<node X="-253907" Y="221193" />
</zone>
<!-- Heavenly rift zone -->
<zone name="heavenly_rift" type="NoRestartZone" shape="NPoly" minZ="12000" maxZ="10800">
<node X="114169" Y="13781" />
<node X="112353" Y="15581" />
<node X="111219" Y="15072" />
<node X="111584" Y="14238" />
<node X="112815" Y="12991" />
<node X="113640" Y="12642" />
</zone>
<!-- High five zone -->
<zone name="olympiad_no_restart" type="NoRestartZone" shape="Cuboid" minZ="-8485" maxZ="1149">
<stat name="restartTime" val="0" />

View File

@ -0,0 +1,142 @@
/*
* 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 org.l2jmobius.gameserver.instancemanager;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.gameserver.model.Location;
import org.l2jmobius.gameserver.model.Spawn;
import org.l2jmobius.gameserver.model.actor.Creature;
import org.l2jmobius.gameserver.model.actor.Npc;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.model.zone.ZoneType;
import org.l2jmobius.gameserver.network.NpcStringId;
import org.l2jmobius.gameserver.network.serverpackets.ExShowScreenMessage;
/**
* @author Brutallis
*/
public class HeavenlyRiftManager
{
private static final ZoneType ZONE = ZoneManager.getInstance().getZoneByName("heavenly_rift");
public static ZoneType getZone()
{
return ZONE;
}
public static int getAliveNpcCount(int npcId)
{
int result = 0;
for (Creature creature : ZONE.getCharactersInside())
{
if (creature.isMonster() && !creature.isDead() && (creature.getId() == npcId))
{
result++;
}
}
return result;
}
public static void startEvent20Bomb(PlayerInstance player)
{
ZONE.broadcastPacket(new ExShowScreenMessage(NpcStringId.SET_OFF_BOMBS_AND_GET_TREASURES, 2, 5000));
spawnMonster(18003, 113352, 12936, 10976, 1800000);
spawnMonster(18003, 113592, 13272, 10976, 1800000);
spawnMonster(18003, 113816, 13592, 10976, 1800000);
spawnMonster(18003, 113080, 13192, 10976, 1800000);
spawnMonster(18003, 113336, 13528, 10976, 1800000);
spawnMonster(18003, 113560, 13832, 10976, 1800000);
spawnMonster(18003, 112776, 13512, 10976, 1800000);
spawnMonster(18003, 113064, 13784, 10976, 1800000);
spawnMonster(18003, 112440, 13848, 10976, 1800000);
spawnMonster(18003, 112728, 14104, 10976, 1800000);
spawnMonster(18003, 112760, 14600, 10976, 1800000);
spawnMonster(18003, 112392, 14456, 10976, 1800000);
spawnMonster(18003, 112104, 14184, 10976, 1800000);
spawnMonster(18003, 111816, 14488, 10976, 1800000);
spawnMonster(18003, 112104, 14760, 10976, 1800000);
spawnMonster(18003, 112392, 15032, 10976, 1800000);
spawnMonster(18003, 112120, 15288, 10976, 1800000);
spawnMonster(18003, 111784, 15064, 10976, 1800000);
spawnMonster(18003, 111480, 14824, 10976, 1800000);
spawnMonster(18003, 113144, 14216, 10976, 1800000);
}
public static void startEventTower(PlayerInstance player)
{
ZONE.broadcastPacket(new ExShowScreenMessage(NpcStringId.PROTECT_THE_CENTRAL_TOWER_FROM_DIVINE_ANGELS, 2, 5000));
spawnMonster(18004, 112648, 14072, 10976, 1800000);
ThreadPool.schedule(() ->
{
for (int i = 0; i < 20; ++i)
{
spawnMonster(20139, 112696, 13960, 10958, 1800000);
}
}, 10000);
}
public static void startEvent40Angels(PlayerInstance player)
{
ZONE.broadcastPacket(new ExShowScreenMessage(NpcStringId.DESTROY_WEAKENED_DIVINE_ANGELS, 2, 5000));
for (int i = 0; i < 40; ++i)
{
spawnMonster(20139, 112696, 13960, 10958, 1800000);
}
}
private static void spawnMonster(int npcId, int x, int y, int z, long despawnTime)
{
try
{
Spawn spawn = new Spawn(npcId);
Location location = new Location(x, y, z);
spawn.setLocation(location);
Npc npc = spawn.doSpawn();
npc.scheduleDespawn(despawnTime);
}
catch (Exception e)
{
}
}
public static class ClearZoneTask implements Runnable
{
private final Npc _npc;
public ClearZoneTask(Npc npc)
{
_npc = npc;
}
@Override
public void run()
{
for (Creature creature : ZONE.getCharactersInside())
{
if (creature.isPlayer())
{
creature.teleToLocation(114264, 13352, -5104);
}
else if (creature.isNpc() && (creature.getId() != 30401))
{
creature.decayMe();
}
}
_npc.setBusy(false);
}
}
}

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<list applyTaxes="true" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../xsd/multisell.xsd">
<npcs>
<npc>30952</npc> <!-- Dimensional Vortex -->
</npcs>
<item>
<!-- Broken Celestial Shard -->
<ingredient count="1" id="49767" />
<!-- Scroll of Heavenly Protection -->
<production count="1" id="49768" />
</item>
</list>

View File

@ -0,0 +1,12 @@
<html><body>Arushinai:<br>
Baium spent hundreds of years imprisoned. He was forced to watch how slowly his empire died...
Baium's anger was so great that the <font color="LEVEL">Heavenly Rift</font> itself began yo change under his influence.
I'll give you a little clue... So that you can imagine what can happen in the fault.
Or you will be attacked by <font color="LEVEL">40 Divine Angels</font> (kill them as soon as you notice),
or the will be <font color="LEVEL">20 Bombs</font> (their explosions will summon the Divine Angels, who will also have to be killed).
And be careful: from an exploding bomb can drop anything valuable! Either you need <font color="LEVEL">to protect the Tower</font> from 20 Divine Angels who will try to destroy it.
If you do this, you will receive a reward. Be extremely attentive!<br>
Fight shoulder to shoulder with you members. And remember: if you leave the Heavenly Rift before the due time, you can not return here.
Gather with strength - and go!<br>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest Arushinai proceed">Proceed to the task</button>
</body></html>

View File

@ -0,0 +1,4 @@
<html><body>Arushinai:<br>
It's not easy to get into the Heavenly Rift. When are you ready, I will send you <font color="LEVEL">back to Dimensional Vortex</font>.<br>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h npc_%objectId%_finish">Move all party</button>
</body></html>

View File

@ -0,0 +1,6 @@
<html><body>Arushinai:<br>
Do you know how the Heavenly Rift came about? The ego of the emperor Baium split the heaven.
Inside the fault, you can stay <font color="LEVEL">not longer than 30 minutes</font>. In such a dangerous place, mutual assistance and teamwork are especially important.
And remember: if you leave the rift prematurely, you will not be able to return here!<br>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest Arushinai 30401-1.htm">Learn more</button>
</body></html>

View File

@ -0,0 +1,155 @@
/*
* 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 ai.areas.TowerOfInsolence.Arushinai;
import org.l2jmobius.Config;
import org.l2jmobius.commons.util.Rnd;
import org.l2jmobius.gameserver.instancemanager.GlobalVariablesManager;
import org.l2jmobius.gameserver.instancemanager.HeavenlyRiftManager;
import org.l2jmobius.gameserver.model.Party;
import org.l2jmobius.gameserver.model.actor.Npc;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.network.SystemMessageId;
import org.l2jmobius.gameserver.network.serverpackets.SystemMessage;
import ai.AbstractNpcAI;
/**
* @author Brutallis
*/
public class Arushinai extends AbstractNpcAI
{
// NPC
private static final int ARUSHINAI = 30401;
private Arushinai()
{
addStartNpc(ARUSHINAI);
addTalkId(ARUSHINAI);
addFirstTalkId(ARUSHINAI);
}
@Override
public String onFirstTalk(Npc npc, PlayerInstance player)
{
return npc.getId() + ".htm";
}
@Override
public String onAdvEvent(String event, Npc npc, PlayerInstance player)
{
if (event.equals("30401-1.htm") || event.equals("30401-2.htm"))
{
return event;
}
if (event.equals("proceed"))
{
if (!player.isGM())
{
Party party = player.getParty();
if (party == null)
{
player.sendPacket(SystemMessageId.YOU_ARE_NOT_CURRENTLY_IN_A_PARTY_SO_YOU_CANNOT_ENTER);
player.teleToLocation(114264, 13352, -5104);
return null;
}
if (!party.isLeader(player))
{
player.sendPacket(SystemMessageId.ONLY_A_PARTY_LEADER_CAN_MAKE_THE_REQUEST_TO_ENTER);
return null;
}
}
if (GlobalVariablesManager.getInstance().getInt("heavenly_rift_complete", 0) != 0)
{
return null; // TODO: Find html?
}
final int riftLevel = Rnd.get(1, 3);
GlobalVariablesManager.getInstance().set("heavenly_rift_level", riftLevel);
GlobalVariablesManager.getInstance().set("heavenly_rift_complete", 4);
switch (riftLevel)
{
case 1:
{
HeavenlyRiftManager.startEvent20Bomb(player);
return null;
}
case 2:
{
HeavenlyRiftManager.startEventTower(player);
return null;
}
case 3:
{
HeavenlyRiftManager.startEvent40Angels(player);
break;
}
}
return null;
}
if (!event.equals("finish"))
{
return null;
}
if (player.isInParty())
{
Party party = player.getParty();
if (!party.isLeader(player))
{
player.sendPacket(SystemMessageId.YOU_CANNOT_PROCEED_AS_YOU_ARE_NOT_A_PARTY_LEADER);
return null;
}
for (PlayerInstance partyMember : party.getMembers())
{
if (player.calculateDistance2D(partyMember) > Config.ALT_PARTY_RANGE)
{
continue;
}
final SystemMessage sm = new SystemMessage(SystemMessageId.C1_IS_IN_A_LOCATION_WHICH_CANNOT_BE_ENTERED_THEREFORE_IT_CANNOT_BE_PROCESSED);
sm.addPcName(partyMember);
player.sendPacket(sm);
party.broadcastToPartyMembers(player, sm);
return null;
}
GlobalVariablesManager.getInstance().set("heavenly_rift_reward", 0);
for (PlayerInstance partyMember : party.getMembers())
{
partyMember.teleToLocation(114264, 13352, -5104);
}
return null;
}
if (player.isGM())
{
GlobalVariablesManager.getInstance().set("heavenly_rift_complete", 0);
player.teleToLocation(114264, 13352, -5104);
return null;
}
player.sendPacket(SystemMessageId.YOU_ARE_NOT_IN_A_PARTY);
return null;
}
public static void main(String[] args)
{
new Arushinai();
}
}

View File

@ -0,0 +1,6 @@
<html><head><body>
Dimensional Vortex:<br>
The energy of Emperor Baium's Rage caused by his imprisoning cracked the skies forming a rift. This rift leads to a new dimension. In order to get there, you will need a <font color=LEVEL>Celestial Shard</font>. You can extract it from the <font color=LEVEL>Unidentified Stone</font> after you kill all the monsters at the 6th floor or at higher floors of the Tower of Insolence.
<br>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest DimensionalVortex tryenter">Use Celestial Shard</Button>
</body></html>

View File

@ -0,0 +1,5 @@
<html><body>Dimensional Vortex:<br>
Eliminate all the monsters at the 6th floor or higher floors of the Tower of Insolence and use the <font color="LEVEL">Unidentified Stone</font> to extract <font color="LEVEL">Broken Celestial Shards</font> from it. You can exchange them for a special scroll, which might be useful during your hunt in the Tower of Insolence.<br>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h npc_%objectId%_Multisell 30952">Exchange Broken Celestial Shard</Button>
<Button ALIGN=LEFT ICON="RETURN" action="bypass -h Quest DimensionalVortex 30952.htm">Home</Button>
</body></html>

View File

@ -0,0 +1,4 @@
<html><body>Dimensional Vortex:<br>
You need an <font color="LEVEL">Airborne Fragment</font> from defeating the monsters on the sixth floor of the Tower of Insolence to enter the Airborne Rift.<br>
<Button ALIGN=LEFT ICON="RETURN" action="bypass -h Quest DimensionalVortex 30952.htm">Back</button>
</body></html>

View File

@ -0,0 +1,6 @@
<html><body>Dimensional Vortex:<br>
Baium was the emperor of Elmoreden, but angered the Gods and was put into solitude for years. He resented Einhasad for cursing him. A small rift appeared in the skies because of the ominous energy surrounding Baium.
<br>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest DimensionalVortex 30952-1.htm">Tell me about the Heavenly Rift.</button>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest DimensionalVortex 30952-2.htm">I want to exchange Broken Celestial Shards.</button>
</body></html>

View File

@ -0,0 +1,135 @@
/*
* 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 ai.areas.TowerOfInsolence.DimensionalVortex;
import org.l2jmobius.Config;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.gameserver.instancemanager.GlobalVariablesManager;
import org.l2jmobius.gameserver.instancemanager.HeavenlyRiftManager;
import org.l2jmobius.gameserver.model.Party;
import org.l2jmobius.gameserver.model.actor.Npc;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.network.SystemMessageId;
import org.l2jmobius.gameserver.network.serverpackets.SystemMessage;
import ai.AbstractNpcAI;
/**
* @author Brutallis
*/
public class DimensionalVortex extends AbstractNpcAI
{
// NPC
private static final int DIMENTIONAL_VORTEX = 30952;
// Items
private static final int CELESTIAL_SHARD = 49759;
private static final int BROKEN_CELESTIAL_SHARD = 49767;
private DimensionalVortex()
{
addStartNpc(DIMENTIONAL_VORTEX);
addTalkId(DIMENTIONAL_VORTEX);
addFirstTalkId(DIMENTIONAL_VORTEX);
}
@Override
public String onAdvEvent(String event, Npc npc, PlayerInstance player)
{
if (event.equals("30952-1.htm") || event.equals("30952-2.htm") || event.equals("30952-3.htm"))
{
return event;
}
if (event.equals("tryenter"))
{
if (getQuestItemsCount(player, CELESTIAL_SHARD) >= 1)
{
if (player.isGM())
{
player.destroyItemByItemId("Rift", CELESTIAL_SHARD, 1, npc, true);
GlobalVariablesManager.getInstance().set("heavenly_rift_complete", 0);
GlobalVariablesManager.getInstance().set("heavenly_rift_level", 0);
player.teleToLocation(112685, 13362, 10966);
ThreadPool.schedule(new HeavenlyRiftManager.ClearZoneTask(npc), 180000);
return null;
}
if (!player.isInParty())
{
player.sendPacket(SystemMessageId.YOU_ARE_NOT_CURRENTLY_IN_A_PARTY_SO_YOU_CANNOT_ENTER);
return null;
}
final Party party = player.getParty();
if ((party == null) || !party.isLeader(player))
{
player.sendPacket(SystemMessageId.ONLY_A_PARTY_LEADER_CAN_MAKE_THE_REQUEST_TO_ENTER);
return null;
}
for (PlayerInstance partyMember : party.getMembers())
{
if (player.calculateDistance2D(partyMember) > Config.ALT_PARTY_RANGE)
{
continue;
}
final SystemMessage sm = new SystemMessage(SystemMessageId.C1_IS_IN_A_LOCATION_WHICH_CANNOT_BE_ENTERED_THEREFORE_IT_CANNOT_BE_PROCESSED);
sm.addPcName(partyMember);
player.sendPacket(sm);
party.broadcastToPartyMembers(player, sm);
return null;
}
player.destroyItemByItemId("Rift", CELESTIAL_SHARD, 1, npc, true);
GlobalVariablesManager.getInstance().set("heavenly_rift_complete", 0);
GlobalVariablesManager.getInstance().set("heavenly_rift_level", 0);
for (PlayerInstance partyMember : party.getMembers())
{
partyMember.teleToLocation(112685, 13362, 10966);
}
ThreadPool.schedule(new HeavenlyRiftManager.ClearZoneTask(npc), 1200000);
}
else
{
return "30952-3.htm";
}
}
else if (event.equals("exchange"))
{
long count = getQuestItemsCount(player, BROKEN_CELESTIAL_SHARD);
if (count < 10)
{
return "30952-2.htm";
}
if ((count % 10) != 0)
{
count -= count % 10;
}
final long reward = count / 10;
player.destroyItemByItemId("Rift", BROKEN_CELESTIAL_SHARD, count, npc, true);
player.addItem("Rift", CELESTIAL_SHARD, reward, npc, true);
}
return null;
}
@Override
public String onFirstTalk(Npc npc, PlayerInstance player)
{
return npc.getId() + ".htm";
}
public static void main(String[] args)
{
new DimensionalVortex();
}
}

View File

@ -0,0 +1,233 @@
/*
* 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 ai.areas.TowerOfInsolence;
import java.util.List;
import java.util.concurrent.ScheduledFuture;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.commons.util.CommonUtil;
import org.l2jmobius.commons.util.Rnd;
import org.l2jmobius.gameserver.data.xml.impl.SpawnData;
import org.l2jmobius.gameserver.enums.ChatType;
import org.l2jmobius.gameserver.model.ChanceLocation;
import org.l2jmobius.gameserver.model.Location;
import org.l2jmobius.gameserver.model.Spawn;
import org.l2jmobius.gameserver.model.actor.Npc;
import org.l2jmobius.gameserver.model.actor.instance.MonsterInstance;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.model.skills.AbnormalVisualEffect;
import org.l2jmobius.gameserver.model.spawns.NpcSpawnTemplate;
import org.l2jmobius.gameserver.network.NpcStringId;
import ai.AbstractNpcAI;
/**
* @author Brutallis
*/
public class EnergyOfInsolence extends AbstractNpcAI
{
private static final int LEVEL_MAX_DIFF = 9;
private static final int TIME_UNTIL_MOVE = 1800000;
private static final int ELMOREDEN_LADY = 20977;
private static final int POWER_ANGEL_AMON = 21081;
private static final int ENERGY_OF_INSOLENCE_DROP_RATE = 70;
private static final int ENERGY_OF_INSOLENCE_ITEM_ID = 49685;
private static final int ENERGY_OF_INSOLENCE_DROP_COUNT = 1;
private static final int UNIDENTIFIED_STONE_DROP_RATE = 4;
private static final int UNIDENTIFIED_STONE_ITEM_ID = 49766;
private static final int[] ENERGY_OF_INSOLENCE_NPC_IDS = new int[]
{
ELMOREDEN_LADY,
POWER_ANGEL_AMON
};
private static final int[] ENERGY_OF_INSOLENCE_MINIONS = new int[]
{
20978,
20979,
21073,
21082,
21083
};
private static final int[] UNIDENTIFIED_STONE_NPC_IDS = new int[]
{
20980,
20981,
20982,
20983,
20984,
20985,
21074,
21075,
21076,
21077,
21080
};
private static ScheduledFuture<?> _scheduleTaskElmoreden;
private static ScheduledFuture<?> _scheduleTaskAmon;
private EnergyOfInsolence()
{
addSpawnId(ENERGY_OF_INSOLENCE_NPC_IDS);
addKillId(ENERGY_OF_INSOLENCE_NPC_IDS);
addKillId(UNIDENTIFIED_STONE_NPC_IDS);
addKillId(ENERGY_OF_INSOLENCE_MINIONS);
}
private void makeInvul(Npc npc)
{
npc.getEffectList().startAbnormalVisualEffect(new AbnormalVisualEffect[]
{
AbnormalVisualEffect.INVINCIBILITY
});
npc.setInvul(true);
}
private void makeMortal(Npc npc)
{
npc.getEffectList().stopAbnormalVisualEffect(new AbnormalVisualEffect[]
{
AbnormalVisualEffect.INVINCIBILITY
});
npc.setInvul(false);
}
private void makeTalk(Npc npc, boolean spawning)
{
NpcStringId npcStringId = null;
switch (npc.getId())
{
case ELMOREDEN_LADY:
{
npcStringId = spawning ? NpcStringId.MY_SERVANTS_CAN_KEEP_ME_SAFE_I_HAVE_NOTHING_TO_FEAR : NpcStringId.CAN_T_DIE_IN_A_PLACE_LIKE_THIS;
break;
}
case POWER_ANGEL_AMON:
{
npcStringId = spawning ? NpcStringId.I_WONDER_WHO_IT_IS_THAT_IS_LURKING_ABOUT : NpcStringId.WHY_WOULD_YOU_BUILD_A_TOWER_IN_OUR_TERRITORY;
}
}
npc.broadcastSay(ChatType.NPC_SHOUT, npcStringId);
}
@Override
public String onSpawn(Npc npc)
{
if (CommonUtil.contains(ENERGY_OF_INSOLENCE_NPC_IDS, npc.getId()))
{
makeTalk(npc, true);
switch (npc.getId())
{
case ELMOREDEN_LADY:
{
makeInvul(npc);
_scheduleTaskElmoreden = ThreadPool.schedule(new ScheduleAITask(npc, ELMOREDEN_LADY), TIME_UNTIL_MOVE);
break;
}
case POWER_ANGEL_AMON:
{
_scheduleTaskAmon = ThreadPool.schedule(new ScheduleAITask(npc, POWER_ANGEL_AMON), TIME_UNTIL_MOVE);
}
}
}
return super.onSpawn(npc);
}
@Override
public String onKill(Npc npc, PlayerInstance killer, boolean isSummon)
{
if (CommonUtil.contains(UNIDENTIFIED_STONE_NPC_IDS, npc.getId()) && ((killer.getLevel() - npc.getLevel()) <= LEVEL_MAX_DIFF) && (Rnd.get(100) <= UNIDENTIFIED_STONE_DROP_RATE))
{
npc.dropItem(killer, UNIDENTIFIED_STONE_ITEM_ID, ENERGY_OF_INSOLENCE_DROP_COUNT);
}
if (CommonUtil.contains(ENERGY_OF_INSOLENCE_NPC_IDS, npc.getId()))
{
makeTalk(npc, false);
switch (npc.getId())
{
case ELMOREDEN_LADY:
{
_scheduleTaskElmoreden.cancel(true);
_scheduleTaskElmoreden = ThreadPool.schedule(new ScheduleAITask(null, ELMOREDEN_LADY), TIME_UNTIL_MOVE);
break;
}
case POWER_ANGEL_AMON:
{
_scheduleTaskAmon.cancel(true);
_scheduleTaskAmon = ThreadPool.schedule(new ScheduleAITask(null, POWER_ANGEL_AMON), TIME_UNTIL_MOVE);
}
}
if (((killer.getLevel() - npc.getLevel()) <= LEVEL_MAX_DIFF) && (Rnd.get(100) <= ENERGY_OF_INSOLENCE_DROP_RATE))
{
npc.dropItem(killer, ENERGY_OF_INSOLENCE_ITEM_ID, ENERGY_OF_INSOLENCE_DROP_COUNT);
}
}
if (CommonUtil.contains(ENERGY_OF_INSOLENCE_MINIONS, npc.getId()))
{
final MonsterInstance leader = ((MonsterInstance) npc).getLeader();
if ((leader != null) && (leader.getMinionList().getSpawnedMinions().size() == 0) && !leader.isDead())
{
makeMortal(leader);
}
}
return super.onKill(npc, killer, isSummon);
}
public static AbstractNpcAI provider()
{
return new EnergyOfInsolence();
}
public class ScheduleAITask implements Runnable
{
private final Npc _npc;
private final int _npcId;
public ScheduleAITask(Npc npc, int npcId)
{
_npc = npc;
_npcId = npcId;
}
@Override
public void run()
{
if (_npc != null)
{
_npc.deleteMe();
}
try
{
final Spawn spawn = new Spawn(_npcId);
final List<NpcSpawnTemplate> spawns = SpawnData.getInstance().getNpcSpawns(npcSpawnTemplate -> npcSpawnTemplate.getId() == _npcId);
final List<ChanceLocation> locations = spawns.get(0).getLocation();
final Location location = locations.get(Rnd.get(locations.size()));
spawn.setLocation(location);
spawn.doSpawn();
}
catch (Exception e)
{
}
}
}
public static void main(String[] args)
{
new EnergyOfInsolence();
}
}

View File

@ -0,0 +1,106 @@
/*
* 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 ai.areas.TowerOfInsolence.HeavenlyRift;
import org.l2jmobius.commons.util.Rnd;
import org.l2jmobius.gameserver.instancemanager.GlobalVariablesManager;
import org.l2jmobius.gameserver.instancemanager.HeavenlyRiftManager;
import org.l2jmobius.gameserver.model.World;
import org.l2jmobius.gameserver.model.WorldObject;
import org.l2jmobius.gameserver.model.actor.Npc;
import org.l2jmobius.gameserver.model.actor.Playable;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.model.events.AbstractScript;
import org.l2jmobius.gameserver.network.serverpackets.ExChangeNpcState;
import ai.AbstractNpcAI;
/**
* @author Brutallis
*/
public class Bomb extends AbstractNpcAI
{
// NPCs
private static final int BOMB = 18003;
private static final int DIVINE_ANGEL = 20139;
// Items
private static final int[] ITEM_DROP_1 = new int[]
{
49756,
49762,
49763
};
private static final int[] ITEM_DROP_2 = new int[]
{
49760,
49761
};
public Bomb()
{
addKillId(BOMB);
addSpawnId(BOMB);
}
@Override
public String onSpawn(Npc npc)
{
npc.broadcastPacket(new ExChangeNpcState(npc.getObjectId(), 1));
return super.onSpawn(npc);
}
@Override
public String onKill(Npc npc, PlayerInstance killer, boolean isSummon)
{
if (Rnd.get(100) < 33)
{
AbstractScript.addSpawn(DIVINE_ANGEL, npc, false, 1800000);
}
else
{
World.getInstance().forEachVisibleObjectInRange((WorldObject) npc, Playable.class, 200, creature ->
{
if ((creature != null) && !creature.isDead())
{
creature.reduceCurrentHp(Rnd.get(300, 400), npc, null);
}
});
if (Rnd.get(100) < 50)
{
if (Rnd.get(100) < 90)
{
npc.dropItem(killer.getActingPlayer(), ITEM_DROP_1[Rnd.get(ITEM_DROP_1.length)], 1);
}
else
{
npc.dropItem(killer.getActingPlayer(), ITEM_DROP_2[Rnd.get(ITEM_DROP_2.length)], 1);
}
}
}
if (HeavenlyRiftManager.getAliveNpcCount(npc.getId()) == 0)
{
GlobalVariablesManager.getInstance().set("heavenly_rift_complete", GlobalVariablesManager.getInstance().getInt("heavenly_rift_level", 0));
GlobalVariablesManager.getInstance().set("heavenly_rift_level", 0);
}
return super.onKill(npc, killer, isSummon);
}
public static void main(String[] args)
{
new Bomb();
}
}

View File

@ -0,0 +1,79 @@
/*
* 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 ai.areas.TowerOfInsolence.HeavenlyRift;
import org.l2jmobius.gameserver.ai.AttackableAI;
import org.l2jmobius.gameserver.enums.ChatType;
import org.l2jmobius.gameserver.instancemanager.GlobalVariablesManager;
import org.l2jmobius.gameserver.instancemanager.HeavenlyRiftManager;
import org.l2jmobius.gameserver.model.actor.Creature;
import org.l2jmobius.gameserver.model.actor.Npc;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.network.NpcStringId;
import ai.AbstractNpcAI;
/**
* @author Brutallis
*/
public class DivineAngel extends AbstractNpcAI
{
// NPCs
private static final int TOWER = 18004;
private static final int DIVINE_ANGEL = 20139;
public DivineAngel()
{
addSpawnId(DIVINE_ANGEL);
addKillId(DIVINE_ANGEL);
}
@Override
public String onKill(Npc npc, PlayerInstance killer, boolean isSummon)
{
if ((GlobalVariablesManager.getInstance().getInt("heavenly_rift_level", 0) > 1) && (HeavenlyRiftManager.getAliveNpcCount(npc.getId()) == 0))
{
GlobalVariablesManager.getInstance().set("heavenly_rift_complete", GlobalVariablesManager.getInstance().getInt("heavenly_rift_level", 0));
GlobalVariablesManager.getInstance().set("heavenly_rift_level", 0);
GlobalVariablesManager.getInstance().set("heavenly_rift_reward", 1);
for (Creature creature : HeavenlyRiftManager.getZone().getCharactersInside())
{
if (creature.isMonster() && (creature.getId() == TOWER) && !creature.isDead())
{
((Npc) creature).broadcastSay(ChatType.NPC_SHOUT, NpcStringId.DIVINE_ANGELS_ARE_NOWHERE_TO_BE_SEEN_I_WANT_TO_TALK_TO_THE_PARTY_LEADER);
}
}
}
return super.onKill(npc, killer, isSummon);
}
@Override
public String onSpawn(Npc npc)
{
if (GlobalVariablesManager.getInstance().getInt("heavenly_rift_level", 0) == 2)
{
((AttackableAI) npc.getAI()).setGlobalAggro(0);
}
return super.onSpawn(npc);
}
public static void main(String[] args)
{
new DivineAngel();
}
}

View File

@ -0,0 +1,64 @@
/*
* 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 ai.areas.TowerOfInsolence.HeavenlyRift;
import org.l2jmobius.gameserver.instancemanager.GlobalVariablesManager;
import org.l2jmobius.gameserver.instancemanager.HeavenlyRiftManager;
import org.l2jmobius.gameserver.model.actor.Creature;
import org.l2jmobius.gameserver.model.actor.Npc;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.network.NpcStringId;
import org.l2jmobius.gameserver.network.serverpackets.ExShowScreenMessage;
import ai.AbstractNpcAI;
/**
* @author Brutallis
*/
public class Tower extends AbstractNpcAI
{
// NPCs
private static final int TOWER = 18004;
private static final int DIVINE_ANGEL = 20139;
public Tower()
{
addKillId(TOWER);
}
@Override
public String onKill(Npc npc, PlayerInstance killer, boolean isSummon)
{
HeavenlyRiftManager.getZone().broadcastPacket(new ExShowScreenMessage(NpcStringId.YOU_HAVE_FAILED, 2, 5000));
for (Creature creature : HeavenlyRiftManager.getZone().getCharactersInside())
{
if (creature.isMonster() && !creature.isDead() && (creature.getId() == DIVINE_ANGEL))
{
creature.decayMe();
}
}
GlobalVariablesManager.getInstance().set("heavenly_rift_complete", GlobalVariablesManager.getInstance().getInt("heavenly_rift_level", 0));
GlobalVariablesManager.getInstance().set("heavenly_rift_level", 0);
GlobalVariablesManager.getInstance().set("heavenly_rift_reward", 0);
return super.onKill(npc, killer, isSummon);
}
public static void main(String[] args)
{
new Tower();
}
}

View File

@ -3,8 +3,6 @@
<spawn name="Aden">
<group>
<npc id="30949" x="110831" y="15973" z="-4368" heading="412" respawnTime="60sec" />
<npc id="30950" x="114112" y="20042" z="944" heading="50148" respawnTime="60sec" />
<npc id="30951" x="118644" y="16680" z="6000" heading="42000" respawnTime="60sec" />
<npc id="31646" x="120112" y="30912" z="-3616" heading="49000" respawnTime="60sec" />
<npc id="30747" x="110395" y="41625" z="-4619" heading="0" respawnTime="60sec" />
<npc id="30764" x="117380" y="75616" z="-2664" heading="26000" respawnTime="60sec" />

View File

@ -1609,10 +1609,9 @@
</spawn>
<spawn name="23_18">
<group>
<npc id="30952" x="114220" y="13320" z="-5096" heading="228" respawnTime="60sec" /> <!-- Saviors -->
<npc id="30953" x="114048" y="20048" z="928" heading="49444" respawnTime="60sec" /> <!-- Saviors -->
<npc id="30954" x="118600" y="16724" z="5984" heading="42000" respawnTime="60sec" /> <!-- Saviors -->
<npc id="31862" x="112747" y="14163" z="10075" heading="0" respawnTime="60sec" /> <!-- Saviors -->
<npc id="30952" x="114220" y="13320" z="-5096" heading="228" respawnTime="60sec" /> <!-- Dimensional Vortex -->
<npc id="31862" x="112747" y="14163" z="10075" heading="0" respawnTime="60sec" /> <!-- Angelic Vortex -->
<npc id="30401" x="112634" y="13364" z="2445" heading="8021" /> <!--Arushinai-->
</group>
</spawn>
</list>

View File

@ -141,7 +141,7 @@
<sex>MALE</sex>
<acquire exp="44" sp="2" />
<stats str="40" int="21" dex="30" wit="20" con="43" men="10">
<vitals hp="2578" hpRegen="2" mp="1345" mpRegen="0.9" />
<vitals hp="39" hpRegen="2" mp="1345" mpRegen="0.9" />
<attack physical="4" magical="5.79" random="30" critical="8" accuracy="0" attackSpeed="253" type="FIST" range="40" distance="80" width="120" />
<defence physical="44.44" magical="32.52" />
<speed>
@ -175,7 +175,7 @@
<sex>MALE</sex>
<acquire sp="1" />
<stats str="40" int="21" dex="30" wit="20" con="43" men="10">
<vitals hp="2578" hpRegen="5.5" mp="1345" mpRegen="2.1" />
<vitals hp="1372" hpRegen="5.5" mp="1345" mpRegen="2.1" />
<attack physical="290.45" magical="198.34" random="30" critical="4" accuracy="20" attackSpeed="257" type="BOW" range="50" distance="80" width="120" />
<defence physical="195.66" magical="143.18" />
<speed>
@ -185,7 +185,7 @@
<hitTime>520</hitTime>
<abnormalResist physical="10" magical="10" />
</stats>
<status undying="false" />
<status undying="false" attackable="true" canMove="false"/>
<skillList>
<skill id="4273" level="3" /> <!-- Resist Daggers/Rapier Weapon -->
<skill id="4274" level="1" /> <!-- Blunt Weapon Weak Point -->
@ -305,6 +305,7 @@
<race>DEMONIC</race>
<sex>FEMALE</sex>
<acquire exp="18379865" sp="551395" />
<equipment rhand="5800" lhand="5799"/>
<stats str="40" int="21" dex="30" wit="20" con="43" men="10">
<vitals hp="1241578.01903" hpRegen="7.5" mp="1190.325" mpRegen="2.7" />
<attack physical="734.25" magical="501.4" random="30" critical="4" accuracy="4.75" attackSpeed="253" type="FIST" range="40" distance="80" width="120" />

View File

@ -1778,6 +1778,7 @@
<race>DIVINE</race>
<sex>MALE</sex>
<acquire exp="243344" sp="7300" />
<equipment rhand="148"/> <!-- rhand: Sword of Valhalla -->
<stats str="40" int="21" dex="30" wit="20" con="43" men="10">
<vitals hp="1719.9123557143" hpRegen="8.5" mp="1466.445" mpRegen="3" />
<attack physical="32.16396" magical="21.96382" random="30" critical="4" accuracy="4.75" attackSpeed="253" type="SWORD" range="40" distance="80" width="120" />
@ -1803,7 +1804,11 @@
</skillList>
<shots shotChance="30" spiritChance="30" />
<exCrtEffect>false</exCrtEffect>
<ai aggroRange="500" clanHelpRange="300" isAggressive="false" />
<ai aggroRange="2000" clanHelpRange="300" isAggressive="true">
<clanList>
<clan>ALL</clan>
</clanList>
</ai>
<collision>
<radius normal="13.5" />
<height normal="36.5" />

View File

@ -322,6 +322,16 @@
<node X="-253907" Y="221193" />
</zone>
<!-- Heavenly rift zone -->
<zone name="heavenly_rift" type="NoRestartZone" shape="NPoly" minZ="12000" maxZ="10800">
<node X="114169" Y="13781" />
<node X="112353" Y="15581" />
<node X="111219" Y="15072" />
<node X="111584" Y="14238" />
<node X="112815" Y="12991" />
<node X="113640" Y="12642" />
</zone>
<!-- High five zone -->
<zone name="olympiad_no_restart" type="NoRestartZone" shape="Cuboid" minZ="-8485" maxZ="1149">
<stat name="restartTime" val="0" />

View File

@ -0,0 +1,142 @@
/*
* 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 org.l2jmobius.gameserver.instancemanager;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.gameserver.model.Location;
import org.l2jmobius.gameserver.model.Spawn;
import org.l2jmobius.gameserver.model.actor.Creature;
import org.l2jmobius.gameserver.model.actor.Npc;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.model.zone.ZoneType;
import org.l2jmobius.gameserver.network.NpcStringId;
import org.l2jmobius.gameserver.network.serverpackets.ExShowScreenMessage;
/**
* @author Brutallis
*/
public class HeavenlyRiftManager
{
private static final ZoneType ZONE = ZoneManager.getInstance().getZoneByName("heavenly_rift");
public static ZoneType getZone()
{
return ZONE;
}
public static int getAliveNpcCount(int npcId)
{
int result = 0;
for (Creature creature : ZONE.getCharactersInside())
{
if (creature.isMonster() && !creature.isDead() && (creature.getId() == npcId))
{
result++;
}
}
return result;
}
public static void startEvent20Bomb(PlayerInstance player)
{
ZONE.broadcastPacket(new ExShowScreenMessage(NpcStringId.SET_OFF_BOMBS_AND_GET_TREASURES, 2, 5000));
spawnMonster(18003, 113352, 12936, 10976, 1800000);
spawnMonster(18003, 113592, 13272, 10976, 1800000);
spawnMonster(18003, 113816, 13592, 10976, 1800000);
spawnMonster(18003, 113080, 13192, 10976, 1800000);
spawnMonster(18003, 113336, 13528, 10976, 1800000);
spawnMonster(18003, 113560, 13832, 10976, 1800000);
spawnMonster(18003, 112776, 13512, 10976, 1800000);
spawnMonster(18003, 113064, 13784, 10976, 1800000);
spawnMonster(18003, 112440, 13848, 10976, 1800000);
spawnMonster(18003, 112728, 14104, 10976, 1800000);
spawnMonster(18003, 112760, 14600, 10976, 1800000);
spawnMonster(18003, 112392, 14456, 10976, 1800000);
spawnMonster(18003, 112104, 14184, 10976, 1800000);
spawnMonster(18003, 111816, 14488, 10976, 1800000);
spawnMonster(18003, 112104, 14760, 10976, 1800000);
spawnMonster(18003, 112392, 15032, 10976, 1800000);
spawnMonster(18003, 112120, 15288, 10976, 1800000);
spawnMonster(18003, 111784, 15064, 10976, 1800000);
spawnMonster(18003, 111480, 14824, 10976, 1800000);
spawnMonster(18003, 113144, 14216, 10976, 1800000);
}
public static void startEventTower(PlayerInstance player)
{
ZONE.broadcastPacket(new ExShowScreenMessage(NpcStringId.PROTECT_THE_CENTRAL_TOWER_FROM_DIVINE_ANGELS, 2, 5000));
spawnMonster(18004, 112648, 14072, 10976, 1800000);
ThreadPool.schedule(() ->
{
for (int i = 0; i < 20; ++i)
{
spawnMonster(20139, 112696, 13960, 10958, 1800000);
}
}, 10000);
}
public static void startEvent40Angels(PlayerInstance player)
{
ZONE.broadcastPacket(new ExShowScreenMessage(NpcStringId.DESTROY_WEAKENED_DIVINE_ANGELS, 2, 5000));
for (int i = 0; i < 40; ++i)
{
spawnMonster(20139, 112696, 13960, 10958, 1800000);
}
}
private static void spawnMonster(int npcId, int x, int y, int z, long despawnTime)
{
try
{
Spawn spawn = new Spawn(npcId);
Location location = new Location(x, y, z);
spawn.setLocation(location);
Npc npc = spawn.doSpawn();
npc.scheduleDespawn(despawnTime);
}
catch (Exception e)
{
}
}
public static class ClearZoneTask implements Runnable
{
private final Npc _npc;
public ClearZoneTask(Npc npc)
{
_npc = npc;
}
@Override
public void run()
{
for (Creature creature : ZONE.getCharactersInside())
{
if (creature.isPlayer())
{
creature.teleToLocation(114264, 13352, -5104);
}
else if (creature.isNpc() && (creature.getId() != 30401))
{
creature.decayMe();
}
}
_npc.setBusy(false);
}
}
}

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<list applyTaxes="true" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../xsd/multisell.xsd">
<npcs>
<npc>30952</npc> <!-- Dimensional Vortex -->
</npcs>
<item>
<!-- Broken Celestial Shard -->
<ingredient count="1" id="49767" />
<!-- Scroll of Heavenly Protection -->
<production count="1" id="49768" />
</item>
</list>

View File

@ -0,0 +1,12 @@
<html><body>Arushinai:<br>
Baium spent hundreds of years imprisoned. He was forced to watch how slowly his empire died...
Baium's anger was so great that the <font color="LEVEL">Heavenly Rift</font> itself began yo change under his influence.
I'll give you a little clue... So that you can imagine what can happen in the fault.
Or you will be attacked by <font color="LEVEL">40 Divine Angels</font> (kill them as soon as you notice),
or the will be <font color="LEVEL">20 Bombs</font> (their explosions will summon the Divine Angels, who will also have to be killed).
And be careful: from an exploding bomb can drop anything valuable! Either you need <font color="LEVEL">to protect the Tower</font> from 20 Divine Angels who will try to destroy it.
If you do this, you will receive a reward. Be extremely attentive!<br>
Fight shoulder to shoulder with you members. And remember: if you leave the Heavenly Rift before the due time, you can not return here.
Gather with strength - and go!<br>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest Arushinai proceed">Proceed to the task</button>
</body></html>

View File

@ -0,0 +1,4 @@
<html><body>Arushinai:<br>
It's not easy to get into the Heavenly Rift. When are you ready, I will send you <font color="LEVEL">back to Dimensional Vortex</font>.<br>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h npc_%objectId%_finish">Move all party</button>
</body></html>

View File

@ -0,0 +1,6 @@
<html><body>Arushinai:<br>
Do you know how the Heavenly Rift came about? The ego of the emperor Baium split the heaven.
Inside the fault, you can stay <font color="LEVEL">not longer than 30 minutes</font>. In such a dangerous place, mutual assistance and teamwork are especially important.
And remember: if you leave the rift prematurely, you will not be able to return here!<br>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest Arushinai 30401-1.htm">Learn more</button>
</body></html>

View File

@ -0,0 +1,155 @@
/*
* 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 ai.areas.TowerOfInsolence.Arushinai;
import org.l2jmobius.Config;
import org.l2jmobius.commons.util.Rnd;
import org.l2jmobius.gameserver.instancemanager.GlobalVariablesManager;
import org.l2jmobius.gameserver.instancemanager.HeavenlyRiftManager;
import org.l2jmobius.gameserver.model.Party;
import org.l2jmobius.gameserver.model.actor.Npc;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.network.SystemMessageId;
import org.l2jmobius.gameserver.network.serverpackets.SystemMessage;
import ai.AbstractNpcAI;
/**
* @author Brutallis
*/
public class Arushinai extends AbstractNpcAI
{
// NPC
private static final int ARUSHINAI = 30401;
private Arushinai()
{
addStartNpc(ARUSHINAI);
addTalkId(ARUSHINAI);
addFirstTalkId(ARUSHINAI);
}
@Override
public String onFirstTalk(Npc npc, PlayerInstance player)
{
return npc.getId() + ".htm";
}
@Override
public String onAdvEvent(String event, Npc npc, PlayerInstance player)
{
if (event.equals("30401-1.htm") || event.equals("30401-2.htm"))
{
return event;
}
if (event.equals("proceed"))
{
if (!player.isGM())
{
Party party = player.getParty();
if (party == null)
{
player.sendPacket(SystemMessageId.YOU_ARE_NOT_CURRENTLY_IN_A_PARTY_SO_YOU_CANNOT_ENTER);
player.teleToLocation(114264, 13352, -5104);
return null;
}
if (!party.isLeader(player))
{
player.sendPacket(SystemMessageId.ONLY_A_PARTY_LEADER_CAN_MAKE_THE_REQUEST_TO_ENTER);
return null;
}
}
if (GlobalVariablesManager.getInstance().getInt("heavenly_rift_complete", 0) != 0)
{
return null; // TODO: Find html?
}
final int riftLevel = Rnd.get(1, 3);
GlobalVariablesManager.getInstance().set("heavenly_rift_level", riftLevel);
GlobalVariablesManager.getInstance().set("heavenly_rift_complete", 4);
switch (riftLevel)
{
case 1:
{
HeavenlyRiftManager.startEvent20Bomb(player);
return null;
}
case 2:
{
HeavenlyRiftManager.startEventTower(player);
return null;
}
case 3:
{
HeavenlyRiftManager.startEvent40Angels(player);
break;
}
}
return null;
}
if (!event.equals("finish"))
{
return null;
}
if (player.isInParty())
{
Party party = player.getParty();
if (!party.isLeader(player))
{
player.sendPacket(SystemMessageId.YOU_CANNOT_PROCEED_AS_YOU_ARE_NOT_A_PARTY_LEADER);
return null;
}
for (PlayerInstance partyMember : party.getMembers())
{
if (player.calculateDistance2D(partyMember) > Config.ALT_PARTY_RANGE)
{
continue;
}
final SystemMessage sm = new SystemMessage(SystemMessageId.C1_IS_IN_A_LOCATION_WHICH_CANNOT_BE_ENTERED_THEREFORE_IT_CANNOT_BE_PROCESSED);
sm.addPcName(partyMember);
player.sendPacket(sm);
party.broadcastToPartyMembers(player, sm);
return null;
}
GlobalVariablesManager.getInstance().set("heavenly_rift_reward", 0);
for (PlayerInstance partyMember : party.getMembers())
{
partyMember.teleToLocation(114264, 13352, -5104);
}
return null;
}
if (player.isGM())
{
GlobalVariablesManager.getInstance().set("heavenly_rift_complete", 0);
player.teleToLocation(114264, 13352, -5104);
return null;
}
player.sendPacket(SystemMessageId.YOU_ARE_NOT_IN_A_PARTY);
return null;
}
public static void main(String[] args)
{
new Arushinai();
}
}

View File

@ -0,0 +1,6 @@
<html><head><body>
Dimensional Vortex:<br>
The energy of Emperor Baium's Rage caused by his imprisoning cracked the skies forming a rift. This rift leads to a new dimension. In order to get there, you will need a <font color=LEVEL>Celestial Shard</font>. You can extract it from the <font color=LEVEL>Unidentified Stone</font> after you kill all the monsters at the 6th floor or at higher floors of the Tower of Insolence.
<br>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest DimensionalVortex tryenter">Use Celestial Shard</Button>
</body></html>

View File

@ -0,0 +1,5 @@
<html><body>Dimensional Vortex:<br>
Eliminate all the monsters at the 6th floor or higher floors of the Tower of Insolence and use the <font color="LEVEL">Unidentified Stone</font> to extract <font color="LEVEL">Broken Celestial Shards</font> from it. You can exchange them for a special scroll, which might be useful during your hunt in the Tower of Insolence.<br>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h npc_%objectId%_Multisell 30952">Exchange Broken Celestial Shard</Button>
<Button ALIGN=LEFT ICON="RETURN" action="bypass -h Quest DimensionalVortex 30952.htm">Home</Button>
</body></html>

View File

@ -0,0 +1,4 @@
<html><body>Dimensional Vortex:<br>
You need an <font color="LEVEL">Airborne Fragment</font> from defeating the monsters on the sixth floor of the Tower of Insolence to enter the Airborne Rift.<br>
<Button ALIGN=LEFT ICON="RETURN" action="bypass -h Quest DimensionalVortex 30952.htm">Back</button>
</body></html>

View File

@ -0,0 +1,6 @@
<html><body>Dimensional Vortex:<br>
Baium was the emperor of Elmoreden, but angered the Gods and was put into solitude for years. He resented Einhasad for cursing him. A small rift appeared in the skies because of the ominous energy surrounding Baium.
<br>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest DimensionalVortex 30952-1.htm">Tell me about the Heavenly Rift.</button>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest DimensionalVortex 30952-2.htm">I want to exchange Broken Celestial Shards.</button>
</body></html>

View File

@ -0,0 +1,135 @@
/*
* 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 ai.areas.TowerOfInsolence.DimensionalVortex;
import org.l2jmobius.Config;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.gameserver.instancemanager.GlobalVariablesManager;
import org.l2jmobius.gameserver.instancemanager.HeavenlyRiftManager;
import org.l2jmobius.gameserver.model.Party;
import org.l2jmobius.gameserver.model.actor.Npc;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.network.SystemMessageId;
import org.l2jmobius.gameserver.network.serverpackets.SystemMessage;
import ai.AbstractNpcAI;
/**
* @author Brutallis
*/
public class DimensionalVortex extends AbstractNpcAI
{
// NPC
private static final int DIMENTIONAL_VORTEX = 30952;
// Items
private static final int CELESTIAL_SHARD = 49759;
private static final int BROKEN_CELESTIAL_SHARD = 49767;
private DimensionalVortex()
{
addStartNpc(DIMENTIONAL_VORTEX);
addTalkId(DIMENTIONAL_VORTEX);
addFirstTalkId(DIMENTIONAL_VORTEX);
}
@Override
public String onAdvEvent(String event, Npc npc, PlayerInstance player)
{
if (event.equals("30952-1.htm") || event.equals("30952-2.htm") || event.equals("30952-3.htm"))
{
return event;
}
if (event.equals("tryenter"))
{
if (getQuestItemsCount(player, CELESTIAL_SHARD) >= 1)
{
if (player.isGM())
{
player.destroyItemByItemId("Rift", CELESTIAL_SHARD, 1, npc, true);
GlobalVariablesManager.getInstance().set("heavenly_rift_complete", 0);
GlobalVariablesManager.getInstance().set("heavenly_rift_level", 0);
player.teleToLocation(112685, 13362, 10966);
ThreadPool.schedule(new HeavenlyRiftManager.ClearZoneTask(npc), 180000);
return null;
}
if (!player.isInParty())
{
player.sendPacket(SystemMessageId.YOU_ARE_NOT_CURRENTLY_IN_A_PARTY_SO_YOU_CANNOT_ENTER);
return null;
}
final Party party = player.getParty();
if ((party == null) || !party.isLeader(player))
{
player.sendPacket(SystemMessageId.ONLY_A_PARTY_LEADER_CAN_MAKE_THE_REQUEST_TO_ENTER);
return null;
}
for (PlayerInstance partyMember : party.getMembers())
{
if (player.calculateDistance2D(partyMember) > Config.ALT_PARTY_RANGE)
{
continue;
}
final SystemMessage sm = new SystemMessage(SystemMessageId.C1_IS_IN_A_LOCATION_WHICH_CANNOT_BE_ENTERED_THEREFORE_IT_CANNOT_BE_PROCESSED);
sm.addPcName(partyMember);
player.sendPacket(sm);
party.broadcastToPartyMembers(player, sm);
return null;
}
player.destroyItemByItemId("Rift", CELESTIAL_SHARD, 1, npc, true);
GlobalVariablesManager.getInstance().set("heavenly_rift_complete", 0);
GlobalVariablesManager.getInstance().set("heavenly_rift_level", 0);
for (PlayerInstance partyMember : party.getMembers())
{
partyMember.teleToLocation(112685, 13362, 10966);
}
ThreadPool.schedule(new HeavenlyRiftManager.ClearZoneTask(npc), 1200000);
}
else
{
return "30952-3.htm";
}
}
else if (event.equals("exchange"))
{
long count = getQuestItemsCount(player, BROKEN_CELESTIAL_SHARD);
if (count < 10)
{
return "30952-2.htm";
}
if ((count % 10) != 0)
{
count -= count % 10;
}
final long reward = count / 10;
player.destroyItemByItemId("Rift", BROKEN_CELESTIAL_SHARD, count, npc, true);
player.addItem("Rift", CELESTIAL_SHARD, reward, npc, true);
}
return null;
}
@Override
public String onFirstTalk(Npc npc, PlayerInstance player)
{
return npc.getId() + ".htm";
}
public static void main(String[] args)
{
new DimensionalVortex();
}
}

View File

@ -0,0 +1,233 @@
/*
* 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 ai.areas.TowerOfInsolence;
import java.util.List;
import java.util.concurrent.ScheduledFuture;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.commons.util.CommonUtil;
import org.l2jmobius.commons.util.Rnd;
import org.l2jmobius.gameserver.data.xml.impl.SpawnData;
import org.l2jmobius.gameserver.enums.ChatType;
import org.l2jmobius.gameserver.model.ChanceLocation;
import org.l2jmobius.gameserver.model.Location;
import org.l2jmobius.gameserver.model.Spawn;
import org.l2jmobius.gameserver.model.actor.Npc;
import org.l2jmobius.gameserver.model.actor.instance.MonsterInstance;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.model.skills.AbnormalVisualEffect;
import org.l2jmobius.gameserver.model.spawns.NpcSpawnTemplate;
import org.l2jmobius.gameserver.network.NpcStringId;
import ai.AbstractNpcAI;
/**
* @author Brutallis
*/
public class EnergyOfInsolence extends AbstractNpcAI
{
private static final int LEVEL_MAX_DIFF = 9;
private static final int TIME_UNTIL_MOVE = 1800000;
private static final int ELMOREDEN_LADY = 20977;
private static final int POWER_ANGEL_AMON = 21081;
private static final int ENERGY_OF_INSOLENCE_DROP_RATE = 70;
private static final int ENERGY_OF_INSOLENCE_ITEM_ID = 49685;
private static final int ENERGY_OF_INSOLENCE_DROP_COUNT = 1;
private static final int UNIDENTIFIED_STONE_DROP_RATE = 4;
private static final int UNIDENTIFIED_STONE_ITEM_ID = 49766;
private static final int[] ENERGY_OF_INSOLENCE_NPC_IDS = new int[]
{
ELMOREDEN_LADY,
POWER_ANGEL_AMON
};
private static final int[] ENERGY_OF_INSOLENCE_MINIONS = new int[]
{
20978,
20979,
21073,
21082,
21083
};
private static final int[] UNIDENTIFIED_STONE_NPC_IDS = new int[]
{
20980,
20981,
20982,
20983,
20984,
20985,
21074,
21075,
21076,
21077,
21080
};
private static ScheduledFuture<?> _scheduleTaskElmoreden;
private static ScheduledFuture<?> _scheduleTaskAmon;
private EnergyOfInsolence()
{
addSpawnId(ENERGY_OF_INSOLENCE_NPC_IDS);
addKillId(ENERGY_OF_INSOLENCE_NPC_IDS);
addKillId(UNIDENTIFIED_STONE_NPC_IDS);
addKillId(ENERGY_OF_INSOLENCE_MINIONS);
}
private void makeInvul(Npc npc)
{
npc.getEffectList().startAbnormalVisualEffect(new AbnormalVisualEffect[]
{
AbnormalVisualEffect.INVINCIBILITY
});
npc.setInvul(true);
}
private void makeMortal(Npc npc)
{
npc.getEffectList().stopAbnormalVisualEffect(new AbnormalVisualEffect[]
{
AbnormalVisualEffect.INVINCIBILITY
});
npc.setInvul(false);
}
private void makeTalk(Npc npc, boolean spawning)
{
NpcStringId npcStringId = null;
switch (npc.getId())
{
case ELMOREDEN_LADY:
{
npcStringId = spawning ? NpcStringId.MY_SERVANTS_CAN_KEEP_ME_SAFE_I_HAVE_NOTHING_TO_FEAR : NpcStringId.CAN_T_DIE_IN_A_PLACE_LIKE_THIS;
break;
}
case POWER_ANGEL_AMON:
{
npcStringId = spawning ? NpcStringId.I_WONDER_WHO_IT_IS_THAT_IS_LURKING_ABOUT : NpcStringId.WHY_WOULD_YOU_BUILD_A_TOWER_IN_OUR_TERRITORY;
}
}
npc.broadcastSay(ChatType.NPC_SHOUT, npcStringId);
}
@Override
public String onSpawn(Npc npc)
{
if (CommonUtil.contains(ENERGY_OF_INSOLENCE_NPC_IDS, npc.getId()))
{
makeTalk(npc, true);
switch (npc.getId())
{
case ELMOREDEN_LADY:
{
makeInvul(npc);
_scheduleTaskElmoreden = ThreadPool.schedule(new ScheduleAITask(npc, ELMOREDEN_LADY), TIME_UNTIL_MOVE);
break;
}
case POWER_ANGEL_AMON:
{
_scheduleTaskAmon = ThreadPool.schedule(new ScheduleAITask(npc, POWER_ANGEL_AMON), TIME_UNTIL_MOVE);
}
}
}
return super.onSpawn(npc);
}
@Override
public String onKill(Npc npc, PlayerInstance killer, boolean isSummon)
{
if (CommonUtil.contains(UNIDENTIFIED_STONE_NPC_IDS, npc.getId()) && ((killer.getLevel() - npc.getLevel()) <= LEVEL_MAX_DIFF) && (Rnd.get(100) <= UNIDENTIFIED_STONE_DROP_RATE))
{
npc.dropItem(killer, UNIDENTIFIED_STONE_ITEM_ID, ENERGY_OF_INSOLENCE_DROP_COUNT);
}
if (CommonUtil.contains(ENERGY_OF_INSOLENCE_NPC_IDS, npc.getId()))
{
makeTalk(npc, false);
switch (npc.getId())
{
case ELMOREDEN_LADY:
{
_scheduleTaskElmoreden.cancel(true);
_scheduleTaskElmoreden = ThreadPool.schedule(new ScheduleAITask(null, ELMOREDEN_LADY), TIME_UNTIL_MOVE);
break;
}
case POWER_ANGEL_AMON:
{
_scheduleTaskAmon.cancel(true);
_scheduleTaskAmon = ThreadPool.schedule(new ScheduleAITask(null, POWER_ANGEL_AMON), TIME_UNTIL_MOVE);
}
}
if (((killer.getLevel() - npc.getLevel()) <= LEVEL_MAX_DIFF) && (Rnd.get(100) <= ENERGY_OF_INSOLENCE_DROP_RATE))
{
npc.dropItem(killer, ENERGY_OF_INSOLENCE_ITEM_ID, ENERGY_OF_INSOLENCE_DROP_COUNT);
}
}
if (CommonUtil.contains(ENERGY_OF_INSOLENCE_MINIONS, npc.getId()))
{
final MonsterInstance leader = ((MonsterInstance) npc).getLeader();
if ((leader != null) && (leader.getMinionList().getSpawnedMinions().size() == 0) && !leader.isDead())
{
makeMortal(leader);
}
}
return super.onKill(npc, killer, isSummon);
}
public static AbstractNpcAI provider()
{
return new EnergyOfInsolence();
}
public class ScheduleAITask implements Runnable
{
private final Npc _npc;
private final int _npcId;
public ScheduleAITask(Npc npc, int npcId)
{
_npc = npc;
_npcId = npcId;
}
@Override
public void run()
{
if (_npc != null)
{
_npc.deleteMe();
}
try
{
final Spawn spawn = new Spawn(_npcId);
final List<NpcSpawnTemplate> spawns = SpawnData.getInstance().getNpcSpawns(npcSpawnTemplate -> npcSpawnTemplate.getId() == _npcId);
final List<ChanceLocation> locations = spawns.get(0).getLocation();
final Location location = locations.get(Rnd.get(locations.size()));
spawn.setLocation(location);
spawn.doSpawn();
}
catch (Exception e)
{
}
}
}
public static void main(String[] args)
{
new EnergyOfInsolence();
}
}

View File

@ -0,0 +1,106 @@
/*
* 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 ai.areas.TowerOfInsolence.HeavenlyRift;
import org.l2jmobius.commons.util.Rnd;
import org.l2jmobius.gameserver.instancemanager.GlobalVariablesManager;
import org.l2jmobius.gameserver.instancemanager.HeavenlyRiftManager;
import org.l2jmobius.gameserver.model.World;
import org.l2jmobius.gameserver.model.WorldObject;
import org.l2jmobius.gameserver.model.actor.Npc;
import org.l2jmobius.gameserver.model.actor.Playable;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.model.events.AbstractScript;
import org.l2jmobius.gameserver.network.serverpackets.ExChangeNpcState;
import ai.AbstractNpcAI;
/**
* @author Brutallis
*/
public class Bomb extends AbstractNpcAI
{
// NPCs
private static final int BOMB = 18003;
private static final int DIVINE_ANGEL = 20139;
// Items
private static final int[] ITEM_DROP_1 = new int[]
{
49756,
49762,
49763
};
private static final int[] ITEM_DROP_2 = new int[]
{
49760,
49761
};
public Bomb()
{
addKillId(BOMB);
addSpawnId(BOMB);
}
@Override
public String onSpawn(Npc npc)
{
npc.broadcastPacket(new ExChangeNpcState(npc.getObjectId(), 1));
return super.onSpawn(npc);
}
@Override
public String onKill(Npc npc, PlayerInstance killer, boolean isSummon)
{
if (Rnd.get(100) < 33)
{
AbstractScript.addSpawn(DIVINE_ANGEL, npc, false, 1800000);
}
else
{
World.getInstance().forEachVisibleObjectInRange((WorldObject) npc, Playable.class, 200, creature ->
{
if ((creature != null) && !creature.isDead())
{
creature.reduceCurrentHp(Rnd.get(300, 400), npc, null);
}
});
if (Rnd.get(100) < 50)
{
if (Rnd.get(100) < 90)
{
npc.dropItem(killer.getActingPlayer(), ITEM_DROP_1[Rnd.get(ITEM_DROP_1.length)], 1);
}
else
{
npc.dropItem(killer.getActingPlayer(), ITEM_DROP_2[Rnd.get(ITEM_DROP_2.length)], 1);
}
}
}
if (HeavenlyRiftManager.getAliveNpcCount(npc.getId()) == 0)
{
GlobalVariablesManager.getInstance().set("heavenly_rift_complete", GlobalVariablesManager.getInstance().getInt("heavenly_rift_level", 0));
GlobalVariablesManager.getInstance().set("heavenly_rift_level", 0);
}
return super.onKill(npc, killer, isSummon);
}
public static void main(String[] args)
{
new Bomb();
}
}

View File

@ -0,0 +1,79 @@
/*
* 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 ai.areas.TowerOfInsolence.HeavenlyRift;
import org.l2jmobius.gameserver.ai.AttackableAI;
import org.l2jmobius.gameserver.enums.ChatType;
import org.l2jmobius.gameserver.instancemanager.GlobalVariablesManager;
import org.l2jmobius.gameserver.instancemanager.HeavenlyRiftManager;
import org.l2jmobius.gameserver.model.actor.Creature;
import org.l2jmobius.gameserver.model.actor.Npc;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.network.NpcStringId;
import ai.AbstractNpcAI;
/**
* @author Brutallis
*/
public class DivineAngel extends AbstractNpcAI
{
// NPCs
private static final int TOWER = 18004;
private static final int DIVINE_ANGEL = 20139;
public DivineAngel()
{
addSpawnId(DIVINE_ANGEL);
addKillId(DIVINE_ANGEL);
}
@Override
public String onKill(Npc npc, PlayerInstance killer, boolean isSummon)
{
if ((GlobalVariablesManager.getInstance().getInt("heavenly_rift_level", 0) > 1) && (HeavenlyRiftManager.getAliveNpcCount(npc.getId()) == 0))
{
GlobalVariablesManager.getInstance().set("heavenly_rift_complete", GlobalVariablesManager.getInstance().getInt("heavenly_rift_level", 0));
GlobalVariablesManager.getInstance().set("heavenly_rift_level", 0);
GlobalVariablesManager.getInstance().set("heavenly_rift_reward", 1);
for (Creature creature : HeavenlyRiftManager.getZone().getCharactersInside())
{
if (creature.isMonster() && (creature.getId() == TOWER) && !creature.isDead())
{
((Npc) creature).broadcastSay(ChatType.NPC_SHOUT, NpcStringId.DIVINE_ANGELS_ARE_NOWHERE_TO_BE_SEEN_I_WANT_TO_TALK_TO_THE_PARTY_LEADER);
}
}
}
return super.onKill(npc, killer, isSummon);
}
@Override
public String onSpawn(Npc npc)
{
if (GlobalVariablesManager.getInstance().getInt("heavenly_rift_level", 0) == 2)
{
((AttackableAI) npc.getAI()).setGlobalAggro(0);
}
return super.onSpawn(npc);
}
public static void main(String[] args)
{
new DivineAngel();
}
}

View File

@ -0,0 +1,64 @@
/*
* 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 ai.areas.TowerOfInsolence.HeavenlyRift;
import org.l2jmobius.gameserver.instancemanager.GlobalVariablesManager;
import org.l2jmobius.gameserver.instancemanager.HeavenlyRiftManager;
import org.l2jmobius.gameserver.model.actor.Creature;
import org.l2jmobius.gameserver.model.actor.Npc;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.network.NpcStringId;
import org.l2jmobius.gameserver.network.serverpackets.ExShowScreenMessage;
import ai.AbstractNpcAI;
/**
* @author Brutallis
*/
public class Tower extends AbstractNpcAI
{
// NPCs
private static final int TOWER = 18004;
private static final int DIVINE_ANGEL = 20139;
public Tower()
{
addKillId(TOWER);
}
@Override
public String onKill(Npc npc, PlayerInstance killer, boolean isSummon)
{
HeavenlyRiftManager.getZone().broadcastPacket(new ExShowScreenMessage(NpcStringId.YOU_HAVE_FAILED, 2, 5000));
for (Creature creature : HeavenlyRiftManager.getZone().getCharactersInside())
{
if (creature.isMonster() && !creature.isDead() && (creature.getId() == DIVINE_ANGEL))
{
creature.decayMe();
}
}
GlobalVariablesManager.getInstance().set("heavenly_rift_complete", GlobalVariablesManager.getInstance().getInt("heavenly_rift_level", 0));
GlobalVariablesManager.getInstance().set("heavenly_rift_level", 0);
GlobalVariablesManager.getInstance().set("heavenly_rift_reward", 0);
return super.onKill(npc, killer, isSummon);
}
public static void main(String[] args)
{
new Tower();
}
}

View File

@ -3,8 +3,6 @@
<spawn name="Aden">
<group>
<npc id="30949" x="110831" y="15973" z="-4368" heading="412" respawnTime="60sec" />
<npc id="30950" x="114112" y="20042" z="944" heading="50148" respawnTime="60sec" />
<npc id="30951" x="118644" y="16680" z="6000" heading="42000" respawnTime="60sec" />
<npc id="31646" x="120112" y="30912" z="-3616" heading="49000" respawnTime="60sec" />
<npc id="30747" x="110395" y="41625" z="-4619" heading="0" respawnTime="60sec" />
<npc id="30764" x="117380" y="75616" z="-2664" heading="26000" respawnTime="60sec" />

View File

@ -1638,6 +1638,7 @@
<npc id="19133" x="115000" y="11309" z="-5120" heading="32767" respawnTime="60sec" /> <!-- Antharas -->
<npc id="19133" x="115000" y="11409" z="-5120" heading="32767" respawnTime="60sec" /> <!-- Antharas -->
<npc id="31714" x="114922" y="11230" z="-5130" heading="336" respawnTime="60sec" /> <!-- Ateld -->
<npc id="30401" x="112634" y="13364" z="2445" heading="8021" /> <!--Arushinai-->
</group>
</spawn>
</list>

View File

@ -141,12 +141,12 @@
<sex>MALE</sex>
<acquire exp="44" sp="2" />
<stats str="40" int="21" dex="30" wit="20" con="43" men="10">
<vitals hp="39" hpRegen="2" mp="40" mpRegen="0.9" />
<vitals hp="39" hpRegen="2" mp="1345" mpRegen="0.9" />
<attack physical="4" magical="5.79" random="30" critical="8" accuracy="0" attackSpeed="253" type="FIST" range="40" distance="80" width="120" />
<defence physical="44.44" magical="32.52" />
<speed>
<walk ground="23" />
<run ground="110" />
<walk ground="1" />
<run ground="1" />
</speed>
<hitTime>370</hitTime>
<abnormalResist physical="10" magical="10" />
@ -175,7 +175,7 @@
<sex>MALE</sex>
<acquire sp="1" />
<stats str="40" int="21" dex="30" wit="20" con="43" men="10">
<vitals hp="1372" hpRegen="5.5" mp="720" mpRegen="2.1" />
<vitals hp="1372" hpRegen="5.5" mp="1345" mpRegen="2.1" />
<attack physical="290.45" magical="198.34" random="30" critical="4" accuracy="20" attackSpeed="257" type="BOW" range="50" distance="80" width="120" />
<defence physical="195.66" magical="143.18" />
<speed>
@ -185,7 +185,7 @@
<hitTime>520</hitTime>
<abnormalResist physical="10" magical="10" />
</stats>
<status undying="false" />
<status undying="false" attackable="true" canMove="false"/>
<skillList>
<skill id="4273" level="3" /> <!-- Resist Daggers/Rapier Weapon -->
<skill id="4274" level="1" /> <!-- Blunt Weapon Weak Point -->
@ -305,6 +305,7 @@
<race>DEMONIC</race>
<sex>FEMALE</sex>
<acquire exp="9189932" sp="275697" />
<equipment rhand="5800" lhand="5799"/>
<stats str="40" int="21" dex="30" wit="20" con="43" men="10">
<vitals hp="1241577.52641" hpRegen="7.5" mp="2284.185" mpRegen="2.7" />
<attack physical="734.25" magical="501.4" random="30" critical="4" accuracy="4.75" attackSpeed="253" type="FIST" range="40" distance="80" width="120" />

View File

@ -1718,6 +1718,7 @@
<race>DIVINE</race>
<sex>MALE</sex>
<acquire exp="243344" sp="7300" />
<equipment rhand="148"/> <!-- rhand: Sword of Valhalla -->
<stats str="40" int="21" dex="30" wit="20" con="43" men="10">
<vitals hp="1719.9123557143" hpRegen="8.5" mp="1466.445" mpRegen="3" />
<attack physical="32.16396" magical="21.96382" random="30" critical="4" accuracy="4.75" attackSpeed="253" type="SWORD" range="40" distance="80" width="120" />
@ -1743,7 +1744,11 @@
</skillList>
<shots shotChance="30" spiritChance="30" />
<exCrtEffect>false</exCrtEffect>
<ai aggroRange="500" clanHelpRange="300" isAggressive="false" />
<ai aggroRange="2000" clanHelpRange="300" isAggressive="true">
<clanList>
<clan>ALL</clan>
</clanList>
</ai>
<collision>
<radius normal="13.5" />
<height normal="36.5" />

View File

@ -322,6 +322,16 @@
<node X="-253907" Y="221193" />
</zone>
<!-- Heavenly rift zone -->
<zone name="heavenly_rift" type="NoRestartZone" shape="NPoly" minZ="12000" maxZ="10800">
<node X="114169" Y="13781" />
<node X="112353" Y="15581" />
<node X="111219" Y="15072" />
<node X="111584" Y="14238" />
<node X="112815" Y="12991" />
<node X="113640" Y="12642" />
</zone>
<!-- High five zone -->
<zone name="olympiad_no_restart" type="NoRestartZone" shape="Cuboid" minZ="-8485" maxZ="1149">
<stat name="restartTime" val="0" />

View File

@ -0,0 +1,142 @@
/*
* 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 org.l2jmobius.gameserver.instancemanager;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.gameserver.model.Location;
import org.l2jmobius.gameserver.model.Spawn;
import org.l2jmobius.gameserver.model.actor.Creature;
import org.l2jmobius.gameserver.model.actor.Npc;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.model.zone.ZoneType;
import org.l2jmobius.gameserver.network.NpcStringId;
import org.l2jmobius.gameserver.network.serverpackets.ExShowScreenMessage;
/**
* @author Brutallis
*/
public class HeavenlyRiftManager
{
private static final ZoneType ZONE = ZoneManager.getInstance().getZoneByName("heavenly_rift");
public static ZoneType getZone()
{
return ZONE;
}
public static int getAliveNpcCount(int npcId)
{
int result = 0;
for (Creature creature : ZONE.getCharactersInside())
{
if (creature.isMonster() && !creature.isDead() && (creature.getId() == npcId))
{
result++;
}
}
return result;
}
public static void startEvent20Bomb(PlayerInstance player)
{
ZONE.broadcastPacket(new ExShowScreenMessage(NpcStringId.SET_OFF_BOMBS_AND_GET_TREASURES, 2, 5000));
spawnMonster(18003, 113352, 12936, 10976, 1800000);
spawnMonster(18003, 113592, 13272, 10976, 1800000);
spawnMonster(18003, 113816, 13592, 10976, 1800000);
spawnMonster(18003, 113080, 13192, 10976, 1800000);
spawnMonster(18003, 113336, 13528, 10976, 1800000);
spawnMonster(18003, 113560, 13832, 10976, 1800000);
spawnMonster(18003, 112776, 13512, 10976, 1800000);
spawnMonster(18003, 113064, 13784, 10976, 1800000);
spawnMonster(18003, 112440, 13848, 10976, 1800000);
spawnMonster(18003, 112728, 14104, 10976, 1800000);
spawnMonster(18003, 112760, 14600, 10976, 1800000);
spawnMonster(18003, 112392, 14456, 10976, 1800000);
spawnMonster(18003, 112104, 14184, 10976, 1800000);
spawnMonster(18003, 111816, 14488, 10976, 1800000);
spawnMonster(18003, 112104, 14760, 10976, 1800000);
spawnMonster(18003, 112392, 15032, 10976, 1800000);
spawnMonster(18003, 112120, 15288, 10976, 1800000);
spawnMonster(18003, 111784, 15064, 10976, 1800000);
spawnMonster(18003, 111480, 14824, 10976, 1800000);
spawnMonster(18003, 113144, 14216, 10976, 1800000);
}
public static void startEventTower(PlayerInstance player)
{
ZONE.broadcastPacket(new ExShowScreenMessage(NpcStringId.PROTECT_THE_CENTRAL_TOWER_FROM_DIVINE_ANGELS, 2, 5000));
spawnMonster(18004, 112648, 14072, 10976, 1800000);
ThreadPool.schedule(() ->
{
for (int i = 0; i < 20; ++i)
{
spawnMonster(20139, 112696, 13960, 10958, 1800000);
}
}, 10000);
}
public static void startEvent40Angels(PlayerInstance player)
{
ZONE.broadcastPacket(new ExShowScreenMessage(NpcStringId.DESTROY_WEAKENED_DIVINE_ANGELS, 2, 5000));
for (int i = 0; i < 40; ++i)
{
spawnMonster(20139, 112696, 13960, 10958, 1800000);
}
}
private static void spawnMonster(int npcId, int x, int y, int z, long despawnTime)
{
try
{
Spawn spawn = new Spawn(npcId);
Location location = new Location(x, y, z);
spawn.setLocation(location);
Npc npc = spawn.doSpawn();
npc.scheduleDespawn(despawnTime);
}
catch (Exception e)
{
}
}
public static class ClearZoneTask implements Runnable
{
private final Npc _npc;
public ClearZoneTask(Npc npc)
{
_npc = npc;
}
@Override
public void run()
{
for (Creature creature : ZONE.getCharactersInside())
{
if (creature.isPlayer())
{
creature.teleToLocation(114264, 13352, -5104);
}
else if (creature.isNpc() && (creature.getId() != 30401))
{
creature.decayMe();
}
}
_npc.setBusy(false);
}
}
}

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<list applyTaxes="true" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../xsd/multisell.xsd">
<npcs>
<npc>30952</npc> <!-- Dimensional Vortex -->
</npcs>
<item>
<!-- Broken Celestial Shard -->
<ingredient count="1" id="49767" />
<!-- Scroll of Heavenly Protection -->
<production count="1" id="49768" />
</item>
</list>

View File

@ -0,0 +1,12 @@
<html><body>Arushinai:<br>
Baium spent hundreds of years imprisoned. He was forced to watch how slowly his empire died...
Baium's anger was so great that the <font color="LEVEL">Heavenly Rift</font> itself began yo change under his influence.
I'll give you a little clue... So that you can imagine what can happen in the fault.
Or you will be attacked by <font color="LEVEL">40 Divine Angels</font> (kill them as soon as you notice),
or the will be <font color="LEVEL">20 Bombs</font> (their explosions will summon the Divine Angels, who will also have to be killed).
And be careful: from an exploding bomb can drop anything valuable! Either you need <font color="LEVEL">to protect the Tower</font> from 20 Divine Angels who will try to destroy it.
If you do this, you will receive a reward. Be extremely attentive!<br>
Fight shoulder to shoulder with you members. And remember: if you leave the Heavenly Rift before the due time, you can not return here.
Gather with strength - and go!<br>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest Arushinai proceed">Proceed to the task</button>
</body></html>

View File

@ -0,0 +1,4 @@
<html><body>Arushinai:<br>
It's not easy to get into the Heavenly Rift. When are you ready, I will send you <font color="LEVEL">back to Dimensional Vortex</font>.<br>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h npc_%objectId%_finish">Move all party</button>
</body></html>

View File

@ -0,0 +1,6 @@
<html><body>Arushinai:<br>
Do you know how the Heavenly Rift came about? The ego of the emperor Baium split the heaven.
Inside the fault, you can stay <font color="LEVEL">not longer than 30 minutes</font>. In such a dangerous place, mutual assistance and teamwork are especially important.
And remember: if you leave the rift prematurely, you will not be able to return here!<br>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest Arushinai 30401-1.htm">Learn more</button>
</body></html>

View File

@ -0,0 +1,155 @@
/*
* 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 ai.areas.TowerOfInsolence.Arushinai;
import org.l2jmobius.Config;
import org.l2jmobius.commons.util.Rnd;
import org.l2jmobius.gameserver.instancemanager.GlobalVariablesManager;
import org.l2jmobius.gameserver.instancemanager.HeavenlyRiftManager;
import org.l2jmobius.gameserver.model.Party;
import org.l2jmobius.gameserver.model.actor.Npc;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.network.SystemMessageId;
import org.l2jmobius.gameserver.network.serverpackets.SystemMessage;
import ai.AbstractNpcAI;
/**
* @author Brutallis
*/
public class Arushinai extends AbstractNpcAI
{
// NPC
private static final int ARUSHINAI = 30401;
private Arushinai()
{
addStartNpc(ARUSHINAI);
addTalkId(ARUSHINAI);
addFirstTalkId(ARUSHINAI);
}
@Override
public String onFirstTalk(Npc npc, PlayerInstance player)
{
return npc.getId() + ".htm";
}
@Override
public String onAdvEvent(String event, Npc npc, PlayerInstance player)
{
if (event.equals("30401-1.htm") || event.equals("30401-2.htm"))
{
return event;
}
if (event.equals("proceed"))
{
if (!player.isGM())
{
Party party = player.getParty();
if (party == null)
{
player.sendPacket(SystemMessageId.YOU_ARE_NOT_CURRENTLY_IN_A_PARTY_SO_YOU_CANNOT_ENTER);
player.teleToLocation(114264, 13352, -5104);
return null;
}
if (!party.isLeader(player))
{
player.sendPacket(SystemMessageId.ONLY_A_PARTY_LEADER_CAN_MAKE_THE_REQUEST_TO_ENTER);
return null;
}
}
if (GlobalVariablesManager.getInstance().getInt("heavenly_rift_complete", 0) != 0)
{
return null; // TODO: Find html?
}
final int riftLevel = Rnd.get(1, 3);
GlobalVariablesManager.getInstance().set("heavenly_rift_level", riftLevel);
GlobalVariablesManager.getInstance().set("heavenly_rift_complete", 4);
switch (riftLevel)
{
case 1:
{
HeavenlyRiftManager.startEvent20Bomb(player);
return null;
}
case 2:
{
HeavenlyRiftManager.startEventTower(player);
return null;
}
case 3:
{
HeavenlyRiftManager.startEvent40Angels(player);
break;
}
}
return null;
}
if (!event.equals("finish"))
{
return null;
}
if (player.isInParty())
{
Party party = player.getParty();
if (!party.isLeader(player))
{
player.sendPacket(SystemMessageId.YOU_CANNOT_PROCEED_AS_YOU_ARE_NOT_A_PARTY_LEADER);
return null;
}
for (PlayerInstance partyMember : party.getMembers())
{
if (player.calculateDistance2D(partyMember) > Config.ALT_PARTY_RANGE)
{
continue;
}
final SystemMessage sm = new SystemMessage(SystemMessageId.C1_IS_IN_A_LOCATION_WHICH_CANNOT_BE_ENTERED_THEREFORE_IT_CANNOT_BE_PROCESSED);
sm.addPcName(partyMember);
player.sendPacket(sm);
party.broadcastToPartyMembers(player, sm);
return null;
}
GlobalVariablesManager.getInstance().set("heavenly_rift_reward", 0);
for (PlayerInstance partyMember : party.getMembers())
{
partyMember.teleToLocation(114264, 13352, -5104);
}
return null;
}
if (player.isGM())
{
GlobalVariablesManager.getInstance().set("heavenly_rift_complete", 0);
player.teleToLocation(114264, 13352, -5104);
return null;
}
player.sendPacket(SystemMessageId.YOU_ARE_NOT_IN_A_PARTY);
return null;
}
public static void main(String[] args)
{
new Arushinai();
}
}

View File

@ -0,0 +1,6 @@
<html><head><body>
Dimensional Vortex:<br>
The energy of Emperor Baium's Rage caused by his imprisoning cracked the skies forming a rift. This rift leads to a new dimension. In order to get there, you will need a <font color=LEVEL>Celestial Shard</font>. You can extract it from the <font color=LEVEL>Unidentified Stone</font> after you kill all the monsters at the 6th floor or at higher floors of the Tower of Insolence.
<br>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest DimensionalVortex tryenter">Use Celestial Shard</Button>
</body></html>

View File

@ -0,0 +1,5 @@
<html><body>Dimensional Vortex:<br>
Eliminate all the monsters at the 6th floor or higher floors of the Tower of Insolence and use the <font color="LEVEL">Unidentified Stone</font> to extract <font color="LEVEL">Broken Celestial Shards</font> from it. You can exchange them for a special scroll, which might be useful during your hunt in the Tower of Insolence.<br>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h npc_%objectId%_Multisell 30952">Exchange Broken Celestial Shard</Button>
<Button ALIGN=LEFT ICON="RETURN" action="bypass -h Quest DimensionalVortex 30952.htm">Home</Button>
</body></html>

View File

@ -0,0 +1,4 @@
<html><body>Dimensional Vortex:<br>
You need an <font color="LEVEL">Airborne Fragment</font> from defeating the monsters on the sixth floor of the Tower of Insolence to enter the Airborne Rift.<br>
<Button ALIGN=LEFT ICON="RETURN" action="bypass -h Quest DimensionalVortex 30952.htm">Back</button>
</body></html>

View File

@ -0,0 +1,6 @@
<html><body>Dimensional Vortex:<br>
Baium was the emperor of Elmoreden, but angered the Gods and was put into solitude for years. He resented Einhasad for cursing him. A small rift appeared in the skies because of the ominous energy surrounding Baium.
<br>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest DimensionalVortex 30952-1.htm">Tell me about the Heavenly Rift.</button>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest DimensionalVortex 30952-2.htm">I want to exchange Broken Celestial Shards.</button>
</body></html>

View File

@ -0,0 +1,135 @@
/*
* 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 ai.areas.TowerOfInsolence.DimensionalVortex;
import org.l2jmobius.Config;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.gameserver.instancemanager.GlobalVariablesManager;
import org.l2jmobius.gameserver.instancemanager.HeavenlyRiftManager;
import org.l2jmobius.gameserver.model.Party;
import org.l2jmobius.gameserver.model.actor.Npc;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.network.SystemMessageId;
import org.l2jmobius.gameserver.network.serverpackets.SystemMessage;
import ai.AbstractNpcAI;
/**
* @author Brutallis
*/
public class DimensionalVortex extends AbstractNpcAI
{
// NPC
private static final int DIMENTIONAL_VORTEX = 30952;
// Items
private static final int CELESTIAL_SHARD = 49759;
private static final int BROKEN_CELESTIAL_SHARD = 49767;
private DimensionalVortex()
{
addStartNpc(DIMENTIONAL_VORTEX);
addTalkId(DIMENTIONAL_VORTEX);
addFirstTalkId(DIMENTIONAL_VORTEX);
}
@Override
public String onAdvEvent(String event, Npc npc, PlayerInstance player)
{
if (event.equals("30952-1.htm") || event.equals("30952-2.htm") || event.equals("30952-3.htm"))
{
return event;
}
if (event.equals("tryenter"))
{
if (getQuestItemsCount(player, CELESTIAL_SHARD) >= 1)
{
if (player.isGM())
{
player.destroyItemByItemId("Rift", CELESTIAL_SHARD, 1, npc, true);
GlobalVariablesManager.getInstance().set("heavenly_rift_complete", 0);
GlobalVariablesManager.getInstance().set("heavenly_rift_level", 0);
player.teleToLocation(112685, 13362, 10966);
ThreadPool.schedule(new HeavenlyRiftManager.ClearZoneTask(npc), 180000);
return null;
}
if (!player.isInParty())
{
player.sendPacket(SystemMessageId.YOU_ARE_NOT_CURRENTLY_IN_A_PARTY_SO_YOU_CANNOT_ENTER);
return null;
}
final Party party = player.getParty();
if ((party == null) || !party.isLeader(player))
{
player.sendPacket(SystemMessageId.ONLY_A_PARTY_LEADER_CAN_MAKE_THE_REQUEST_TO_ENTER);
return null;
}
for (PlayerInstance partyMember : party.getMembers())
{
if (player.calculateDistance2D(partyMember) > Config.ALT_PARTY_RANGE)
{
continue;
}
final SystemMessage sm = new SystemMessage(SystemMessageId.C1_IS_IN_A_LOCATION_WHICH_CANNOT_BE_ENTERED_THEREFORE_IT_CANNOT_BE_PROCESSED);
sm.addPcName(partyMember);
player.sendPacket(sm);
party.broadcastToPartyMembers(player, sm);
return null;
}
player.destroyItemByItemId("Rift", CELESTIAL_SHARD, 1, npc, true);
GlobalVariablesManager.getInstance().set("heavenly_rift_complete", 0);
GlobalVariablesManager.getInstance().set("heavenly_rift_level", 0);
for (PlayerInstance partyMember : party.getMembers())
{
partyMember.teleToLocation(112685, 13362, 10966);
}
ThreadPool.schedule(new HeavenlyRiftManager.ClearZoneTask(npc), 1200000);
}
else
{
return "30952-3.htm";
}
}
else if (event.equals("exchange"))
{
long count = getQuestItemsCount(player, BROKEN_CELESTIAL_SHARD);
if (count < 10)
{
return "30952-2.htm";
}
if ((count % 10) != 0)
{
count -= count % 10;
}
final long reward = count / 10;
player.destroyItemByItemId("Rift", BROKEN_CELESTIAL_SHARD, count, npc, true);
player.addItem("Rift", CELESTIAL_SHARD, reward, npc, true);
}
return null;
}
@Override
public String onFirstTalk(Npc npc, PlayerInstance player)
{
return npc.getId() + ".htm";
}
public static void main(String[] args)
{
new DimensionalVortex();
}
}

View File

@ -0,0 +1,233 @@
/*
* 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 ai.areas.TowerOfInsolence;
import java.util.List;
import java.util.concurrent.ScheduledFuture;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.commons.util.CommonUtil;
import org.l2jmobius.commons.util.Rnd;
import org.l2jmobius.gameserver.data.xml.impl.SpawnData;
import org.l2jmobius.gameserver.enums.ChatType;
import org.l2jmobius.gameserver.model.ChanceLocation;
import org.l2jmobius.gameserver.model.Location;
import org.l2jmobius.gameserver.model.Spawn;
import org.l2jmobius.gameserver.model.actor.Npc;
import org.l2jmobius.gameserver.model.actor.instance.MonsterInstance;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.model.skills.AbnormalVisualEffect;
import org.l2jmobius.gameserver.model.spawns.NpcSpawnTemplate;
import org.l2jmobius.gameserver.network.NpcStringId;
import ai.AbstractNpcAI;
/**
* @author Brutallis
*/
public class EnergyOfInsolence extends AbstractNpcAI
{
private static final int LEVEL_MAX_DIFF = 9;
private static final int TIME_UNTIL_MOVE = 1800000;
private static final int ELMOREDEN_LADY = 20977;
private static final int POWER_ANGEL_AMON = 21081;
private static final int ENERGY_OF_INSOLENCE_DROP_RATE = 70;
private static final int ENERGY_OF_INSOLENCE_ITEM_ID = 49685;
private static final int ENERGY_OF_INSOLENCE_DROP_COUNT = 1;
private static final int UNIDENTIFIED_STONE_DROP_RATE = 4;
private static final int UNIDENTIFIED_STONE_ITEM_ID = 49766;
private static final int[] ENERGY_OF_INSOLENCE_NPC_IDS = new int[]
{
ELMOREDEN_LADY,
POWER_ANGEL_AMON
};
private static final int[] ENERGY_OF_INSOLENCE_MINIONS = new int[]
{
20978,
20979,
21073,
21082,
21083
};
private static final int[] UNIDENTIFIED_STONE_NPC_IDS = new int[]
{
20980,
20981,
20982,
20983,
20984,
20985,
21074,
21075,
21076,
21077,
21080
};
private static ScheduledFuture<?> _scheduleTaskElmoreden;
private static ScheduledFuture<?> _scheduleTaskAmon;
private EnergyOfInsolence()
{
addSpawnId(ENERGY_OF_INSOLENCE_NPC_IDS);
addKillId(ENERGY_OF_INSOLENCE_NPC_IDS);
addKillId(UNIDENTIFIED_STONE_NPC_IDS);
addKillId(ENERGY_OF_INSOLENCE_MINIONS);
}
private void makeInvul(Npc npc)
{
npc.getEffectList().startAbnormalVisualEffect(new AbnormalVisualEffect[]
{
AbnormalVisualEffect.INVINCIBILITY
});
npc.setInvul(true);
}
private void makeMortal(Npc npc)
{
npc.getEffectList().stopAbnormalVisualEffect(new AbnormalVisualEffect[]
{
AbnormalVisualEffect.INVINCIBILITY
});
npc.setInvul(false);
}
private void makeTalk(Npc npc, boolean spawning)
{
NpcStringId npcStringId = null;
switch (npc.getId())
{
case ELMOREDEN_LADY:
{
npcStringId = spawning ? NpcStringId.MY_SERVANTS_CAN_KEEP_ME_SAFE_I_HAVE_NOTHING_TO_FEAR : NpcStringId.CAN_T_DIE_IN_A_PLACE_LIKE_THIS;
break;
}
case POWER_ANGEL_AMON:
{
npcStringId = spawning ? NpcStringId.I_WONDER_WHO_IT_IS_THAT_IS_LURKING_ABOUT : NpcStringId.WHY_WOULD_YOU_BUILD_A_TOWER_IN_OUR_TERRITORY;
}
}
npc.broadcastSay(ChatType.NPC_SHOUT, npcStringId);
}
@Override
public String onSpawn(Npc npc)
{
if (CommonUtil.contains(ENERGY_OF_INSOLENCE_NPC_IDS, npc.getId()))
{
makeTalk(npc, true);
switch (npc.getId())
{
case ELMOREDEN_LADY:
{
makeInvul(npc);
_scheduleTaskElmoreden = ThreadPool.schedule(new ScheduleAITask(npc, ELMOREDEN_LADY), TIME_UNTIL_MOVE);
break;
}
case POWER_ANGEL_AMON:
{
_scheduleTaskAmon = ThreadPool.schedule(new ScheduleAITask(npc, POWER_ANGEL_AMON), TIME_UNTIL_MOVE);
}
}
}
return super.onSpawn(npc);
}
@Override
public String onKill(Npc npc, PlayerInstance killer, boolean isSummon)
{
if (CommonUtil.contains(UNIDENTIFIED_STONE_NPC_IDS, npc.getId()) && ((killer.getLevel() - npc.getLevel()) <= LEVEL_MAX_DIFF) && (Rnd.get(100) <= UNIDENTIFIED_STONE_DROP_RATE))
{
npc.dropItem(killer, UNIDENTIFIED_STONE_ITEM_ID, ENERGY_OF_INSOLENCE_DROP_COUNT);
}
if (CommonUtil.contains(ENERGY_OF_INSOLENCE_NPC_IDS, npc.getId()))
{
makeTalk(npc, false);
switch (npc.getId())
{
case ELMOREDEN_LADY:
{
_scheduleTaskElmoreden.cancel(true);
_scheduleTaskElmoreden = ThreadPool.schedule(new ScheduleAITask(null, ELMOREDEN_LADY), TIME_UNTIL_MOVE);
break;
}
case POWER_ANGEL_AMON:
{
_scheduleTaskAmon.cancel(true);
_scheduleTaskAmon = ThreadPool.schedule(new ScheduleAITask(null, POWER_ANGEL_AMON), TIME_UNTIL_MOVE);
}
}
if (((killer.getLevel() - npc.getLevel()) <= LEVEL_MAX_DIFF) && (Rnd.get(100) <= ENERGY_OF_INSOLENCE_DROP_RATE))
{
npc.dropItem(killer, ENERGY_OF_INSOLENCE_ITEM_ID, ENERGY_OF_INSOLENCE_DROP_COUNT);
}
}
if (CommonUtil.contains(ENERGY_OF_INSOLENCE_MINIONS, npc.getId()))
{
final MonsterInstance leader = ((MonsterInstance) npc).getLeader();
if ((leader != null) && (leader.getMinionList().getSpawnedMinions().size() == 0) && !leader.isDead())
{
makeMortal(leader);
}
}
return super.onKill(npc, killer, isSummon);
}
public static AbstractNpcAI provider()
{
return new EnergyOfInsolence();
}
public class ScheduleAITask implements Runnable
{
private final Npc _npc;
private final int _npcId;
public ScheduleAITask(Npc npc, int npcId)
{
_npc = npc;
_npcId = npcId;
}
@Override
public void run()
{
if (_npc != null)
{
_npc.deleteMe();
}
try
{
final Spawn spawn = new Spawn(_npcId);
final List<NpcSpawnTemplate> spawns = SpawnData.getInstance().getNpcSpawns(npcSpawnTemplate -> npcSpawnTemplate.getId() == _npcId);
final List<ChanceLocation> locations = spawns.get(0).getLocation();
final Location location = locations.get(Rnd.get(locations.size()));
spawn.setLocation(location);
spawn.doSpawn();
}
catch (Exception e)
{
}
}
}
public static void main(String[] args)
{
new EnergyOfInsolence();
}
}

View File

@ -0,0 +1,106 @@
/*
* 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 ai.areas.TowerOfInsolence.HeavenlyRift;
import org.l2jmobius.commons.util.Rnd;
import org.l2jmobius.gameserver.instancemanager.GlobalVariablesManager;
import org.l2jmobius.gameserver.instancemanager.HeavenlyRiftManager;
import org.l2jmobius.gameserver.model.World;
import org.l2jmobius.gameserver.model.WorldObject;
import org.l2jmobius.gameserver.model.actor.Npc;
import org.l2jmobius.gameserver.model.actor.Playable;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.model.events.AbstractScript;
import org.l2jmobius.gameserver.network.serverpackets.ExChangeNpcState;
import ai.AbstractNpcAI;
/**
* @author Brutallis
*/
public class Bomb extends AbstractNpcAI
{
// NPCs
private static final int BOMB = 18003;
private static final int DIVINE_ANGEL = 20139;
// Items
private static final int[] ITEM_DROP_1 = new int[]
{
49756,
49762,
49763
};
private static final int[] ITEM_DROP_2 = new int[]
{
49760,
49761
};
public Bomb()
{
addKillId(BOMB);
addSpawnId(BOMB);
}
@Override
public String onSpawn(Npc npc)
{
npc.broadcastPacket(new ExChangeNpcState(npc.getObjectId(), 1));
return super.onSpawn(npc);
}
@Override
public String onKill(Npc npc, PlayerInstance killer, boolean isSummon)
{
if (Rnd.get(100) < 33)
{
AbstractScript.addSpawn(DIVINE_ANGEL, npc, false, 1800000);
}
else
{
World.getInstance().forEachVisibleObjectInRange((WorldObject) npc, Playable.class, 200, creature ->
{
if ((creature != null) && !creature.isDead())
{
creature.reduceCurrentHp(Rnd.get(300, 400), npc, null);
}
});
if (Rnd.get(100) < 50)
{
if (Rnd.get(100) < 90)
{
npc.dropItem(killer.getActingPlayer(), ITEM_DROP_1[Rnd.get(ITEM_DROP_1.length)], 1);
}
else
{
npc.dropItem(killer.getActingPlayer(), ITEM_DROP_2[Rnd.get(ITEM_DROP_2.length)], 1);
}
}
}
if (HeavenlyRiftManager.getAliveNpcCount(npc.getId()) == 0)
{
GlobalVariablesManager.getInstance().set("heavenly_rift_complete", GlobalVariablesManager.getInstance().getInt("heavenly_rift_level", 0));
GlobalVariablesManager.getInstance().set("heavenly_rift_level", 0);
}
return super.onKill(npc, killer, isSummon);
}
public static void main(String[] args)
{
new Bomb();
}
}

View File

@ -0,0 +1,79 @@
/*
* 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 ai.areas.TowerOfInsolence.HeavenlyRift;
import org.l2jmobius.gameserver.ai.AttackableAI;
import org.l2jmobius.gameserver.enums.ChatType;
import org.l2jmobius.gameserver.instancemanager.GlobalVariablesManager;
import org.l2jmobius.gameserver.instancemanager.HeavenlyRiftManager;
import org.l2jmobius.gameserver.model.actor.Creature;
import org.l2jmobius.gameserver.model.actor.Npc;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.network.NpcStringId;
import ai.AbstractNpcAI;
/**
* @author Brutallis
*/
public class DivineAngel extends AbstractNpcAI
{
// NPCs
private static final int TOWER = 18004;
private static final int DIVINE_ANGEL = 20139;
public DivineAngel()
{
addSpawnId(DIVINE_ANGEL);
addKillId(DIVINE_ANGEL);
}
@Override
public String onKill(Npc npc, PlayerInstance killer, boolean isSummon)
{
if ((GlobalVariablesManager.getInstance().getInt("heavenly_rift_level", 0) > 1) && (HeavenlyRiftManager.getAliveNpcCount(npc.getId()) == 0))
{
GlobalVariablesManager.getInstance().set("heavenly_rift_complete", GlobalVariablesManager.getInstance().getInt("heavenly_rift_level", 0));
GlobalVariablesManager.getInstance().set("heavenly_rift_level", 0);
GlobalVariablesManager.getInstance().set("heavenly_rift_reward", 1);
for (Creature creature : HeavenlyRiftManager.getZone().getCharactersInside())
{
if (creature.isMonster() && (creature.getId() == TOWER) && !creature.isDead())
{
((Npc) creature).broadcastSay(ChatType.NPC_SHOUT, NpcStringId.DIVINE_ANGELS_ARE_NOWHERE_TO_BE_SEEN_I_WANT_TO_TALK_TO_THE_PARTY_LEADER);
}
}
}
return super.onKill(npc, killer, isSummon);
}
@Override
public String onSpawn(Npc npc)
{
if (GlobalVariablesManager.getInstance().getInt("heavenly_rift_level", 0) == 2)
{
((AttackableAI) npc.getAI()).setGlobalAggro(0);
}
return super.onSpawn(npc);
}
public static void main(String[] args)
{
new DivineAngel();
}
}

View File

@ -0,0 +1,64 @@
/*
* 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 ai.areas.TowerOfInsolence.HeavenlyRift;
import org.l2jmobius.gameserver.instancemanager.GlobalVariablesManager;
import org.l2jmobius.gameserver.instancemanager.HeavenlyRiftManager;
import org.l2jmobius.gameserver.model.actor.Creature;
import org.l2jmobius.gameserver.model.actor.Npc;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.network.NpcStringId;
import org.l2jmobius.gameserver.network.serverpackets.ExShowScreenMessage;
import ai.AbstractNpcAI;
/**
* @author Brutallis
*/
public class Tower extends AbstractNpcAI
{
// NPCs
private static final int TOWER = 18004;
private static final int DIVINE_ANGEL = 20139;
public Tower()
{
addKillId(TOWER);
}
@Override
public String onKill(Npc npc, PlayerInstance killer, boolean isSummon)
{
HeavenlyRiftManager.getZone().broadcastPacket(new ExShowScreenMessage(NpcStringId.YOU_HAVE_FAILED, 2, 5000));
for (Creature creature : HeavenlyRiftManager.getZone().getCharactersInside())
{
if (creature.isMonster() && !creature.isDead() && (creature.getId() == DIVINE_ANGEL))
{
creature.decayMe();
}
}
GlobalVariablesManager.getInstance().set("heavenly_rift_complete", GlobalVariablesManager.getInstance().getInt("heavenly_rift_level", 0));
GlobalVariablesManager.getInstance().set("heavenly_rift_level", 0);
GlobalVariablesManager.getInstance().set("heavenly_rift_reward", 0);
return super.onKill(npc, killer, isSummon);
}
public static void main(String[] args)
{
new Tower();
}
}

View File

@ -3,8 +3,6 @@
<spawn name="Aden">
<group>
<npc id="30949" x="110831" y="15973" z="-4368" heading="412" respawnTime="60sec" />
<npc id="30950" x="114112" y="20042" z="944" heading="50148" respawnTime="60sec" />
<npc id="30951" x="118644" y="16680" z="6000" heading="42000" respawnTime="60sec" />
<npc id="31646" x="120112" y="30912" z="-3616" heading="49000" respawnTime="60sec" />
<npc id="30747" x="110395" y="41625" z="-4619" heading="0" respawnTime="60sec" />
<npc id="30764" x="117380" y="75616" z="-2664" heading="26000" respawnTime="60sec" />

View File

@ -1638,6 +1638,7 @@
<npc id="19133" x="115000" y="11309" z="-5120" heading="32767" respawnTime="60sec" /> <!-- Antharas -->
<npc id="19133" x="115000" y="11409" z="-5120" heading="32767" respawnTime="60sec" /> <!-- Antharas -->
<npc id="31714" x="114922" y="11230" z="-5130" heading="336" respawnTime="60sec" /> <!-- Ateld -->
<npc id="30401" x="112634" y="13364" z="2445" heading="8021" /> <!--Arushinai-->
</group>
</spawn>
</list>

View File

@ -185,7 +185,7 @@
<hitTime>520</hitTime>
<abnormalResist physical="10" magical="10" />
</stats>
<status undying="false" />
<status undying="false" attackable="true" canMove="false"/>
<skillList>
<skill id="4273" level="3" /> <!-- Resist Daggers/Rapier Weapon -->
<skill id="4274" level="1" /> <!-- Blunt Weapon Weak Point -->

View File

@ -1745,7 +1745,11 @@
</skillList>
<shots shotChance="30" spiritChance="30" />
<exCrtEffect>false</exCrtEffect>
<ai aggroRange="500" clanHelpRange="300" isAggressive="false" />
<ai aggroRange="2000" clanHelpRange="300" isAggressive="true">
<clanList>
<clan>ALL</clan>
</clanList>
</ai>
<collision>
<radius normal="13.5" />
<height normal="36.5" />

View File

@ -322,6 +322,16 @@
<node X="-253907" Y="221193" />
</zone>
<!-- Heavenly rift zone -->
<zone name="heavenly_rift" type="NoRestartZone" shape="NPoly" minZ="12000" maxZ="10800">
<node X="114169" Y="13781" />
<node X="112353" Y="15581" />
<node X="111219" Y="15072" />
<node X="111584" Y="14238" />
<node X="112815" Y="12991" />
<node X="113640" Y="12642" />
</zone>
<!-- High five zone -->
<zone name="olympiad_no_restart" type="NoRestartZone" shape="Cuboid" minZ="-8485" maxZ="1149">
<stat name="restartTime" val="0" />

View File

@ -0,0 +1,142 @@
/*
* 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 org.l2jmobius.gameserver.instancemanager;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.gameserver.model.Location;
import org.l2jmobius.gameserver.model.Spawn;
import org.l2jmobius.gameserver.model.actor.Creature;
import org.l2jmobius.gameserver.model.actor.Npc;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.model.zone.ZoneType;
import org.l2jmobius.gameserver.network.NpcStringId;
import org.l2jmobius.gameserver.network.serverpackets.ExShowScreenMessage;
/**
* @author Brutallis
*/
public class HeavenlyRiftManager
{
private static final ZoneType ZONE = ZoneManager.getInstance().getZoneByName("heavenly_rift");
public static ZoneType getZone()
{
return ZONE;
}
public static int getAliveNpcCount(int npcId)
{
int result = 0;
for (Creature creature : ZONE.getCharactersInside())
{
if (creature.isMonster() && !creature.isDead() && (creature.getId() == npcId))
{
result++;
}
}
return result;
}
public static void startEvent20Bomb(PlayerInstance player)
{
ZONE.broadcastPacket(new ExShowScreenMessage(NpcStringId.SET_OFF_BOMBS_AND_GET_TREASURES, 2, 5000));
spawnMonster(18003, 113352, 12936, 10976, 1800000);
spawnMonster(18003, 113592, 13272, 10976, 1800000);
spawnMonster(18003, 113816, 13592, 10976, 1800000);
spawnMonster(18003, 113080, 13192, 10976, 1800000);
spawnMonster(18003, 113336, 13528, 10976, 1800000);
spawnMonster(18003, 113560, 13832, 10976, 1800000);
spawnMonster(18003, 112776, 13512, 10976, 1800000);
spawnMonster(18003, 113064, 13784, 10976, 1800000);
spawnMonster(18003, 112440, 13848, 10976, 1800000);
spawnMonster(18003, 112728, 14104, 10976, 1800000);
spawnMonster(18003, 112760, 14600, 10976, 1800000);
spawnMonster(18003, 112392, 14456, 10976, 1800000);
spawnMonster(18003, 112104, 14184, 10976, 1800000);
spawnMonster(18003, 111816, 14488, 10976, 1800000);
spawnMonster(18003, 112104, 14760, 10976, 1800000);
spawnMonster(18003, 112392, 15032, 10976, 1800000);
spawnMonster(18003, 112120, 15288, 10976, 1800000);
spawnMonster(18003, 111784, 15064, 10976, 1800000);
spawnMonster(18003, 111480, 14824, 10976, 1800000);
spawnMonster(18003, 113144, 14216, 10976, 1800000);
}
public static void startEventTower(PlayerInstance player)
{
ZONE.broadcastPacket(new ExShowScreenMessage(NpcStringId.PROTECT_THE_CENTRAL_TOWER_FROM_DIVINE_ANGELS, 2, 5000));
spawnMonster(18004, 112648, 14072, 10976, 1800000);
ThreadPool.schedule(() ->
{
for (int i = 0; i < 20; ++i)
{
spawnMonster(20139, 112696, 13960, 10958, 1800000);
}
}, 10000);
}
public static void startEvent40Angels(PlayerInstance player)
{
ZONE.broadcastPacket(new ExShowScreenMessage(NpcStringId.DESTROY_WEAKENED_DIVINE_ANGELS, 2, 5000));
for (int i = 0; i < 40; ++i)
{
spawnMonster(20139, 112696, 13960, 10958, 1800000);
}
}
private static void spawnMonster(int npcId, int x, int y, int z, long despawnTime)
{
try
{
Spawn spawn = new Spawn(npcId);
Location location = new Location(x, y, z);
spawn.setLocation(location);
Npc npc = spawn.doSpawn();
npc.scheduleDespawn(despawnTime);
}
catch (Exception e)
{
}
}
public static class ClearZoneTask implements Runnable
{
private final Npc _npc;
public ClearZoneTask(Npc npc)
{
_npc = npc;
}
@Override
public void run()
{
for (Creature creature : ZONE.getCharactersInside())
{
if (creature.isPlayer())
{
creature.teleToLocation(114264, 13352, -5104);
}
else if (creature.isNpc() && (creature.getId() != 30401))
{
creature.decayMe();
}
}
_npc.setBusy(false);
}
}
}

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<list applyTaxes="true" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../xsd/multisell.xsd">
<npcs>
<npc>30952</npc> <!-- Dimensional Vortex -->
</npcs>
<item>
<!-- Broken Celestial Shard -->
<ingredient count="1" id="49767" />
<!-- Scroll of Heavenly Protection -->
<production count="1" id="49768" />
</item>
</list>

View File

@ -0,0 +1,12 @@
<html><body>Arushinai:<br>
Baium spent hundreds of years imprisoned. He was forced to watch how slowly his empire died...
Baium's anger was so great that the <font color="LEVEL">Heavenly Rift</font> itself began yo change under his influence.
I'll give you a little clue... So that you can imagine what can happen in the fault.
Or you will be attacked by <font color="LEVEL">40 Divine Angels</font> (kill them as soon as you notice),
or the will be <font color="LEVEL">20 Bombs</font> (their explosions will summon the Divine Angels, who will also have to be killed).
And be careful: from an exploding bomb can drop anything valuable! Either you need <font color="LEVEL">to protect the Tower</font> from 20 Divine Angels who will try to destroy it.
If you do this, you will receive a reward. Be extremely attentive!<br>
Fight shoulder to shoulder with you members. And remember: if you leave the Heavenly Rift before the due time, you can not return here.
Gather with strength - and go!<br>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest Arushinai proceed">Proceed to the task</button>
</body></html>

View File

@ -0,0 +1,4 @@
<html><body>Arushinai:<br>
It's not easy to get into the Heavenly Rift. When are you ready, I will send you <font color="LEVEL">back to Dimensional Vortex</font>.<br>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h npc_%objectId%_finish">Move all party</button>
</body></html>

View File

@ -0,0 +1,6 @@
<html><body>Arushinai:<br>
Do you know how the Heavenly Rift came about? The ego of the emperor Baium split the heaven.
Inside the fault, you can stay <font color="LEVEL">not longer than 30 minutes</font>. In such a dangerous place, mutual assistance and teamwork are especially important.
And remember: if you leave the rift prematurely, you will not be able to return here!<br>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest Arushinai 30401-1.htm">Learn more</button>
</body></html>

View File

@ -0,0 +1,155 @@
/*
* 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 ai.areas.TowerOfInsolence.Arushinai;
import org.l2jmobius.Config;
import org.l2jmobius.commons.util.Rnd;
import org.l2jmobius.gameserver.instancemanager.GlobalVariablesManager;
import org.l2jmobius.gameserver.instancemanager.HeavenlyRiftManager;
import org.l2jmobius.gameserver.model.Party;
import org.l2jmobius.gameserver.model.actor.Npc;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.network.SystemMessageId;
import org.l2jmobius.gameserver.network.serverpackets.SystemMessage;
import ai.AbstractNpcAI;
/**
* @author Brutallis
*/
public class Arushinai extends AbstractNpcAI
{
// NPC
private static final int ARUSHINAI = 30401;
private Arushinai()
{
addStartNpc(ARUSHINAI);
addTalkId(ARUSHINAI);
addFirstTalkId(ARUSHINAI);
}
@Override
public String onFirstTalk(Npc npc, PlayerInstance player)
{
return npc.getId() + ".htm";
}
@Override
public String onAdvEvent(String event, Npc npc, PlayerInstance player)
{
if (event.equals("30401-1.htm") || event.equals("30401-2.htm"))
{
return event;
}
if (event.equals("proceed"))
{
if (!player.isGM())
{
Party party = player.getParty();
if (party == null)
{
player.sendPacket(SystemMessageId.YOU_ARE_NOT_CURRENTLY_IN_A_PARTY_SO_YOU_CANNOT_ENTER);
player.teleToLocation(114264, 13352, -5104);
return null;
}
if (!party.isLeader(player))
{
player.sendPacket(SystemMessageId.ONLY_A_PARTY_LEADER_CAN_MAKE_THE_REQUEST_TO_ENTER);
return null;
}
}
if (GlobalVariablesManager.getInstance().getInt("heavenly_rift_complete", 0) != 0)
{
return null; // TODO: Find html?
}
final int riftLevel = Rnd.get(1, 3);
GlobalVariablesManager.getInstance().set("heavenly_rift_level", riftLevel);
GlobalVariablesManager.getInstance().set("heavenly_rift_complete", 4);
switch (riftLevel)
{
case 1:
{
HeavenlyRiftManager.startEvent20Bomb(player);
return null;
}
case 2:
{
HeavenlyRiftManager.startEventTower(player);
return null;
}
case 3:
{
HeavenlyRiftManager.startEvent40Angels(player);
break;
}
}
return null;
}
if (!event.equals("finish"))
{
return null;
}
if (player.isInParty())
{
Party party = player.getParty();
if (!party.isLeader(player))
{
player.sendPacket(SystemMessageId.YOU_CANNOT_PROCEED_AS_YOU_ARE_NOT_A_PARTY_LEADER);
return null;
}
for (PlayerInstance partyMember : party.getMembers())
{
if (player.calculateDistance2D(partyMember) > Config.ALT_PARTY_RANGE)
{
continue;
}
final SystemMessage sm = new SystemMessage(SystemMessageId.C1_IS_IN_A_LOCATION_WHICH_CANNOT_BE_ENTERED_THEREFORE_IT_CANNOT_BE_PROCESSED);
sm.addPcName(partyMember);
player.sendPacket(sm);
party.broadcastToPartyMembers(player, sm);
return null;
}
GlobalVariablesManager.getInstance().set("heavenly_rift_reward", 0);
for (PlayerInstance partyMember : party.getMembers())
{
partyMember.teleToLocation(114264, 13352, -5104);
}
return null;
}
if (player.isGM())
{
GlobalVariablesManager.getInstance().set("heavenly_rift_complete", 0);
player.teleToLocation(114264, 13352, -5104);
return null;
}
player.sendPacket(SystemMessageId.YOU_ARE_NOT_IN_A_PARTY);
return null;
}
public static void main(String[] args)
{
new Arushinai();
}
}

View File

@ -0,0 +1,6 @@
<html><head><body>
Dimensional Vortex:<br>
The energy of Emperor Baium's Rage caused by his imprisoning cracked the skies forming a rift. This rift leads to a new dimension. In order to get there, you will need a <font color=LEVEL>Celestial Shard</font>. You can extract it from the <font color=LEVEL>Unidentified Stone</font> after you kill all the monsters at the 6th floor or at higher floors of the Tower of Insolence.
<br>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest DimensionalVortex tryenter">Use Celestial Shard</Button>
</body></html>

View File

@ -0,0 +1,5 @@
<html><body>Dimensional Vortex:<br>
Eliminate all the monsters at the 6th floor or higher floors of the Tower of Insolence and use the <font color="LEVEL">Unidentified Stone</font> to extract <font color="LEVEL">Broken Celestial Shards</font> from it. You can exchange them for a special scroll, which might be useful during your hunt in the Tower of Insolence.<br>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h npc_%objectId%_Multisell 30952">Exchange Broken Celestial Shard</Button>
<Button ALIGN=LEFT ICON="RETURN" action="bypass -h Quest DimensionalVortex 30952.htm">Home</Button>
</body></html>

View File

@ -0,0 +1,4 @@
<html><body>Dimensional Vortex:<br>
You need an <font color="LEVEL">Airborne Fragment</font> from defeating the monsters on the sixth floor of the Tower of Insolence to enter the Airborne Rift.<br>
<Button ALIGN=LEFT ICON="RETURN" action="bypass -h Quest DimensionalVortex 30952.htm">Back</button>
</body></html>

View File

@ -0,0 +1,6 @@
<html><body>Dimensional Vortex:<br>
Baium was the emperor of Elmoreden, but angered the Gods and was put into solitude for years. He resented Einhasad for cursing him. A small rift appeared in the skies because of the ominous energy surrounding Baium.
<br>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest DimensionalVortex 30952-1.htm">Tell me about the Heavenly Rift.</button>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest DimensionalVortex 30952-2.htm">I want to exchange Broken Celestial Shards.</button>
</body></html>

View File

@ -0,0 +1,135 @@
/*
* 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 ai.areas.TowerOfInsolence.DimensionalVortex;
import org.l2jmobius.Config;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.gameserver.instancemanager.GlobalVariablesManager;
import org.l2jmobius.gameserver.instancemanager.HeavenlyRiftManager;
import org.l2jmobius.gameserver.model.Party;
import org.l2jmobius.gameserver.model.actor.Npc;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.network.SystemMessageId;
import org.l2jmobius.gameserver.network.serverpackets.SystemMessage;
import ai.AbstractNpcAI;
/**
* @author Brutallis
*/
public class DimensionalVortex extends AbstractNpcAI
{
// NPC
private static final int DIMENTIONAL_VORTEX = 30952;
// Items
private static final int CELESTIAL_SHARD = 49759;
private static final int BROKEN_CELESTIAL_SHARD = 49767;
private DimensionalVortex()
{
addStartNpc(DIMENTIONAL_VORTEX);
addTalkId(DIMENTIONAL_VORTEX);
addFirstTalkId(DIMENTIONAL_VORTEX);
}
@Override
public String onAdvEvent(String event, Npc npc, PlayerInstance player)
{
if (event.equals("30952-1.htm") || event.equals("30952-2.htm") || event.equals("30952-3.htm"))
{
return event;
}
if (event.equals("tryenter"))
{
if (getQuestItemsCount(player, CELESTIAL_SHARD) >= 1)
{
if (player.isGM())
{
player.destroyItemByItemId("Rift", CELESTIAL_SHARD, 1, npc, true);
GlobalVariablesManager.getInstance().set("heavenly_rift_complete", 0);
GlobalVariablesManager.getInstance().set("heavenly_rift_level", 0);
player.teleToLocation(112685, 13362, 10966);
ThreadPool.schedule(new HeavenlyRiftManager.ClearZoneTask(npc), 180000);
return null;
}
if (!player.isInParty())
{
player.sendPacket(SystemMessageId.YOU_ARE_NOT_CURRENTLY_IN_A_PARTY_SO_YOU_CANNOT_ENTER);
return null;
}
final Party party = player.getParty();
if ((party == null) || !party.isLeader(player))
{
player.sendPacket(SystemMessageId.ONLY_A_PARTY_LEADER_CAN_MAKE_THE_REQUEST_TO_ENTER);
return null;
}
for (PlayerInstance partyMember : party.getMembers())
{
if (player.calculateDistance2D(partyMember) > Config.ALT_PARTY_RANGE)
{
continue;
}
final SystemMessage sm = new SystemMessage(SystemMessageId.C1_IS_IN_A_LOCATION_WHICH_CANNOT_BE_ENTERED_THEREFORE_IT_CANNOT_BE_PROCESSED);
sm.addPcName(partyMember);
player.sendPacket(sm);
party.broadcastToPartyMembers(player, sm);
return null;
}
player.destroyItemByItemId("Rift", CELESTIAL_SHARD, 1, npc, true);
GlobalVariablesManager.getInstance().set("heavenly_rift_complete", 0);
GlobalVariablesManager.getInstance().set("heavenly_rift_level", 0);
for (PlayerInstance partyMember : party.getMembers())
{
partyMember.teleToLocation(112685, 13362, 10966);
}
ThreadPool.schedule(new HeavenlyRiftManager.ClearZoneTask(npc), 1200000);
}
else
{
return "30952-3.htm";
}
}
else if (event.equals("exchange"))
{
long count = getQuestItemsCount(player, BROKEN_CELESTIAL_SHARD);
if (count < 10)
{
return "30952-2.htm";
}
if ((count % 10) != 0)
{
count -= count % 10;
}
final long reward = count / 10;
player.destroyItemByItemId("Rift", BROKEN_CELESTIAL_SHARD, count, npc, true);
player.addItem("Rift", CELESTIAL_SHARD, reward, npc, true);
}
return null;
}
@Override
public String onFirstTalk(Npc npc, PlayerInstance player)
{
return npc.getId() + ".htm";
}
public static void main(String[] args)
{
new DimensionalVortex();
}
}

View File

@ -0,0 +1,233 @@
/*
* 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 ai.areas.TowerOfInsolence;
import java.util.List;
import java.util.concurrent.ScheduledFuture;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.commons.util.CommonUtil;
import org.l2jmobius.commons.util.Rnd;
import org.l2jmobius.gameserver.data.xml.impl.SpawnData;
import org.l2jmobius.gameserver.enums.ChatType;
import org.l2jmobius.gameserver.model.ChanceLocation;
import org.l2jmobius.gameserver.model.Location;
import org.l2jmobius.gameserver.model.Spawn;
import org.l2jmobius.gameserver.model.actor.Npc;
import org.l2jmobius.gameserver.model.actor.instance.MonsterInstance;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.model.skills.AbnormalVisualEffect;
import org.l2jmobius.gameserver.model.spawns.NpcSpawnTemplate;
import org.l2jmobius.gameserver.network.NpcStringId;
import ai.AbstractNpcAI;
/**
* @author Brutallis
*/
public class EnergyOfInsolence extends AbstractNpcAI
{
private static final int LEVEL_MAX_DIFF = 9;
private static final int TIME_UNTIL_MOVE = 1800000;
private static final int ELMOREDEN_LADY = 20977;
private static final int POWER_ANGEL_AMON = 21081;
private static final int ENERGY_OF_INSOLENCE_DROP_RATE = 70;
private static final int ENERGY_OF_INSOLENCE_ITEM_ID = 49685;
private static final int ENERGY_OF_INSOLENCE_DROP_COUNT = 1;
private static final int UNIDENTIFIED_STONE_DROP_RATE = 4;
private static final int UNIDENTIFIED_STONE_ITEM_ID = 49766;
private static final int[] ENERGY_OF_INSOLENCE_NPC_IDS = new int[]
{
ELMOREDEN_LADY,
POWER_ANGEL_AMON
};
private static final int[] ENERGY_OF_INSOLENCE_MINIONS = new int[]
{
20978,
20979,
21073,
21082,
21083
};
private static final int[] UNIDENTIFIED_STONE_NPC_IDS = new int[]
{
20980,
20981,
20982,
20983,
20984,
20985,
21074,
21075,
21076,
21077,
21080
};
private static ScheduledFuture<?> _scheduleTaskElmoreden;
private static ScheduledFuture<?> _scheduleTaskAmon;
private EnergyOfInsolence()
{
addSpawnId(ENERGY_OF_INSOLENCE_NPC_IDS);
addKillId(ENERGY_OF_INSOLENCE_NPC_IDS);
addKillId(UNIDENTIFIED_STONE_NPC_IDS);
addKillId(ENERGY_OF_INSOLENCE_MINIONS);
}
private void makeInvul(Npc npc)
{
npc.getEffectList().startAbnormalVisualEffect(new AbnormalVisualEffect[]
{
AbnormalVisualEffect.INVINCIBILITY
});
npc.setInvul(true);
}
private void makeMortal(Npc npc)
{
npc.getEffectList().stopAbnormalVisualEffect(new AbnormalVisualEffect[]
{
AbnormalVisualEffect.INVINCIBILITY
});
npc.setInvul(false);
}
private void makeTalk(Npc npc, boolean spawning)
{
NpcStringId npcStringId = null;
switch (npc.getId())
{
case ELMOREDEN_LADY:
{
npcStringId = spawning ? NpcStringId.MY_SERVANTS_CAN_KEEP_ME_SAFE_I_HAVE_NOTHING_TO_FEAR : NpcStringId.CAN_T_DIE_IN_A_PLACE_LIKE_THIS;
break;
}
case POWER_ANGEL_AMON:
{
npcStringId = spawning ? NpcStringId.I_WONDER_WHO_IT_IS_THAT_IS_LURKING_ABOUT : NpcStringId.WHY_WOULD_YOU_BUILD_A_TOWER_IN_OUR_TERRITORY;
}
}
npc.broadcastSay(ChatType.NPC_SHOUT, npcStringId);
}
@Override
public String onSpawn(Npc npc)
{
if (CommonUtil.contains(ENERGY_OF_INSOLENCE_NPC_IDS, npc.getId()))
{
makeTalk(npc, true);
switch (npc.getId())
{
case ELMOREDEN_LADY:
{
makeInvul(npc);
_scheduleTaskElmoreden = ThreadPool.schedule(new ScheduleAITask(npc, ELMOREDEN_LADY), TIME_UNTIL_MOVE);
break;
}
case POWER_ANGEL_AMON:
{
_scheduleTaskAmon = ThreadPool.schedule(new ScheduleAITask(npc, POWER_ANGEL_AMON), TIME_UNTIL_MOVE);
}
}
}
return super.onSpawn(npc);
}
@Override
public String onKill(Npc npc, PlayerInstance killer, boolean isSummon)
{
if (CommonUtil.contains(UNIDENTIFIED_STONE_NPC_IDS, npc.getId()) && ((killer.getLevel() - npc.getLevel()) <= LEVEL_MAX_DIFF) && (Rnd.get(100) <= UNIDENTIFIED_STONE_DROP_RATE))
{
npc.dropItem(killer, UNIDENTIFIED_STONE_ITEM_ID, ENERGY_OF_INSOLENCE_DROP_COUNT);
}
if (CommonUtil.contains(ENERGY_OF_INSOLENCE_NPC_IDS, npc.getId()))
{
makeTalk(npc, false);
switch (npc.getId())
{
case ELMOREDEN_LADY:
{
_scheduleTaskElmoreden.cancel(true);
_scheduleTaskElmoreden = ThreadPool.schedule(new ScheduleAITask(null, ELMOREDEN_LADY), TIME_UNTIL_MOVE);
break;
}
case POWER_ANGEL_AMON:
{
_scheduleTaskAmon.cancel(true);
_scheduleTaskAmon = ThreadPool.schedule(new ScheduleAITask(null, POWER_ANGEL_AMON), TIME_UNTIL_MOVE);
}
}
if (((killer.getLevel() - npc.getLevel()) <= LEVEL_MAX_DIFF) && (Rnd.get(100) <= ENERGY_OF_INSOLENCE_DROP_RATE))
{
npc.dropItem(killer, ENERGY_OF_INSOLENCE_ITEM_ID, ENERGY_OF_INSOLENCE_DROP_COUNT);
}
}
if (CommonUtil.contains(ENERGY_OF_INSOLENCE_MINIONS, npc.getId()))
{
final MonsterInstance leader = ((MonsterInstance) npc).getLeader();
if ((leader != null) && (leader.getMinionList().getSpawnedMinions().size() == 0) && !leader.isDead())
{
makeMortal(leader);
}
}
return super.onKill(npc, killer, isSummon);
}
public static AbstractNpcAI provider()
{
return new EnergyOfInsolence();
}
public class ScheduleAITask implements Runnable
{
private final Npc _npc;
private final int _npcId;
public ScheduleAITask(Npc npc, int npcId)
{
_npc = npc;
_npcId = npcId;
}
@Override
public void run()
{
if (_npc != null)
{
_npc.deleteMe();
}
try
{
final Spawn spawn = new Spawn(_npcId);
final List<NpcSpawnTemplate> spawns = SpawnData.getInstance().getNpcSpawns(npcSpawnTemplate -> npcSpawnTemplate.getId() == _npcId);
final List<ChanceLocation> locations = spawns.get(0).getLocation();
final Location location = locations.get(Rnd.get(locations.size()));
spawn.setLocation(location);
spawn.doSpawn();
}
catch (Exception e)
{
}
}
}
public static void main(String[] args)
{
new EnergyOfInsolence();
}
}

View File

@ -0,0 +1,106 @@
/*
* 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 ai.areas.TowerOfInsolence.HeavenlyRift;
import org.l2jmobius.commons.util.Rnd;
import org.l2jmobius.gameserver.instancemanager.GlobalVariablesManager;
import org.l2jmobius.gameserver.instancemanager.HeavenlyRiftManager;
import org.l2jmobius.gameserver.model.World;
import org.l2jmobius.gameserver.model.WorldObject;
import org.l2jmobius.gameserver.model.actor.Npc;
import org.l2jmobius.gameserver.model.actor.Playable;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.model.events.AbstractScript;
import org.l2jmobius.gameserver.network.serverpackets.ExChangeNpcState;
import ai.AbstractNpcAI;
/**
* @author Brutallis
*/
public class Bomb extends AbstractNpcAI
{
// NPCs
private static final int BOMB = 18003;
private static final int DIVINE_ANGEL = 20139;
// Items
private static final int[] ITEM_DROP_1 = new int[]
{
49756,
49762,
49763
};
private static final int[] ITEM_DROP_2 = new int[]
{
49760,
49761
};
public Bomb()
{
addKillId(BOMB);
addSpawnId(BOMB);
}
@Override
public String onSpawn(Npc npc)
{
npc.broadcastPacket(new ExChangeNpcState(npc.getObjectId(), 1));
return super.onSpawn(npc);
}
@Override
public String onKill(Npc npc, PlayerInstance killer, boolean isSummon)
{
if (Rnd.get(100) < 33)
{
AbstractScript.addSpawn(DIVINE_ANGEL, npc, false, 1800000);
}
else
{
World.getInstance().forEachVisibleObjectInRange((WorldObject) npc, Playable.class, 200, creature ->
{
if ((creature != null) && !creature.isDead())
{
creature.reduceCurrentHp(Rnd.get(300, 400), npc, null);
}
});
if (Rnd.get(100) < 50)
{
if (Rnd.get(100) < 90)
{
npc.dropItem(killer.getActingPlayer(), ITEM_DROP_1[Rnd.get(ITEM_DROP_1.length)], 1);
}
else
{
npc.dropItem(killer.getActingPlayer(), ITEM_DROP_2[Rnd.get(ITEM_DROP_2.length)], 1);
}
}
}
if (HeavenlyRiftManager.getAliveNpcCount(npc.getId()) == 0)
{
GlobalVariablesManager.getInstance().set("heavenly_rift_complete", GlobalVariablesManager.getInstance().getInt("heavenly_rift_level", 0));
GlobalVariablesManager.getInstance().set("heavenly_rift_level", 0);
}
return super.onKill(npc, killer, isSummon);
}
public static void main(String[] args)
{
new Bomb();
}
}

View File

@ -0,0 +1,79 @@
/*
* 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 ai.areas.TowerOfInsolence.HeavenlyRift;
import org.l2jmobius.gameserver.ai.AttackableAI;
import org.l2jmobius.gameserver.enums.ChatType;
import org.l2jmobius.gameserver.instancemanager.GlobalVariablesManager;
import org.l2jmobius.gameserver.instancemanager.HeavenlyRiftManager;
import org.l2jmobius.gameserver.model.actor.Creature;
import org.l2jmobius.gameserver.model.actor.Npc;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.network.NpcStringId;
import ai.AbstractNpcAI;
/**
* @author Brutallis
*/
public class DivineAngel extends AbstractNpcAI
{
// NPCs
private static final int TOWER = 18004;
private static final int DIVINE_ANGEL = 20139;
public DivineAngel()
{
addSpawnId(DIVINE_ANGEL);
addKillId(DIVINE_ANGEL);
}
@Override
public String onKill(Npc npc, PlayerInstance killer, boolean isSummon)
{
if ((GlobalVariablesManager.getInstance().getInt("heavenly_rift_level", 0) > 1) && (HeavenlyRiftManager.getAliveNpcCount(npc.getId()) == 0))
{
GlobalVariablesManager.getInstance().set("heavenly_rift_complete", GlobalVariablesManager.getInstance().getInt("heavenly_rift_level", 0));
GlobalVariablesManager.getInstance().set("heavenly_rift_level", 0);
GlobalVariablesManager.getInstance().set("heavenly_rift_reward", 1);
for (Creature creature : HeavenlyRiftManager.getZone().getCharactersInside())
{
if (creature.isMonster() && (creature.getId() == TOWER) && !creature.isDead())
{
((Npc) creature).broadcastSay(ChatType.NPC_SHOUT, NpcStringId.DIVINE_ANGELS_ARE_NOWHERE_TO_BE_SEEN_I_WANT_TO_TALK_TO_THE_PARTY_LEADER);
}
}
}
return super.onKill(npc, killer, isSummon);
}
@Override
public String onSpawn(Npc npc)
{
if (GlobalVariablesManager.getInstance().getInt("heavenly_rift_level", 0) == 2)
{
((AttackableAI) npc.getAI()).setGlobalAggro(0);
}
return super.onSpawn(npc);
}
public static void main(String[] args)
{
new DivineAngel();
}
}

View File

@ -0,0 +1,64 @@
/*
* 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 ai.areas.TowerOfInsolence.HeavenlyRift;
import org.l2jmobius.gameserver.instancemanager.GlobalVariablesManager;
import org.l2jmobius.gameserver.instancemanager.HeavenlyRiftManager;
import org.l2jmobius.gameserver.model.actor.Creature;
import org.l2jmobius.gameserver.model.actor.Npc;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.network.NpcStringId;
import org.l2jmobius.gameserver.network.serverpackets.ExShowScreenMessage;
import ai.AbstractNpcAI;
/**
* @author Brutallis
*/
public class Tower extends AbstractNpcAI
{
// NPCs
private static final int TOWER = 18004;
private static final int DIVINE_ANGEL = 20139;
public Tower()
{
addKillId(TOWER);
}
@Override
public String onKill(Npc npc, PlayerInstance killer, boolean isSummon)
{
HeavenlyRiftManager.getZone().broadcastPacket(new ExShowScreenMessage(NpcStringId.YOU_HAVE_FAILED, 2, 5000));
for (Creature creature : HeavenlyRiftManager.getZone().getCharactersInside())
{
if (creature.isMonster() && !creature.isDead() && (creature.getId() == DIVINE_ANGEL))
{
creature.decayMe();
}
}
GlobalVariablesManager.getInstance().set("heavenly_rift_complete", GlobalVariablesManager.getInstance().getInt("heavenly_rift_level", 0));
GlobalVariablesManager.getInstance().set("heavenly_rift_level", 0);
GlobalVariablesManager.getInstance().set("heavenly_rift_reward", 0);
return super.onKill(npc, killer, isSummon);
}
public static void main(String[] args)
{
new Tower();
}
}

View File

@ -3,8 +3,6 @@
<spawn name="Aden">
<group>
<npc id="30949" x="110831" y="15973" z="-4368" heading="412" respawnTime="60sec" />
<npc id="30950" x="114112" y="20042" z="944" heading="50148" respawnTime="60sec" />
<npc id="30951" x="118644" y="16680" z="6000" heading="42000" respawnTime="60sec" />
<npc id="31646" x="120112" y="30912" z="-3616" heading="49000" respawnTime="60sec" />
<npc id="30747" x="110395" y="41625" z="-4619" heading="0" respawnTime="60sec" />
<npc id="30764" x="117380" y="75616" z="-2664" heading="26000" respawnTime="60sec" />

View File

@ -1638,6 +1638,7 @@
<npc id="19133" x="115000" y="11309" z="-5120" heading="32767" respawnTime="60sec" /> <!-- Antharas -->
<npc id="19133" x="115000" y="11409" z="-5120" heading="32767" respawnTime="60sec" /> <!-- Antharas -->
<npc id="31714" x="114922" y="11230" z="-5130" heading="336" respawnTime="60sec" /> <!-- Ateld -->
<npc id="30401" x="112634" y="13364" z="2445" heading="8021" /> <!--Arushinai-->
</group>
</spawn>
</list>

View File

@ -185,7 +185,7 @@
<hitTime>520</hitTime>
<abnormalResist physical="10" magical="10" />
</stats>
<status undying="false" />
<status undying="false" attackable="true" canMove="false"/>
<skillList>
<skill id="4273" level="3" /> <!-- Resist Daggers/Rapier Weapon -->
<skill id="4274" level="1" /> <!-- Blunt Weapon Weak Point -->

View File

@ -1745,7 +1745,11 @@
</skillList>
<shots shotChance="30" spiritChance="30" />
<exCrtEffect>false</exCrtEffect>
<ai aggroRange="500" clanHelpRange="300" isAggressive="false" />
<ai aggroRange="2000" clanHelpRange="300" isAggressive="true">
<clanList>
<clan>ALL</clan>
</clanList>
</ai>
<collision>
<radius normal="13.5" />
<height normal="36.5" />

View File

@ -322,6 +322,16 @@
<node X="-253907" Y="221193" />
</zone>
<!-- Heavenly rift zone -->
<zone name="heavenly_rift" type="NoRestartZone" shape="NPoly" minZ="12000" maxZ="10800">
<node X="114169" Y="13781" />
<node X="112353" Y="15581" />
<node X="111219" Y="15072" />
<node X="111584" Y="14238" />
<node X="112815" Y="12991" />
<node X="113640" Y="12642" />
</zone>
<!-- High five zone -->
<zone name="olympiad_no_restart" type="NoRestartZone" shape="Cuboid" minZ="-8485" maxZ="1149">
<stat name="restartTime" val="0" />

View File

@ -0,0 +1,142 @@
/*
* 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 org.l2jmobius.gameserver.instancemanager;
import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.gameserver.model.Location;
import org.l2jmobius.gameserver.model.Spawn;
import org.l2jmobius.gameserver.model.actor.Creature;
import org.l2jmobius.gameserver.model.actor.Npc;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.model.zone.ZoneType;
import org.l2jmobius.gameserver.network.NpcStringId;
import org.l2jmobius.gameserver.network.serverpackets.ExShowScreenMessage;
/**
* @author Brutallis
*/
public class HeavenlyRiftManager
{
private static final ZoneType ZONE = ZoneManager.getInstance().getZoneByName("heavenly_rift");
public static ZoneType getZone()
{
return ZONE;
}
public static int getAliveNpcCount(int npcId)
{
int result = 0;
for (Creature creature : ZONE.getCharactersInside())
{
if (creature.isMonster() && !creature.isDead() && (creature.getId() == npcId))
{
result++;
}
}
return result;
}
public static void startEvent20Bomb(PlayerInstance player)
{
ZONE.broadcastPacket(new ExShowScreenMessage(NpcStringId.SET_OFF_BOMBS_AND_GET_TREASURES, 2, 5000));
spawnMonster(18003, 113352, 12936, 10976, 1800000);
spawnMonster(18003, 113592, 13272, 10976, 1800000);
spawnMonster(18003, 113816, 13592, 10976, 1800000);
spawnMonster(18003, 113080, 13192, 10976, 1800000);
spawnMonster(18003, 113336, 13528, 10976, 1800000);
spawnMonster(18003, 113560, 13832, 10976, 1800000);
spawnMonster(18003, 112776, 13512, 10976, 1800000);
spawnMonster(18003, 113064, 13784, 10976, 1800000);
spawnMonster(18003, 112440, 13848, 10976, 1800000);
spawnMonster(18003, 112728, 14104, 10976, 1800000);
spawnMonster(18003, 112760, 14600, 10976, 1800000);
spawnMonster(18003, 112392, 14456, 10976, 1800000);
spawnMonster(18003, 112104, 14184, 10976, 1800000);
spawnMonster(18003, 111816, 14488, 10976, 1800000);
spawnMonster(18003, 112104, 14760, 10976, 1800000);
spawnMonster(18003, 112392, 15032, 10976, 1800000);
spawnMonster(18003, 112120, 15288, 10976, 1800000);
spawnMonster(18003, 111784, 15064, 10976, 1800000);
spawnMonster(18003, 111480, 14824, 10976, 1800000);
spawnMonster(18003, 113144, 14216, 10976, 1800000);
}
public static void startEventTower(PlayerInstance player)
{
ZONE.broadcastPacket(new ExShowScreenMessage(NpcStringId.PROTECT_THE_CENTRAL_TOWER_FROM_DIVINE_ANGELS, 2, 5000));
spawnMonster(18004, 112648, 14072, 10976, 1800000);
ThreadPool.schedule(() ->
{
for (int i = 0; i < 20; ++i)
{
spawnMonster(20139, 112696, 13960, 10958, 1800000);
}
}, 10000);
}
public static void startEvent40Angels(PlayerInstance player)
{
ZONE.broadcastPacket(new ExShowScreenMessage(NpcStringId.DESTROY_WEAKENED_DIVINE_ANGELS, 2, 5000));
for (int i = 0; i < 40; ++i)
{
spawnMonster(20139, 112696, 13960, 10958, 1800000);
}
}
private static void spawnMonster(int npcId, int x, int y, int z, long despawnTime)
{
try
{
Spawn spawn = new Spawn(npcId);
Location location = new Location(x, y, z);
spawn.setLocation(location);
Npc npc = spawn.doSpawn();
npc.scheduleDespawn(despawnTime);
}
catch (Exception e)
{
}
}
public static class ClearZoneTask implements Runnable
{
private final Npc _npc;
public ClearZoneTask(Npc npc)
{
_npc = npc;
}
@Override
public void run()
{
for (Creature creature : ZONE.getCharactersInside())
{
if (creature.isPlayer())
{
creature.teleToLocation(114264, 13352, -5104);
}
else if (creature.isNpc() && (creature.getId() != 30401))
{
creature.decayMe();
}
}
_npc.setBusy(false);
}
}
}

Some files were not shown because too many files have changed in this diff Show More