Merged with released L2J-Unity files.

This commit is contained in:
mobiusdev
2016-06-12 01:34:09 +00:00
parent e003e87887
commit 635557f5da
18352 changed files with 3245113 additions and 2892959 deletions

View File

@@ -0,0 +1,6 @@
<html><body>Apprentice:<br>
Have you seen the Dwarven Workshop here?<br>
They're working on some kind of new product, and they're offering people a sneak peek at it.<br>
It's not complete, or anything, so don't judge too harshly, but do you want to give it a go?<br>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest Apprentice rideKukuru">"Why not?"</Button>
</body></html>

View File

@@ -0,0 +1,97 @@
/*
* 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.TalkingIsland.Apprentice;
import com.l2jmobius.gameserver.enums.ChatType;
import com.l2jmobius.gameserver.instancemanager.QuestManager;
import com.l2jmobius.gameserver.model.StatsSet;
import com.l2jmobius.gameserver.model.actor.L2Npc;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.model.holders.SkillHolder;
import com.l2jmobius.gameserver.model.quest.Quest;
import com.l2jmobius.gameserver.model.quest.QuestState;
import com.l2jmobius.gameserver.network.NpcStringId;
import ai.AbstractNpcAI;
import quests.Q10329_BackupSeekers.Q10329_BackupSeekers;
/**
* Apprentice AI.
* @author St3eT
*/
public final class Apprentice extends AbstractNpcAI
{
// NPCs
private static final int APPRENTICE = 33124;
// Skill
private static final SkillHolder KUKURU = new SkillHolder(9204, 1); // Kukuru
private Apprentice()
{
addSpawnId(APPRENTICE);
addStartNpc(APPRENTICE);
addTalkId(APPRENTICE);
addFirstTalkId(APPRENTICE);
}
@Override
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
{
if (event.equals("rideKukuru"))
{
if (!player.isTransformed())
{
KUKURU.getSkill().applyEffects(npc, player);
final QuestState st = player.getQuestState(Q10329_BackupSeekers.class.getSimpleName());
if ((st != null) && st.isStarted())
{
final Quest quest_10329 = QuestManager.getInstance().getQuest(Q10329_BackupSeekers.class.getSimpleName());
if (quest_10329 != null)
{
quest_10329.notifyEvent("RESPAWN_BART", null, player);
}
}
}
else
{
npc.broadcastSay(ChatType.NPC_GENERAL, NpcStringId.YOU_CAN_T_RIDE_A_KUKURI_NOW);
}
}
return super.onAdvEvent(event, npc, player);
}
@Override
public void onTimerEvent(String event, StatsSet params, L2Npc npc, L2PcInstance player)
{
if (event.equals("SPAM_TEXT") && (npc != null))
{
npc.broadcastSay(ChatType.NPC_GENERAL, NpcStringId.TRY_RIDING_A_KUKURI, 1000);
}
}
@Override
public String onSpawn(L2Npc npc)
{
getTimers().addRepeatingTimer("SPAM_TEXT", 12000, npc, null);
return super.onSpawn(npc);
}
public static void main(String[] args)
{
new Apprentice();
}
}

View File

@@ -0,0 +1,3 @@
<html><body>Master Defender:<br>
The <font color="LEVEL">Sigel Knight's</font> <font color="978d83">power is growing</font>.
</body></html>

View File

@@ -0,0 +1,33 @@
<html>
<body scroll="no">
<!-- Edge Decoration Table -->
<table border="0" cellpadding="0" cellspacing="0" width="292" height="358" background="L2UI_CH3.refinewnd_back_Pattern">
<tr>
<td>
<!-- Class Mark Table -->
<table border="0" cellpadding="0" cellspacing="0" width="292"
background="L2UI_CT1.HtmlWnd_DF_TextureKnight">
<tr>
<td align="center">
<!-- Text Table -->
<table border="0" cellpadding="0" cellspacing="0" width="272" height="338">
<tr>
<td height="90"></td>
</tr>
<tr>
<td align="center">It is not possible for you to Awaken as a Sigel Knight.<br>
<font color="af9878">(Only characters level 85 or above who have completed their 3rd
class transfer and possess the Scroll of Afterlife may Awaken.) </font></td>
</tr>
</table>
<!-- //Text Table -->
</td>
</tr>
</table>
<!-- //Class Mark Table -->
</td>
</tr>
</table>
<!-- //Edge Decoration -->
</body>
</html>

View File

@@ -0,0 +1,34 @@
<html>
<body scroll="no">
<!-- Edge Decoration Table -->
<table border="0" cellpadding="0" cellspacing="0" width="292" height="358" background="L2UI_CH3.refinewnd_back_Pattern">
<tr>
<td>
<!-- Class Mark Table -->
<table border="0" cellpadding="0" cellspacing="0" width="292"
background="L2UI_CT1.HtmlWnd_DF_TextureKnight">
<tr>
<td align="center">
<!-- Text Table -->
<table border="0" cellpadding="0" cellspacing="0" width="272" height="338">
<tr>
<td height="150"></td>
</tr>
<tr>
<td align="center">You are not walking the Knight's path. You must seek the mark that is
appropriate for you.<br> <font color="af9878">(Only Knight Class characters may
Awaken <font color="LEVEL">as Sigel Knights</font>.)</font></td>
</tr>
</table>
<!-- //Text Table -->
</td>
</tr>
</table>
<!-- //Class Mark Table -->
</td>
</tr>
</table>
<!-- //Edge Decoration -->
</body>
</html>

View File

@@ -0,0 +1,19 @@
<html><body scroll="no">
<!-- Edge Decoration Table -->
<table border="0" cellpadding="0" cellspacing="0" width="292" height="358" background="L2UI_CH3.refinewnd_back_Pattern">
<tr><td>
<!-- Class Mark Table -->
<table border="0" cellpadding="0" cellspacing="0" width="292" background="L2UI_CT1.HtmlWnd_DF_TextureKnight">
<tr><td align="center">
<!-- Text Table -->
<table border="0" cellpadding="0" cellspacing="0" width="272" height="338">
<tr><td height="216"> </td></tr>
<tr><td height="100" align="center" valign="bottom">You are brave to take this road!<br>Will you accept the help of the ancient hero Nabiarov and be awoken as a <font color="LEVEL">Sigel Knight</font>?</td></tr>
<tr><td align="center"><button value="Awaken" action="bypass -h Quest AwakeningMaster awakening" width="200" height="31" back="L2UI_CT1.HtmlWnd_DF_Awake_Down" fore="L2UI_CT1.HtmlWnd_DF_Awake"></td></tr>
</table>
<!-- //Text Table -->
</td></tr></table>
<!-- //Class Mark Table -->
</td></tr></table>
<!-- //Edge Decoration -->
</body></html>

View File

@@ -0,0 +1,3 @@
<html><body>Weapon/Force Master:<br>
The <font color="LEVEL">Tyrr Warrior's</font> <font color="978d83">power is growing</font>.
</body></html>

View File

@@ -0,0 +1,33 @@
<html>
<body scroll="no">
<!-- Edge Decoration Table -->
<table border="0" cellpadding="0" cellspacing="0" width="292" height="358" background="L2UI_CH3.refinewnd_back_Pattern">
<tr>
<td>
<!-- Class Mark Table -->
<table border="0" cellpadding="0" cellspacing="0" width="292"
background="L2UI_CT1.HtmlWnd_DF_TextureWarrior">
<tr>
<td align="center">
<!-- Text Table -->
<table border="0" cellpadding="0" cellspacing="0" width="272" height="338">
<tr>
<td height="90"></td>
</tr>
<tr>
<td align="center">It is not possible for you to Awaken as a Tyrr Warrior. <br>
<font color="af9878">(Only characters level 85 or above who have completed their 3rd
class transfer and possess the Scroll of Afterlife may Awaken.) </font></td>
</tr>
</table>
<!-- //Text Table -->
</td>
</tr>
</table>
<!-- //Class Mark Table -->
</td>
</tr>
</table>
<!-- //Edge Decoration -->
</body>
</html>

View File

@@ -0,0 +1,34 @@
<html>
<body scroll="no">
<!-- Edge Decoration Table -->
<table border="0" cellpadding="0" cellspacing="0" width="292" height="358" background="L2UI_CH3.refinewnd_back_Pattern">
<tr>
<td>
<!-- Class Mark Table -->
<table border="0" cellpadding="0" cellspacing="0" width="292"
background="L2UI_CT1.HtmlWnd_DF_TextureWarrior">
<tr>
<td align="center">
<!-- Text Table -->
<table border="0" cellpadding="0" cellspacing="0" width="272" height="338">
<tr>
<td height="150"></td>
</tr>
<tr>
<td align="center">The path you walk is not that of a Warrior. Seek the mark that is
appropriate for you.<br> <font color="af9878">(Only Warrior Class characters may
Awaken as a Tyrr Warrior.)</font></td>
</tr>
</table>
<!-- //Text Table -->
</td>
</tr>
</table>
<!-- //Class Mark Table -->
</td>
</tr>
</table>
<!-- //Edge Decoration -->
</body>
</html>

View File

@@ -0,0 +1,19 @@
<html><body scroll="no">
<!-- Edge Decoration Table -->
<table border="0" cellpadding="0" cellspacing="0" width="292" height="358" background="L2UI_CH3.refinewnd_back_Pattern">
<tr><td>
<!-- Class Mark Table -->
<table border="0" cellpadding="0" cellspacing="0" width="292" background="L2UI_CT1.HtmlWnd_DF_TextureWarrior">
<tr><td align="center">
<!-- Text Table -->
<table border="0" cellpadding="0" cellspacing="0" width="272" height="338">
<tr><td height="216"> </td></tr>
<tr><td height="100" align="center" valign="bottom">You are brave to take this road!<br>Will you accept the help of the ancient hero Nabiarov and be awoken as a <font color="LEVEL">Tyrr Warrior</font>?</td></tr>
<tr><td align="center"><button value="Awaken" action="bypass -h Quest AwakeningMaster awakening" width="200" height="31" back="L2UI_CT1.HtmlWnd_DF_Awake_Down" fore="L2UI_CT1.HtmlWnd_DF_Awake"></td></tr>
</table>
<!-- //Text Table -->
</td></tr></table>
<!-- //Class Mark Table -->
</td></tr></table>
<!-- //Edge Decoration -->
</body></html>

View File

@@ -0,0 +1,3 @@
<html><body>Dagger Master:<br>
The <font color="LEVEL">Othell Rogue's</font> <font color="978d83">power is growing</font>.
</body></html>

View File

@@ -0,0 +1,32 @@
<html>
<body scroll="no">
<!-- Edge Decoration Table -->
<table border="0" cellpadding="0" cellspacing="0" width="292" height="358" background="L2UI_CH3.refinewnd_back_Pattern">
<tr>
<td>
<!-- Class Mark Table -->
<table border="0" cellpadding="0" cellspacing="0" width="292" background="L2UI_CT1.HtmlWnd_DF_TextureRogue">
<tr>
<td align="center">
<!-- Text Table -->
<table border="0" cellpadding="0" cellspacing="0" width="272" height="338">
<tr>
<td height="90"></td>
</tr>
<tr>
<td align="center">It is not possible for you to Awaken as an Othell Rogue.<br>
<font color="af9878">(Only characters level 85 or above who have completed their 3rd
class transfer and possess the Scroll of Afterlife may Awaken.)</font></td>
</tr>
</table>
<!-- //Text Table -->
</td>
</tr>
</table>
<!-- //Class Mark Table -->
</td>
</tr>
</table>
<!-- //Edge Decoration -->
</body>
</html>

View File

@@ -0,0 +1,33 @@
<html>
<body scroll="no">
<!-- Edge Decoration Table -->
<table border="0" cellpadding="0" cellspacing="0" width="292" height="358" background="L2UI_CH3.refinewnd_back_Pattern">
<tr>
<td>
<!-- Class Mark Table -->
<table border="0" cellpadding="0" cellspacing="0" width="292" background="L2UI_CT1.HtmlWnd_DF_TextureRogue">
<tr>
<td align="center">
<!-- Text Table -->
<table border="0" cellpadding="0" cellspacing="0" width="272" height="338">
<tr>
<td height="150"></td>
</tr>
<tr>
<td align="center">You do not walk the Rogue’s path. You must seek another that is
appropriate for your class.<br> <font color="af9878">(Only Rogue Type Class
characters may Awaken as an Othell Rogue.) </font></td>
</tr>
</table>
<!-- //Text Table -->
</td>
</tr>
</table>
<!-- //Class Mark Table -->
</td>
</tr>
</table>
<!-- //Edge Decoration -->
</body>
</html>

View File

@@ -0,0 +1,19 @@
<html><body scroll="no">
<!-- Edge Decoration Table -->
<table border="0" cellpadding="0" cellspacing="0" width="292" height="358" background="L2UI_CH3.refinewnd_back_Pattern">
<tr><td>
<!-- Class Mark Table -->
<table border="0" cellpadding="0" cellspacing="0" width="292" background="L2UI_CT1.HtmlWnd_DF_TextureRogue">
<tr><td align="center">
<!-- Text Table -->
<table border="0" cellpadding="0" cellspacing="0" width="272" height="338">
<tr><td height="216"> </td></tr>
<tr><td height="100" align="center" valign="bottom">You are brave to take this road!<br>Will you accept the help of the ancient hero Nabiarov and be awoken as a <font color="LEVEL">Othell Rogue</font>?</td></tr>
<tr><td align="center"><button value="Awaken" action="bypass -h Quest AwakeningMaster awakening" width="200" height="31" back="L2UI_CT1.HtmlWnd_DF_Awake_Down" fore="L2UI_CT1.HtmlWnd_DF_Awake"></td></tr>
</table>
<!-- //Text Table -->
</td></tr></table>
<!-- //Class Mark Table -->
</td></tr></table>
<!-- //Edge Decoration -->
</body></html>

View File

@@ -0,0 +1,3 @@
<html><body>Bow/Crossbow Master:<br>
The <font color="LEVEL">Yul Archer's</font> <font color="978d83">power is growing</font>.
</body></html>

View File

@@ -0,0 +1,33 @@
<html>
<body scroll="no">
<!-- Edge Decoration Table -->
<table border="0" cellpadding="0" cellspacing="0" width="292" height="358" background="L2UI_CH3.refinewnd_back_Pattern">
<tr>
<td>
<!-- Class Mark Table -->
<table border="0" cellpadding="0" cellspacing="0" width="292"
background="L2UI_CT1.HtmlWnd_DF_TextureArcher">
<tr>
<td align="center">
<!-- Text Table -->
<table border="0" cellpadding="0" cellspacing="0" width="272" height="338">
<tr>
<td height="90"></td>
</tr>
<tr>
<td align="center">It is not possible for you to Awaken as a Yul Archer. <br>
<font color="af9878">(Only characters level 85 or above who have completed their 3rd
class transfer and possess the Scroll of Afterlife may Awaken.) </font></td>
</tr>
</table>
<!-- //Text Table -->
</td>
</tr>
</table>
<!-- //Class Mark Table -->
</td>
</tr>
</table>
<!-- //Edge Decoration -->
</body>
</html>

View File

@@ -0,0 +1,34 @@
<html>
<body scroll="no">
<!-- Edge Decoration Table -->
<table border="0" cellpadding="0" cellspacing="0" width="292" height="358" background="L2UI_CH3.refinewnd_back_Pattern">
<tr>
<td>
<!-- Class Mark Table -->
<table border="0" cellpadding="0" cellspacing="0" width="292"
background="L2UI_CT1.HtmlWnd_DF_TextureArcher">
<tr>
<td align="center">
<!-- Text Table -->
<table border="0" cellpadding="0" cellspacing="0" width="272" height="338">
<tr>
<td height="150"></td>
</tr>
<tr>
<td align="center">You do not walk the Archer’s path. You must seek another that is
appropriate for your class.<br> <font color="af9878">(Only Archer Class characters
may Awaken as a Yul Archer.)</font></td>
</tr>
</table>
<!-- //Text Table -->
</td>
</tr>
</table>
<!-- //Class Mark Table -->
</td>
</tr>
</table>
<!-- //Edge Decoration -->
</body>
</html>

View File

@@ -0,0 +1,19 @@
<html><body scroll="no">
<!-- Edge Decoration Table -->
<table border="0" cellpadding="0" cellspacing="0" width="292" height="358" background="L2UI_CH3.refinewnd_back_Pattern">
<tr><td>
<!-- Class Mark Table -->
<table border="0" cellpadding="0" cellspacing="0" width="292" background="L2UI_CT1.HtmlWnd_DF_TextureArcher">
<tr><td align="center">
<!-- Text Table -->
<table border="0" cellpadding="0" cellspacing="0" width="272" height="338">
<tr><td height="216"> </td></tr>
<tr><td height="100" align="center" valign="bottom">You are brave to take this road!<br>Will you accept the help of the ancient hero Nabiarov and be awoken as a <font color="LEVEL">Yul Archer</font>?</td></tr>
<tr><td align="center"><button value="Awaken" action="bypass -h Quest AwakeningMaster awakening" width="200" height="31" back="L2UI_CT1.HtmlWnd_DF_Awake_Down" fore="L2UI_CT1.HtmlWnd_DF_Awake"></td></tr>
</table>
<!-- //Text Table -->
</td></tr></table>
<!-- //Class Mark Table -->
</td></tr></table>
<!-- //Edge Decoration -->
</body></html>

View File

@@ -0,0 +1,3 @@
<html><body>Master Wizard:<br>
The <font color="LEVEL">Feoh Wizard's</font> <font color="978d83">power is growing</font>.
</body></html>

View File

@@ -0,0 +1,33 @@
<html>
<body scroll="no">
<!-- Edge Decoration Table -->
<table border="0" cellpadding="0" cellspacing="0" width="292" height="358" background="L2UI_CH3.refinewnd_back_Pattern">
<tr>
<td>
<!-- Class Mark Table -->
<table border="0" cellpadding="0" cellspacing="0" width="292"
background="L2UI_CT1.HtmlWnd_DF_TextureWizard">
<tr>
<td align="center">
<!-- Text Table -->
<table border="0" cellpadding="0" cellspacing="0" width="272" height="338">
<tr>
<td height="90"></td>
</tr>
<tr>
<td align="center">It is not possible for you to Awaken as a Feoh Wizard.<br>
<font color="af9878">(Only characters level 85 or above who have completed their 3rd
class transfer and possess the Scroll of Afterlife may Awaken.)</font></td>
</tr>
</table>
<!-- //Text Table -->
</td>
</tr>
</table>
<!-- //Class Mark Table -->
</td>
</tr>
</table>
<!-- //Edge Decoration -->
</body>
</html>

View File

@@ -0,0 +1,34 @@
<html>
<body scroll="no">
<!-- Edge Decoration Table -->
<table border="0" cellpadding="0" cellspacing="0" width="292" height="358" background="L2UI_CH3.refinewnd_back_Pattern">
<tr>
<td>
<!-- Class Mark Table -->
<table border="0" cellpadding="0" cellspacing="0" width="292"
background="L2UI_CT1.HtmlWnd_DF_TextureWizard">
<tr>
<td align="center">
<!-- Text Table -->
<table border="0" cellpadding="0" cellspacing="0" width="272" height="338">
<tr>
<td height="150"></td>
</tr>
<tr>
<td align="center">You do not walk the Wizard’s path. You must seek another that is
appropriate for your class.<br> <font color="af9878">(Only Wizard Class characters
may Awaken as a Feoh Wizard.)</font></td>
</tr>
</table>
<!-- //Text Table -->
</td>
</tr>
</table>
<!-- //Class Mark Table -->
</td>
</tr>
</table>
<!-- //Edge Decoration -->
</body>
</html>

View File

@@ -0,0 +1,19 @@
<html><body scroll="no">
<!-- Edge Decoration Table -->
<table border="0" cellpadding="0" cellspacing="0" width="292" height="358" background="L2UI_CH3.refinewnd_back_Pattern">
<tr><td>
<!-- Class Mark Table -->
<table border="0" cellpadding="0" cellspacing="0" width="292" background="L2UI_CT1.HtmlWnd_DF_TextureWizard">
<tr><td align="center">
<!-- Text Table -->
<table border="0" cellpadding="0" cellspacing="0" width="272" height="338">
<tr><td height="216"> </td></tr>
<tr><td height="100" align="center" valign="bottom">You are brave to take this road!<br>Will you accept the help of the ancient hero Nabiarov and be awoken as a <font color="LEVEL">Feoh Wizard</font>?</td></tr>
<tr><td align="center"><button value="Awaken" action="bypass -h Quest AwakeningMaster awakening" width="200" height="31" back="L2UI_CT1.HtmlWnd_DF_Awake_Down" fore="L2UI_CT1.HtmlWnd_DF_Awake"></td></tr>
</table>
<!-- //Text Table -->
</td></tr></table>
<!-- //Class Mark Table -->
</td></tr></table>
<!-- //Edge Decoration -->
</body></html>

View File

@@ -0,0 +1,3 @@
<html><body>Buff Master:<br>
The <font color="LEVEL">Iss Enchanter's</font> <font color="978d83">power is growing</font>.
</body></html>

View File

@@ -0,0 +1,33 @@
<html>
<body scroll="no">
<!-- Edge Decoration Table -->
<table border="0" cellpadding="0" cellspacing="0" width="292" height="358" background="L2UI_CH3.refinewnd_back_Pattern">
<tr>
<td>
<!-- Class Mark Table -->
<table border="0" cellpadding="0" cellspacing="0" width="292"
background="L2UI_CT1.HtmlWnd_DF_TextureEnchanter">
<tr>
<td align="center">
<!-- Text Table -->
<table border="0" cellpadding="0" cellspacing="0" width="272" height="338">
<tr>
<td height="90"></td>
</tr>
<tr>
<td align="center">It is not possible for you to Awaken as an Iss Enchanter. <br>
<font color="af9878">(Only characters level 85 or above who have completed their 3rd
class transfer and possess the Scroll of Afterlife may Awaken.)</font></td>
</tr>
</table>
<!-- //Text Table -->
</td>
</tr>
</table>
<!-- //Class Mark Table -->
</td>
</tr>
</table>
<!-- //Edge Decoration -->
</body>
</html>

View File

@@ -0,0 +1,34 @@
<html>
<body scroll="no">
<!-- Edge Decoration Table -->
<table border="0" cellpadding="0" cellspacing="0" width="292" height="358" background="L2UI_CH3.refinewnd_back_Pattern">
<tr>
<td>
<!-- Class Mark Table -->
<table border="0" cellpadding="0" cellspacing="0" width="292"
background="L2UI_CT1.HtmlWnd_DF_TextureEnchanter">
<tr>
<td align="center">
<!-- Text Table -->
<table border="0" cellpadding="0" cellspacing="0" width="272" height="338">
<tr>
<td height="150"></td>
</tr>
<tr>
<td align="center">You do not walk the Enchanter’s path. You must seek another that is
appropriate for your class.<br> <font color="af9878">(Only Enchanter Class
characters may Awaken as an Iss Enchanter.)</font></td>
</tr>
</table>
<!-- //Text Table -->
</td>
</tr>
</table>
<!-- //Class Mark Table -->
</td>
</tr>
</table>
<!-- //Edge Decoration -->
</body>
</html>

View File

@@ -0,0 +1,19 @@
<html><body scroll="no">
<!-- Edge Decoration Table -->
<table border="0" cellpadding="0" cellspacing="0" width="292" height="358" background="L2UI_CH3.refinewnd_back_Pattern">
<tr><td>
<!-- Class Mark Table -->
<table border="0" cellpadding="0" cellspacing="0" width="292" background="L2UI_CT1.HtmlWnd_DF_TextureEnchanter">
<tr><td align="center">
<!-- Text Table -->
<table border="0" cellpadding="0" cellspacing="0" width="272" height="338">
<tr><td height="216"> </td></tr>
<tr><td height="100" align="center" valign="bottom">You are brave to take this road!<br>Will you accept the help of the ancient hero Nabiarov and be awoken as a <font color="LEVEL">Iss Enchanter</font>?</td></tr>
<tr><td align="center"><button value="Awaken" action="bypass -h Quest AwakeningMaster awakening" width="200" height="31" back="L2UI_CT1.HtmlWnd_DF_Awake_Down" fore="L2UI_CT1.HtmlWnd_DF_Awake"></td></tr>
</table>
<!-- //Text Table -->
</td></tr></table>
<!-- //Class Mark Table -->
</td></tr></table>
<!-- //Edge Decoration -->
</body></html>

View File

@@ -0,0 +1,3 @@
<html><body>Master Summoner:<br>
The <font color="LEVEL">Wynn Summoner's</font> <font color="978d83">power is growing</font>.
</body></html>

View File

@@ -0,0 +1,33 @@
<html>
<body scroll="no">
<!-- Edge Decoration Table -->
<table border="0" cellpadding="0" cellspacing="0" width="292" height="358" background="L2UI_CH3.refinewnd_back_Pattern">
<tr>
<td>
<!-- Class Mark Table -->
<table border="0" cellpadding="0" cellspacing="0" width="292"
background="L2UI_CT1.HtmlWnd_DF_TextureSummoner">
<tr>
<td align="center">
<!-- Text Table -->
<table border="0" cellpadding="0" cellspacing="0" width="272" height="338">
<tr>
<td height="90"></td>
</tr>
<tr>
<td align="center">It is not possible for you to Awaken as a Wynn Summoner. <br>
<font color="af9878">(Only characters level 85 or above who have completed their 3rd
class transfer and possess the Scroll of Afterlife may Awaken.) </font></td>
</tr>
</table>
<!-- //Text Table -->
</td>
</tr>
</table>
<!-- //Class Mark Table -->
</td>
</tr>
</table>
<!-- //Edge Decoration -->
</body>
</html>

View File

@@ -0,0 +1,34 @@
<html>
<body scroll="no">
<!-- Edge Decoration Table -->
<table border="0" cellpadding="0" cellspacing="0" width="292" height="358" background="L2UI_CH3.refinewnd_back_Pattern">
<tr>
<td>
<!-- Class Mark Table -->
<table border="0" cellpadding="0" cellspacing="0" width="292"
background="L2UI_CT1.HtmlWnd_DF_TextureSummoner">
<tr>
<td align="center">
<!-- Text Table -->
<table border="0" cellpadding="0" cellspacing="0" width="272" height="338">
<tr>
<td height="150"></td>
</tr>
<tr>
<td align="center">You do not walk the Summoner’s path. You must seek another that is
appropriate for your class.<br> <font color="af9878">(Only Summoner Class
characters may Awaken as an Wynn Summoner.)</font></td>
</tr>
</table>
<!-- //Text Table -->
</td>
</tr>
</table>
<!-- //Class Mark Table -->
</td>
</tr>
</table>
<!-- //Edge Decoration -->
</body>
</html>

View File

@@ -0,0 +1,19 @@
<html><body scroll="no">
<!-- Edge Decoration Table -->
<table border="0" cellpadding="0" cellspacing="0" width="292" height="358" background="L2UI_CH3.refinewnd_back_Pattern">
<tr><td>
<!-- Class Mark Table -->
<table border="0" cellpadding="0" cellspacing="0" width="292" background="L2UI_CT1.HtmlWnd_DF_TextureSummoner">
<tr><td align="center">
<!-- Text Table -->
<table border="0" cellpadding="0" cellspacing="0" width="272" height="338">
<tr><td height="216"> </td></tr>
<tr><td height="100" align="center" valign="bottom">You are brave to take this road!<br>Will you accept the help of the ancient hero Nabiarov and be awoken as a <font color="LEVEL">Wynn Summoner</font>?</td></tr>
<tr><td align="center"><button value="Awaken" action="bypass -h Quest AwakeningMaster awakening" width="200" height="31" back="L2UI_CT1.HtmlWnd_DF_Awake_Down" fore="L2UI_CT1.HtmlWnd_DF_Awake"></td></tr>
</table>
<!-- //Text Table -->
</td></tr></table>
<!-- //Class Mark Table -->
</td></tr></table>
<!-- //Edge Decoration -->
</body></html>

View File

@@ -0,0 +1,3 @@
<html><body>Master Healer:<br>
The <font color="LEVEL">Aeore Healer's</font> <font color="978d83">power is growing</font>.
</body></html>

View File

@@ -0,0 +1,33 @@
<html>
<body scroll="no">
<!-- Edge Decoration Table -->
<table border="0" cellpadding="0" cellspacing="0" width="292" height="358" background="L2UI_CH3.refinewnd_back_Pattern">
<tr>
<td>
<!-- Class Mark Table -->
<table border="0" cellpadding="0" cellspacing="0" width="292"
background="L2UI_CT1.HtmlWnd_DF_TextureHealer">
<tr>
<td align="center">
<!-- Text Table -->
<table border="0" cellpadding="0" cellspacing="0" width="272" height="338">
<tr>
<td height="90"></td>
</tr>
<tr>
<td align="center">It is not possible for you to Awaken as an Aeore Healer. <br>
<font color="af9878">(Only characters level 85 or above who have completed their 3rd
class transfer and possess the Scroll of Afterlife may Awaken.)</font></td>
</tr>
</table>
<!-- //Text Table -->
</td>
</tr>
</table>
<!-- //Class Mark Table -->
</td>
</tr>
</table>
<!-- //Edge Decoration -->
</body>
</html>

View File

@@ -0,0 +1,34 @@
<html>
<body scroll="no">
<!-- Edge Decoration Table -->
<table border="0" cellpadding="0" cellspacing="0" width="292" height="358" background="L2UI_CH3.refinewnd_back_Pattern">
<tr>
<td>
<!-- Class Mark Table -->
<table border="0" cellpadding="0" cellspacing="0" width="292"
background="L2UI_CT1.HtmlWnd_DF_TextureHealer">
<tr>
<td align="center">
<!-- Text Table -->
<table border="0" cellpadding="0" cellspacing="0" width="272" height="338">
<tr>
<td height="150"></td>
</tr>
<tr>
<td align="center">You do not walk the Healer’s path. You must seek another that is
appropriate for your class.<br> <font color="af9878">(Only Healer Class characters
may Awaken as an Aeore Healer.)</font></td>
</tr>
</table>
<!-- //Text Table -->
</td>
</tr>
</table>
<!-- //Class Mark Table -->
</td>
</tr>
</table>
<!-- //Edge Decoration -->
</body>
</html>

View File

@@ -0,0 +1,19 @@
<html><body scroll="no">
<!-- Edge Decoration Table -->
<table border="0" cellpadding="0" cellspacing="0" width="292" height="358" background="L2UI_CH3.refinewnd_back_Pattern">
<tr><td>
<!-- Class Mark Table -->
<table border="0" cellpadding="0" cellspacing="0" width="292" background="L2UI_CT1.HtmlWnd_DF_TextureHealer">
<tr><td align="center">
<!-- Text Table -->
<table border="0" cellpadding="0" cellspacing="0" width="272" height="338">
<tr><td height="216"> </td></tr>
<tr><td height="100" align="center" valign="bottom">You are brave to take this road!<br>Will you accept the help of the ancient hero Nabiarov and be awoken as a <font color="LEVEL">Aeore Healer</font>?</td></tr>
<tr><td align="center"><button value="Awaken" action="bypass -h Quest AwakeningMaster awakening" width="200" height="31" back="L2UI_CT1.HtmlWnd_DF_Awake_Down" fore="L2UI_CT1.HtmlWnd_DF_Awake"></td></tr>
</table>
<!-- //Text Table -->
</td></tr></table>
<!-- //Class Mark Table -->
</td></tr></table>
<!-- //Edge Decoration -->
</body></html>

View File

@@ -0,0 +1,346 @@
/*
* 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.TalkingIsland.AwakeningMaster;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import com.l2jmobius.gameserver.ThreadPoolManager;
import com.l2jmobius.gameserver.data.xml.impl.SkillTreesData;
import com.l2jmobius.gameserver.enums.CategoryType;
import com.l2jmobius.gameserver.enums.Race;
import com.l2jmobius.gameserver.enums.UserInfoType;
import com.l2jmobius.gameserver.model.actor.L2Npc;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.model.base.ClassId;
import com.l2jmobius.gameserver.model.entity.Hero;
import com.l2jmobius.gameserver.model.events.EventType;
import com.l2jmobius.gameserver.model.events.ListenerRegisterType;
import com.l2jmobius.gameserver.model.events.annotations.RegisterEvent;
import com.l2jmobius.gameserver.model.events.annotations.RegisterType;
import com.l2jmobius.gameserver.model.events.impl.character.player.OnPlayerChangeToAwakenedClass;
import com.l2jmobius.gameserver.model.holders.SkillHolder;
import com.l2jmobius.gameserver.model.items.instance.L2ItemInstance;
import com.l2jmobius.gameserver.model.quest.QuestState;
import com.l2jmobius.gameserver.network.SystemMessageId;
import com.l2jmobius.gameserver.network.serverpackets.AcquireSkillList;
import com.l2jmobius.gameserver.network.serverpackets.ExChangeToAwakenedClass;
import com.l2jmobius.gameserver.network.serverpackets.ExShowUsm;
import com.l2jmobius.gameserver.network.serverpackets.SocialAction;
import com.l2jmobius.gameserver.network.serverpackets.UserInfo;
import ai.AbstractNpcAI;
import quests.Q10338_SeizeYourDestiny.Q10338_SeizeYourDestiny;
import quests.Q10472_WindsOfFateEncroachingShadows.Q10472_WindsOfFateEncroachingShadows;
/**
* AwakeningMaster AI.
* @author Sdw
*/
public final class AwakeningMaster extends AbstractNpcAI
{
// NPCs
private static final int SIGEL_MASTER = 33397;
private static final int TYRR_MASTER = 33398;
private static final int OTHELL_MASTER = 33399;
private static final int YUL_MASTER = 33400;
private static final int FEOH_MASTER = 33401;
private static final int ISS_MASTER = 33402;
private static final int WYNN_MASTER = 33403;
private static final int AEORE_MASTER = 33404;
// Items
private static final int SCROLL_OF_AFTERLIFE = 17600;
private static final Map<CategoryType, Integer> AWAKE_POWER = new HashMap<>();
static
{
AWAKE_POWER.put(CategoryType.SIGEL_GROUP, 32264);
AWAKE_POWER.put(CategoryType.TYRR_GROUP, 32265);
AWAKE_POWER.put(CategoryType.OTHELL_GROUP, 32266);
AWAKE_POWER.put(CategoryType.YUL_GROUP, 32267);
AWAKE_POWER.put(CategoryType.FEOH_GROUP, 32268);
AWAKE_POWER.put(CategoryType.ISS_GROUP, 32269);
AWAKE_POWER.put(CategoryType.WYNN_GROUP, 32270);
AWAKE_POWER.put(CategoryType.AEORE_GROUP, 32271);
}
// Skills
private static final SkillHolder WYNN_POWER = new SkillHolder(16390, 1);
private static final SkillHolder FEOH_POWER = new SkillHolder(16391, 1);
private static final SkillHolder TYRR_POWER = new SkillHolder(16392, 1);
private static final SkillHolder OTHELL_POWER = new SkillHolder(16393, 1);
private static final SkillHolder ISS_POWER = new SkillHolder(16394, 1);
private static final SkillHolder YUL_POWER = new SkillHolder(16395, 1);
private static final SkillHolder SIGEL_POWER = new SkillHolder(16396, 1);
private static final SkillHolder AEORE_POWER = new SkillHolder(16397, 1);
private AwakeningMaster()
{
addStartNpc(SIGEL_MASTER, TYRR_MASTER, OTHELL_MASTER, YUL_MASTER, FEOH_MASTER, ISS_MASTER, WYNN_MASTER, AEORE_MASTER);
addTalkId(SIGEL_MASTER, TYRR_MASTER, OTHELL_MASTER, YUL_MASTER, FEOH_MASTER, ISS_MASTER, WYNN_MASTER, AEORE_MASTER);
addFirstTalkId(SIGEL_MASTER, TYRR_MASTER, OTHELL_MASTER, YUL_MASTER, FEOH_MASTER, ISS_MASTER, WYNN_MASTER, AEORE_MASTER);
}
@Override
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
{
final QuestState st = getQuestState(player, true);
if (st == null)
{
return null;
}
final String htmltext = null;
switch (event)
{
case "awakening":
{
final QuestState st2 = player.getQuestState(Q10338_SeizeYourDestiny.class.getSimpleName());
if (hasQuestItems(player, SCROLL_OF_AFTERLIFE) && (player.getLevel() > 84) && (!player.isSubClassActive() || player.isDualClassActive()) && player.isInCategory(CategoryType.FOURTH_CLASS_GROUP) && (st2 != null) && st2.isCompleted())
{
switch (npc.getId())
{
case SIGEL_MASTER:
{
if (!player.isInCategory(CategoryType.SIGEL_CANDIDATE))
{
return SIGEL_MASTER + "-no_class.htm";
}
break;
}
case TYRR_MASTER:
{
if (!player.isInCategory(CategoryType.TYRR_CANDIDATE))
{
return TYRR_MASTER + "-no_class.htm";
}
break;
}
case OTHELL_MASTER:
{
if (!player.isInCategory(CategoryType.OTHELL_CANDIDATE))
{
return OTHELL_MASTER + "-no_class.htm";
}
break;
}
case YUL_MASTER:
{
if (!player.isInCategory(CategoryType.YUL_CANDIDATE))
{
return YUL_MASTER + "-no_class.htm";
}
break;
}
case FEOH_MASTER:
{
if (!player.isInCategory(CategoryType.FEOH_CANDIDATE))
{
return FEOH_MASTER + "-no_class.htm";
}
break;
}
case ISS_MASTER:
{
if (!player.isInCategory(CategoryType.ISS_CANDIDATE))
{
return ISS_MASTER + "-no_class.htm";
}
break;
}
case WYNN_MASTER:
{
if (!player.isInCategory(CategoryType.WYNN_CANDIDATE))
{
return WYNN_MASTER + "-no_class.htm";
}
break;
}
case AEORE_MASTER:
{
if (!player.isInCategory(CategoryType.AEORE_CANDIDATE))
{
return AEORE_MASTER + "-no_class.htm";
}
break;
}
}
for (ClassId newClass : player.getClassId().getNextClassIds())
{
player.sendPacket(new ExChangeToAwakenedClass(newClass.getId()));
}
}
else
{
return npc.getId() + "-no.htm";
}
break;
}
}
return htmltext;
}
@Override
public String onFirstTalk(L2Npc npc, L2PcInstance player)
{
if (player.getRace().equals(Race.ERTHEIA))
{
// Ertheia dual class quest
final QuestState qs = player.getQuestState(Q10472_WindsOfFateEncroachingShadows.class.getSimpleName());
if (qs != null)
{
if ((npc.getId() == WYNN_MASTER) && qs.isCond(8))
{
return setNextErtheiaQuestState(npc, qs, WYNN_MASTER, 9, WYNN_POWER);
}
else if ((npc.getId() == FEOH_MASTER) && qs.isCond(9))
{
return setNextErtheiaQuestState(npc, qs, FEOH_MASTER, 10, FEOH_POWER);
}
else if ((npc.getId() == TYRR_MASTER) && qs.isCond(10))
{
return setNextErtheiaQuestState(npc, qs, TYRR_MASTER, 11, TYRR_POWER);
}
else if ((npc.getId() == OTHELL_MASTER) && qs.isCond(11))
{
return setNextErtheiaQuestState(npc, qs, OTHELL_MASTER, 12, OTHELL_POWER);
}
else if ((npc.getId() == ISS_MASTER) && qs.isCond(12))
{
return setNextErtheiaQuestState(npc, qs, ISS_MASTER, 13, ISS_POWER);
}
else if ((npc.getId() == YUL_MASTER) && qs.isCond(13))
{
return setNextErtheiaQuestState(npc, qs, YUL_MASTER, 14, YUL_POWER);
}
else if ((npc.getId() == SIGEL_MASTER) && qs.isCond(14))
{
return setNextErtheiaQuestState(npc, qs, SIGEL_MASTER, 15, SIGEL_POWER);
}
else if ((npc.getId() == AEORE_MASTER) && qs.isCond(15))
{
return setNextErtheiaQuestState(npc, qs, AEORE_MASTER, 16, AEORE_POWER);
}
}
return "ertheia.html";
}
return npc.getId() + ".html";
}
private String setNextErtheiaQuestState(L2Npc npc, QuestState qs, int npcId, int cond, SkillHolder skill)
{
npc.setTarget(qs.getPlayer());
npc.doCast(skill.getSkill());
qs.setCond(cond, true);
return npcId + "-01.html";
}
@RegisterEvent(EventType.ON_PLAYER_CHANGE_TO_AWAKENED_CLASS)
@RegisterType(ListenerRegisterType.GLOBAL_PLAYERS)
public void OnPlayerChangeToAwakenedClass(OnPlayerChangeToAwakenedClass event)
{
final L2PcInstance player = event.getActiveChar();
if (player.isSubClassActive() && !player.isDualClassActive())
{
return;
}
if ((player.getLevel() < 85) || !player.isInCategory(CategoryType.FOURTH_CLASS_GROUP))
{
return;
}
final QuestState st = player.getQuestState(Q10338_SeizeYourDestiny.class.getSimpleName());
if ((st == null) || !st.isCompleted())
{
return;
}
if (player.isHero() || Hero.getInstance().isUnclaimedHero(player.getObjectId()))
{
player.sendPacket(SystemMessageId.YOU_CANNOT_AWAKEN_WHEN_YOU_ARE_A_HERO_OR_ON_THE_WAIT_LIST_FOR_HERO_STATUS);
return;
}
if (!player.isInventoryUnder80(false))
{
player.sendPacket(SystemMessageId.YOU_CANNOT_AWAKEN_DUE_TO_YOUR_CURRENT_INVENTORY_WEIGHT_PLEASE_ORGANIZE_YOUR_INVENTORY_AND_TRY_AGAIN_DWARVEN_CHARACTERS_MUST_BE_AT_20_OR_BELOW_THE_INVENTORY_MAX_TO_AWAKEN);
return;
}
if (player.isMounted() || player.isTransformed())
{
player.sendPacket(SystemMessageId.YOU_CANNOT_AWAKEN_WHILE_YOU_RE_TRANSFORMED_OR_RIDING);
return;
}
final L2ItemInstance item = player.getInventory().getItemByItemId(SCROLL_OF_AFTERLIFE);
if (item == null)
{
return;
}
if (!player.destroyItem("Awakening", item, player, true))
{
return;
}
for (ClassId newClass : player.getClassId().getNextClassIds())
{
player.setClassId(newClass.getId());
if (player.isDualClassActive())
{
player.getSubClasses().get(player.getClassIndex()).setClassId(player.getActiveClass());
}
else
{
player.setBaseClass(player.getActiveClass());
}
player.sendPacket(SystemMessageId.CONGRATULATIONS_YOU_VE_COMPLETED_A_CLASS_TRANSFER);
final UserInfo ui = new UserInfo(player, false);
ui.addComponentType(UserInfoType.BASIC_INFO);
ui.addComponentType(UserInfoType.MAX_HPCPMP);
player.sendPacket(ui);
player.broadcastInfo();
player.broadcastPacket(new SocialAction(player.getObjectId(), 20));
for (Entry<CategoryType, Integer> ent : AWAKE_POWER.entrySet())
{
if (player.isInCategory(ent.getKey()))
{
giveItems(player, ent.getValue(), 1);
break;
}
}
SkillTreesData.getInstance().cleanSkillUponAwakening(player);
player.sendPacket(new AcquireSkillList(player));
player.sendSkillList();
}
ThreadPoolManager.getInstance().scheduleGeneral(() ->
{
player.sendPacket(ExShowUsm.AWAKENING_END);
}, 10000);
}
public static void main(String[] args)
{
new AwakeningMaster();
}
}

View File

@@ -0,0 +1,5 @@
<html><body>
We can't accept your power yet. You'll need to go back.<br>
<font color="af9878">(Only characters level 85 or above who have completed their 3rd class transfer and possess the Scroll of Afterlife may Awaken.)<br>
If you have a Fragment of Chaos, you can Awaken after changing the power of your dual class through Hardin.</font>
</body></html>

View File

@@ -0,0 +1,70 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package ai.areas.TalkingIsland;
import com.l2jmobius.gameserver.enums.ChatType;
import com.l2jmobius.gameserver.model.StatsSet;
import com.l2jmobius.gameserver.model.actor.L2Npc;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.network.NpcStringId;
import ai.AbstractNpcAI;
/**
* Banette AI.
* @author St3eT
*/
public final class Banette extends AbstractNpcAI
{
// NPCs
private static final int BANETTE = 33114;
private Banette()
{
addSpawnId(BANETTE);
}
@Override
public void onTimerEvent(String event, StatsSet params, L2Npc npc, L2PcInstance player)
{
switch (getRandom(4))
{
case 0:
npc.broadcastSay(ChatType.NPC_GENERAL, NpcStringId.TRAINING_GROUND_IS_LOCATED_STRAIGHT_AHEAD);
break;
case 1:
npc.broadcastSay(ChatType.NPC_GENERAL, NpcStringId.WHILE_TRAINING_IN_THE_TRAINING_GROUNDS_IT_BECOMES_PROGRESSIVELY_DIFFICULT);
break;
case 2:
npc.broadcastSay(ChatType.NPC_GENERAL, NpcStringId.TRAINING_GROUNDS_ACCESS_YOU_NEED_TO_SPEAK_WITH_PANTHEON_IN_THE_MUSEUM);
break;
}
getTimers().addTimer("NPC_SHOUT", (10 + getRandom(5)) * 1000, npc, null);
}
@Override
public String onSpawn(L2Npc npc)
{
getTimers().addTimer("NPC_SHOUT", (10 + getRandom(5)) * 1000, npc, null);
return super.onSpawn(npc);
}
public static void main(String[] args)
{
new Banette();
}
}

View File

@@ -0,0 +1,61 @@
/*
* 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.TalkingIsland;
import com.l2jmobius.gameserver.enums.ChatType;
import com.l2jmobius.gameserver.model.actor.L2Npc;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.network.NpcStringId;
import ai.AbstractNpcAI;
/**
* Bink AI.
* @author Gladicek
*/
public final class Bink extends AbstractNpcAI
{
// NPCs
private static final int BINK = 33223;
private Bink()
{
addSpawnId(BINK);
}
@Override
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
{
if (event.equals("SPAM_TEXT") && (npc != null))
{
npc.broadcastSay(ChatType.NPC_GENERAL, NpcStringId.TALKING_ISLAND_VILLAGE_IS_REALLY_BEAUTIFUL, 1000);
}
return super.onAdvEvent(event, npc, player);
}
@Override
public String onSpawn(L2Npc npc)
{
startQuestTimer("SPAM_TEXT", 10000, npc, null, true);
return super.onSpawn(npc);
}
public static void main(String[] args)
{
new Bink();
}
}

View File

@@ -0,0 +1,92 @@
/*
* 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.TalkingIsland;
import com.l2jmobius.gameserver.GeoData;
import com.l2jmobius.gameserver.enums.ChatType;
import com.l2jmobius.gameserver.model.StatsSet;
import com.l2jmobius.gameserver.model.actor.L2Npc;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.network.NpcStringId;
import com.l2jmobius.gameserver.util.Util;
import ai.AbstractNpcAI;
/**
* Boy and Girl AI.
* @author St3eT
*/
public final class BoyAndGirl extends AbstractNpcAI
{
// NPCs
private static final int BOY = 33224;
private static final int GIRL = 33217;
// Items
private static final int WEAPON = 15304;
private BoyAndGirl()
{
addSpawnId(BOY, GIRL);
addMoveFinishedId(BOY, GIRL);
}
@Override
public void onTimerEvent(String event, StatsSet params, L2Npc npc, L2PcInstance player)
{
if (event.equals("NPC_CHANGEWEAP"))
{
if (npc.isScriptValue(1))
{
npc.setRHandId(0);
npc.setScriptValue(0);
}
else
{
npc.setRHandId(WEAPON);
npc.setScriptValue(1);
}
getTimers().addTimer("NPC_CHANGEWEAP", 15000 + (getRandom(5) * 1000), npc, null);
}
else if (event.equals("NPC_SHOUT"))
{
npc.broadcastSay(ChatType.NPC_GENERAL, npc.getId() == BOY ? NpcStringId.WEEE : NpcStringId.BOYS_ARE_SO_ANNOYING);
getTimers().addTimer("NPC_SHOUT", 10000 + (getRandom(5) * 1000), npc, null);
}
}
@Override
public String onSpawn(L2Npc npc)
{
getTimers().addTimer("NPC_CHANGEWEAP", 15000 + (getRandom(5) * 1000), npc, null);
getTimers().addTimer("NPC_SHOUT", 10000 + (getRandom(5) * 1000), npc, null);
npc.setIsRunning(true);
addMoveToDesire(npc, GeoData.getInstance().moveCheck(npc.getLocation(), Util.getRandomPosition(npc.getSpawn().getLocation(), 200, 600), npc.getInstanceWorld()), 23);
return super.onSpawn(npc);
}
@Override
public void onMoveFinished(L2Npc npc)
{
addMoveToDesire(npc, GeoData.getInstance().moveCheck(npc.getLocation(), Util.getRandomPosition(npc.getSpawn().getLocation(), 200, 600), npc.getInstanceWorld()), 23);
super.onMoveFinished(npc);
}
public static void main(String[] args)
{
new BoyAndGirl();
}
}

View File

@@ -0,0 +1,85 @@
/*
* 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.TalkingIsland;
import com.l2jmobius.gameserver.GeoData;
import com.l2jmobius.gameserver.enums.ChatType;
import com.l2jmobius.gameserver.model.StatsSet;
import com.l2jmobius.gameserver.model.actor.L2Npc;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.network.NpcStringId;
import com.l2jmobius.gameserver.util.Util;
import ai.AbstractNpcAI;
/**
* Devno AI.
* @author St3eT
*/
public final class Devno extends AbstractNpcAI
{
// NPC
private static final int DEVNO = 33241;
private Devno()
{
addSpawnId(DEVNO);
}
@Override
public void onTimerEvent(String event, StatsSet params, L2Npc npc, L2PcInstance player)
{
if (event.equals("NPC_MOVE"))
{
if (getRandomBoolean())
{
addMoveToDesire(npc, GeoData.getInstance().moveCheck(npc.getLocation(), Util.getRandomPosition(npc.getSpawn().getLocation(), 0, 500), npc.getInstanceWorld()), 23);
}
getTimers().addTimer("NPC_MOVE", (10 + getRandom(5)) * 1000, npc, null);
}
else if (event.equals("NPC_SHOUT"))
{
switch (getRandom(4))
{
case 0:
npc.broadcastSay(ChatType.NPC_GENERAL, NpcStringId.CARRY_OUT_YOUR_QUESTS_FAITHFULLY_IN_TALKING_ISLAND_AND_YOU_LL_GET_TO_THE_1ST_CLASS_TRANSFER_IN_NO_TIME);
break;
case 1:
npc.broadcastSay(ChatType.NPC_GENERAL, NpcStringId.I_SEE_THAT_ADVENTURERS_ARE_RETURNING_TO_TALKING_ISLAND_FOR_THE_AWAKENING);
break;
case 2:
npc.broadcastSay(ChatType.NPC_GENERAL, NpcStringId.YOU_CAN_SEE_VARIOUS_STATISTICS_IN_THE_MUSEUM_STATS_IN_THE_MAIN_MENU);
break;
}
getTimers().addTimer("NPC_SHOUT", (10 + getRandom(5)) * 1000, npc, null);
}
}
@Override
public String onSpawn(L2Npc npc)
{
getTimers().addTimer("NPC_MOVE", (10 + getRandom(5)) * 1000, npc, null);
getTimers().addTimer("NPC_SHOUT", (10 + getRandom(5)) * 1000, npc, null);
return super.onSpawn(npc);
}
public static void main(String[] args)
{
new Devno();
}
}

View File

@@ -0,0 +1,87 @@
/*
* 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.TalkingIsland;
import com.l2jmobius.gameserver.model.L2World;
import com.l2jmobius.gameserver.model.actor.L2Npc;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import ai.AbstractNpcAI;
/**
* Drill Sergeant AI.
* @author St3eT
*/
public final class DrillSergeant extends AbstractNpcAI
{
// NPCs
private static final int SERGANT = 33007; // Drill Sergant
private static final int GUARD = 33018;
// Misc
//@formatter:off
private final int[] SOCIAL_ACTIONS = {9, 10, 11, 1 };
//@formatter:on
private DrillSergeant()
{
addSpawnId(SERGANT);
}
@Override
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
{
if (event.equals("SOCIAL_SHOW"))
{
final int socialActionId = SOCIAL_ACTIONS[getRandom(SOCIAL_ACTIONS.length)];
npc.broadcastSocialAction(socialActionId);
L2World.getInstance().forEachVisibleObjectInRange(npc, L2Npc.class, 500, chars ->
{
if (chars.getId() == GUARD)
{
chars.getVariables().set("SOCIAL_ACTION_ID", socialActionId);
startQuestTimer("SOCIAL_ACTION", getRandom(500, 1500), chars, null);
}
});
}
else if (event.equals("SOCIAL_ACTION"))
{
final int socialActionId = npc.getVariables().getInt("SOCIAL_ACTION_ID", 0);
if (socialActionId > 0)
{
npc.broadcastSocialAction(socialActionId);
}
}
return super.onAdvEvent(event, npc, player);
}
@Override
public String onSpawn(L2Npc npc)
{
if (npc.getId() == SERGANT)
{
startQuestTimer("SOCIAL_SHOW", 10000, npc, null, true);
}
npc.setRandomAnimation(false);
return super.onSpawn(npc);
}
public static void main(String[] args)
{
new DrillSergeant();
}
}

View File

@@ -0,0 +1,81 @@
/*
* 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.TalkingIsland;
import com.l2jmobius.gameserver.GeoData;
import com.l2jmobius.gameserver.enums.ChatType;
import com.l2jmobius.gameserver.model.StatsSet;
import com.l2jmobius.gameserver.model.actor.L2Npc;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.network.NpcStringId;
import com.l2jmobius.gameserver.util.Util;
import ai.AbstractNpcAI;
/**
* Eleve AI.
* @author St3eT
*/
public final class Eleve extends AbstractNpcAI
{
// NPC
private static final int ELEVE = 33246;
private Eleve()
{
addSpawnId(ELEVE);
}
@Override
public void onTimerEvent(String event, StatsSet params, L2Npc npc, L2PcInstance player)
{
if (event.equals("NPC_MOVE"))
{
if (getRandomBoolean())
{
addMoveToDesire(npc, GeoData.getInstance().moveCheck(npc.getLocation(), Util.getRandomPosition(npc.getSpawn().getLocation(), 0, 500), npc.getInstanceWorld()), 23);
}
getTimers().addTimer("NPC_MOVE", (10 + getRandom(5)) * 1000, npc, null);
}
else if (event.equals("NPC_SHOUT"))
{
final int rand = getRandom(3);
if (rand == 0)
{
npc.broadcastSay(ChatType.NPC_GENERAL, NpcStringId.DON_T_KNOW_WHAT_TO_DO_LOOK_AT_THE_MAP);
}
else if (rand == 1)
{
npc.broadcastSay(ChatType.NPC_GENERAL, NpcStringId.DO_YOU_SEE_A_SCROLL_ICON_GO_THAT_LOCATION);
}
getTimers().addTimer("NPC_SHOUT", (10 + getRandom(5)) * 1000, npc, null);
}
}
@Override
public String onSpawn(L2Npc npc)
{
getTimers().addTimer("NPC_MOVE", (10 + getRandom(5)) * 1000, npc, null);
getTimers().addTimer("NPC_SHOUT", (10 + getRandom(5)) * 1000, npc, null);
return super.onSpawn(npc);
}
public static void main(String[] args)
{
new Eleve();
}
}

View File

@@ -0,0 +1,67 @@
/*
* 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.TalkingIsland;
import com.l2jmobius.gameserver.enums.ChatType;
import com.l2jmobius.gameserver.model.actor.L2Npc;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.network.NpcStringId;
import ai.AbstractNpcAI;
/**
* Gagabu AI.
* @author Gladicek
*/
public final class Gagabu extends AbstractNpcAI
{
// NPCs
private static final int GAGABU = 33284;
// Misc
private static final NpcStringId[] GAGABU_SHOUT =
{
NpcStringId.SPIRITSHOTS_ARE_MIXED,
NpcStringId.WHEN_WILL_I_ORGANIZE_THIS_ALL
};
private Gagabu()
{
addSpawnId(GAGABU);
}
@Override
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
{
if (event.equals("SPAM_TEXT") && (npc != null))
{
npc.broadcastSay(ChatType.NPC_GENERAL, GAGABU_SHOUT[getRandom(2)], 1000);
}
return super.onAdvEvent(event, npc, player);
}
@Override
public String onSpawn(L2Npc npc)
{
startQuestTimer("SPAM_TEXT", 8000, npc, null, true);
return super.onSpawn(npc);
}
public static void main(String[] args)
{
new Gagabu();
}
}

View File

@@ -0,0 +1,63 @@
/*
* 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.TalkingIsland;
import com.l2jmobius.gameserver.enums.ChatType;
import com.l2jmobius.gameserver.model.actor.L2Npc;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.network.NpcStringId;
import ai.AbstractNpcAI;
/**
* Galad AI.
* @author Gladicek
*/
public final class Galad extends AbstractNpcAI
{
// NPCs
private static final int GALAD = 33572;
private Galad()
{
addSpawnId(GALAD);
}
@Override
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
{
if (event.equals("SPAM_TEXT") && (npc != null))
{
npc.broadcastSocialAction(3);
npc.broadcastSay(ChatType.NPC_GENERAL, NpcStringId.OCCASIONALLY_RARE_JEWELS_OF_GIANTS_ARE_DISCOVERED_IN_THE_BEACH, 1000);
}
return super.onAdvEvent(event, npc, player);
}
@Override
public String onSpawn(L2Npc npc)
{
startQuestTimer("SPAM_TEXT", 8000, npc, null, true);
return super.onSpawn(npc);
}
public static void main(String[] args)
{
new Galad();
}
}

View File

@@ -0,0 +1,4 @@
<html><body>Seknus:<br>
During the war with the gods, the Giants activated the Metusella project and the Spicula project. When the two were combined, the Kamaels were born.<br>We may call ourselves either Metusella or Spicula, but everyone calls us <font color="LEVEL">Giant's Minions</font>.<br>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest GiantSoldiers TELEPORT_OUT">"I'll return to the Museum Lobby now."</Button>
</body></html>

View File

@@ -0,0 +1,4 @@
<html><body>Drell:<br>
It has been long since the passing of the Giants and the unsealing of the Kamaels. The Kamaels have evolved greatly since then, but have not forgotten the fact that the Giants are the true rulers of the world.<br>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest GiantSoldiers TELEPORT_OUT">"I'll return to the Museum Lobby now."</Button>
</body></html>

View File

@@ -0,0 +1,5 @@
<html><body>Asin:<br>
After the fall of the Floating Island, some Kamaels were able to resonate with the <font color="LEVEL">soul of Hermuncus</font>, newly awakened from his slumber.<br>
Many Kamael warriors including myself have gathered here since then, but were powerless to save our master...<br>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest GiantSoldiers TELEPORT_OUT">"I want to go back to the Museum Lobby."</Button>
</body></html>

View File

@@ -0,0 +1,4 @@
<html><body>Ranlof:<br>
The Book of the Righteous Path told the tales of many of the ancient heroes of the giants. Their successors figured out that the book itself was powerfully magical, and that they could absorb the book and inherit the giants' powers.<br>
That allowed them to face the very Gods themselves in battle. The giants called the process of absorbing that power <font color="LEVEL">Awakening</font>.
</body></html>

View File

@@ -0,0 +1,5 @@
<html><body>Skia:<br>
Ye Sagira was forsaken land. Everyone was wiped out during the war with the gods -- the Spiculas, the Giants, everyone. So why did the island crash to the ground?<br>
It is an omen. <font color="LEVEL">The Giants may be nearing resurrection</font>!<br>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest GiantSoldiers TELEPORT_OUT">"I'll return to the Museum Lobby now."</Button>
</body></html>

View File

@@ -0,0 +1,4 @@
<html><body>Roviel:<br>
After Sayune's life expired, Sayha took the spirit while the Giants absorbed parts of the body, gaining the ability to fly.<br>
The remaining parts of the body were absorbed by parts of the <font color="LEVEL">land</font>, which we now call Sayune and use for transportation if we have received the power of the Giants to <font color="LEVEL">Awaken</font>.
</body></html>

View File

@@ -0,0 +1,6 @@
<html><body>Roviel:<br>
Ever heard of Sayune? This transport method has a story behind it, you see. Sayha, the wind god, loved a woman belonging to the race of the Greater Giants. They had a child named <font color="LEVEL">Sayune</font>.<br>
The child is said to have inherited the feather-light swiftness of the father, and fierce intelligence of the mother.<br>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest GiantSoldiers 33485-1.html">"Go on."</Button>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest GiantSoldiers TELEPORT_OUT">"I'll return to the Museum Lobby now."</Button>
</body></html>

View File

@@ -0,0 +1,4 @@
<html><body>Beloa:<br>
Metusella's instincts resonate with the voice of Giants...but the independent will also yearns for freedom. What a tragic paradox...<br>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest GiantSoldiers TELEPORT_OUT">"I'll return to the Museum Lobby now."</Button>
</body></html>

View File

@@ -0,0 +1,5 @@
<html><body>Laksian:<br>
The Awakened have recently discovered the <font color="LEVEL">Sayune</font>, a method of transport among the Giants. Immediate investigation led to creating something similar with Shine Stones concentrated in rune and mana. The gigantic leaps practically let you fly!<br>
The effects aren't earth-shattering, but to reproduce such a thing...aren't the continental scholars amazing?<br>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest GiantSoldiers TELEPORT_OUT">"I'll return to the Museum Lobby now."</Button>
</body></html>

View File

@@ -0,0 +1,151 @@
/*
* 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.TalkingIsland.GiantSoldiers;
import com.l2jmobius.gameserver.enums.ChatType;
import com.l2jmobius.gameserver.model.Location;
import com.l2jmobius.gameserver.model.actor.L2Npc;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.network.NpcStringId;
import ai.AbstractNpcAI;
/**
* Giant's Soldiers AI.
* @author Gladicek
*/
public final class GiantSoldiers extends AbstractNpcAI
{
// NPCs
private static final int LAKSIAN = 33486;
private static final int BELOA = 33487;
private static final int SKIA = 33484;
private static final int RANLOF = 33483;
private static final int ROVIEL = 33485;
private static final int ASIN = 33482;
private static final int SEKNUS = 33480;
private static final int DRELL = 33481;
private static final int CELLPHINE = 33477;
// Location
private static final Location NEAR_PANTHEON = new Location(-114371, 260183, -1192);
public GiantSoldiers()
{
addStartNpc(LAKSIAN, BELOA, SKIA, RANLOF, ROVIEL, ASIN, SEKNUS, DRELL, CELLPHINE);
addFirstTalkId(LAKSIAN, BELOA, SKIA, RANLOF, ROVIEL, ASIN, SEKNUS, DRELL);
addSpawnId(LAKSIAN);
addSpawnId(BELOA);
}
@Override
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
{
if (npc == null)
{
return null;
}
String htmltext = null;
switch (event)
{
case "CHAT_MESSAGE_1A":
{
npc.broadcastSay(ChatType.NPC_GENERAL, NpcStringId.WE_SAW_PEOPLE_USE_SAYUNE_OTHER_THAN_THE_GIANT_S_MINIONS, 1000);
startQuestTimer("CHAT_MESSAGE_2A", 2000, npc, null);
break;
}
case "CHAT_MESSAGE_1B":
{
npc.broadcastSay(ChatType.NPC_GENERAL, NpcStringId.IT_S_BECAUSE_THEY_HAVE_BECOME_AWAKEN_THE_POWER_OF_THE_GIANT_S, 1000);
startQuestTimer("CHAT_MESSAGE_2B", 1500, npc, null);
break;
}
case "CHAT_MESSAGE_2A":
{
npc.broadcastSay(ChatType.NPC_GENERAL, NpcStringId.DUH_YOU_CAN_T_USE_SAYUNE_WITHOUT_POWERS_OF_GIANTS_IN_THE_FIRST_PLACE, 1000);
startQuestTimer("CHAT_MESSAGE_3A", 15000, npc, null);
break;
}
case "CHAT_MESSAGE_2B":
{
npc.broadcastSay(ChatType.NPC_GENERAL, NpcStringId.I_THINK_THAT_S_WHY_MANY_PEOPLE_COME_TO_VISIT_CELPHINE, 1000);
startQuestTimer("CHAT_MESSAGE_3B", 15000, npc, null);
break;
}
case "CHAT_MESSAGE_3A":
{
npc.broadcastSay(ChatType.NPC_GENERAL, NpcStringId.AFTER_YE_SAGIRA_FELL_THERE_WERE_MANY_SACRIFICES_MADE, 1000);
startQuestTimer("CHAT_MESSAGE_4A", 1500, npc, null);
break;
}
case "CHAT_MESSAGE_3B":
{
npc.broadcastSay(ChatType.NPC_GENERAL, NpcStringId.DIDN_T_THAT_RELEASE_THE_SEAL_ON_HERMUNCUS, 1000);
startQuestTimer("CHAT_MESSAGE_4B", 2000, npc, null);
break;
}
case "CHAT_MESSAGE_4A":
{
npc.broadcastSay(ChatType.NPC_GENERAL, NpcStringId.THAT_S_THE_RUMOR_BUT_NOTHING_TO_CONFIRM_IT, 1000);
startQuestTimer("CHAT_MESSAGE_1A", 15000, npc, null);
break;
}
case "CHAT_MESSAGE_4B":
{
npc.broadcastSay(ChatType.NPC_GENERAL, NpcStringId.IT_S_GOT_TO_BE_TRUE_WE_NEED_TO_FIND_IT, 1000);
startQuestTimer("CHAT_MESSAGE_1B", 15000, npc, null);
break;
}
case "33485-1.html":
{
htmltext = event;
break;
}
case "TELEPORT_OUT":
{
player.teleToLocation(NEAR_PANTHEON);
break;
}
}
return htmltext;
}
@Override
public String onSpawn(L2Npc npc)
{
switch (npc.getId())
{
case LAKSIAN:
{
startQuestTimer("CHAT_MESSAGE_1A", 1500, npc, null);
break;
}
case BELOA:
{
startQuestTimer("CHAT_MESSAGE_1B", 2500, npc, null);
break;
}
}
return super.onSpawn(npc);
}
public static void main(String[] args)
{
new GiantSoldiers();
}
}

View File

@@ -0,0 +1,68 @@
/*
* 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.TalkingIsland;
import com.l2jmobius.gameserver.enums.ChatType;
import com.l2jmobius.gameserver.model.actor.L2Npc;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.network.NpcStringId;
import ai.AbstractNpcAI;
/**
* Guard Soldier AI.
* @author Gladicek
*/
public final class GuardSoldier extends AbstractNpcAI
{
// NPCs
private static final int GUARD_SOLDIER = 33286;
private GuardSoldier()
{
addSpawnId(GUARD_SOLDIER);
}
@Override
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
{
if (event.equals("SPAM_TEXT") && (npc != null))
{
npc.broadcastSocialAction(3);
npc.broadcastSay(ChatType.NPC_GENERAL, NpcStringId.LADY_YOU_MUST_GO_IN, 1000);
}
else if (event.equals("SOCIAL_ACTION") && (npc != null))
{
npc.broadcastSocialAction(2);
}
return super.onAdvEvent(event, npc, player);
}
@Override
public String onSpawn(L2Npc npc)
{
startQuestTimer("SPAM_TEXT", 12000, npc, null, true);
startQuestTimer("SOCIAL_ACTION", 15000, npc, null, true);
return super.onSpawn(npc);
}
public static void main(String[] args)
{
new GuardSoldier();
}
}

View File

@@ -0,0 +1,4 @@
<html><body>Hadel:<br>
The Reliquary of the Giants is where the Giant heroes are buried. In the times of the Giants, when a hero died, their soul would be embedded within the Scroll of Afterlife while their body was put into the ground. This was done so that the power of Giants would be passed on from generation to generation.<br>
I won't stop you from visiting the Reliquary of the Giants if you wish to pay your respects to them.
</body></html>

View File

@@ -0,0 +1,6 @@
<html><body>Giant's Minion Hadel:<br>
Only a true hero may enter here.<br1>
It's too dangerous for someone like you.<br>
(This place is available only for characters of level 85 or higher who are awakened or have gone through the 3rd liberation.)<br>
<Button ALIGN=LEFT ICON="RETURN" action="bypass -h Quest Hadel 33344.html">Back</Button>
</body></html>

View File

@@ -0,0 +1,7 @@
<html><body>Hadel:<br>
This place is forsaken and forgotten...a resting place for my master. Where do you head from here, lowly one? <br>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest Hadel 33344-01.html">"Tell me about the Reliquary of the Giants."</Button>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest Hadel teleportToGiants">"I'll go to the Reliquary of the Giants now."</Button>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest Hadel teleportToHarnak">"Harnak Underground Ruins!" (only for characters of level 85 or higher who have gone through awakening or the 3rd liberation)</Button>
<Button ALIGN=LEFT ICON="QUEST" action="bypass -h npc_%objectId%_Quest">Quest</Button>
</body></html>

View File

@@ -0,0 +1,81 @@
/*
* 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.TalkingIsland.Hadel;
import com.l2jmobius.gameserver.enums.CategoryType;
import com.l2jmobius.gameserver.model.Location;
import com.l2jmobius.gameserver.model.actor.L2Npc;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import ai.AbstractNpcAI;
/**
* Hadel AI.
* @author St3eT
*/
public final class Hadel extends AbstractNpcAI
{
// NPC
private static final int HADEL = 33344;
// Locations
private static final Location GIANTS = new Location(-114562, 227307, -2864);
private static final Location HARNAK = new Location(-114700, 147909, -7720);
private Hadel()
{
addStartNpc(HADEL);
addTalkId(HADEL);
addFirstTalkId(HADEL);
}
@Override
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
{
String htmltext = null;
switch (event)
{
case "33344.html":
case "33344-01.html":
{
htmltext = event;
break;
}
case "teleportToGiants":
{
player.teleToLocation(GIANTS);
break;
}
case "teleportToHarnak":
{
if ((!player.isInCategory(CategoryType.AWAKEN_GROUP)) || (player.getLevel() < 85))
{
htmltext = "33344-noClass.html";
break;
}
player.teleToLocation(HARNAK);
break;
}
}
return htmltext;
}
public static void main(String[] args)
{
new Hadel();
}
}

View File

@@ -0,0 +1,72 @@
/*
* 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.TalkingIsland;
import com.l2jmobius.gameserver.GeoData;
import com.l2jmobius.gameserver.model.Location;
import com.l2jmobius.gameserver.model.actor.L2Npc;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import ai.AbstractNpcAI;
/**
* Handermonkey AI.
* @author Gladicek
*/
public final class Handermonkey extends AbstractNpcAI
{
// NPC
private static final int HANDERMONKEY = 33203;
private Handermonkey()
{
addSpawnId(HANDERMONKEY);
}
@Override
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
{
if (event.equals("NPC_MOVE") && (npc != null))
{
if (getRandom(100) < 70)
{
final int x = npc.getSpawn().getX() + (getRandom(-100, 100));
final int y = npc.getSpawn().getY() + (getRandom(-100, 100));
final Location loc = GeoData.getInstance().moveCheck(npc.getX(), npc.getY(), npc.getZ(), x, y, npc.getZ(), npc.getInstanceWorld());
addMoveToDesire(npc, loc, 0);
}
else
{
npc.broadcastSocialAction(9);
}
}
return super.onAdvEvent(event, npc, player);
}
@Override
public String onSpawn(L2Npc npc)
{
npc.setRunning();
startQuestTimer("NPC_MOVE", 5000, npc, null, true);
return super.onSpawn(npc);
}
public static void main(String[] args)
{
new Handermonkey();
}
}

View File

@@ -0,0 +1,3 @@
<html><body>Hardin:<br>
I am sad because my HTML missing.
</body></html>

View File

@@ -0,0 +1,7 @@
<html><body>Hardin:<br>
Your strength seems to be different from those of the Material Realm.<br>
Only those who suppress their inborn strength with the strength of the giants may use the strength of chaos.<br>
Someone like you can use your original powers at any time, so you don't need it.<br>
You cannot learn the strength of chaos. Go back.<br>
(Ertheia cannot use Chaos Essence)
</body></html>

View File

@@ -0,0 +1,5 @@
<html><body>Agent of Chaos Hardin:<br>
This place is a tomb for your soul. The <font color="LEVEL">strength of the giants</font> sleep here.<br>
Why has an Ertheia of the Wind race come here?<br>
<Button ALIGN=LEFT ICON="QUEST" action="bypass -h npc_%objectId%_Quest">Quest</Button>
</body></html>

View File

@@ -0,0 +1,58 @@
/*
* 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.TalkingIsland.Hardin;
import com.l2jmobius.gameserver.enums.Race;
import com.l2jmobius.gameserver.model.actor.L2Npc;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.model.quest.QuestState;
import ai.AbstractNpcAI;
import quests.Q10472_WindsOfFateEncroachingShadows.Q10472_WindsOfFateEncroachingShadows;
/**
* Hardin AI.
* @author malyelfik
*/
public final class Hardin extends AbstractNpcAI
{
// NPC
private static final int HARDIN = 33870;
private Hardin()
{
addStartNpc(HARDIN);
addFirstTalkId(HARDIN);
}
@Override
public String onFirstTalk(L2Npc npc, L2PcInstance player)
{
String htmltext = "33870-01.html"; // Anybody except Ertheia race TODO: Find HTML
if (player.getRace().equals(Race.ERTHEIA))
{
final QuestState st = player.getQuestState(Q10472_WindsOfFateEncroachingShadows.class.getSimpleName());
htmltext = ((st != null) && (st.getCond() >= 7) && (st.getCond() <= 17)) ? "33870-03.html" : "33870-02.html";
}
return htmltext;
}
public static void main(String[] args)
{
new Hardin();
}
}

View File

@@ -0,0 +1,62 @@
/*
* 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.TalkingIsland;
import com.l2jmobius.gameserver.enums.ChatType;
import com.l2jmobius.gameserver.model.StatsSet;
import com.l2jmobius.gameserver.model.actor.L2Npc;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.network.NpcStringId;
import ai.AbstractNpcAI;
/**
* Hera AI.
* @author St3eT
*/
public final class Hera extends AbstractNpcAI
{
// NPC
private static final int HERA = 33208;
private Hera()
{
addSpawnId(HERA);
}
@Override
public void onTimerEvent(String event, StatsSet params, L2Npc npc, L2PcInstance player)
{
if (event.equals("NPC_SHOUT"))
{
npc.broadcastSay(ChatType.NPC_GENERAL, getRandomBoolean() ? NpcStringId.DOES_THE_GODDESS_SEE_WHAT_SHE_HAS_DONE : NpcStringId.WHY_HAVE_THE_HEROES_ABANDONED_US);
getTimers().addTimer("NPC_SHOUT", 10000 + (getRandom(5) * 1000), npc, null);
}
}
@Override
public String onSpawn(L2Npc npc)
{
getTimers().addTimer("NPC_SHOUT", 10000 + (getRandom(5) * 1000), npc, null);
return super.onSpawn(npc);
}
public static void main(String[] args)
{
new Hera();
}
}

View File

@@ -0,0 +1,70 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package ai.areas.TalkingIsland;
import com.l2jmobius.gameserver.enums.ChatType;
import com.l2jmobius.gameserver.model.StatsSet;
import com.l2jmobius.gameserver.model.actor.L2Npc;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.network.NpcStringId;
import ai.AbstractNpcAI;
/**
* Heymond AI.
* @author St3eT
*/
public final class Heymond extends AbstractNpcAI
{
// NPCs
private static final int BANETTE = 33114;
private Heymond()
{
addSpawnId(BANETTE);
}
@Override
public void onTimerEvent(String event, StatsSet params, L2Npc npc, L2PcInstance player)
{
switch (getRandom(4))
{
case 0:
npc.broadcastSay(ChatType.NPC_GENERAL, NpcStringId.VIEW_OUR_WIDE_VARIETY_OF_ACCESSORIES);
break;
case 1:
npc.broadcastSay(ChatType.NPC_GENERAL, NpcStringId.THE_BEST_WEAPON_DOESN_T_MAKE_YOU_THE_BEST);
break;
case 2:
npc.broadcastSay(ChatType.NPC_GENERAL, NpcStringId.WE_BUY_AND_SELL_COME_TAKE_A_LOOK);
break;
}
getTimers().addTimer("NPC_SHOUT", (10 + getRandom(5)) * 1000, npc, null);
}
@Override
public String onSpawn(L2Npc npc)
{
getTimers().addTimer("NPC_SHOUT", (10 + getRandom(5)) * 1000, npc, null);
return super.onSpawn(npc);
}
public static void main(String[] args)
{
new Heymond();
}
}

View File

@@ -0,0 +1,67 @@
/*
* 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.TalkingIsland;
import com.l2jmobius.gameserver.enums.ChatType;
import com.l2jmobius.gameserver.model.actor.L2Npc;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.network.NpcStringId;
import ai.AbstractNpcAI;
/**
* Holly AI.
* @author Gladicek
*/
public final class Holly extends AbstractNpcAI
{
// NPCs
private static final int HOLLY = 33219;
private Holly()
{
addSpawnId(HOLLY);
}
@Override
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
{
if (event.equals("SPAM_TEXT") && (npc != null))
{
npc.broadcastSay(ChatType.NPC_GENERAL, NpcStringId.GIRAN_SHUTTLE_DOES_NOT_COME_ANYMORE_IT_S_ALL_IN_THE_PAST, 1000);
}
else if (event.equals("SOCIAL_ACTION") && (npc != null))
{
npc.broadcastSocialAction(6);
}
return super.onAdvEvent(event, npc, player);
}
@Override
public String onSpawn(L2Npc npc)
{
npc.setRandomAnimation(false);
startQuestTimer("SPAM_TEXT", 10000, npc, null, true);
startQuestTimer("SOCIAL_ACTION", 2000, npc, null, true);
return super.onSpawn(npc);
}
public static void main(String[] args)
{
new Holly();
}
}

View File

@@ -0,0 +1,81 @@
/*
* 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.TalkingIsland;
import com.l2jmobius.gameserver.GeoData;
import com.l2jmobius.gameserver.enums.ChatType;
import com.l2jmobius.gameserver.model.StatsSet;
import com.l2jmobius.gameserver.model.actor.L2Npc;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.network.NpcStringId;
import com.l2jmobius.gameserver.util.Util;
import ai.AbstractNpcAI;
/**
* Karonf AI.
* @author St3eT
*/
public final class Karonf extends AbstractNpcAI
{
// NPC
private static final int KARONF = 33242;
private Karonf()
{
addSpawnId(KARONF);
}
@Override
public void onTimerEvent(String event, StatsSet params, L2Npc npc, L2PcInstance player)
{
if (event.equals("NPC_MOVE"))
{
if (getRandomBoolean())
{
addMoveToDesire(npc, GeoData.getInstance().moveCheck(npc.getLocation(), Util.getRandomPosition(npc.getSpawn().getLocation(), 0, 500), npc.getInstanceWorld()), 23);
}
getTimers().addTimer("NPC_MOVE", (10 + getRandom(5)) * 1000, npc, null);
}
else if (event.equals("NPC_SHOUT"))
{
final int rand = getRandom(3);
if (rand == 0)
{
npc.broadcastSay(ChatType.NPC_GENERAL, NpcStringId.WHEN_YOU_GO_TO_THE_MUSEUM_SPEAK_TO_PANTHEON);
}
else if (rand == 1)
{
npc.broadcastSay(ChatType.NPC_GENERAL, NpcStringId.SOME_FOLKS_DON_T_KNOW_WHAT_THEY_ARE_DOING);
}
getTimers().addTimer("NPC_SHOUT", (10 + getRandom(5)) * 1000, npc, null);
}
}
@Override
public String onSpawn(L2Npc npc)
{
getTimers().addTimer("NPC_MOVE", (10 + getRandom(5)) * 1000, npc, null);
getTimers().addTimer("NPC_SHOUT", (10 + getRandom(5)) * 1000, npc, null);
return super.onSpawn(npc);
}
public static void main(String[] args)
{
new Karonf();
}
}

View File

@@ -0,0 +1,72 @@
/*
* 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.TalkingIsland;
import com.l2jmobius.gameserver.enums.ChatType;
import com.l2jmobius.gameserver.model.actor.L2Npc;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.network.NpcStringId;
import ai.AbstractNpcAI;
/**
* Luderic AI.
* @author Gladicek
*/
public final class Luderic extends AbstractNpcAI
{
// NPCs
private static final int LUDERIC = 33575;
// Misc
private static final NpcStringId[] LUDERIC_SHOUT =
{
NpcStringId.THERE_IS_A_DAY_WHERE_YOU_CAN_SEE_EVEN_THE_ADEN_CONTINENT_IF_THE_WEATHER_IS_GOOD,
NpcStringId.IF_I_M_HERE_IT_FEELS_LIKE_TIME_HAS_STOPPED
};
private Luderic()
{
addSpawnId(LUDERIC);
}
@Override
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
{
if (event.equals("SPAM_TEXT") && (npc != null))
{
npc.broadcastSay(ChatType.NPC_GENERAL, LUDERIC_SHOUT[getRandom(2)], 1000);
}
else if (event.equals("SOCIAL_ACTION") && (npc != null))
{
npc.broadcastSocialAction(1);
}
return super.onAdvEvent(event, npc, player);
}
@Override
public String onSpawn(L2Npc npc)
{
startQuestTimer("SPAM_TEXT", 7000, npc, null, true);
startQuestTimer("SOCIAL_ACTION", 3000, npc, null, true);
return super.onSpawn(npc);
}
public static void main(String[] args)
{
new Luderic();
}
}

View File

@@ -0,0 +1,68 @@
/*
* 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.TalkingIsland;
import com.l2jmobius.gameserver.enums.ChatType;
import com.l2jmobius.gameserver.model.actor.L2Npc;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.network.NpcStringId;
import ai.AbstractNpcAI;
/**
* Lumi AI.
* @author Gladicek
*/
public final class Lumi extends AbstractNpcAI
{
// NPCs
private static final int LUMI = 33025;
// Misc
private static final NpcStringId[] LUMI_SHOUT =
{
NpcStringId.TO_YOUR_RIGHT_THE_ADMINISTRATIVE_DISTRICT_AND_TO_THE_LEFT_IS_THE_MUSEUM,
NpcStringId.WHEN_YOU_USE_THE_TELEPORTER_YOU_CAN_GO_TO_THE_RUINS_OF_YE_SAGIRA,
NpcStringId.HAVE_YOU_BEEN_TO_RUINS_OF_YE_SAGIRA_YOU_HAVE_TO_GO_AT_LEAST_ONCE,
};
private Lumi()
{
addSpawnId(LUMI);
}
@Override
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
{
if (event.equals("SPAM_TEXT") && (npc != null))
{
npc.broadcastSay(ChatType.NPC_GENERAL, LUMI_SHOUT[getRandom(3)], 1000);
}
return super.onAdvEvent(event, npc, player);
}
@Override
public String onSpawn(L2Npc npc)
{
startQuestTimer("SPAM_TEXT", 8000, npc, null, true);
return super.onSpawn(npc);
}
public static void main(String[] args)
{
new Lumi();
}
}

View File

@@ -0,0 +1,61 @@
/*
* 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.TalkingIsland;
import com.l2jmobius.gameserver.enums.ChatType;
import com.l2jmobius.gameserver.model.actor.L2Npc;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.network.NpcStringId;
import ai.AbstractNpcAI;
/**
* Mahram AI.
* @author St3eT
*/
public final class Mahram extends AbstractNpcAI
{
// NPCs
private static final int MAHRAM = 33271;
private Mahram()
{
addSpawnId(MAHRAM);
}
@Override
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
{
if (event.equals("SPAM_TEXT") && (npc != null))
{
npc.broadcastSay(ChatType.NPC_GENERAL, NpcStringId.ALCHEMY_IS_A_SCIENCE_AND_AN_ART, 1000);
}
return super.onAdvEvent(event, npc, player);
}
@Override
public String onSpawn(L2Npc npc)
{
startQuestTimer("SPAM_TEXT", 10000, npc, null, true);
return super.onSpawn(npc);
}
public static void main(String[] args)
{
new Mahram();
}
}

View File

@@ -0,0 +1,61 @@
/*
* 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.TalkingIsland;
import com.l2jmobius.gameserver.enums.ChatType;
import com.l2jmobius.gameserver.model.actor.L2Npc;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.network.NpcStringId;
import ai.AbstractNpcAI;
/**
* Mai AI.
* @author Gladicek
*/
public final class Mai extends AbstractNpcAI
{
// NPCs
private static final int MAI = 33238;
private Mai()
{
addSpawnId(MAI);
}
@Override
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
{
if (event.equals("SPAM_TEXT") && (npc != null))
{
npc.broadcastSay(ChatType.NPC_GENERAL, NpcStringId.EVERY_RACE_BUILT_A_PIECE_OF_THIS_VILLAGE, 1000);
}
return super.onAdvEvent(event, npc, player);
}
@Override
public String onSpawn(L2Npc npc)
{
startQuestTimer("SPAM_TEXT", 15000, npc, null, true);
return super.onSpawn(npc);
}
public static void main(String[] args)
{
new Mai();
}
}

View File

@@ -0,0 +1,61 @@
/*
* 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.TalkingIsland;
import com.l2jmobius.gameserver.enums.ChatType;
import com.l2jmobius.gameserver.model.actor.L2Npc;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.network.NpcStringId;
import ai.AbstractNpcAI;
/**
* Marin Smith AI.
* @author Gladicek
*/
public final class MarinSmith extends AbstractNpcAI
{
// NPCs
private static final int MARIN_SMITH = 33285;
private MarinSmith()
{
addSpawnId(MARIN_SMITH);
}
@Override
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
{
if (event.equals("SPAM_TEXT") && (npc != null))
{
npc.broadcastSay(ChatType.NPC_GENERAL, NpcStringId.HMM_IS_THIS_STILL_A_DECENT_WEAPON, 1000);
}
return super.onAdvEvent(event, npc, player);
}
@Override
public String onSpawn(L2Npc npc)
{
startQuestTimer("SPAM_TEXT", 6000, npc, null, true);
return super.onSpawn(npc);
}
public static void main(String[] args)
{
new MarinSmith();
}
}

View File

@@ -0,0 +1,81 @@
/*
* 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.TalkingIsland;
import com.l2jmobius.gameserver.GeoData;
import com.l2jmobius.gameserver.enums.ChatType;
import com.l2jmobius.gameserver.model.StatsSet;
import com.l2jmobius.gameserver.model.actor.L2Npc;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.network.NpcStringId;
import com.l2jmobius.gameserver.util.Util;
import ai.AbstractNpcAI;
/**
* Marsha AI.
* @author St3eT
*/
public final class Marsha extends AbstractNpcAI
{
// NPC
private static final int MARSHA = 33109;
private Marsha()
{
addSpawnId(MARSHA);
}
@Override
public void onTimerEvent(String event, StatsSet params, L2Npc npc, L2PcInstance player)
{
if (event.equals("NPC_MOVE"))
{
if (getRandomBoolean())
{
addMoveToDesire(npc, GeoData.getInstance().moveCheck(npc.getLocation(), Util.getRandomPosition(npc.getSpawn().getLocation(), 0, 500), npc.getInstanceWorld()), 23);
}
getTimers().addTimer("NPC_MOVE", (10 + getRandom(5)) * 1000, npc, null);
}
else if (event.equals("NPC_SHOUT"))
{
final int rand = getRandom(3);
if (rand == 0)
{
npc.broadcastSay(ChatType.NPC_GENERAL, NpcStringId.IT_S_QUITE_A_WALK_TO_RUINS_OF_YE_SAGIRA);
}
else if (rand == 1)
{
npc.broadcastSay(ChatType.NPC_GENERAL, NpcStringId.ISN_T_THERE_AN_EASIER_WAY_TO_GET_THERE);
}
getTimers().addTimer("NPC_SHOUT", (10 + getRandom(5)) * 1000, npc, null);
}
}
@Override
public String onSpawn(L2Npc npc)
{
getTimers().addTimer("NPC_MOVE", (10 + getRandom(5)) * 1000, npc, null);
getTimers().addTimer("NPC_SHOUT", (10 + getRandom(5)) * 1000, npc, null);
return super.onSpawn(npc);
}
public static void main(String[] args)
{
new Marsha();
}
}

View File

@@ -0,0 +1,70 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package ai.areas.TalkingIsland;
import com.l2jmobius.gameserver.enums.ChatType;
import com.l2jmobius.gameserver.model.Location;
import com.l2jmobius.gameserver.model.actor.L2Npc;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.network.NpcStringId;
import ai.AbstractNpcAI;
/**
* Milia AI.
* @author St3eT
*/
public final class Milia extends AbstractNpcAI
{
// NPCs
private static final int MILIA = 30006;
// Locations
private static final Location GLUDIO_AIRSHIP = new Location(-149406, 255247, -80);
private Milia()
{
addSpawnId(MILIA);
addStartNpc(MILIA);
addTalkId(MILIA);
}
@Override
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
{
if (event.equals("gludioAirship"))
{
player.teleToLocation(GLUDIO_AIRSHIP);
}
else if (event.equals("TEXT_SPAM") && (npc != null))
{
npc.broadcastSay(ChatType.NPC_GENERAL, NpcStringId.SPEAK_WITH_ME_ABOUT_TRAVELING_AROUND_ADEN, 1000);
}
return super.onAdvEvent(event, npc, player);
}
@Override
public String onSpawn(L2Npc npc)
{
startQuestTimer("TEXT_SPAM", 10000, npc, null, true);
return super.onSpawn(npc);
}
public static void main(String[] args)
{
new Milia();
}
}

View File

@@ -0,0 +1,8 @@
<html><body>Monk of Chaos:<br>
The skills that were once given to each race to balance their power have been taken back. Through the will of Chaos, you can learn the skills of other races as long as you have a Chaos Pomander.<br>
Chaos Pomander is a crystal of power that can combine anything. If you have one, you have been selected by my master to work for a balanced world.<br>
Are you ready for that world? If so, select the Revelation of Chaos, and through it a power appropriate for you.<br>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest MonkOfChaos LearnRevelationSkills">Receive the Revelation of Chaos.</Button>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest MonkOfChaos CancelRevelationSkills">Reset the Revelation skill.(100,000,000 Adena)</Button>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest MonkOfChaos 33880-2.html">"Who are Monks of Chaos?"</Button>
</body></html>

View File

@@ -0,0 +1,6 @@
<html><body>Monk of Chaos:<br>
We, the Monks of Chaos, serve the balance.<br>
You may think chaos is a destructive force, but nothing could be further from the truth.
<font color="LEVEL">Chaos</font> seeks to balance light and darkness by reverting them to the original energies.<br>
We who respect his will are the only ones truly free to act on it.
</body></html>

View File

@@ -0,0 +1,6 @@
<html><body>Monk of Chaos:<br>
Nothing could be created or destroyed without chaos. It is the beginning and the end of all things.<br>
We, the Monks of Chaos, understand this. It is the law of the universe.<br>
If you wish, we will reveal our master's will to you.<br>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest MonkOfChaos 33880-1.html">"So tell me about this Revelation of Chaos."</Button>
</body></html>

View File

@@ -0,0 +1,178 @@
/*
* 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.TalkingIsland.MonkOfChaos;
import java.util.List;
import com.l2jmobius.gameserver.data.xml.impl.SkillData;
import com.l2jmobius.gameserver.data.xml.impl.SkillTreesData;
import com.l2jmobius.gameserver.enums.CategoryType;
import com.l2jmobius.gameserver.enums.SubclassType;
import com.l2jmobius.gameserver.model.L2SkillLearn;
import com.l2jmobius.gameserver.model.actor.L2Npc;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.model.base.AcquireSkillType;
import com.l2jmobius.gameserver.model.skills.Skill;
import com.l2jmobius.gameserver.network.SystemMessageId;
import com.l2jmobius.gameserver.network.serverpackets.ExAcquirableSkillListByClass;
import ai.AbstractNpcAI;
/**
* Monk of Chaos AI.
* @author Sdw
*/
public final class MonkOfChaos extends AbstractNpcAI
{
private static final int MONK_OF_CHAOS = 33880;
private static final int MIN_LEVEL = 85;
private static final long CANCEL_FEE = 100000000;
private static final int CHAOS_POMANDER = 37374;
private static final int CHAOS_POMANDER_DUALCLASS = 37375;
private static final String[] REVELATION_VAR_NAMES =
{
"RevelationSkill1",
"RevelationSkill2"
};
private static final String[] DUALCLASS_REVELATION_VAR_NAMES =
{
"DualclassRevelationSkill1",
"DualclassRevelationSkill2"
};
private MonkOfChaos()
{
addStartNpc(MONK_OF_CHAOS);
addTalkId(MONK_OF_CHAOS);
addFirstTalkId(MONK_OF_CHAOS);
}
@Override
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
{
String htmltext = null;
switch (event)
{
case "33880-1.html":
case "33880-2.html":
{
htmltext = event;
break;
}
case "LearnRevelationSkills":
{
if ((player.getLevel() < MIN_LEVEL) || !player.isInCategory(CategoryType.AWAKEN_GROUP))
{
htmltext = "no-learn.html";
break;
}
if (player.isSubClassActive() && !player.isDualClassActive())
{
htmltext = "no-subclass.html";
break;
}
if (player.isDualClassActive())
{
final List<L2SkillLearn> skills = SkillTreesData.getInstance().getAvailableRevelationSkills(player, SubclassType.DUALCLASS);
if (skills.size() > 0)
{
player.sendPacket(new ExAcquirableSkillListByClass(skills, AcquireSkillType.REVELATION_DUALCLASS));
}
else
{
player.sendPacket(SystemMessageId.THERE_ARE_NO_OTHER_SKILLS_TO_LEARN);
}
}
else
{
final List<L2SkillLearn> skills = SkillTreesData.getInstance().getAvailableRevelationSkills(player, SubclassType.BASECLASS);
if (skills.size() > 0)
{
player.sendPacket(new ExAcquirableSkillListByClass(skills, AcquireSkillType.REVELATION));
}
else
{
player.sendPacket(SystemMessageId.THERE_ARE_NO_OTHER_SKILLS_TO_LEARN);
}
}
break;
}
case "CancelRevelationSkills":
{
if (player.isSubClassActive() && !player.isDualClassActive())
{
htmltext = "no-subclass.html";
break;
}
int count = 0;
final String[] varNames = player.isDualClassActive() ? DUALCLASS_REVELATION_VAR_NAMES : REVELATION_VAR_NAMES;
final int chaosPomander = player.isDualClassActive() ? CHAOS_POMANDER_DUALCLASS : CHAOS_POMANDER;
for (String varName : varNames)
{
if (player.getVariables().getInt(varName, 0) > 0)
{
count++;
}
}
if ((player.getLevel() < MIN_LEVEL) || !player.isInCategory(CategoryType.AWAKEN_GROUP) || (count == 0))
{
htmltext = "no-cancel.html";
break;
}
if (player.getAdena() < CANCEL_FEE)
{
htmltext = "no-adena.html";
break;
}
for (String varName : varNames)
{
final int skillId = player.getVariables().getInt(varName, 0);
final Skill sk = SkillData.getInstance().getSkill(skillId, 1);
if (sk != null)
{
player.removeSkill(sk);
player.getVariables().remove(varName);
giveItems(player, chaosPomander, count);
}
}
htmltext = "canceled.html";
break;
}
}
return htmltext;
}
public static void main(String[] args)
{
new MonkOfChaos();
}
}

View File

@@ -0,0 +1,3 @@
<html><body>Monk of Chaos:<br>
Heh! The Revelation of Chaos has been canceled. But you can pass it again when you come back to your senses.
</body></html>

View File

@@ -0,0 +1,4 @@
<html><body>Monk of Chaos:<br>
You do not have enough <font color="level">Adena</font> to cancel the Revelation of Chaos.<br>
Come back another time.
</body></html>

View File

@@ -0,0 +1,4 @@
<html><body>Monk of Chaos:<br>
You cannot cancel the Revelation of Chaos, because you have not passed it.<br>
Come back another time.
</body></html>

View File

@@ -0,0 +1,5 @@
<html><body>Monk of Chaos:<br>
You are not strong enough to fulfill the Revelation of Chaos.<br>
Come back another time.<br>
(Available only to Awaken characters level 85 or above.)
</body></html>

View File

@@ -0,0 +1,5 @@
<html><body>Monk of Chaos:<br>
The skills that weYou are not strong enough to fulfill the Revelation of Chaos.<br>
Come back another time.<br>
(Not available on subclasses.)
</body></html>

View File

@@ -0,0 +1,81 @@
/*
* 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.TalkingIsland;
import com.l2jmobius.gameserver.GeoData;
import com.l2jmobius.gameserver.enums.ChatType;
import com.l2jmobius.gameserver.model.StatsSet;
import com.l2jmobius.gameserver.model.actor.L2Npc;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.network.NpcStringId;
import com.l2jmobius.gameserver.util.Util;
import ai.AbstractNpcAI;
/**
* Morgan AI.
* @author St3eT
*/
public final class Morgan extends AbstractNpcAI
{
// NPC
private static final int MORGAN = 33121;
private Morgan()
{
addSpawnId(MORGAN);
}
@Override
public void onTimerEvent(String event, StatsSet params, L2Npc npc, L2PcInstance player)
{
if (event.equals("NPC_MOVE"))
{
if (getRandomBoolean())
{
addMoveToDesire(npc, GeoData.getInstance().moveCheck(npc.getLocation(), Util.getRandomPosition(npc.getSpawn().getLocation(), 0, 500), npc.getInstanceWorld()), 23);
}
getTimers().addTimer("NPC_MOVE", (10 + getRandom(5)) * 1000, npc, null);
}
else if (event.equals("NPC_SHOUT"))
{
final int rand = getRandom(3);
if (rand == 0)
{
npc.broadcastSay(ChatType.NPC_GENERAL, NpcStringId.DON_T_GO_HUNTING_WITHOUT_SOULSHOT);
}
else if (rand == 1)
{
npc.broadcastSay(ChatType.NPC_GENERAL, NpcStringId.BELOW_LEVEL_75_BE_SURE_TO_RECEIVE_NEWBIE_BUFFS);
}
getTimers().addTimer("NPC_SHOUT", (10 + getRandom(5)) * 1000, npc, null);
}
}
@Override
public String onSpawn(L2Npc npc)
{
getTimers().addTimer("NPC_MOVE", (10 + getRandom(5)) * 1000, npc, null);
getTimers().addTimer("NPC_SHOUT", (10 + getRandom(5)) * 1000, npc, null);
return super.onSpawn(npc);
}
public static void main(String[] args)
{
new Morgan();
}
}

View File

@@ -0,0 +1,74 @@
/*
* 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.TalkingIsland;
import com.l2jmobius.gameserver.enums.ChatType;
import com.l2jmobius.gameserver.model.actor.L2Npc;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.network.NpcStringId;
import ai.AbstractNpcAI;
/**
* Oris AI.
* @author Gladicek
*/
public final class Oris extends AbstractNpcAI
{
// NPCs
private static final int ORIS = 33116;
private Oris()
{
addSpawnId(ORIS);
addStartNpc(ORIS);
addTalkId(ORIS);
}
@Override
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
{
if (event.equals("SOCIAL_ACTION_1"))
{
npc.broadcastSocialAction(6);
startQuestTimer("SOCIAL_ACTION_2", 2500, npc, null);
}
else if (event.equals("SOCIAL_ACTION_2"))
{
npc.broadcastSocialAction(7);
}
else if (event.equals("SPAM_TEXT") && (npc != null))
{
npc.broadcastSay(ChatType.NPC_GENERAL, NpcStringId.I_HAVEN_T_FELT_THIS_GOOD_IN_AGES, 1000);
}
return super.onAdvEvent(event, npc, player);
}
@Override
public String onSpawn(L2Npc npc)
{
npc.setRandomAnimation(false);
startQuestTimer("SOCIAL_ACTION_1", 6500, npc, null, true);
startQuestTimer("SPAM_TEXT", 10000, npc, null, true);
return super.onSpawn(npc);
}
public static void main(String[] args)
{
new Oris();
}
}

View File

@@ -0,0 +1,4 @@
<html><body>Pantheon:<br>
The Airborne Island came crashing down here, but it was the Giants' ruins that got everyone's attention.<br>
Aden hired scholars and workers, and the town was quickly reconstructed as a mishmash of two architectural philosophies.
</body></html>

View File

@@ -0,0 +1,4 @@
<html><body>Pantheon:<br>
Your level is not sufficient for the museum. Come back when you are qualified.<br>
<Button ALIGN=LEFT ICON="QUEST" action="bypass -h npc_%objectId%_Quest">Quest</Button>
</body></html>

View File

@@ -0,0 +1,6 @@
<html><body>Pantheon:<br>
Welcome to the Talking Island! Ask me anything you need to know.<br>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest Pantheon teleport_museum">"I want to go inside the museum."</Button>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest Pantheon 32972-1.html">"Can you tell me about Talking Island?"</Button>
<Button ALIGN=LEFT ICON="QUEST" action="bypass -h npc_%objectId%_Quest">Quest</Button>
</body></html>

View File

@@ -0,0 +1,105 @@
/*
* 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.TalkingIsland.Pantheon;
import com.l2jmobius.gameserver.enums.ChatType;
import com.l2jmobius.gameserver.model.Location;
import com.l2jmobius.gameserver.model.actor.L2Npc;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.model.quest.QuestState;
import com.l2jmobius.gameserver.network.NpcStringId;
import com.l2jmobius.gameserver.network.serverpackets.ExShowScreenMessage;
import ai.AbstractNpcAI;
import quests.Q10320_LetsGoToTheCentralSquare.Q10320_LetsGoToTheCentralSquare;
/**
* Pantheon AI.
* @author Gladicek
*/
public final class Pantheon extends AbstractNpcAI
{
// NPC
private static final int PANTHEON = 32972;
// Location
private static final Location MUSEUM = new Location(-114711, 243911, -7968);
// Misc
private static final int MIN_LEVEL = 20;
private Pantheon()
{
addSpawnId(PANTHEON);
addStartNpc(PANTHEON);
addFirstTalkId(PANTHEON);
addTalkId(PANTHEON);
}
@Override
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
{
String htmltext = null;
switch (event)
{
case "32972-1.html":
{
htmltext = event;
break;
}
case "teleport_museum":
{
if (player.getLevel() < MIN_LEVEL)
{
htmltext = "32972-noteleport.html";
}
else
{
player.teleToLocation(MUSEUM);
}
break;
}
case "TEXT_SPAM":
{
npc.broadcastSay(ChatType.NPC_GENERAL, NpcStringId.IS_IT_BETTER_TO_END_DESTINY_OR_START_DESTINY);
break;
}
}
return htmltext;
}
@Override
public String onFirstTalk(L2Npc npc, L2PcInstance player)
{
final QuestState st = player.getQuestState(Q10320_LetsGoToTheCentralSquare.class.getSimpleName());
if (st == null)
{
showOnScreenMsg(player, NpcStringId.BEGIN_TUTORIAL_QUESTS, ExShowScreenMessage.TOP_CENTER, 4500);
}
return super.onFirstTalk(npc, player);
}
@Override
public String onSpawn(L2Npc npc)
{
startQuestTimer("TEXT_SPAM", 10000, npc, null, true);
return super.onSpawn(npc);
}
public static void main(String[] args)
{
new Pantheon();
}
}

View File

@@ -0,0 +1,9 @@
<html><head><body>Subclass/Dual Class Master Raina:<br>
So you need to <font color="LEVEL">create/reset a subclass</font>?<br>
<font color="af9878">A new class subclass starts at </font><font color="LEVEL">level 40</font><font color="af9878">.<br>
</font><Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest Raina addSubclass">"I'll add a new subclass (create new)."</Button><br>
(<font color="af9878">Change dual classes and your level will be </font><font color="LEVEL">reset to level 40</font><font color="af9878">.)<br>
</font><Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest Raina removeSubclass">"I'll eliminate a subclass and add another one (reset)."</Button><br>
<font color="LEVEL">Maintain your level while changing classes</font><font color="af9878">.<br>
</font><Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest Raina changeSubclass">"I'll change my subclass (requires Subclass Change Certificate)."</Button>
</body></html>

View File

@@ -0,0 +1,7 @@
<html><body>Subclass/Dual Class Master Raina:<br>
I heard that Ertheia are curious people. But a gem that absorbs power... I still can't help thinking that it's really dangerous. You could have died. <br>
But thanks to your efforts, even Ertheia can use the power of the giants now.<br>
But because you're different than the race from the Material Realm, your power will not merge with the giants'. Because they do not mingle, you will not be able to use your power while using the giants' power. Of course, you can use your original power instead of the giants' power anytime you wish.<br>
Now! Would you like to use the power of the giants?<br>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest Raina ertheiaDualClass">"Yes, on with a dual class!"</Button>
</body></html>

View File

@@ -0,0 +1,7 @@
<html><body>Subclass/Dual Class Master Raina:<br>
Hello!<br1>
I will be assisting you with <font color="LEVEL">reawakening an Awakened dual class</font>.<br1>
To reawaken a dual class, you need to have an Awakened dual class. After reawakening, your level will be reduced to level 85, and all the skills you've learned will be forgotten.<br>
(<font color="af9878">Change dual classes and your level will be </font><font color="LEVEL">reset to level 85</font><font color="af9878"></font>).<br>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest Raina reawekenDualclass">"I'll reawaken."</Button>
</body></html>

View File

@@ -0,0 +1,6 @@
<html><body>Subclass/Dual Class Master Raina:<br>
So you want to know about <font color="LEVEL">items designated for a dual class</font>?<br1>
They're for those who grow their dual class powers beyond imaginable limits.<br1>
You can purchase as many as you want, but <font color="LEVEL">you have to be at certain level with your main and dual classes in order to use them</font>.<br>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h npc_%objectId%_multisell 2027">"Let me take a look at the items for dual classes."</Button>
</body></html>

View File

@@ -0,0 +1,6 @@
<html><body> Subclass/Dual Class Master Raina:<br><br>
Hello!<br>
I'm collecting XP Bottles.<br>
I'll give you items if you bring me XP Bottles, how's that?<br>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h npc_%objectId%_multisell 857">"I have XP bottles right here."</Button>
</body> </html>

View File

@@ -0,0 +1,10 @@
<html><body>Subclass/Dual Class Master Raina:<br>
Hello!<br1>
You have a question about subclass or dual class?<br>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest Raina 33491-01.html">"Yeah. How do I create or reset a subclass?"</Button>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest Raina 33491-02.html">"I want to add a dual class." (for Ertheia only)</Button>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest Raina 33491-03.html">"Can I reawaken my Awakened dual class?"</Button>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest Raina 33491-04.html">"So...what are the items for dual classes?" </Button>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest Raina 33491-05.html">"What's with these XP Bottles?"</Button>
<Button ALIGN=LEFT ICON="QUEST" action="bypass -h npc_%objectId%_Quest">Quest</Button>
</body></html>

View File

@@ -0,0 +1,885 @@
/*
* 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.TalkingIsland.Raina;
import static com.l2jmobius.gameserver.model.base.ClassLevel.THIRD;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.EnumMap;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import com.l2jmobius.Config;
import com.l2jmobius.gameserver.data.xml.impl.CategoryData;
import com.l2jmobius.gameserver.data.xml.impl.ClassListData;
import com.l2jmobius.gameserver.data.xml.impl.SkillTreesData;
import com.l2jmobius.gameserver.enums.CategoryType;
import com.l2jmobius.gameserver.enums.Race;
import com.l2jmobius.gameserver.enums.SubclassInfoType;
import com.l2jmobius.gameserver.model.actor.L2Npc;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.model.base.ClassId;
import com.l2jmobius.gameserver.model.base.ClassLevel;
import com.l2jmobius.gameserver.model.base.PlayerClass;
import com.l2jmobius.gameserver.model.base.SubClass;
import com.l2jmobius.gameserver.model.events.EventType;
import com.l2jmobius.gameserver.model.events.ListenerRegisterType;
import com.l2jmobius.gameserver.model.events.annotations.Id;
import com.l2jmobius.gameserver.model.events.annotations.RegisterEvent;
import com.l2jmobius.gameserver.model.events.annotations.RegisterType;
import com.l2jmobius.gameserver.model.events.impl.character.npc.OnNpcMenuSelect;
import com.l2jmobius.gameserver.model.quest.QuestState;
import com.l2jmobius.gameserver.network.SystemMessageId;
import com.l2jmobius.gameserver.network.serverpackets.AcquireSkillList;
import com.l2jmobius.gameserver.network.serverpackets.ExSubjobInfo;
import com.l2jmobius.gameserver.network.serverpackets.NpcHtmlMessage;
import ai.AbstractNpcAI;
import quests.Q10385_RedThreadOfFate.Q10385_RedThreadOfFate;
import quests.Q10472_WindsOfFateEncroachingShadows.Q10472_WindsOfFateEncroachingShadows;
/**
* Raina AI.
* @author St3eT
*/
public final class Raina extends AbstractNpcAI
{
// NPC
private static final int RAINA = 33491;
// Items
private static final int SUBCLASS_CERTIFICATE = 30433;
private static final int CHAOS_POMANDER = 37375;
private final static int ABELIUS_POWER = 32264;
private final static int SAPYROS_POWER = 32265;
private final static int ASHAGEN_POWER = 32266;
private final static int CRANIGG_POWER = 32267;
private final static int SOLTKREIG_POWER = 32268;
private final static int NAVIAROPE_POWER = 32269;
private final static int LEISTER_POWER = 32270;
private final static int LAKCIS_POWER = 32271;
// Misc
private static final Set<PlayerClass> mainSubclassSet;
private static final Set<PlayerClass> neverSubclassed = EnumSet.of(PlayerClass.Overlord, PlayerClass.Warsmith);
private static final Set<PlayerClass> subclasseSet1 = EnumSet.of(PlayerClass.DarkAvenger, PlayerClass.Paladin, PlayerClass.TempleKnight, PlayerClass.ShillienKnight);
private static final Set<PlayerClass> subclasseSet2 = EnumSet.of(PlayerClass.TreasureHunter, PlayerClass.AbyssWalker, PlayerClass.Plainswalker);
private static final Set<PlayerClass> subclasseSet3 = EnumSet.of(PlayerClass.Hawkeye, PlayerClass.SilverRanger, PlayerClass.PhantomRanger);
private static final Set<PlayerClass> subclasseSet4 = EnumSet.of(PlayerClass.Warlock, PlayerClass.ElementalSummoner, PlayerClass.PhantomSummoner);
private static final Set<PlayerClass> subclasseSet5 = EnumSet.of(PlayerClass.Sorceror, PlayerClass.Spellsinger, PlayerClass.Spellhowler);
private static final EnumMap<PlayerClass, Set<PlayerClass>> subclassSetMap = new EnumMap<>(PlayerClass.class);
static
{
final Set<PlayerClass> subclasses = PlayerClass.getSet(null, THIRD);
subclasses.removeAll(neverSubclassed);
mainSubclassSet = subclasses;
subclassSetMap.put(PlayerClass.DarkAvenger, subclasseSet1);
subclassSetMap.put(PlayerClass.Paladin, subclasseSet1);
subclassSetMap.put(PlayerClass.TempleKnight, subclasseSet1);
subclassSetMap.put(PlayerClass.ShillienKnight, subclasseSet1);
subclassSetMap.put(PlayerClass.TreasureHunter, subclasseSet2);
subclassSetMap.put(PlayerClass.AbyssWalker, subclasseSet2);
subclassSetMap.put(PlayerClass.Plainswalker, subclasseSet2);
subclassSetMap.put(PlayerClass.Hawkeye, subclasseSet3);
subclassSetMap.put(PlayerClass.SilverRanger, subclasseSet3);
subclassSetMap.put(PlayerClass.PhantomRanger, subclasseSet3);
subclassSetMap.put(PlayerClass.Warlock, subclasseSet4);
subclassSetMap.put(PlayerClass.ElementalSummoner, subclasseSet4);
subclassSetMap.put(PlayerClass.PhantomSummoner, subclasseSet4);
subclassSetMap.put(PlayerClass.Sorceror, subclasseSet5);
subclassSetMap.put(PlayerClass.Spellsinger, subclasseSet5);
subclassSetMap.put(PlayerClass.Spellhowler, subclasseSet5);
}
private static final Map<CategoryType, Integer> classCloak = new HashMap<>();
{
classCloak.put(CategoryType.SIGEL_GROUP, 30310); // Abelius Cloak
classCloak.put(CategoryType.TYRR_GROUP, 30311); // Sapyros Cloak Grade
classCloak.put(CategoryType.OTHELL_GROUP, 30312); // Ashagen Cloak Grade
classCloak.put(CategoryType.YUL_GROUP, 30313); // Cranigg Cloak Grade
classCloak.put(CategoryType.FEOH_GROUP, 30314); // Soltkreig Cloak Grade
classCloak.put(CategoryType.ISS_GROUP, 30315); // Naviarope Cloak Grade
classCloak.put(CategoryType.WYNN_GROUP, 30316); // Leister Cloak Grade
classCloak.put(CategoryType.AEORE_GROUP, 30317); // Laksis Cloak Grade
}
private static final List<PlayerClass> dualClassList = new ArrayList<>();
{
dualClassList.addAll(Arrays.asList(PlayerClass.sigelPhoenixKnight, PlayerClass.sigelHellKnight, PlayerClass.sigelEvasTemplar, PlayerClass.sigelShilenTemplar));
dualClassList.addAll(Arrays.asList(PlayerClass.tyrrDuelist, PlayerClass.tyrrDreadnought, PlayerClass.tyrrTitan, PlayerClass.tyrrGrandKhavatari, PlayerClass.tyrrDoombringer));
dualClassList.addAll(Arrays.asList(PlayerClass.othellAdventurer, PlayerClass.othellWindRider, PlayerClass.othellGhostHunter, PlayerClass.othellFortuneSeeker));
dualClassList.addAll(Arrays.asList(PlayerClass.yulSagittarius, PlayerClass.yulMoonlightSentinel, PlayerClass.yulGhostSentinel, PlayerClass.yulTrickster));
dualClassList.addAll(Arrays.asList(PlayerClass.feohArchmage, PlayerClass.feohSoultaker, PlayerClass.feohMysticMuse, PlayerClass.feoStormScreamer, PlayerClass.feohSoulHound));
dualClassList.addAll(Arrays.asList(PlayerClass.issHierophant, PlayerClass.issSwordMuse, PlayerClass.issSpectralDancer, PlayerClass.issDoomcryer));
dualClassList.addAll(Arrays.asList(PlayerClass.wynnArcanaLord, PlayerClass.wynnElementalMaster, PlayerClass.wynnSpectralMaster));
dualClassList.addAll(Arrays.asList(PlayerClass.aeoreCardinal, PlayerClass.aeoreEvaSaint, PlayerClass.aeoreShillienSaint));
}
// @formatter:off
private static final int[] REAWAKEN_PRICE =
{
100_000_000, 90_000_000, 80_000_000, 70_000_000, 60_000_000, 50_000_000, 40_000_000, 30_000_000, 20_000_000, 10_000_000
};
// @formatter:on
private Raina()
{
addStartNpc(RAINA);
addFirstTalkId(RAINA);
addTalkId(RAINA);
}
@Override
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
{
String htmltext = null;
switch (event)
{
case "33491-01.html":
case "33491-02.html":
case "33491-03.html":
case "33491-04.html":
case "33491-05.html":
case "reawakenCancel.html":
{
htmltext = event;
break;
}
case "addSubclass":
{
if (player.isTransformed())
{
htmltext = "noTransform.html";
}
else if (player.hasSummon())
{
htmltext = "noSummon.html";
}
else if (player.getRace() == Race.ERTHEIA)
{
htmltext = "noErtheia.html";
}
else if (!haveDoneQuest(player, false))
{
htmltext = "noQuest.html";
}
else if (!hasAllSubclassLeveled(player) || (player.getTotalSubClasses() >= Config.MAX_SUBCLASS))
{
htmltext = "addFailed.html";
}
else if (!player.isInventoryUnder90(true) || (player.getWeightPenalty() >= 2))
{
htmltext = "inventoryLimit.html";
}
else
{
final Set<PlayerClass> availSubs = getAvailableSubClasses(player);
final StringBuilder sb = new StringBuilder();
final NpcHtmlMessage html = getNpcHtmlMessage(player, npc, "subclassList.html");
if ((availSubs == null) || availSubs.isEmpty())
{
break;
}
for (PlayerClass subClass : availSubs)
{
if (subClass != null)
{
final int classId = subClass.ordinal();
final int npcStringId = 11170000 + classId;
sb.append("<fstring p1=\"0\" p2=\"" + classId + "\">" + npcStringId + "</fstring>");
}
}
html.replace("%subclassList%", sb.toString());
player.sendPacket(html);
}
break;
}
case "removeSubclass":
{
if (player.isTransformed())
{
htmltext = "noTransform.html";
}
else if (player.hasSummon())
{
htmltext = "noSummon.html";
}
else if (player.getRace() == Race.ERTHEIA)
{
htmltext = "noErtheia.html";
}
else if (!player.isInventoryUnder90(true) || (player.getWeightPenalty() >= 2))
{
htmltext = "inventoryLimit.html";
}
else if (player.getSubClasses().isEmpty())
{
htmltext = "noSubChange.html";
}
else
{
final StringBuilder sb = new StringBuilder();
final NpcHtmlMessage html = getNpcHtmlMessage(player, npc, "subclassRemoveList.html");
for (SubClass subClass : player.getSubClasses().values())
{
if (subClass != null)
{
final int classId = subClass.getClassId();
final int npcStringId = 11170000 + classId;
sb.append("<fstring p1=\"2\" p2=\"" + subClass.getClassIndex() + "\">" + npcStringId + "</fstring>");
}
}
html.replace("%removeList%", sb.toString());
player.sendPacket(html);
}
break;
}
case "changeSubclass": // TODO: Finish me
{
if (player.isTransformed())
{
htmltext = "noTransform.html";
}
else if (player.hasSummon())
{
htmltext = "noSummon.html";
}
else if (player.getRace() == Race.ERTHEIA)
{
htmltext = "noErtheia.html";
}
else if (player.getSubClasses().isEmpty())
{
htmltext = "noSubChange.html";
}
else if (!hasQuestItems(player, SUBCLASS_CERTIFICATE))
{
htmltext = "noCertificate.html";
}
else
{
player.sendMessage("Not done yet.");
}
break;
}
case "ertheiaDualClass":
{
// TODO: Maybe html is different when you have 85lvl but you haven't completed quest
if (player.hasDualClass() || !haveDoneQuest(player, true))
{
htmltext = "addDualClassErtheiaFailed.html";
}
else
{
htmltext = "addDualClassErtheia.html";
}
break;
}
case "addDualClass_SIGEL_GROUP":
case "addDualClass_TYRR_GROUP":
case "addDualClass_OTHELL_GROUP":
case "addDualClass_YUL_GROUP":
case "addDualClass_FEOH_GROUP":
case "addDualClass_ISS_GROUP":
case "addDualClass_WYNN_GROUP":
case "addDualClass_AEORE_GROUP":
{
final CategoryType cType = CategoryType.valueOf(event.replace("addDualClass_", ""));
if (cType == null)
{
_log.warning(getClass().getSimpleName() + ": Cannot parse CategoryType, event: " + event);
}
final StringBuilder sb = new StringBuilder();
final NpcHtmlMessage html = getNpcHtmlMessage(player, npc, "addDualClassErtheiaList.html");
for (PlayerClass dualClasses : getDualClasses(player, cType))
{
if (dualClasses != null)
{
sb.append("<button value=\"" + ClassListData.getInstance().getClass(dualClasses.ordinal()).getClassName() + "\" action=\"bypass -h menu_select?ask=6&reply=" + dualClasses.ordinal() + "\" width=\"200\" height=\"31\" back=\"L2UI_CT1.HtmlWnd_DF_Awake_Down\" fore=\"L2UI_CT1.HtmlWnd_DF_Awake\"><br>");
}
}
html.replace("%dualclassList%", sb.toString());
player.sendPacket(html);
break;
}
case "reawekenDualclass":
{
if (player.isTransformed())
{
htmltext = "noTransform.html";
}
else if (player.hasSummon())
{
htmltext = "noSummon.html";
}
else if (!player.hasDualClass() || !player.isDualClassActive() || (player.getClassId().level() != ClassLevel.AWAKEN.ordinal()))
{
htmltext = "reawakenNoDual.html";
}
else
{
final NpcHtmlMessage html = getNpcHtmlMessage(player, npc, "reawaken.html");
final int index = player.getLevel() > 94 ? REAWAKEN_PRICE.length - 1 : player.getLevel() - 85;
html.replace("%price%", REAWAKEN_PRICE[index]);
player.sendPacket(html);
}
break;
}
case "reawakenDualclassConfirm":
{
final int index = player.getLevel() > 94 ? REAWAKEN_PRICE.length - 1 : player.getLevel() - 85;
if (player.isTransformed())
{
htmltext = "noTransform.html";
}
else if (player.hasSummon())
{
htmltext = "noSummon.html";
}
else if (!player.hasDualClass() || !player.isDualClassActive() || (player.getClassId().level() != ClassLevel.AWAKEN.ordinal()))
{
htmltext = "reawakenNoDual.html";
}
else if ((player.getAdena() < REAWAKEN_PRICE[index]) || !hasQuestItems(player, getCloakId(player)))
{
final NpcHtmlMessage html = getNpcHtmlMessage(player, npc, "reawakenNoFee.html");
html.replace("%price%", REAWAKEN_PRICE[index]);
player.sendPacket(html);
}
else
{
final NpcHtmlMessage html = getNpcHtmlMessage(player, npc, "reawakenList.html");
player.sendPacket(html);
}
break;
}
case "reawaken_SIGEL_GROUP":
case "reawaken_TYRR_GROUP":
case "reawaken_OTHELL_GROUP":
case "reawaken_YUL_GROUP":
case "reawaken_FEOH_GROUP":
case "reawaken_ISS_GROUP":
case "reawaken_WYNN_GROUP":
case "reawaken_AEORE_GROUP":
{
final CategoryType cType = CategoryType.valueOf(event.replace("reawaken_", ""));
if (cType == null)
{
_log.warning(getClass().getSimpleName() + ": Cannot parse CategoryType, event: " + event);
}
final StringBuilder sb = new StringBuilder();
final NpcHtmlMessage html = getNpcHtmlMessage(player, npc, "reawakenClassList.html");
for (PlayerClass dualClasses : getDualClasses(player, cType))
{
if (dualClasses != null)
{
sb.append("<button value=\"" + ClassListData.getInstance().getClass(dualClasses.ordinal()).getClassName() + "\" action=\"bypass -h menu_select?ask=5&reply=" + dualClasses.ordinal() + "\" width=\"200\" height=\"31\" back=\"L2UI_CT1.HtmlWnd_DF_Awake_Down\" fore=\"L2UI_CT1.HtmlWnd_DF_Awake\"><br>");
}
}
html.replace("%dualclassList%", sb.toString());
player.sendPacket(html);
break;
}
}
return htmltext;
}
@RegisterEvent(EventType.ON_NPC_MENU_SELECT)
@RegisterType(ListenerRegisterType.NPC)
@Id(RAINA)
public final void OnNpcMenuSelect(OnNpcMenuSelect event)
{
final L2PcInstance player = event.getTalker();
final L2Npc npc = event.getNpc();
final int ask = event.getAsk();
switch (ask)
{
case 0: // Add subclass confirm menu
{
final int classId = event.getReply();
final StringBuilder sb = new StringBuilder();
final NpcHtmlMessage html = getNpcHtmlMessage(player, npc, "addConfirm.html");
if (!isValidNewSubClass(player, classId))
{
return;
}
final int npcStringId = 11170000 + classId;
sb.append("<fstring p1=\"1\" p2=\"" + classId + "\">" + npcStringId + "</fstring>");
html.replace("%confirmButton%", sb.toString());
player.sendPacket(html);
break;
}
case 1: // Add subclass
{
final int classId = event.getReply();
if (!isValidNewSubClass(player, classId))
{
return;
}
if (!player.addSubClass(classId, player.getTotalSubClasses() + 1, false))
{
return;
}
player.setActiveClass(player.getTotalSubClasses());
player.sendPacket(new ExSubjobInfo(player, SubclassInfoType.NEW_SLOT_USED));
player.sendPacket(SystemMessageId.THE_NEW_SUBCLASS_HAS_BEEN_ADDED);
player.sendPacket(getNpcHtmlMessage(player, npc, "addSuccess.html"));
break;
}
case 2: // Remove (change) subclass list
{
final int subclassIndex = event.getReply();
final Set<PlayerClass> availSubs = getAvailableSubClasses(player);
final StringBuilder sb = new StringBuilder();
final NpcHtmlMessage html = getNpcHtmlMessage(player, npc, "removeSubclassList.html");
if ((availSubs == null) || availSubs.isEmpty())
{
return;
}
for (PlayerClass subClass : availSubs)
{
if (subClass != null)
{
final int classId = subClass.ordinal();
final int npcStringId = 11170000 + classId;
sb.append("<fstring p1=\"3\" p2=\"" + classId + "\">" + npcStringId + "</fstring>");
}
}
npc.getVariables().set("SUBCLASS_INDEX_" + player.getObjectId(), subclassIndex);
html.replace("%subclassList%", sb.toString());
player.sendPacket(html);
break;
}
case 3: // Remove (change) subclass confirm menu
{
final int classId = event.getReply();
final int classIndex = npc.getVariables().getInt("SUBCLASS_INDEX_" + player.getObjectId(), -1);
if (classIndex < 0)
{
return;
}
final StringBuilder sb = new StringBuilder();
final NpcHtmlMessage html = getNpcHtmlMessage(player, npc, "addConfirm2.html");
final int npcStringId = 11170000 + classId;
sb.append("<fstring p1=\"4\" p2=\"" + classId + "\">" + npcStringId + "</fstring>");
html.replace("%confirmButton%", sb.toString());
player.sendPacket(html);
break;
}
case 4: // Remove (change) subclass
{
final int classId = event.getReply();
final int classIndex = npc.getVariables().getInt("SUBCLASS_INDEX_" + player.getObjectId(), -1);
if (classIndex < 0)
{
return;
}
if (player.modifySubClass(classIndex, classId, false))
{
player.abortCast();
player.stopAllEffectsExceptThoseThatLastThroughDeath();
player.stopAllEffectsNotStayOnSubclassChange();
player.stopCubics();
player.setActiveClass(classIndex);
player.sendPacket(new ExSubjobInfo(player, SubclassInfoType.CLASS_CHANGED));
player.sendPacket(getNpcHtmlMessage(player, npc, "addSuccess.html"));
player.sendPacket(SystemMessageId.THE_NEW_SUBCLASS_HAS_BEEN_ADDED);
}
break;
}
case 5: // Reawaken (change dual class)
{
final int classId = event.getReply();
if (player.isTransformed() || player.hasSummon() || (!player.hasDualClass() || !player.isDualClassActive() || (player.getClassId().level() != ClassLevel.AWAKEN.ordinal())))
{
break;
}
// Validating classId
if (!getDualClasses(player, null).contains(PlayerClass.values()[classId]))
{
break;
}
final int index = player.getLevel() > 94 ? REAWAKEN_PRICE.length - 1 : player.getLevel() - 85;
if ((player.getAdena() < REAWAKEN_PRICE[index]) || !hasQuestItems(player, getCloakId(player)))
{
final NpcHtmlMessage html = getNpcHtmlMessage(player, npc, "reawakenNoFee.html");
html.replace("%price%", REAWAKEN_PRICE[index]);
player.sendPacket(html);
break;
}
player.reduceAdena((getClass().getSimpleName() + "_Reawaken"), REAWAKEN_PRICE[index], npc, true);
takeItems(player, getCloakId(player), 1);
final int classIndex = player.getClassIndex();
if (player.modifySubClass(classIndex, classId, true))
{
player.abortCast();
player.stopAllEffectsExceptThoseThatLastThroughDeath();
player.stopAllEffectsNotStayOnSubclassChange();
player.stopCubics();
player.setActiveClass(classIndex);
player.sendPacket(new ExSubjobInfo(player, SubclassInfoType.CLASS_CHANGED));
player.sendPacket(getNpcHtmlMessage(player, npc, "reawakenSuccess.html"));
SkillTreesData.getInstance().cleanSkillUponAwakening(player);
player.sendPacket(new AcquireSkillList(player));
player.sendSkillList();
addPowerItem(player);
}
break;
}
case 6: // Add dual class for ertheia
{
final int classId = event.getReply();
if (player.isTransformed() || player.hasSummon() || player.hasDualClass())
{
break;
}
final QuestState qs = player.getQuestState(Q10472_WindsOfFateEncroachingShadows.class.getSimpleName());
if ((qs == null) || !qs.isCompleted())
{
break;
}
// Validating classId
if (!getDualClasses(player, null).contains(PlayerClass.values()[classId]))
{
break;
}
if (player.addSubClass(classId, player.getTotalSubClasses() + 1, true))
{
player.setActiveClass(player.getTotalSubClasses());
player.sendPacket(new ExSubjobInfo(player, SubclassInfoType.NEW_SLOT_USED));
player.sendPacket(SystemMessageId.THE_NEW_SUBCLASS_HAS_BEEN_ADDED);
player.sendPacket(getNpcHtmlMessage(player, npc, "addSuccess.html"));
SkillTreesData.getInstance().cleanSkillUponAwakening(player);
player.sendPacket(new AcquireSkillList(player));
player.sendSkillList();
addPowerItem(player);
giveItems(player, CHAOS_POMANDER, 2);
}
break;
}
}
}
private void addPowerItem(L2PcInstance player)
{
int itemId = ABELIUS_POWER; // Sigel
if (player.isInCategory(CategoryType.TYRR_GROUP))
{
itemId = SAPYROS_POWER;
}
else if (player.isInCategory(CategoryType.OTHELL_GROUP))
{
itemId = ASHAGEN_POWER;
}
else if (player.isInCategory(CategoryType.YUL_GROUP))
{
itemId = CRANIGG_POWER;
}
else if (player.isInCategory(CategoryType.FEOH_GROUP))
{
itemId = SOLTKREIG_POWER;
}
else if (player.isInCategory(CategoryType.ISS_GROUP))
{
itemId = NAVIAROPE_POWER;
}
else if (player.isInCategory(CategoryType.WYNN_GROUP))
{
itemId = LEISTER_POWER;
}
else if (player.isInCategory(CategoryType.AEORE_GROUP))
{
itemId = LAKCIS_POWER;
}
giveItems(player, itemId, 1);
}
/**
* Returns list of available subclasses Base class and already used subclasses removed
* @param player
* @return
*/
private Set<PlayerClass> getAvailableSubClasses(L2PcInstance player)
{
final int currentBaseId = player.getBaseClass();
final ClassId baseCID = ClassId.getClassId(currentBaseId);
final int baseClassId = (baseCID.level() > 2) ? baseCID.getParent().ordinal() : currentBaseId;
final Set<PlayerClass> availSubs = getSubclasses(player, baseClassId);
if ((availSubs != null) && !availSubs.isEmpty())
{
for (PlayerClass pclass : availSubs)
{
// scan for already used subclasses
final int availClassId = pclass.ordinal();
final ClassId cid = ClassId.getClassId(availClassId);
for (SubClass subList : player.getSubClasses().values())
{
final ClassId subId = ClassId.getClassId(subList.getClassId());
if (subId.equalsOrChildOf(cid))
{
availSubs.remove(cid);
break;
}
}
}
}
return availSubs;
}
private boolean haveDoneQuest(L2PcInstance player, boolean isErtheia)
{
final QuestState qs = isErtheia ? player.getQuestState(Q10472_WindsOfFateEncroachingShadows.class.getSimpleName()) : player.getQuestState(Q10385_RedThreadOfFate.class.getSimpleName());
return (((qs != null) && qs.isCompleted()) || Config.ALT_GAME_SUBCLASS_WITHOUT_QUESTS);
}
/**
* Check new subclass classId for validity. Base class not added into allowed subclasses.
* @param player
* @param classId
* @return
*/
private boolean isValidNewSubClass(L2PcInstance player, int classId)
{
final ClassId cid = ClassId.values()[classId];
ClassId subClassId;
for (SubClass subList : player.getSubClasses().values())
{
subClassId = ClassId.values()[subList.getClassId()];
if (subClassId.equalsOrChildOf(cid))
{
return false;
}
}
// get player base class
final int currentBaseId = player.getBaseClass();
final ClassId baseCID = ClassId.getClassId(currentBaseId);
// we need 2nd occupation ID
final int baseClassId = baseCID.level() > 2 ? baseCID.getParent().ordinal() : currentBaseId;
final Set<PlayerClass> availSubs = getSubclasses(player, baseClassId);
if ((availSubs == null) || availSubs.isEmpty())
{
return false;
}
boolean found = false;
for (PlayerClass pclass : availSubs)
{
if (pclass.ordinal() == classId)
{
found = true;
break;
}
}
return found;
}
private boolean hasAllSubclassLeveled(L2PcInstance player)
{
boolean leveled = true;
for (SubClass sub : player.getSubClasses().values())
{
if ((sub != null) && (sub.getLevel() < 75))
{
leveled = false;
}
}
return leveled;
}
public final List<PlayerClass> getAvailableDualclasses(L2PcInstance player)
{
final List<PlayerClass> dualClasses = new ArrayList<>();
for (PlayerClass playerClass : PlayerClass.values())
{
if (!playerClass.isOfRace(Race.ERTHEIA) && playerClass.isOfLevel(ClassLevel.AWAKEN) && (playerClass.ordinal() != player.getClassId().getId()))
{
dualClasses.add(playerClass);
}
}
return dualClasses;
}
private List<PlayerClass> getDualClasses(L2PcInstance player, CategoryType cType)
{
final List<PlayerClass> tempList = new ArrayList<>();
final int baseClassId = player.getBaseClass();
final int dualClassId = player.getClassId().getId();
for (PlayerClass temp : dualClassList)
{
if ((temp.ordinal() != baseClassId) && (temp.ordinal() != dualClassId) && ((cType == null) || CategoryData.getInstance().isInCategory(cType, temp.ordinal())))
{
tempList.add(temp);
}
}
return tempList;
}
public final Set<PlayerClass> getSubclasses(L2PcInstance player, int classId)
{
Set<PlayerClass> subclasses = null;
final PlayerClass pClass = PlayerClass.values()[classId];
if ((pClass.getLevel() == ClassLevel.THIRD) || (pClass.getLevel() == ClassLevel.FOURTH))
{
subclasses = EnumSet.copyOf(mainSubclassSet);
subclasses.remove(pClass);
subclasses.removeAll(PlayerClass.getSet(Race.ERTHEIA, THIRD));
if (player.getRace() == Race.KAMAEL)
{
if (player.getAppearance().getSex())
{
subclasses.remove(PlayerClass.femaleSoulbreaker);
}
else
{
subclasses.remove(PlayerClass.maleSoulbreaker);
}
if (!player.getSubClasses().containsKey(2) || (player.getSubClasses().get(2).getLevel() < 75))
{
subclasses.remove(PlayerClass.inspector);
}
}
else
{
// Only Kamael can take Kamael classes as subclasses.
subclasses.removeAll(PlayerClass.getSet(Race.KAMAEL, THIRD));
}
final Set<PlayerClass> unavailableClasses = subclassSetMap.get(pClass);
if (unavailableClasses != null)
{
subclasses.removeAll(unavailableClasses);
}
}
if (subclasses != null)
{
final ClassId currClassId = ClassId.getClassId(player.getClassId().getId());
for (PlayerClass tempClass : subclasses)
{
final ClassId tempClassId = ClassId.getClassId(tempClass.ordinal());
if (currClassId.equalsOrChildOf(tempClassId))
{
subclasses.remove(tempClass);
}
}
}
return subclasses;
}
private NpcHtmlMessage getNpcHtmlMessage(L2PcInstance player, L2Npc npc, String fileName)
{
final NpcHtmlMessage html = new NpcHtmlMessage(npc.getObjectId());
final String text = getHtm(player.getHtmlPrefix(), fileName);
if (text == null)
{
_log.info("Cannot find HTML file for " + Raina.class.getSimpleName() + " AI: " + fileName);
return null;
}
html.setHtml(text);
return html;
}
private int getCloakId(L2PcInstance player)
{
CategoryType catType = null;
if (player.isInCategory(CategoryType.SIGEL_GROUP))
{
catType = CategoryType.SIGEL_GROUP;
}
else if (player.isInCategory(CategoryType.TYRR_GROUP))
{
catType = CategoryType.TYRR_GROUP;
}
else if (player.isInCategory(CategoryType.OTHELL_GROUP))
{
catType = CategoryType.OTHELL_GROUP;
}
else if (player.isInCategory(CategoryType.YUL_GROUP))
{
catType = CategoryType.YUL_GROUP;
}
else if (player.isInCategory(CategoryType.FEOH_GROUP))
{
catType = CategoryType.FEOH_GROUP;
}
else if (player.isInCategory(CategoryType.ISS_GROUP))
{
catType = CategoryType.ISS_GROUP;
}
else if (player.isInCategory(CategoryType.WYNN_GROUP))
{
catType = CategoryType.WYNN_GROUP;
}
else if (player.isInCategory(CategoryType.AEORE_GROUP))
{
catType = CategoryType.AEORE_GROUP;
}
return classCloak.get(catType);
}
public static void main(String[] args)
{
new Raina();
}
}

View File

@@ -0,0 +1,6 @@
<html><body>Subclass/Dual Class Master Raina:<br><br>
The choice is no easy one.<br>
The new subclass will be a level 40, 2nd-transfer class. <br>
Are you sure you want to go ahead with this decision? <br>
%confirmButton%
</body></html>

View File

@@ -0,0 +1,6 @@
<html><body>Subclass/Dual Class Master Raina:<br><br>
The choice is no easy one.<br>
<font="LEVEL">The new subclass will have none of the skill enchants or the skills you learned through codices. Think carefully.</font><br>
Are you sure you want to go ahead with this decision? <br>
%confirmButton%
</body></html>

View File

@@ -0,0 +1,12 @@
<html><body>Subclass/Dual Class Master Raina:<br>
Which class would you like as your Dual Class?<br1>
<font color="LEVEL">(A Level 85 Dual Class will be added, and the 3rd transfer skills provided will be based on Human class.)</font><br>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest Raina addDualClass_SIGEL_GROUP">"I want choose a the Sigel Knight class."</Button>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest Raina addDualClass_TYRR_GROUP">"I want choose a the Tyrr Warrior class."</Button>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest Raina addDualClass_OTHELL_GROUP">"I want choose a the Othell Rogue class."</Button>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest Raina addDualClass_YUL_GROUP">"I want choose a the Yul Archer class."</Button>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest Raina addDualClass_FEOH_GROUP">"I want choose a the Feoh Wizard class."</Button>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest Raina addDualClass_ISS_GROUP">"I want choose a the Iss Enchanter class."</Button>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest Raina addDualClass_WYNN_GROUP">"I want choose a the Wynn Summoner class."</Button>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest Raina addDualClass_AEORE_GROUP">"I want choose a the Aeore Healer class."</Button>
</body></html>

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