java/net/sf/l2j/gameserver/model/actor/instance/L2ClassMasterInstance.java =================================================================== --- C:/Documents and Settings/wajs/workspace/L2_GameServerSVN/java/net/sf/l2j/gameserver/model/actor/instance/L2ClassMasterInstance.java (revision 2117) +++ C:/Documents and Settings/wajs/workspace/L2_GameServerSVN/java/net/sf/l2j/gameserver/model/actor/instance/L2ClassMasterInstance.java (working copy) @@ -22,6 +22,8 @@ import net.sf.l2j.gameserver.CharTemplateTable; import net.sf.l2j.gameserver.ai.CtrlIntention; import net.sf.l2j.gameserver.model.base.ClassId; +import net.sf.l2j.gameserver.model.base.PlayerClass; +import net.sf.l2j.gameserver.model.base.ClassLevel; import net.sf.l2j.gameserver.model.quest.Quest; import net.sf.l2j.gameserver.serverpackets.ActionFailed; import net.sf.l2j.gameserver.serverpackets.MyTargetSelected; @@ -80,42 +82,17 @@ int jobLevel = 0; int level = player.getLevel(); - - switch (classId) + ClassLevel lvl = PlayerClass.values()[classId.getId()].getLevel(); + switch (lvl) { - case fighter: - case mage: - case elvenFighter: - case elvenMage: - case darkFighter: - case darkMage: - case orcFighter: - case orcMage: - case dwarvenFighter: - jobLevel = 1; - break; - case elvenScout: - case elvenKnight: - case elvenWizard: - case oracle: - case knight: - case warrior: - case rogue: - case wizard: - case cleric: - case palusKnight: - case assassin: - case darkWizard: - case shillienOracle: - case orcRaider: - case orcMonk: - case orcShaman: - case scavenger: - case artisan: - jobLevel = 2; - break; - default: - jobLevel = 3; + case First: + jobLevel = 1; + break; + case Second: + jobLevel = 2; + break; + default: + jobLevel = 3; } if (!Config.ALLOW_CLASS_MASTERS) @@ -132,16 +109,15 @@ { if (classId.getId() == _secondClassIds[i]) { - changeClass(player, 88+i); - player.setBaseClass(player.getActiveClass()); - player.sendPacket(new SystemMessage(1606)); - NpcHtmlMessage html = new NpcHtmlMessage(1); StringBuffer sb = new StringBuffer(); - sb.append(""); - sb.append("You have now become a " + CharTemplateTable.getClassNameById(classId.ordinal()) + "."); - sb.append(""); - + sb.append(""); + sb.append("
"+CharTemplateTable.getClassNameById(classId.getId())+" Class Master:
"); + sb.append("
"); + sb.append("Advance to "+CharTemplateTable.getClassNameById(88+i)+""); + sb.append("
"); + sb.append("Upgrade Hatchling to Strider"); + sb.append(""); html.setHtml(sb.toString()); player.sendPacket(html); return; @@ -187,28 +163,42 @@ { if(command.startsWith("change_class")) { - int val = Integer.parseInt(command.substring(13)); - changeClass(player, val); + int val = Integer.parseInt(command.substring(13)); + changeClass(player, val); - //set base_class = classid after profession change - player.setBaseClass(player.getActiveClass()); - } - else - { - // this class dont know any other commands, let forward - // the command to the parent class - - super.onBypassFeedback(player, command); - } - } + 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 + + NpcHtmlMessage html = new NpcHtmlMessage(1); + StringBuffer sb = new StringBuffer(); + sb.append(""); + sb.append("You have now become a " + CharTemplateTable.getClassNameById(player.getClassId().getId()) + "."); + sb.append(""); + + html.setHtml(sb.toString()); + player.sendPacket(html); + } + else + { + super.onBypassFeedback(player, command); + } + } private void changeClass(L2PcInstance player, int val) { if (Config.DEBUG) _log.fine("Changing class to ClassId:"+val); - player.setClassId(val); - if (Config.DEBUG) _log.fine("name:"+player.getName()); - if (Config.DEBUG) _log.fine("level:"+player.getLevel()); - if (Config.DEBUG) _log.fine("classId:"+player.getClassId()); + if (player.isSubClassActive()) + { + player.upgradeSubClass(player.getClassIndex(), val); + player.setActiveClass(player.getClassIndex()); + } + else + { + player.setClassId(val); + player.setBaseClass(player.getActiveClass()); + } player.broadcastUserInfo(); } } java/net/sf/l2j/gameserver/model/actor/instance/L2PcInstance.java =================================================================== --- C:/Documents and Settings/wajs/workspace/L2_GameServerSVN/java/net/sf/l2j/gameserver/model/actor/instance/L2PcInstance.java (revision 2117) +++ C:/Documents and Settings/wajs/workspace/L2_GameServerSVN/java/net/sf/l2j/gameserver/model/actor/instance/L2PcInstance.java (working copy) @@ -192,6 +192,7 @@ private static final String RESTORE_CHAR_SUBCLASSES = "SELECT class_id,exp,sp,level,class_index FROM character_subclasses WHERE char_obj_id=? ORDER BY class_index ASC"; private static final String ADD_CHAR_SUBCLASS = "INSERT INTO character_subclasses (char_obj_id,class_id,exp,sp,level,class_index) VALUES (?,?,?,?,?,?)"; private static final String UPDATE_CHAR_SUBCLASS = "UPDATE character_subclasses SET exp=?,sp=?,level=? WHERE char_obj_id=? AND class_index =?"; + private static final String UPDATE_CHAR_SUBCLASS_CLASSID = "UPDATE character_subclasses SET class_id=? WHERE char_obj_id=? AND class_index =?"; private static final String DELETE_CHAR_SUBCLASS = "DELETE FROM character_subclasses WHERE char_obj_id=? AND class_index=?"; private static final String RESTORE_CHAR_HENNAS = "SELECT slot,symbol_id FROM character_hennas WHERE char_obj_id=? AND class_index=?"; @@ -7163,6 +7164,52 @@ } /** + * This method is mainly used to get a 3rd class for a subclass + * 1. Replace the subclass at classIndex by the specified class ID.
+ * 2. This method no longer changes the active _classIndex of the player. This is only + * done by the calling of setActiveClass() method as that should be the only way to do so. + * + * @param int classIndex + * @param int newClassId + * @return boolean subclassUpgraded + */ + public boolean upgradeSubClass(int classIndex, int newClassId) + { + if (!getSubClasses().containsKey(classIndex)) + return false; + + java.sql.Connection con = null; + + try + { + //upgrade info about existing subclass. + con = L2DatabaseFactory.getInstance().getConnection(); + PreparedStatement statement = con.prepareStatement(UPDATE_CHAR_SUBCLASS_CLASSID); + statement.setInt(1, newClassId); + statement.setInt(2, getObjectId()); + statement.setInt(3, classIndex); + statement.execute(); + statement.close(); + } + catch (Exception e) + { + _log.warning("WARNING: Could not upgrade character sub class for " + getName() + ": " + e); + return false; + } + finally + { + try { con.close(); } catch (Exception e) {} + } + + getSubClasses().get(classIndex).setClassId(newClassId); + + if (Config.DEBUG) + _log.info(getName() + " upgraded sub class at index " + classIndex + " with class ID " + newClassId + "."); + + return true; + } + + /** * 1. Completely erase all existance of the subClass linked to the classIndex.
* 2. Send over the newClassId to addSubClass()to create a new instance on this classIndex.
* 3. Upon Exception, revert the player to their BaseClass to avoid further problems.
java/net/sf/l2j/gameserver/model/base/PlayerClass.java =================================================================== --- C:/Documents and Settings/wajs/workspace/L2_GameServerSVN/java/net/sf/l2j/gameserver/model/base/PlayerClass.java (revision 2117) +++ C:/Documents and Settings/wajs/workspace/L2_GameServerSVN/java/net/sf/l2j/gameserver/model/base/PlayerClass.java (working copy) @@ -233,4 +233,8 @@ { return this.level == pLevel; } + public final ClassLevel getLevel() + { + return level; + } }