Sync with L2JServer Jan 24th 2015.
This commit is contained in:
9
trunk/dist/game/data/scripts/ai/npc/Raina/33491-01.html
vendored
Normal file
9
trunk/dist/game/data/scripts/ai/npc/Raina/33491-01.html
vendored
Normal 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>
|
7
trunk/dist/game/data/scripts/ai/npc/Raina/33491-02.html
vendored
Normal file
7
trunk/dist/game/data/scripts/ai/npc/Raina/33491-02.html
vendored
Normal 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>
|
7
trunk/dist/game/data/scripts/ai/npc/Raina/33491-03.html
vendored
Normal file
7
trunk/dist/game/data/scripts/ai/npc/Raina/33491-03.html
vendored
Normal 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>
|
6
trunk/dist/game/data/scripts/ai/npc/Raina/33491-04.html
vendored
Normal file
6
trunk/dist/game/data/scripts/ai/npc/Raina/33491-04.html
vendored
Normal 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>
|
6
trunk/dist/game/data/scripts/ai/npc/Raina/33491-05.html
vendored
Normal file
6
trunk/dist/game/data/scripts/ai/npc/Raina/33491-05.html
vendored
Normal 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>
|
10
trunk/dist/game/data/scripts/ai/npc/Raina/33491.html
vendored
Normal file
10
trunk/dist/game/data/scripts/ai/npc/Raina/33491.html
vendored
Normal 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>
|
866
trunk/dist/game/data/scripts/ai/npc/Raina/Raina.java
vendored
Normal file
866
trunk/dist/game/data/scripts/ai/npc/Raina/Raina.java
vendored
Normal file
@@ -0,0 +1,866 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2015 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack 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.
|
||||
*
|
||||
* L2J DataPack 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.npc.Raina;
|
||||
|
||||
import static com.l2jserver.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 java.util.logging.Level;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.Config;
|
||||
import com.l2jserver.gameserver.cache.HtmCache;
|
||||
import com.l2jserver.gameserver.data.xml.impl.CategoryData;
|
||||
import com.l2jserver.gameserver.data.xml.impl.ClassListData;
|
||||
import com.l2jserver.gameserver.data.xml.impl.SkillTreesData;
|
||||
import com.l2jserver.gameserver.enums.CategoryType;
|
||||
import com.l2jserver.gameserver.enums.Race;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.model.base.ClassId;
|
||||
import com.l2jserver.gameserver.model.base.ClassLevel;
|
||||
import com.l2jserver.gameserver.model.base.PlayerClass;
|
||||
import com.l2jserver.gameserver.model.base.SubClass;
|
||||
import com.l2jserver.gameserver.model.events.EventType;
|
||||
import com.l2jserver.gameserver.model.events.ListenerRegisterType;
|
||||
import com.l2jserver.gameserver.model.events.annotations.Id;
|
||||
import com.l2jserver.gameserver.model.events.annotations.RegisterEvent;
|
||||
import com.l2jserver.gameserver.model.events.annotations.RegisterType;
|
||||
import com.l2jserver.gameserver.model.events.impl.character.npc.OnNpcMenuSelect;
|
||||
import com.l2jserver.gameserver.model.quest.QuestState;
|
||||
import com.l2jserver.gameserver.network.SystemMessageId;
|
||||
import com.l2jserver.gameserver.network.serverpackets.AcquireSkillList;
|
||||
import com.l2jserver.gameserver.network.serverpackets.NpcHtmlMessage;
|
||||
|
||||
/**
|
||||
* 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 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()
|
||||
{
|
||||
super(Raina.class.getSimpleName(), "ai/npc");
|
||||
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 "reawakenCancel.html":
|
||||
{
|
||||
htmltext = event;
|
||||
break;
|
||||
}
|
||||
case "addSubclass":
|
||||
{
|
||||
if (player.isTransformed())
|
||||
{
|
||||
htmltext = "noTransform.html";
|
||||
break;
|
||||
}
|
||||
else if (player.hasSummon())
|
||||
{
|
||||
htmltext = "noSummon.html";
|
||||
break;
|
||||
}
|
||||
else if (player.getRace() == Race.ERTHEIA)
|
||||
{
|
||||
htmltext = "noErtheia.html";
|
||||
break;
|
||||
}
|
||||
else if (!haveDoneQuest(player) && Config.ALT_GAME_SUBCLASS_WITHOUT_QUESTS && !player.isGM())
|
||||
{
|
||||
htmltext = "noQuest.html";
|
||||
break;
|
||||
}
|
||||
else if (!hasAllSubclassLeveled(player) || (player.getTotalSubClasses() >= Config.MAX_SUBCLASS))
|
||||
{
|
||||
htmltext = "addFailed.html";
|
||||
break;
|
||||
}
|
||||
else if (!player.isInventoryUnder90(true) || (player.getWeightPenalty() >= 2))
|
||||
{
|
||||
htmltext = "inventoryLimit.html";
|
||||
break;
|
||||
}
|
||||
|
||||
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";
|
||||
break;
|
||||
}
|
||||
else if (player.hasSummon())
|
||||
{
|
||||
htmltext = "noSummon.html";
|
||||
break;
|
||||
}
|
||||
else if (player.getRace() == Race.ERTHEIA)
|
||||
{
|
||||
htmltext = "noErtheia.html";
|
||||
break;
|
||||
}
|
||||
else if (!player.isInventoryUnder90(true) || (player.getWeightPenalty() >= 2))
|
||||
{
|
||||
htmltext = "inventoryLimit.html";
|
||||
break;
|
||||
}
|
||||
else if (player.getSubClasses().isEmpty())
|
||||
{
|
||||
htmltext = "noSubChange.html";
|
||||
break;
|
||||
}
|
||||
|
||||
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":
|
||||
{
|
||||
if (player.isTransformed())
|
||||
{
|
||||
htmltext = "noTransform.html";
|
||||
break;
|
||||
}
|
||||
else if (player.hasSummon())
|
||||
{
|
||||
htmltext = "noSummon.html";
|
||||
break;
|
||||
}
|
||||
else if (player.getRace() == Race.ERTHEIA)
|
||||
{
|
||||
htmltext = "noErtheia.html";
|
||||
break;
|
||||
}
|
||||
else if (player.getSubClasses().isEmpty())
|
||||
{
|
||||
htmltext = "noSubChange.html";
|
||||
break;
|
||||
}
|
||||
else if (!hasQuestItems(player, SUBCLASS_CERTIFICATE))
|
||||
{
|
||||
htmltext = "noCertificate.html";
|
||||
break;
|
||||
}
|
||||
|
||||
player.sendMessage("Not done yet.");
|
||||
break;
|
||||
}
|
||||
case "ertheiaDualClass":
|
||||
{
|
||||
if ((player.getRace() != Race.ERTHEIA) || (player.getLevel() < 85) || player.hasDualClass())
|
||||
{
|
||||
htmltext = "addDualClassErtheiaFailed.html";
|
||||
break;
|
||||
}
|
||||
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.log(Level.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";
|
||||
break;
|
||||
}
|
||||
else if (player.hasSummon())
|
||||
{
|
||||
htmltext = "noSummon.html";
|
||||
break;
|
||||
}
|
||||
else if (!player.hasDualClass() || !player.isDualClassActive() || (player.getClassId().level() != ClassLevel.AWAKEN.ordinal()))
|
||||
{
|
||||
htmltext = "reawakenNoDual.html";
|
||||
break;
|
||||
}
|
||||
|
||||
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";
|
||||
break;
|
||||
}
|
||||
else if (player.hasSummon())
|
||||
{
|
||||
htmltext = "noSummon.html";
|
||||
break;
|
||||
}
|
||||
else if (!player.hasDualClass() || !player.isDualClassActive() || (player.getClassId().level() != ClassLevel.AWAKEN.ordinal()))
|
||||
{
|
||||
htmltext = "reawakenNoDual.html";
|
||||
break;
|
||||
}
|
||||
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);
|
||||
break;
|
||||
}
|
||||
|
||||
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.log(Level.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;
|
||||
}
|
||||
|
||||
final NpcHtmlMessage html = getNpcHtmlMessage(player, npc, "addSuccess.html");
|
||||
player.setActiveClass(player.getTotalSubClasses());
|
||||
player.sendPacket(SystemMessageId.THE_NEW_SUBCLASS_HAS_BEEN_ADDED);
|
||||
player.sendPacket(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);
|
||||
|
||||
final NpcHtmlMessage html = getNpcHtmlMessage(player, npc, "addSuccess.html");
|
||||
|
||||
player.sendPacket(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);
|
||||
|
||||
final NpcHtmlMessage html = getNpcHtmlMessage(player, npc, "reawakenSuccess.html");
|
||||
player.sendPacket(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())
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
// Validating classId
|
||||
if (!getDualClasses(player, null).contains(PlayerClass.values()[classId]))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (player.addSubClass(classId, player.getTotalSubClasses() + 1, true))
|
||||
{
|
||||
final NpcHtmlMessage html = getNpcHtmlMessage(player, npc, "addSuccess.html");
|
||||
player.setActiveClass(player.getTotalSubClasses());
|
||||
player.sendPacket(SystemMessageId.THE_NEW_SUBCLASS_HAS_BEEN_ADDED);
|
||||
player.sendPacket(html);
|
||||
SkillTreesData.getInstance().cleanSkillUponAwakening(player);
|
||||
player.sendPacket(new AcquireSkillList(player));
|
||||
player.sendSkillList();
|
||||
addPowerItem(player);
|
||||
}
|
||||
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);
|
||||
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)
|
||||
{
|
||||
final QuestState qs = player.getQuestState("Q10385_RedThreadOfFate"); // TODO: Replace with class name
|
||||
return qs == null ? false : qs.isCompleted();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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(this);
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
Set<PlayerClass> unavailableClasses = subclassSetMap.get(this);
|
||||
|
||||
if (unavailableClasses != null)
|
||||
{
|
||||
subclasses.removeAll(unavailableClasses);
|
||||
}
|
||||
}
|
||||
return subclasses;
|
||||
}
|
||||
|
||||
private NpcHtmlMessage getNpcHtmlMessage(L2PcInstance player, L2Npc npc, String fileName)
|
||||
{
|
||||
final NpcHtmlMessage html = new NpcHtmlMessage(npc.getObjectId());
|
||||
html.setHtml(HtmCache.getInstance().getHtm(player.getHtmlPrefix(), "data/scripts/ai/npc/Raina/" + fileName));
|
||||
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();
|
||||
}
|
||||
}
|
6
trunk/dist/game/data/scripts/ai/npc/Raina/addConfirm.html
vendored
Normal file
6
trunk/dist/game/data/scripts/ai/npc/Raina/addConfirm.html
vendored
Normal 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>
|
6
trunk/dist/game/data/scripts/ai/npc/Raina/addConfirm2.html
vendored
Normal file
6
trunk/dist/game/data/scripts/ai/npc/Raina/addConfirm2.html
vendored
Normal 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>
|
12
trunk/dist/game/data/scripts/ai/npc/Raina/addDualClassErtheia.html
vendored
Normal file
12
trunk/dist/game/data/scripts/ai/npc/Raina/addDualClassErtheia.html
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
<html><body>Subclass/Dual Class Master Raina:<br><br>
|
||||
So, into which class would you like to Reawaken?<br>
|
||||
Remember that if you proceed, you will go back to <font color="LEVEL">Lv. 85, and all your skills will be reset.</font><br>
|
||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest Raina addDualClass_SIGEL_GROUP">"I will change to the Knight class."</Button>
|
||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest Raina addDualClass_TYRR_GROUP">"I will change to the Warrior class."</Button>
|
||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest Raina addDualClass_OTHELL_GROUP">"I will change to the Rogue class."</Button>
|
||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest Raina addDualClass_YUL_GROUP">"I will change to the Archer class."</Button>
|
||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest Raina addDualClass_FEOH_GROUP">"I will change to the Wizard class."</Button>
|
||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest Raina addDualClass_ISS_GROUP">"I will change to the Enchanter class."</Button>
|
||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest Raina addDualClass_WYNN_GROUP">"I will change to the Summoner class."</Button>
|
||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest Raina addDualClass_AEORE_GROUP">"I will change to the Healer class."</Button>
|
||||
</body></html>
|
5
trunk/dist/game/data/scripts/ai/npc/Raina/addDualClassErtheiaFailed.html
vendored
Normal file
5
trunk/dist/game/data/scripts/ai/npc/Raina/addDualClassErtheiaFailed.html
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
<html><body>Subclass/Dual Class Master Raina:<br><br>
|
||||
You do not meet the conditions to add a dual class.<br>
|
||||
Come back when you're ready, or ask for something else.<br>
|
||||
(Only Ertheia characters Lv. 85 or above may add a dual class once.)
|
||||
</body></html>
|
9
trunk/dist/game/data/scripts/ai/npc/Raina/addDualClassErtheiaList.html
vendored
Normal file
9
trunk/dist/game/data/scripts/ai/npc/Raina/addDualClassErtheiaList.html
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
<html><body scroll="no">
|
||||
<table border=0 cellpadding=0 cellspacing=0 width=292 height=358 background="L2UI_CH3.refinewnd_back_Pattern">
|
||||
<tr><td valign="top" align="center"><br><br><br><br>
|
||||
These are the classes available to you.<br1>
|
||||
You must choose which you want to be.<br><br>
|
||||
%dualclassList%
|
||||
</td></tr>
|
||||
</table>
|
||||
</body></html>
|
8
trunk/dist/game/data/scripts/ai/npc/Raina/addFailed.html
vendored
Normal file
8
trunk/dist/game/data/scripts/ai/npc/Raina/addFailed.html
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
<html><body>Subclass/Dual Class Master Raina:<br><br>
|
||||
Sorry, but you're not qualified to add a subclass.<br1>
|
||||
To add a new subclass, you need the following qualifications:<br>
|
||||
First, <font color="LEVEL">you've completed the 'Red Thread of Fate' quest</font>. If you want to get on that, let me know.<br>
|
||||
Second, <font color="LEVEL">your current class has done the 2nd class transfer, and all your subclass levels are 75 or higher</font>. For example, if your subclasses are Temple Knight and Silver Ranger, they must both be level 75 for you to add a third subclass.<br>
|
||||
Third, you may only have <font color="LEVEL">up to 3 subclasses</font>, I'm afraid.<br>
|
||||
Got it?
|
||||
</body></html>
|
5
trunk/dist/game/data/scripts/ai/npc/Raina/addSuccess.html
vendored
Normal file
5
trunk/dist/game/data/scripts/ai/npc/Raina/addSuccess.html
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
<html><body>Subclass/Dual Class Master Raina:<br><br>
|
||||
Congratulations!<br>
|
||||
Your new subclass has been added.<br>
|
||||
I look forward to your future endeavors with your new subclass!<br>
|
||||
</body></html>
|
3
trunk/dist/game/data/scripts/ai/npc/Raina/inventoryLimit.html
vendored
Normal file
3
trunk/dist/game/data/scripts/ai/npc/Raina/inventoryLimit.html
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
<html><body>Subclass/Dual Class Master Raina:<br><br>
|
||||
You need inventory space and free weight to create or renew a subclass. Go free up your weight and inventory to less than 80%, and I'll see what I can do.
|
||||
</body></html>
|
5
trunk/dist/game/data/scripts/ai/npc/Raina/noCertificate.html
vendored
Normal file
5
trunk/dist/game/data/scripts/ai/npc/Raina/noCertificate.html
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
<html><body>Subclass/Dual Class Master Raina:<br><br>
|
||||
You need a Subclass Change Certificate in order to receive the power of the gods. This was given to heroes long before Shilen's destructive rampages came about, so you can't find new ones anymore.<br>
|
||||
But if you have the certificate, talk to me again as a subclass ready to receive the power of the gods.<br>
|
||||
<font color="af9878">But a dual class isn't ready to receive the power of the gods, so I can't change classes for that.</font>
|
||||
</body></html>
|
4
trunk/dist/game/data/scripts/ai/npc/Raina/noErtheia.html
vendored
Normal file
4
trunk/dist/game/data/scripts/ai/npc/Raina/noErtheia.html
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
<html><body>Subclass/Dual Class Master Raina:<br><br>
|
||||
Ertheia cannot add or modify subclasses.<br>
|
||||
Please talk to me when you're ready to add a dual class.
|
||||
</body></html>
|
4
trunk/dist/game/data/scripts/ai/npc/Raina/noQuest.html
vendored
Normal file
4
trunk/dist/game/data/scripts/ai/npc/Raina/noQuest.html
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
<html><body>Subclass/Dual Class Master Raina:<br><br>
|
||||
You haven't completed the 'Red Thread of Fate' quest yet.<br>
|
||||
To create a subclass, you have to <font color="LEVEL">complete the 'Red Thread of Fate' quest</font>. If you want to work on the quest, let me know.
|
||||
</body></html>
|
4
trunk/dist/game/data/scripts/ai/npc/Raina/noSubChange.html
vendored
Normal file
4
trunk/dist/game/data/scripts/ai/npc/Raina/noSubChange.html
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
<html><body>Subclass/Dual Class Master Raina:<br><br>
|
||||
You don't have a subclass to change.<br>
|
||||
Make a subclass.
|
||||
</body></html>
|
4
trunk/dist/game/data/scripts/ai/npc/Raina/noSummon.html
vendored
Normal file
4
trunk/dist/game/data/scripts/ai/npc/Raina/noSummon.html
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
<html><body>Subclass/Dual Class Master Raina:<br><br>
|
||||
You cannot create a new subclass<br>
|
||||
when there is a pet or servitor.
|
||||
</body></html>
|
4
trunk/dist/game/data/scripts/ai/npc/Raina/noTransform.html
vendored
Normal file
4
trunk/dist/game/data/scripts/ai/npc/Raina/noTransform.html
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
<html><body>Subclass/Dual Class Master Raina:<br><br>
|
||||
I cannot create a new subclass while you're transformed.<br>
|
||||
Change back to your original form, then talk to me again.
|
||||
</body></html>
|
5
trunk/dist/game/data/scripts/ai/npc/Raina/onlyErtheia.html
vendored
Normal file
5
trunk/dist/game/data/scripts/ai/npc/Raina/onlyErtheia.html
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
<html><body>Subclass/Dual Class Master Raina:<br><br>
|
||||
You do not meet the conditions to add a dual class.<br>
|
||||
Come back when you're ready, or ask for something else.<br>
|
||||
(Only Ertheia characters Lv. 85 or above may add a dual class once.)
|
||||
</body></html>
|
10
trunk/dist/game/data/scripts/ai/npc/Raina/reawaken.html
vendored
Normal file
10
trunk/dist/game/data/scripts/ai/npc/Raina/reawaken.html
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
<html><body>Subclass/Dual Class Master Raina:<br><br>
|
||||
In order to reawaken your dual class,<br>
|
||||
<font color="LEVEL">you need the cloak you received when you first awakened it,<br>
|
||||
and some %price% Adena</font> to pay the fee.<br>
|
||||
Upon reawakening, zou will lose zour current<br>
|
||||
abilities, but gain new powers is exchange. You will be reducted to <font color="LEVEL">level 85, and all your skills will be reset.</font> You can choose the class you want, but <font color="LEVEL">you cannot receive powers from the same class as your main class</font>.<br>
|
||||
<font color="af9878">(After reawakening, the 3rd skills provided will be based on human classes.)</font><br>
|
||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest Raina reawakenDualclassConfirm">"I'll reawaken."</Button>
|
||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest Raina reawakenCancel.html">"I will think about it."</Button>
|
||||
</body></html>
|
5
trunk/dist/game/data/scripts/ai/npc/Raina/reawakenCancel.html
vendored
Normal file
5
trunk/dist/game/data/scripts/ai/npc/Raina/reawakenCancel.html
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
<html><body>Subclass/Dual Class Master Raina:<br><br>
|
||||
I see.<br>
|
||||
Make a carful decision because you will lose the power you have, to get new power.<br>
|
||||
When you make up your mind, come back to me.
|
||||
</body></html>
|
9
trunk/dist/game/data/scripts/ai/npc/Raina/reawakenClassList.html
vendored
Normal file
9
trunk/dist/game/data/scripts/ai/npc/Raina/reawakenClassList.html
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
<html><body scroll="no">
|
||||
<table border=0 cellpadding=0 cellspacing=0 width=292 height=358 background="L2UI_CH3.refinewnd_back_Pattern">
|
||||
<tr><td valign="top" align="center"><br><br><br><br>
|
||||
These are the classes available to you.<br1>
|
||||
You must choose which you want to be.<br><br>
|
||||
%dualclassList%
|
||||
</td></tr>
|
||||
</table>
|
||||
</body></html>
|
12
trunk/dist/game/data/scripts/ai/npc/Raina/reawakenList.html
vendored
Normal file
12
trunk/dist/game/data/scripts/ai/npc/Raina/reawakenList.html
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
<html><body>Subclass/Dual Class Master Raina:<br><br>
|
||||
So, into which class would you like to Reawaken?<br>
|
||||
Remember that if you proceed, you will go back to <font color="LEVEL">Lv. 85, and all your skills will be reset.</font><br>
|
||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest Raina reawaken_SIGEL_GROUP">"I will change to the Knight class."</Button>
|
||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest Raina reawaken_TYRR_GROUP">"I will change to the Warrior class."</Button>
|
||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest Raina reawaken_OTHELL_GROUP">"I will change to the Rogue class."</Button>
|
||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest Raina reawaken_YUL_GROUP">"I will change to the Archer class."</Button>
|
||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest Raina reawaken_FEOH_GROUP">"I will change to the Wizard class."</Button>
|
||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest Raina reawaken_ISS_GROUP">"I will change to the Enchanter class."</Button>
|
||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest Raina reawaken_WYNN_GROUP">"I will change to the Summoner class."</Button>
|
||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest Raina reawaken_AEORE_GROUP">"I will change to the Healer class."</Button>
|
||||
</body></html>
|
6
trunk/dist/game/data/scripts/ai/npc/Raina/reawakenNoDual.html
vendored
Normal file
6
trunk/dist/game/data/scripts/ai/npc/Raina/reawakenNoDual.html
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
<html><body>Subclass/Dual Class Master Raina:<br><br>
|
||||
You don't look like a Awakened dual class.<br>
|
||||
If you want to Reawaken, you must be an <font color="LEVEL">Awakened dual class</font>.<br>
|
||||
Please come find me when you have Awakened as a dual class.<br><br>
|
||||
(You can become a specialized Awakened class through Hardin or the Giant's stone statue at the Reliquary of the Giants.)
|
||||
</body></html>
|
6
trunk/dist/game/data/scripts/ai/npc/Raina/reawakenNoFee.html
vendored
Normal file
6
trunk/dist/game/data/scripts/ai/npc/Raina/reawakenNoFee.html
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
<html><body>Subclass/Dual Class Master Raina:<br><br>
|
||||
To change your dual class,<br>
|
||||
<font color="LEVEL">you need the cloak you received when you awakened your dual class,<br>
|
||||
and %price% Adena</font> for a fee.<br>
|
||||
Please come back with everything you need.
|
||||
</body></html>
|
7
trunk/dist/game/data/scripts/ai/npc/Raina/removeSubclassList.html
vendored
Normal file
7
trunk/dist/game/data/scripts/ai/npc/Raina/removeSubclassList.html
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
<html><body>Subclass/Dual Class Master Raina:<br><br>
|
||||
Which subclass would you like to change to?<br>
|
||||
Please select a subclass from the list below.<br>
|
||||
<font color="LEVEL">The new subclas will be a level 40, 2nd-transfer class with none of the skill enchants or the skills you learned through codices. Think carefully.</font><br>
|
||||
Also, dual classes can't be reset.<br>
|
||||
%subclassList%
|
||||
</body></html>
|
4
trunk/dist/game/data/scripts/ai/npc/Raina/subclassList.html
vendored
Normal file
4
trunk/dist/game/data/scripts/ai/npc/Raina/subclassList.html
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
<html><body>Subclass/Dual Class Master Raina:<br><br>
|
||||
Select a Subclass.<br><br>
|
||||
%subclassList%
|
||||
</body></html>
|
7
trunk/dist/game/data/scripts/ai/npc/Raina/subclassRemoveList.html
vendored
Normal file
7
trunk/dist/game/data/scripts/ai/npc/Raina/subclassRemoveList.html
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
<html><body>Subclass/Dual Class Master Raina:<br><br>
|
||||
Which subclass would you like to change to?<br>
|
||||
Please select a subclass from the list below.<br>
|
||||
<font color="LEVEL">The new subclas will be a level 40, 2nd-transfer class with none of the skill enchants or the skills you learned through codices. Think carefully.</font><br>
|
||||
Also, dual classes can't be reset.<br>
|
||||
%removeList%
|
||||
</body></html>
|
Reference in New Issue
Block a user