Index: /java/net/sf/l2j/gameserver/model/L2PcInstance.java =================================================================== --- /java/net/sf/l2j/gameserver/model/L2PcInstance.java (revision 1905) +++ /java/net/sf/l2j/gameserver/model/L2PcInstance.java (working copy) @@ -129,11 +129,11 @@ private static final String UPDATE_CHARACTER_SKILL_LEVEL = "UPDATE character_skills SET skill_level=? WHERE skill_id=? AND char_obj_id=? AND class_index=?"; private static final String DELETE_SKILL_FROM_CHAR = "DELETE FROM character_skills WHERE skill_id=? AND char_obj_id=? AND class_index=?"; private static final String DELETE_CHAR_SKILLS = "DELETE FROM character_skills WHERE char_obj_id=? AND class_index=?"; - + private static final String ADD_SKILL_SAVE = "INSERT INTO character_skills_save (char_obj_id,skill_id,skill_level,effect_count,effect_cur_time,class_index) VALUES (?,?,?,?,?,?)"; private static final String RESTORE_SKILL_SAVE = "SELECT skill_id,skill_level,effect_count,effect_cur_time FROM character_skills_save WHERE char_obj_id=? AND class_index=?"; private static final String DELETE_SKILL_SAVE = "DELETE FROM character_skills_save WHERE char_obj_id=? AND class_index=?"; - + private static final String RESTORE_CHARACTER = "SELECT account_name, obj_Id, char_name, level, maxHp, curHp, maxCp, curCp, maxMp, curMp, acc, crit, evasion, mAtk, mDef, mSpd, pAtk, pDef, pSpd, runSpd, walkSpd, str, con, dex, _int, men, wit, face, hairStyle, hairColor, sex, heading, x, y, z, movement_multiplier, attack_speed_multiplier, colRad, colHeight, exp, sp, karma, pvpkills, pkkills, clanid, maxload, race, classid, deletetime, cancraft, title, allyId, rec_have, rec_left, accesslevel, online, char_slot, lastAccess, clan_privs, wantspeace, deleteclan, base_class FROM characters WHERE obj_id=?"; private static final String RESTORE_CHAR_SUBCLASSES = "SELECT class_id,exp,sp,level FROM character_subclasses WHERE char_obj_id=?"; @@ -417,8 +417,8 @@ private boolean _isProcessingTransaction = false; private long _lastAccess; + private int _boatId; - /** * Create a new L2PcInstance and add it in the characters table of the database.

* @@ -456,6 +456,9 @@ // Set the Face type of the L2PcInstance player.setFace(face); + // Set the base class ID to that of the actual class ID. + player.setBaseClass(player.getClassId()); + // Add the player in the characters table of the database boolean ok = player.createDb(); @@ -642,7 +645,7 @@ */ public final int getLevel() { - if (_classIndex == 0) + if (!isSubClassActive()) return _level; int subIndex = _classIndex - 1; @@ -719,6 +722,10 @@ _baseClass = baseClass; } + public void setBaseClass(ClassId classId) + { + _baseClass = classId.ordinal(); + } /** * Set the In Store Mode of the L2PcInstance to True or False.

@@ -1416,7 +1423,7 @@ */ public int getExp() { - if (_classIndex == 0) + if (!isSubClassActive()) return _exp; int subIndex = _classIndex - 1; @@ -1541,9 +1548,10 @@ int currExp = getExp(); int currSp = getSp(); - if (currExp > Experience.LEVEL[76]) currExp = Experience.LEVEL[76]; + if (currExp > Experience.LEVEL[76]) + currExp = Experience.LEVEL[76]; - int max_xp = Experience.LEVEL[76] - currExp; + final int max_xp = Experience.LEVEL[76] - currExp; if (addToExp > max_xp) currExp += max_xp; @@ -1556,7 +1564,7 @@ setSp(currSp); // Remove Karma when the player kills L2MonsterInstance - if (_exp != 0 || isGM()) + if (currExp != 0 || isGM()) { // NEW KARMA REMOVAL FROM XP by ootz0rz int karmaRemove = addToExp; @@ -1574,8 +1582,8 @@ // Send a Server->Client packet StatusUpdate to the L2PcInstance StatusUpdate su = new StatusUpdate(getObjectId()); - su.addAttribute(StatusUpdate.EXP, _exp); - su.addAttribute(StatusUpdate.SP, _sp); + su.addAttribute(StatusUpdate.EXP, currExp); + su.addAttribute(StatusUpdate.SP, currSp); su.addAttribute(StatusUpdate.KARMA, _karma); sendPacket(su); @@ -1585,18 +1593,10 @@ sm.addNumber(addToSp); sendPacket(sm); - // If the L2PcInstance increases it's level send a Server->Client packet SocialAction (broadcast) if ((currExp >= Experience.LEVEL[getLevel() + 1]) && (currExp < Experience.LEVEL[76])) - { - SocialAction sa = new SocialAction(getObjectId(), 15); - broadcastPacket(sa); + broadcastPacket(new SocialAction(getObjectId(), 15)); - // Already done in broadcastPacket - //sendPacket(sa); - } - - while ((currExp >= Experience.LEVEL[getLevel() + 1]) && (currExp < Experience.LEVEL[76])) { // Manage the increase level task of a L2PcInstance (Max MP, Max MP, Recommandation, Expertise and beginner skills...) @@ -1669,7 +1669,7 @@ if (exp < 0) exp = 0; - if (_classIndex == 0) { + if (!isSubClassActive()) { _exp = exp; return; } @@ -1683,7 +1683,7 @@ */ public Race getRace() { - if (_classIndex == 0) + if (!isSubClassActive()) return getTemplate().race; boolean isFemale = (getSex() == 1); @@ -1697,7 +1697,7 @@ */ public int getSp() { - if (_classIndex == 0) + if (!isSubClassActive()) return _sp; int subIndex = _classIndex - 1; @@ -1712,7 +1712,7 @@ if (sp < 0) sp = 0; - if (_classIndex == 0) { + if (!isSubClassActive()) { _sp = sp; return; } @@ -2865,8 +2865,8 @@ // Set the PvP Flag of the L2PcInstance setPvpFlag(0); - stopRentPet(); - stopWaterTask(); + stopRentPet(); + stopWaterTask(); // Kill the L2PcInstance super.doDie(killer); @@ -3208,7 +3208,7 @@ // Increase the level of the L2PcIstance if (getLevel() < 75) - if (_classIndex == 0) { + if (!isSubClassActive()) { _level++; } else { @@ -3262,7 +3262,7 @@ if (Config.DEBUG) _log.finest("decreasing level of " + getName()); if (getLevel() < 75) - if (_classIndex == 0) { + if (!isSubClassActive()) { _level--; } else { @@ -4027,7 +4027,7 @@ statement.setInt(51, getClanPrivileges()); statement.setInt(52, getWantsPeace()); statement.setLong(53, getDeleteClanTime()); - statement.setInt(54, getClassId().getId()); + statement.setInt(54, getBaseClass()); statement.executeUpdate(); statement.close(); } @@ -4090,21 +4090,21 @@ player._activeClass = activeClassId; try { - player._baseClass = rset.getInt("base_class"); + player.setBaseClass(rset.getInt("base_class")); } catch (Exception e) { - player._baseClass = player._activeClass; + player.setBaseClass(activeClassId); } if (restoreSubClassData(player)) { int classIndex = 1; - if (activeClassId == player._baseClass) + if (activeClassId == player.getBaseClass()) player._classIndex = 0; else - for (SubClass subClass : player._subClasses) + for (SubClass subClass : player.getSubClasses()) { - if (subClass.getClassId() == player._activeClass) { + if (subClass.getClassId() == player.getActiveClass()) { player._classIndex = classIndex; break; } @@ -4124,20 +4124,20 @@ int baseExp = rset.getInt("exp"); int baseSp = rset.getInt("sp"); + // Set the correct exp if the level was manipulated in the database. + if (baseExp < Experience.LEVEL[player.getLevel()] || + baseExp > Experience.LEVEL[player.getLevel()+1]) + { + baseExp = Experience.LEVEL[player.getLevel()]; + } + // Even if the class index is not that of the base class, make sure // the fields for _exp and _sp (representing the base class values) are correct. - if (player._classIndex > 0) { + if (player.isSubClassActive()) { player._exp = baseExp; player._sp = baseSp; } else { - // Set the correct exp if the level was manipulated in the database. - if (baseExp < Experience.LEVEL[player.getLevel()] || - baseExp > Experience.LEVEL[player.getLevel()+1]) - { - baseExp = Experience.LEVEL[player.getLevel()]; - } - player.setExp(baseExp); player.setSp(baseSp); } @@ -4223,9 +4223,7 @@ try { con = L2DatabaseFactory.getInstance().getConnection(); - PreparedStatement statement; - - statement = con.prepareStatement(RESTORE_CHAR_SUBCLASSES); + PreparedStatement statement = con.prepareStatement(RESTORE_CHAR_SUBCLASSES); statement.setInt(1, player.getObjectId()); ResultSet rset = statement.executeQuery(); @@ -4269,9 +4267,81 @@ // Retrieve from the database all henna of this L2PcInstance and add them to _henna. restoreHenna(); + + // Retrieve from the database the recipe book of this L2PcInstance. + if (!isSubClassActive()) + restoreRecipeBook(); } /** + * Store recipe book data for this L2PcInstance, if not on an active sub-class. + */ + private void storeRecipeBook() + { + // If the player is on a sub-class don't even attempt to store a recipe book. + if (isSubClassActive()) + return; + + java.sql.Connection con = null; + + try { + con = L2DatabaseFactory.getInstance().getConnection(); + PreparedStatement statement = con.prepareStatement("DELETE FROM character_recipebook WHERE char_id=?"); + statement.setInt(1, getObjectId()); + statement.execute(); + statement.close(); + + L2RecipeList[] recipes = getRecipeBook(); + + for (int count = 0; count < recipes.length; count++) + { + statement = con.prepareStatement("INSERT INTO character_recipebook (char_id, id) values(?,?)"); + statement.setInt(1, getObjectId()); + statement.setInt(2, recipes[count].getId()); + statement.execute(); + statement.close(); + } + } + catch (Exception e) { + _log.warning("Could not store recipe book data: " + e); + } + finally { + try { con.close(); } catch (Exception e) {} + } + } + + /** + * Restore recipe book data for this L2PcInstance. + */ + private void restoreRecipeBook() + { + java.sql.Connection con = null; + + try { + con = L2DatabaseFactory.getInstance().getConnection(); + PreparedStatement statement = con.prepareStatement("SELECT id FROM character_recipebook WHERE char_id=?"); + statement.setInt(1, getObjectId()); + ResultSet rset = statement.executeQuery(); + + while (rset.next()) { + int id = rset.getInt("id"); + + L2RecipeList recipe = RecipeController.getInstance().getRecipeList(id - 1); + registerRecipeList(recipe); + } + + rset.close(); + statement.close(); + } + catch (Exception e) { + _log.warning("Could not restore recipe book data:" + e); + } + finally { + try { con.close(); } catch (Exception e) {} + } + } + + /** * Update L2PcInstance stats in the characters table of the database.

*/ public void store() @@ -4326,7 +4396,7 @@ statement.setInt(28, getClanId()); statement.setInt(29, getMaxLoad()); - if (getClassIndex() == 0) + if (!isSubClassActive()) statement.setInt(30, getRace().ordinal()); else statement.setInt(30, getBaseTemplate().race.ordinal()); @@ -4385,6 +4455,8 @@ } } } + + storeRecipeBook(); } catch (Exception e) { @@ -5618,22 +5690,22 @@ stopRentPet(); } } - + private ScheduledFuture _taskWater; class WaterTask implements Runnable { public void run() { - double reduceHp = getMaxHp()/100; - if (reduceHp < 1) - reduceHp = 1; - reduceCurrentHp(reduceHp,L2PcInstance.this,false); - //reduced hp, becouse not rest - SystemMessage sm = new SystemMessage(297); - sm.addNumber((int)reduceHp); - sendPacket(sm); - + double reduceHp = getMaxHp()/100; + if (reduceHp < 1) + reduceHp = 1; + reduceCurrentHp(reduceHp,L2PcInstance.this,false); + //reduced hp, becouse not rest + SystemMessage sm = new SystemMessage(297); + sm.addNumber((int)reduceHp); + sendPacket(sm); + } } @@ -6174,15 +6246,17 @@ { SubClass newClass = new SubClass(); newClass.setClassId(classId); - newClass.setClassIndex(getTotalSubClasses() + 1); - if (subIndex > -1) + if (subIndex > -1) { _subClasses.set(subIndex, newClass); - else + } + else { if (getTotalSubClasses() == 3) return false; - else - _subClasses.add(newClass); + + newClass.setClassIndex(getTotalSubClasses() + 1); + _subClasses.add(newClass); + } java.sql.Connection con = null; @@ -6206,13 +6280,9 @@ try { con.close(); } catch (Exception e) {} } - classId--; ClassId id = ClassId.values()[classId]; - int newIndex = getTotalSubClasses(); - _log.info("ClassId: " + classId + ", NewClass: " + newClass.getClassId()); - // Add all the necessary skills up to level 40 for this new class. L2SkillLearn[] availSkills = SkillTreeTable.getInstance().getAvailableSkills(this, id); int numSkillsAdded = 0; @@ -6292,6 +6362,11 @@ return addSubClass(newClassId, subIndex); } + public boolean isSubClassActive() + { + return _classIndex > 0; + } + public List getSubClasses() { return _subClasses; @@ -6360,6 +6435,11 @@ for (L2Effect effect : getAllEffects()) effect.exit(); + if (isSubClassActive()) + _recipebook.clear(); + else + restoreRecipeBook(); + restoreSkills(); rewardSkills(); restoreEffects(); @@ -6430,17 +6510,17 @@ { _taskWater.cancel(false); _taskWater = null; - sendPacket(new SetupGauge(2, 0)); + sendPacket(new SetupGauge(2, 0)); } } public void startWaterTask() { - if (!isDead() && _taskWater == null) - { - int timeinwater = 86; - sendPacket(new SetupGauge(2, timeinwater * 1000)); + if (!isDead() && _taskWater == null) + { + int timeinwater = 86; + sendPacket(new SetupGauge(2, timeinwater * 1000)); _taskWater = ClientScheduler.getInstance().scheduleLowAtFixedRate(new WaterTask(), timeinwater * 1000, 1000); - } + } } public boolean isInWater() { @@ -6464,7 +6544,7 @@ zone = ZoneManager.getInstance().getZone(L2ZoneType.Type_Water, getX(), getY()); //checking if char is in water zone if (zone == null) zone = ZoneManager.getInstance().getZoneType(L2ZoneType.Type_Underground).getZone(getX(), getY()); //checking if char is in underground and in water - if (zone != null) + if (zone != null) { coord = zone.getCoord(getX(), getY()); if (coord != null && getZ() > coord[4]) @@ -6475,7 +6555,7 @@ } startWaterTask(); - } + } public void onPlayerEnter() { @@ -6540,10 +6620,17 @@ _recomHave -= 3; } - if (_recomHave < 0) { + if (_recomHave < 0) _recomHave = 0; - } - } + public int getBoatId() + { + return _boatId; + } + + public void setBoatId(int boatId) + { + _boatId = boatId; + } }