Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- Index: java/config/custom.properties
- ===================================================================
- --- java/config/custom.properties (revision 470)
- +++ java/config/custom.properties (working copy)
- @@ -139,16 +139,34 @@
- # ------------------------------------------------------------
- # Allow use Event Managers for changing occupation
- # ------------------------------------------------------------
- -# If you need change occupation only use quest then set this to False
- -# Class transfers can also be configured seperately.
- -# Also, you can activate html pop up for class change
- -# Default = False
- +# Default: False
- AllowClassMasters = False
- -AllowMobileClassChange = False
- -AllowFirstClass = True
- -AllowSecondClass = True
- -AllowThirdClass = True
- +# ConfigClassMaster=1;[57(100000)];[];2;[57(1000000)];[];3;[57(10000000)],[5575(1000000)];[6622(1)]
- +# 1st occupation change for 100.000 Adena (item id 57)
- +# 2nd occupation change for 1.000.0000 Adena (item id 57)
- +# 3rd occupation change for 10.000.0000 Adena (item id 57) and 1.000.000 Ancient Adena (item id 5575)
- +# on 3rd occupation change player will be rewarded with 1 Book of Giants (item id 6622)
- +# ConfigClassMaster=1;[];[];2;[];[];3;[];[]
- +# 1st, 2nd, 3rd occupation change for free, without rewards.
- +# ConfigClassMaster=1;[];[];2;[];[]
- +# Allow only first and second change.
- +ConfigClassMaster = 1;[];[];2;[];[];3;[];[]
- +
- +# Class Masters will allow changing to any occupation on any level inside class tree
- +# For example, Dwarven Fighter will be able to advance to:
- +# Artisan, Scavenger, Warsmith, Bounty Hunter, Maestro, Fortune Seeker.
- +# But Warsmith will be able to change only to Maestro.
- +# Default = False
- +AllowEntireTree = False
- +
- +# When character reach levels 20,40,76 he will receive tutorial page
- +# with list of the all possible variants, and can select and immediately
- +# change to the new occupation, or decide to choose later (on next login).
- +# Can be used with or without classic Class Masters.
- +# Default = False
- +AlternateClassMaster = False
- +
- #-------------------------------------------------------------
- # L2J Core NPC
- #-------------------------------------------------------------
- Index: java/net/sf/l2j/Config.java
- ===================================================================
- --- java/net/sf/l2j/Config.java (revision 470)
- +++ java/net/sf/l2j/Config.java (working copy)
- @@ -27,10 +27,13 @@
- import java.util.List;
- import java.util.Map;
- import java.util.Properties;
- +import java.util.StringTokenizer;
- import java.util.logging.Logger;
- import javolution.util.FastList;
- import javolution.util.FastMap;
- +import gnu.trove.map.hash.TIntIntHashMap;
- +import gnu.trove.map.hash.TIntObjectHashMap;
- /**
- * This class contains global server configuration.<br>
- @@ -753,16 +756,11 @@
- /** Allow teleporting to towns that are under siege ?*/
- public static boolean ALLOW_SIEGE_TELEPORT;
- /** Allow use Event Managers for change occupation ?*/
- - public static boolean ALLOW_CLASS_MASTERS;
- - /** Allow occupation change with html pop up?*/
- - public static boolean ALLOW_MOBILE_CLASS_CHANGE;
- - /** Allow first occupation change?*/
- - public static boolean ALLOW_FIRST_CLASS;
- - /** Allow second occupation change?*/
- - public static boolean ALLOW_SECOND_CLASS;
- - /** Allow third occupation change?*/
- - public static boolean ALLOW_THIRD_CLASS;
- -
- + public static boolean ALLOW_CLASS_MASTERS;
- + public static ClassMasterSettings CLASS_MASTER_SETTINGS;
- + public static boolean ALLOW_ENTIRE_TREE;
- + public static boolean ALTERNATE_CLASS_MASTER;
- +
- /** Time between 2 updates of IP */
- public static int IP_UPDATE_TIME;
- @@ -1885,12 +1883,14 @@
- OFFLINE_SET_NAME_COLOR = Boolean.valueOf(customSettings.getProperty("OfflineSetNameColor", "false"));
- OFFLINE_NAME_COLOR = Integer.decode("0x" + customSettings.getProperty("OfflineNameColor", "808080"));
- ALLOW_SIEGE_TELEPORT = Boolean.valueOf(customSettings.getProperty("AllowSiegeTeleport", "False"));
- - ALLOW_CLASS_MASTERS = Boolean.valueOf(customSettings.getProperty("AllowClassMasters", "False"));
- - ALLOW_MOBILE_CLASS_CHANGE = Boolean.valueOf(customSettings.getProperty("AllowMobileClassChange", "False"));
- - ALLOW_FIRST_CLASS = Boolean.valueOf(customSettings.getProperty("AllowFirstClass", "True"));
- - ALLOW_SECOND_CLASS = Boolean.valueOf(customSettings.getProperty("AllowSecondClass", "True"));
- - ALLOW_THIRD_CLASS = Boolean.valueOf(customSettings.getProperty("AllowThirdClass", "True"));
- - }
- + ALLOW_CLASS_MASTERS = Boolean.valueOf(customSettings.getProperty("AllowClassMasters", "False"));
- + ALLOW_ENTIRE_TREE = Boolean.valueOf(customSettings.getProperty("AllowEntireTree", "False"));
- + ALTERNATE_CLASS_MASTER = Boolean.valueOf(customSettings.getProperty("AlternateClassMaster", "False"));
- + if (ALLOW_CLASS_MASTERS || ALTERNATE_CLASS_MASTER)
- + {
- + CLASS_MASTER_SETTINGS = new ClassMasterSettings(String.valueOf(customSettings.getProperty("ConfigClassMaster")));
- + }
- + }
- catch (Exception e)
- {
- e.printStackTrace();
- @@ -2365,11 +2365,18 @@
- else if (pName.equalsIgnoreCase("AllowSiegeTeleport")) ALLOW_SIEGE_TELEPORT = Boolean.valueOf(pValue);
- - else if (pName.equalsIgnoreCase("AllowClassMasters")) ALLOW_CLASS_MASTERS = Boolean.valueOf(pValue);
- - else if (pName.equalsIgnoreCase("AllowMobileClassChange")) ALLOW_MOBILE_CLASS_CHANGE = Boolean.valueOf(pValue);
- - else if (pName.equalsIgnoreCase("AllowFirstClass")) ALLOW_FIRST_CLASS = Boolean.valueOf(pValue);
- - else if (pName.equalsIgnoreCase("AllowSecondClass")) ALLOW_SECOND_CLASS = Boolean.valueOf(pValue);
- - else if (pName.equalsIgnoreCase("AllowThirdClass")) ALLOW_THIRD_CLASS = Boolean.valueOf(pValue);
- + else if (pName.equalsIgnoreCase("AllowClassMasters"))
- + {
- + ALLOW_CLASS_MASTERS = Boolean.valueOf(pValue);
- + }
- + else if (pName.equalsIgnoreCase("AllowEntireTree"))
- + {
- + ALLOW_ENTIRE_TREE = Boolean.valueOf(pValue);
- + }
- + else if (pName.equalsIgnoreCase("AlternateClassMaster"))
- + {
- + ALTERNATE_CLASS_MASTER = Boolean.valueOf(pValue);
- + }
- else if (pName.equalsIgnoreCase("AltGameFreights")) ALT_GAME_FREIGHTS = Boolean.valueOf(pValue);
- else if (pName.equalsIgnoreCase("AltGameFreightPrice")) ALT_GAME_FREIGHT_PRICE = Integer.parseInt(pValue);
- @@ -2452,4 +2459,103 @@
- e.printStackTrace();
- }
- }
- +
- + public static class ClassMasterSettings
- + {
- + private final TIntObjectHashMap<TIntIntHashMap> _claimItems;
- + private final TIntObjectHashMap<TIntIntHashMap> _rewardItems;
- + private final TIntObjectHashMap<Boolean> _allowedClassChange;
- +
- + public ClassMasterSettings(String _configLine)
- + {
- + _claimItems = new TIntObjectHashMap<>(3);
- + _rewardItems = new TIntObjectHashMap<>(3);
- + _allowedClassChange = new TIntObjectHashMap<>(3);
- + if (_configLine != null)
- + {
- + parseConfigLine(_configLine.trim());
- + }
- + }
- +
- + private void parseConfigLine(String _configLine)
- + {
- + StringTokenizer st = new StringTokenizer(_configLine, ";");
- +
- + while (st.hasMoreTokens())
- + {
- + // get allowed class change
- + int job = Integer.parseInt(st.nextToken());
- +
- + _allowedClassChange.put(job, true);
- +
- + TIntIntHashMap _items = new TIntIntHashMap();
- + // parse items needed for class change
- + if (st.hasMoreTokens())
- + {
- + StringTokenizer st2 = new StringTokenizer(st.nextToken(), "[],");
- +
- + while (st2.hasMoreTokens())
- + {
- + StringTokenizer st3 = new StringTokenizer(st2.nextToken(), "()");
- + int _itemId = Integer.parseInt(st3.nextToken());
- + int _quantity = Integer.parseInt(st3.nextToken());
- + _items.put(_itemId, _quantity);
- + }
- + }
- +
- + _claimItems.put(job, _items);
- +
- + _items = new TIntIntHashMap();
- + // parse gifts after class change
- + if (st.hasMoreTokens())
- + {
- + StringTokenizer st2 = new StringTokenizer(st.nextToken(), "[],");
- +
- + while (st2.hasMoreTokens())
- + {
- + StringTokenizer st3 = new StringTokenizer(st2.nextToken(), "()");
- + int _itemId = Integer.parseInt(st3.nextToken());
- + int _quantity = Integer.parseInt(st3.nextToken());
- + _items.put(_itemId, _quantity);
- + }
- + }
- +
- + _rewardItems.put(job, _items);
- + }
- + }
- +
- + public boolean isAllowed(int job)
- + {
- + if (_allowedClassChange == null)
- + {
- + return false;
- + }
- + if (_allowedClassChange.containsKey(job))
- + {
- + return _allowedClassChange.get(job);
- + }
- +
- + return false;
- + }
- +
- + public TIntIntHashMap getRewardItems(int job)
- + {
- + if (_rewardItems.containsKey(job))
- + {
- + return _rewardItems.get(job);
- + }
- +
- + return null;
- + }
- +
- + public TIntIntHashMap getRequireItems(int job)
- + {
- + if (_claimItems.containsKey(job))
- + {
- + return _claimItems.get(job);
- + }
- +
- + return null;
- + }
- + }
- }
- \ No newline at end of file
- Index: java/net/sf/l2j/gameserver/clientpackets/EnterWorld.java
- ===================================================================
- --- java/net/sf/l2j/gameserver/clientpackets/EnterWorld.java (revision 470)
- +++ java/net/sf/l2j/gameserver/clientpackets/EnterWorld.java (working copy)
- @@ -269,15 +269,21 @@
- }
- // just in case player gets disconnected
- - if (Config.ALLOW_MOBILE_CLASS_CHANGE)
- - {
- - if (Config.ALLOW_FIRST_CLASS && activeChar.getClassId().level() == 0 && activeChar.getLevel() >= 20)
- - L2ClassMasterInstance.showClassMasterWindow(activeChar, 2);
- - else if (Config.ALLOW_SECOND_CLASS && activeChar.getClassId().level() == 1 && activeChar.getLevel() >= 40)
- - L2ClassMasterInstance.showClassMasterWindow(activeChar, 2);
- - else if (Config.ALLOW_THIRD_CLASS && activeChar.getClassId().level() == 2 && activeChar.getLevel() >= 76)
- - L2ClassMasterInstance.showClassMasterWindow(activeChar, 2);
- - }
- + if (Config.ALTERNATE_CLASS_MASTER)
- + {
- + if (Config.CLASS_MASTER_SETTINGS.isAllowed(1) && (activeChar.getClassId().level() == 0) && (activeChar.getLevel() >= 20))
- + {
- + L2ClassMasterInstance.showHtmlMenu(activeChar, 0, 1);
- + }
- + else if (Config.CLASS_MASTER_SETTINGS.isAllowed(2) && (activeChar.getClassId().level() == 1) && (activeChar.getLevel() >= 40))
- + {
- + L2ClassMasterInstance.showHtmlMenu(activeChar, 0, 2);
- + }
- + else if (Config.CLASS_MASTER_SETTINGS.isAllowed(3) && (activeChar.getClassId().level() == 2) && (activeChar.getLevel() >= 76))
- + {
- + L2ClassMasterInstance.showHtmlMenu(activeChar, 0, 3);
- + }
- + }
- PetitionManager.getInstance().checkPetitionMessages(activeChar);
- Index: java/net/sf/l2j/gameserver/clientpackets/RequestBypassToServer.java
- ===================================================================
- --- java/net/sf/l2j/gameserver/clientpackets/RequestBypassToServer.java (revision 470)
- +++ java/net/sf/l2j/gameserver/clientpackets/RequestBypassToServer.java (working copy)
- @@ -182,8 +182,8 @@
- Olympiad.getInstance().bypassChangeArena(_command, activeChar);
- else if (_command.startsWith("change_class"))
- {
- - if (Config.ALLOW_CLASS_MASTERS || Config.ALLOW_MOBILE_CLASS_CHANGE)
- - L2ClassMasterInstance.changeClass(activeChar, _command);
- + if (Config.ALLOW_CLASS_MASTERS || Config.ALTERNATE_CLASS_MASTER)
- + L2ClassMasterInstance.checkAndChangeClass(activeChar, Integer.valueOf(_command.substring(13)));
- }
- }
- catch (Exception e)
- Index: java/net/sf/l2j/gameserver/clientpackets/RequestTutorialLinkHtml.java
- ===================================================================
- --- java/net/sf/l2j/gameserver/clientpackets/RequestTutorialLinkHtml.java (revision 470)
- +++ java/net/sf/l2j/gameserver/clientpackets/RequestTutorialLinkHtml.java (working copy)
- @@ -21,6 +21,7 @@
- import java.nio.ByteBuffer;
- import net.sf.l2j.gameserver.ClientThread;
- +import net.sf.l2j.gameserver.model.actor.instance.L2ClassMasterInstance;
- import net.sf.l2j.gameserver.model.actor.instance.L2PcInstance;
- import net.sf.l2j.gameserver.model.quest.QuestState;
- @@ -42,6 +43,8 @@
- if (player == null)
- return;
- + L2ClassMasterInstance.onTutorialLink(player, _bypass);
- +
- QuestState qs = player.getQuestState("255_Tutorial");
- if (qs != null)
- qs.getQuest().notifyEvent(_bypass, null, player);
- Index: java/net/sf/l2j/gameserver/model/actor/instance/L2ClassMasterInstance.java
- ===================================================================
- --- java/net/sf/l2j/gameserver/model/actor/instance/L2ClassMasterInstance.java (revision 470)
- +++ java/net/sf/l2j/gameserver/model/actor/instance/L2ClassMasterInstance.java (working copy)
- @@ -1,288 +1,462 @@
- /*
- - * 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 2, 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, write to the Free Software
- - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- - * 02111-1307, USA.
- - *
- - * http://www.gnu.org/copyleft/gpl.html
- + * 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 net.sf.l2j.gameserver.model.actor.instance;
- -import javolution.text.TextBuilder;
- -
- import net.sf.l2j.Config;
- -import net.sf.l2j.gameserver.ai.CtrlIntention;
- +import net.sf.l2j.gameserver.cache.HtmCache;
- import net.sf.l2j.gameserver.datatables.CharTemplateTable;
- +import net.sf.l2j.gameserver.datatables.ItemTable;
- +import net.sf.l2j.gameserver.instancemanager.QuestManager;
- import net.sf.l2j.gameserver.model.base.ClassId;
- -import net.sf.l2j.gameserver.model.base.ClassLevel;
- -import net.sf.l2j.gameserver.model.base.PlayerClass;
- import net.sf.l2j.gameserver.model.quest.Quest;
- -import net.sf.l2j.gameserver.serverpackets.ActionFailed;
- -import net.sf.l2j.gameserver.serverpackets.MyTargetSelected;
- import net.sf.l2j.gameserver.serverpackets.NpcHtmlMessage;
- -import net.sf.l2j.gameserver.serverpackets.SystemMessage;
- -import net.sf.l2j.gameserver.serverpackets.ValidateLocation;
- +import net.sf.l2j.gameserver.serverpackets.TutorialCloseHtml;
- +import net.sf.l2j.gameserver.serverpackets.TutorialShowHtml;
- +import net.sf.l2j.gameserver.serverpackets.TutorialShowQuestionMark;
- import net.sf.l2j.gameserver.templates.L2NpcTemplate;
- -/**
- - * This class ...
- - *
- - * @version $Revision: 1.4.2.1.2.7 $ $Date: 2005/03/27 15:29:32 $
- - */
- -public final class L2ClassMasterInstance extends L2FolkInstance
- +public final class L2ClassMasterInstance extends L2NpcInstance
- {
- - private static int[] _secondClassIds =
- - {
- - 2,3,5,6,9,8,12,13,14,16,17,20,21,23,24,27,
- - 28,30,33,34,36,37,40,41,43,46,48,51,52,55,57
- - };
- -
- - /**
- - * @param template
- - */
- - public L2ClassMasterInstance(int objectId, L2NpcTemplate template)
- - {
- - super(objectId, template);
- - }
- -
- - public void onAction(L2PcInstance player)
- - {
- - if (!canTarget(player))
- - return;
- -
- - player.setLastFolkNPC(this);
- -
- - if (getObjectId() != player.getTargetId())
- - {
- -
- - // Set the target of the L2PcInstance player
- - player.setTarget(this);
- -
- - // Send a Server->Client packet MyTargetSelected to the L2PcInstance player
- - player.sendPacket(new MyTargetSelected(getObjectId(), 0));
- -
- - // Send a Server->Client packet ValidateLocation to correct the L2NpcInstance position and heading on the client
- - player.sendPacket(new ValidateLocation(this));
- - }
- - else
- - {
- - if (!canInteract(player))
- - {
- - player.getAI().setIntention(CtrlIntention.AI_INTENTION_INTERACT, this);
- - return;
- - }
- -
- -
- - showClassMasterWindow(player, Config.ALLOW_CLASS_MASTERS ? 1 : 0);
- - }
- - player.sendPacket(new ActionFailed());
- - }
- -
- - public static void showClassMasterWindow(L2PcInstance player, int allowedState)
- - {
- - NpcHtmlMessage html = new NpcHtmlMessage(0);
- - TextBuilder sb = new TextBuilder();
- -
- - if (allowedState > 0)
- - {
- - if (Config.DEBUG)
- - _log.fine("ClassMaster activated");
- -
- - ClassId classId = player.getClassId();
- -
- - int jobLevel = 0;
- - int level = player.getLevel();
- - ClassLevel lvl = PlayerClass.values()[classId.getId()].getLevel();
- - switch (lvl)
- - {
- - case First:
- - jobLevel = 1;
- - break;
- - case Second:
- - jobLevel = 2;
- - break;
- - case Third:
- - jobLevel = 3;
- - break;
- - default:
- - jobLevel = 4;
- - break;
- - }
- -
- - if ((Config.ALLOW_FIRST_CLASS && level >= 20 && jobLevel == 1) || (Config.ALLOW_SECOND_CLASS && level >= 40 && jobLevel == 2))
- - {
- - html.setFile("data/html/classmaster/" + classId.getId() + ".htm");
- - player.sendPacket(html);
- - }
- - else if (Config.ALLOW_THIRD_CLASS && level >= 76 && jobLevel == 3)
- - {
- - for (int i = 0; i < _secondClassIds.length; i++)
- - {
- - if (classId.getId() == _secondClassIds[i])
- - {
- - sb.append("<html><body<center>");
- - sb.append("<img src=\"L2UI_CH3.herotower_deco\" width=256 height=32>");
- - sb.append("<br><br><table width=200>");
- - sb.append("<tr><td>"+CharTemplateTable.getClassNameById(classId.getId())+" Class Master:</td></tr>");
- - sb.append("<tr><td><br></td></tr>");
- - sb.append("<tr><td><a action=\"bypass -h change_class "+(88+i)+"\">Advance to "+CharTemplateTable.getClassNameById(88+i)+"</a></td></tr>");
- - sb.append("<tr><td><br></td></tr></table><br><br>");
- - sb.append("<img src=\"L2UI_CH3.herotower_deco\" width=256 height=32>");
- -
- - sb.append("</center></body></html>");
- - html.setHtml(sb.toString());
- - player.sendPacket(html);
- -
- - }
- - }
- - }
- - else if (allowedState != 2)
- - {
- - sb.append("<html><head><body>");
- -
- - switch (jobLevel)
- - {
- - case 1:
- - if (Config.ALLOW_FIRST_CLASS)
- - sb.append("<br>Come back here when you reach level 20 to change your class.");
- - else
- - sb.append("<br>You have to complete First Class Transfer on your own.");
- - break;
- - case 2:
- - if (Config.ALLOW_SECOND_CLASS)
- - sb.append("<br>Come back here when you reach level 40 to change your class.");
- - else
- - sb.append("<br>You have to complete Second Class Transfer on your own.");
- - break;
- - case 3:
- - if (Config.ALLOW_THIRD_CLASS)
- - sb.append("<br>Come back here when you reach level 76 to change your class.");
- - else
- - sb.append("<br>You have to complete Third Class Transfer on your own.");
- - break;
- - default:
- - sb.append("<br>There are no more classes available for you.");
- - break;
- - }
- -
- - for (Quest q : Quest.findAllEvents())
- - sb.append("Event: <a action=\"bypass -h Quest "+q.getName()+"\">"+q.getDescr()+"</a><br>");
- -
- - sb.append("</body></html>");
- - html.setHtml(sb.toString());
- - player.sendPacket(html);
- - }
- - }
- - else
- - {
- - sb.append("<html><head><body>");
- - sb.append("<br><center>Class Master is deactivated.</center>");
- - sb.append("</body></html>");
- - html.setHtml(sb.toString());
- - player.sendPacket(html);
- - }
- - }
- -
- - public static void changeClass(L2PcInstance player, String command)
- - {
- - int val = Integer.parseInt(command.substring(13));
- -
- -
- - // Exploit prevention
- - ClassId classId = player.getClassId();
- - int level = player.getLevel();
- - int jobLevel = 0;
- - int newJobLevel = 0;
- -
- -
- - // some protection checks, just to be sure
- - ClassLevel lvlnow = PlayerClass.values()[classId.getId()].getLevel();
- - switch (lvlnow)
- - {
- - case First:
- - if (!Config.ALLOW_FIRST_CLASS)
- - return;
- - jobLevel = 1;
- - break;
- - case Second:
- - if (!Config.ALLOW_SECOND_CLASS)
- - return;
- - jobLevel = 2;
- - break;
- - case Third:
- - if (!Config.ALLOW_THIRD_CLASS)
- - return;
- - jobLevel = 3;
- - break;
- - default:
- - jobLevel = 4;
- - break;
- - }
- -
- - if (jobLevel == 4)
- - return; // no more job changes
- -
- - ClassLevel lvlnext = PlayerClass.values()[val].getLevel();
- - switch (lvlnext)
- - {
- - case First:
- - newJobLevel = 1;
- - break;
- - case Second:
- - newJobLevel = 2;
- - break;
- - case Third:
- - newJobLevel = 3;
- - break;
- - default:
- - newJobLevel = 4;
- - break;
- - }
- -
- - // prevents changing between same level jobs
- - if (newJobLevel != jobLevel + 1)
- - return;
- -
- - if (level < 20 && newJobLevel > 1)
- - return;
- - if (level < 40 && newJobLevel > 2)
- - return;
- - if (level < 76 && newJobLevel > 3)
- - return;
- - // -- prevention ends
- -
- - if (Config.DEBUG)
- - _log.fine("Changing class to ClassId:"+val);
- -
- -
- - player.setClassId(val);
- -
- -
- - if (player.isSubClassActive())
- - player.getSubClasses().get(player.getClassIndex()).setClassId(player.getActiveClass());
- - else
- - player.setBaseClass(player.getActiveClass());
- -
- -
- - player.broadcastUserInfo();
- -
- -
- - if (val >= 88)
- - player.sendPacket(new SystemMessage(1606)); // system sound 3rd occupation
- - else
- - {
- - player.sendPacket(new SystemMessage(1308)); // system sound for 1st and 2nd occupation
- - showClassMasterWindow(player, 2);
- - }
- - }
- -}
- \ No newline at end of file
- + /**
- + * @param objectId
- + * @param template
- + */
- + public L2ClassMasterInstance(int objectId, L2NpcTemplate template)
- + {
- + super(objectId, template);
- + }
- +
- + @Override
- + public String getHtmlPath(int npcId, int val)
- + {
- + String pom = "";
- +
- + if (val == 0)
- + {
- + pom = "" + npcId;
- + }
- + else
- + {
- + pom = npcId + "-" + val;
- + }
- +
- + return "data/html/classmaster/" + pom + ".htm";
- + }
- +
- + @Override
- + public void onBypassFeedback(L2PcInstance player, String command)
- + {
- + if (command.startsWith("1stClass"))
- + {
- + showHtmlMenu(player, getObjectId(), 1);
- + }
- + else if (command.startsWith("2ndClass"))
- + {
- + showHtmlMenu(player, getObjectId(), 2);
- + }
- + else if (command.startsWith("3rdClass"))
- + {
- + showHtmlMenu(player, getObjectId(), 3);
- + }
- + else if (command.startsWith("change_class"))
- + {
- + int val = Integer.parseInt(command.substring(13));
- +
- + if (checkAndChangeClass(player, val))
- + {
- + NpcHtmlMessage html = new NpcHtmlMessage(getObjectId());
- + html.setFile("data/html/classmaster/ok.htm");
- + CharTemplateTable.getInstance();
- + html.replace("%name%", CharTemplateTable.getClassNameById(val));
- + player.sendPacket(html);
- + }
- + }
- + else
- + {
- + super.onBypassFeedback(player, command);
- + }
- + }
- +
- + public static final void onTutorialLink(L2PcInstance player, String request)
- + {
- + if (!Config.ALTERNATE_CLASS_MASTER || (request == null) || !request.startsWith("CO"))
- + {
- + return;
- + }
- +
- + try
- + {
- + int val = Integer.parseInt(request.substring(2));
- + checkAndChangeClass(player, val);
- + }
- + catch (NumberFormatException e)
- + {
- + }
- + player.sendPacket(new TutorialCloseHtml());
- + }
- +
- + public static final void onTutorialQuestionMark(L2PcInstance player, int number)
- + {
- + if (!Config.ALTERNATE_CLASS_MASTER || (number != 1001))
- + {
- + return;
- + }
- +
- + showTutorialHtml(player);
- + }
- +
- + public static final void showQuestionMark(L2PcInstance player)
- + {
- + if (!Config.ALTERNATE_CLASS_MASTER)
- + {
- + return;
- + }
- +
- + final ClassId classId = player.getClassId();
- + if (getMinLevel(classId.level()) > player.getLevel())
- + {
- + return;
- + }
- +
- + if (!Config.CLASS_MASTER_SETTINGS.isAllowed(classId.level() + 1))
- + {
- + return;
- + }
- +
- + player.sendPacket(new TutorialShowQuestionMark(1001));
- + }
- +
- + public static final void showHtmlMenu(L2PcInstance player, int objectId, int level)
- + {
- + NpcHtmlMessage html = new NpcHtmlMessage(objectId);
- +
- + if (!Config.ALLOW_CLASS_MASTERS && !Config.ALTERNATE_CLASS_MASTER)
- + {
- + html.setFile("data/html/classmaster/disabled.htm");
- + }
- + else if (!Config.CLASS_MASTER_SETTINGS.isAllowed(level))
- + {
- + int jobLevel = player.getClassId().level();
- + final StringBuilder sb = new StringBuilder(100);
- + sb.append("<html><body>");
- + switch (jobLevel)
- + {
- + case 0:
- + if (Config.CLASS_MASTER_SETTINGS.isAllowed(1))
- + {
- + sb.append("Come back here when you reached level 20 to change your class.<br>");
- + }
- + else if (Config.CLASS_MASTER_SETTINGS.isAllowed(2))
- + {
- + sb.append("Come back after your first occupation change.<br>");
- + }
- + else if (Config.CLASS_MASTER_SETTINGS.isAllowed(3))
- + {
- + sb.append("Come back after your second occupation change.<br>");
- + }
- + else
- + {
- + sb.append("I can't change your occupation.<br>");
- + }
- + break;
- + case 1:
- + if (Config.CLASS_MASTER_SETTINGS.isAllowed(2))
- + {
- + sb.append("Come back here when you reached level 40 to change your class.<br>");
- + }
- + else if (Config.CLASS_MASTER_SETTINGS.isAllowed(3))
- + {
- + sb.append("Come back after your second occupation change.<br>");
- + }
- + else
- + {
- + sb.append("I can't change your occupation.<br>");
- + }
- + break;
- + case 2:
- + if (Config.CLASS_MASTER_SETTINGS.isAllowed(3))
- + {
- + sb.append("Come back here when you reached level 76 to change your class.<br>");
- + }
- + else
- + {
- + sb.append("I can't change your occupation.<br>");
- + }
- + break;
- + case 3:
- + sb.append("There is no class change available for you anymore.<br>");
- + break;
- + }
- + sb.append("</body></html>");
- + html.setHtml(sb.toString());
- + }
- + else
- + {
- + final ClassId currentClassId = player.getClassId();
- + if (currentClassId.level() >= level)
- + {
- + html.setFile("data/html/classmaster/nomore.htm");
- + }
- + else
- + {
- + final int minLevel = getMinLevel(currentClassId.level());
- + if ((player.getLevel() >= minLevel) || Config.ALLOW_ENTIRE_TREE)
- + {
- + final StringBuilder menu = new StringBuilder(100);
- + for (ClassId cid : ClassId.values())
- + {
- + if (validateClassId(currentClassId, cid) && (cid.level() == level))
- + {
- + if (objectId > 0)
- + {
- + menu.append("<a action=\"bypass -h npc_%objectId%_change_class ");
- + }
- + else
- + {
- + menu.append("<a action=\"bypass -h change_class ");
- + }
- + menu.append(String.valueOf(cid.getId()));
- + menu.append("\">");
- + CharTemplateTable.getInstance();
- + menu.append(CharTemplateTable.getClassNameById(cid.getId()));
- + menu.append("</a><br>");
- + }
- + }
- +
- + if (menu.length() > 0)
- + {
- + html.setFile("data/html/classmaster/template.htm");
- + CharTemplateTable.getInstance();
- + html.replace("%name%", CharTemplateTable.getClassNameById(currentClassId.getId()));
- + html.replace("%menu%", menu.toString());
- + }
- + else
- + {
- + html.setFile("data/html/classmaster/comebacklater.htm");
- + html.replace("%level%", String.valueOf(getMinLevel(level - 1)));
- + }
- + }
- + else
- + {
- + if (minLevel < Integer.MAX_VALUE)
- + {
- + html.setFile("data/html/classmaster/comebacklater.htm");
- + html.replace("%level%", String.valueOf(minLevel));
- + }
- + else
- + {
- + html.setFile("data/html/classmaster/nomore.htm");
- + }
- + }
- + }
- + }
- +
- + html.replace("%objectId%", String.valueOf(objectId));
- + html.replace("%req_items%", getRequiredItems(level));
- + player.sendPacket(html);
- + }
- +
- + private static final void showTutorialHtml(L2PcInstance player)
- + {
- + final ClassId currentClassId = player.getClassId();
- + if ((getMinLevel(currentClassId.level()) > player.getLevel()) && !Config.ALLOW_ENTIRE_TREE)
- + {
- + return;
- + }
- +
- + String msg = HtmCache.getInstance().getHtm("data/html/classmaster/tutorialtemplate.htm");
- +
- + CharTemplateTable.getInstance();
- + msg = msg.replaceAll("%name%", CharTemplateTable.getClassNameById(currentClassId.getId()));
- +
- + final StringBuilder menu = new StringBuilder(100);
- + for (ClassId cid : ClassId.values())
- + {
- + if (validateClassId(currentClassId, cid))
- + {
- + menu.append("<a action=\"link CO");
- + menu.append(String.valueOf(cid.getId()));
- + menu.append("\">");
- + CharTemplateTable.getInstance();
- + menu.append(CharTemplateTable.getClassNameById(cid.getId()));
- + menu.append("</a><br>");
- + }
- + }
- +
- + msg = msg.replaceAll("%menu%", menu.toString());
- + msg = msg.replace("%req_items%", getRequiredItems(currentClassId.level() + 1));
- + player.sendPacket(new TutorialShowHtml(msg));
- + }
- +
- + public static final boolean checkAndChangeClass(L2PcInstance player, int val)
- + {
- + final ClassId currentClassId = player.getClassId();
- + if ((getMinLevel(currentClassId.level()) > player.getLevel()) && !Config.ALLOW_ENTIRE_TREE)
- + {
- + return false;
- + }
- +
- + if (!validateClassId(currentClassId, val))
- + {
- + return false;
- + }
- +
- + int newJobLevel = currentClassId.level() + 1;
- +
- + // Weight/Inventory check
- + if (!Config.CLASS_MASTER_SETTINGS.getRewardItems(newJobLevel).isEmpty())
- + {
- + if ((player.getWeightPenalty() >= 3) || ((player.getInventoryLimit() * 0.8) <= player.getInventory().getSize()))
- + {
- + player.sendMessage("Progress in a quest is possible only when your inventory's weight and volume are less than 80 percent of capacity.");
- + return false;
- + }
- + }
- +
- + // check if player have all required items for class transfer
- + for (int _itemId : Config.CLASS_MASTER_SETTINGS.getRequireItems(newJobLevel).keys())
- + {
- + int _count = Config.CLASS_MASTER_SETTINGS.getRequireItems(newJobLevel).get(_itemId);
- + if (player.getInventory().getInventoryItemCount(_itemId, -1) < _count)
- + {
- + player.sendMessage("Incorrect item count.");
- + return false;
- + }
- + }
- +
- + // get all required items for class transfer
- + for (int _itemId : Config.CLASS_MASTER_SETTINGS.getRequireItems(newJobLevel).keys())
- + {
- + int _count = Config.CLASS_MASTER_SETTINGS.getRequireItems(newJobLevel).get(_itemId);
- + if (!player.destroyItemByItemId("ClassMaster", _itemId, _count, player, true))
- + {
- + return false;
- + }
- + }
- +
- + // reward player with items
- + for (int _itemId : Config.CLASS_MASTER_SETTINGS.getRewardItems(newJobLevel).keys())
- + {
- + int _count = Config.CLASS_MASTER_SETTINGS.getRewardItems(newJobLevel).get(_itemId);
- + player.addItem("ClassMaster", _itemId, _count, player, true);
- + }
- +
- + player.setClassId(val);
- +
- + if (player.isSubClassActive())
- + {
- + player.getSubClasses().get(player.getClassIndex()).setClassId(player.getActiveClass());
- + }
- + else
- + {
- + player.setBaseClass(player.getActiveClass());
- + }
- +
- + Quest q = QuestManager.getInstance().getQuest("SkillTransfer");
- + if (q != null)
- + {
- + q.startQuestTimer("givePormanders", 1, null, player);
- + }
- +
- + player.broadcastUserInfo();
- +
- + if (Config.CLASS_MASTER_SETTINGS.isAllowed(player.getClassId().level() + 1) && Config.ALTERNATE_CLASS_MASTER && (((player.getClassId().level() == 1) && (player.getLevel() >= 40)) || ((player.getClassId().level() == 2) && (player.getLevel() >= 76))))
- + {
- + showQuestionMark(player);
- + }
- +
- + return true;
- + }
- +
- + /**
- + * Returns minimum player level required for next class transfer
- + * @param level - current skillId level (0 - start, 1 - first, etc)
- + * @return
- + */
- + private static final int getMinLevel(int level)
- + {
- + switch (level)
- + {
- + case 0:
- + return 20;
- + case 1:
- + return 40;
- + case 2:
- + return 76;
- + default:
- + return Integer.MAX_VALUE;
- + }
- + }
- +
- + /**
- + * Returns true if class change is possible
- + * @param oldCID current player ClassId
- + * @param val new class index
- + * @return
- + */
- + private static final boolean validateClassId(ClassId oldCID, int val)
- + {
- + try
- + {
- + return validateClassId(oldCID, ClassId.values()[val]);
- + }
- + catch (Exception e)
- + {
- + // possible ArrayOutOfBoundsException
- + }
- + return false;
- + }
- +
- + /**
- + * Returns true if class change is possible
- + * @param oldCID current player ClassId
- + * @param newCID new ClassId
- + * @return true if class change is possible
- + */
- + private static final boolean validateClassId(ClassId oldCID, ClassId newCID)
- + {
- + if ((newCID == null) || (newCID.getRace() == null))
- + {
- + return false;
- + }
- +
- + if (oldCID.equals(newCID.getParent()))
- + {
- + return true;
- + }
- +
- + if (Config.ALLOW_ENTIRE_TREE && newCID.childOf(oldCID))
- + {
- + return true;
- + }
- +
- + return false;
- + }
- +
- + private static String getRequiredItems(int level)
- + {
- + if ((Config.CLASS_MASTER_SETTINGS.getRequireItems(level) == null) || Config.CLASS_MASTER_SETTINGS.getRequireItems(level).isEmpty())
- + {
- + return "<tr><td>none</td></r>";
- + }
- + StringBuilder sb = new StringBuilder();
- + for (int _itemId : Config.CLASS_MASTER_SETTINGS.getRequireItems(level).keys())
- + {
- + int _count = Config.CLASS_MASTER_SETTINGS.getRequireItems(level).get(_itemId);
- + sb.append("<tr><td><font color=\"LEVEL\">" + _count + "</font></td><td>" + ItemTable.getInstance().getTemplate(_itemId).getName() + "</td></tr>");
- + }
- + return sb.toString();
- + }
- +}
- Index: java/net/sf/l2j/gameserver/model/actor/stat/PcStat.java
- ===================================================================
- --- java/net/sf/l2j/gameserver/model/actor/stat/PcStat.java (revision 470)
- +++ java/net/sf/l2j/gameserver/model/actor/stat/PcStat.java (working copy)
- @@ -164,15 +164,21 @@
- {
- // That's the best thing to do here as
- // players can increase level too fast in high rates
- - if (Config.ALLOW_MOBILE_CLASS_CHANGE)
- - {
- - if (Config.ALLOW_FIRST_CLASS && getActiveChar().getClassId().level() == 0 && getActiveChar().getLevel() >= 20)
- - L2ClassMasterInstance.showClassMasterWindow(getActiveChar(), 2);
- - else if (Config.ALLOW_SECOND_CLASS && getActiveChar().getClassId().level() == 1 && getActiveChar().getLevel() >= 40)
- - L2ClassMasterInstance.showClassMasterWindow(getActiveChar(), 2);
- - else if (Config.ALLOW_THIRD_CLASS && getActiveChar().getClassId().level() == 2 && getActiveChar().getLevel() >= 76)
- - L2ClassMasterInstance.showClassMasterWindow(getActiveChar(), 2);
- - }
- + if (Config.ALTERNATE_CLASS_MASTER)
- + {
- + if (Config.CLASS_MASTER_SETTINGS.isAllowed(1) && (getActiveChar().getClassId().level() == 0) && (getActiveChar().getLevel() >= 20))
- + {
- + L2ClassMasterInstance.showHtmlMenu(getActiveChar(), 0, 1);
- + }
- + else if (Config.CLASS_MASTER_SETTINGS.isAllowed(2) && (getActiveChar().getClassId().level() == 1) && (getActiveChar().getLevel() >= 40))
- + {
- + L2ClassMasterInstance.showHtmlMenu(getActiveChar(), 0, 2);
- + }
- + else if (Config.CLASS_MASTER_SETTINGS.isAllowed(3) && (getActiveChar().getClassId().level() == 2) && (getActiveChar().getLevel() >= 76))
- + {
- + L2ClassMasterInstance.showHtmlMenu(getActiveChar(), 0, 3);
- + }
- + }
- applyNewbieStatus();
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement