Advertisement
kgkotzamanidis

Custom SubClassMaster

Mar 1st, 2024 (edited)
240
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 27.16 KB | Source Code | 0 0
  1. [Java section]
  2. [SubClassMaster.java]
  3. /*
  4.  * Copyright (C) 2024 k_gkotzamanidis
  5.  *
  6.  * This program is free software: you can redistribute it and/or modify
  7.  * it under the terms of the GNU General Public License as published by
  8.  * the Free Software Foundation, either version 3 of the License, or
  9.  * (at your option) any later version.
  10.  *
  11.  * This program is distributed in the hope that it will be useful,
  12.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  * GNU General Public License for more details.
  15.  *
  16.  * You should have received a copy of the GNU General Public License
  17.  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  18.  */
  19. package ai.others.SubClass;
  20.  
  21. import java.util.EnumMap;
  22. import java.util.EnumSet;
  23. import java.util.Set;
  24. import java.util.logging.Logger;
  25. import java.util.stream.Collectors;
  26.  
  27. import ai.AbstractNpcAI;
  28. import gr.l2jmobius.Config;
  29. import gr.l2jmobius.gameserver.data.xml.CategoryData;
  30. import gr.l2jmobius.gameserver.data.xml.SkillData;
  31. import gr.l2jmobius.gameserver.enums.CategoryType;
  32. import gr.l2jmobius.gameserver.enums.ClassId;
  33. import gr.l2jmobius.gameserver.enums.Race;
  34. import gr.l2jmobius.gameserver.enums.SubclassInfoType;
  35. import gr.l2jmobius.gameserver.model.actor.Npc;
  36. import gr.l2jmobius.gameserver.model.actor.Player;
  37. import gr.l2jmobius.gameserver.model.events.EventType;
  38. import gr.l2jmobius.gameserver.model.events.ListenerRegisterType;
  39. import gr.l2jmobius.gameserver.model.events.annotations.Id;
  40. import gr.l2jmobius.gameserver.model.events.annotations.RegisterEvent;
  41. import gr.l2jmobius.gameserver.model.events.annotations.RegisterType;
  42. import gr.l2jmobius.gameserver.model.events.impl.creature.npc.OnNpcMenuSelect;
  43. import gr.l2jmobius.gameserver.model.holders.SubClassHolder;
  44. import gr.l2jmobius.gameserver.model.olympiad.OlympiadManager;
  45. import gr.l2jmobius.gameserver.model.skill.Skill;
  46. import gr.l2jmobius.gameserver.model.zone.ZoneId;
  47. import gr.l2jmobius.gameserver.network.SystemMessageId;
  48. import gr.l2jmobius.gameserver.network.serverpackets.AcquireSkillList;
  49. import gr.l2jmobius.gameserver.network.serverpackets.ExSubjobInfo;
  50. import gr.l2jmobius.gameserver.network.serverpackets.NpcHtmlMessage;
  51. import gr.l2jmobius.gameserver.network.serverpackets.SystemMessage;
  52. import gr.l2jmobius.gameserver.network.serverpackets.ability.ExAcquireAPSkillList;
  53.  
  54. /**
  55.  * @author k_gkotzamanidis
  56.  */
  57.  
  58. public class SubClassMaster extends AbstractNpcAI{
  59.     private static final Logger LOGGER = Logger.getLogger(SubClassMaster.class.getName());
  60.    
  61.     private static final int ANATOLIUS = 900105;
  62.     private static final int CLIENT_CLASS_BUTTON = 11170000;
  63.     private static final int IDENTITY_CRISIS_SKILL_ID = 1570;
  64.    
  65.     private static final Set<ClassId> mainSubClassSet;
  66.     private static final Set<ClassId> neverSubClassed = EnumSet.of(ClassId.OVERLORD, ClassId.WARSMITH);
  67.     private static final Set<ClassId> SubClassSet1 = EnumSet.of(ClassId.DARK_AVENGER, ClassId.PALADIN, ClassId.TEMPLE_KNIGHT, ClassId.SHILLIEN_KNIGHT);
  68.     private static final Set<ClassId> SubClassSet2 = EnumSet.of(ClassId.TREASURE_HUNTER, ClassId.ABYSS_WALKER, ClassId.PLAINS_WALKER);
  69.     private static final Set<ClassId> SubClassSet3 = EnumSet.of(ClassId.HAWKEYE, ClassId.SILVER_RANGER, ClassId.PHANTOM_RANGER);
  70.     private static final Set<ClassId> SubClassSet4 = EnumSet.of(ClassId.WARLOCK, ClassId.ELEMENTAL_SUMMONER, ClassId.PHANTOM_SUMMONER);
  71.     private static final Set<ClassId> SubClassSet5 = EnumSet.of(ClassId.SORCERER, ClassId.SPELLSINGER, ClassId.SPELLHOWLER);
  72.     private static final EnumMap<ClassId, Set<ClassId>> SubClassSetMap = new EnumMap<>(ClassId.class);
  73.    
  74.     static{
  75.         final Set<ClassId> subclasses = CategoryData.getInstance().getCategoryByType(CategoryType.THIRD_CLASS_GROUP).stream().map(ClassId::getClassId).collect(Collectors.toSet());
  76.         subclasses.removeAll(neverSubClassed);
  77.         mainSubClassSet = subclasses;
  78.         SubClassSetMap.put(ClassId.DARK_AVENGER, SubClassSet1);
  79.         SubClassSetMap.put(ClassId.PALADIN, SubClassSet1);
  80.         SubClassSetMap.put(ClassId.TEMPLE_KNIGHT, SubClassSet1);
  81.         SubClassSetMap.put(ClassId.SHILLIEN_KNIGHT, SubClassSet1);
  82.         SubClassSetMap.put(ClassId.TREASURE_HUNTER, SubClassSet2);
  83.         SubClassSetMap.put(ClassId.ABYSS_WALKER, SubClassSet2);
  84.         SubClassSetMap.put(ClassId.PLAINS_WALKER, SubClassSet2);
  85.         SubClassSetMap.put(ClassId.HAWKEYE, SubClassSet3);
  86.         SubClassSetMap.put(ClassId.SILVER_RANGER, SubClassSet3);
  87.         SubClassSetMap.put(ClassId.PHANTOM_RANGER, SubClassSet3);
  88.         SubClassSetMap.put(ClassId.WARLOCK, SubClassSet4);
  89.         SubClassSetMap.put(ClassId.ELEMENTAL_SUMMONER, SubClassSet4);
  90.         SubClassSetMap.put(ClassId.PHANTOM_SUMMONER, SubClassSet4);
  91.         SubClassSetMap.put(ClassId.SORCERER, SubClassSet5);
  92.         SubClassSetMap.put(ClassId.SPELLSINGER, SubClassSet5);
  93.         SubClassSetMap.put(ClassId.SPELLHOWLER, SubClassSet5);
  94.     }
  95.    
  96.     public static void main(String[] args){
  97.         new SubClassMaster();
  98.     }
  99.    
  100.     private SubClassMaster(){
  101.         addStartNpc(ANATOLIUS);
  102.         addFirstTalkId(ANATOLIUS);
  103.         addTalkId(ANATOLIUS);
  104.         LOGGER.info("SubClassMaster: The Custom NPC has been Initiallize with ID 900105.");
  105.     }
  106.    
  107.     @Override
  108.     public String onFirstTalk(Npc npc, Player player){
  109.         return "Welcome.html";
  110.     }
  111.    
  112.     @Override
  113.     public String onAdvEvent(String event, Npc npc, Player player){
  114.         String htmltext = null;
  115.        
  116.         switch (event){
  117.             case "main":{
  118.                 htmltext = "SubClassMaster.html";
  119.                 break;
  120.             }
  121.             case "addSubclass":{
  122.                 if (checkRules(npc, player, true)){
  123.                     break;
  124.                 }else{
  125.                     final Set<ClassId> availSubs = getAvailableSubClasses(player);
  126.                     final StringBuilder sb = new StringBuilder();
  127.                     final NpcHtmlMessage html = getNpcHtmlMessage(player, npc, "SubClassList.html");
  128.                    
  129.                     if ((availSubs == null) || availSubs.isEmpty()) {
  130.                         break;
  131.                     }
  132.                    
  133.                     for (ClassId subClass : availSubs){
  134.                         if (subClass != null){
  135.                             final int classId = subClass.getId();
  136.                             final int npcStringId = CLIENT_CLASS_BUTTON + classId;
  137.                            
  138.                             sb.append("<fstring p1=\"0\" p2=\"" + classId + "\">" + npcStringId + "</fstring>");
  139.                         }
  140.                     }
  141.                    
  142.                     html.replace("%subclass_list%", sb.toString());
  143.                     player.sendPacket(html);
  144.                     break;
  145.                 }
  146.             }
  147.             case "removeSubclass":{
  148.                 if (checkRules(npc, player, false)){
  149.                     break;
  150.                 }else{
  151.                     final StringBuilder sb = new StringBuilder();
  152.                     final NpcHtmlMessage html = getNpcHtmlMessage(player, npc, "SubClassList.html");
  153.                    
  154.                     for (SubClassHolder subClass : player.getSubClasses().values()) {
  155.                         if (subClass != null) {
  156.                             final int classId = subClass.getClassId();
  157.                             final int npcStringId = CLIENT_CLASS_BUTTON + classId;
  158.                        
  159.                             sb.append("<fstring p1=\"2\" p2=\"" + subClass.getClassIndex() + "\">" + npcStringId + "</fstring>");
  160.                         }
  161.                     }
  162.                     html.replace("%subclass_list%", sb.toString());
  163.                     player.sendPacket(html);
  164.                     break;
  165.                 }
  166.             }
  167.             case "changeSubclass":{
  168.                 if (checkRules(npc, player, false)){
  169.                     break;
  170.                 }else{
  171.                     final StringBuilder sb = new StringBuilder();
  172.                     final NpcHtmlMessage html = getNpcHtmlMessage(player, npc, "SubClassList.html");
  173.                    
  174.                     for (SubClassHolder subClass : player.getSubClasses().values()){
  175.                         if (subClass != null){
  176.                             final int classId = subClass.getClassId();
  177.                             final int npcStringId = CLIENT_CLASS_BUTTON + classId;
  178.                        
  179.                             if (subClass.getClassIndex() == player.getClassIndex()){
  180.                                 sb.append("<fstring p1=\"5\" p2=\"" + 0 + "\">" + CLIENT_CLASS_BUTTON + "</fstring>");
  181.                             }else{
  182.                                 sb.append("<fstring p1=\"5\" p2=\"" + subClass.getClassIndex() + "\">" + npcStringId + "</fstring>");
  183.                             }
  184.                         }
  185.                     }
  186.                     html.replace("%subclass_list%", sb.toString());
  187.                     player.sendPacket(html);
  188.                     break;
  189.                 }
  190.             }
  191.         }
  192.         return htmltext;
  193.     }
  194.    
  195.     @RegisterEvent(EventType.ON_NPC_MENU_SELECT)
  196.     @RegisterType(ListenerRegisterType.NPC)
  197.     @Id(ANATOLIUS)
  198.     public void onNpcMenuSelect(OnNpcMenuSelect event){
  199.         final Player player = event.getTalker();
  200.         final Npc npc = event.getNpc();
  201.         final int ask = event.getAsk();
  202.        
  203.         switch (ask){
  204.             /** Here the confirm button take the SubClass! */
  205.             case 0:{
  206.                 final int classId = event.getReply();
  207.                 final StringBuilder sb = new StringBuilder();
  208.                 final NpcHtmlMessage html = getNpcHtmlMessage(player, npc, "SubClassConfirmAdd.html");
  209.                
  210.                 if (!isValidNewSubClass(player, classId)){
  211.                     return;
  212.                 }
  213.                
  214.                 final int npcStringId = CLIENT_CLASS_BUTTON + classId;
  215.                 sb.append("<fstring p1=\"1\" p2=\"" + classId + "\">" + npcStringId + "</fstring>");
  216.                 html.replace("%confirm_add%", sb.toString());
  217.                 player.sendPacket(html);
  218.                 break;
  219.             }
  220.             /** Here you give the SubClass from Case 0 while press it */
  221.             case 1:{
  222.                 final int classId = event.getReply();
  223.                
  224.                 if (!isValidNewSubClass(player, classId)){
  225.                     return;
  226.                 }
  227.                 if (!player.addSubClass(classId, player.getTotalSubClasses() + 1, false)){
  228.                     return;
  229.                 }
  230.                  
  231.                 player.setActiveClass(player.getTotalSubClasses());
  232.                 player.sendPacket(new ExSubjobInfo(player, SubclassInfoType.NEW_SLOT_USED));
  233.                 final SystemMessage sm = new SystemMessage(SystemMessageId.THE_NEW_DUAL_CLASS_S1_HAS_BEEN_ADDED_CONGRATS);
  234.                 sm.addItemName(player.getActiveClass());
  235.                 player.sendPacket(sm);
  236.                 player.sendPacket(getNpcHtmlMessage(player, npc, "SubClassSuccess.html"));
  237.                
  238.                 final Skill identityCrisis = SkillData.getInstance().getSkill(IDENTITY_CRISIS_SKILL_ID, 1);
  239.                 if (identityCrisis != null) {
  240.                     identityCrisis.applyEffects(player, player);
  241.                 }
  242.                 break;
  243.             }
  244.             /** Here take the Subclass index to change with a new! */
  245.             case 2:{
  246.                 final int subclassIndex = event.getReply();
  247.                 final Set<ClassId> availSubs = getAvailableSubClasses(player);
  248.                 final StringBuilder sb = new StringBuilder();
  249.                 final NpcHtmlMessage html = getNpcHtmlMessage(player, npc, "SubClassList.html");
  250.                
  251.                 if ((availSubs == null) || availSubs.isEmpty()) {
  252.                     return;
  253.                 }
  254.                
  255.                 for (ClassId subClass : availSubs){
  256.                     if (subClass != null){
  257.                         final int classId = subClass.getId();
  258.                         final int npcStringId = CLIENT_CLASS_BUTTON + classId;
  259.                        
  260.                         sb.append("<fstring p1=\"3\" p2=\"" + classId + "\">" + npcStringId + "</fstring>");
  261.                     }
  262.                 }
  263.                 npc.getVariables().set("SUBCLASS_INDEX_" + player.getObjectId(), subclassIndex);
  264.                 html.replace("%subclass_list%", sb.toString());
  265.                 player.sendPacket(html);
  266.                 break;
  267.             }
  268.             case 3:{
  269.                 final int classId = event.getReply();
  270.                 final int classIndex = npc.getVariables().getInt("SUBCLASS_INDEX_" + player.getObjectId(), -1);
  271.                
  272.                 if (classIndex < 0){
  273.                     return;
  274.                 }
  275.                
  276.                 final StringBuilder sb = new StringBuilder();
  277.                 final NpcHtmlMessage html = getNpcHtmlMessage(player, npc, "SubClassConfirmRemove.html");
  278.                 final int npcStringId = CLIENT_CLASS_BUTTON + classId;
  279.                 sb.append("<fstring p1=\"4\" p2=\"" + classId + "\">" + npcStringId + "</fstring>");
  280.                 html.replace("%confirm_remove%", sb.toString());
  281.                 player.sendPacket(html);
  282.                 break;
  283.             }
  284.             case 4:{
  285.                 final int classId = event.getReply();
  286.                 final int classIndex = npc.getVariables().getInt("SUBCLASS_INDEX_" + player.getObjectId(), -1);
  287.                
  288.                 if (classIndex < 0){
  289.                     return;
  290.                 }
  291.                
  292.                 if (player.modifySubClass(classIndex, classId, false)){
  293.                     player.abortCast();
  294.                     player.stopAllEffectsExceptThoseThatLastThroughDeath();
  295.                     player.stopAllEffects();
  296.                     player.stopCubics();
  297.                     player.setActiveClass(classIndex);
  298.                     player.sendPacket(new ExSubjobInfo(player, SubclassInfoType.CLASS_CHANGED));
  299.                     player.sendPacket(getNpcHtmlMessage(player, npc, "SubClassSuccess.html"));
  300.                     final SystemMessage sm = new SystemMessage(SystemMessageId.THE_NEW_DUAL_CLASS_S1_HAS_BEEN_ADDED_CONGRATS);
  301.                     sm.addItemName(player.getActiveClass());
  302.                     player.sendPacket(sm);
  303.                    
  304.                     final Skill identityCrisis = SkillData.getInstance().getSkill(IDENTITY_CRISIS_SKILL_ID, 1);
  305.                     if (identityCrisis != null) {
  306.                         identityCrisis.applyEffects(player, player);
  307.                     }
  308.                 }
  309.                 break;
  310.             }
  311.             case 5:{
  312.                 final int subclassIndex = event.getReply();
  313.                 final int activeClass = player.getClassId().getId();
  314.                
  315.                 player.setActiveClass(subclassIndex);
  316.                
  317.                 final SystemMessage msg = new SystemMessage(SystemMessageId.YOU_HAVE_SUCCESSFULLY_SWITCHED_S1_TO_S2);
  318.                 msg.addClassId(activeClass);
  319.                 msg.addClassId(player.getClassId().getId());
  320.                 player.sendPacket(msg);
  321.  
  322.                 player.updateSymbolSealSkills();
  323.                 player.broadcastUserInfo();
  324.                 player.sendStorageMaxCount();
  325.                 player.sendPacket(new AcquireSkillList(player));
  326.                 player.sendPacket(new ExSubjobInfo(player, SubclassInfoType.CLASS_CHANGED));
  327.                 player.sendPacket(getNpcHtmlMessage(player, npc, "SubClassSuccess.html"));
  328.                 player.sendPacket(new ExAcquireAPSkillList(player));
  329.                
  330.                 final Skill identityCrisis = SkillData.getInstance().getSkill(IDENTITY_CRISIS_SKILL_ID, 1);
  331.                 if (identityCrisis != null) {
  332.                     identityCrisis.applyEffects(player, player);
  333.                 }
  334.                
  335.                 break;
  336.             }
  337.         }
  338.     }
  339.    
  340.     private Set<ClassId> getAvailableSubClasses(Player player) {
  341.         final int currentBaseId = player.getBaseClass();
  342.         final ClassId baseCID = ClassId.getClassId(currentBaseId);
  343.         final int baseClassId = (CategoryData.getInstance().isInCategory(CategoryType.FOURTH_CLASS_GROUP, baseCID.getId()) || CategoryData.getInstance().isInCategory(CategoryType.FIFTH_CLASS_GROUP, baseCID.getId()) || CategoryData.getInstance().isInCategory(CategoryType.SIXTH_CLASS_GROUP, baseCID.getId())) ? baseCID.getParent().getId() : currentBaseId;
  344.         final Set<ClassId> availSubs = getSubclasses(player, baseClassId);
  345.         if ((availSubs != null) && !availSubs.isEmpty()) {
  346.             for (ClassId pclass : availSubs) {
  347.                 // scan for already used subclasses
  348.                 final int availClassId = pclass.getId();
  349.                 final ClassId cid = ClassId.getClassId(availClassId);
  350.                 for (SubClassHolder subList : player.getSubClasses().values()) {
  351.                     final ClassId subId = ClassId.getClassId(subList.getClassId());
  352.                     if (subId.equalsOrChildOf(cid)) {
  353.                         availSubs.remove(cid);
  354.                         break;
  355.                     }
  356.                 }
  357.             }
  358.         }
  359.         return availSubs;
  360.     }
  361.    
  362.     private boolean isValidNewSubClass(Player player, int classId) {
  363.         final ClassId cid = ClassId.getClassId(classId);
  364.         ClassId subClassId;
  365.         for (SubClassHolder subList : player.getSubClasses().values()) {
  366.             subClassId = ClassId.getClassId(subList.getClassId());
  367.             if (subClassId.equalsOrChildOf(cid)) {
  368.                 return false;
  369.             }
  370.         }
  371.  
  372.         // get player base class
  373.         final int currentBaseId = player.getBaseClass();
  374.         final ClassId baseCID = ClassId.getClassId(currentBaseId);
  375.  
  376.         // we need 2nd occupation ID
  377.         final int baseClassId = (CategoryData.getInstance().isInCategory(CategoryType.FOURTH_CLASS_GROUP, baseCID.getId()) || CategoryData.getInstance().isInCategory(CategoryType.FIFTH_CLASS_GROUP, baseCID.getId()) || CategoryData.getInstance().isInCategory(CategoryType.SIXTH_CLASS_GROUP, baseCID.getId())) ? baseCID.getParent().getId() : currentBaseId;
  378.         final Set<ClassId> availSubs = getSubclasses(player, baseClassId);
  379.         if ((availSubs == null) || availSubs.isEmpty()) {
  380.             return false;
  381.         }
  382.  
  383.         boolean found = false;
  384.         for (ClassId pclass : availSubs) {
  385.             if (pclass.getId() == classId) {
  386.                 found = true;
  387.                 break;
  388.             }
  389.         }
  390.         return found;
  391.     }
  392.    
  393.     public final Set<ClassId> getSubclasses(Player player, int classId) {
  394.         Set<ClassId> subclasses = null;
  395.         final ClassId pClass = ClassId.getClassId(classId);
  396.         if (CategoryData.getInstance().isInCategory(CategoryType.THIRD_CLASS_GROUP, classId) || (CategoryData.getInstance().isInCategory(CategoryType.FOURTH_CLASS_GROUP, classId))) {
  397.             subclasses = EnumSet.copyOf(mainSubClassSet);
  398.             subclasses.remove(pClass);
  399.  
  400.             // Ertheia classes cannot be subclassed and only Kamael can take Kamael classes as subclasses.
  401.             for (ClassId cid : ClassId.values()) {
  402.                 if ((cid.getRace() == Race.ERTHEIA) || ((cid.getRace() == Race.KAMAEL) && (player.getRace() != Race.KAMAEL))) {
  403.                     subclasses.remove(cid);
  404.                 }
  405.             }
  406.  
  407.             if (player.getRace() == Race.KAMAEL) {
  408.                 if (player.getAppearance().isFemale()) {
  409.                     subclasses.remove(ClassId.MALE_SOULBREAKER);
  410.                 } else {
  411.                     subclasses.remove(ClassId.FEMALE_SOULBREAKER);
  412.                 }
  413.  
  414.                 if (!player.getSubClasses().containsKey(2) || (player.getSubClasses().get(2).getLevel() < 75)) {
  415.                     subclasses.remove(ClassId.INSPECTOR);
  416.                 }
  417.             }
  418.  
  419.             final Set<ClassId> unavailableClasses = SubClassSetMap.get(pClass);
  420.             if (unavailableClasses != null) {
  421.                 subclasses.removeAll(unavailableClasses);
  422.             }
  423.         }
  424.  
  425.         if (subclasses != null) {
  426.             final ClassId currClassId = player.getClassId();
  427.             for (ClassId tempClass : subclasses) {
  428.                 if (currClassId.equalsOrChildOf(tempClass)) {
  429.                     subclasses.remove(tempClass);
  430.                 }
  431.             }
  432.         }
  433.         return subclasses;
  434.     }
  435.    
  436.     private NpcHtmlMessage getNpcHtmlMessage(Player player, Npc npc, String fileName) {
  437.         final NpcHtmlMessage html = new NpcHtmlMessage(npc.getObjectId());
  438.         final String text = getHtm(player, fileName);
  439.         if (text == null) {
  440.             LOGGER.info("Cannot find HTML file for " + SubClassMaster.class.getSimpleName() + " AI: " + fileName);
  441.             return null;
  442.         }
  443.         html.setHtml(text);
  444.         return html;
  445.     }
  446.    
  447.     private boolean checkRules(Npc npc, Player player, boolean addSubclass){
  448.         boolean _check = false;
  449.         final StringBuilder sb = new StringBuilder();
  450.         final NpcHtmlMessage html = getNpcHtmlMessage(player, npc, "SubClassError.html");
  451.        
  452.         if (addSubclass){
  453.             if (player.getTotalSubClasses() >= Config.MAX_SUBCLASS){
  454.                 sb.append("you have reached the limit of Subclasses (" + Config.MAX_SUBCLASS + ").");
  455.                 html.replace("%subclass_error%", sb.toString());
  456.                 player.sendPacket(html);
  457.                 _check = true;
  458.             }
  459.         }
  460.        
  461.         if (OlympiadManager.getInstance().isRegisteredInComp(player)){
  462.             OlympiadManager.getInstance().unRegisterNoble(player);
  463.             _check = true;
  464.         }
  465.        
  466.         if (player.isTransformed() || player.isSubclassLocked()){
  467.             sb.append("you are in transformed now.");
  468.             html.replace("%subclass_error%", sb.toString());
  469.             player.sendPacket(html);
  470.             _check = true;
  471.         }else if (player.hasSummon() || player.isMounted() || player.isFlying()){
  472.             sb.append("you have summon a pet or mounted.");
  473.             html.replace("%subclass_error%", sb.toString());
  474.             player.sendPacket(html);
  475.             _check = true;
  476.         }else if (!player.isInventoryUnder90(true) || (player.getWeightPenalty() >= 2)){
  477.             sb.append("your inventory capacity is more 90% or <br> you have weight penalty.");
  478.             html.replace("%subclass_error%", sb.toString());
  479.             player.sendPacket(html);
  480.             _check = true;
  481.         }else if (player.isCastingNow() || player.isAttackingNow() || player.isCombatFlagEquipped() || player.isInCombat() || player.isInDuel()){
  482.             sb.append("you casting spell now or attack.");
  483.             html.replace("%subclass_error%", sb.toString());
  484.             player.sendPacket(html);
  485.             _check = true;
  486.         }else if (!player.isInsideZone(ZoneId.PEACE)){
  487.             sb.append("you are not inside into a Peace Zone.");
  488.             html.replace("%subclass_error%", sb.toString());
  489.             player.sendPacket(html);
  490.             _check = true;
  491.         }else if (player.isDead() || player.isFakeDeath()){
  492.             sb.append("you are dead or use fake Death.");
  493.             html.replace("%subclass_error%", sb.toString());
  494.             player.sendPacket(html);
  495.             _check = true;
  496.         }else if (player.isCursedWeaponEquipped() || player.getReputation() < 0){
  497.             sb.append("you karma of equipped Cursed Weapon.");
  498.             html.replace("%subclass_error%", sb.toString());
  499.             player.sendPacket(html);
  500.             _check = true;
  501.         }else if (player.isAffectedBySkill(IDENTITY_CRISIS_SKILL_ID)){
  502.             sb.append("you are under skill effect wait.");
  503.             html.replace("%subclass_error%", sb.toString());
  504.             player.sendPacket(html);
  505.             _check = true;
  506.         }
  507.         return _check;
  508.     }
  509. }
  510.  
  511. [HTML section]
  512. [SubClassConfirmAdd.html]
  513. <html>
  514.     <title>SubClass Master: Confirm Add</title>
  515.     <body>
  516.     <center>
  517.         Here we are the choice is not an easy task!<br>
  518.         <font color="LEVEL">The new subclass will have none of the skill enchants or the skills you learned through codices. Think carefully.</font><br>
  519.         Are you sure you want to go ahead with this decision? <br>
  520.         %confirm_add%
  521.     </center>
  522.     </body>
  523. </html>
  524. [SubClassConfirmChange.html]
  525. <html>
  526.     <title>SubClass Master: Confirm Change</title>
  527.     <body>
  528.     <center>
  529.         %confirm_change%
  530.     </center>
  531.     </body>
  532. </html>
  533. [SubClassConfirmRemove.html]
  534. <html>
  535.     <title>SubClass Master: Confirm Remove</title>
  536.     <body>
  537.     <center>
  538.         %confirm_remove%
  539.     </center>
  540.     </body>
  541. </html>
  542. [SubClassError.html]
  543. <html>
  544.     <title>SubClass Master</title>
  545.     <body>
  546.     <center>
  547.         <img src="L2UI_CT1.HtmlWnd_DF_TextureKnight" width=300 height=220>
  548.         We cannot proceed your request because <font color="LEVEL"> %subclass_error%</font>
  549.     </center>
  550.     </body>
  551. </html>
  552. [SubClassList.html]
  553. <html>
  554.     <title>SubClass Master: Classes List</title>
  555.     <body>
  556.     <center>
  557.         <font color="LEVEL">Select an Class</font><br>
  558.         %subclass_list%
  559.     </center>
  560.     </body>
  561. </html>
  562. [SubClassMaster.html]
  563. <html>
  564.     <title>SubClass Master</title>
  565.     <body>
  566.     <center>
  567.         <button value="Add SubClass" action="bypass -h Quest SubClassMaster addSubclass" width=200 height=21 back="L2UI_CT1.Button_DF_Down" fore="L2UI_CT1.Button_DF" />
  568.         <button value="Remove SubClass" action="bypass -h Quest SubClassMaster removeSubclass" width=200 height=21 back="L2UI_CT1.Button_DF_Down" fore="L2UI_CT1.Button_DF" />
  569.         <button value="Change to SubClass" action="bypass -h Quest SubClassMaster changeSubclass" width=200 height=21 back="L2UI_CT1.Button_DF_Down" fore="L2UI_CT1.Button_DF" />
  570.     </center>
  571.     </body>
  572. </html>
  573. [SubClassSuccess.html]
  574. <html>
  575.     <title>SubClass Master: Success</title>
  576.     <body>
  577.         <table width="295" cellspacing="0">
  578.             <tr>
  579.                 <td>
  580.             <center>
  581.                 <img src="L2UI_CT1.HtmlWnd_DF_TextureKnight" width=300 height=220>
  582.                 <font color="LEVEL">Your subclass was successful,<br> welcome to our new Class</font><br>
  583.             </center>
  584.                 </td>
  585.             </tr>
  586.         </table>
  587.     </body>
  588. </html>
  589. [Welcome.html]
  590. <html>
  591.     <title>SubClass Master</title>
  592.     <body>
  593.         <table width="295" cellspacing="0">
  594.             <tr>
  595.                 <td>
  596.             <center>
  597.                 <img src="L2UI_CT1.HtmlWnd_DF_TextureKnight" width=300 height=220>
  598.                 <font color="LEVEL">Welcome.</font><br>
  599.                 I am the SubClass Master of this game<br>
  600.                 Do you want to switch to another Class?<br>
  601.                 <button value="Show me the Path's" action="bypass -h Quest SubClassMaster main" width=200 height=21 back="L2UI_CT1.Button_DF_Down" fore="L2UI_CT1.Button_DF" />
  602.             </center>
  603.                 </td>
  604.             </tr>
  605.         </table>
  606.     </body>
  607. </html>
  608.  
  609.  
  610.  
  611.  
  612.  
  613.  
  614.  
  615.  
  616.  
  617.  
  618.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement